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:
Jonas Jensen
2019-03-05 11:22:02 +01:00
parent a3f452b8ae
commit d310338c9b

View File

@@ -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)
)
}
/**