Index: runtime/vm/flow_graph_allocator.cc |
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc |
index 1ac20cad0629be9276ce3e70a54ca0bd50762906..5c16a8bcfd7f34f05f0a9cf9abe17a8320f59f78 100644 |
--- a/runtime/vm/flow_graph_allocator.cc |
+++ b/runtime/vm/flow_graph_allocator.cc |
@@ -102,18 +102,6 @@ FlowGraphAllocator::FlowGraphAllocator(const FlowGraph& flow_graph) |
} |
-// Remove environments from the instructions which can't deoptimize. |
-void FlowGraphAllocator::EliminateEnvironments() { |
- for (intptr_t i = 0; i < block_order_.length(); ++i) { |
- BlockEntryInstr* block = block_order_[i]; |
- for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
- Instruction* current = it.Current(); |
- if (!current->CanDeoptimize()) current->RemoveEnvironment(); |
- } |
- } |
-} |
- |
- |
void SSALivenessAnalysis::ComputeInitialSets() { |
const intptr_t block_count = postorder_.length(); |
for (intptr_t i = 0; i < block_count; i++) { |
@@ -152,10 +140,17 @@ void SSALivenessAnalysis::ComputeInitialSets() { |
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()); |
+ Definition* defn = env_it.CurrentValue()->definition(); |
+ if (defn->IsMaterializeObject()) { |
+ // MaterializeObject instruction is not in the graph. |
+ // Treat its inputs as part of the environment. |
+ for (intptr_t i = 0; i < defn->InputCount(); i++) { |
+ if (!defn->InputAt(i)->BindsToConstant()) { |
+ live_in->Add(defn->InputAt(i)->definition()->ssa_temp_index()); |
+ } |
+ } |
+ } else if (!defn->IsPushArgument() && !defn->IsConstant()) { |
+ live_in->Add(defn->ssa_temp_index()); |
} |
} |
} |
@@ -742,6 +737,16 @@ void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, |
continue; |
} |
+ MaterializeObjectInstr* mat = def->AsMaterializeObject(); |
+ if (mat != NULL) { |
+ // MaterializeObject itself produces no value. But its uses |
+ // are treated as part of the environment: allocated locations |
+ // will be used when building deoptimization data. |
+ locations[i] = Location::NoLocation(); |
+ ProcessMaterializationUses(block, block_start_pos, use_pos, mat); |
+ continue; |
+ } |
+ |
const intptr_t vreg = def->ssa_temp_index(); |
LiveRange* range = GetLiveRange(vreg); |
range->AddUseInterval(block_start_pos, use_pos); |
@@ -754,6 +759,42 @@ void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, |
} |
+void FlowGraphAllocator::ProcessMaterializationUses( |
+ BlockEntryInstr* block, |
+ const intptr_t block_start_pos, |
+ const intptr_t use_pos, |
+ MaterializeObjectInstr* mat) { |
+ // Materialization can occur several times in the same environment. |
+ // Check if we already processed this one. |
+ if (mat->locations() != NULL) { |
+ return; // Already processed. |
+ } |
+ |
+ // Initialize location for every input of the MaterializeObject instruction. |
+ Location* locations = |
+ Isolate::Current()->current_zone()->Alloc<Location>(mat->InputCount()); |
+ |
+ for (intptr_t i = 0; i < mat->InputCount(); ++i) { |
+ Definition* def = mat->InputAt(i)->definition(); |
+ |
+ ConstantInstr* constant = def->AsConstant(); |
+ if (constant != NULL) { |
+ locations[i] = Location::Constant(constant->value()); |
+ continue; |
+ } |
+ |
+ locations[i] = Location::Any(); |
+ |
+ 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]); |
+ } |
+ |
+ mat->set_locations(locations); |
+} |
+ |
+ |
// Create and update live ranges corresponding to instruction's inputs, |
// temporaries and output. |
void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, |
@@ -2435,8 +2476,6 @@ void FlowGraphAllocator::CollectRepresentations() { |
void FlowGraphAllocator::AllocateRegisters() { |
CollectRepresentations(); |
- EliminateEnvironments(); |
- |
liveness_.Analyze(); |
NumberInstructions(); |