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

Unified Diff: runtime/vm/intermediate_language.cc

Issue 12335063: Add functions for setting an environment and rebinding a use. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased and incorportated review comments. Created 7 years, 10 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
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language.cc
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 5d731f7a1d6dcdd2c88990e8024a560007eadb0e..9d12334daa6671c62a2f59d06791ae7b132da00b 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -318,6 +318,25 @@ FOR_EACH_INSTRUCTION(DEFINE_ACCEPT)
#undef DEFINE_ACCEPT
+void Instruction::SetEnvironment(Environment* deopt_env) {
+ intptr_t use_index = 0;
+ for (Environment::DeepIterator it(deopt_env); !it.Done(); it.Advance()) {
+ Value* use = it.CurrentValue();
+ use->set_instruction(this);
+ use->set_use_index(use_index++);
+ }
+ env_ = deopt_env;
+}
+
+
+void Instruction::RemoveEnvironment() {
+ for (Environment::DeepIterator it(env()); !it.Done(); it.Advance()) {
+ it.CurrentValue()->RemoveFromUseList();
+ }
+ env_ = NULL;
+}
+
+
Instruction* Instruction::RemoveFromGraph(bool return_previous) {
ASSERT(!IsBlockEntry());
ASSERT(!IsControl());
@@ -326,29 +345,23 @@ Instruction* Instruction::RemoveFromGraph(bool return_previous) {
ASSERT(!IsReThrow());
ASSERT(!IsGoto());
ASSERT(previous() != NULL);
+ // We cannot assert that the instruction, if it is a definition, has no
+ // uses. This function is used to remove instructions from the graph and
+ // reinsert them elsewhere (e.g., hoisting).
Instruction* prev_instr = previous();
Instruction* next_instr = next();
ASSERT(next_instr != NULL);
ASSERT(!next_instr->IsBlockEntry());
prev_instr->LinkTo(next_instr);
- // Reset successor and previous instruction to indicate
- // that the instruction is removed from the graph.
+ UnuseAllInputs();
+ // Reset the successor and previous instruction to indicate that the
+ // instruction is removed from the graph.
set_previous(NULL);
set_next(NULL);
return return_previous ? prev_instr : next_instr;
}
-void Instruction::InsertBefore(Instruction* next) {
- ASSERT(previous_ == NULL);
- ASSERT(next_ == NULL);
- next_ = next;
- previous_ = next->previous_;
- next->previous_ = this;
- previous_->next_ = this;
-}
-
-
void Instruction::InsertAfter(Instruction* prev) {
ASSERT(previous_ == NULL);
ASSERT(next_ == NULL);
@@ -356,6 +369,13 @@ void Instruction::InsertAfter(Instruction* prev) {
next_ = prev->next_;
next_->previous_ = this;
previous_->next_ = this;
+
+ // Update def-use chains whenever instructions are added to the graph
+ // after initial graph construction.
+ for (intptr_t i = InputCount() - 1; i >= 0; --i) {
+ Value* input = InputAt(i);
+ input->definition()->AddInputUse(input);
+ }
}
@@ -472,7 +492,6 @@ void Value::RemoveFromUseList() {
if (next != NULL) next->set_previous_use(prev);
}
- set_definition(NULL);
set_previous_use(NULL);
set_next_use(NULL);
}
@@ -537,23 +556,15 @@ void Definition::ReplaceWith(Definition* other,
}
// Take other's environment from this definition.
ASSERT(other->env() == NULL);
- intptr_t use_index = 0;
- for (Environment::DeepIterator it(env()); !it.Done(); it.Advance()) {
- Value* use = it.CurrentValue();
- use->set_instruction(other);
- use->set_use_index(use_index++);
- }
- other->set_env(env());
- set_env(NULL);
+ other->SetEnvironment(env());
+ env_ = NULL;
// Replace all uses of this definition with other.
ReplaceUsesWith(other);
// Reuse this instruction's SSA name for other.
ASSERT(!other->HasSSATemp());
if (HasSSATemp()) other->set_ssa_temp_index(ssa_temp_index());
- // Remove this definition's input uses.
- UnuseAllInputs();
- // Finally remove this definition from the graph.
+ // Finally insert the other definition in place of this one in the graph.
previous()->LinkTo(other);
if ((iterator != NULL) && (this == iterator->Current())) {
// Remove through the iterator.
@@ -561,6 +572,8 @@ void Definition::ReplaceWith(Definition* other,
iterator->RemoveCurrentFromGraph();
} else {
other->LinkTo(next());
+ // Remove this definition's input uses.
+ UnuseAllInputs();
}
set_previous(NULL);
set_next(NULL);
@@ -583,23 +596,18 @@ void BranchInstr::RawSetInputAt(intptr_t i, Value* value) {
// A misleadingly named function for use in template functions that replace
// both definitions with definitions and branch comparisons with
// comparisons. In the branch case, leave the branch intact and replace its
-// comparison with another comparison.
+// comparison with a new comparison not currently in the graph.
void BranchInstr::ReplaceWith(ComparisonInstr* other,
ForwardInstructionIterator* ignored) {
- // Record the new comparison's input uses.
- for (intptr_t i = other->InputCount() - 1; i >= 0; --i) {
- Value* input = other->InputAt(i);
- input->definition()->AddInputUse(input);
- }
SetComparison(other);
}
void BranchInstr::SetComparison(ComparisonInstr* comp) {
- // The new comparison's input uses are already recorded in their
- // definition's use lists.
for (intptr_t i = comp->InputCount() - 1; i >= 0; --i) {
- comp->InputAt(i)->set_instruction(this);
+ Value* input = comp->InputAt(i);
+ input->definition()->AddInputUse(input);
+ input->set_instruction(this);
}
// There should be no need to copy or unuse an environment.
ASSERT(comparison()->env() == NULL);
@@ -1174,9 +1182,7 @@ Definition* AssertAssignableInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
// It is ok to insert instructions before the current during
// forward iteration.
optimizer->InsertBefore(this, null_constant, NULL, Definition::kValue);
- instantiator_type_arguments()->RemoveFromUseList();
- instantiator_type_arguments()->set_definition(null_constant);
- null_constant->AddInputUse(instantiator_type_arguments());
+ instantiator_type_arguments()->BindTo(null_constant);
}
return this;
}
@@ -1205,9 +1211,6 @@ Instruction* BranchInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
(comp->input_use_list()->next_use() == NULL) &&
(comp->env_use_list() == NULL)) {
comp->RemoveFromGraph();
- // It is safe to pass a NULL iterator because we're replacing the
- // comparison wrapped in a BranchInstr which does not modify the
- // linked list of instructions.
SetComparison(comp);
if (FLAG_trace_optimization) {
OS::Print("Merging comparison v%"Pd"\n", comp->ssa_temp_index());
@@ -1541,14 +1544,11 @@ void Environment::DeepCopyTo(Instruction* instr) const {
}
Environment* copy = DeepCopy();
- intptr_t use_index = 0;
+ instr->SetEnvironment(copy);
for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) {
Value* value = it.CurrentValue();
- value->set_instruction(instr);
- value->set_use_index(use_index++);
value->definition()->AddEnvUse(value);
}
- instr->set_env(copy);
}
@@ -1560,6 +1560,7 @@ void Environment::DeepCopyToOuter(Instruction* instr) const {
ASSERT(instr->env()->outer() == NULL);
intptr_t argument_count = instr->env()->fixed_parameter_count();
Environment* copy = DeepCopy(values_.length() - argument_count);
+ instr->env()->outer_ = copy;
intptr_t use_index = instr->env()->Length(); // Start index after inner.
for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) {
Value* value = it.CurrentValue();
@@ -1567,7 +1568,6 @@ void Environment::DeepCopyToOuter(Instruction* instr) const {
value->set_use_index(use_index++);
value->definition()->AddEnvUse(value);
}
- instr->env()->outer_ = copy;
}
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698