@@ -19,19 +19,18 @@ newtype TValueNumber =
19
19
fieldAddressValueNumber ( _, irFunc , field , objectAddress )
20
20
} or
21
21
TBinaryValueNumber (
22
- IRFunction irFunc , Opcode opcode , IRType type , TValueNumber leftOperand ,
23
- TValueNumber rightOperand
22
+ IRFunction irFunc , Opcode opcode , TValueNumber leftOperand , TValueNumber rightOperand
24
23
) {
25
- binaryValueNumber ( _, irFunc , opcode , type , leftOperand , rightOperand )
24
+ binaryValueNumber ( _, irFunc , opcode , leftOperand , rightOperand )
26
25
} or
27
26
TPointerArithmeticValueNumber (
28
- IRFunction irFunc , Opcode opcode , IRType type , int elementSize , TValueNumber leftOperand ,
27
+ IRFunction irFunc , Opcode opcode , int elementSize , TValueNumber leftOperand ,
29
28
TValueNumber rightOperand
30
29
) {
31
- pointerArithmeticValueNumber ( _, irFunc , opcode , type , elementSize , leftOperand , rightOperand )
30
+ pointerArithmeticValueNumber ( _, irFunc , opcode , elementSize , leftOperand , rightOperand )
32
31
} or
33
- TUnaryValueNumber ( IRFunction irFunc , Opcode opcode , IRType type , TValueNumber operand ) {
34
- unaryValueNumber ( _, irFunc , opcode , type , operand )
32
+ TUnaryValueNumber ( IRFunction irFunc , Opcode opcode , TValueNumber operand ) {
33
+ unaryValueNumber ( _, irFunc , opcode , operand )
35
34
} or
36
35
TInheritanceConversionValueNumber (
37
36
IRFunction irFunc , Opcode opcode , Class baseClass , Class derivedClass , TValueNumber operand
@@ -99,14 +98,28 @@ private predicate numberableInstruction(Instruction instr) {
99
98
instr instanceof LoadTotalOverlapInstruction
100
99
}
101
100
101
+ private predicate filteredNumberableInstruction ( Instruction instr ) {
102
+ // count rather than strictcount to handle missing AST elements
103
+ // separate instanceof and inline casts to avoid failed casts with a count of 0
104
+ instr instanceof VariableAddressInstruction and
105
+ count ( instr .( VariableAddressInstruction ) .getIRVariable ( ) .getAST ( ) ) != 1
106
+ or
107
+ instr instanceof ConstantInstruction and
108
+ count ( instr .getResultIRType ( ) ) != 1
109
+ or
110
+ instr instanceof FieldAddressInstruction and
111
+ count ( instr .( FieldAddressInstruction ) .getField ( ) ) != 1
112
+ }
113
+
102
114
private predicate variableAddressValueNumber (
103
115
VariableAddressInstruction instr , IRFunction irFunc , Language:: AST ast
104
116
) {
105
117
instr .getEnclosingIRFunction ( ) = irFunc and
106
118
// The underlying AST element is used as value-numbering key instead of the
107
119
// `IRVariable` to work around a problem where a variable or expression with
108
120
// multiple types gives rise to multiple `IRVariable`s.
109
- instr .getIRVariable ( ) .getAST ( ) = ast
121
+ instr .getIRVariable ( ) .getAST ( ) = ast and
122
+ strictcount ( instr .getIRVariable ( ) .getAST ( ) ) = 1
110
123
}
111
124
112
125
private predicate initializeParameterValueNumber (
@@ -123,10 +136,11 @@ private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRF
123
136
instr .getEnclosingIRFunction ( ) = irFunc
124
137
}
125
138
126
- private predicate constantValueNumber (
139
+ predicate constantValueNumber (
127
140
ConstantInstruction instr , IRFunction irFunc , IRType type , string value
128
141
) {
129
142
instr .getEnclosingIRFunction ( ) = irFunc and
143
+ strictcount ( instr .getResultIRType ( ) ) = 1 and
130
144
instr .getResultIRType ( ) = type and
131
145
instr .getValue ( ) = value
132
146
}
@@ -145,42 +159,40 @@ private predicate fieldAddressValueNumber(
145
159
) {
146
160
instr .getEnclosingIRFunction ( ) = irFunc and
147
161
instr .getField ( ) = field and
162
+ strictcount ( instr .getField ( ) ) = 1 and
148
163
tvalueNumber ( instr .getObjectAddress ( ) ) = objectAddress
149
164
}
150
165
151
166
private predicate binaryValueNumber (
152
- BinaryInstruction instr , IRFunction irFunc , Opcode opcode , IRType type , TValueNumber leftOperand ,
167
+ BinaryInstruction instr , IRFunction irFunc , Opcode opcode , TValueNumber leftOperand ,
153
168
TValueNumber rightOperand
154
169
) {
155
170
instr .getEnclosingIRFunction ( ) = irFunc and
156
171
not instr instanceof PointerArithmeticInstruction and
157
172
instr .getOpcode ( ) = opcode and
158
- instr .getResultIRType ( ) = type and
159
173
tvalueNumber ( instr .getLeft ( ) ) = leftOperand and
160
174
tvalueNumber ( instr .getRight ( ) ) = rightOperand
161
175
}
162
176
163
177
private predicate pointerArithmeticValueNumber (
164
- PointerArithmeticInstruction instr , IRFunction irFunc , Opcode opcode , IRType type ,
165
- int elementSize , TValueNumber leftOperand , TValueNumber rightOperand
178
+ PointerArithmeticInstruction instr , IRFunction irFunc , Opcode opcode , int elementSize ,
179
+ TValueNumber leftOperand , TValueNumber rightOperand
166
180
) {
167
181
instr .getEnclosingIRFunction ( ) = irFunc and
168
182
instr .getOpcode ( ) = opcode and
169
- instr .getResultIRType ( ) = type and
170
183
instr .getElementSize ( ) = elementSize and
171
184
tvalueNumber ( instr .getLeft ( ) ) = leftOperand and
172
185
tvalueNumber ( instr .getRight ( ) ) = rightOperand
173
186
}
174
187
175
188
private predicate unaryValueNumber (
176
- UnaryInstruction instr , IRFunction irFunc , Opcode opcode , IRType type , TValueNumber operand
189
+ UnaryInstruction instr , IRFunction irFunc , Opcode opcode , TValueNumber operand
177
190
) {
178
191
instr .getEnclosingIRFunction ( ) = irFunc and
179
192
not instr instanceof InheritanceConversionInstruction and
180
193
not instr instanceof CopyInstruction and
181
194
not instr instanceof FieldAddressInstruction and
182
195
instr .getOpcode ( ) = opcode and
183
- instr .getResultIRType ( ) = type and
184
196
tvalueNumber ( instr .getUnary ( ) ) = operand
185
197
}
186
198
@@ -200,9 +212,9 @@ private predicate loadTotalOverlapValueNumber(
200
212
TValueNumber operand
201
213
) {
202
214
instr .getEnclosingIRFunction ( ) = irFunc and
203
- instr .getResultIRType ( ) = type and
204
215
tvalueNumber ( instr .getAnOperand ( ) .( MemoryOperand ) .getAnyDef ( ) ) = memOperand and
205
- tvalueNumberOfOperand ( instr .getAnOperand ( ) .( AddressOperand ) ) = operand
216
+ tvalueNumberOfOperand ( instr .getAnOperand ( ) .( AddressOperand ) ) = operand and
217
+ instr .getResultIRType ( ) = type
206
218
}
207
219
208
220
/**
@@ -212,7 +224,11 @@ private predicate loadTotalOverlapValueNumber(
212
224
private predicate uniqueValueNumber ( Instruction instr , IRFunction irFunc ) {
213
225
instr .getEnclosingIRFunction ( ) = irFunc and
214
226
not instr .getResultIRType ( ) instanceof IRVoidType and
215
- not numberableInstruction ( instr )
227
+ (
228
+ not numberableInstruction ( instr )
229
+ or
230
+ filteredNumberableInstruction ( instr )
231
+ )
216
232
}
217
233
218
234
/**
@@ -255,7 +271,7 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
255
271
initializeThisValueNumber ( instr , irFunc ) and
256
272
result = TInitializeThisValueNumber ( irFunc )
257
273
or
258
- exists ( IRType type , string value |
274
+ exists ( string value , IRType type |
259
275
constantValueNumber ( instr , irFunc , type , value ) and
260
276
result = TConstantValueNumber ( irFunc , type , value )
261
277
)
@@ -270,14 +286,14 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
270
286
result = TFieldAddressValueNumber ( irFunc , field , objectAddress )
271
287
)
272
288
or
273
- exists ( Opcode opcode , IRType type , TValueNumber leftOperand , TValueNumber rightOperand |
274
- binaryValueNumber ( instr , irFunc , opcode , type , leftOperand , rightOperand ) and
275
- result = TBinaryValueNumber ( irFunc , opcode , type , leftOperand , rightOperand )
289
+ exists ( Opcode opcode , TValueNumber leftOperand , TValueNumber rightOperand |
290
+ binaryValueNumber ( instr , irFunc , opcode , leftOperand , rightOperand ) and
291
+ result = TBinaryValueNumber ( irFunc , opcode , leftOperand , rightOperand )
276
292
)
277
293
or
278
- exists ( Opcode opcode , IRType type , TValueNumber operand |
279
- unaryValueNumber ( instr , irFunc , opcode , type , operand ) and
280
- result = TUnaryValueNumber ( irFunc , opcode , type , operand )
294
+ exists ( Opcode opcode , TValueNumber operand |
295
+ unaryValueNumber ( instr , irFunc , opcode , operand ) and
296
+ result = TUnaryValueNumber ( irFunc , opcode , operand )
281
297
)
282
298
or
283
299
exists (
@@ -287,14 +303,10 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
287
303
result = TInheritanceConversionValueNumber ( irFunc , opcode , baseClass , derivedClass , operand )
288
304
)
289
305
or
290
- exists (
291
- Opcode opcode , IRType type , int elementSize , TValueNumber leftOperand ,
292
- TValueNumber rightOperand
293
- |
294
- pointerArithmeticValueNumber ( instr , irFunc , opcode , type , elementSize , leftOperand ,
295
- rightOperand ) and
306
+ exists ( Opcode opcode , int elementSize , TValueNumber leftOperand , TValueNumber rightOperand |
307
+ pointerArithmeticValueNumber ( instr , irFunc , opcode , elementSize , leftOperand , rightOperand ) and
296
308
result =
297
- TPointerArithmeticValueNumber ( irFunc , opcode , type , elementSize , leftOperand , rightOperand )
309
+ TPointerArithmeticValueNumber ( irFunc , opcode , elementSize , leftOperand , rightOperand )
298
310
)
299
311
or
300
312
exists ( IRType type , TValueNumber memOperand , TValueNumber operand |
0 commit comments