mirror of
https://github.com/github/codeql.git
synced 2025-12-18 18:10:39 +01:00
67 lines
2.1 KiB
Plaintext
67 lines
2.1 KiB
Plaintext
/**
|
|
* Provides the module `Ssa` for working with static single assignment (SSA) form.
|
|
*/
|
|
|
|
private import CIL
|
|
|
|
/**
|
|
* Provides classes for working with static single assignment (SSA) form.
|
|
*/
|
|
module Ssa {
|
|
private import internal.SsaImplCommon as SsaImpl
|
|
private import internal.SsaImpl
|
|
|
|
/** An SSA definition. */
|
|
class Definition extends SsaImpl::Definition {
|
|
/** Gets a read of this SSA definition. */
|
|
final ReadAccess getARead() { result = getARead(this) }
|
|
|
|
/** Gets the underlying variable update, if any. */
|
|
final VariableUpdate getVariableUpdate() {
|
|
exists(BasicBlock bb, int i |
|
|
result.updatesAt(bb, i) and
|
|
this.definesAt(result.getVariable(), bb, i)
|
|
)
|
|
}
|
|
|
|
/** Gets a first read of this SSA definition. */
|
|
final ReadAccess getAFirstRead() { result = getAFirstRead(this) }
|
|
|
|
/** Holds if `first` and `second` are adjacent reads of this SSA definition. */
|
|
final predicate hasAdjacentReads(ReadAccess first, ReadAccess second) {
|
|
hasAdjacentReads(this, first, second)
|
|
}
|
|
|
|
private Definition getAPhiInput() { result = this.(PhiNode).getAnInput() }
|
|
|
|
/**
|
|
* Gets a definition that ultimately defines this SSA definition and is
|
|
* not itself a phi node.
|
|
*/
|
|
final Definition getAnUltimateDefinition() {
|
|
result = this.getAPhiInput*() and
|
|
not result instanceof PhiNode
|
|
}
|
|
|
|
/** Gets the location of this SSA definition. */
|
|
Location getLocation() { result = this.getVariableUpdate().getLocation() }
|
|
}
|
|
|
|
/** A phi node. */
|
|
class PhiNode extends SsaImpl::PhiNode, Definition {
|
|
final override Location getLocation() { result = this.getBasicBlock().getLocation() }
|
|
|
|
/** Gets an input to this phi node. */
|
|
final Definition getAnInput() { result = getAPhiInput(this) }
|
|
|
|
/**
|
|
* Holds if if `def` is an input to this phi node, and a reference to `def` at
|
|
* index `i` in basic block `bb` can reach this phi node without going through
|
|
* other references.
|
|
*/
|
|
final predicate hasLastInputRef(Definition def, BasicBlock bb, int i) {
|
|
hasLastInputRef(this, def, bb, i)
|
|
}
|
|
}
|
|
}
|