OSDN Git Service

Merge "Update maximum number of reachable blocks in last step"
authorBill Buzbee <buzbee@android.com>
Tue, 30 Sep 2014 19:16:40 +0000 (19:16 +0000)
committerGerrit Code Review <noreply-gerritcodereview@google.com>
Tue, 30 Sep 2014 19:16:40 +0000 (19:16 +0000)
1  2 
compiler/dex/mir_graph.cc

@@@ -1681,12 -1415,9 +1681,9 @@@ void MIRGraph::InitializeMethodUses() 
  void MIRGraph::SSATransformationStart() {
    DCHECK(temp_scoped_alloc_.get() == nullptr);
    temp_scoped_alloc_.reset(ScopedArenaAllocator::Create(&cu_->arena_stack));
 -  temp_bit_vector_size_ = cu_->num_dalvik_registers;
 +  temp_bit_vector_size_ = GetNumOfCodeAndTempVRs();
    temp_bit_vector_ = new (temp_scoped_alloc_.get()) ArenaBitVector(
        temp_scoped_alloc_.get(), temp_bit_vector_size_, false, kBitMapRegisterV);
-   // Update the maximum number of reachable blocks.
-   max_num_reachable_blocks_ = num_reachable_blocks_;
  }
  
  void MIRGraph::SSATransformationEnd() {
    temp_bit_vector_ = nullptr;
    DCHECK(temp_scoped_alloc_.get() != nullptr);
    temp_scoped_alloc_.reset();
+   // Update the maximum number of reachable blocks.
+   max_num_reachable_blocks_ = num_reachable_blocks_;
  }
  
 -void MIRGraph::ComputeTopologicalSortOrder() {
 -  std::queue<BasicBlock*> q;
 -  std::map<int, int> visited_cnt_values;
 -
 -  // Clear the nodes.
 -  ClearAllVisitedFlags();
 +size_t MIRGraph::GetNumDalvikInsns() const {
 +  size_t cumulative_size = 0u;
 +  bool counted_current_item = false;
 +  const uint8_t size_for_null_code_item = 2u;
 +
 +  for (auto it : m_units_) {
 +    const DexFile::CodeItem* code_item = it->GetCodeItem();
 +    // Even if the code item is null, we still count non-zero value so that
 +    // each m_unit is counted as having impact.
 +    cumulative_size += (code_item == nullptr ?
 +        size_for_null_code_item : code_item->insns_size_in_code_units_);
 +    if (code_item == current_code_item_) {
 +      counted_current_item = true;
 +    }
 +  }
  
 -  // Create the topological order if need be.
 -  if (topological_order_ != nullptr) {
 -    topological_order_ = new (arena_) GrowableArray<BasicBlockId>(arena_, 0);
 +  // If the current code item was not counted yet, count it now.
 +  // This can happen for example in unit tests where some fields like m_units_
 +  // are not initialized.
 +  if (counted_current_item == false) {
 +    cumulative_size += (current_code_item_ == nullptr ?
 +        size_for_null_code_item : current_code_item_->insns_size_in_code_units_);
    }
 -  topological_order_->Reset();
  
 -  // Set up visitedCntValues map for all BB. The default value for this counters in the map is zero.
 -  // also fill initial queue.
 -  GrowableArray<BasicBlock*>::Iterator iterator(&block_list_);
 +  return cumulative_size;
 +}
  
 -  while (true) {
 -    BasicBlock* bb = iterator.Next();
 +static BasicBlock* SelectTopologicalSortOrderFallBack(
 +    MIRGraph* mir_graph, const ArenaBitVector* current_loop,
 +    const ScopedArenaVector<size_t>* visited_cnt_values, ScopedArenaAllocator* allocator,
 +    ScopedArenaVector<BasicBlockId>* tmp_stack) {
 +  // No true loop head has been found but there may be true loop heads after the mess we need
 +  // to resolve. To avoid taking one of those, pick the candidate with the highest number of
 +  // reachable unvisited nodes. That candidate will surely be a part of a loop.
 +  BasicBlock* fall_back = nullptr;
 +  size_t fall_back_num_reachable = 0u;
 +  // Reuse the same bit vector for each candidate to mark reachable unvisited blocks.
 +  ArenaBitVector candidate_reachable(allocator, mir_graph->GetNumBlocks(), false, kBitMapMisc);
 +  AllNodesIterator iter(mir_graph);
 +  for (BasicBlock* candidate = iter.Next(); candidate != nullptr; candidate = iter.Next()) {
 +    if (candidate->hidden ||                            // Hidden, or
 +        candidate->visited ||                           // already processed, or
 +        (*visited_cnt_values)[candidate->id] == 0u ||   // no processed predecessors, or
 +        (current_loop != nullptr &&                     // outside current loop.
 +         !current_loop->IsBitSet(candidate->id))) {
 +      continue;
 +    }
 +    DCHECK(tmp_stack->empty());
 +    tmp_stack->push_back(candidate->id);
 +    candidate_reachable.ClearAllBits();
 +    size_t num_reachable = 0u;
 +    while (!tmp_stack->empty()) {
 +      BasicBlockId current_id = tmp_stack->back();
 +      tmp_stack->pop_back();
 +      BasicBlock* current_bb = mir_graph->GetBasicBlock(current_id);
 +      DCHECK(current_bb != nullptr);
 +      ChildBlockIterator child_iter(current_bb, mir_graph);
 +      BasicBlock* child_bb = child_iter.Next();
 +      for ( ; child_bb != nullptr; child_bb = child_iter.Next()) {
 +        DCHECK(!child_bb->hidden);
 +        if (child_bb->visited ||                            // Already processed, or
 +            (current_loop != nullptr &&                     // outside current loop.
 +             !current_loop->IsBitSet(child_bb->id))) {
 +          continue;
 +        }
 +        if (!candidate_reachable.IsBitSet(child_bb->id)) {
 +          candidate_reachable.SetBit(child_bb->id);
 +          tmp_stack->push_back(child_bb->id);
 +          num_reachable += 1u;
 +        }
 +      }
 +    }
 +    if (fall_back_num_reachable < num_reachable) {
 +      fall_back_num_reachable = num_reachable;
 +      fall_back = candidate;
 +    }
 +  }
 +  return fall_back;
 +}
  
 -    if (bb == nullptr) {
 -      break;
 +// Compute from which unvisited blocks is bb_id reachable through unvisited blocks.
 +static void ComputeUnvisitedReachableFrom(MIRGraph* mir_graph, BasicBlockId bb_id,
 +                                          ArenaBitVector* reachable,
 +                                          ScopedArenaVector<BasicBlockId>* tmp_stack) {
 +  // NOTE: Loop heads indicated by the "visited" flag.
 +  DCHECK(tmp_stack->empty());
 +  reachable->ClearAllBits();
 +  tmp_stack->push_back(bb_id);
 +  while (!tmp_stack->empty()) {
 +    BasicBlockId current_id = tmp_stack->back();
 +    tmp_stack->pop_back();
 +    BasicBlock* current_bb = mir_graph->GetBasicBlock(current_id);
 +    DCHECK(current_bb != nullptr);
 +    for (BasicBlockId pred_id : current_bb->predecessors) {
 +      BasicBlock* pred_bb = mir_graph->GetBasicBlock(pred_id);
 +      DCHECK(pred_bb != nullptr);
 +      if (!pred_bb->visited && !reachable->IsBitSet(pred_bb->id)) {
 +        reachable->SetBit(pred_bb->id);
 +        tmp_stack->push_back(pred_bb->id);
 +      }
      }
 +  }
 +}
  
 +void MIRGraph::ComputeTopologicalSortOrder() {
 +  ScopedArenaAllocator allocator(&cu_->arena_stack);
 +  unsigned int num_blocks = GetNumBlocks();
 +
 +  ScopedArenaQueue<BasicBlock*> q(allocator.Adapter());
 +  ScopedArenaVector<size_t> visited_cnt_values(num_blocks, 0u, allocator.Adapter());
 +  ScopedArenaVector<BasicBlockId> loop_head_stack(allocator.Adapter());
 +  size_t max_nested_loops = 0u;
 +  ArenaBitVector loop_exit_blocks(&allocator, num_blocks, false, kBitMapMisc);
 +  loop_exit_blocks.ClearAllBits();
 +
 +  // Count the number of blocks to process and add the entry block(s).
 +  unsigned int num_blocks_to_process = 0u;
 +  for (BasicBlock* bb : block_list_) {
      if (bb->hidden == true) {
        continue;
      }