Revert "Revert "Optimize code generation of check-cast and instance-of.""

This reverts commit 7537437c6a2f89249a48e30effcc27d4e7c5a04f.

Change-Id: If759cb08646e47b62829bebc3c5b1e2f2969cf84
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 3c57180..8dd31be 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -4719,16 +4719,29 @@
   DISALLOW_COPY_AND_ASSIGN(HThrow);
 };
 
+/**
+ * Implementation strategies for the code generator of a HInstanceOf
+ * or `HCheckCast`.
+ */
+enum class TypeCheckKind {
+  kExactCheck,            // Can do a single class compare.
+  kClassHierarchyCheck,   // Can just walk the super class chain.
+  kAbstractClassCheck,    // Can just walk the super class chain, starting one up.
+  kInterfaceCheck,        // No optimization yet when checking against an interface.
+  kArrayObjectCheck,      // Can just check if the array is not primitive.
+  kArrayCheck             // No optimization yet when checking against a generic array.
+};
+
 class HInstanceOf : public HExpression<2> {
  public:
   HInstanceOf(HInstruction* object,
               HLoadClass* constant,
-              bool class_is_final,
+              TypeCheckKind check_kind,
               uint32_t dex_pc)
       : HExpression(Primitive::kPrimBoolean,
-                    SideEffectsForArchRuntimeCalls(class_is_final),
+                    SideEffectsForArchRuntimeCalls(check_kind),
                     dex_pc),
-        class_is_final_(class_is_final),
+        check_kind_(check_kind),
         must_do_null_check_(true) {
     SetRawInputAt(0, object);
     SetRawInputAt(1, constant);
@@ -4744,20 +4757,25 @@
     return false;
   }
 
-  bool IsClassFinal() const { return class_is_final_; }
+  bool IsExactCheck() const { return check_kind_ == TypeCheckKind::kExactCheck; }
+
+  TypeCheckKind GetTypeCheckKind() const { return check_kind_; }
 
   // Used only in code generation.
   bool MustDoNullCheck() const { return must_do_null_check_; }
   void ClearMustDoNullCheck() { must_do_null_check_ = false; }
 
-  static SideEffects SideEffectsForArchRuntimeCalls(bool class_is_final) {
-    return class_is_final ? SideEffects::None() : SideEffects::CanTriggerGC();
+  static SideEffects SideEffectsForArchRuntimeCalls(TypeCheckKind check_kind) {
+    return (check_kind == TypeCheckKind::kExactCheck)
+        ? SideEffects::None()
+        // Mips currently does runtime calls for any other checks.
+        : SideEffects::CanTriggerGC();
   }
 
   DECLARE_INSTRUCTION(InstanceOf);
 
  private:
-  const bool class_is_final_;
+  const TypeCheckKind check_kind_;
   bool must_do_null_check_;
 
   DISALLOW_COPY_AND_ASSIGN(HInstanceOf);
@@ -4813,10 +4831,10 @@
  public:
   HCheckCast(HInstruction* object,
              HLoadClass* constant,
-             bool class_is_final,
+             TypeCheckKind check_kind,
              uint32_t dex_pc)
       : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc),
-        class_is_final_(class_is_final),
+        check_kind_(check_kind),
         must_do_null_check_(true) {
     SetRawInputAt(0, object);
     SetRawInputAt(1, constant);
@@ -4837,14 +4855,14 @@
 
   bool MustDoNullCheck() const { return must_do_null_check_; }
   void ClearMustDoNullCheck() { must_do_null_check_ = false; }
+  TypeCheckKind GetTypeCheckKind() const { return check_kind_; }
 
-
-  bool IsClassFinal() const { return class_is_final_; }
+  bool IsExactCheck() const { return check_kind_ == TypeCheckKind::kExactCheck; }
 
   DECLARE_INSTRUCTION(CheckCast);
 
  private:
-  const bool class_is_final_;
+  const TypeCheckKind check_kind_;
   bool must_do_null_check_;
 
   DISALLOW_COPY_AND_ASSIGN(HCheckCast);