1
+ /**
2
+ * Provides classes describing basic blocks in the IR of a function.
3
+ */
4
+
1
5
private import internal.IRInternal
2
6
import Instruction
3
7
private import internal.IRBlockImports as Imports
@@ -18,13 +22,20 @@ private import Cached
18
22
class IRBlockBase extends TIRBlock {
19
23
final string toString ( ) { result = getFirstInstruction ( this ) .toString ( ) }
20
24
25
+ /** Gets the source location of the first non-`Phi` instruction in this block. */
21
26
final Language:: Location getLocation ( ) { result = getFirstInstruction ( ) .getLocation ( ) }
22
27
28
+ /**
29
+ * Gets a string that uniquely identifies this block within its enclosing function.
30
+ *
31
+ * This predicate is used by debugging and printing code only.
32
+ */
23
33
final string getUniqueId ( ) { result = getFirstInstruction ( this ) .getUniqueId ( ) }
24
34
25
35
/**
26
- * Gets the zero-based index of the block within its function. This is used
27
- * by debugging and printing code only.
36
+ * Gets the zero-based index of the block within its function.
37
+ *
38
+ * This predicate is used by debugging and printing code only.
28
39
*/
29
40
int getDisplayIndex ( ) {
30
41
exists ( IRConfiguration:: IRConfiguration config |
@@ -42,27 +53,51 @@ class IRBlockBase extends TIRBlock {
42
53
)
43
54
}
44
55
56
+ /**
57
+ * Gets the `index`th non-`Phi` instruction in this block.
58
+ */
45
59
final Instruction getInstruction ( int index ) { result = getInstruction ( this , index ) }
46
60
61
+ /**
62
+ * Get the `Phi` instructions that appear at the start of this block.
63
+ */
47
64
final PhiInstruction getAPhiInstruction ( ) {
48
65
Construction:: getPhiInstructionBlockStart ( result ) = getFirstInstruction ( )
49
66
}
50
67
68
+ /**
69
+ * Get the instructions in this block, including `Phi` instructions.
70
+ */
51
71
final Instruction getAnInstruction ( ) {
52
72
result = getInstruction ( _) or
53
73
result = getAPhiInstruction ( )
54
74
}
55
75
76
+ /**
77
+ * Gets the first non-`Phi` instruction in this block.
78
+ */
56
79
final Instruction getFirstInstruction ( ) { result = getFirstInstruction ( this ) }
57
80
81
+ /**
82
+ * Gets the last instruction in this block.
83
+ */
58
84
final Instruction getLastInstruction ( ) { result = getInstruction ( getInstructionCount ( ) - 1 ) }
59
85
86
+ /**
87
+ * Gets the number of non-`Phi` instructions in this block.
88
+ */
60
89
final int getInstructionCount ( ) { result = getInstructionCount ( this ) }
61
90
91
+ /**
92
+ * Gets the `IRFunction` that contains this block.
93
+ */
62
94
final IRFunction getEnclosingIRFunction ( ) {
63
95
result = getFirstInstruction ( this ) .getEnclosingIRFunction ( )
64
96
}
65
97
98
+ /**
99
+ * Gets the `Function` that contains this block.
100
+ */
66
101
final Language:: Function getEnclosingFunction ( ) {
67
102
result = getFirstInstruction ( this ) .getEnclosingFunction ( )
68
103
}
@@ -74,28 +109,65 @@ class IRBlockBase extends TIRBlock {
74
109
* instruction of another block.
75
110
*/
76
111
class IRBlock extends IRBlockBase {
112
+ /**
113
+ * Gets the blocks to which control flows directly from this block.
114
+ */
77
115
final IRBlock getASuccessor ( ) { blockSuccessor ( this , result ) }
78
116
117
+ /**
118
+ * Gets the blocks from which control flows directly to this block.
119
+ */
79
120
final IRBlock getAPredecessor ( ) { blockSuccessor ( result , this ) }
80
121
122
+ /**
123
+ * Gets the block to which control flows directly from this block along an edge of kind `kind`.
124
+ */
81
125
final IRBlock getSuccessor ( EdgeKind kind ) { blockSuccessor ( this , result , kind ) }
82
126
127
+ /**
128
+ * Gets the block to which control flows directly from this block along a back edge of kind
129
+ * `kind`.
130
+ */
83
131
final IRBlock getBackEdgeSuccessor ( EdgeKind kind ) { backEdgeSuccessor ( this , result , kind ) }
84
132
133
+ /**
134
+ * Holds if this block immediately dominates `block`.
135
+ *
136
+ * Block `A` immediate dominates block `B` if block `A` strictly dominates block `B` and block `B`
137
+ * is a direct successor of block `A`.
138
+ */
85
139
final predicate immediatelyDominates ( IRBlock block ) { blockImmediatelyDominates ( this , block ) }
86
140
141
+ /**
142
+ * Holds if this block strictly dominates `block`.
143
+ *
144
+ * Block `A` strictly dominates block `B` if block `A` dominates block `B` and blocks `A` and `B`
145
+ * are not the same block.
146
+ */
87
147
final predicate strictlyDominates ( IRBlock block ) { blockImmediatelyDominates + ( this , block ) }
88
148
149
+ /**
150
+ * Holds if this block dominates `block`.
151
+ *
152
+ * Block `A` dominates block `B` if any control flow path from the entry block of the function to
153
+ * block `B` must pass through block `A`. A block always dominates itself.
154
+ */
89
155
final predicate dominates ( IRBlock block ) { strictlyDominates ( block ) or this = block }
90
156
157
+ /**
158
+ * Gets the set of blocks on the dominance frontier of this block.
159
+ *
160
+ * The dominance frontier of block `A` is the set of blocks `B` such that block `A` does not
161
+ * dominate block `B`, but block `A` does dominate an immediate predecessor of block `B`.
162
+ */
91
163
pragma [ noinline]
92
164
final IRBlock dominanceFrontier ( ) {
93
165
dominates ( result .getAPredecessor ( ) ) and
94
166
not strictlyDominates ( result )
95
167
}
96
168
97
169
/**
98
- * Holds if this block is reachable from the entry point of its function
170
+ * Holds if this block is reachable from the entry block of its function.
99
171
*/
100
172
final predicate isReachableFromFunctionEntry ( ) {
101
173
this = getEnclosingIRFunction ( ) .getEntryBlock ( ) or
0 commit comments