@@ -14,19 +14,66 @@ private newtype TOperand =
1414 not Construction:: isInCycle ( useInstr ) and
1515 strictcount ( Construction:: getRegisterOperandDefinition ( useInstr , tag ) ) = 1
1616 } or
17- TNonPhiMemoryOperand (
18- Instruction useInstr , MemoryOperandTag tag , Instruction defInstr , Overlap overlap
19- ) {
20- defInstr = Construction:: getMemoryOperandDefinition ( useInstr , tag , overlap ) and
21- not Construction:: isInCycle ( useInstr ) and
22- strictcount ( Construction:: getMemoryOperandDefinition ( useInstr , tag , _) ) = 1
17+ TNonPhiMemoryOperand ( Instruction useInstr , MemoryOperandTag tag ) {
18+ useInstr .getOpcode ( ) .hasOperand ( tag )
2319 } or
2420 TPhiOperand (
2521 PhiInstruction useInstr , Instruction defInstr , IRBlock predecessorBlock , Overlap overlap
2622 ) {
2723 defInstr = Construction:: getPhiOperandDefinition ( useInstr , predecessorBlock , overlap )
2824 }
2925
26+ /**
27+ * Base class for all register operands. This is a placeholder for the IPA union type that we will
28+ * eventually use for this purpose.
29+ */
30+ private class RegisterOperandBase extends TRegisterOperand {
31+ /** Gets a textual representation of this element. */
32+ abstract string toString ( ) ;
33+ }
34+
35+ /**
36+ * Returns the register operand with the specified parameters.
37+ */
38+ private RegisterOperandBase registerOperand (
39+ Instruction useInstr , RegisterOperandTag tag , Instruction defInstr
40+ ) {
41+ result = TRegisterOperand ( useInstr , tag , defInstr )
42+ }
43+
44+ /**
45+ * Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
46+ * will eventually use for this purpose.
47+ */
48+ private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
49+ /** Gets a textual representation of this element. */
50+ abstract string toString ( ) ;
51+ }
52+
53+ /**
54+ * Returns the non-Phi memory operand with the specified parameters.
55+ */
56+ private NonPhiMemoryOperandBase nonPhiMemoryOperand ( Instruction useInstr , MemoryOperandTag tag ) {
57+ result = TNonPhiMemoryOperand ( useInstr , tag )
58+ }
59+
60+ /**
61+ * Base class for all Phi operands. This is a placeholder for the IPA union type that we will
62+ * eventually use for this purpose.
63+ */
64+ private class PhiOperandBase extends TPhiOperand {
65+ abstract string toString ( ) ;
66+ }
67+
68+ /**
69+ * Returns the Phi operand with the specified parameters.
70+ */
71+ private PhiOperandBase phiOperand (
72+ Instruction useInstr , Instruction defInstr , IRBlock predecessorBlock , Overlap overlap
73+ ) {
74+ result = TPhiOperand ( useInstr , defInstr , predecessorBlock , overlap )
75+ }
76+
3077/**
3178 * A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
3279 */
@@ -165,8 +212,8 @@ class Operand extends TOperand {
165212 */
166213class MemoryOperand extends Operand {
167214 MemoryOperand ( ) {
168- this = TNonPhiMemoryOperand ( _ , _ , _ , _ ) or
169- this = TPhiOperand ( _ , _ , _ , _ )
215+ this instanceof NonPhiMemoryOperandBase or
216+ this instanceof PhiOperandBase
170217 }
171218
172219 /**
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
200247 */
201248class NonPhiOperand extends Operand {
202249 Instruction useInstr ;
203- Instruction defInstr ;
204250 OperandTag tag ;
205251
206252 NonPhiOperand ( ) {
207- this = TRegisterOperand ( useInstr , tag , defInstr ) or
208- this = TNonPhiMemoryOperand ( useInstr , tag , defInstr , _ )
253+ this = registerOperand ( useInstr , tag , _ ) or
254+ this = nonPhiMemoryOperand ( useInstr , tag )
209255 }
210256
211257 final override Instruction getUse ( ) { result = useInstr }
212258
213- final override Instruction getAnyDef ( ) { result = defInstr }
214-
215259 final override string getDumpLabel ( ) { result = tag .getLabel ( ) }
216260
217261 final override int getDumpSortOrder ( ) { result = tag .getSortOrder ( ) }
@@ -222,22 +266,41 @@ class NonPhiOperand extends Operand {
222266/**
223267 * An operand that consumes a register (non-memory) result.
224268 */
225- class RegisterOperand extends NonPhiOperand , TRegisterOperand {
269+ class RegisterOperand extends NonPhiOperand , RegisterOperandBase {
226270 override RegisterOperandTag tag ;
271+ Instruction defInstr ;
272+
273+ RegisterOperand ( ) { this = registerOperand ( useInstr , tag , defInstr ) }
274+
275+ final override string toString ( ) { result = tag .toString ( ) }
276+
277+ final override Instruction getAnyDef ( ) { result = defInstr }
227278
228279 final override Overlap getDefinitionOverlap ( ) {
229280 // All register results overlap exactly with their uses.
230281 result instanceof MustExactlyOverlap
231282 }
232283}
233284
234- class NonPhiMemoryOperand extends NonPhiOperand , MemoryOperand , TNonPhiMemoryOperand {
285+ class NonPhiMemoryOperand extends NonPhiOperand , MemoryOperand , NonPhiMemoryOperandBase {
235286 override MemoryOperandTag tag ;
236- Overlap overlap ;
237287
238- NonPhiMemoryOperand ( ) { this = TNonPhiMemoryOperand ( useInstr , tag , defInstr , overlap ) }
288+ NonPhiMemoryOperand ( ) { this = nonPhiMemoryOperand ( useInstr , tag ) }
239289
240- final override Overlap getDefinitionOverlap ( ) { result = overlap }
290+ final override string toString ( ) { result = tag .toString ( ) }
291+
292+ final override Instruction getAnyDef ( ) {
293+ result = unique( Instruction defInstr | hasDefinition ( defInstr , _) )
294+ }
295+
296+ final override Overlap getDefinitionOverlap ( ) { hasDefinition ( _, result ) }
297+
298+ pragma [ noinline]
299+ private predicate hasDefinition ( Instruction defInstr , Overlap overlap ) {
300+ defInstr = Construction:: getMemoryOperandDefinition ( useInstr , tag , overlap ) and
301+ not Construction:: isInCycle ( useInstr ) and
302+ strictcount ( Construction:: getMemoryOperandDefinition ( useInstr , tag , _) ) = 1
303+ }
241304}
242305
243306class TypedOperand extends NonPhiMemoryOperand {
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
254317 */
255318class AddressOperand extends RegisterOperand {
256319 override AddressOperandTag tag ;
257-
258- override string toString ( ) { result = "Address" }
259320}
260321
261322/**
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
264325 */
265326class BufferSizeOperand extends RegisterOperand {
266327 override BufferSizeOperandTag tag ;
267-
268- override string toString ( ) { result = "BufferSize" }
269328}
270329
271330/**
@@ -274,62 +333,48 @@ class BufferSizeOperand extends RegisterOperand {
274333 */
275334class LoadOperand extends TypedOperand {
276335 override LoadOperandTag tag ;
277-
278- override string toString ( ) { result = "Load" }
279336}
280337
281338/**
282339 * The source value operand of a `Store` instruction.
283340 */
284341class StoreValueOperand extends RegisterOperand {
285342 override StoreValueOperandTag tag ;
286-
287- override string toString ( ) { result = "StoreValue" }
288343}
289344
290345/**
291346 * The sole operand of a unary instruction (e.g. `Convert`, `Negate`, `Copy`).
292347 */
293348class UnaryOperand extends RegisterOperand {
294349 override UnaryOperandTag tag ;
295-
296- override string toString ( ) { result = "Unary" }
297350}
298351
299352/**
300353 * The left operand of a binary instruction (e.g. `Add`, `CompareEQ`).
301354 */
302355class LeftOperand extends RegisterOperand {
303356 override LeftOperandTag tag ;
304-
305- override string toString ( ) { result = "Left" }
306357}
307358
308359/**
309360 * The right operand of a binary instruction (e.g. `Add`, `CompareEQ`).
310361 */
311362class RightOperand extends RegisterOperand {
312363 override RightOperandTag tag ;
313-
314- override string toString ( ) { result = "Right" }
315364}
316365
317366/**
318367 * The condition operand of a `ConditionalBranch` or `Switch` instruction.
319368 */
320369class ConditionOperand extends RegisterOperand {
321370 override ConditionOperandTag tag ;
322-
323- override string toString ( ) { result = "Condition" }
324371}
325372
326373/**
327374 * The operand representing the target function of an `Call` instruction.
328375 */
329376class CallTargetOperand extends RegisterOperand {
330377 override CallTargetOperandTag tag ;
331-
332- override string toString ( ) { result = "CallTarget" }
333378}
334379
335380/**
@@ -347,43 +392,34 @@ class ArgumentOperand extends RegisterOperand {
347392 */
348393class ThisArgumentOperand extends ArgumentOperand {
349394 override ThisArgumentOperandTag tag ;
350-
351- override string toString ( ) { result = "ThisArgument" }
352395}
353396
354397/**
355398 * An operand representing an argument to a function call.
356399 */
357400class PositionalArgumentOperand extends ArgumentOperand {
358401 override PositionalArgumentOperandTag tag ;
359- int argIndex ;
360-
361- PositionalArgumentOperand ( ) { argIndex = tag .getArgIndex ( ) }
362-
363- override string toString ( ) { result = "Arg(" + argIndex + ")" }
364402
365403 /**
366404 * Gets the zero-based index of the argument.
367405 */
368- final int getIndex ( ) { result = argIndex }
406+ final int getIndex ( ) { result = tag . getArgIndex ( ) }
369407}
370408
371409class SideEffectOperand extends TypedOperand {
372410 override SideEffectOperandTag tag ;
373-
374- override string toString ( ) { result = "SideEffect" }
375411}
376412
377413/**
378414 * An operand of a `PhiInstruction`.
379415 */
380- class PhiInputOperand extends MemoryOperand , TPhiOperand {
416+ class PhiInputOperand extends MemoryOperand , PhiOperandBase {
381417 PhiInstruction useInstr ;
382418 Instruction defInstr ;
383419 IRBlock predecessorBlock ;
384420 Overlap overlap ;
385421
386- PhiInputOperand ( ) { this = TPhiOperand ( useInstr , defInstr , predecessorBlock , overlap ) }
422+ PhiInputOperand ( ) { this = phiOperand ( useInstr , defInstr , predecessorBlock , overlap ) }
387423
388424 override string toString ( ) { result = "Phi" }
389425
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
413449class ChiTotalOperand extends NonPhiMemoryOperand {
414450 override ChiTotalOperandTag tag ;
415451
416- override string toString ( ) { result = "ChiTotal" }
417-
418452 final override MemoryAccessKind getMemoryAccess ( ) { result instanceof ChiTotalMemoryAccess }
419453}
420454
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
424458class ChiPartialOperand extends NonPhiMemoryOperand {
425459 override ChiPartialOperandTag tag ;
426460
427- override string toString ( ) { result = "ChiPartial" }
428-
429461 final override MemoryAccessKind getMemoryAccess ( ) { result instanceof ChiPartialMemoryAccess }
430462}
0 commit comments