mirror of
https://github.com/github/codeql.git
synced 2026-03-05 15:16:47 +01:00
Merge pull request #18819 from aschackmull/ssa/refactor-phiread3
Ssa: Refactor shared SSA in preparation for eliminating phi-read definitions
This commit is contained in:
@@ -490,26 +490,11 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate captureDefReaches(Definition def, SsaInput::BasicBlock bb2, int i2) {
|
||||
variableCapture(def.getSourceVariable(), _, _, _) and
|
||||
exists(SsaInput::BasicBlock bb1, int i1 |
|
||||
Impl::adjacentDefRead(def, bb1, i1, bb2, i2) and
|
||||
def.definesAt(_, bb1, i1)
|
||||
)
|
||||
or
|
||||
exists(SsaInput::BasicBlock bb3, int i3 |
|
||||
captureDefReaches(def, bb3, i3) and
|
||||
SsaInput::variableRead(bb3, i3, _, _) and
|
||||
Impl::adjacentDefRead(def, bb3, i3, bb2, i2)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `init` is a closure variable that captures the value of `capturedvar`. */
|
||||
cached
|
||||
predicate captures(SsaImplicitInit init, SsaVariable capturedvar) {
|
||||
exists(BasicBlock bb, int i |
|
||||
captureDefReaches(capturedvar, bb, i) and
|
||||
Impl::ssaDefReachesRead(_, capturedvar, bb, i) and
|
||||
variableCapture(capturedvar.getSourceVariable(), init.getSourceVariable(), bb, i)
|
||||
)
|
||||
}
|
||||
@@ -523,34 +508,15 @@ private module Cached {
|
||||
Impl::uncertainWriteDefinitionInput(redef, def)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate defReaches(Definition def, DataFlowIntegration::Node node) {
|
||||
exists(DataFlowIntegration::SsaDefinitionExtNode nodeFrom |
|
||||
nodeFrom.getDefinitionExt() = def and
|
||||
DataFlowIntegrationImpl::localFlowStep(_, nodeFrom, node, false)
|
||||
)
|
||||
or
|
||||
exists(DataFlowIntegration::Node mid |
|
||||
defReaches(def, mid) and
|
||||
DataFlowIntegrationImpl::localFlowStep(_, mid, node, _)
|
||||
|
|
||||
// flow into phi input node
|
||||
mid instanceof DataFlowIntegration::SsaInputNode
|
||||
or
|
||||
// flow into definition
|
||||
mid instanceof DataFlowIntegration::SsaDefinitionExtNode
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the value defined at `def` can reach `use` without passing through
|
||||
* any other uses, but possibly through phi nodes and uncertain implicit updates.
|
||||
*/
|
||||
cached
|
||||
predicate firstUse(Definition def, VarRead use) {
|
||||
exists(DataFlowIntegration::ExprNode nodeTo |
|
||||
nodeTo.getExpr() = use and
|
||||
defReaches(def, nodeTo)
|
||||
exists(BasicBlock bb, int i |
|
||||
Impl::firstUse(def, bb, i, _) and
|
||||
use.getControlFlowNode() = bb.getNode(i)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -609,30 +575,6 @@ private module Cached {
|
||||
|
||||
cached
|
||||
module SsaPublic {
|
||||
pragma[nomagic]
|
||||
private predicate useReaches(VarRead use, DataFlowIntegration::Node node, boolean sameVar) {
|
||||
exists(DataFlowIntegration::ExprNode nodeFrom |
|
||||
nodeFrom.getExpr() = use and
|
||||
DataFlowIntegration::localFlowStep(_, nodeFrom, node, true) and
|
||||
sameVar = true
|
||||
)
|
||||
or
|
||||
exists(DataFlowIntegration::Node mid, boolean sameVarMid |
|
||||
useReaches(use, mid, sameVarMid) and
|
||||
DataFlowIntegration::localFlowStep(_, mid, node, _)
|
||||
|
|
||||
exists(Impl::DefinitionExt def |
|
||||
// flow into definition
|
||||
def = mid.(DataFlowIntegration::SsaDefinitionExtNode).getDefinitionExt()
|
||||
or
|
||||
// flow into phi input node
|
||||
def = mid.(DataFlowIntegration::SsaInputNode).getDefinitionExt()
|
||||
|
|
||||
if def instanceof Impl::PhiReadNode then sameVar = sameVarMid else sameVar = false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `use1` and `use2` form an adjacent use-use-pair of the same SSA
|
||||
* variable, that is, the value read in `use1` can reach `use2` without passing
|
||||
@@ -640,9 +582,10 @@ private module Cached {
|
||||
*/
|
||||
cached
|
||||
predicate adjacentUseUseSameVar(VarRead use1, VarRead use2) {
|
||||
exists(DataFlowIntegration::ExprNode nodeTo |
|
||||
nodeTo.getExpr() = use2 and
|
||||
useReaches(use1, nodeTo, true)
|
||||
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
|
||||
use1.getControlFlowNode() = bb1.getNode(i1) and
|
||||
use2.getControlFlowNode() = bb2.getNode(i2) and
|
||||
Impl::adjacentUseUse(bb1, i1, bb2, i2, _, true)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -654,9 +597,10 @@ private module Cached {
|
||||
*/
|
||||
cached
|
||||
predicate adjacentUseUse(VarRead use1, VarRead use2) {
|
||||
exists(DataFlowIntegration::ExprNode nodeTo |
|
||||
nodeTo.getExpr() = use2 and
|
||||
useReaches(use1, nodeTo, _)
|
||||
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
|
||||
use1.getControlFlowNode() = bb1.getNode(i1) and
|
||||
use2.getControlFlowNode() = bb2.getNode(i2) and
|
||||
Impl::adjacentUseUse(bb1, i1, bb2, i2, _, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user