OSDN Git Service

Skip null check in MarkGCCard() for known non-null values.
authorVladimir Marko <vmarko@google.com>
Mon, 24 Nov 2014 19:45:41 +0000 (19:45 +0000)
committerVladimir Marko <vmarko@google.com>
Mon, 24 Nov 2014 19:49:22 +0000 (19:49 +0000)
Use GVN's knowledge of non-null values to set a new MIR flag
for IPUT/SPUT/APUT to skip the value null check.

Change-Id: I97a8d1447acb530c9bbbf7b362add366d1486ee1

13 files changed:
compiler/dex/compiler_enums.h
compiler/dex/local_value_numbering.cc
compiler/dex/local_value_numbering_test.cc
compiler/dex/mir_graph.h
compiler/dex/quick/arm/int_arm.cc
compiler/dex/quick/arm64/int_arm64.cc
compiler/dex/quick/codegen_util.cc
compiler/dex/quick/gen_common.cc
compiler/dex/quick/gen_invoke.cc
compiler/dex/quick/mips/int_mips.cc
compiler/dex/quick/mir_to_lir.cc
compiler/dex/quick/mir_to_lir.h
compiler/dex/quick/x86/int_x86.cc

index b56fd6f..4d377df 100644 (file)
@@ -316,9 +316,8 @@ enum ExtendedMIROpcode {
 
 enum MIROptimizationFlagPositions {
   kMIRIgnoreNullCheck = 0,
-  kMIRNullCheckOnly,
   kMIRIgnoreRangeCheck,
-  kMIRRangeCheckOnly,
+  kMIRStoreNonNullValue,              // Storing non-null value, always mark GC card.
   kMIRClassIsInitialized,
   kMIRClassIsInDexCache,
   kMirIgnoreDivZeroCheck,
index e0c4e27..114346d 100644 (file)
@@ -1110,6 +1110,12 @@ void LocalValueNumbering::HandlePutObject(MIR* mir) {
   // If we're storing a non-aliasing reference, stop tracking it as non-aliasing now.
   uint16_t base = GetOperandValue(mir->ssa_rep->uses[0]);
   HandleEscapingRef(base);
+  if (gvn_->CanModify() && null_checked_.count(base) != 0u) {
+    if (gvn_->GetCompilationUnit()->verbose) {
+      LOG(INFO) << "Removing GC card mark value null check for 0x" << std::hex << mir->offset;
+    }
+    mir->optimization_flags |= MIR_STORE_NON_NULL_VALUE;
+  }
 }
 
 void LocalValueNumbering::HandleEscapingRef(uint16_t base) {
index f4f13f2..0fcb584 100644 (file)
@@ -607,7 +607,9 @@ TEST_F(LocalValueNumberingTest, EscapingRefs) {
   EXPECT_NE(value_names_[13], value_names_[16]);  // New value.
   EXPECT_NE(value_names_[14], value_names_[17]);  // New value.
   for (size_t i = 0u; i != mir_count_; ++i) {
-    int expected = (i != 0u && i != 3u && i != 6u) ? MIR_IGNORE_NULL_CHECK : 0;
+    int expected =
+        ((i != 0u && i != 3u && i != 6u) ? MIR_IGNORE_NULL_CHECK : 0) |
+        ((i == 3u) ? MIR_STORE_NON_NULL_VALUE: 0);
     EXPECT_EQ(expected, mirs_[i].optimization_flags) << i;
   }
 }
@@ -640,7 +642,8 @@ TEST_F(LocalValueNumberingTest, EscapingArrayRefs) {
   for (size_t i = 0u; i != mir_count_; ++i) {
     int expected =
         ((i != 0u && i != 3u && i != 6u && i != 9u) ? MIR_IGNORE_NULL_CHECK : 0u) |
-        ((i >= 4 && i != 6u && i != 9u) ? MIR_IGNORE_RANGE_CHECK : 0u);
+        ((i >= 4 && i != 6u && i != 9u) ? MIR_IGNORE_RANGE_CHECK : 0u) |
+        ((i == 3u) ? MIR_STORE_NON_NULL_VALUE: 0);
     EXPECT_EQ(expected, mirs_[i].optimization_flags) << i;
   }
 }
index c8ea972..1a18841 100644 (file)
@@ -145,9 +145,8 @@ enum OatMethodAttributes {
 #define INVALID_OFFSET (0xDEADF00FU)
 
 #define MIR_IGNORE_NULL_CHECK           (1 << kMIRIgnoreNullCheck)
-#define MIR_NULL_CHECK_ONLY             (1 << kMIRNullCheckOnly)
 #define MIR_IGNORE_RANGE_CHECK          (1 << kMIRIgnoreRangeCheck)
-#define MIR_RANGE_CHECK_ONLY            (1 << kMIRRangeCheckOnly)
+#define MIR_STORE_NON_NULL_VALUE        (1 << kMIRStoreNonNullValue)
 #define MIR_CLASS_IS_INITIALIZED        (1 << kMIRClassIsInitialized)
 #define MIR_CLASS_IS_IN_DEX_CACHE       (1 << kMIRClassIsInDexCache)
 #define MIR_IGNORE_DIV_ZERO_CHECK       (1 << kMirIgnoreDivZeroCheck)
index cab039b..e38dbf5 100644 (file)
@@ -872,7 +872,7 @@ bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
 
   if (is_object && !mir_graph_->IsConstantNullRef(rl_new_value)) {
     // Mark card for object assuming new value is stored.
-    MarkGCCard(rl_new_value.reg, rl_object.reg);
+    MarkGCCard(0, rl_new_value.reg, rl_object.reg);
   }
 
   RegLocation rl_offset = LoadValue(rl_src_offset, kCoreReg);
@@ -1471,7 +1471,7 @@ void ArmMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
     FreeTemp(reg_ptr);
   }
   if (card_mark) {
-    MarkGCCard(rl_src.reg, rl_array.reg);
+    MarkGCCard(opt_flags, rl_src.reg, rl_array.reg);
   }
 }
 
index 0e00698..b12fc0a 100644 (file)
@@ -758,7 +758,7 @@ bool Arm64Mir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
 
   if (is_object && !mir_graph_->IsConstantNullRef(rl_new_value)) {
     // Mark card for object assuming new value is stored.
-    MarkGCCard(rl_new_value.reg, rl_object.reg);
+    MarkGCCard(0, rl_new_value.reg, rl_object.reg);
   }
 
   RegStorage r_ptr = AllocTempRef();
@@ -1281,7 +1281,7 @@ void Arm64Mir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
     FreeTemp(reg_ptr);
   }
   if (card_mark) {
-    MarkGCCard(rl_src.reg, rl_array.reg);
+    MarkGCCard(opt_flags, rl_src.reg, rl_array.reg);
   }
 }
 
index 80cb535..1cde01e 100644 (file)
@@ -314,13 +314,17 @@ void Mir2Lir::UpdateLIROffsets() {
   }
 }
 
-void Mir2Lir::MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) {
+void Mir2Lir::MarkGCCard(int opt_flags, RegStorage val_reg, RegStorage tgt_addr_reg) {
   DCHECK(val_reg.Valid());
   DCHECK_EQ(val_reg.Is64Bit(), cu_->target64);
-  LIR* branch_over = OpCmpImmBranch(kCondEq, val_reg, 0, nullptr);
-  UnconditionallyMarkGCCard(tgt_addr_reg);
-  LIR* target = NewLIR0(kPseudoTargetLabel);
-  branch_over->target = target;
+  if ((opt_flags & MIR_STORE_NON_NULL_VALUE) != 0) {
+    UnconditionallyMarkGCCard(tgt_addr_reg);
+  } else {
+    LIR* branch_over = OpCmpImmBranch(kCondEq, val_reg, 0, nullptr);
+    UnconditionallyMarkGCCard(tgt_addr_reg);
+    LIR* target = NewLIR0(kPseudoTargetLabel);
+    branch_over->target = target;
+  }
 }
 
 /* Dump instructions and constant pool contents */
index 4dd24cb..d1b8b03 100644 (file)
@@ -665,7 +665,7 @@ void Mir2Lir::GenSput(MIR* mir, RegLocation rl_src, OpSize size) {
                     field_info.IsVolatile() ? kVolatile : kNotVolatile);
     }
     if (IsRef(size) && !mir_graph_->IsConstantNullRef(rl_src)) {
-      MarkGCCard(rl_src.reg, r_base);
+      MarkGCCard(mir->optimization_flags, rl_src.reg, r_base);
     }
     FreeTemp(r_base);
   } else {
@@ -940,7 +940,7 @@ void Mir2Lir::GenIPut(MIR* mir, int opt_flags, OpSize size,
     }
     MarkPossibleNullPointerExceptionAfter(opt_flags, store);
     if (IsRef(size) && !mir_graph_->IsConstantNullRef(rl_src)) {
-      MarkGCCard(rl_src.reg, rl_obj.reg);
+      MarkGCCard(opt_flags, rl_src.reg, rl_obj.reg);
     }
   } else {
     QuickEntrypointEnum target;
index a7900ae..31b81bf 100755 (executable)
@@ -1668,7 +1668,7 @@ bool Mir2Lir::GenInlinedUnsafePut(CallInfo* info, bool is_long,
     GenMemBarrier(kAnyAny);
   }
   if (is_object) {
-    MarkGCCard(rl_value.reg, rl_object.reg);
+    MarkGCCard(0, rl_value.reg, rl_object.reg);
   }
   return true;
 }
index fb47238..0778c3b 100644 (file)
@@ -641,7 +641,7 @@ void MipsMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
     FreeTemp(reg_ptr);
   }
   if (card_mark) {
-    MarkGCCard(rl_src.reg, rl_array.reg);
+    MarkGCCard(opt_flags, rl_src.reg, rl_array.reg);
   }
 }
 
index 70ef991..0d30927 100644 (file)
@@ -332,7 +332,7 @@ bool Mir2Lir::GenSpecialIPut(MIR* mir, const InlineMethod& special) {
         kNotVolatile);
   }
   if (IsRef(size)) {
-    MarkGCCard(reg_src, reg_obj);
+    MarkGCCard(0, reg_src, reg_obj);
   }
   return true;
 }
index 886b238..49b8452 100644 (file)
@@ -1075,8 +1075,9 @@ class Mir2Lir : public Backend {
      * @brief Mark a garbage collection card. Skip if the stored value is null.
      * @param val_reg the register holding the stored value to check against null.
      * @param tgt_addr_reg the address of the object or array where the value was stored.
+     * @param opt_flags the optimization flags which may indicate that the value is non-null.
      */
-    void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg);
+    void MarkGCCard(int opt_flags, RegStorage val_reg, RegStorage tgt_addr_reg);
 
     /*
      * @brief Load the address of the dex method into the register.
index 3f501b4..74ae8a6 100755 (executable)
@@ -1170,7 +1170,7 @@ bool X86Mir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
     if (is_object && !mir_graph_->IsConstantNullRef(rl_new_value)) {
       // Mark card for object assuming new value is stored.
       FreeTemp(rs_r0);  // Temporarily release EAX for MarkGCCard().
-      MarkGCCard(rl_new_value.reg, rl_object.reg);
+      MarkGCCard(0, rl_new_value.reg, rl_object.reg);
       LockTemp(rs_r0);
     }
 
@@ -2398,7 +2398,7 @@ void X86Mir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array,
     if (!constant_index) {
       FreeTemp(rl_index.reg);
     }
-    MarkGCCard(rl_src.reg, rl_array.reg);
+    MarkGCCard(opt_flags, rl_src.reg, rl_array.reg);
   }
 }