Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Unified Diff: runtime/vm/flow_graph_allocator.cc

Issue 14682020: Optimize functions containing try-catch. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed Srdjan's comments Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/flow_graph_allocator.cc
===================================================================
--- runtime/vm/flow_graph_allocator.cc (revision 22436)
+++ runtime/vm/flow_graph_allocator.cc (working copy)
@@ -183,6 +183,17 @@
}
}
}
+ } else if (block->IsCatchBlockEntry()) {
+ // Process initial definitions.
Kevin Millikin (Google) 2013/05/08 11:42:00 It's disconcerting that locals are treated so diff
Florian Schneider 2013/05/08 17:10:55 This deals with SSA values, similar to the initial
+ CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry();
+ for (intptr_t i = 0;
+ i < catch_entry->initial_definitions()->length();
+ i++) {
+ intptr_t vreg =
+ (*catch_entry->initial_definitions())[i]->ssa_temp_index();
+ kill_[catch_entry->postorder_number()]->Add(vreg);
+ live_in_[catch_entry->postorder_number()]->Remove(vreg);
+ }
}
}
@@ -246,7 +257,7 @@
ASSERT(start < end);
// Live ranges are being build by visiting instructions in post-order.
- // This implies that use intervals will be perpended in a monotonically
+ // This implies that use intervals will be prepended in a monotonically
// decreasing order.
if (first_use_interval() != NULL) {
// If the first use interval and the use interval we are adding
@@ -493,7 +504,54 @@
}
}
- ConnectIncomingPhiMoves(block);
+ if (block->IsJoinEntry()) {
+ ConnectIncomingPhiMoves(block->AsJoinEntry());
+ } else if (block->IsCatchBlockEntry()) {
+ // Process initial definitions.
+ CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry();
+ for (intptr_t i = 0;
+ i < catch_entry->initial_definitions()->length();
+ i++) {
+ Definition* defn = (*catch_entry->initial_definitions())[i];
Kevin Millikin (Google) 2013/05/08 11:42:00 All this code that is duplicated below should be m
Florian Schneider 2013/05/08 17:10:55 Done.
+ LiveRange* range = GetLiveRange(defn->ssa_temp_index());
+ range->DefineAt(catch_entry->start_pos()); // Defined at block entry.
+ if (defn->IsParameter()) {
+ ParameterInstr* param = defn->AsParameter();
+ // Assert that copied and non-copied parameters are mutually
+ // exclusive. This might change in the future and, if so, the
+ // index will be wrong.
+ ASSERT((flow_graph_.num_copied_params() == 0) ||
+ (flow_graph_.num_non_copied_params() == 0));
+ // Slot index for the leftmost copied parameter is 0.
+ intptr_t slot_index = param->index();
+ // Slot index for the rightmost fixed parameter is -1.
+ slot_index -= flow_graph_.num_non_copied_params();
+ range->set_assigned_location(Location::StackSlot(slot_index));
+ range->set_spill_slot(Location::StackSlot(slot_index));
+ } else {
+ ConstantInstr* constant = defn->AsConstant();
+ ASSERT(constant != NULL);
+ range->set_assigned_location(Location::Constant(constant->value()));
+ range->set_spill_slot(Location::Constant(constant->value()));
+ }
+ spill_slots_.Add(range->End());
+ quad_spill_slots_.Add(false);
+ AssignSafepoints(range);
+ range->finger()->Initialize(range);
+ UsePosition* use = range->finger()->FirstRegisterBeneficialUse(
+ catch_entry->start_pos());
+ if (use != NULL) {
+ LiveRange* tail =
+ SplitBetween(range, catch_entry->start_pos(), use->pos());
+ // Parameters and constants are tagged, so allocated to CPU registers.
+ CompleteRange(tail, Location::kRegister);
+ }
+ ConvertAllUses(range);
+ if (defn->IsParameter() && range->spill_slot().stack_index() >= 0) {
+ MarkAsObjectAtSafepoints(range);
+ }
+ }
+ }
}
// Process incoming parameters and constants. Do this after all other
@@ -518,7 +576,6 @@
range->set_assigned_location(Location::StackSlot(slot_index));
range->set_spill_slot(Location::StackSlot(slot_index));
if (flow_graph_.num_copied_params() > 0) {
- ASSERT(spill_slots_.length() == slot_index);
spill_slots_.Add(range->End());
quad_spill_slots_.Add(false);
}
@@ -653,12 +710,9 @@
}
-void FlowGraphAllocator::ConnectIncomingPhiMoves(BlockEntryInstr* block) {
- // If this block is a join we need to add destinations of phi
- // resolution moves to phi's live range so that register allocator will
- // fill them with moves.
- JoinEntryInstr* join = block->AsJoinEntry();
- if (join == NULL) return;
+void FlowGraphAllocator::ConnectIncomingPhiMoves(JoinEntryInstr* join) {
+ // For join blocks we need to add destinations of phi resolution moves
+ // to phi's live range so that register allocator will fill them with moves.
// All uses are recorded at the start position in the block.
const intptr_t pos = join->start_pos();
@@ -681,7 +735,7 @@
if (is_loop_header) range->mark_loop_phi();
for (intptr_t pred_idx = 0; pred_idx < phi->InputCount(); pred_idx++) {
- BlockEntryInstr* pred = block->PredecessorAt(pred_idx);
+ BlockEntryInstr* pred = join->PredecessorAt(pred_idx);
GotoInstr* goto_instr = pred->last_instruction()->AsGoto();
ASSERT((goto_instr != NULL) && (goto_instr->HasParallelMove()));
MoveOperands* move =
@@ -1517,7 +1571,11 @@
// Search for a free spill slot among allocated: the value in it should be
// dead and its type should match (e.g. it should not be a part of the quad if
// we are allocating normal double slot).
- intptr_t idx = 0;
+ // For CPU registers we need to take reserved slots for try-catch into
+ // account.
+ intptr_t idx = register_kind_ == Location::kRegister
+ ? flow_graph_.graph_entry()->fixed_slot_count()
+ : 0;
for (; idx < spill_slots_.length(); idx++) {
if ((need_quad == quad_spill_slots_[idx]) &&
(spill_slots_[idx] <= start)) {
@@ -2409,6 +2467,17 @@
!it.Done();
it.Advance()) {
BlockEntryInstr* block = it.Current();
+
+ // Catch entry.
+ if (block->IsCatchBlockEntry()) {
+ CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry();
+ for (intptr_t i = 0;
+ i < catch_entry->initial_definitions()->length();
+ ++i) {
+ Definition* def = (*catch_entry->initial_definitions())[i];
+ value_representations_[def->ssa_temp_index()] = def->representation();
+ }
+ }
// Phis.
if (block->IsJoinEntry()) {
JoinEntryInstr* join = block->AsJoinEntry();

Powered by Google App Engine
This is Rietveld 408576698