OSDN Git Service

Avoid Cache*LoweringInfo pass when there's no GET/PUT/INVOKE.
authorVladimir Marko <vmarko@google.com>
Thu, 6 Mar 2014 15:18:04 +0000 (15:18 +0000)
committerVladimir Marko <vmarko@google.com>
Tue, 11 Mar 2014 10:52:37 +0000 (10:52 +0000)
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

compiler/dex/bb_optimizations.h
compiler/dex/mir_dataflow.cc
compiler/dex/mir_graph.cc
compiler/dex/mir_graph.h

index 1a90ca8..1ad4958 100644 (file)
@@ -34,6 +34,10 @@ class CacheFieldLoweringInfo : public Pass {
   void Start(CompilationUnit* cUnit) const {
     cUnit->mir_graph->DoCacheFieldLoweringInfo();
   }
+
+  bool Gate(const CompilationUnit *cUnit) const {
+    return cUnit->mir_graph->HasFieldAccess();
+  }
 };
 
 /**
@@ -48,6 +52,10 @@ class CacheMethodLoweringInfo : public Pass {
   void Start(CompilationUnit* cUnit) const {
     cUnit->mir_graph->DoCacheMethodLoweringInfo();
   }
+
+  bool Gate(const CompilationUnit *cUnit) const {
+    return cUnit->mir_graph->HasInvokes();
+  }
 };
 
 /**
index c3954fe..1c0205d 100644 (file)
@@ -277,88 +277,88 @@ const uint64_t MIRGraph::oat_data_flow_attributes_[kMirOpLast] = {
   DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_B | DF_CORE_C | DF_LVN,
 
   // 52 IGET vA, vB, field@CCCC
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_LVN,
+  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 53 IGET_WIDE vA, vB, field@CCCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_LVN,
+  DF_DA | DF_A_WIDE | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 54 IGET_OBJECT vA, vB, field@CCCC
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_A | DF_REF_B | DF_LVN,
+  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_A | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 55 IGET_BOOLEAN vA, vB, field@CCCC
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_LVN,
+  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 56 IGET_BYTE vA, vB, field@CCCC
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_LVN,
+  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 57 IGET_CHAR vA, vB, field@CCCC
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_LVN,
+  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 58 IGET_SHORT vA, vB, field@CCCC
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_LVN,
+  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 59 IPUT vA, vB, field@CCCC
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B | DF_LVN,
+  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 5A IPUT_WIDE vA, vB, field@CCCC
-  DF_UA | DF_A_WIDE | DF_UB | DF_NULL_CHK_2 | DF_REF_B | DF_LVN,
+  DF_UA | DF_A_WIDE | DF_UB | DF_NULL_CHK_2 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 5B IPUT_OBJECT vA, vB, field@CCCC
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_A | DF_REF_B | DF_LVN,
+  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_A | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 5C IPUT_BOOLEAN vA, vB, field@CCCC
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B | DF_LVN,
+  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 5D IPUT_BYTE vA, vB, field@CCCC
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B | DF_LVN,
+  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 5E IPUT_CHAR vA, vB, field@CCCC
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B | DF_LVN,
+  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 5F IPUT_SHORT vA, vB, field@CCCC
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B | DF_LVN,
+  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // 60 SGET vAA, field@BBBB
-  DF_DA | DF_UMS,
+  DF_DA | DF_SFIELD | DF_UMS,
 
   // 61 SGET_WIDE vAA, field@BBBB
-  DF_DA | DF_A_WIDE | DF_UMS,
+  DF_DA | DF_A_WIDE | DF_SFIELD | DF_UMS,
 
   // 62 SGET_OBJECT vAA, field@BBBB
-  DF_DA | DF_REF_A | DF_UMS,
+  DF_DA | DF_REF_A | DF_SFIELD | DF_UMS,
 
   // 63 SGET_BOOLEAN vAA, field@BBBB
-  DF_DA | DF_UMS,
+  DF_DA | DF_SFIELD | DF_UMS,
 
   // 64 SGET_BYTE vAA, field@BBBB
-  DF_DA | DF_UMS,
+  DF_DA | DF_SFIELD | DF_UMS,
 
   // 65 SGET_CHAR vAA, field@BBBB
-  DF_DA | DF_UMS,
+  DF_DA | DF_SFIELD | DF_UMS,
 
   // 66 SGET_SHORT vAA, field@BBBB
-  DF_DA | DF_UMS,
+  DF_DA | DF_SFIELD | DF_UMS,
 
   // 67 SPUT vAA, field@BBBB
-  DF_UA | DF_UMS,
+  DF_UA | DF_SFIELD | DF_UMS,
 
   // 68 SPUT_WIDE vAA, field@BBBB
-  DF_UA | DF_A_WIDE | DF_UMS,
+  DF_UA | DF_A_WIDE | DF_SFIELD | DF_UMS,
 
   // 69 SPUT_OBJECT vAA, field@BBBB
-  DF_UA | DF_REF_A | DF_UMS,
+  DF_UA | DF_REF_A | DF_SFIELD | DF_UMS,
 
   // 6A SPUT_BOOLEAN vAA, field@BBBB
-  DF_UA | DF_UMS,
+  DF_UA | DF_SFIELD | DF_UMS,
 
   // 6B SPUT_BYTE vAA, field@BBBB
-  DF_UA | DF_UMS,
+  DF_UA | DF_SFIELD | DF_UMS,
 
   // 6C SPUT_CHAR vAA, field@BBBB
-  DF_UA | DF_UMS,
+  DF_UA | DF_SFIELD | DF_UMS,
 
   // 6D SPUT_SHORT vAA, field@BBBB
-  DF_UA | DF_UMS,
+  DF_UA | DF_SFIELD | DF_UMS,
 
   // 6E INVOKE_VIRTUAL {vD, vE, vF, vG, vA}
   DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
@@ -712,31 +712,31 @@ const uint64_t MIRGraph::oat_data_flow_attributes_[kMirOpLast] = {
   DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
 
   // E3 IGET_VOLATILE
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_LVN,
+  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // E4 IPUT_VOLATILE
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B | DF_LVN,
+  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // E5 SGET_VOLATILE
-  DF_DA | DF_UMS,
+  DF_DA | DF_SFIELD | DF_UMS,
 
   // E6 SPUT_VOLATILE
-  DF_UA | DF_UMS,
+  DF_UA | DF_SFIELD | DF_UMS,
 
   // E7 IGET_OBJECT_VOLATILE
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_A | DF_REF_B | DF_LVN,
+  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_A | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // E8 IGET_WIDE_VOLATILE
-  DF_DA | DF_A_WIDE | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_LVN,
+  DF_DA | DF_A_WIDE | DF_UB | DF_NULL_CHK_0 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // E9 IPUT_WIDE_VOLATILE
-  DF_UA | DF_A_WIDE | DF_UB | DF_NULL_CHK_2 | DF_REF_B | DF_LVN,
+  DF_UA | DF_A_WIDE | DF_UB | DF_NULL_CHK_2 | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // EA SGET_WIDE_VOLATILE
-  DF_DA | DF_A_WIDE | DF_UMS,
+  DF_DA | DF_A_WIDE | DF_SFIELD | DF_UMS,
 
   // EB SPUT_WIDE_VOLATILE
-  DF_UA | DF_A_WIDE | DF_UMS,
+  DF_UA | DF_A_WIDE | DF_SFIELD | DF_UMS,
 
   // EC BREAKPOINT
   DF_NOP,
@@ -757,22 +757,22 @@ const uint64_t MIRGraph::oat_data_flow_attributes_[kMirOpLast] = {
   DF_NOP,
 
   // F2 IGET_QUICK
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_LVN,
+  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IFIELD | DF_LVN,
 
   // F3 IGET_WIDE_QUICK
-  DF_DA | DF_A_WIDE | DF_UB | DF_NULL_CHK_0 | DF_LVN,
+  DF_DA | DF_A_WIDE | DF_UB | DF_NULL_CHK_0 | DF_IFIELD | DF_LVN,
 
   // F4 IGET_OBJECT_QUICK
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_LVN,
+  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IFIELD | DF_LVN,
 
   // F5 IPUT_QUICK
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_LVN,
+  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IFIELD | DF_LVN,
 
   // F6 IPUT_WIDE_QUICK
-  DF_UA | DF_A_WIDE | DF_UB | DF_NULL_CHK_2 | DF_LVN,
+  DF_UA | DF_A_WIDE | DF_UB | DF_NULL_CHK_2 | DF_IFIELD | DF_LVN,
 
   // F7 IPUT_OBJECT_QUICK
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_LVN,
+  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IFIELD | DF_LVN,
 
   // F8 INVOKE_VIRTUAL_QUICK
   DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
@@ -787,13 +787,13 @@ const uint64_t MIRGraph::oat_data_flow_attributes_[kMirOpLast] = {
   DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,
 
   // FC IPUT_OBJECT_VOLATILE
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_A | DF_REF_B | DF_LVN,
+  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_A | DF_REF_B | DF_IFIELD | DF_LVN,
 
   // FD SGET_OBJECT_VOLATILE
-  DF_DA | DF_REF_A | DF_UMS,
+  DF_DA | DF_REF_A | DF_SFIELD | DF_UMS,
 
   // FE SPUT_OBJECT_VOLATILE
-  DF_UA | DF_REF_A | DF_UMS,
+  DF_UA | DF_REF_A | DF_SFIELD | DF_UMS,
 
   // FF UNUSED_FF
   DF_NOP,
index 0b50e2f..8bb5615 100644 (file)
@@ -88,6 +88,7 @@ MIRGraph::MIRGraph(CompilationUnit* cu, ArenaAllocator* arena)
       num_non_special_compiler_temps_(0),
       max_available_non_special_compiler_temps_(0),
       punt_to_interpreter_(false),
+      merged_df_flags_(0u),
       ifield_lowering_infos_(arena, 0u),
       sfield_lowering_infos_(arena, 0u),
       method_lowering_infos_(arena, 0u) {
@@ -598,9 +599,11 @@ void MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_
   entry_block_->fall_through = cur_block->id;
   cur_block->predecessors->Insert(entry_block_->id);
 
-    /* Identify code range in try blocks and set up the empty catch blocks */
+  /* Identify code range in try blocks and set up the empty catch blocks */
   ProcessTryCatchBlocks();
 
+  uint64_t merged_df_flags = 0u;
+
   /* Parse all instructions and put them into containing basic blocks */
   while (code_ptr < code_end) {
     MIR *insn = static_cast<MIR *>(arena_->Alloc(sizeof(MIR), kArenaAllocMIR));
@@ -617,6 +620,7 @@ void MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_
     int verify_flags = Instruction::VerifyFlagsOf(insn->dalvikInsn.opcode);
 
     uint64_t df_flags = oat_data_flow_attributes_[insn->dalvikInsn.opcode];
+    merged_df_flags |= df_flags;
 
     if (df_flags & DF_HAS_DEFS) {
       def_count_ += (df_flags & DF_A_WIDE) ? 2 : 1;
@@ -715,6 +719,7 @@ void MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_
       cur_block = next_block;
     }
   }
+  merged_df_flags_ = merged_df_flags;
 
   if (cu_->enable_debug & (1 << kDebugDumpCFG)) {
     DumpCFG("/sdcard/1_post_parse_cfg/", true);
index 2abc0cc..80311ec 100644 (file)
@@ -98,6 +98,8 @@ enum DataFlowAttributePos {
   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 @@ enum DataFlowAttributePos {
 #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 @@ class MIRGraph {
    */
   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 @@ class MIRGraph {
   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_;