Skip to content

Commit b16d90e

Browse files
author
Robert Marsh
committed
C++: separate IR ValueNumber newtype and interface
1 parent 3313af5 commit b16d90e

File tree

10 files changed

+815
-780
lines changed

10 files changed

+815
-780
lines changed

config/identical-files.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@
181181
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintSSA.qll",
182182
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll"
183183
],
184+
"C++ IR ValueNumberInternal": [
185+
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll",
186+
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll",
187+
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll"
188+
],
184189
"C++ IR ValueNumber": [
185190
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll",
186191
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll",
Lines changed: 3 additions & 259 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
private import internal.ValueNumberingInternal
2-
private import cpp
2+
private import internal.ValueNumberingImports
33
private import IR
44

55
/**
@@ -15,51 +15,13 @@ class ValueNumberPropertyProvider extends IRPropertyProvider {
1515
}
1616
}
1717

18-
newtype TValueNumber =
19-
TVariableAddressValueNumber(IRFunction irFunc, IRVariable var) {
20-
variableAddressValueNumber(_, irFunc, var)
21-
} or
22-
TInitializeParameterValueNumber(IRFunction irFunc, IRVariable var) {
23-
initializeParameterValueNumber(_, irFunc, var)
24-
} or
25-
TInitializeThisValueNumber(IRFunction irFunc) { initializeThisValueNumber(_, irFunc) } or
26-
TConstantValueNumber(IRFunction irFunc, Type type, string value) {
27-
constantValueNumber(_, irFunc, type, value)
28-
} or
29-
TStringConstantValueNumber(IRFunction irFunc, Type type, string value) {
30-
stringConstantValueNumber(_, irFunc, type, value)
31-
} or
32-
TFieldAddressValueNumber(IRFunction irFunc, Field field, ValueNumber objectAddress) {
33-
fieldAddressValueNumber(_, irFunc, field, objectAddress)
34-
} or
35-
TBinaryValueNumber(
36-
IRFunction irFunc, Opcode opcode, Type type, ValueNumber leftOperand, ValueNumber rightOperand
37-
) {
38-
binaryValueNumber(_, irFunc, opcode, type, leftOperand, rightOperand)
39-
} or
40-
TPointerArithmeticValueNumber(
41-
IRFunction irFunc, Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
42-
ValueNumber rightOperand
43-
) {
44-
pointerArithmeticValueNumber(_, irFunc, opcode, type, elementSize, leftOperand, rightOperand)
45-
} or
46-
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, Type type, ValueNumber operand) {
47-
unaryValueNumber(_, irFunc, opcode, type, operand)
48-
} or
49-
TInheritanceConversionValueNumber(
50-
IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand
51-
) {
52-
inheritanceConversionValueNumber(_, irFunc, opcode, baseClass, derivedClass, operand)
53-
} or
54-
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
55-
5618
/**
5719
* The value number assigned to a particular set of instructions that produce equivalent results.
5820
*/
5921
class ValueNumber extends TValueNumber {
6022
final string toString() { result = getExampleInstruction().getResultId() }
6123

62-
final Location getLocation() { result = getExampleInstruction().getLocation() }
24+
final Language::Location getLocation() { result = getExampleInstruction().getLocation() }
6325

6426
/**
6527
* Gets the instructions that have been assigned this value number. This will always produce at
@@ -85,231 +47,13 @@ class ValueNumber extends TValueNumber {
8547
final Operand getAUse() { this = valueNumber(result.getDef()) }
8648
}
8749

88-
/**
89-
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
90-
* operand.
91-
* For example:
92-
* ```
93-
* Point p = { 1, 2 };
94-
* Point q = p;
95-
* int a = p.x;
96-
* ```
97-
* The use of `p` on line 2 is linked to the definition of `p` on line 1, and is congruent to that
98-
* definition because it accesses the exact same memory.
99-
* The use of `p.x` on line 3 is linked to the definition of `p` on line 1 as well, but is not
100-
* congruent to that definition because `p.x` accesses only a subset of the memory defined by `p`.
101-
*/
102-
private class CongruentCopyInstruction extends CopyInstruction {
103-
CongruentCopyInstruction() {
104-
this.getSourceValueOperand().getDefinitionOverlap() instanceof MustExactlyOverlap
105-
}
106-
}
107-
108-
/**
109-
* Holds if this library knows how to assign a value number to the specified instruction, other than
110-
* a `unique` value number that is never shared by multiple instructions.
111-
*/
112-
private predicate numberableInstruction(Instruction instr) {
113-
instr instanceof VariableAddressInstruction
114-
or
115-
instr instanceof InitializeParameterInstruction
116-
or
117-
instr instanceof InitializeThisInstruction
118-
or
119-
instr instanceof ConstantInstruction
120-
or
121-
instr instanceof StringConstantInstruction
122-
or
123-
instr instanceof FieldAddressInstruction
124-
or
125-
instr instanceof BinaryInstruction
126-
or
127-
instr instanceof UnaryInstruction and not instr instanceof CopyInstruction
128-
or
129-
instr instanceof PointerArithmeticInstruction
130-
or
131-
instr instanceof CongruentCopyInstruction
132-
}
133-
134-
private predicate variableAddressValueNumber(
135-
VariableAddressInstruction instr, IRFunction irFunc, IRVariable var
136-
) {
137-
instr.getEnclosingIRFunction() = irFunc and
138-
instr.getVariable() = var
139-
}
140-
141-
private predicate initializeParameterValueNumber(
142-
InitializeParameterInstruction instr, IRFunction irFunc, IRVariable var
143-
) {
144-
instr.getEnclosingIRFunction() = irFunc and
145-
instr.getVariable() = var
146-
}
147-
148-
private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRFunction irFunc) {
149-
instr.getEnclosingIRFunction() = irFunc
150-
}
151-
152-
private predicate constantValueNumber(
153-
ConstantInstruction instr, IRFunction irFunc, Type type, string value
154-
) {
155-
instr.getEnclosingIRFunction() = irFunc and
156-
instr.getResultType() = type and
157-
instr.getValue() = value
158-
}
159-
160-
private predicate stringConstantValueNumber(
161-
StringConstantInstruction instr, IRFunction irFunc, Type type, string value
162-
) {
163-
instr.getEnclosingIRFunction() = irFunc and
164-
instr.getResultType() = type and
165-
instr.getValue().getValue() = value
166-
}
167-
168-
private predicate fieldAddressValueNumber(
169-
FieldAddressInstruction instr, IRFunction irFunc, Field field, ValueNumber objectAddress
170-
) {
171-
instr.getEnclosingIRFunction() = irFunc and
172-
instr.getField() = field and
173-
valueNumber(instr.getObjectAddress()) = objectAddress
174-
}
175-
176-
private predicate binaryValueNumber(
177-
BinaryInstruction instr, IRFunction irFunc, Opcode opcode, Type type, ValueNumber leftOperand,
178-
ValueNumber rightOperand
179-
) {
180-
instr.getEnclosingIRFunction() = irFunc and
181-
not instr instanceof PointerArithmeticInstruction and
182-
instr.getOpcode() = opcode and
183-
instr.getResultType() = type and
184-
valueNumber(instr.getLeft()) = leftOperand and
185-
valueNumber(instr.getRight()) = rightOperand
186-
}
187-
188-
private predicate pointerArithmeticValueNumber(
189-
PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, Type type, int elementSize,
190-
ValueNumber leftOperand, ValueNumber rightOperand
191-
) {
192-
instr.getEnclosingIRFunction() = irFunc and
193-
instr.getOpcode() = opcode and
194-
instr.getResultType() = type and
195-
instr.getElementSize() = elementSize and
196-
valueNumber(instr.getLeft()) = leftOperand and
197-
valueNumber(instr.getRight()) = rightOperand
198-
}
199-
200-
private predicate unaryValueNumber(
201-
UnaryInstruction instr, IRFunction irFunc, Opcode opcode, Type type, ValueNumber operand
202-
) {
203-
instr.getEnclosingIRFunction() = irFunc and
204-
not instr instanceof InheritanceConversionInstruction and
205-
not instr instanceof CopyInstruction and
206-
instr.getOpcode() = opcode and
207-
instr.getResultType() = type and
208-
valueNumber(instr.getUnary()) = operand
209-
}
210-
211-
private predicate inheritanceConversionValueNumber(
212-
InheritanceConversionInstruction instr, IRFunction irFunc, Opcode opcode, Class baseClass,
213-
Class derivedClass, ValueNumber operand
214-
) {
215-
instr.getEnclosingIRFunction() = irFunc and
216-
instr.getOpcode() = opcode and
217-
instr.getBaseClass() = baseClass and
218-
instr.getDerivedClass() = derivedClass and
219-
valueNumber(instr.getUnary()) = operand
220-
}
221-
222-
/**
223-
* Holds if `instr` should be assigned a unique value number because this library does not know how
224-
* to determine if two instances of that instruction are equivalent.
225-
*/
226-
private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) {
227-
instr.getEnclosingIRFunction() = irFunc and
228-
not instr.getResultType() instanceof VoidType and
229-
not numberableInstruction(instr)
230-
}
231-
23250
/**
23351
* Gets the value number assigned to `instr`, if any. Returns at most one result.
23452
*/
235-
cached
236-
ValueNumber valueNumber(Instruction instr) {
237-
result = nonUniqueValueNumber(instr)
238-
or
239-
exists(IRFunction irFunc |
240-
uniqueValueNumber(instr, irFunc) and
241-
result = TUniqueValueNumber(irFunc, instr)
242-
)
243-
}
53+
ValueNumber valueNumber(Instruction instr) { result = tvalueNumber(instr) }
24454

24555
/**
24656
* Gets the value number assigned to the exact definition of `op`, if any.
24757
* Returns at most one result.
24858
*/
24959
ValueNumber valueNumberOfOperand(Operand op) { result = valueNumber(op.getDef()) }
250-
251-
/**
252-
* Gets the value number assigned to `instr`, if any, unless that instruction is assigned a unique
253-
* value number.
254-
*/
255-
private ValueNumber nonUniqueValueNumber(Instruction instr) {
256-
exists(IRFunction irFunc |
257-
irFunc = instr.getEnclosingIRFunction() and
258-
(
259-
exists(IRVariable var |
260-
variableAddressValueNumber(instr, irFunc, var) and
261-
result = TVariableAddressValueNumber(irFunc, var)
262-
)
263-
or
264-
exists(IRVariable var |
265-
initializeParameterValueNumber(instr, irFunc, var) and
266-
result = TInitializeParameterValueNumber(irFunc, var)
267-
)
268-
or
269-
initializeThisValueNumber(instr, irFunc) and
270-
result = TInitializeThisValueNumber(irFunc)
271-
or
272-
exists(Type type, string value |
273-
constantValueNumber(instr, irFunc, type, value) and
274-
result = TConstantValueNumber(irFunc, type, value)
275-
)
276-
or
277-
exists(Type type, string value |
278-
stringConstantValueNumber(instr, irFunc, type, value) and
279-
result = TStringConstantValueNumber(irFunc, type, value)
280-
)
281-
or
282-
exists(Field field, ValueNumber objectAddress |
283-
fieldAddressValueNumber(instr, irFunc, field, objectAddress) and
284-
result = TFieldAddressValueNumber(irFunc, field, objectAddress)
285-
)
286-
or
287-
exists(Opcode opcode, Type type, ValueNumber leftOperand, ValueNumber rightOperand |
288-
binaryValueNumber(instr, irFunc, opcode, type, leftOperand, rightOperand) and
289-
result = TBinaryValueNumber(irFunc, opcode, type, leftOperand, rightOperand)
290-
)
291-
or
292-
exists(Opcode opcode, Type type, ValueNumber operand |
293-
unaryValueNumber(instr, irFunc, opcode, type, operand) and
294-
result = TUnaryValueNumber(irFunc, opcode, type, operand)
295-
)
296-
or
297-
exists(Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand |
298-
inheritanceConversionValueNumber(instr, irFunc, opcode, baseClass, derivedClass, operand) and
299-
result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand)
300-
)
301-
or
302-
exists(
303-
Opcode opcode, Type type, int elementSize, ValueNumber leftOperand, ValueNumber rightOperand
304-
|
305-
pointerArithmeticValueNumber(instr, irFunc, opcode, type, elementSize, leftOperand,
306-
rightOperand) and
307-
result = TPointerArithmeticValueNumber(irFunc, opcode, type, elementSize, leftOperand,
308-
rightOperand)
309-
)
310-
or
311-
// The value number of a copy is just the value number of its source value.
312-
result = valueNumber(instr.(CongruentCopyInstruction).getSourceValue())
313-
)
314-
)
315-
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import semmle.code.cpp.ir.implementation.aliased_ssa.IR as IR
2+
import semmle.code.cpp.ir.internal.IRCppLanguage as Language

0 commit comments

Comments
 (0)