OSDN Git Service

Constant fold after inlining.
authorNicolas Geoffray <ngeoffray@google.com>
Fri, 16 Jan 2015 12:35:40 +0000 (12:35 +0000)
committerNicolas Geoffray <ngeoffray@google.com>
Mon, 19 Jan 2015 09:29:40 +0000 (09:29 +0000)
- Inlining opens up new opportunities for constant folding.
- Fix a bug in constant folder where the result type was not
  correctly set for the folding of a HCompare.
- Improve graph checker's coverage.

Change-Id: I0943bf8ff65505c4addc4a555a526b55e00b5268

compiler/optimizing/graph_checker.cc
compiler/optimizing/graph_checker.h
compiler/optimizing/nodes.cc
compiler/optimizing/optimizing_compiler.cc

index e55175f..b20d589 100644 (file)
@@ -363,9 +363,29 @@ static Primitive::Type PrimitiveKind(Primitive::Type type) {
   }
 }
 
+void SSAChecker::VisitIf(HIf* instruction) {
+  VisitInstruction(instruction);
+  HInstruction* input = instruction->InputAt(0);
+  if (input->IsIntConstant()) {
+    int value = input->AsIntConstant()->GetValue();
+    if (value != 0 && value != 1) {
+      std::stringstream error;
+      error << "If instruction " << instruction->GetId()
+            << " has a non-boolean constant input whose value is: "
+            << value << ".";
+      errors_.push_back(error.str());
+    }
+  } else if (instruction->InputAt(0)->GetType() != Primitive::kPrimBoolean) {
+    std::stringstream error;
+    error << "If instruction " << instruction->GetId()
+          << " has a non-boolean input type: "
+          << instruction->InputAt(0)->GetType() << ".";
+    errors_.push_back(error.str());
+  }
+}
+
 void SSAChecker::VisitCondition(HCondition* op) {
   VisitInstruction(op);
-  // TODO: check inputs types, and special case the `null` check.
   if (op->GetType() != Primitive::kPrimBoolean) {
     std::stringstream error;
     error << "Condition " << op->DebugName() << " " << op->GetId()
@@ -373,6 +393,34 @@ void SSAChecker::VisitCondition(HCondition* op) {
           << op->GetType() << ".";
     errors_.push_back(error.str());
   }
+  HInstruction* lhs = op->InputAt(0);
+  HInstruction* rhs = op->InputAt(1);
+  if (lhs->GetType() == Primitive::kPrimNot && rhs->IsIntConstant()) {
+    if (rhs->AsIntConstant()->GetValue() != 0) {
+      std::stringstream error;
+      error << "Condition " << op->DebugName() << " " << op->GetId()
+            << " compares an object with a non-0 integer: "
+            << rhs->AsIntConstant()->GetValue()
+            << ".";
+      errors_.push_back(error.str());
+    }
+  } else if (rhs->GetType() == Primitive::kPrimNot && lhs->IsIntConstant()) {
+    if (lhs->AsIntConstant()->GetValue() != 0) {
+      std::stringstream error;
+      error << "Condition " << op->DebugName() << " " << op->GetId()
+            << " compares a non-0 integer with an object: "
+            << lhs->AsIntConstant()->GetValue()
+            << ".";
+      errors_.push_back(error.str());
+    }
+  } else if (PrimitiveKind(lhs->GetType()) != PrimitiveKind(rhs->GetType())) {
+    std::stringstream error;
+    error << "Condition " << op->DebugName() << " " << op->GetId()
+          << " has inputs of different type: "
+          << lhs->GetType() << ", and " << rhs->GetType()
+          << ".";
+    errors_.push_back(error.str());
+  }
 }
 
 void SSAChecker::VisitBinaryOperation(HBinaryOperation* op) {
index ba60cb9..ae1557b 100644 (file)
@@ -101,6 +101,7 @@ class SSAChecker : public GraphChecker {
   void VisitPhi(HPhi* phi) OVERRIDE;
   void VisitBinaryOperation(HBinaryOperation* op) OVERRIDE;
   void VisitCondition(HCondition* op) OVERRIDE;
+  void VisitIf(HIf* instruction) OVERRIDE;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(SSAChecker);
index 4133cf6..ade3138 100644 (file)
@@ -643,7 +643,12 @@ HConstant* HBinaryOperation::TryStaticEvaluation() const {
   } else if (GetLeft()->IsLongConstant() && GetRight()->IsLongConstant()) {
     int64_t value = Evaluate(GetLeft()->AsLongConstant()->GetValue(),
                              GetRight()->AsLongConstant()->GetValue());
-    return new(GetBlock()->GetGraph()->GetArena()) HLongConstant(value);
+    if (GetResultType() == Primitive::kPrimLong) {
+      return new(GetBlock()->GetGraph()->GetArena()) HLongConstant(value);
+    } else {
+      DCHECK(GetResultType() == Primitive::kPrimInt);
+      return new(GetBlock()->GetGraph()->GetArena()) HIntConstant(value);
+    }
   }
   return nullptr;
 }
index 6056373..ad48198 100644 (file)
@@ -208,11 +208,12 @@ static void RunOptimizations(HGraph* graph,
   SsaRedundantPhiElimination redundant_phi(graph);
   SsaDeadPhiElimination dead_phi(graph);
   HDeadCodeElimination dce(graph);
-  HConstantFolding fold(graph);
+  HConstantFolding fold1(graph);
   InstructionSimplifier simplify1(graph);
 
   HInliner inliner(graph, dex_compilation_unit, driver, stats);
 
+  HConstantFolding fold2(graph);
   GVNOptimization gvn(graph);
   BoundsCheckElimination bce(graph);
   InstructionSimplifier simplify2(graph);
@@ -224,9 +225,10 @@ static void RunOptimizations(HGraph* graph,
     &dead_phi,
     &intrinsics,
     &dce,
-    &fold,
+    &fold1,
     &simplify1,
     &inliner,
+    &fold2,
     &gvn,
     &bce,
     &simplify2