mirror of
https://github.com/github/codeql.git
synced 2026-04-24 08:15:14 +02:00
C++: improve irreducible back edge detection
This commit is contained in:
committed by
Robert Marsh
parent
ba7cb8f4ae
commit
aff4066020
@@ -70,21 +70,26 @@ predicate semBackEdge(SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionP
|
||||
// Conservatively assume that every edge is a back edge if we don't have dominance information.
|
||||
(
|
||||
phi.getBasicBlock().bbDominates(edge.getOrigBlock()) or
|
||||
trimmedReachable(phi.getBasicBlock(), edge.getOrigBlock()) or
|
||||
irreducibleSccEdge(phi.getBasicBlock(), edge.getOrigBlock()) or
|
||||
not edge.getOrigBlock().hasDominanceInformation()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate trimmedReachable(SemBasicBlock b1, SemBasicBlock b2) {
|
||||
b1 = b2
|
||||
or
|
||||
exists(SemBasicBlock mid |
|
||||
trimmedReachable(b1, mid) and
|
||||
trimmedEdges(mid, b2)
|
||||
)
|
||||
/**
|
||||
* Holds if the edge from b1 to b2 is part of a multiple-entry cycle in an irreducible control flow
|
||||
* graph.
|
||||
*
|
||||
* An ireducible control flow graph is one where the usual dominance-based back edge detection does
|
||||
* not work, because there is a cycle with multiple entry points, meaning there are
|
||||
* mutually-reachable basic blocks where neither dominates the other. For such a graph, we first
|
||||
* all detectable back-edges using the normal condition that the predecessor block is dominated by
|
||||
* the successor block, then mark all edges in a cycle in the resulting graph as back edges.
|
||||
*/
|
||||
private predicate irreducibleSccEdge(SemBasicBlock b1, SemBasicBlock b2) {
|
||||
trimmedEdge(b1, b2) and trimmedEdge+(b2, b1)
|
||||
}
|
||||
|
||||
private predicate trimmedEdges(SemBasicBlock pred, SemBasicBlock succ) {
|
||||
private predicate trimmedEdge(SemBasicBlock pred, SemBasicBlock succ) {
|
||||
pred.getASuccessor() = succ and
|
||||
not succ.bbDominates(pred)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user