Skip to content

Commit 45a35a8

Browse files
authored
Merge pull request #1265 from rdmarsh2/rdmarsh/cpp/gvn-string-pooling
C++: string pooling in IR value numbering
2 parents 04954f7 + e7ca6c8 commit 45a35a8

File tree

5 files changed

+73
-1
lines changed

5 files changed

+73
-1
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ newtype TValueNumber =
3131
TConstantValueNumber(IRFunction irFunc, Type type, string value) {
3232
constantValueNumber(_, irFunc, type, value)
3333
} or
34+
TStringConstantValueNumber(IRFunction irFunc, Type type, string value) {
35+
stringConstantValueNumber(_, irFunc, type, value)
36+
} or
3437
TFieldAddressValueNumber(IRFunction irFunc, Field field, ValueNumber objectAddress) {
3538
fieldAddressValueNumber(_, irFunc, field, objectAddress)
3639
} or
@@ -127,6 +130,7 @@ private predicate numberableInstruction(Instruction instr) {
127130
instr instanceof InitializeParameterInstruction or
128131
instr instanceof InitializeThisInstruction or
129132
instr instanceof ConstantInstruction or
133+
instr instanceof StringConstantInstruction or
130134
instr instanceof FieldAddressInstruction or
131135
instr instanceof BinaryInstruction or
132136
instr instanceof UnaryInstruction or
@@ -157,6 +161,13 @@ private predicate constantValueNumber(ConstantInstruction instr, IRFunction irFu
157161
instr.getValue() = value
158162
}
159163

164+
private predicate stringConstantValueNumber(StringConstantInstruction instr, IRFunction irFunc, Type type,
165+
string value) {
166+
instr.getEnclosingIRFunction() = irFunc and
167+
instr.getResultType() = type and
168+
instr.getValue().getValue() = value
169+
}
170+
160171
private predicate fieldAddressValueNumber(FieldAddressInstruction instr, IRFunction irFunc,
161172
Field field, ValueNumber objectAddress) {
162173
instr.getEnclosingIRFunction() = irFunc and
@@ -255,6 +266,10 @@ private ValueNumber nonUniqueValueNumber(Instruction instr) {
255266
constantValueNumber(instr, irFunc, type, value) and
256267
result = TConstantValueNumber(irFunc, type, value)
257268
) or
269+
exists(Type type, string value |
270+
stringConstantValueNumber(instr, irFunc, type, value) and
271+
result = TStringConstantValueNumber(irFunc, type, value)
272+
) or
258273
exists(Field field, ValueNumber objectAddress |
259274
fieldAddressValueNumber(instr, irFunc, field, objectAddress) and
260275
result = TFieldAddressValueNumber(irFunc, field, objectAddress)

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ newtype TValueNumber =
3131
TConstantValueNumber(IRFunction irFunc, Type type, string value) {
3232
constantValueNumber(_, irFunc, type, value)
3333
} or
34+
TStringConstantValueNumber(IRFunction irFunc, Type type, string value) {
35+
stringConstantValueNumber(_, irFunc, type, value)
36+
} or
3437
TFieldAddressValueNumber(IRFunction irFunc, Field field, ValueNumber objectAddress) {
3538
fieldAddressValueNumber(_, irFunc, field, objectAddress)
3639
} or
@@ -127,6 +130,7 @@ private predicate numberableInstruction(Instruction instr) {
127130
instr instanceof InitializeParameterInstruction or
128131
instr instanceof InitializeThisInstruction or
129132
instr instanceof ConstantInstruction or
133+
instr instanceof StringConstantInstruction or
130134
instr instanceof FieldAddressInstruction or
131135
instr instanceof BinaryInstruction or
132136
instr instanceof UnaryInstruction or
@@ -157,6 +161,13 @@ private predicate constantValueNumber(ConstantInstruction instr, IRFunction irFu
157161
instr.getValue() = value
158162
}
159163

164+
private predicate stringConstantValueNumber(StringConstantInstruction instr, IRFunction irFunc, Type type,
165+
string value) {
166+
instr.getEnclosingIRFunction() = irFunc and
167+
instr.getResultType() = type and
168+
instr.getValue().getValue() = value
169+
}
170+
160171
private predicate fieldAddressValueNumber(FieldAddressInstruction instr, IRFunction irFunc,
161172
Field field, ValueNumber objectAddress) {
162173
instr.getEnclosingIRFunction() = irFunc and
@@ -255,6 +266,10 @@ private ValueNumber nonUniqueValueNumber(Instruction instr) {
255266
constantValueNumber(instr, irFunc, type, value) and
256267
result = TConstantValueNumber(irFunc, type, value)
257268
) or
269+
exists(Type type, string value |
270+
stringConstantValueNumber(instr, irFunc, type, value) and
271+
result = TStringConstantValueNumber(irFunc, type, value)
272+
) or
258273
exists(Field field, ValueNumber objectAddress |
259274
fieldAddressValueNumber(instr, irFunc, field, objectAddress) and
260275
result = TFieldAddressValueNumber(irFunc, field, objectAddress)

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ newtype TValueNumber =
3131
TConstantValueNumber(IRFunction irFunc, Type type, string value) {
3232
constantValueNumber(_, irFunc, type, value)
3333
} or
34+
TStringConstantValueNumber(IRFunction irFunc, Type type, string value) {
35+
stringConstantValueNumber(_, irFunc, type, value)
36+
} or
3437
TFieldAddressValueNumber(IRFunction irFunc, Field field, ValueNumber objectAddress) {
3538
fieldAddressValueNumber(_, irFunc, field, objectAddress)
3639
} or
@@ -127,6 +130,7 @@ private predicate numberableInstruction(Instruction instr) {
127130
instr instanceof InitializeParameterInstruction or
128131
instr instanceof InitializeThisInstruction or
129132
instr instanceof ConstantInstruction or
133+
instr instanceof StringConstantInstruction or
130134
instr instanceof FieldAddressInstruction or
131135
instr instanceof BinaryInstruction or
132136
instr instanceof UnaryInstruction or
@@ -157,6 +161,13 @@ private predicate constantValueNumber(ConstantInstruction instr, IRFunction irFu
157161
instr.getValue() = value
158162
}
159163

164+
private predicate stringConstantValueNumber(StringConstantInstruction instr, IRFunction irFunc, Type type,
165+
string value) {
166+
instr.getEnclosingIRFunction() = irFunc and
167+
instr.getResultType() = type and
168+
instr.getValue().getValue() = value
169+
}
170+
160171
private predicate fieldAddressValueNumber(FieldAddressInstruction instr, IRFunction irFunc,
161172
Field field, ValueNumber objectAddress) {
162173
instr.getEnclosingIRFunction() = irFunc and
@@ -255,6 +266,10 @@ private ValueNumber nonUniqueValueNumber(Instruction instr) {
255266
constantValueNumber(instr, irFunc, type, value) and
256267
result = TConstantValueNumber(irFunc, type, value)
257268
) or
269+
exists(Type type, string value |
270+
stringConstantValueNumber(instr, irFunc, type, value) and
271+
result = TStringConstantValueNumber(irFunc, type, value)
272+
) or
258273
exists(Field field, ValueNumber objectAddress |
259274
fieldAddressValueNumber(instr, irFunc, field, objectAddress) and
260275
result = TFieldAddressValueNumber(irFunc, field, objectAddress)

cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,3 +744,23 @@ test.cpp:
744744
# 104| v0_28(void) = ReturnValue : r0_27, m0_26
745745
# 104| v0_29(void) = UnmodeledUse : mu*
746746
# 104| v0_30(void) = ExitFunction :
747+
748+
# 112| void test06()
749+
# 112| Block 0
750+
# 112| v0_0(void) = EnterFunction :
751+
# 112| m0_1(unknown) = AliasedDefinition :
752+
# 112| valnum = unique
753+
# 112| mu0_2(unknown) = UnmodeledDefinition :
754+
# 112| valnum = unique
755+
# 113| r0_3(glval<char[2]>) = StringConstant["a"] :
756+
# 113| valnum = r0_3
757+
# 114| r0_4(glval<char[2]>) = StringConstant["b"] :
758+
# 114| valnum = unique
759+
# 115| r0_5(glval<char[2]>) = StringConstant["a"] :
760+
# 115| valnum = r0_3
761+
# 116| r0_6(glval<char[2]>) = StringConstant["c"] :
762+
# 116| valnum = unique
763+
# 117| v0_7(void) = NoOp :
764+
# 112| v0_8(void) = ReturnVoid :
765+
# 112| v0_9(void) = UnmodeledUse : mu*
766+
# 112| v0_10(void) = ExitFunction :

cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/test.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,11 @@ int inheritanceConversions(Derived* pd) {
107107
int y = pb->b;
108108

109109
return y;
110-
}
110+
}
111+
112+
void test06() {
113+
"a";
114+
"b";
115+
"a";
116+
"c";
117+
}

0 commit comments

Comments
 (0)