Skip to content

Commit f8318ef

Browse files
committed
C++: Move TIRVariable to its own file
The `SSAConstruction.getNewIRVariable` was very slow on Wireshark. This was probably because it couldn't join on multiple columns simultaneously. Instead of improving the join, I observed that the `TIRVariable` type was the same between all three IR stages except for a few occurrences of `FunctionIR` that could easily be changed to `Function`. By sharing `TIRVariable` between all the stages, we avoid recomputing it and translating it between every stage, turning the slow `getNewIRVariable` predicate into a no-op. This change means that later stages of the IR can't introduce new variables, but that was already the case because `config/identical-files.json` forced all three `IRVariable.qll` files to be identical.
1 parent 6243c72 commit f8318ef

File tree

6 files changed

+48
-121
lines changed

6 files changed

+48
-121
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,7 @@ import FunctionIR
33
import cpp
44
import semmle.code.cpp.ir.implementation.TempVariableTag
55
private import semmle.code.cpp.ir.internal.TempVariableTag
6-
7-
private newtype TIRVariable =
8-
TIRAutomaticUserVariable(LocalScopeVariable var, FunctionIR funcIR) {
9-
exists(Function func |
10-
func = funcIR.getFunction() and
11-
(
12-
var.getFunction() = func or
13-
var.(Parameter).getCatchBlock().getEnclosingFunction() = func
14-
)
15-
)
16-
} or
17-
TIRStaticUserVariable(Variable var, FunctionIR funcIR) {
18-
(
19-
var instanceof GlobalOrNamespaceVariable or
20-
var instanceof MemberVariable and not var instanceof Field
21-
) and
22-
exists(VariableAccess access |
23-
access.getTarget() = var and
24-
access.getEnclosingFunction() = funcIR.getFunction()
25-
)
26-
} or
27-
TIRTempVariable(FunctionIR funcIR, Locatable ast, TempVariableTag tag,
28-
Type type) {
29-
Construction::hasTempVariable(funcIR.getFunction(), ast, tag, type)
30-
}
6+
private import semmle.code.cpp.ir.internal.TIRVariable
317

328
IRUserVariable getIRUserVariable(Function func, Variable var) {
339
result.getVariable() = var and
@@ -40,7 +16,7 @@ IRUserVariable getIRUserVariable(Function func, Variable var) {
4016
* generated by the AST-to-IR translation (`IRTempVariable`).
4117
*/
4218
abstract class IRVariable extends TIRVariable {
43-
FunctionIR funcIR;
19+
Function func;
4420

4521
abstract string toString();
4622

@@ -72,14 +48,14 @@ abstract class IRVariable extends TIRVariable {
7248
* Gets the IR for the function that references this variable.
7349
*/
7450
final FunctionIR getFunctionIR() {
75-
result = funcIR
51+
result.getFunction() = func
7652
}
7753

7854
/**
7955
* Gets the function that references this variable.
8056
*/
8157
final Function getFunction() {
82-
result = funcIR.getFunction()
58+
result = func
8359
}
8460
}
8561

@@ -126,7 +102,7 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable,
126102
LocalScopeVariable localVar;
127103

128104
IRAutomaticUserVariable() {
129-
this = TIRAutomaticUserVariable(localVar, funcIR) and
105+
this = TIRAutomaticUserVariable(localVar, func) and
130106
var = localVar
131107
}
132108

@@ -137,7 +113,7 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable,
137113

138114
class IRStaticUserVariable extends IRUserVariable, TIRStaticUserVariable {
139115
IRStaticUserVariable() {
140-
this = TIRStaticUserVariable(var, funcIR)
116+
this = TIRStaticUserVariable(var, func)
141117
}
142118
}
143119

@@ -152,7 +128,7 @@ class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable {
152128
Type type;
153129

154130
IRTempVariable() {
155-
this = TIRTempVariable(funcIR, ast, tag, type)
131+
this = TIRTempVariable(func, ast, tag, type)
156132
}
157133

158134
override final Type getType() {

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,8 @@ cached private module Cached {
7171
}
7272

7373
private IRVariable getNewIRVariable(OldIR::IRVariable var) {
74-
result.getFunction() = var.getFunction() and
75-
(
76-
exists(OldIR::IRUserVariable userVar, IRUserVariable newUserVar |
77-
userVar = var and
78-
newUserVar.getVariable() = userVar.getVariable() and
79-
result = newUserVar
80-
) or
81-
exists(OldIR::IRTempVariable tempVar, IRTempVariable newTempVar |
82-
tempVar = var and
83-
newTempVar.getAST() = tempVar.getAST() and
84-
newTempVar.getTag() = tempVar.getTag() and
85-
result = newTempVar
86-
)
87-
)
74+
// This is just a type cast. Both classes derive from the same newtype.
75+
result = var
8876
}
8977

9078
cached newtype TInstruction =

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

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,7 @@ import FunctionIR
33
import cpp
44
import semmle.code.cpp.ir.implementation.TempVariableTag
55
private import semmle.code.cpp.ir.internal.TempVariableTag
6-
7-
private newtype TIRVariable =
8-
TIRAutomaticUserVariable(LocalScopeVariable var, FunctionIR funcIR) {
9-
exists(Function func |
10-
func = funcIR.getFunction() and
11-
(
12-
var.getFunction() = func or
13-
var.(Parameter).getCatchBlock().getEnclosingFunction() = func
14-
)
15-
)
16-
} or
17-
TIRStaticUserVariable(Variable var, FunctionIR funcIR) {
18-
(
19-
var instanceof GlobalOrNamespaceVariable or
20-
var instanceof MemberVariable and not var instanceof Field
21-
) and
22-
exists(VariableAccess access |
23-
access.getTarget() = var and
24-
access.getEnclosingFunction() = funcIR.getFunction()
25-
)
26-
} or
27-
TIRTempVariable(FunctionIR funcIR, Locatable ast, TempVariableTag tag,
28-
Type type) {
29-
Construction::hasTempVariable(funcIR.getFunction(), ast, tag, type)
30-
}
6+
private import semmle.code.cpp.ir.internal.TIRVariable
317

328
IRUserVariable getIRUserVariable(Function func, Variable var) {
339
result.getVariable() = var and
@@ -40,7 +16,7 @@ IRUserVariable getIRUserVariable(Function func, Variable var) {
4016
* generated by the AST-to-IR translation (`IRTempVariable`).
4117
*/
4218
abstract class IRVariable extends TIRVariable {
43-
FunctionIR funcIR;
19+
Function func;
4420

4521
abstract string toString();
4622

@@ -72,14 +48,14 @@ abstract class IRVariable extends TIRVariable {
7248
* Gets the IR for the function that references this variable.
7349
*/
7450
final FunctionIR getFunctionIR() {
75-
result = funcIR
51+
result.getFunction() = func
7652
}
7753

7854
/**
7955
* Gets the function that references this variable.
8056
*/
8157
final Function getFunction() {
82-
result = funcIR.getFunction()
58+
result = func
8359
}
8460
}
8561

@@ -126,7 +102,7 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable,
126102
LocalScopeVariable localVar;
127103

128104
IRAutomaticUserVariable() {
129-
this = TIRAutomaticUserVariable(localVar, funcIR) and
105+
this = TIRAutomaticUserVariable(localVar, func) and
130106
var = localVar
131107
}
132108

@@ -137,7 +113,7 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable,
137113

138114
class IRStaticUserVariable extends IRUserVariable, TIRStaticUserVariable {
139115
IRStaticUserVariable() {
140-
this = TIRStaticUserVariable(var, funcIR)
116+
this = TIRStaticUserVariable(var, func)
141117
}
142118
}
143119

@@ -152,7 +128,7 @@ class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable {
152128
Type type;
153129

154130
IRTempVariable() {
155-
this = TIRTempVariable(funcIR, ast, tag, type)
131+
this = TIRTempVariable(func, ast, tag, type)
156132
}
157133

158134
override final Type getType() {

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,7 @@ import FunctionIR
33
import cpp
44
import semmle.code.cpp.ir.implementation.TempVariableTag
55
private import semmle.code.cpp.ir.internal.TempVariableTag
6-
7-
private newtype TIRVariable =
8-
TIRAutomaticUserVariable(LocalScopeVariable var, FunctionIR funcIR) {
9-
exists(Function func |
10-
func = funcIR.getFunction() and
11-
(
12-
var.getFunction() = func or
13-
var.(Parameter).getCatchBlock().getEnclosingFunction() = func
14-
)
15-
)
16-
} or
17-
TIRStaticUserVariable(Variable var, FunctionIR funcIR) {
18-
(
19-
var instanceof GlobalOrNamespaceVariable or
20-
var instanceof MemberVariable and not var instanceof Field
21-
) and
22-
exists(VariableAccess access |
23-
access.getTarget() = var and
24-
access.getEnclosingFunction() = funcIR.getFunction()
25-
)
26-
} or
27-
TIRTempVariable(FunctionIR funcIR, Locatable ast, TempVariableTag tag,
28-
Type type) {
29-
Construction::hasTempVariable(funcIR.getFunction(), ast, tag, type)
30-
}
6+
private import semmle.code.cpp.ir.internal.TIRVariable
317

328
IRUserVariable getIRUserVariable(Function func, Variable var) {
339
result.getVariable() = var and
@@ -40,7 +16,7 @@ IRUserVariable getIRUserVariable(Function func, Variable var) {
4016
* generated by the AST-to-IR translation (`IRTempVariable`).
4117
*/
4218
abstract class IRVariable extends TIRVariable {
43-
FunctionIR funcIR;
19+
Function func;
4420

4521
abstract string toString();
4622

@@ -72,14 +48,14 @@ abstract class IRVariable extends TIRVariable {
7248
* Gets the IR for the function that references this variable.
7349
*/
7450
final FunctionIR getFunctionIR() {
75-
result = funcIR
51+
result.getFunction() = func
7652
}
7753

7854
/**
7955
* Gets the function that references this variable.
8056
*/
8157
final Function getFunction() {
82-
result = funcIR.getFunction()
58+
result = func
8359
}
8460
}
8561

@@ -126,7 +102,7 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable,
126102
LocalScopeVariable localVar;
127103

128104
IRAutomaticUserVariable() {
129-
this = TIRAutomaticUserVariable(localVar, funcIR) and
105+
this = TIRAutomaticUserVariable(localVar, func) and
130106
var = localVar
131107
}
132108

@@ -137,7 +113,7 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable,
137113

138114
class IRStaticUserVariable extends IRUserVariable, TIRStaticUserVariable {
139115
IRStaticUserVariable() {
140-
this = TIRStaticUserVariable(var, funcIR)
116+
this = TIRStaticUserVariable(var, func)
141117
}
142118
}
143119

@@ -152,7 +128,7 @@ class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable {
152128
Type type;
153129

154130
IRTempVariable() {
155-
this = TIRTempVariable(funcIR, ast, tag, type)
131+
this = TIRTempVariable(func, ast, tag, type)
156132
}
157133

158134
override final Type getType() {

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,8 @@ cached private module Cached {
7171
}
7272

7373
private IRVariable getNewIRVariable(OldIR::IRVariable var) {
74-
result.getFunction() = var.getFunction() and
75-
(
76-
exists(OldIR::IRUserVariable userVar, IRUserVariable newUserVar |
77-
userVar = var and
78-
newUserVar.getVariable() = userVar.getVariable() and
79-
result = newUserVar
80-
) or
81-
exists(OldIR::IRTempVariable tempVar, IRTempVariable newTempVar |
82-
tempVar = var and
83-
newTempVar.getAST() = tempVar.getAST() and
84-
newTempVar.getTag() = tempVar.getTag() and
85-
result = newTempVar
86-
)
87-
)
74+
// This is just a type cast. Both classes derive from the same newtype.
75+
result = var
8876
}
8977

9078
cached newtype TInstruction =
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
private import cpp
2+
private import semmle.code.cpp.ir.implementation.TempVariableTag
3+
private import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as Construction
4+
5+
newtype TIRVariable =
6+
TIRAutomaticUserVariable(LocalScopeVariable var, Function func) {
7+
var.getFunction() = func or
8+
var.(Parameter).getCatchBlock().getEnclosingFunction() = func
9+
} or
10+
TIRStaticUserVariable(Variable var, Function func) {
11+
(
12+
var instanceof GlobalOrNamespaceVariable or
13+
var instanceof MemberVariable and not var instanceof Field
14+
) and
15+
exists(VariableAccess access |
16+
access.getTarget() = var and
17+
access.getEnclosingFunction() = func
18+
)
19+
} or
20+
TIRTempVariable(Function func, Locatable ast, TempVariableTag tag, Type type) {
21+
Construction::hasTempVariable(func, ast, tag, type)
22+
}
23+

0 commit comments

Comments
 (0)