Skip to content

Commit 9a3907c

Browse files
committed
C++: Performance fix for FlowVar.getAnAccess
The previous formulation of this predicate caused a CP in snapshots where a variable had a large number of definitions and also reached a large number of sub-basic-blocks. This should fix performance of https://github.com/FrodeSolheim/fs-uae and https://github.com/libretro/libretro-uae. The `FlowVar.getAnAccess` predicate is still at risk of CP'ing when a large group of defs has a large group of uses, but that has not been observed to happen in practice yet. We would need to make `localFlowStep` expose phi definitions in order to avoid that risk.
1 parent dc3c5a6 commit 9a3907c

File tree

1 file changed

+10
-3
lines changed
  • cpp/ql/src/semmle/code/cpp/dataflow/internal

1 file changed

+10
-3
lines changed

cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,7 @@ module FlowVar_internal {
221221
BlockVar() { this = TBlockVar(sbb, v) }
222222

223223
override VariableAccess getAnAccess() {
224-
result.getTarget() = v and
225-
result = getAReachedBlockVarSBB(this).getANode() and
226-
not overwrite(result, _)
224+
variableAccessInSBB(v, getAReachedBlockVarSBB(this), result)
227225
}
228226

229227
override predicate definedByInitialValue(LocalScopeVariable lsv) {
@@ -373,6 +371,15 @@ module FlowVar_internal {
373371
)
374372
}
375373

374+
/** Holds if `va` is a read access to `v` in `sbb`, where `v` is modeled by `BlockVar`. */
375+
pragma[noinline]
376+
private predicate variableAccessInSBB(Variable v, SubBasicBlock sbb, VariableAccess va) {
377+
exists(TBlockVar(_, v)) and
378+
va.getTarget() = v and
379+
va = sbb.getANode() and
380+
not overwrite(va, _)
381+
}
382+
376383
/**
377384
* A local variable that is uninitialized immediately after its declaration.
378385
*/

0 commit comments

Comments
 (0)