Skip to content

Commit 0d239e8

Browse files
committed
C++: Manual magic for isInCycle
The `isInCycle` predicate would take a long time on Wireshark with 6GB RAM, sometimes OOMing in the fastTC HOP. Analyzing wireshark with 6GB is important because that's the standard configuration on our Jenkins workers. With this commit, I can analyze Wireshark with 6GB on my laptop. The `getNonPhiOperandDef` predicate on Wireshark is 34M tuples, while `getDefIfHasNeighbors` is 11M tuples, and the TC of `getDefIfHasNeighbors` is 23M tuples (487 MB).
1 parent ecad925 commit 0d239e8

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,19 @@ private module Cached {
102102
result = getMemoryOperandDefinition(instr, _, _)
103103
}
104104

105+
/**
106+
* Gets a non-phi instruction that defines an operand of `instr` but only if
107+
* both `instr` and the result have neighbor on the other side of the edge
108+
* between them. This is a necessary condition for being in a cycle, and it
109+
* removes about two thirds of the tuples that would otherwise be in this
110+
* predicate.
111+
*/
112+
private Instruction getNonPhiOperandDefOfIntermediate(Instruction instr) {
113+
result = getNonPhiOperandDef(instr) and
114+
exists(getNonPhiOperandDef(result)) and
115+
instr = getNonPhiOperandDef(_)
116+
}
117+
105118
/**
106119
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
107120
* through a phi instruction and therefore should be impossible.
@@ -115,7 +128,7 @@ private module Cached {
115128
cached
116129
predicate isInCycle(Instruction instr) {
117130
instr instanceof Instruction and
118-
getNonPhiOperandDef+(instr) = instr
131+
getNonPhiOperandDefOfIntermediate+(instr) = instr
119132
}
120133

121134
cached

0 commit comments

Comments
 (0)