summaryrefslogtreecommitdiff
path: root/compiler/optimizing/graph_checker.cc
diff options
context:
space:
mode:
author David Brazdil <dbrazdil@google.com> 2015-11-06 01:36:20 +0000
committer David Brazdil <dbrazdil@google.com> 2015-11-09 10:27:08 +0000
commitdb51efb3617d15f1cd9e5ff0cc2d934777014e9a (patch)
treefa70acb9f8d090def2cae550db8c2e1f630f31c4 /compiler/optimizing/graph_checker.cc
parent2649cba0fb7cdbd8fa60cb4f2fb320fb2b18ee37 (diff)
ART: Fix critical edge splitting under try/catch
A critical edge would not be split if the predecessor ends with TryBoundary. This would eventually trip liveness analysis because a back edge block would have smaller liveness position than a nested loop. Another implication of this change is that an edge between a loop's pre-header ending with TryBoundary and the header will be split, guaranteeing that a pre-header always has just one successor. Bug: 25493695 Bug: 25454012 Change-Id: I5a13b8bb74509b48f5d628906f7158af007f99ae
Diffstat (limited to 'compiler/optimizing/graph_checker.cc')
-rw-r--r--compiler/optimizing/graph_checker.cc17
1 files changed, 15 insertions, 2 deletions
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index c32ef51988..f77576db6c 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -460,12 +460,18 @@ void SSAChecker::CheckLoop(HBasicBlock* loop_header) {
int id = loop_header->GetBlockId();
HLoopInformation* loop_information = loop_header->GetLoopInformation();
- // Ensure the pre-header block is first in the list of
- // predecessors of a loop header.
+ // Ensure the pre-header block is first in the list of predecessors of a loop
+ // header and that the header block is its only successor.
if (!loop_header->IsLoopPreHeaderFirstPredecessor()) {
AddError(StringPrintf(
"Loop pre-header is not the first predecessor of the loop header %d.",
id));
+ } else if (loop_information->GetPreHeader()->GetSuccessors().size() != 1) {
+ AddError(StringPrintf(
+ "Loop pre-header %d of loop defined by header %d has %zu successors.",
+ loop_information->GetPreHeader()->GetBlockId(),
+ id,
+ loop_information->GetPreHeader()->GetSuccessors().size()));
}
// Ensure the loop header has only one incoming branch and the remaining
@@ -508,6 +514,13 @@ void SSAChecker::CheckLoop(HBasicBlock* loop_header) {
"Loop defined by header %d has an invalid back edge %d.",
id,
back_edge_id));
+ } else if (back_edge->GetLoopInformation() != loop_information) {
+ AddError(StringPrintf(
+ "Back edge %d of loop defined by header %d belongs to nested loop "
+ "with header %d.",
+ back_edge_id,
+ id,
+ back_edge->GetLoopInformation()->GetHeader()->GetBlockId()));
}
}
}