diff options
| author | 2015-06-26 08:56:45 +0000 | |
|---|---|---|
| committer | 2015-06-26 08:56:46 +0000 | |
| commit | 2f81cd8f4ff21caf133024795bd5ae028c9f68cd (patch) | |
| tree | 9f7124df650984b848e00625c4185641b5f1650c /compiler/optimizing/nodes.cc | |
| parent | e4a15549608b1c5b1e1cb32f840a8467602dcc14 (diff) | |
| parent | 0b5c7d1994b76090afcc825e737f2b8c546da2f8 (diff) | |
Merge "ART: Implement try/catch blocks in Builder"
Diffstat (limited to 'compiler/optimizing/nodes.cc')
| -rw-r--r-- | compiler/optimizing/nodes.cc | 66 | 
1 files changed, 55 insertions, 11 deletions
| diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index a6390af1f2..881f9ec117 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -189,15 +189,20 @@ void HGraph::TransformToSsa() {    ssa_builder.BuildSsa();  } -void HGraph::SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor) { -  // Insert a new node between `block` and `successor` to split the -  // critical edge. +HBasicBlock* HGraph::SplitEdge(HBasicBlock* block, HBasicBlock* successor) {    HBasicBlock* new_block = new (arena_) HBasicBlock(this, successor->GetDexPc());    AddBlock(new_block); -  new_block->AddInstruction(new (arena_) HGoto());    // Use `InsertBetween` to ensure the predecessor index and successor index of    // `block` and `successor` are preserved.    new_block->InsertBetween(block, successor); +  return new_block; +} + +void HGraph::SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor) { +  // Insert a new node between `block` and `successor` to split the +  // critical edge. +  HBasicBlock* new_block = SplitEdge(block, successor); +  new_block->AddInstruction(new (arena_) HGoto());    if (successor->IsLoopHeader()) {      // If we split at a back edge boundary, make the new block the back edge.      HLoopInformation* info = successor->GetLoopInformation(); @@ -1019,6 +1024,35 @@ void HInstruction::MoveBefore(HInstruction* cursor) {    }  } +HBasicBlock* HBasicBlock::SplitBefore(HInstruction* cursor) { +  DCHECK(!graph_->IsInSsaForm()) << "Support for SSA form not implemented"; +  DCHECK_EQ(cursor->GetBlock(), this); + +  HBasicBlock* new_block = new (GetGraph()->GetArena()) HBasicBlock(GetGraph(), 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); +  AddInstruction(new (GetGraph()->GetArena()) HGoto()); + +  for (size_t i = 0, e = GetSuccessors().Size(); i < e; ++i) { +    HBasicBlock* successor = GetSuccessors().Get(i); +    new_block->successors_.Add(successor); +    successor->predecessors_.Put(successor->GetPredecessorIndexOf(this), new_block); +  } +  successors_.Reset(); +  AddSuccessor(new_block); + +  return new_block; +} +  HBasicBlock* HBasicBlock::SplitAfter(HInstruction* cursor) {    DCHECK(!cursor->IsControlFlow());    DCHECK_NE(instructions_.last_instruction_, cursor); @@ -1048,14 +1082,24 @@ HBasicBlock* HBasicBlock::SplitAfter(HInstruction* cursor) {    return new_block;  } +bool HBasicBlock::IsExceptionalSuccessor(size_t idx) const { +  return !GetInstructions().IsEmpty() +      && GetLastInstruction()->IsTryBoundary() +      && GetLastInstruction()->AsTryBoundary()->IsExceptionalSuccessor(idx); +} + +static bool HasOnlyOneInstruction(const HBasicBlock& block) { +  return block.GetPhis().IsEmpty() +      && !block.GetInstructions().IsEmpty() +      && block.GetFirstInstruction() == block.GetLastInstruction(); +} +  bool HBasicBlock::IsSingleGoto() const { -  HLoopInformation* loop_info = GetLoopInformation(); -  DCHECK(EndsWithControlFlowInstruction()); -  return GetPhis().IsEmpty() -         && GetFirstInstruction() == GetLastInstruction() -         && GetLastInstruction()->IsGoto() -         // Back edges generate the suspend check. -         && (loop_info == nullptr || !loop_info->IsBackEdge(*this)); +  return HasOnlyOneInstruction(*this) && GetLastInstruction()->IsGoto(); +} + +bool HBasicBlock::IsSingleTryBoundary() const { +  return HasOnlyOneInstruction(*this) && GetLastInstruction()->IsTryBoundary();  }  bool HBasicBlock::EndsWithControlFlowInstruction() const { |