-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathDominance.qll
More file actions
90 lines (79 loc) · 2.76 KB
/
Dominance.qll
File metadata and controls
90 lines (79 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**
* Provides classes and predicates for control-flow graph dominance.
*/
overlay[local?]
module;
import java
/*
* Predicates for basic-block-level dominance.
*/
/** Exit points for basic-block control-flow. */
private predicate bbSink(BasicBlock exit) { exit.getLastNode() instanceof ControlFlow::ExitNode }
/** Reversed `bbSucc`. */
private predicate bbPred(BasicBlock post, BasicBlock pre) { post = pre.getASuccessor() }
/**
* The dominance frontier relation for basic blocks.
*
* This is equivalent to:
*
* ```
* x.dominates(w.getAPredecessor()) and not x.strictlyDominates(w)
* ```
*/
predicate dominanceFrontier(BasicBlock x, BasicBlock w) {
x = w.getAPredecessor() and not x.immediatelyDominates(w)
or
exists(BasicBlock prev | dominanceFrontier(prev, w) |
x.immediatelyDominates(prev) and
not x.immediatelyDominates(w)
)
}
/*
* Predicates for expression-level dominance.
*/
/** Immediate dominance relation on control-flow graph nodes. */
predicate iDominates(ControlFlowNode dominator, ControlFlowNode node) {
exists(BasicBlock bb, int i | dominator = bb.getNode(i) and node = bb.getNode(i + 1))
or
exists(BasicBlock dom, BasicBlock bb |
dom.immediatelyDominates(bb) and
dominator = dom.getLastNode() and
node = bb.getFirstNode()
)
}
/** Holds if `dom` strictly dominates `node`. */
overlay[caller?]
pragma[inline]
predicate strictlyDominates(ControlFlowNode dom, ControlFlowNode node) {
// This predicate is gigantic, so it must be inlined.
dom.getBasicBlock().strictlyDominates(node.getBasicBlock())
or
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i < j)
}
/** Holds if `dom` dominates `node`. (This is reflexive.) */
overlay[caller?]
pragma[inline]
predicate dominates(ControlFlowNode dom, ControlFlowNode node) {
// This predicate is gigantic, so it must be inlined.
dom.getBasicBlock().strictlyDominates(node.getBasicBlock())
or
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i <= j)
}
/** Holds if `dom` strictly post-dominates `node`. */
overlay[caller?]
pragma[inline]
predicate strictlyPostDominates(ControlFlowNode dom, ControlFlowNode node) {
// This predicate is gigantic, so it must be inlined.
dom.getBasicBlock().strictlyPostDominates(node.getBasicBlock())
or
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i > j)
}
/** Holds if `dom` post-dominates `node`. (This is reflexive.) */
overlay[caller?]
pragma[inline]
predicate postDominates(ControlFlowNode dom, ControlFlowNode node) {
// This predicate is gigantic, so it must be inlined.
dom.getBasicBlock().strictlyPostDominates(node.getBasicBlock())
or
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i >= j)
}