Index: runtime/vm/flow_graph_allocator.cc |
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc |
index 2118c08fb44d5cee13d1d9f4921779269795ed71..458533da7dbbf09aeab10563cade4a58d56228e1 100644 |
--- a/runtime/vm/flow_graph_allocator.cc |
+++ b/runtime/vm/flow_graph_allocator.cc |
@@ -149,9 +149,12 @@ void FlowGraphAllocator::ComputeInitialSets() { |
// Add non-argument uses from the deoptimization environment (pushed |
// arguments are not allocated by the register allocator). |
if (current->env() != NULL) { |
- for (intptr_t i = 0; i < current->env()->Length(); ++i) { |
- Value* value = current->env()->ValueAt(i); |
- if (!value->definition()->IsPushArgument()) { |
+ for (Environment::DeepIterator env_it(current->env()); |
+ !env_it.Done(); |
+ env_it.Advance()) { |
+ Value* value = env_it.CurrentValue(); |
+ if (!value->definition()->IsPushArgument() && |
+ !value->BindsToConstant()) { |
live_in->Add(value->definition()->ssa_temp_index()); |
} |
} |
@@ -738,49 +741,53 @@ void FlowGraphAllocator::ConnectIncomingPhiMoves(BlockEntryInstr* block) { |
void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, |
Instruction* current) { |
ASSERT(current->env() != NULL); |
- |
Environment* env = current->env(); |
+ while (env != NULL) { |
+ // 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 -----* |
+ // |
- // 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 -----* |
- // |
+ if (env->Length() == 0) { |
+ env = env->outer(); |
+ continue; |
+ } |
- if (env->Length() == 0) return; |
+ const intptr_t block_start_pos = block->start_pos(); |
+ const intptr_t use_pos = current->lifetime_position() + 1; |
- 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>(env->Length()); |
- Location* locations = |
- Isolate::Current()->current_zone()->Alloc<Location>(env->Length()); |
+ for (intptr_t i = 0; i < env->Length(); ++i) { |
+ Value* value = env->ValueAt(i); |
+ locations[i] = Location::Any(); |
+ Definition* def = value->definition(); |
- for (intptr_t i = 0; i < env->Length(); ++i) { |
- Value* value = env->ValueAt(i); |
- locations[i] = Location::Any(); |
- Definition* def = value->definition(); |
+ if (def->IsPushArgument()) { |
+ // Frame size is unknown until after allocation. |
+ locations[i] = Location::NoLocation(); |
+ continue; |
+ } |
- if (def->IsPushArgument()) { |
- // Frame size is unknown until after allocation. |
- locations[i] = Location::NoLocation(); |
- continue; |
- } |
+ ConstantInstr* constant = def->AsConstant(); |
+ if (constant != NULL) { |
+ locations[i] = Location::Constant(constant->value()); |
+ continue; |
+ } |
- ConstantInstr* constant = def->AsConstant(); |
- if (constant != NULL) { |
- locations[i] = Location::Constant(constant->value()); |
- 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]); |
} |
- 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]); |
+ env->set_locations(locations); |
+ env = env->outer(); |
} |
- |
- env->set_locations(locations); |
} |
@@ -1371,6 +1378,7 @@ LiveRange* LiveRange::SplitAt(intptr_t split_pos) { |
last_before_split = interval; |
} |
+ ASSERT(last_before_split != NULL); |
ASSERT(last_before_split->next() == first_after_split); |
ASSERT(last_before_split->end() <= split_pos); |
ASSERT(split_pos <= first_after_split->start()); |