load store elimination.

This adds a pass to eliminate some unnecessary heap loads/stores. It
first collects heap locations and then tracks values stored to those heap
locations. Alias analysis is done based on offset, type, singleton,
pre-existence, etc.

Change-Id: I11a9d8ef20d1b2f245607eb25118e9aff9be472a
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 0d668e8..4f4648d 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -75,6 +75,7 @@
 static constexpr uint64_t kMaxLongShiftValue = 0x3f;
 
 static constexpr uint32_t kUnknownFieldIndex = static_cast<uint32_t>(-1);
+static constexpr uint16_t kUnknownClassDefIndex = static_cast<uint16_t>(-1);
 
 static constexpr InvokeType kInvalidInvokeType = static_cast<InvokeType>(-1);
 
@@ -4181,18 +4182,21 @@
             Primitive::Type field_type,
             bool is_volatile,
             uint32_t index,
+            uint16_t declaring_class_def_index,
             const DexFile& dex_file,
             Handle<mirror::DexCache> dex_cache)
       : field_offset_(field_offset),
         field_type_(field_type),
         is_volatile_(is_volatile),
         index_(index),
+        declaring_class_def_index_(declaring_class_def_index),
         dex_file_(dex_file),
         dex_cache_(dex_cache) {}
 
   MemberOffset GetFieldOffset() const { return field_offset_; }
   Primitive::Type GetFieldType() const { return field_type_; }
   uint32_t GetFieldIndex() const { return index_; }
+  uint16_t GetDeclaringClassDefIndex() const { return declaring_class_def_index_;}
   const DexFile& GetDexFile() const { return dex_file_; }
   bool IsVolatile() const { return is_volatile_; }
   Handle<mirror::DexCache> GetDexCache() const { return dex_cache_; }
@@ -4202,6 +4206,7 @@
   const Primitive::Type field_type_;
   const bool is_volatile_;
   const uint32_t index_;
+  const uint16_t declaring_class_def_index_;
   const DexFile& dex_file_;
   const Handle<mirror::DexCache> dex_cache_;
 };
@@ -4213,13 +4218,20 @@
                     MemberOffset field_offset,
                     bool is_volatile,
                     uint32_t field_idx,
+                    uint16_t declaring_class_def_index,
                     const DexFile& dex_file,
                     Handle<mirror::DexCache> dex_cache,
                     uint32_t dex_pc)
-      : HExpression(
-            field_type,
-            SideEffects::FieldReadOfType(field_type, is_volatile), dex_pc),
-        field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache) {
+      : HExpression(field_type,
+                    SideEffects::FieldReadOfType(field_type, is_volatile),
+                    dex_pc),
+        field_info_(field_offset,
+                    field_type,
+                    is_volatile,
+                    field_idx,
+                    declaring_class_def_index,
+                    dex_file,
+                    dex_cache) {
     SetRawInputAt(0, value);
   }
 
@@ -4259,12 +4271,19 @@
                     MemberOffset field_offset,
                     bool is_volatile,
                     uint32_t field_idx,
+                    uint16_t declaring_class_def_index,
                     const DexFile& dex_file,
                     Handle<mirror::DexCache> dex_cache,
                     uint32_t dex_pc)
-      : HTemplateInstruction(
-          SideEffects::FieldWriteOfType(field_type, is_volatile), dex_pc),
-        field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache),
+      : HTemplateInstruction(SideEffects::FieldWriteOfType(field_type, is_volatile),
+                             dex_pc),
+        field_info_(field_offset,
+                    field_type,
+                    is_volatile,
+                    field_idx,
+                    declaring_class_def_index,
+                    dex_file,
+                    dex_cache),
         value_can_be_null_(true) {
     SetRawInputAt(0, object);
     SetRawInputAt(1, value);
@@ -4685,13 +4704,20 @@
                   MemberOffset field_offset,
                   bool is_volatile,
                   uint32_t field_idx,
+                  uint16_t declaring_class_def_index,
                   const DexFile& dex_file,
                   Handle<mirror::DexCache> dex_cache,
                   uint32_t dex_pc)
-      : HExpression(
-            field_type,
-            SideEffects::FieldReadOfType(field_type, is_volatile), dex_pc),
-        field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache) {
+      : HExpression(field_type,
+                    SideEffects::FieldReadOfType(field_type, is_volatile),
+                    dex_pc),
+        field_info_(field_offset,
+                    field_type,
+                    is_volatile,
+                    field_idx,
+                    declaring_class_def_index,
+                    dex_file,
+                    dex_cache) {
     SetRawInputAt(0, cls);
   }
 
@@ -4728,12 +4754,19 @@
                   MemberOffset field_offset,
                   bool is_volatile,
                   uint32_t field_idx,
+                  uint16_t declaring_class_def_index,
                   const DexFile& dex_file,
                   Handle<mirror::DexCache> dex_cache,
                   uint32_t dex_pc)
-      : HTemplateInstruction(
-          SideEffects::FieldWriteOfType(field_type, is_volatile), dex_pc),
-        field_info_(field_offset, field_type, is_volatile, field_idx, dex_file, dex_cache),
+      : HTemplateInstruction(SideEffects::FieldWriteOfType(field_type, is_volatile),
+                             dex_pc),
+        field_info_(field_offset,
+                    field_type,
+                    is_volatile,
+                    field_idx,
+                    declaring_class_def_index,
+                    dex_file,
+                    dex_cache),
         value_can_be_null_(true) {
     SetRawInputAt(0, cls);
     SetRawInputAt(1, value);