Opt compiler: Basic simplification for arithmetic operations.

The optimisations in this patch do not look further than the
inputs of each operation.

Change-Id: Iddd0ab6b360b9e7bb042db22086d51a31be85530
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index d4498a6..c4f6f6d 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -1569,6 +1569,14 @@
   virtual int32_t Evaluate(int32_t x, int32_t y) const = 0;
   virtual int64_t Evaluate(int64_t x, int64_t y) const = 0;
 
+  // Returns an input that can legally be used as the right input and is
+  // constant, or nullptr.
+  HConstant* GetConstantRight() const;
+
+  // If `GetConstantRight()` returns one of the input, this returns the other
+  // one. Otherwise it returns nullptr.
+  HInstruction* GetLeastConstantLeft() const;
+
   DECLARE_INSTRUCTION(BinaryOperation);
 
  private:
@@ -1840,6 +1848,12 @@
 
   bool CanBeMoved() const OVERRIDE { return true; }
 
+  virtual bool IsMinusOne() const { return false; }
+  virtual bool IsZero() const { return false; }
+  virtual bool IsOne() const { return false; }
+
+  static HConstant* NewConstant(ArenaAllocator* allocator, Primitive::Type type, int64_t val);
+
   DECLARE_INSTRUCTION(Constant);
 
  private:
@@ -1859,6 +1873,16 @@
 
   size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); }
 
+  bool IsMinusOne() const OVERRIDE {
+    return bit_cast<uint32_t>(AsFloatConstant()->GetValue()) == bit_cast<uint32_t>((-1.0f));
+  }
+  bool IsZero() const OVERRIDE {
+    return AsFloatConstant()->GetValue() == 0.0f;
+  }
+  bool IsOne() const OVERRIDE {
+    return bit_cast<uint32_t>(AsFloatConstant()->GetValue()) == bit_cast<uint32_t>(1.0f);
+  }
+
   DECLARE_INSTRUCTION(FloatConstant);
 
  private:
@@ -1880,6 +1904,16 @@
 
   size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); }
 
+  bool IsMinusOne() const OVERRIDE {
+    return bit_cast<uint64_t>(AsDoubleConstant()->GetValue()) == bit_cast<uint64_t>((-1.0));
+  }
+  bool IsZero() const OVERRIDE {
+    return AsDoubleConstant()->GetValue() == 0.0;
+  }
+  bool IsOne() const OVERRIDE {
+    return bit_cast<uint64_t>(AsDoubleConstant()->GetValue()) == bit_cast<uint64_t>(1.0);
+  }
+
   DECLARE_INSTRUCTION(DoubleConstant);
 
  private:
@@ -1925,6 +1959,10 @@
   // method is an workaround until we fix the above.
   bool ActAsNullConstant() const OVERRIDE { return value_ == 0; }
 
+  bool IsMinusOne() const OVERRIDE { return GetValue() == -1; }
+  bool IsZero() const OVERRIDE { return GetValue() == 0; }
+  bool IsOne() const OVERRIDE { return GetValue() == 1; }
+
   DECLARE_INSTRUCTION(IntConstant);
 
  private:
@@ -1945,6 +1983,10 @@
 
   size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); }
 
+  bool IsMinusOne() const OVERRIDE { return GetValue() == -1; }
+  bool IsZero() const OVERRIDE { return GetValue() == 0; }
+  bool IsOne() const OVERRIDE { return GetValue() == 1; }
+
   DECLARE_INSTRUCTION(LongConstant);
 
  private:
@@ -3473,6 +3515,12 @@
   DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopIterator);
 };
 
+inline int64_t Int64FromConstant(HConstant* constant) {
+  DCHECK(constant->IsIntConstant() || constant->IsLongConstant());
+  return constant->IsIntConstant() ? constant->AsIntConstant()->GetValue()
+                                   : constant->AsLongConstant()->GetValue();
+}
+
 }  // namespace art
 
 #endif  // ART_COMPILER_OPTIMIZING_NODES_H_