-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathSsaReadPositionCommon.qll
More file actions
67 lines (54 loc) · 2.3 KB
/
SsaReadPositionCommon.qll
File metadata and controls
67 lines (54 loc) · 2.3 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
/**
* Provides classes for representing a position at which an SSA variable is read.
*/
overlay[local?]
module;
private import SsaReadPositionSpecific
import SsaReadPositionSpecific::Public
private newtype TSsaReadPosition =
TSsaReadPositionBlock(BasicBlock bb) { bb = getAReadBasicBlock(_) } or
TSsaReadPositionPhiInputEdge(BasicBlock bbOrig, BasicBlock bbPhi) {
exists(SsaPhiNode phi | phi.hasInputFromBlock(_, bbOrig) and bbPhi = phi.getBasicBlock())
}
/**
* A position at which an SSA variable is read. This includes both ordinary
* reads occurring in basic blocks and input to phi nodes occurring along an
* edge between two basic blocks.
*/
class SsaReadPosition extends TSsaReadPosition {
/** Holds if `v` is read at this position. */
abstract predicate hasReadOfVar(SsaVariable v);
/** Gets a textual representation of this SSA read position. */
abstract string toString();
}
/** A basic block in which an SSA variable is read. */
class SsaReadPositionBlock extends SsaReadPosition, TSsaReadPositionBlock {
/** Gets the basic block corresponding to this position. */
BasicBlock getBlock() { this = TSsaReadPositionBlock(result) }
override predicate hasReadOfVar(SsaVariable v) { this.getBlock() = getAReadBasicBlock(v) }
override string toString() { result = "block" }
}
/**
* An edge between two basic blocks where the latter block has an SSA phi
* definition. The edge therefore has a read of an SSA variable serving as the
* input to the phi node.
*/
class SsaReadPositionPhiInputEdge extends SsaReadPosition, TSsaReadPositionPhiInputEdge {
/** Gets the source of the edge. */
BasicBlock getOrigBlock() { this = TSsaReadPositionPhiInputEdge(result, _) }
/** Gets the target of the edge. */
BasicBlock getPhiBlock() { this = TSsaReadPositionPhiInputEdge(_, result) }
override predicate hasReadOfVar(SsaVariable v) { this.phiInput(_, v) }
/** Holds if `inp` is an input to `phi` along this edge. */
predicate phiInput(SsaPhiNode phi, SsaVariable inp) {
phi.hasInputFromBlock(inp, this.getOrigBlock()) and
this.getPhiBlock() = phi.getBasicBlock()
}
override string toString() { result = "edge" }
}
/**
* Holds if `rix` is the number of input edges to `phi`.
*/
predicate maxPhiInputRank(SsaPhiNode phi, int rix) {
rix = max(int r | rankedPhiInput(phi, _, _, r))
}