Skip to content

Commit 150e8f8

Browse files
aartbikcommit-bot@chromium.org
authored andcommitted
[dart/vm] Fix dominance violation
Rationale: The flow graph checker still had a few ugly exceptions due to dominance violation after inlining. This CL fixes the violation, removes the exceptions from the flow graph checker, and also adds a new utility that can be used in some other places. dart-lang#36899 Change-Id: I42766af22a3696fe050b0e5c4a2dfe930933fc40 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/111502 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Aart Bik <[email protected]>
1 parent 0855321 commit 150e8f8

File tree

6 files changed

+28
-29
lines changed

6 files changed

+28
-29
lines changed

runtime/vm/compiler/backend/branch_optimizer.cc

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,8 @@ void BranchSimplifier::Simplify(FlowGraph* flow_graph) {
169169
new_branch->comparison()->SetDeoptId(*comparison);
170170
// The phi can be used in the branch's environment. Rename such
171171
// uses.
172-
for (Environment::DeepIterator it(new_branch->env()); !it.Done();
173-
it.Advance()) {
174-
Value* use = it.CurrentValue();
175-
if (use->definition() == phi) {
176-
Definition* replacement = phi->InputAt(i)->definition();
177-
use->RemoveFromUseList();
178-
use->set_definition(replacement);
179-
replacement->AddEnvUse(use);
180-
}
181-
}
172+
Definition* replacement = phi->InputAt(i)->definition();
173+
new_branch->ReplaceInEnvironment(phi, replacement);
182174
}
183175

184176
new_branch->InsertBefore(old_goto);

runtime/vm/compiler/backend/flow_graph_checker.cc

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ void FlowGraphChecker::VisitInstruction(Instruction* instruction) {
226226
for (intptr_t i = 0, n = instruction->InputCount(); i < n; ++i) {
227227
VisitUseDef(instruction, instruction->InputAt(i), i, /*is_env*/ false);
228228
}
229-
// Check all environment inputs.
229+
// Check all environment inputs (including outer ones).
230230
intptr_t i = 0;
231231
for (Environment::DeepIterator it(instruction->env()); !it.Done();
232232
it.Advance()) {
@@ -271,14 +271,15 @@ void FlowGraphChecker::VisitUseDef(Instruction* instruction,
271271
// Make sure each input is properly defined in the graph by something
272272
// that dominates the input (note that the proper dominance relation
273273
// on the input values of Phis is checked by the Phi visitor below).
274-
bool test_def = def->HasSSATemp();
275274
if (def->IsPhi()) {
276275
ASSERT(def->GetBlock()->IsJoinEntry());
277276
// Phis are never linked into graph.
278277
ASSERT(def->next() == nullptr);
279278
ASSERT(def->previous() == nullptr);
280279
} else if (def->IsConstant() || def->IsParameter() ||
281280
def->IsSpecialParameter()) {
281+
// Special constants reside outside the IR.
282+
if (IsSpecialConstant(def)) return;
282283
// Initial definitions are partially linked into graph, but some
283284
// constants are fully linked into graph (so no next() assert).
284285
ASSERT(def->previous() != nullptr);
@@ -287,14 +288,10 @@ void FlowGraphChecker::VisitUseDef(Instruction* instruction,
287288
ASSERT(def->next() != nullptr);
288289
ASSERT(def->previous() != nullptr);
289290
}
290-
if (test_def) {
291-
ASSERT(is_env || // TODO(dartbug.com/36899)
292-
DefDominatesUse(def, instruction));
293-
if (is_env) {
294-
ASSERT(IsInUseList(def->env_use_list(), instruction));
295-
} else {
296-
ASSERT(IsInUseList(def->input_use_list(), instruction));
297-
}
291+
if (def->HasSSATemp()) {
292+
ASSERT(DefDominatesUse(def, instruction));
293+
ASSERT(IsInUseList(is_env ? def->env_use_list() : def->input_use_list(),
294+
instruction));
298295
}
299296
}
300297

runtime/vm/compiler/backend/il.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,18 @@ void Instruction::RemoveEnvironment() {
11721172
env_ = NULL;
11731173
}
11741174

1175+
void Instruction::ReplaceInEnvironment(Definition* current,
1176+
Definition* replacement) {
1177+
for (Environment::DeepIterator it(env()); !it.Done(); it.Advance()) {
1178+
Value* use = it.CurrentValue();
1179+
if (use->definition() == current) {
1180+
use->RemoveFromUseList();
1181+
use->set_definition(replacement);
1182+
replacement->AddEnvUse(use);
1183+
}
1184+
}
1185+
}
1186+
11751187
Instruction* Instruction::RemoveFromGraph(bool return_previous) {
11761188
ASSERT(!IsBlockEntry());
11771189
ASSERT(!IsBranch());

runtime/vm/compiler/backend/il.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,7 @@ class Instruction : public ZoneAllocated {
830830
Environment* env() const { return env_; }
831831
void SetEnvironment(Environment* deopt_env);
832832
void RemoveEnvironment();
833+
void ReplaceInEnvironment(Definition* current, Definition* replacement);
833834

834835
intptr_t lifetime_position() const { return lifetime_position_; }
835836
void set_lifetime_position(intptr_t pos) { lifetime_position_ = pos; }

runtime/vm/compiler/backend/inliner.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,11 @@ static void ReplaceParameterStubs(Zone* zone,
635635
}
636636
redefinition->InsertAfter(callee_entry);
637637
defn = redefinition;
638+
// Since the redefinition does not dominate the callee entry, replace
639+
// uses of the receiver argument in this entry with the redefined value.
640+
callee_entry->ReplaceInEnvironment(
641+
call_data->parameter_stubs->At(first_arg_stub_index + i),
642+
actual->definition());
638643
} else if (actual != NULL) {
639644
defn = actual->definition();
640645
}

runtime/vm/compiler/backend/redundancy_elimination.cc

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3128,15 +3128,7 @@ void AllocationSinking::CreateMaterializationAt(
31283128
// MaterializeObject instruction.
31293129
// We must preserve the identity: all mentions are replaced by the same
31303130
// materialization.
3131-
for (Environment::DeepIterator env_it(exit->env()); !env_it.Done();
3132-
env_it.Advance()) {
3133-
Value* use = env_it.CurrentValue();
3134-
if (use->definition() == alloc) {
3135-
use->RemoveFromUseList();
3136-
use->set_definition(mat);
3137-
mat->AddEnvUse(use);
3138-
}
3139-
}
3131+
exit->ReplaceInEnvironment(alloc, mat);
31403132

31413133
// Mark MaterializeObject as an environment use of this allocation.
31423134
// This will allow us to discover it when we are looking for deoptimization

0 commit comments

Comments
 (0)