mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +01:00
C++: Implement dominanceFrontier with recursion
This implementation is borrowed from Java's QL library and offers a
great performance improvement. For example, on Wireshark the performance
goes from
Dominance::bbDominates#ff ....... 40.3s
SSAUtils::dominanceFrontier#ff .. 30s
to
SSAUtils::dominanceFrontier#ff .. 418ms (executed 67 times)
The big performance problem before was the need to materialize
`bbDominates`, which is the reflexive-transitive "basic block dominates"
relation. It had 79 million rows on Wireshark.
This commit is contained in:
@@ -4,10 +4,19 @@ import semmle.code.cpp.controlflow.SSA // must be imported for proper caching of
|
|||||||
import semmle.code.cpp.rangeanalysis.RangeSSA // must be imported for proper caching of SSAHelper
|
import semmle.code.cpp.rangeanalysis.RangeSSA // must be imported for proper caching of SSAHelper
|
||||||
|
|
||||||
/* The dominance frontier of a block `x` is the set of all blocks `w` such that
|
/* The dominance frontier of a block `x` is the set of all blocks `w` such that
|
||||||
* `x` dominates a predecessor of `w` but does not strictly dominate `w`. */
|
* `x` dominates a predecessor of `w` but does not strictly dominate `w`.
|
||||||
pragma[noinline]
|
*
|
||||||
|
* This implementation is equivalent to:
|
||||||
|
*
|
||||||
|
* bbDominates(x, w.getAPredecessor()) and not bbStrictlyDominates(x, w)
|
||||||
|
*/
|
||||||
private predicate dominanceFrontier(BasicBlock x, BasicBlock w) {
|
private predicate dominanceFrontier(BasicBlock x, BasicBlock w) {
|
||||||
bbDominates(x, w.getAPredecessor()) and not bbStrictlyDominates(x, w)
|
x = w.getAPredecessor() and not bbIDominates(x, w)
|
||||||
|
or
|
||||||
|
exists(BasicBlock prev | dominanceFrontier(prev, w) |
|
||||||
|
bbIDominates(x, prev) and
|
||||||
|
not bbIDominates(x, w)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user