11private import internal.ValueNumberingInternal
2- private import cpp
2+ private import internal.ValueNumberingImports
33private 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 */
5921class 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 */
24959ValueNumber 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- }
0 commit comments