| 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());
|
|
|