Skip to content

Commit e7234f5

Browse files
committed
C++: Split index calculation from BB membership
Instead of computing these two things in one predicate, they are computed in separate predicates and then joined. This splits the predicate `primitive_basic_block_member`, which took 77s before, into predicates that together take 18s on a medium-sized db.
1 parent 4cc2745 commit e7234f5

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

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

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,31 @@ private cached module Cached {
4343
(not successors_extended(_, node) and successors_extended(node, _))
4444
}
4545

46+
pragma[noinline]
47+
private predicate member_step(Node n1, Node n2) {
48+
successors_extended(n1, n2) and
49+
not n2 instanceof PrimitiveBasicBlock
50+
}
51+
52+
private int getMemberIndex(Node node) {
53+
primitive_basic_block_entry_node(node) and
54+
result = 0
55+
or
56+
exists(Node prev |
57+
member_step(prev, node) and
58+
result = getMemberIndex(prev) + 1
59+
)
60+
}
61+
62+
private predicate isMember(Node node, PrimitiveBasicBlock bb) {
63+
member_step*(bb, node)
64+
}
65+
4666
/** Holds if `node` is the `pos`th control-flow node in primitive basic block `bb`. */
4767
cached
4868
predicate primitive_basic_block_member(Node node, PrimitiveBasicBlock bb, int pos) {
49-
(node = bb and pos = 0)
50-
or
51-
(not (node instanceof PrimitiveBasicBlock) and
52-
exists (Node pred
53-
| successors_extended(pred, node)
54-
| primitive_basic_block_member(pred, bb, pos - 1)))
69+
pos = getMemberIndex(node) and
70+
isMember(node, bb)
5571
}
5672

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

0 commit comments

Comments
 (0)