Skip to content

Commit 55f157e

Browse files
jbjRobert Marsh
authored andcommitted
C++: Fix overlappingVariableMemoryLocations perf
The `overlappingVariableMemoryLocations` predicate was a helper predicate introduced to fix a join-order issue in `overlappingIRVariableMemoryLocations`. Unfortunately it caused a performance issue of its own because it could grow too large. On the small project (38MB zip) awslabs/s2n there were 181M rows in `overlappingVariableMemoryLocations`, and it took 134s to evaluate. The fix is to collapse the two predicates into one and fix join ordering by including an extra column in the predicates being joined. In addition, some parameters were reordered to avoid the overhead of auto-generated `join_rhs` predicates. Tuple counts of `overlappingVariableMemoryLocations` before: 623285 ~176% {2} r1 = JOIN AliasedSSA::isCoveredOffset#fff_120#join_rhs AS L WITH AliasedSSA::isCoveredOffset#fff_120#join_rhs AS R ON FIRST 2 OUTPUT L.<2>, R.<2> 119138 ~3% {2} r2 = SCAN AliasedSSA::VariableMemoryLocation::getVirtualVariable_dispred#ff AS I OUTPUT I.<1>, I.<0> 172192346 ~0% {2} r3 = JOIN r2 WITH AliasedSSA::hasUnknownOffset#ff_10#join_rhs AS R ON FIRST 1 OUTPUT R.<1>, r2.<1> 172815631 ~0% {2} r4 = r1 \/ r3 172192346 ~0% {2} r5 = JOIN r2 WITH AliasedSSA::hasUnknownOffset#ff_10#join_rhs AS R ON FIRST 1 OUTPUT r2.<1>, R.<1> 345007977 ~87% {2} r6 = r4 \/ r5 return r6 Tuple counts of `overlappingIRVariableMemoryLocations` after: 117021 ~134% {2} r1 = JOIN AliasedSSA::isCoveredOffset#ffff AS L WITH AliasedSSA::isCoveredOffset#ffff AS R ON FIRST 3 OUTPUT L.<3>, R.<3> 201486 ~1% {2} r2 = JOIN AliasedSSA::hasUnknownOffset#fff AS L WITH AliasedSSA::hasVariableAndVirtualVariable#fff AS R ON FIRST 2 OUTPUT L.<2>, R.<2> 318507 ~26% {2} r3 = r1 \/ r2 201486 ~3% {2} r4 = JOIN AliasedSSA::hasUnknownOffset#fff AS L WITH AliasedSSA::hasVariableAndVirtualVariable#fff AS R ON FIRST 2 OUTPUT R.<2>, L.<2> 519993 ~92% {2} r5 = r3 \/ r4 return r5
1 parent 9b9d712 commit 55f157e

File tree

1 file changed

+24
-17
lines changed
  • cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal

1 file changed

+24
-17
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -401,43 +401,50 @@ private predicate isRelatableMemoryLocation(VariableMemoryLocation vml) {
401401
vml.getStartBitOffset() != Ints::unknown()
402402
}
403403

404-
private predicate isCoveredOffset(VariableMemoryLocation vml, VirtualVariable vv, int offsetRank) {
404+
private predicate isCoveredOffset(
405+
VirtualVariable vv, IRVariable var, int offsetRank, VariableMemoryLocation vml
406+
) {
405407
exists(int startRank, int endRank |
406408
vml.getStartBitOffset() = rank[startRank](IntValue offset_ | isRelevantOffset(vv, offset_)) and
407409
vml.getEndBitOffset() = rank[endRank](IntValue offset_ | isRelevantOffset(vv, offset_)) and
408-
vv = vml.getVirtualVariable() and
410+
hasVariableAndVirtualVariable(vv, var, vml) and
409411
isRelatableMemoryLocation(vml) and
410412
offsetRank in [startRank .. endRank]
411413
)
412414
}
413415

414-
private predicate hasUnknownOffset(VariableMemoryLocation vml, VirtualVariable vv) {
415-
vml.getVirtualVariable() = vv and
416+
private predicate hasUnknownOffset(VirtualVariable vv, IRVariable var, VariableMemoryLocation vml) {
417+
hasVariableAndVirtualVariable(vv, var, vml) and
416418
(
417419
vml.getStartBitOffset() = Ints::unknown() or
418420
vml.getEndBitOffset() = Ints::unknown()
419421
)
420422
}
421423

422-
private predicate overlappingVariableMemoryLocations(
423-
VariableMemoryLocation def, VariableMemoryLocation use
424+
private predicate hasVariableAndVirtualVariable(
425+
VirtualVariable vv, IRVariable var, VariableMemoryLocation vml
424426
) {
425-
exists(VirtualVariable vv, int offsetRank |
426-
isCoveredOffset(def, vv, offsetRank) and isCoveredOffset(use, vv, offsetRank)
427-
)
428-
or
429-
hasUnknownOffset(def, use.getVirtualVariable())
430-
or
431-
hasUnknownOffset(use, def.getVirtualVariable())
427+
var = vml.getVariable() and
428+
vv = vml.getVirtualVariable()
432429
}
433430

434-
// Internal ticket: QL-937
435-
pragma[noopt]
436431
private predicate overlappingIRVariableMemoryLocations(
437432
VariableMemoryLocation def, VariableMemoryLocation use
438433
) {
439-
overlappingVariableMemoryLocations(def, use) and
440-
def.getVariable() = use.getVariable()
434+
exists(VirtualVariable vv, IRVariable var, int offsetRank |
435+
isCoveredOffset(vv, var, offsetRank, def) and
436+
isCoveredOffset(vv, var, offsetRank, use)
437+
)
438+
or
439+
exists(VirtualVariable vv, IRVariable var |
440+
hasUnknownOffset(vv, var, def) and
441+
hasVariableAndVirtualVariable(vv, var, use)
442+
)
443+
or
444+
exists(VirtualVariable vv, IRVariable var |
445+
hasUnknownOffset(vv, var, use) and
446+
hasVariableAndVirtualVariable(vv, var, def)
447+
)
441448
}
442449

443450
private Overlap getVariableMemoryLocationOverlap(

0 commit comments

Comments
 (0)