Add support for intrinsic optimizations.

Change-Id: Ib5a4224022f9360e60c09a19ac8642270a7f3b64
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 3287a0a..973bfbb 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -16,15 +16,16 @@
 
 #include "instruction_simplifier.h"
 
+#include "intrinsics.h"
 #include "mirror/class-inl.h"
 #include "scoped_thread_state_change.h"
 
 namespace art {
 
-class InstructionSimplifierVisitor : public HGraphVisitor {
+class InstructionSimplifierVisitor : public HGraphDelegateVisitor {
  public:
   InstructionSimplifierVisitor(HGraph* graph, OptimizingCompilerStats* stats)
-      : HGraphVisitor(graph),
+      : HGraphDelegateVisitor(graph),
         stats_(stats) {}
 
   void Run();
@@ -71,6 +72,7 @@
   void VisitXor(HXor* instruction) OVERRIDE;
   void VisitInstanceOf(HInstanceOf* instruction) OVERRIDE;
   void VisitFakeString(HFakeString* fake_string) OVERRIDE;
+  void VisitInvoke(HInvoke* invoke) OVERRIDE;
 
   bool CanEnsureNotNullAt(HInstruction* instr, HInstruction* at) const;
 
@@ -1033,4 +1035,29 @@
   instruction->GetBlock()->RemoveInstruction(instruction);
 }
 
+void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
+  if (instruction->GetIntrinsic() == Intrinsics::kStringEquals) {
+    HInstruction* argument = instruction->InputAt(1);
+    HInstruction* receiver = instruction->InputAt(0);
+    if (receiver == argument) {
+      // Because String.equals is an instance call, the receiver is
+      // a null check if we don't know it's null. The argument however, will
+      // be the actual object. So we cannot end up in a situation where both
+      // are equal but could be null.
+      DCHECK(CanEnsureNotNullAt(argument, instruction));
+      instruction->ReplaceWith(GetGraph()->GetIntConstant(1));
+      instruction->GetBlock()->RemoveInstruction(instruction);
+    } else {
+      StringEqualsOptimizations optimizations(instruction);
+      if (CanEnsureNotNullAt(argument, instruction)) {
+        optimizations.SetArgumentNotNull();
+      }
+      ScopedObjectAccess soa(Thread::Current());
+      if (argument->GetReferenceTypeInfo().IsStringClass()) {
+        optimizations.SetArgumentIsString();
+      }
+    }
+  }
+}
+
 }  // namespace art