mirror of
https://github.com/github/codeql.git
synced 2026-05-01 19:55:15 +02:00
C++: Prune getAReachedBlockVarSBB using live vars
On a Postgres snapshot, where the `getAReachedBlockVarSBB` predicate
performs badly because of a Yacc-generated 20,000-line parser loop, that
predicate is reduced from 4m22s to 1m32s plus 5.2s for the live
variables analysis.
This change removes 17,142 rows from `BlockVar.getAnAccess` on Postgres.
I sampled some of them, and they were all of the following form:
while (...) {
T x;
f1(&x); // access
f2(&x); // definition
}
Such accesses are ruled out now because we deliberately lose track of
variables when they go out of scope.
This commit is contained in:
@@ -483,19 +483,48 @@ module FlowVar_internal {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
// The noopt is needed to avoid getting `variableLiveInSBB` joined in before
|
||||
// `getASuccessor`.
|
||||
pragma[noopt]
|
||||
private SubBasicBlock getAReachedBlockVarSBB(TBlockVar start) {
|
||||
start = TBlockVar(result, _)
|
||||
exists(Variable v |
|
||||
start = TBlockVar(result, v) and
|
||||
variableLiveInSBB(result, v)
|
||||
)
|
||||
or
|
||||
exists(SubBasicBlock mid, SubBasicBlock sbbDef, Variable v |
|
||||
start = TBlockVar(sbbDef, v) and
|
||||
mid = getAReachedBlockVarSBB(start) and
|
||||
start = TBlockVar(sbbDef, v) and
|
||||
result = mid.getASuccessor() and
|
||||
variableLiveInSBB(result, v) and
|
||||
not skipLoop(mid, result, sbbDef, v) and
|
||||
not assignmentLikeOperation(result, v, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a value held in `v` at the start of `sbb` (or after the first
|
||||
* assignment, if that assignment is to `v`) might later be read.
|
||||
*/
|
||||
private predicate variableLiveInSBB(SubBasicBlock sbb, Variable v) {
|
||||
variableAccessInSBB(v, sbb, _)
|
||||
or
|
||||
exists(SubBasicBlock succ | succ = sbb.getASuccessor() |
|
||||
variableLiveInSBB(succ, v) and
|
||||
not variableNotLiveBefore(succ, v)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if liveness of `v` should stop propagating backwards from `sbb`.
|
||||
*/
|
||||
private predicate variableNotLiveBefore(SubBasicBlock sbb, Variable v) {
|
||||
assignmentLikeOperation(sbb, v, _, _)
|
||||
or
|
||||
// Liveness of `v` is killed when going backwards from a block that declares it
|
||||
exists(DeclStmt ds | ds.getADeclaration().(LocalVariable) = v and sbb.contains(ds))
|
||||
}
|
||||
|
||||
/** 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) {
|
||||
|
||||
Reference in New Issue
Block a user