From 9a3907c97f8a2aa7ae8e81f6783afb7af6c2c5f6 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Mon, 5 Nov 2018 10:23:50 +0100 Subject: [PATCH] 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. --- .../semmle/code/cpp/dataflow/internal/FlowVar.qll | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index 963b648727fb..1e22c1b1997e 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -221,9 +221,7 @@ module FlowVar_internal { BlockVar() { this = TBlockVar(sbb, v) } override VariableAccess getAnAccess() { - result.getTarget() = v and - result = getAReachedBlockVarSBB(this).getANode() and - not overwrite(result, _) + variableAccessInSBB(v, getAReachedBlockVarSBB(this), result) } override predicate definedByInitialValue(LocalScopeVariable lsv) { @@ -373,6 +371,15 @@ module FlowVar_internal { ) } + /** Holds if `va` is a read access to `v` in `sbb`, where `v` is modeled by `BlockVar`. */ + pragma[noinline] + private predicate variableAccessInSBB(Variable v, SubBasicBlock sbb, VariableAccess va) { + exists(TBlockVar(_, v)) and + va.getTarget() = v and + va = sbb.getANode() and + not overwrite(va, _) + } + /** * A local variable that is uninitialized immediately after its declaration. */