Skip to content

Commit 03802ed

Browse files
C++: Allow filtering of IR creation to speed up dumps
This change provides a mechanism by which a query can tell the IR package to only create IR for certain functions. This is mostly useful for "PrintIR.qll", which uses this feature to avoid the expense of creating IR for functions that aren't going to be printed.
1 parent 62db19b commit 03802ed

File tree

3 files changed

+85
-7
lines changed

3 files changed

+85
-7
lines changed

cpp/ql/src/semmle/code/cpp/PrintAST.qll

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,36 @@ private predicate locationSortKeys(Locatable ast, string file, int line,
5959
)
6060
}
6161

62+
private Function getEnclosingFunction(Locatable ast) {
63+
result = ast.(Expr).getEnclosingFunction() or
64+
result = ast.(Stmt).getEnclosingFunction() or
65+
result = ast.(Initializer).getExpr().getEnclosingFunction() or
66+
result = ast.(Parameter).getFunction() or
67+
exists(DeclStmt stmt |
68+
stmt.getADeclarationEntry() = ast and
69+
result = stmt.getEnclosingFunction()
70+
) or
71+
result = ast
72+
}
73+
6274
/**
6375
* Most nodes are just a wrapper around `Locatable`, but we do synthesize new
6476
* nodes for things like parameter lists and constructor init lists.
6577
*/
6678
private newtype TPrintASTNode =
67-
TASTNode(Locatable ast) or
68-
TParametersNode(Function func) or
79+
TASTNode(Locatable ast) {
80+
shouldPrintFunction(getEnclosingFunction(ast))
81+
} or
82+
TParametersNode(Function func) {
83+
shouldPrintFunction(func)
84+
} or
6985
TConstructorInitializersNode(Constructor ctor) {
70-
ctor.hasEntryPoint()
86+
ctor.hasEntryPoint() and
87+
shouldPrintFunction(ctor)
7188
} or
7289
TDestructorDestructionsNode(Destructor dtor) {
73-
dtor.hasEntryPoint()
90+
dtor.hasEntryPoint() and
91+
shouldPrintFunction(dtor)
7492
}
7593

7694
/**
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import cpp
2+
3+
private newtype TIRConfiguration = MkIRConfiguration()
4+
5+
/**
6+
* The query can extend this class to control which functions have IR generated for them.
7+
*/
8+
class IRConfiguration extends TIRConfiguration {
9+
string toString() {
10+
result = "IRConfiguration"
11+
}
12+
13+
/**
14+
* Holds if IR should be created for function `func`. By default, holds for all functions.
15+
*/
16+
predicate shouldCreateIRForFunction(Function func) {
17+
any()
18+
}
19+
}

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,40 @@
11
private import IR
22
import cpp
3+
import semmle.code.cpp.ir.IRConfiguration
4+
5+
private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
6+
7+
/**
8+
* The query can extend this class to control which functions are printed.
9+
*/
10+
class PrintIRConfiguration extends TPrintIRConfiguration {
11+
string toString() {
12+
result = "PrintIRConfiguration"
13+
}
14+
15+
/**
16+
* Holds if the IR for `func` should be printed. By default, holds for all
17+
* functions.
18+
*/
19+
predicate shouldPrintFunction(Function func) {
20+
any()
21+
}
22+
}
23+
24+
private predicate shouldPrintFunction(Function func) {
25+
exists(PrintIRConfiguration config |
26+
config.shouldPrintFunction(func)
27+
)
28+
}
29+
30+
/**
31+
* Override of `IRConfiguration` to only create IR for the functions that are to be dumped.
32+
*/
33+
private class FilteredIRConfiguration extends IRConfiguration {
34+
override predicate shouldCreateIRForFunction(Function func) {
35+
shouldPrintFunction(func)
36+
}
37+
}
338

439
private string getAdditionalInstructionProperty(Instruction instr, string key) {
540
exists(IRPropertyProvider provider |
@@ -14,9 +49,15 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
1449
}
1550

1651
private newtype TPrintableIRNode =
17-
TPrintableFunctionIR(FunctionIR funcIR) or
18-
TPrintableIRBlock(IRBlock block) or
19-
TPrintableInstruction(Instruction instr)
52+
TPrintableFunctionIR(FunctionIR funcIR) {
53+
shouldPrintFunction(funcIR.getFunction())
54+
} or
55+
TPrintableIRBlock(IRBlock block) {
56+
shouldPrintFunction(block.getFunction())
57+
} or
58+
TPrintableInstruction(Instruction instr) {
59+
shouldPrintFunction(instr.getFunction())
60+
}
2061

2162
/**
2263
* A node to be emitted in the IR graph.

0 commit comments

Comments
 (0)