Index: runtime/vm/flow_graph_allocator.cc |
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc |
index 75adcd33e881015fc9e744dc98949d9444463d54..302503ae5e8344e737e6848f85dcd633d27aa3e7 100644 |
--- a/runtime/vm/flow_graph_allocator.cc |
+++ b/runtime/vm/flow_graph_allocator.cc |
@@ -100,10 +100,19 @@ void FlowGraphAllocator::EliminateEnvironmentUses() { |
UseVal* use = (*values)[i]->AsUse(); |
if (use == NULL) continue; |
- PhiInstr* phi = use->definition()->AsPhi(); |
- if (phi == NULL) continue; |
+ Definition* def = use->definition(); |
+ |
+ PushArgumentInstr* push_argument = def->AsPushArgument(); |
+ if ((push_argument != NULL) && push_argument->WasEliminated()) { |
+ (*values)[i] = push_argument->value(); |
+ continue; |
+ } |
- if (!phi->is_alive()) (*values)[i] = null_value; |
+ PhiInstr* phi = def->AsPhi(); |
+ if ((phi != NULL) && !phi->is_alive()) { |
+ (*values)[i] = null_value; |
+ continue; |
+ } |
} |
} else { |
current->set_env(NULL); |
@@ -146,10 +155,12 @@ void FlowGraphAllocator::ComputeInitialSets() { |
const GrowableArray<Value*>& values = current->env()->values(); |
for (intptr_t j = 0; j < values.length(); j++) { |
Value* val = values[j]; |
srdjan
2012/08/09 20:25:26
I think this looks simpler :
UseVal* use_val = va
Vyacheslav Egorov (Google)
2012/08/10 14:27:46
Agreed.
|
- if (val->IsUse()) { |
- const intptr_t use = val->AsUse()->definition()->ssa_temp_index(); |
- live_in->Add(use); |
- } |
+ if (!val->IsUse()) continue; |
+ |
+ Definition* def = val->AsUse()->definition(); |
+ if (def->IsPushArgument()) continue; |
+ |
+ live_in->Add(def->ssa_temp_index()); |
} |
} |
} |
@@ -656,6 +667,55 @@ void FlowGraphAllocator::ConnectIncomingPhiMoves(BlockEntryInstr* block) { |
} |
+void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, |
+ Instruction* current) { |
+ ASSERT(current->env() != NULL); |
+ |
+ Environment* env = current->env(); |
+ |
+ // Any value mentioned in the deoptimization environment should survive |
+ // until the end of instruction but it does not need to be in the register. |
+ // Expected shape of live range: |
+ // |
+ // i i' |
+ // value -----* |
+ // |
+ |
+ const GrowableArray<Value*>& values = env->values(); |
+ if (values.length() == 0) return; |
+ |
+ const intptr_t block_start_pos = block->start_pos(); |
+ const intptr_t use_pos = current->lifetime_position() + 1; |
+ |
+ Location* locations = |
+ Isolate::Current()->current_zone()->Alloc<Location>(values.length()); |
+ |
+ for (intptr_t i = 0; i < values.length(); ++i) { |
+ Value* value = values[i]; |
+ if (value->IsUse()) { |
+ locations[i] = Location::Any(); |
+ Definition* def = value->AsUse()->definition(); |
+ |
+ if (def->IsPushArgument()) { |
+ // Frame size is unknown until after allocation. |
+ locations[i] = Location::NoLocation(); |
+ continue; |
+ } |
+ |
+ const intptr_t vreg = def->ssa_temp_index(); |
+ LiveRange* range = GetLiveRange(vreg); |
+ range->AddUseInterval(block_start_pos, use_pos); |
+ range->AddUse(use_pos, &locations[i]); |
+ } else { |
+ ASSERT(value->IsConstant()); |
+ locations[i] = Location::NoLocation(); |
+ } |
+ } |
+ |
+ env->set_locations(locations); |
+} |
+ |
+ |
// Create and update live ranges corresponding to instruction's inputs, |
// temporaries and output. |
void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, |
@@ -683,10 +743,7 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, |
(locs->out().policy() == Location::kSameAsFirstInput); |
// Add uses from the deoptimization environment. |
- Environment* env = current->env(); |
- if (env != NULL) { |
- env->InitializeLocations(this, block->start_pos(), pos + 1); |
- } |
+ if (current->env() != NULL) ProcessEnvironmentUses(block, current); |
// Process inputs. |
// Skip the first input if output is specified with kSameAsFirstInput policy, |