Skip to content

Commit 16b1517

Browse files
committed
C++: use shortestDistances in PrimitiveBasicBlocks
The use of transitive closure for BB index calculation has been the cause of an out-of-memory error. This commit switches the calculation to use the `shortestDistances` HOP, which still has the problem that the result needs to fit in RAM, but at least the RAM requirements are sure to be linear in the size of the result. The `shortestDistances` HOP is already used for BB index calculation for the C++ IR and for C#. We could guard even better against OOM by switching the calculation to use manual recursion, but that would undo the much-needed performance improvements we got from #123. This change improves performance on Wireshark, which is notorious for having long basic blocks. When I benchmarked `shortestDistances` for #123, it was slower than TC. With the current evaluator, it looks like `shortestDistances` is faster. Performance before was: PrimitiveBasicBlocks::Cached::getMemberIndex#ff ................... 9.7s (executed 8027 times) #PrimitiveBasicBlocks::Cached::member_step#ffPlus ................. 6.6s PrimitiveBasicBlocks::Cached::primitive_basic_block_entry_node#f .. 3.5s PrimitiveBasicBlocks::Cached::primitive_basic_block_member#fff .... 2.3s Performance with this commit is: PrimitiveBasicBlocks::Cached::primitive_basic_block_entry_node#f ................................................................... 3.5s shortestDistances@PrimitiveBasicBlocks::Cached::primitive_basic_block_entry_node#1@PrimitiveBasicBlocks::Cached::member_step#2#fff . 3s PrimitiveBasicBlocks::Cached::primitive_basic_block_member#fff ..................................................................... 963ms
1 parent 61f7c78 commit 16b1517

File tree

1 file changed

+2
-21
lines changed

1 file changed

+2
-21
lines changed

cpp/ql/src/semmle/code/cpp/controlflow/internal/PrimitiveBasicBlocks.qll

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -60,29 +60,10 @@ private cached module Cached {
6060
not n2 instanceof PrimitiveBasicBlock
6161
}
6262

63-
/** Returns the index of `node` in its `PrimitiveBasicBlock`. */
64-
private int getMemberIndex(Node node) {
65-
primitive_basic_block_entry_node(node) and
66-
result = 0
67-
or
68-
exists(Node prev |
69-
member_step(prev, node) and
70-
result = getMemberIndex(prev) + 1
71-
)
72-
}
73-
7463
/** Holds if `node` is the `pos`th control-flow node in primitive basic block `bb`. */
7564
cached
76-
predicate primitive_basic_block_member(Node node, PrimitiveBasicBlock bb, int pos) {
77-
primitive_basic_block_entry_node(bb) and
78-
(
79-
pos = 0 and
80-
node = bb
81-
or
82-
pos = getMemberIndex(node) and
83-
member_step+(bb, node)
84-
)
85-
}
65+
predicate primitive_basic_block_member(Node node, PrimitiveBasicBlock bb, int pos) =
66+
shortestDistances(primitive_basic_block_entry_node/1, member_step/2)(bb, node, pos)
8667

8768
/** Gets the number of control-flow nodes in the primitive basic block `bb`. */
8869
cached

0 commit comments

Comments
 (0)