diff options
author | 2022-07-22 15:21:29 +0100 | |
---|---|---|
committer | 2022-08-09 09:44:21 +0000 | |
commit | c6b816ceb2b35300c937ef2e7d008598b6afba21 (patch) | |
tree | 9bb081881ddd8e237521c9513c7ce6160fa6db11 /compiler/optimizing/nodes.cc | |
parent | e6d405470c12c4dfd5f7757e9e951751a23622d3 (diff) |
Propagating values from if clauses to its successors
We have knowledge of the value of some variables at compile time due
to the fact they are used in if clauses. For example:
if (variable == constant) {
// SSA `variable` guaranteed to be equal to constant here.
} else {
// No guarantees can be made here (except for booleans since
// they only have two values).
}
Similarly with `variable != constant`.
We can also apply this to boolean parameters e.g.
void foo (boolean val) {
if (val) {
// `val` guaranteed to be true here.
...
}
...
}
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: I55df0252d672870993d06e5ac92f5bba44d902bd
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r-- | compiler/optimizing/nodes.cc | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 6ac4e07ca7..4fbb033c2f 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -1477,6 +1477,10 @@ bool HInstructionList::FoundBefore(const HInstruction* instruction1, UNREACHABLE(); } +bool HInstruction::Dominates(HInstruction* other_instruction) const { + return other_instruction == this || StrictlyDominates(other_instruction); +} + bool HInstruction::StrictlyDominates(HInstruction* other_instruction) const { if (other_instruction == this) { // An instruction does not strictly dominate itself. @@ -1536,14 +1540,19 @@ void HInstruction::ReplaceWith(HInstruction* other) { DCHECK(env_uses_.empty()); } -void HInstruction::ReplaceUsesDominatedBy(HInstruction* dominator, HInstruction* replacement) { +void HInstruction::ReplaceUsesDominatedBy(HInstruction* dominator, + HInstruction* replacement, + bool strictly_dominated) { const HUseList<HInstruction*>& uses = GetUses(); for (auto it = uses.begin(), end = uses.end(); it != end; /* ++it below */) { HInstruction* user = it->GetUser(); size_t index = it->GetIndex(); // Increment `it` now because `*it` may disappear thanks to user->ReplaceInput(). ++it; - if (dominator->StrictlyDominates(user)) { + const bool dominated = + strictly_dominated ? dominator->StrictlyDominates(user) : dominator->Dominates(user); + + if (dominated) { user->ReplaceInput(replacement, index); } else if (user->IsPhi() && !user->AsPhi()->IsCatchPhi()) { // If the input flows from a block dominated by `dominator`, we can replace it. |