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.
This commit is contained in:
Jonas Jensen
2018-11-05 10:23:50 +01:00
parent dc3c5a684c
commit 9a3907c97f

View File

@@ -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.
*/