Have constant folding be more flexible.

- Have Evaluate methods take as argument(s) and return value
  instances of HConstant (instead of built-in 32- or 64-bit
  integer values), to let the evaluated instruction choose
  the type of the statically evaluated node; for instance,
  art::HEqual::Evaluate shall return a HIntConstant
  node (as implementation of a Boolean constant) whatever
  the type of its inputs (a pair of HIntConstant or a pair
  of HLongConstant).
- Split the evaluation job from the operation logic: the
  former is addressed by Evaluate methods, while the latter
  is done by a generic Compute method.
- Adress valid BinOp(int, long) and BinOp(long, int) cases.
- Add a constructor to art::HIntConstant to build an integer
  constant from a `bool` value.

Change-Id: If84b6fe8406bb94ddb1aa8b02e36628dff526db3
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index efaf48c..32ec85a 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -1005,31 +1005,25 @@
 
 HConstant* HUnaryOperation::TryStaticEvaluation() const {
   if (GetInput()->IsIntConstant()) {
-    int32_t value = Evaluate(GetInput()->AsIntConstant()->GetValue());
-    return GetBlock()->GetGraph()->GetIntConstant(value);
+    return Evaluate(GetInput()->AsIntConstant());
   } else if (GetInput()->IsLongConstant()) {
-    int64_t value = Evaluate(GetInput()->AsLongConstant()->GetValue());
-    return GetBlock()->GetGraph()->GetLongConstant(value);
+    return Evaluate(GetInput()->AsLongConstant());
   }
   return nullptr;
 }
 
 HConstant* HBinaryOperation::TryStaticEvaluation() const {
-  if (GetLeft()->IsIntConstant() && GetRight()->IsIntConstant()) {
-    int32_t value = Evaluate(GetLeft()->AsIntConstant()->GetValue(),
-                             GetRight()->AsIntConstant()->GetValue());
-    return GetBlock()->GetGraph()->GetIntConstant(value);
-  } else if (GetLeft()->IsLongConstant() && GetRight()->IsLongConstant()) {
-    int64_t value = Evaluate(GetLeft()->AsLongConstant()->GetValue(),
-                             GetRight()->AsLongConstant()->GetValue());
-    if (GetResultType() == Primitive::kPrimLong) {
-      return GetBlock()->GetGraph()->GetLongConstant(value);
-    } else if (GetResultType() == Primitive::kPrimBoolean) {
-      // This can be the result of an HCondition evaluation.
-      return GetBlock()->GetGraph()->GetIntConstant(static_cast<int32_t>(value));
-    } else {
-      DCHECK_EQ(GetResultType(), Primitive::kPrimInt);
-      return GetBlock()->GetGraph()->GetIntConstant(static_cast<int32_t>(value));
+  if (GetLeft()->IsIntConstant()) {
+    if (GetRight()->IsIntConstant()) {
+      return Evaluate(GetLeft()->AsIntConstant(), GetRight()->AsIntConstant());
+    } else if (GetRight()->IsLongConstant()) {
+      return Evaluate(GetLeft()->AsIntConstant(), GetRight()->AsLongConstant());
+    }
+  } else if (GetLeft()->IsLongConstant()) {
+    if (GetRight()->IsIntConstant()) {
+      return Evaluate(GetLeft()->AsLongConstant(), GetRight()->AsIntConstant());
+    } else if (GetRight()->IsLongConstant()) {
+      return Evaluate(GetLeft()->AsLongConstant(), GetRight()->AsLongConstant());
     }
   }
   return nullptr;