mirror of
https://github.com/github/codeql.git
synced 2025-12-17 17:23:36 +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
|
||||
|
||||
/* 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`. */
|
||||
pragma[noinline]
|
||||
* `x` dominates a predecessor of `w` but does not strictly dominate `w`.
|
||||
*
|
||||
* This implementation is equivalent to:
|
||||
*
|
||||
* bbDominates(x, w.getAPredecessor()) and not bbStrictlyDominates(x, 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