summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/bounds_check_elimination.h4
-rw-r--r--compiler/optimizing/graph_visualizer.cc2
-rw-r--r--compiler/optimizing/instruction_simplifier.cc72
-rw-r--r--compiler/optimizing/nodes.cc5
-rw-r--r--compiler/optimizing/nodes.h16
5 files changed, 90 insertions, 9 deletions
diff --git a/compiler/optimizing/bounds_check_elimination.h b/compiler/optimizing/bounds_check_elimination.h
index 6dc53207ea..b9df686ffd 100644
--- a/compiler/optimizing/bounds_check_elimination.h
+++ b/compiler/optimizing/bounds_check_elimination.h
@@ -29,13 +29,13 @@ class BoundsCheckElimination : public HOptimization {
BoundsCheckElimination(HGraph* graph,
const SideEffectsAnalysis& side_effects,
HInductionVarAnalysis* induction_analysis)
- : HOptimization(graph, kBoundsCheckEliminationPassName),
+ : HOptimization(graph, kBoundsCheckEliminiationPassName),
side_effects_(side_effects),
induction_analysis_(induction_analysis) {}
void Run() OVERRIDE;
- static constexpr const char* kBoundsCheckEliminationPassName = "BCE";
+ static constexpr const char* kBoundsCheckEliminiationPassName = "BCE";
private:
const SideEffectsAnalysis& side_effects_;
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index 280516252b..32c3a925e0 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -21,7 +21,6 @@
#include <cctype>
#include <sstream>
-#include "bounds_check_elimination.h"
#include "code_generator.h"
#include "dead_code_elimination.h"
#include "disassembler.h"
@@ -506,7 +505,6 @@ class HGraphVisualizerPrinter : public HGraphDelegateVisitor {
if (IsPass(LICM::kLoopInvariantCodeMotionPassName)
|| IsPass(HDeadCodeElimination::kFinalDeadCodeEliminationPassName)
|| IsPass(HDeadCodeElimination::kInitialDeadCodeEliminationPassName)
- || IsPass(BoundsCheckElimination::kBoundsCheckEliminationPassName)
|| IsPass(SsaBuilder::kSsaBuilderPassName)) {
HLoopInformation* info = instruction->GetBlock()->GetLoopInformation();
if (info == nullptr) {
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 49fc8c71b3..d6384d9473 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -66,6 +66,10 @@ class InstructionSimplifierVisitor : public HGraphDelegateVisitor {
void VisitGreaterThanOrEqual(HGreaterThanOrEqual* condition) OVERRIDE;
void VisitLessThan(HLessThan* condition) OVERRIDE;
void VisitLessThanOrEqual(HLessThanOrEqual* condition) OVERRIDE;
+ void VisitBelow(HBelow* condition) OVERRIDE;
+ void VisitBelowOrEqual(HBelowOrEqual* condition) OVERRIDE;
+ void VisitAbove(HAbove* condition) OVERRIDE;
+ void VisitAboveOrEqual(HAboveOrEqual* condition) OVERRIDE;
void VisitDiv(HDiv* instruction) OVERRIDE;
void VisitMul(HMul* instruction) OVERRIDE;
void VisitNeg(HNeg* instruction) OVERRIDE;
@@ -496,6 +500,36 @@ void InstructionSimplifierVisitor::VisitSuspendCheck(HSuspendCheck* check) {
block->RemoveInstruction(check);
}
+static HCondition* GetOppositeConditionSwapOps(ArenaAllocator* arena, HInstruction* cond) {
+ HInstruction *lhs = cond->InputAt(0);
+ HInstruction *rhs = cond->InputAt(1);
+ switch (cond->GetKind()) {
+ case HInstruction::kEqual:
+ return new (arena) HEqual(rhs, lhs);
+ case HInstruction::kNotEqual:
+ return new (arena) HNotEqual(rhs, lhs);
+ case HInstruction::kLessThan:
+ return new (arena) HGreaterThan(rhs, lhs);
+ case HInstruction::kLessThanOrEqual:
+ return new (arena) HGreaterThanOrEqual(rhs, lhs);
+ case HInstruction::kGreaterThan:
+ return new (arena) HLessThan(rhs, lhs);
+ case HInstruction::kGreaterThanOrEqual:
+ return new (arena) HLessThanOrEqual(rhs, lhs);
+ case HInstruction::kBelow:
+ return new (arena) HAbove(rhs, lhs);
+ case HInstruction::kBelowOrEqual:
+ return new (arena) HAboveOrEqual(rhs, lhs);
+ case HInstruction::kAbove:
+ return new (arena) HBelow(rhs, lhs);
+ case HInstruction::kAboveOrEqual:
+ return new (arena) HBelowOrEqual(rhs, lhs);
+ default:
+ LOG(FATAL) << "Unknown ConditionType " << cond->GetKind();
+ }
+ return nullptr;
+}
+
void InstructionSimplifierVisitor::VisitEqual(HEqual* equal) {
HInstruction* input_const = equal->GetConstantRight();
if (input_const != nullptr) {
@@ -758,13 +792,47 @@ void InstructionSimplifierVisitor::VisitLessThanOrEqual(HLessThanOrEqual* condit
VisitCondition(condition);
}
-// TODO: unsigned comparisons too?
+void InstructionSimplifierVisitor::VisitBelow(HBelow* condition) {
+ VisitCondition(condition);
+}
+
+void InstructionSimplifierVisitor::VisitBelowOrEqual(HBelowOrEqual* condition) {
+ VisitCondition(condition);
+}
+
+void InstructionSimplifierVisitor::VisitAbove(HAbove* condition) {
+ VisitCondition(condition);
+}
+
+void InstructionSimplifierVisitor::VisitAboveOrEqual(HAboveOrEqual* condition) {
+ VisitCondition(condition);
+}
void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) {
- // Try to fold an HCompare into this HCondition.
+ // Reverse condition if left is constant. Our code generators prefer constant
+ // on the right hand side.
+ if (condition->GetLeft()->IsConstant() && !condition->GetRight()->IsConstant()) {
+ HBasicBlock* block = condition->GetBlock();
+ HCondition* replacement = GetOppositeConditionSwapOps(block->GetGraph()->GetArena(), condition);
+ // If it is a fp we must set the opposite bias.
+ if (replacement != nullptr) {
+ if (condition->IsLtBias()) {
+ replacement->SetBias(ComparisonBias::kGtBias);
+ } else if (condition->IsGtBias()) {
+ replacement->SetBias(ComparisonBias::kLtBias);
+ }
+ block->ReplaceAndRemoveInstructionWith(condition, replacement);
+ RecordSimplification();
+
+ condition = replacement;
+ }
+ }
HInstruction* left = condition->GetLeft();
HInstruction* right = condition->GetRight();
+
+ // Try to fold an HCompare into this HCondition.
+
// We can only replace an HCondition which compares a Compare to 0.
// Both 'dx' and 'jack' generate a compare to 0 when compiling a
// condition with a long, float or double comparison as input.
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index cb7bc58b0c..2eabadf861 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -2208,7 +2208,10 @@ void HInvoke::SetIntrinsic(Intrinsics intrinsic,
SetSideEffects(GetSideEffects().Union(SideEffects::CanTriggerGC()));
}
// Adjust method's exception status from intrinsic table.
- SetCanThrow(exceptions == kCanThrow);
+ switch (exceptions) {
+ case kNoThrow: SetCanThrow(false); break;
+ case kCanThrow: SetCanThrow(true); break;
+ }
}
bool HNewInstance::IsStringAlloc() const {
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 019be5d494..7067aabaa1 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -2725,6 +2725,8 @@ class HCondition : public HBinaryOperation {
bool IsGtBias() const { return bias_ == ComparisonBias::kGtBias; }
+ bool IsLtBias() const { return bias_ == ComparisonBias::kLtBias; }
+
void SetBias(ComparisonBias bias) { bias_ = bias; }
bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
@@ -2734,13 +2736,23 @@ class HCondition : public HBinaryOperation {
bool IsFPConditionTrueIfNaN() const {
DCHECK(Primitive::IsFloatingPointType(InputAt(0)->GetType()));
IfCondition if_cond = GetCondition();
- return IsGtBias() ? ((if_cond == kCondGT) || (if_cond == kCondGE)) : (if_cond == kCondNE);
+ if (if_cond == kCondNE) {
+ return true;
+ } else if (if_cond == kCondEQ) {
+ return false;
+ }
+ return ((if_cond == kCondGT) || (if_cond == kCondGE)) && IsGtBias();
}
bool IsFPConditionFalseIfNaN() const {
DCHECK(Primitive::IsFloatingPointType(InputAt(0)->GetType()));
IfCondition if_cond = GetCondition();
- return IsGtBias() ? ((if_cond == kCondLT) || (if_cond == kCondLE)) : (if_cond == kCondEQ);
+ if (if_cond == kCondEQ) {
+ return true;
+ } else if (if_cond == kCondNE) {
+ return false;
+ }
+ return ((if_cond == kCondLT) || (if_cond == kCondLE)) && IsGtBias();
}
private: