OSDN Git Service

Quick: Reduce memory usage and improve compile time.
authorVladimir Marko <vmarko@google.com>
Thu, 9 Oct 2014 13:57:59 +0000 (14:57 +0100)
committerVladimir Marko <vmarko@google.com>
Thu, 9 Oct 2014 14:28:21 +0000 (15:28 +0100)
Move the def-block-matrix from Arena to ScopedArena. Remove
BasicBlockDataFlow::ending_check_v and use a temporary bit
matrix instead. Remove unused BasicBlockDataFlow::phi_v.
Avoid some BitVector::Copy() at the end of null and clinit
check elimination passes when the contents of the source
BitVector is no longer needed.

Change-Id: I8111b2f8a51e63075aa124b528d61b79b6933274

compiler/dex/mir_graph.cc
compiler/dex/mir_graph.h
compiler/dex/mir_optimization.cc
compiler/dex/ssa_transformation.cc

index 276b886..7e83c0c 100644 (file)
@@ -94,11 +94,11 @@ MIRGraph::MIRGraph(CompilationUnit* cu, ArenaAllocator* arena)
       topological_order_indexes_(arena->Adapter(kArenaAllocTopologicalSortOrder)),
       topological_order_loop_head_stack_(arena->Adapter(kArenaAllocTopologicalSortOrder)),
       i_dom_list_(NULL),
-      def_block_matrix_(NULL),
       temp_scoped_alloc_(),
       temp_insn_data_(nullptr),
       temp_bit_vector_size_(0u),
       temp_bit_vector_(nullptr),
+      temp_bit_matrix_(nullptr),
       temp_gvn_(),
       block_list_(arena->Adapter(kArenaAllocBBList)),
       try_block_addr_(NULL),
@@ -1706,6 +1706,7 @@ void MIRGraph::SSATransformationEnd() {
 
   temp_bit_vector_size_ = 0u;
   temp_bit_vector_ = nullptr;
+  temp_bit_matrix_ = nullptr;  // Def block matrix.
   DCHECK(temp_scoped_alloc_.get() != nullptr);
   temp_scoped_alloc_.reset();
 
index 21b6914..cc215bd 100644 (file)
@@ -198,9 +198,7 @@ struct BasicBlockDataFlow {
   ArenaBitVector* use_v;
   ArenaBitVector* def_v;
   ArenaBitVector* live_in_v;
-  ArenaBitVector* phi_v;
   int32_t* vreg_to_ssa_map_exit;
-  ArenaBitVector* ending_check_v;  // For null check and class init check elimination.
 };
 
 /*
@@ -1261,11 +1259,15 @@ class MIRGraph {
   // Stack of the loop head indexes and recalculation flags for RepeatingTopologicalSortIterator.
   ArenaVector<std::pair<uint16_t, bool>> topological_order_loop_head_stack_;
   int* i_dom_list_;
-  ArenaBitVector** def_block_matrix_;    // original num registers x num_blocks.
   std::unique_ptr<ScopedArenaAllocator> temp_scoped_alloc_;
   uint16_t* temp_insn_data_;
   uint32_t temp_bit_vector_size_;
   ArenaBitVector* temp_bit_vector_;
+  // temp_bit_matrix_ used as one of
+  //   - def_block_matrix: original num registers x num_blocks_,
+  //   - ending_null_check_matrix: num_blocks_ x original num registers,
+  //   - ending_clinit_check_matrix: num_blocks_ x unique class count.
+  ArenaBitVector** temp_bit_matrix_;
   std::unique_ptr<GlobalValueNumbering> temp_gvn_;
   static const int kInvalidEntry = -1;
   ArenaVector<BasicBlock*> block_list_;
index bf3d7df..322b737 100644 (file)
@@ -825,18 +825,14 @@ bool MIRGraph::EliminateNullChecksGate() {
     return false;
   }
 
-  if (kIsDebugBuild) {
-    AllNodesIterator iter(this);
-    for (BasicBlock* bb = iter.Next(); bb != nullptr; bb = iter.Next()) {
-      CHECK(bb->data_flow_info == nullptr || bb->data_flow_info->ending_check_v == nullptr);
-    }
-  }
-
   DCHECK(temp_scoped_alloc_.get() == nullptr);
   temp_scoped_alloc_.reset(ScopedArenaAllocator::Create(&cu_->arena_stack));
   temp_bit_vector_size_ = GetNumSSARegs();
   temp_bit_vector_ = new (temp_scoped_alloc_.get()) ArenaBitVector(
-      temp_scoped_alloc_.get(), temp_bit_vector_size_, false, kBitMapTempSSARegisterV);
+      temp_scoped_alloc_.get(), temp_bit_vector_size_, false, kBitMapNullCheck);
+  temp_bit_matrix_ = static_cast<ArenaBitVector**>(
+      temp_scoped_alloc_->Alloc(sizeof(ArenaBitVector*) * GetNumBlocks(), kArenaAllocMisc));
+  std::fill_n(temp_bit_matrix_, GetNumBlocks(), nullptr);
   return true;
 }
 
@@ -865,8 +861,8 @@ bool MIRGraph::EliminateNullChecks(BasicBlock* bb) {
   } else if (bb->predecessors.size() == 1) {
     BasicBlock* pred_bb = GetBasicBlock(bb->predecessors[0]);
     // pred_bb must have already been processed at least once.
-    DCHECK(pred_bb->data_flow_info->ending_check_v != nullptr);
-    ssa_regs_to_check->Copy(pred_bb->data_flow_info->ending_check_v);
+    DCHECK(temp_bit_matrix_[pred_bb->id] != nullptr);
+    ssa_regs_to_check->Copy(temp_bit_matrix_[pred_bb->id]);
     if (pred_bb->block_type == kDalvikByteCode) {
       // Check to see if predecessor had an explicit null-check.
       MIR* last_insn = pred_bb->last_mir_insn;
@@ -894,14 +890,14 @@ bool MIRGraph::EliminateNullChecks(BasicBlock* bb) {
       BasicBlock* pred_bb = GetBasicBlock(pred_id);
       DCHECK(pred_bb != nullptr);
       DCHECK(pred_bb->data_flow_info != nullptr);
-      if (pred_bb->data_flow_info->ending_check_v == nullptr) {
+      if (temp_bit_matrix_[pred_bb->id] == nullptr) {
         continue;
       }
       if (!copied_first) {
         copied_first = true;
-        ssa_regs_to_check->Copy(pred_bb->data_flow_info->ending_check_v);
+        ssa_regs_to_check->Copy(temp_bit_matrix_[pred_bb->id]);
       } else {
-        ssa_regs_to_check->Union(pred_bb->data_flow_info->ending_check_v);
+        ssa_regs_to_check->Union(temp_bit_matrix_[pred_bb->id]);
       }
     }
     DCHECK(copied_first);  // At least one predecessor must have been processed before this bb.
@@ -1015,15 +1011,18 @@ bool MIRGraph::EliminateNullChecks(BasicBlock* bb) {
 
   // Did anything change?
   bool nce_changed = false;
-  if (bb->data_flow_info->ending_check_v == nullptr) {
+  ArenaBitVector* old_ending_ssa_regs_to_check = temp_bit_matrix_[bb->id];
+  if (old_ending_ssa_regs_to_check == nullptr) {
     DCHECK(temp_scoped_alloc_.get() != nullptr);
-    bb->data_flow_info->ending_check_v = new (temp_scoped_alloc_.get()) ArenaBitVector(
-        temp_scoped_alloc_.get(), temp_bit_vector_size_, false, kBitMapNullCheck);
     nce_changed = ssa_regs_to_check->GetHighestBitSet() != -1;
-    bb->data_flow_info->ending_check_v->Copy(ssa_regs_to_check);
-  } else if (!ssa_regs_to_check->SameBitsSet(bb->data_flow_info->ending_check_v)) {
+    temp_bit_matrix_[bb->id] = ssa_regs_to_check;
+    // Create a new ssa_regs_to_check for next BB.
+    temp_bit_vector_ = new (temp_scoped_alloc_.get()) ArenaBitVector(
+        temp_scoped_alloc_.get(), temp_bit_vector_size_, false, kBitMapNullCheck);
+  } else if (!ssa_regs_to_check->SameBitsSet(old_ending_ssa_regs_to_check)) {
     nce_changed = true;
-    bb->data_flow_info->ending_check_v->Copy(ssa_regs_to_check);
+    temp_bit_matrix_[bb->id] = ssa_regs_to_check;
+    temp_bit_vector_ = old_ending_ssa_regs_to_check;  // Reuse for ssa_regs_to_check for next BB.
   }
   return nce_changed;
 }
@@ -1032,12 +1031,7 @@ void MIRGraph::EliminateNullChecksEnd() {
   // Clean up temporaries.
   temp_bit_vector_size_ = 0u;
   temp_bit_vector_ = nullptr;
-  AllNodesIterator iter(this);
-  for (BasicBlock* bb = iter.Next(); bb != nullptr; bb = iter.Next()) {
-    if (bb->data_flow_info != nullptr) {
-      bb->data_flow_info->ending_check_v = nullptr;
-    }
-  }
+  temp_bit_matrix_ = nullptr;
   DCHECK(temp_scoped_alloc_.get() != nullptr);
   temp_scoped_alloc_.reset();
 }
@@ -1067,13 +1061,6 @@ bool MIRGraph::EliminateClassInitChecksGate() {
     return false;
   }
 
-  if (kIsDebugBuild) {
-    AllNodesIterator iter(this);
-    for (BasicBlock* bb = iter.Next(); bb != nullptr; bb = iter.Next()) {
-      CHECK(bb->data_flow_info == nullptr || bb->data_flow_info->ending_check_v == nullptr);
-    }
-  }
-
   DCHECK(temp_scoped_alloc_.get() == nullptr);
   temp_scoped_alloc_.reset(ScopedArenaAllocator::Create(&cu_->arena_stack));
 
@@ -1147,6 +1134,9 @@ bool MIRGraph::EliminateClassInitChecksGate() {
   temp_bit_vector_size_ = unique_class_count;
   temp_bit_vector_ = new (temp_scoped_alloc_.get()) ArenaBitVector(
       temp_scoped_alloc_.get(), temp_bit_vector_size_, false, kBitMapClInitCheck);
+  temp_bit_matrix_ = static_cast<ArenaBitVector**>(
+      temp_scoped_alloc_->Alloc(sizeof(ArenaBitVector*) * GetNumBlocks(), kArenaAllocMisc));
+  std::fill_n(temp_bit_matrix_, GetNumBlocks(), nullptr);
   DCHECK_GT(temp_bit_vector_size_, 0u);
   return true;
 }
@@ -1156,7 +1146,7 @@ bool MIRGraph::EliminateClassInitChecksGate() {
  */
 bool MIRGraph::EliminateClassInitChecks(BasicBlock* bb) {
   DCHECK_EQ((cu_->disable_opt & (1 << kClassInitCheckElimination)), 0u);
-  if (bb->data_flow_info == NULL) {
+  if (bb->data_flow_info == nullptr) {
     return false;
   }
 
@@ -1172,8 +1162,8 @@ bool MIRGraph::EliminateClassInitChecks(BasicBlock* bb) {
     // pred_bb must have already been processed at least once.
     DCHECK(pred_bb != nullptr);
     DCHECK(pred_bb->data_flow_info != nullptr);
-    DCHECK(pred_bb->data_flow_info->ending_check_v != nullptr);
-    classes_to_check->Copy(pred_bb->data_flow_info->ending_check_v);
+    DCHECK(temp_bit_matrix_[pred_bb->id] != nullptr);
+    classes_to_check->Copy(temp_bit_matrix_[pred_bb->id]);
   } else {
     // Starting state is union of all incoming arcs.
     bool copied_first = false;
@@ -1181,14 +1171,14 @@ bool MIRGraph::EliminateClassInitChecks(BasicBlock* bb) {
       BasicBlock* pred_bb = GetBasicBlock(pred_id);
       DCHECK(pred_bb != nullptr);
       DCHECK(pred_bb->data_flow_info != nullptr);
-      if (pred_bb->data_flow_info->ending_check_v == nullptr) {
+      if (temp_bit_matrix_[pred_bb->id] == nullptr) {
         continue;
       }
       if (!copied_first) {
         copied_first = true;
-        classes_to_check->Copy(pred_bb->data_flow_info->ending_check_v);
+        classes_to_check->Copy(temp_bit_matrix_[pred_bb->id]);
       } else {
-        classes_to_check->Union(pred_bb->data_flow_info->ending_check_v);
+        classes_to_check->Union(temp_bit_matrix_[pred_bb->id]);
       }
     }
     DCHECK(copied_first);  // At least one predecessor must have been processed before this bb.
@@ -1219,16 +1209,18 @@ bool MIRGraph::EliminateClassInitChecks(BasicBlock* bb) {
 
   // Did anything change?
   bool changed = false;
-  if (bb->data_flow_info->ending_check_v == nullptr) {
+  ArenaBitVector* old_ending_classes_to_check = temp_bit_matrix_[bb->id];
+  if (old_ending_classes_to_check == nullptr) {
     DCHECK(temp_scoped_alloc_.get() != nullptr);
-    DCHECK(bb->data_flow_info != nullptr);
-    bb->data_flow_info->ending_check_v = new (temp_scoped_alloc_.get()) ArenaBitVector(
-        temp_scoped_alloc_.get(), temp_bit_vector_size_, false, kBitMapClInitCheck);
     changed = classes_to_check->GetHighestBitSet() != -1;
-    bb->data_flow_info->ending_check_v->Copy(classes_to_check);
-  } else if (!classes_to_check->Equal(bb->data_flow_info->ending_check_v)) {
+    temp_bit_matrix_[bb->id] = classes_to_check;
+    // Create a new classes_to_check for next BB.
+    temp_bit_vector_ = new (temp_scoped_alloc_.get()) ArenaBitVector(
+        temp_scoped_alloc_.get(), temp_bit_vector_size_, false, kBitMapClInitCheck);
+  } else if (!classes_to_check->Equal(old_ending_classes_to_check)) {
     changed = true;
-    bb->data_flow_info->ending_check_v->Copy(classes_to_check);
+    temp_bit_matrix_[bb->id] = classes_to_check;
+    temp_bit_vector_ = old_ending_classes_to_check;  // Reuse for classes_to_check for next BB.
   }
   return changed;
 }
@@ -1237,13 +1229,7 @@ void MIRGraph::EliminateClassInitChecksEnd() {
   // Clean up temporaries.
   temp_bit_vector_size_ = 0u;
   temp_bit_vector_ = nullptr;
-  AllNodesIterator iter(this);
-  for (BasicBlock* bb = iter.Next(); bb != nullptr; bb = iter.Next()) {
-    if (bb->data_flow_info != nullptr) {
-      bb->data_flow_info->ending_check_v = nullptr;
-    }
-  }
-
+  temp_bit_matrix_ = nullptr;
   DCHECK(temp_insn_data_ != nullptr);
   temp_insn_data_ = nullptr;
   DCHECK(temp_scoped_alloc_.get() != nullptr);
index 3cc573b..4388041 100644 (file)
@@ -124,7 +124,7 @@ bool MIRGraph::FillDefBlockMatrix(BasicBlock* bb) {
 
   for (uint32_t idx : bb->data_flow_info->def_v->Indexes()) {
     /* Block bb defines register idx */
-    def_block_matrix_[idx]->SetBit(bb->id);
+    temp_bit_matrix_[idx]->SetBit(bb->id);
   }
   return true;
 }
@@ -132,15 +132,17 @@ bool MIRGraph::FillDefBlockMatrix(BasicBlock* bb) {
 void MIRGraph::ComputeDefBlockMatrix() {
   int num_registers = GetNumOfCodeAndTempVRs();
   /* Allocate num_registers bit vector pointers */
-  def_block_matrix_ = static_cast<ArenaBitVector**>
-      (arena_->Alloc(sizeof(ArenaBitVector *) * num_registers,
-                     kArenaAllocDFInfo));
+  DCHECK(temp_scoped_alloc_ != nullptr);
+  DCHECK(temp_bit_matrix_ == nullptr);
+  temp_bit_matrix_ = static_cast<ArenaBitVector**>(
+      temp_scoped_alloc_->Alloc(sizeof(ArenaBitVector*) * num_registers, kArenaAllocDFInfo));
   int i;
 
   /* Initialize num_register vectors with num_blocks bits each */
   for (i = 0; i < num_registers; i++) {
-    def_block_matrix_[i] =
-        new (arena_) ArenaBitVector(arena_, GetNumBlocks(), false, kBitMapBMatrix);
+    temp_bit_matrix_[i] = new (temp_scoped_alloc_.get()) ArenaBitVector(arena_, GetNumBlocks(),
+                                                                        false, kBitMapBMatrix);
+    temp_bit_matrix_[i]->ClearAllBits();
   }
 
   AllNodesIterator iter(this);
@@ -159,7 +161,7 @@ void MIRGraph::ComputeDefBlockMatrix() {
   int num_regs = GetNumOfCodeVRs();
   int in_reg = GetFirstInVR();
   for (; in_reg < num_regs; in_reg++) {
-    def_block_matrix_[in_reg]->SetBit(GetEntryBlock()->id);
+    temp_bit_matrix_[in_reg]->SetBit(GetEntryBlock()->id);
   }
 }
 
@@ -478,7 +480,7 @@ void MIRGraph::InsertPhiNodes() {
 
   /* Iterate through each Dalvik register */
   for (dalvik_reg = GetNumOfCodeAndTempVRs() - 1; dalvik_reg >= 0; dalvik_reg--) {
-    input_blocks->Copy(def_block_matrix_[dalvik_reg]);
+    input_blocks->Copy(temp_bit_matrix_[dalvik_reg]);
     phi_blocks->ClearAllBits();
     do {
       // TUNING: When we repeat this, we could skip indexes from the previous pass.