Avoid Cache*LoweringInfo pass when there's no GET/PUT/INVOKE.

Add new data flow flags indicating instance/static field
access. Record merged flags of all insns and use them to skip
the CacheFieldLoweringInfo pass if the method uses no fields
and the CacheMethodLoweringInfo pass if it has no invokes.

Change-Id: I36a36b438ca9b0f104a7baddc0497d736495cc3c
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index 2abc0cc..80311ec 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -98,6 +98,8 @@
   kRefB,
   kRefC,
   kUsesMethodStar,       // Implicit use of Method*.
+  kUsesIField,           // Accesses an instance field (IGET/IPUT).
+  kUsesSField,           // Accesses a static field (SGET/SPUT).
   kDoLVN,                // Worth computing local value numbers.
 };
 
@@ -134,6 +136,8 @@
 #define DF_REF_B                (UINT64_C(1) << kRefB)
 #define DF_REF_C                (UINT64_C(1) << kRefC)
 #define DF_UMS                  (UINT64_C(1) << kUsesMethodStar)
+#define DF_IFIELD               (UINT64_C(1) << kUsesIField)
+#define DF_SFIELD               (UINT64_C(1) << kUsesSField)
 #define DF_LVN                  (UINT64_C(1) << kDoLVN)
 
 #define DF_HAS_USES             (DF_UA | DF_UB | DF_UC)
@@ -485,14 +489,23 @@
    */
   void DumpCFG(const char* dir_prefix, bool all_blocks, const char* suffix = nullptr);
 
+  bool HasFieldAccess() const {
+    return (merged_df_flags_ & (DF_IFIELD | DF_SFIELD)) != 0u;
+  }
+
+  bool HasInvokes() const {
+    // NOTE: These formats include the rare filled-new-array/range.
+    return (merged_df_flags_ & (DF_FORMAT_35C | DF_FORMAT_3RC)) != 0u;
+  }
+
   void DoCacheFieldLoweringInfo();
 
-  const MirIFieldLoweringInfo& GetIFieldLoweringInfo(MIR* mir) {
+  const MirIFieldLoweringInfo& GetIFieldLoweringInfo(MIR* mir) const {
     DCHECK_LT(mir->meta.ifield_lowering_info, ifield_lowering_infos_.Size());
     return ifield_lowering_infos_.GetRawStorage()[mir->meta.ifield_lowering_info];
   }
 
-  const MirSFieldLoweringInfo& GetSFieldLoweringInfo(MIR* mir) {
+  const MirSFieldLoweringInfo& GetSFieldLoweringInfo(MIR* mir) const {
     DCHECK_LT(mir->meta.sfield_lowering_info, sfield_lowering_infos_.Size());
     return sfield_lowering_infos_.GetRawStorage()[mir->meta.sfield_lowering_info];
   }
@@ -961,6 +974,7 @@
   size_t max_available_non_special_compiler_temps_;
   size_t max_available_special_compiler_temps_;
   bool punt_to_interpreter_;                    // Difficult or not worthwhile - just interpret.
+  uint64_t merged_df_flags_;
   GrowableArray<MirIFieldLoweringInfo> ifield_lowering_infos_;
   GrowableArray<MirSFieldLoweringInfo> sfield_lowering_infos_;
   GrowableArray<MirMethodLoweringInfo> method_lowering_infos_;