Skip to content

Commit aff4066

Browse files
committed
C++: improve irreducible back edge detection
1 parent ba7cb8f commit aff4066

File tree

1 file changed

+14
-9
lines changed
  • cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic

1 file changed

+14
-9
lines changed

cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticSSA.qll

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,21 +70,26 @@ predicate semBackEdge(SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionP
7070
// Conservatively assume that every edge is a back edge if we don't have dominance information.
7171
(
7272
phi.getBasicBlock().bbDominates(edge.getOrigBlock()) or
73-
trimmedReachable(phi.getBasicBlock(), edge.getOrigBlock()) or
73+
irreducibleSccEdge(phi.getBasicBlock(), edge.getOrigBlock()) or
7474
not edge.getOrigBlock().hasDominanceInformation()
7575
)
7676
}
7777

78-
private predicate trimmedReachable(SemBasicBlock b1, SemBasicBlock b2) {
79-
b1 = b2
80-
or
81-
exists(SemBasicBlock mid |
82-
trimmedReachable(b1, mid) and
83-
trimmedEdges(mid, b2)
84-
)
78+
/**
79+
* Holds if the edge from b1 to b2 is part of a multiple-entry cycle in an irreducible control flow
80+
* graph.
81+
*
82+
* An ireducible control flow graph is one where the usual dominance-based back edge detection does
83+
* not work, because there is a cycle with multiple entry points, meaning there are
84+
* mutually-reachable basic blocks where neither dominates the other. For such a graph, we first
85+
* all detectable back-edges using the normal condition that the predecessor block is dominated by
86+
* the successor block, then mark all edges in a cycle in the resulting graph as back edges.
87+
*/
88+
private predicate irreducibleSccEdge(SemBasicBlock b1, SemBasicBlock b2) {
89+
trimmedEdge(b1, b2) and trimmedEdge+(b2, b1)
8590
}
8691

87-
private predicate trimmedEdges(SemBasicBlock pred, SemBasicBlock succ) {
92+
private predicate trimmedEdge(SemBasicBlock pred, SemBasicBlock succ) {
8893
pred.getASuccessor() = succ and
8994
not succ.bbDominates(pred)
9095
}

0 commit comments

Comments
 (0)