Skip to content

Commit d0af9f5

Browse files
author
Dave Bartolomeo
committed
C++: QLDoc all of IRBlock.qll
1 parent 77bf564 commit d0af9f5

File tree

5 files changed

+375
-15
lines changed

5 files changed

+375
-15
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/**
2+
* Provides classes describing basic blocks in the IR of a function.
3+
*/
4+
15
private import internal.IRInternal
26
import Instruction
37
private import internal.IRBlockImports as Imports
@@ -18,13 +22,20 @@ private import Cached
1822
class 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
*/
76111
class 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

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRBlock.qll

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/**
2+
* Provides classes describing basic blocks in the IR of a function.
3+
*/
4+
15
private import internal.IRInternal
26
import Instruction
37
private import internal.IRBlockImports as Imports
@@ -18,13 +22,20 @@ private import Cached
1822
class 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
*/
76111
class 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

Comments
 (0)