@@ -10,79 +10,32 @@ private import Imports::MemoryAccessKind
10
10
private import Imports:: IRType
11
11
private import Imports:: Overlap
12
12
private import Imports:: OperandTag
13
-
14
- cached
15
- private newtype TOperand =
16
- TRegisterOperand ( Instruction useInstr , RegisterOperandTag tag , Instruction defInstr ) {
17
- defInstr = Construction:: getRegisterOperandDefinition ( useInstr , tag ) and
18
- not Construction:: isInCycle ( useInstr ) and
19
- strictcount ( Construction:: getRegisterOperandDefinition ( useInstr , tag ) ) = 1
20
- } or
21
- TNonPhiMemoryOperand ( Instruction useInstr , MemoryOperandTag tag ) {
22
- useInstr .getOpcode ( ) .hasOperand ( tag )
23
- } or
24
- TPhiOperand (
25
- PhiInstruction useInstr , Instruction defInstr , IRBlock predecessorBlock , Overlap overlap
26
- ) {
27
- defInstr = Construction:: getPhiOperandDefinition ( useInstr , predecessorBlock , overlap )
28
- }
29
-
30
- /**
31
- * Base class for all register operands. This is a placeholder for the IPA union type that we will
32
- * eventually use for this purpose.
33
- */
34
- private class RegisterOperandBase extends TRegisterOperand {
35
- /** Gets a textual representation of this element. */
36
- abstract string toString ( ) ;
37
- }
38
-
39
- /**
40
- * Returns the register operand with the specified parameters.
41
- */
42
- private RegisterOperandBase registerOperand (
43
- Instruction useInstr , RegisterOperandTag tag , Instruction defInstr
44
- ) {
45
- result = TRegisterOperand ( useInstr , tag , defInstr )
46
- }
47
-
48
- /**
49
- * Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
50
- * will eventually use for this purpose.
51
- */
52
- private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
53
- /** Gets a textual representation of this element. */
54
- abstract string toString ( ) ;
55
- }
56
-
57
- /**
58
- * Returns the non-Phi memory operand with the specified parameters.
59
- */
60
- private NonPhiMemoryOperandBase nonPhiMemoryOperand ( Instruction useInstr , MemoryOperandTag tag ) {
61
- result = TNonPhiMemoryOperand ( useInstr , tag )
62
- }
13
+ private import Imports:: TOperand
14
+ private import internal.OperandInternal
63
15
64
16
/**
65
- * Base class for all Phi operands. This is a placeholder for the IPA union type that we will
66
- * eventually use for this purpose .
17
+ * An operand of an `Instruction` in this stage of the IR. Implemented as a union of the branches
18
+ * of `TOperand` that are used in this stage .
67
19
*/
68
- private class PhiOperandBase extends TPhiOperand {
69
- abstract string toString ( ) ;
70
- }
71
-
72
- /**
73
- * Returns the Phi operand with the specified parameters.
74
- */
75
- private PhiOperandBase phiOperand (
76
- Instruction useInstr , Instruction defInstr , IRBlock predecessorBlock , Overlap overlap
77
- ) {
78
- result = TPhiOperand ( useInstr , defInstr , predecessorBlock , overlap )
79
- }
20
+ private class TStageOperand =
21
+ TRegisterOperand or TNonSSAMemoryOperand or TPhiOperand or TChiOperand ;
80
22
81
23
/**
82
24
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
83
25
* (the defining instruction) in another instruction (the use instruction)
84
26
*/
85
- class Operand extends TOperand {
27
+ class Operand extends TStageOperand {
28
+ cached
29
+ Operand ( ) {
30
+ // Ensure that the operand does not refer to instructions from earlier stages that are unreachable here
31
+ exists ( Instruction use , Instruction def | this = registerOperand ( use , _, def ) ) or
32
+ exists ( Instruction use | this = nonSSAMemoryOperand ( use , _) ) or
33
+ exists ( Instruction use , Instruction def , IRBlock predecessorBlock |
34
+ this = phiOperand ( use , def , predecessorBlock , _)
35
+ ) or
36
+ exists ( Instruction use | this = chiOperand ( use , _) )
37
+ }
38
+
86
39
/** Gets a textual representation of this element. */
87
40
string toString ( ) { result = "Operand" }
88
41
@@ -238,9 +191,11 @@ class Operand extends TOperand {
238
191
* An operand that consumes a memory result (e.g. the `LoadOperand` on a `Load` instruction).
239
192
*/
240
193
class MemoryOperand extends Operand {
194
+ cached
241
195
MemoryOperand ( ) {
242
- this instanceof NonPhiMemoryOperandBase or
243
- this instanceof PhiOperandBase
196
+ this instanceof TNonSSAMemoryOperand or
197
+ this instanceof TPhiOperand or
198
+ this instanceof TChiOperand
244
199
}
245
200
246
201
/**
@@ -278,7 +233,8 @@ class NonPhiOperand extends Operand {
278
233
279
234
NonPhiOperand ( ) {
280
235
this = registerOperand ( useInstr , tag , _) or
281
- this = nonPhiMemoryOperand ( useInstr , tag )
236
+ this = nonSSAMemoryOperand ( useInstr , tag ) or
237
+ this = chiOperand ( useInstr , tag )
282
238
}
283
239
284
240
final override Instruction getUse ( ) { result = useInstr }
@@ -298,10 +254,11 @@ class NonPhiOperand extends Operand {
298
254
/**
299
255
* An operand that consumes a register (non-memory) result.
300
256
*/
301
- class RegisterOperand extends NonPhiOperand , RegisterOperandBase {
257
+ class RegisterOperand extends NonPhiOperand , TRegisterOperand {
302
258
override RegisterOperandTag tag ;
303
259
Instruction defInstr ;
304
260
261
+ cached
305
262
RegisterOperand ( ) { this = registerOperand ( useInstr , tag , defInstr ) }
306
263
307
264
final override string toString ( ) { result = tag .toString ( ) }
@@ -317,10 +274,15 @@ class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
317
274
/**
318
275
* A memory operand other than the operand of a `Phi` instruction.
319
276
*/
320
- class NonPhiMemoryOperand extends NonPhiOperand , MemoryOperand , NonPhiMemoryOperandBase {
277
+ class NonPhiMemoryOperand extends NonPhiOperand , MemoryOperand , TNonPhiMemoryOperand {
321
278
override MemoryOperandTag tag ;
322
279
323
- NonPhiMemoryOperand ( ) { this = nonPhiMemoryOperand ( useInstr , tag ) }
280
+ cached
281
+ NonPhiMemoryOperand ( ) {
282
+ this = nonSSAMemoryOperand ( useInstr , tag )
283
+ or
284
+ this = chiOperand ( useInstr , tag )
285
+ }
324
286
325
287
final override string toString ( ) { result = tag .toString ( ) }
326
288
@@ -462,12 +424,13 @@ class SideEffectOperand extends TypedOperand {
462
424
/**
463
425
* An operand of a `PhiInstruction`.
464
426
*/
465
- class PhiInputOperand extends MemoryOperand , PhiOperandBase {
427
+ class PhiInputOperand extends MemoryOperand , TPhiOperand {
466
428
PhiInstruction useInstr ;
467
429
Instruction defInstr ;
468
430
IRBlock predecessorBlock ;
469
431
Overlap overlap ;
470
432
433
+ cached
471
434
PhiInputOperand ( ) { this = phiOperand ( useInstr , defInstr , predecessorBlock , overlap ) }
472
435
473
436
override string toString ( ) { result = "Phi" }
0 commit comments