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.
This commit is contained in:
Dave Bartolomeo
2018-11-21 15:35:05 -08:00
parent 62db19bee7
commit 03802ed409
3 changed files with 85 additions and 7 deletions

View File

@@ -59,18 +59,36 @@ private predicate locationSortKeys(Locatable ast, string file, int line,
)
}
private Function getEnclosingFunction(Locatable ast) {
result = ast.(Expr).getEnclosingFunction() or
result = ast.(Stmt).getEnclosingFunction() or
result = ast.(Initializer).getExpr().getEnclosingFunction() or
result = ast.(Parameter).getFunction() or
exists(DeclStmt stmt |
stmt.getADeclarationEntry() = ast and
result = stmt.getEnclosingFunction()
) or
result = ast
}
/**
* Most nodes are just a wrapper around `Locatable`, but we do synthesize new
* nodes for things like parameter lists and constructor init lists.
*/
private newtype TPrintASTNode =
TASTNode(Locatable ast) or
TParametersNode(Function func) or
TASTNode(Locatable ast) {
shouldPrintFunction(getEnclosingFunction(ast))
} or
TParametersNode(Function func) {
shouldPrintFunction(func)
} or
TConstructorInitializersNode(Constructor ctor) {
ctor.hasEntryPoint()
ctor.hasEntryPoint() and
shouldPrintFunction(ctor)
} or
TDestructorDestructionsNode(Destructor dtor) {
dtor.hasEntryPoint()
dtor.hasEntryPoint() and
shouldPrintFunction(dtor)
}
/**

View File

@@ -0,0 +1,19 @@
import cpp
private newtype TIRConfiguration = MkIRConfiguration()
/**
* The query can extend this class to control which functions have IR generated for them.
*/
class IRConfiguration extends TIRConfiguration {
string toString() {
result = "IRConfiguration"
}
/**
* Holds if IR should be created for function `func`. By default, holds for all functions.
*/
predicate shouldCreateIRForFunction(Function func) {
any()
}
}

View File

@@ -1,5 +1,40 @@
private import IR
import cpp
import semmle.code.cpp.ir.IRConfiguration
private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
/**
* The query can extend this class to control which functions are printed.
*/
class PrintIRConfiguration extends TPrintIRConfiguration {
string toString() {
result = "PrintIRConfiguration"
}
/**
* Holds if the IR for `func` should be printed. By default, holds for all
* functions.
*/
predicate shouldPrintFunction(Function func) {
any()
}
}
private predicate shouldPrintFunction(Function func) {
exists(PrintIRConfiguration config |
config.shouldPrintFunction(func)
)
}
/**
* Override of `IRConfiguration` to only create IR for the functions that are to be dumped.
*/
private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldCreateIRForFunction(Function func) {
shouldPrintFunction(func)
}
}
private string getAdditionalInstructionProperty(Instruction instr, string key) {
exists(IRPropertyProvider provider |
@@ -14,9 +49,15 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
}
private newtype TPrintableIRNode =
TPrintableFunctionIR(FunctionIR funcIR) or
TPrintableIRBlock(IRBlock block) or
TPrintableInstruction(Instruction instr)
TPrintableFunctionIR(FunctionIR funcIR) {
shouldPrintFunction(funcIR.getFunction())
} or
TPrintableIRBlock(IRBlock block) {
shouldPrintFunction(block.getFunction())
} or
TPrintableInstruction(Instruction instr) {
shouldPrintFunction(instr.getFunction())
}
/**
* A node to be emitted in the IR graph.