diff options
Diffstat (limited to 'compiler/optimizing/nodes.cc')
| -rw-r--r-- | compiler/optimizing/nodes.cc | 65 | 
1 files changed, 50 insertions, 15 deletions
| diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index b26ce0aa13..f36dc6e2fd 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -1420,7 +1420,38 @@ HBasicBlock* HBasicBlock::SplitCatchBlockAfterMoveException() {    }  } -HBasicBlock* HBasicBlock::SplitAfter(HInstruction* cursor) { +HBasicBlock* HBasicBlock::SplitBeforeForInlining(HInstruction* cursor) { +  DCHECK_EQ(cursor->GetBlock(), this); + +  HBasicBlock* new_block = new (GetGraph()->GetArena()) HBasicBlock(GetGraph(), +                                                                    cursor->GetDexPc()); +  new_block->instructions_.first_instruction_ = cursor; +  new_block->instructions_.last_instruction_ = instructions_.last_instruction_; +  instructions_.last_instruction_ = cursor->previous_; +  if (cursor->previous_ == nullptr) { +    instructions_.first_instruction_ = nullptr; +  } else { +    cursor->previous_->next_ = nullptr; +    cursor->previous_ = nullptr; +  } + +  new_block->instructions_.SetBlockOfInstructions(new_block); + +  for (HBasicBlock* successor : GetSuccessors()) { +    new_block->successors_.push_back(successor); +    successor->predecessors_[successor->GetPredecessorIndexOf(this)] = new_block; +  } +  successors_.clear(); + +  for (HBasicBlock* dominated : GetDominatedBlocks()) { +    dominated->dominator_ = new_block; +    new_block->dominated_blocks_.push_back(dominated); +  } +  dominated_blocks_.clear(); +  return new_block; +} + +HBasicBlock* HBasicBlock::SplitAfterForInlining(HInstruction* cursor) {    DCHECK(!cursor->IsControlFlow());    DCHECK_NE(instructions_.last_instruction_, cursor);    DCHECK_EQ(cursor->GetBlock(), this); @@ -1573,6 +1604,20 @@ void HInstructionList::AddAfter(HInstruction* cursor, const HInstructionList& in    }  } +void HInstructionList::AddBefore(HInstruction* cursor, const HInstructionList& instruction_list) { +  DCHECK(Contains(cursor)); +  if (!instruction_list.IsEmpty()) { +    if (cursor == first_instruction_) { +      first_instruction_ = instruction_list.first_instruction_; +    } else { +      cursor->previous_->next_ = instruction_list.first_instruction_; +    } +    instruction_list.last_instruction_->next_ = cursor; +    instruction_list.first_instruction_->previous_ = cursor->previous_; +    cursor->previous_ = instruction_list.last_instruction_; +  } +} +  void HInstructionList::Add(const HInstructionList& instruction_list) {    if (IsEmpty()) {      first_instruction_ = instruction_list.first_instruction_; @@ -1815,18 +1860,6 @@ void HBasicBlock::ReplaceWith(HBasicBlock* other) {    graph_ = nullptr;  } -// Create space in `blocks` for adding `number_of_new_blocks` entries -// starting at location `at`. Blocks after `at` are moved accordingly. -static void MakeRoomFor(ArenaVector<HBasicBlock*>* blocks, -                        size_t number_of_new_blocks, -                        size_t after) { -  DCHECK_LT(after, blocks->size()); -  size_t old_size = blocks->size(); -  size_t new_size = old_size + number_of_new_blocks; -  blocks->resize(new_size); -  std::copy_backward(blocks->begin() + after + 1u, blocks->begin() + old_size, blocks->end()); -} -  void HGraph::DeleteDeadEmptyBlock(HBasicBlock* block) {    DCHECK_EQ(block->GetGraph(), this);    DCHECK(block->GetSuccessors().empty()); @@ -1880,7 +1913,8 @@ HInstruction* HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) {      DCHECK(!body->IsInLoop());      HInstruction* last = body->GetLastInstruction(); -    invoke->GetBlock()->instructions_.AddAfter(invoke, body->GetInstructions()); +    // Note that we add instructions before the invoke only to simplify polymorphic inlining. +    invoke->GetBlock()->instructions_.AddBefore(invoke, body->GetInstructions());      body->GetInstructions().SetBlockOfInstructions(invoke->GetBlock());      // Replace the invoke with the return value of the inlined graph. @@ -1898,7 +1932,8 @@ HInstruction* HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) {      // with the second half.      ArenaAllocator* allocator = outer_graph->GetArena();      HBasicBlock* at = invoke->GetBlock(); -    HBasicBlock* to = at->SplitAfter(invoke); +    // Note that we split before the invoke only to simplify polymorphic inlining. +    HBasicBlock* to = at->SplitBeforeForInlining(invoke);      HBasicBlock* first = entry_block_->GetSuccessors()[0];      DCHECK(!first->IsInLoop()); |