1+ /**
2+ * Provides classes describing basic blocks in the IR of a function.
3+ */
4+
15private import internal.IRInternal
26import Instruction
37private import internal.IRBlockImports as Imports
@@ -18,13 +22,20 @@ private import Cached
1822class IRBlockBase extends TIRBlock {
1923 final string toString ( ) { result = getFirstInstruction ( this ) .toString ( ) }
2024
25+ /** Gets the source location of the first non-`Phi` instruction in this block. */
2126 final Language:: Location getLocation ( ) { result = getFirstInstruction ( ) .getLocation ( ) }
2227
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+ */
2333 final string getUniqueId ( ) { result = getFirstInstruction ( this ) .getUniqueId ( ) }
2434
2535 /**
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.
2839 */
2940 int getDisplayIndex ( ) {
3041 exists ( IRConfiguration:: IRConfiguration config |
@@ -42,27 +53,51 @@ class IRBlockBase extends TIRBlock {
4253 )
4354 }
4455
56+ /**
57+ * Gets the `index`th non-`Phi` instruction in this block.
58+ */
4559 final Instruction getInstruction ( int index ) { result = getInstruction ( this , index ) }
4660
61+ /**
62+ * Get the `Phi` instructions that appear at the start of this block.
63+ */
4764 final PhiInstruction getAPhiInstruction ( ) {
4865 Construction:: getPhiInstructionBlockStart ( result ) = getFirstInstruction ( )
4966 }
5067
68+ /**
69+ * Get the instructions in this block, including `Phi` instructions.
70+ */
5171 final Instruction getAnInstruction ( ) {
5272 result = getInstruction ( _) or
5373 result = getAPhiInstruction ( )
5474 }
5575
76+ /**
77+ * Gets the first non-`Phi` instruction in this block.
78+ */
5679 final Instruction getFirstInstruction ( ) { result = getFirstInstruction ( this ) }
5780
81+ /**
82+ * Gets the last instruction in this block.
83+ */
5884 final Instruction getLastInstruction ( ) { result = getInstruction ( getInstructionCount ( ) - 1 ) }
5985
86+ /**
87+ * Gets the number of non-`Phi` instructions in this block.
88+ */
6089 final int getInstructionCount ( ) { result = getInstructionCount ( this ) }
6190
91+ /**
92+ * Gets the `IRFunction` that contains this block.
93+ */
6294 final IRFunction getEnclosingIRFunction ( ) {
6395 result = getFirstInstruction ( this ) .getEnclosingIRFunction ( )
6496 }
6597
98+ /**
99+ * Gets the `Function` that contains this block.
100+ */
66101 final Language:: Function getEnclosingFunction ( ) {
67102 result = getFirstInstruction ( this ) .getEnclosingFunction ( )
68103 }
@@ -74,28 +109,65 @@ class IRBlockBase extends TIRBlock {
74109 * instruction of another block.
75110 */
76111class IRBlock extends IRBlockBase {
112+ /**
113+ * Gets the blocks to which control flows directly from this block.
114+ */
77115 final IRBlock getASuccessor ( ) { blockSuccessor ( this , result ) }
78116
117+ /**
118+ * Gets the blocks from which control flows directly to this block.
119+ */
79120 final IRBlock getAPredecessor ( ) { blockSuccessor ( result , this ) }
80121
122+ /**
123+ * Gets the block to which control flows directly from this block along an edge of kind `kind`.
124+ */
81125 final IRBlock getSuccessor ( EdgeKind kind ) { blockSuccessor ( this , result , kind ) }
82126
127+ /**
128+ * Gets the block to which control flows directly from this block along a back edge of kind
129+ * `kind`.
130+ */
83131 final IRBlock getBackEdgeSuccessor ( EdgeKind kind ) { backEdgeSuccessor ( this , result , kind ) }
84132
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+ */
85139 final predicate immediatelyDominates ( IRBlock block ) { blockImmediatelyDominates ( this , block ) }
86140
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+ */
87147 final predicate strictlyDominates ( IRBlock block ) { blockImmediatelyDominates + ( this , block ) }
88148
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+ */
89155 final predicate dominates ( IRBlock block ) { strictlyDominates ( block ) or this = block }
90156
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+ */
91163 pragma [ noinline]
92164 final IRBlock dominanceFrontier ( ) {
93165 dominates ( result .getAPredecessor ( ) ) and
94166 not strictlyDominates ( result )
95167 }
96168
97169 /**
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.
99171 */
100172 final predicate isReachableFromFunctionEntry ( ) {
101173 this = getEnclosingIRFunction ( ) .getEntryBlock ( ) or
0 commit comments