summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Treehugger Robot <treehugger-gerrit@google.com> 2017-12-13 11:06:54 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2017-12-13 11:06:54 +0000
commit03376f4c4de8e419402bf40fdff4135728ffb21e (patch)
tree5d55cc893e2c445f6d181830bd6ae446010fbf8f /compiler/optimizing
parent3f74ea478d755453a2fe5789ce155e80be3e7c7f (diff)
parent1de1e11ac90db9fad8916ac43d43714ccb8d978f (diff)
Merge "ART: Try to statically evaluate some conditions."
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/instruction_simplifier.cc21
-rw-r--r--compiler/optimizing/nodes.cc14
-rw-r--r--compiler/optimizing/nodes.h16
3 files changed, 44 insertions, 7 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index a42a85dc1d..53e449bbbe 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -994,6 +994,27 @@ void InstructionSimplifierVisitor::VisitIf(HIf* instruction) {
instruction->GetBlock()->SwapSuccessors();
RecordSimplification();
}
+ HInstruction* input = instruction->InputAt(0);
+
+ // If a condition 'cond' is evaluated in an HIf instruction then in the successors of the
+ // IF_BLOCK we statically know the value of the condition (TRUE in TRUE_SUCC, FALSE in
+ // FALSE_SUCC). Using that we can replace another evaluation (use) EVAL of the same 'cond'
+ // with TRUE value (FALSE value) if every path from the ENTRY_BLOCK to EVAL_BLOCK contains the
+ // edge HIF_BLOCK->TRUE_SUCC (HIF_BLOCK->FALSE_SUCC).
+ if (!input->IsConstant()) {
+ HBasicBlock* true_succ = instruction->IfTrueSuccessor();
+ HBasicBlock* false_succ = instruction->IfFalseSuccessor();
+
+ DCHECK_EQ(true_succ->GetPredecessors().size(), 1u);
+ input->ReplaceUsesDominatedBy(
+ true_succ->GetFirstInstruction(), GetGraph()->GetIntConstant(1), /* strictly */ false);
+ RecordSimplification();
+
+ DCHECK_EQ(false_succ->GetPredecessors().size(), 1u);
+ input->ReplaceUsesDominatedBy(
+ false_succ->GetFirstInstruction(), GetGraph()->GetIntConstant(0), /* strictly */ false);
+ RecordSimplification();
+ }
}
void InstructionSimplifierVisitor::VisitArrayLength(HArrayLength* instruction) {
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 5f33ed6303..d39c2aded5 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -1111,10 +1111,10 @@ bool HInstructionList::FoundBefore(const HInstruction* instruction1,
return true;
}
-bool HInstruction::StrictlyDominates(HInstruction* other_instruction) const {
+bool HInstruction::Dominates(HInstruction* other_instruction, bool strictly) const {
if (other_instruction == this) {
// An instruction does not strictly dominate itself.
- return false;
+ return !strictly;
}
HBasicBlock* block = GetBlock();
HBasicBlock* other_block = other_instruction->GetBlock();
@@ -1148,6 +1148,10 @@ bool HInstruction::StrictlyDominates(HInstruction* other_instruction) const {
}
}
+bool HInstruction::StrictlyDominates(HInstruction* other_instruction) const {
+ return Dominates(other_instruction, /* strictly */ true);
+}
+
void HInstruction::RemoveEnvironment() {
RemoveEnvironmentUses(this);
environment_ = nullptr;
@@ -1170,14 +1174,16 @@ 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) {
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)) {
+ if (dominator->Dominates(user, strictly)) {
user->ReplaceInput(replacement, index);
}
}
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 42a9d95b9a..affd54ed72 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -2098,9 +2098,13 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {
return IsRemovable() && !HasUses();
}
- // Does this instruction strictly dominate `other_instruction`?
- // Returns false if this instruction and `other_instruction` are the same.
+ // Does this instruction dominate (strictly or in regular sense depending on 'strictly')
+ // `other_instruction`?
+ // Returns '!strictly' if this instruction and `other_instruction` are the same.
// Aborts if this instruction and `other_instruction` are both phis.
+ bool Dominates(HInstruction* other_instruction, bool strictly) const;
+
+ // Return 'Dominates(other_instruction, /*strictly*/ true)'.
bool StrictlyDominates(HInstruction* other_instruction) const;
int GetId() const { return id_; }
@@ -2161,7 +2165,13 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {
void SetLocations(LocationSummary* locations) { locations_ = locations; }
void ReplaceWith(HInstruction* instruction);
- void ReplaceUsesDominatedBy(HInstruction* dominator, HInstruction* replacement);
+
+ // Replace all uses of the instruction which are dominated by 'dominator' with 'replacement'.
+ // 'strictly' determines whether strict or regular domination relation should be checked.
+ void ReplaceUsesDominatedBy(HInstruction* dominator,
+ HInstruction* replacement,
+ bool strictly = true);
+
void ReplaceInput(HInstruction* replacement, size_t index);
// This is almost the same as doing `ReplaceWith()`. But in this helper, the