Skip to content

Commit e382ffc

Browse files
committed
Shared: Address review comments for basic block library
1 parent 53b63be commit e382ffc

File tree

2 files changed

+52
-48
lines changed

2 files changed

+52
-48
lines changed

shared/controlflow/codeql/controlflow/BasicBlock.qll

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,18 +126,23 @@ module Make<LocationSig Location, InputSig<Location> Input> {
126126
/**
127127
* Holds if `df` is in the dominance frontier of this basic block. That is,
128128
* this basic block dominates a predecessor of `df`, but does not dominate
129-
* `df` itself.
129+
* `df` itself. I.e., it is equivaluent to:
130+
* ```
131+
* this.dominates(df.getAPredecessor()) and not this.strictlyDominates(df)
132+
* ```
130133
*/
131134
predicate inDominanceFrontier(BasicBlock df) {
132-
this.dominatesPredecessor(df) and
133-
not this.strictlyDominates(df)
135+
// Algorithm from Cooper et al., "A Simple, Fast Dominance Algorithm" (Figure 5),
136+
// who in turn attribute it to Ferrante et al., "The program dependence graph and
137+
// its use in optimization".
138+
this = df.getAPredecessor() and not bbIDominates(this, df)
139+
or
140+
exists(BasicBlock prev | prev.inDominanceFrontier(df) |
141+
bbIDominates(this, prev) and
142+
not bbIDominates(this, df)
143+
)
134144
}
135145

136-
/**
137-
* Holds if this basic block dominates a predecessor of `df`.
138-
*/
139-
private predicate dominatesPredecessor(BasicBlock df) { this.dominates(df.getAPredecessor()) }
140-
141146
/**
142147
* Gets the basic block that immediately dominates this basic block, if any.
143148
*
@@ -219,7 +224,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
219224
// In cases such as
220225
//
221226
// ```rb
222-
// if x or y
227+
// if x and y
223228
// foo
224229
// else
225230
// bar

shared/controlflow/codeql/controlflow/Cfg.qll

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,12 @@ signature module InputSig<LocationSig Location> {
8282
* Gets an `id` of `node`. This is used to order the predecessors of a join
8383
* basic block.
8484
*/
85-
bindingset[node]
8685
int idOfAstNode(AstNode node);
8786

8887
/**
8988
* Gets an `id` of `scope`. This is used to order the predecessors of a join
9089
* basic block.
9190
*/
92-
bindingset[scope]
9391
int idOfCfgScope(CfgScope scope);
9492
}
9593

@@ -1008,6 +1006,41 @@ module MakeWithSplitting<
10081006
)
10091007
}
10101008

1009+
private module JoinBlockPredecessors {
1010+
predicate hasIdAndKind(BasicBlocks::JoinPredecessorBasicBlock jbp, int id, int kind) {
1011+
id = idOfCfgScope(jbp.(BasicBlocks::EntryBasicBlock).getScope()) and
1012+
kind = 0
1013+
or
1014+
not jbp instanceof BasicBlocks::EntryBasicBlock and
1015+
id = idOfAstNode(jbp.getFirstNode().(AstCfgNode).getAstNode()) and
1016+
kind = 1
1017+
}
1018+
1019+
string getSplitString(BasicBlocks::JoinPredecessorBasicBlock jbp) {
1020+
result = jbp.getFirstNode().(AstCfgNode).getSplitsString()
1021+
or
1022+
not exists(jbp.getFirstNode().(AstCfgNode).getSplitsString()) and
1023+
result = ""
1024+
}
1025+
}
1026+
1027+
/**
1028+
* Gets the `i`th predecessor of join block `jb`, with respect to some
1029+
* arbitrary order.
1030+
*/
1031+
cached
1032+
BasicBlocks::JoinPredecessorBasicBlock getJoinBlockPredecessor(
1033+
BasicBlocks::JoinBasicBlock jb, int i
1034+
) {
1035+
result =
1036+
rank[i + 1](BasicBlocks::JoinPredecessorBasicBlock jbp, int id, int kind |
1037+
jbp = jb.getAPredecessor() and
1038+
JoinBlockPredecessors::hasIdAndKind(jbp, id, kind)
1039+
|
1040+
jbp order by id, kind, JoinBlockPredecessors::getSplitString(jbp)
1041+
)
1042+
}
1043+
10111044
cached
10121045
module Public {
10131046
/**
@@ -1570,15 +1603,13 @@ module MakeWithSplitting<
15701603
BasicBlock getASuccessor() { result = super.getASuccessor() }
15711604

15721605
/** Gets an immediate successor of this basic block of a given type, if any. */
1573-
BasicBlock getASuccessor(SuccessorType t) {
1574-
result.getFirstNode() = this.getLastNode().getASuccessor(t)
1575-
}
1606+
BasicBlock getASuccessor(SuccessorType t) { result = super.getASuccessor(t) }
15761607

15771608
/** Gets an immediate predecessor of this basic block, if any. */
1578-
BasicBlock getAPredecessor() { result.getASuccessor() = this }
1609+
BasicBlock getAPredecessor() { result = super.getAPredecessor() }
15791610

15801611
/** Gets an immediate predecessor of this basic block of a given type, if any. */
1581-
BasicBlock getAPredecessor(SuccessorType t) { result.getASuccessor(t) = this }
1612+
BasicBlock getAPredecessor(SuccessorType t) { result = super.getAPredecessor(t) }
15821613

15831614
/**
15841615
* Holds if this basic block immediately dominates basic block `bb`.
@@ -1673,38 +1704,6 @@ module MakeWithSplitting<
16731704
ExitBasicBlock() { this.getLastNode() instanceof ExitNode }
16741705
}
16751706

1676-
private module JoinBlockPredecessors {
1677-
predicate hasIdAndKind(JoinPredecessorBasicBlock jbp, int id, int kind) {
1678-
id = idOfCfgScope(jbp.(EntryBasicBlock).getScope()) and
1679-
kind = 0
1680-
or
1681-
not jbp instanceof EntryBasicBlock and
1682-
id = idOfAstNode(jbp.getFirstNode().(AstCfgNode).getAstNode()) and
1683-
kind = 1
1684-
}
1685-
1686-
string getSplitString(JoinPredecessorBasicBlock jbp) {
1687-
result = jbp.getFirstNode().(AstCfgNode).getSplitsString()
1688-
or
1689-
not exists(jbp.getFirstNode().(AstCfgNode).getSplitsString()) and
1690-
result = ""
1691-
}
1692-
}
1693-
1694-
/**
1695-
* Gets the `i`th predecessor of join block `jb`, with respect to some
1696-
* arbitrary order.
1697-
*/
1698-
cached
1699-
JoinPredecessorBasicBlock getJoinBlockPredecessor(JoinBasicBlock jb, int i) {
1700-
result =
1701-
rank[i + 1](JoinPredecessorBasicBlock jbp, int id, int kind |
1702-
jbp = jb.getAPredecessor() and JoinBlockPredecessors::hasIdAndKind(jbp, id, kind)
1703-
|
1704-
jbp order by id, kind, JoinBlockPredecessors::getSplitString(jbp)
1705-
)
1706-
}
1707-
17081707
/** A basic block with more than one predecessor. */
17091708
final class JoinBasicBlock extends BasicBlock {
17101709
JoinBasicBlock() { this.getFirstNode().isJoin() }

0 commit comments

Comments
 (0)