@@ -10,79 +10,32 @@ private import Imports::MemoryAccessKind
1010private import Imports:: IRType
1111private import Imports:: Overlap
1212private 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
6315
6416/**
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 .
6719 */
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 ;
8022
8123/**
8224 * An operand of an `Instruction`. The operand represents a use of the result of one instruction
8325 * (the defining instruction) in another instruction (the use instruction)
8426 */
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+
8639 /** Gets a textual representation of this element. */
8740 string toString ( ) { result = "Operand" }
8841
@@ -238,9 +191,11 @@ class Operand extends TOperand {
238191 * An operand that consumes a memory result (e.g. the `LoadOperand` on a `Load` instruction).
239192 */
240193class MemoryOperand extends Operand {
194+ cached
241195 MemoryOperand ( ) {
242- this instanceof NonPhiMemoryOperandBase or
243- this instanceof PhiOperandBase
196+ this instanceof TNonSSAMemoryOperand or
197+ this instanceof TPhiOperand or
198+ this instanceof TChiOperand
244199 }
245200
246201 /**
@@ -278,7 +233,8 @@ class NonPhiOperand extends Operand {
278233
279234 NonPhiOperand ( ) {
280235 this = registerOperand ( useInstr , tag , _) or
281- this = nonPhiMemoryOperand ( useInstr , tag )
236+ this = nonSSAMemoryOperand ( useInstr , tag ) or
237+ this = chiOperand ( useInstr , tag )
282238 }
283239
284240 final override Instruction getUse ( ) { result = useInstr }
@@ -298,10 +254,11 @@ class NonPhiOperand extends Operand {
298254/**
299255 * An operand that consumes a register (non-memory) result.
300256 */
301- class RegisterOperand extends NonPhiOperand , RegisterOperandBase {
257+ class RegisterOperand extends NonPhiOperand , TRegisterOperand {
302258 override RegisterOperandTag tag ;
303259 Instruction defInstr ;
304260
261+ cached
305262 RegisterOperand ( ) { this = registerOperand ( useInstr , tag , defInstr ) }
306263
307264 final override string toString ( ) { result = tag .toString ( ) }
@@ -317,10 +274,15 @@ class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
317274/**
318275 * A memory operand other than the operand of a `Phi` instruction.
319276 */
320- class NonPhiMemoryOperand extends NonPhiOperand , MemoryOperand , NonPhiMemoryOperandBase {
277+ class NonPhiMemoryOperand extends NonPhiOperand , MemoryOperand , TNonPhiMemoryOperand {
321278 override MemoryOperandTag tag ;
322279
323- NonPhiMemoryOperand ( ) { this = nonPhiMemoryOperand ( useInstr , tag ) }
280+ cached
281+ NonPhiMemoryOperand ( ) {
282+ this = nonSSAMemoryOperand ( useInstr , tag )
283+ or
284+ this = chiOperand ( useInstr , tag )
285+ }
324286
325287 final override string toString ( ) { result = tag .toString ( ) }
326288
@@ -462,12 +424,13 @@ class SideEffectOperand extends TypedOperand {
462424/**
463425 * An operand of a `PhiInstruction`.
464426 */
465- class PhiInputOperand extends MemoryOperand , PhiOperandBase {
427+ class PhiInputOperand extends MemoryOperand , TPhiOperand {
466428 PhiInstruction useInstr ;
467429 Instruction defInstr ;
468430 IRBlock predecessorBlock ;
469431 Overlap overlap ;
470432
433+ cached
471434 PhiInputOperand ( ) { this = phiOperand ( useInstr , defInstr , predecessorBlock , overlap ) }
472435
473436 override string toString ( ) { result = "Phi" }
0 commit comments