summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_simplifier.cc
diff options
context:
space:
mode:
author Aart Bik <ajcbik@google.com> 2016-11-03 00:05:51 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2016-11-03 00:05:51 +0000
commitc4005c3e71e98edd4a5a91c75dbee3d97b7dcda1 (patch)
tree4f4b9212ec7cd16e8f972913eebe2a08ff037dd3 /compiler/optimizing/instruction_simplifier.cc
parent3e9e3a3761bd3d9f4a9ea6a49b2707abba702f22 (diff)
parent2767f4ba2df934fea4c50a016e2955c2cf3f6b19 (diff)
Merge "New instruction simplifications. Extra dce pass. Allow more per block repeats."
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r--compiler/optimizing/instruction_simplifier.cc26
1 files changed, 21 insertions, 5 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index e4d280f26d..e06fdee370 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -111,9 +111,11 @@ class InstructionSimplifierVisitor : public HGraphDelegateVisitor {
OptimizingCompilerStats* stats_;
bool simplification_occurred_ = false;
int simplifications_at_current_position_ = 0;
- // We ensure we do not loop infinitely. The value is a finger in the air guess
- // that should allow enough simplification.
- static constexpr int kMaxSamePositionSimplifications = 10;
+ // We ensure we do not loop infinitely. The value should not be too high, since that
+ // would allow looping around the same basic block too many times. The value should
+ // not be too low either, however, since we want to allow revisiting a basic block
+ // with many statements and simplifications at least once.
+ static constexpr int kMaxSamePositionSimplifications = 50;
};
void InstructionSimplifier::Run() {
@@ -605,11 +607,23 @@ static HCondition* GetOppositeConditionSwapOps(ArenaAllocator* arena, HInstructi
return nullptr;
}
+static bool CmpHasBoolType(HInstruction* input, HInstruction* cmp) {
+ if (input->GetType() == Primitive::kPrimBoolean) {
+ return true; // input has direct boolean type
+ } else if (cmp->GetUses().HasExactlyOneElement()) {
+ // Comparison also has boolean type if both its input and the instruction
+ // itself feed into the same phi node.
+ HInstruction* user = cmp->GetUses().front().GetUser();
+ return user->IsPhi() && user->HasInput(input) && user->HasInput(cmp);
+ }
+ return false;
+}
+
void InstructionSimplifierVisitor::VisitEqual(HEqual* equal) {
HInstruction* input_const = equal->GetConstantRight();
if (input_const != nullptr) {
HInstruction* input_value = equal->GetLeastConstantLeft();
- if (input_value->GetType() == Primitive::kPrimBoolean && input_const->IsIntConstant()) {
+ if (CmpHasBoolType(input_value, equal) && input_const->IsIntConstant()) {
HBasicBlock* block = equal->GetBlock();
// We are comparing the boolean to a constant which is of type int and can
// be any constant.
@@ -619,6 +633,7 @@ void InstructionSimplifierVisitor::VisitEqual(HEqual* equal) {
block->RemoveInstruction(equal);
RecordSimplification();
} else if (input_const->AsIntConstant()->IsFalse()) {
+ // Replace (bool_value == false) with !bool_value
equal->ReplaceWith(GetGraph()->InsertOppositeCondition(input_value, equal));
block->RemoveInstruction(equal);
RecordSimplification();
@@ -640,11 +655,12 @@ void InstructionSimplifierVisitor::VisitNotEqual(HNotEqual* not_equal) {
HInstruction* input_const = not_equal->GetConstantRight();
if (input_const != nullptr) {
HInstruction* input_value = not_equal->GetLeastConstantLeft();
- if (input_value->GetType() == Primitive::kPrimBoolean && input_const->IsIntConstant()) {
+ if (CmpHasBoolType(input_value, not_equal) && input_const->IsIntConstant()) {
HBasicBlock* block = not_equal->GetBlock();
// We are comparing the boolean to a constant which is of type int and can
// be any constant.
if (input_const->AsIntConstant()->IsTrue()) {
+ // Replace (bool_value != true) with !bool_value
not_equal->ReplaceWith(GetGraph()->InsertOppositeCondition(input_value, not_equal));
block->RemoveInstruction(not_equal);
RecordSimplification();