diff options
author | 2015-11-10 11:07:31 +0000 | |
---|---|---|
committer | 2015-11-10 18:28:21 +0000 | |
commit | d26a411adee1e71b3f09dd604ab9b23018037138 (patch) | |
tree | 7e9267d50fb0a9bcd6b14a97653c8e0baf91a575 /compiler/optimizing/graph_checker.cc | |
parent | 8a6463a7052ec69e7c0b94a65b26807f570e6359 (diff) |
ART: Refactor iteration over normal/exceptional successors
Add helper methods on HBasicBlock which return ArrayRef with the
suitable sub-array of the `successors_` list.
Change-Id: I66c83bb56f2984d7550bf77c48110af4087515a8
Diffstat (limited to 'compiler/optimizing/graph_checker.cc')
-rw-r--r-- | compiler/optimizing/graph_checker.cc | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc index 27949f7fe8..091f1c7e89 100644 --- a/compiler/optimizing/graph_checker.cc +++ b/compiler/optimizing/graph_checker.cc @@ -162,13 +162,20 @@ void GraphChecker::VisitBoundsCheck(HBoundsCheck* check) { VisitInstruction(check); } +// Returns true if there exists `index2` such that `index2 > index` and +// `array[index] == array[index2]`. +static bool ContainsSameValueAfter(ArrayRef<HBasicBlock* const> array, size_t index) { + ArrayRef<HBasicBlock* const> tail = array.SubArray(index + 1); + return std::find(tail.begin(), tail.end(), array[index]) != tail.end(); +} + void GraphChecker::VisitTryBoundary(HTryBoundary* try_boundary) { - // Ensure that all exception handlers are catch blocks and that handlers - // are not listed multiple times. + ArrayRef<HBasicBlock* const> handlers = try_boundary->GetExceptionHandlers(); + + // Ensure that all exception handlers are catch blocks. // Note that a normal-flow successor may be a catch block before CFG // simplification. We only test normal-flow successors in SsaChecker. - for (HExceptionHandlerIterator it(*try_boundary); !it.Done(); it.Advance()) { - HBasicBlock* handler = it.Current(); + for (HBasicBlock* handler : handlers) { if (!handler->IsCatchBlock()) { AddError(StringPrintf("Block %d with %s:%d has exceptional successor %d which " "is not a catch block.", @@ -177,9 +184,13 @@ void GraphChecker::VisitTryBoundary(HTryBoundary* try_boundary) { try_boundary->GetId(), handler->GetBlockId())); } - if (current_block_->HasSuccessor(handler, it.CurrentSuccessorIndex() + 1)) { + } + + // Ensure that handlers are not listed multiple times. + for (size_t i = 0, e = handlers.size(); i < e; ++i) { + if (ContainsSameValueAfter(handlers, i)) { AddError(StringPrintf("Exception handler block %d of %s:%d is listed multiple times.", - handler->GetBlockId(), + handlers[i]->GetBlockId(), try_boundary->DebugName(), try_boundary->GetId())); } @@ -371,17 +382,14 @@ void SSAChecker::VisitBasicBlock(HBasicBlock* block) { // Ensure that catch blocks are not normal successors, and normal blocks are // never exceptional successors. - const size_t num_normal_successors = block->NumberOfNormalSuccessors(); - for (size_t j = 0; j < num_normal_successors; ++j) { - HBasicBlock* successor = block->GetSuccessors()[j]; + for (HBasicBlock* successor : block->GetNormalSuccessors()) { if (successor->IsCatchBlock()) { AddError(StringPrintf("Catch block %d is a normal successor of block %d.", successor->GetBlockId(), block->GetBlockId())); } } - for (size_t j = num_normal_successors, e = block->GetSuccessors().size(); j < e; ++j) { - HBasicBlock* successor = block->GetSuccessors()[j]; + for (HBasicBlock* successor : block->GetExceptionalSuccessors()) { if (!successor->IsCatchBlock()) { AddError(StringPrintf("Normal block %d is an exceptional successor of block %d.", successor->GetBlockId(), @@ -394,8 +402,7 @@ void SSAChecker::VisitBasicBlock(HBasicBlock* block) { // predecessors). Exceptional edges are synthesized and hence // not accounted for. if (block->GetSuccessors().size() > 1) { - for (size_t j = 0, e = block->NumberOfNormalSuccessors(); j < e; ++j) { - HBasicBlock* successor = block->GetSuccessors()[j]; + for (HBasicBlock* successor : block->GetNormalSuccessors()) { if (successor->IsExitBlock() && block->IsSingleTryBoundary() && block->GetPredecessors().size() == 1u && |