ART: Make GVN work with BoundType.

Support BoundType instruction treatment in GVN.
Note: BoundType must not be a subject to LICM as it must not be
moved from more control dependent basic blocks to less control
dependent (e.g. hoisted out from the loop) due to semantics of
bounding the type.

Test: 477-checker-bound-type.
Test: test-art-target, test-art-host.

Change-Id: I64263d6ec7d9ad75d1fb07d3a89e9973be67682b
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index ef8a757..661f66a 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -2786,6 +2786,14 @@
   SetPackedFlag<kFlagReferenceTypeIsExact>(rti.IsExact());
 }
 
+bool HBoundType::InstructionDataEquals(const HInstruction* other) const {
+  const HBoundType* other_bt = other->AsBoundType();
+  ScopedObjectAccess soa(Thread::Current());
+  return GetUpperBound().IsEqual(other_bt->GetUpperBound()) &&
+         GetUpperCanBeNull() == other_bt->GetUpperCanBeNull() &&
+         CanBeNull() == other_bt->CanBeNull();
+}
+
 void HBoundType::SetUpperBound(const ReferenceTypeInfo& upper_bound, bool can_be_null) {
   if (kIsDebugBuild) {
     ScopedObjectAccess soa(Thread::Current());