mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #47 from jbj/ir-perf-blocks-etc
Approved by dave-bartolomeo
This commit is contained in:
@@ -38,6 +38,7 @@ class FunctionIR extends TFunctionIR {
|
|||||||
/**
|
/**
|
||||||
* Gets the entry point for this function.
|
* Gets the entry point for this function.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final EnterFunctionInstruction getEnterFunctionInstruction() {
|
final EnterFunctionInstruction getEnterFunctionInstruction() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
@@ -45,10 +46,12 @@ class FunctionIR extends TFunctionIR {
|
|||||||
/**
|
/**
|
||||||
* Gets the exit point for this function.
|
* Gets the exit point for this function.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final ExitFunctionInstruction getExitFunctionInstruction() {
|
final ExitFunctionInstruction getExitFunctionInstruction() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
|
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
@@ -56,6 +59,7 @@ class FunctionIR extends TFunctionIR {
|
|||||||
/**
|
/**
|
||||||
* Gets the single return instruction for this function.
|
* Gets the single return instruction for this function.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final ReturnInstruction getReturnInstruction() {
|
final ReturnInstruction getReturnInstruction() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
@@ -64,6 +68,7 @@ class FunctionIR extends TFunctionIR {
|
|||||||
* Gets the variable used to hold the return value of this function. If this
|
* Gets the variable used to hold the return value of this function. If this
|
||||||
* function does not return a value, this predicate does not hold.
|
* function does not return a value, this predicate does not hold.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final IRReturnVariable getReturnVariable() {
|
final IRReturnVariable getReturnVariable() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
@@ -71,6 +76,7 @@ class FunctionIR extends TFunctionIR {
|
|||||||
/**
|
/**
|
||||||
* Gets the block containing the entry point of this function.
|
* Gets the block containing the entry point of this function.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final IRBlock getEntryBlock() {
|
final IRBlock getEntryBlock() {
|
||||||
result.getFirstInstruction() = getEnterFunctionInstruction()
|
result.getFirstInstruction() = getEnterFunctionInstruction()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,11 @@
|
|||||||
private import IRInternal
|
private import IRInternal
|
||||||
|
private import IRBlockConstruction
|
||||||
import Instruction
|
import Instruction
|
||||||
import cpp
|
|
||||||
import semmle.code.cpp.ir.EdgeKind
|
import semmle.code.cpp.ir.EdgeKind
|
||||||
|
|
||||||
private predicate startsBasicBlock(Instruction instr) {
|
|
||||||
not instr instanceof PhiInstruction and
|
|
||||||
(
|
|
||||||
count(Instruction predecessor |
|
|
||||||
instr = predecessor.getASuccessor()
|
|
||||||
) != 1 or // Multiple predecessors or no predecessor
|
|
||||||
exists(Instruction predecessor |
|
|
||||||
instr = predecessor.getASuccessor() and
|
|
||||||
strictcount(Instruction other |
|
|
||||||
other = predecessor.getASuccessor()
|
|
||||||
) > 1
|
|
||||||
) or // Predecessor has multiple successors
|
|
||||||
exists(Instruction predecessor, EdgeKind kind |
|
|
||||||
instr = predecessor.getSuccessor(kind) and
|
|
||||||
not kind instanceof GotoEdge
|
|
||||||
) // Incoming edge is not a GotoEdge
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private newtype TIRBlock =
|
|
||||||
MkIRBlock(Instruction firstInstr) {
|
|
||||||
startsBasicBlock(firstInstr)
|
|
||||||
}
|
|
||||||
|
|
||||||
cached private predicate isEntryBlock(IRBlock block) {
|
|
||||||
block.getFirstInstruction() instanceof EnterFunctionInstruction
|
|
||||||
}
|
|
||||||
|
|
||||||
cached private predicate blockSuccessor(IRBlock pred, IRBlock succ) {
|
|
||||||
succ = pred.getASuccessor()
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate blockImmediatelyDominates(IRBlock dominator, IRBlock block) =
|
|
||||||
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
|
|
||||||
|
|
||||||
class IRBlock extends TIRBlock {
|
class IRBlock extends TIRBlock {
|
||||||
Instruction firstInstr;
|
|
||||||
|
|
||||||
IRBlock() {
|
|
||||||
this = MkIRBlock(firstInstr)
|
|
||||||
}
|
|
||||||
|
|
||||||
final string toString() {
|
final string toString() {
|
||||||
result = firstInstr.toString()
|
result = getFirstInstruction(this).toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
final Location getLocation() {
|
final Location getLocation() {
|
||||||
@@ -54,24 +13,15 @@ class IRBlock extends TIRBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final string getUniqueId() {
|
final string getUniqueId() {
|
||||||
result = firstInstr.getUniqueId()
|
result = getFirstInstruction(this).getUniqueId()
|
||||||
}
|
}
|
||||||
|
|
||||||
final cached Instruction getInstruction(int index) {
|
final Instruction getInstruction(int index) {
|
||||||
index = 0 and result = firstInstr or
|
result = getInstruction(this, index)
|
||||||
(
|
|
||||||
index > 0 and
|
|
||||||
not startsBasicBlock(result) and
|
|
||||||
exists(Instruction predecessor, GotoEdge edge |
|
|
||||||
predecessor = getInstruction(index - 1) and
|
|
||||||
result = predecessor.getSuccessor(edge)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final PhiInstruction getAPhiInstruction() {
|
final PhiInstruction getAPhiInstruction() {
|
||||||
Construction::getPhiInstructionBlockStart(result) =
|
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
|
||||||
getFirstInstruction()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Instruction getAnInstruction() {
|
final Instruction getAnInstruction() {
|
||||||
@@ -80,7 +30,7 @@ class IRBlock extends TIRBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final Instruction getFirstInstruction() {
|
final Instruction getFirstInstruction() {
|
||||||
result = firstInstr
|
result = getFirstInstruction(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
final Instruction getLastInstruction() {
|
final Instruction getLastInstruction() {
|
||||||
@@ -92,23 +42,23 @@ class IRBlock extends TIRBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final FunctionIR getFunctionIR() {
|
final FunctionIR getFunctionIR() {
|
||||||
result = firstInstr.getFunctionIR()
|
result = getFirstInstruction(this).getFunctionIR()
|
||||||
}
|
}
|
||||||
|
|
||||||
final Function getFunction() {
|
final Function getFunction() {
|
||||||
result = firstInstr.getFunction()
|
result = getFirstInstruction(this).getFunction()
|
||||||
}
|
}
|
||||||
|
|
||||||
final IRBlock getASuccessor() {
|
final IRBlock getASuccessor() {
|
||||||
result.getFirstInstruction() = getLastInstruction().getASuccessor()
|
blockSuccessor(this, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
final IRBlock getAPredecessor() {
|
final IRBlock getAPredecessor() {
|
||||||
firstInstr = result.getLastInstruction().getASuccessor()
|
blockSuccessor(result, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
final IRBlock getSuccessor(EdgeKind kind) {
|
final IRBlock getSuccessor(EdgeKind kind) {
|
||||||
result.getFirstInstruction() = getLastInstruction().getSuccessor(kind)
|
blockSuccessor(this, result, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
final predicate immediatelyDominates(IRBlock block) {
|
final predicate immediatelyDominates(IRBlock block) {
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
private import IRInternal
|
||||||
|
import Instruction
|
||||||
|
import cpp
|
||||||
|
import semmle.code.cpp.ir.EdgeKind
|
||||||
|
|
||||||
|
private predicate startsBasicBlock(Instruction instr) {
|
||||||
|
not instr instanceof PhiInstruction and
|
||||||
|
(
|
||||||
|
count(Instruction predecessor |
|
||||||
|
instr = predecessor.getASuccessor()
|
||||||
|
) != 1 or // Multiple predecessors or no predecessor
|
||||||
|
exists(Instruction predecessor |
|
||||||
|
instr = predecessor.getASuccessor() and
|
||||||
|
strictcount(Instruction other |
|
||||||
|
other = predecessor.getASuccessor()
|
||||||
|
) > 1
|
||||||
|
) or // Predecessor has multiple successors
|
||||||
|
exists(Instruction predecessor, EdgeKind kind |
|
||||||
|
instr = predecessor.getSuccessor(kind) and
|
||||||
|
not kind instanceof GotoEdge
|
||||||
|
) // Incoming edge is not a GotoEdge
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate isEntryBlock(TIRBlock block) {
|
||||||
|
block = MkIRBlock(any(EnterFunctionInstruction enter))
|
||||||
|
}
|
||||||
|
|
||||||
|
import Cached
|
||||||
|
private cached module Cached {
|
||||||
|
cached newtype TIRBlock =
|
||||||
|
MkIRBlock(Instruction firstInstr) {
|
||||||
|
startsBasicBlock(firstInstr)
|
||||||
|
}
|
||||||
|
|
||||||
|
cached Instruction getInstruction(TIRBlock block, int index) {
|
||||||
|
index = 0 and block = MkIRBlock(result) or
|
||||||
|
(
|
||||||
|
index > 0 and
|
||||||
|
not startsBasicBlock(result) and
|
||||||
|
exists(Instruction predecessor, GotoEdge edge |
|
||||||
|
predecessor = getInstruction(block, index - 1) and
|
||||||
|
result = predecessor.getSuccessor(edge)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
cached int getInstructionCount(TIRBlock block) {
|
||||||
|
result = strictcount(getInstruction(block, _))
|
||||||
|
}
|
||||||
|
|
||||||
|
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ, EdgeKind kind) {
|
||||||
|
exists(Instruction predLast, Instruction succFirst |
|
||||||
|
predLast = getInstruction(pred, getInstructionCount(pred) - 1) and
|
||||||
|
succFirst = predLast.getSuccessor(kind) and
|
||||||
|
succ = MkIRBlock(succFirst)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ) {
|
||||||
|
blockSuccessor(pred, succ, _)
|
||||||
|
}
|
||||||
|
|
||||||
|
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) =
|
||||||
|
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
Instruction getFirstInstruction(TIRBlock block) {
|
||||||
|
block = MkIRBlock(result)
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.ir.IR
|
import semmle.code.cpp.ir.IR
|
||||||
private import InstructionTag
|
private import InstructionTag
|
||||||
private import Opcode
|
|
||||||
private import TempVariableTag
|
private import TempVariableTag
|
||||||
private import TranslatedElement
|
private import TranslatedElement
|
||||||
private import TranslatedFunction
|
private import TranslatedFunction
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class FunctionIR extends TFunctionIR {
|
|||||||
/**
|
/**
|
||||||
* Gets the entry point for this function.
|
* Gets the entry point for this function.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final EnterFunctionInstruction getEnterFunctionInstruction() {
|
final EnterFunctionInstruction getEnterFunctionInstruction() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
@@ -45,10 +46,12 @@ class FunctionIR extends TFunctionIR {
|
|||||||
/**
|
/**
|
||||||
* Gets the exit point for this function.
|
* Gets the exit point for this function.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final ExitFunctionInstruction getExitFunctionInstruction() {
|
final ExitFunctionInstruction getExitFunctionInstruction() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
|
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
@@ -56,6 +59,7 @@ class FunctionIR extends TFunctionIR {
|
|||||||
/**
|
/**
|
||||||
* Gets the single return instruction for this function.
|
* Gets the single return instruction for this function.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final ReturnInstruction getReturnInstruction() {
|
final ReturnInstruction getReturnInstruction() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
@@ -64,6 +68,7 @@ class FunctionIR extends TFunctionIR {
|
|||||||
* Gets the variable used to hold the return value of this function. If this
|
* Gets the variable used to hold the return value of this function. If this
|
||||||
* function does not return a value, this predicate does not hold.
|
* function does not return a value, this predicate does not hold.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final IRReturnVariable getReturnVariable() {
|
final IRReturnVariable getReturnVariable() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
@@ -71,6 +76,7 @@ class FunctionIR extends TFunctionIR {
|
|||||||
/**
|
/**
|
||||||
* Gets the block containing the entry point of this function.
|
* Gets the block containing the entry point of this function.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final IRBlock getEntryBlock() {
|
final IRBlock getEntryBlock() {
|
||||||
result.getFirstInstruction() = getEnterFunctionInstruction()
|
result.getFirstInstruction() = getEnterFunctionInstruction()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,11 @@
|
|||||||
private import IRInternal
|
private import IRInternal
|
||||||
|
private import IRBlockConstruction
|
||||||
import Instruction
|
import Instruction
|
||||||
import cpp
|
|
||||||
import semmle.code.cpp.ir.EdgeKind
|
import semmle.code.cpp.ir.EdgeKind
|
||||||
|
|
||||||
private predicate startsBasicBlock(Instruction instr) {
|
|
||||||
not instr instanceof PhiInstruction and
|
|
||||||
(
|
|
||||||
count(Instruction predecessor |
|
|
||||||
instr = predecessor.getASuccessor()
|
|
||||||
) != 1 or // Multiple predecessors or no predecessor
|
|
||||||
exists(Instruction predecessor |
|
|
||||||
instr = predecessor.getASuccessor() and
|
|
||||||
strictcount(Instruction other |
|
|
||||||
other = predecessor.getASuccessor()
|
|
||||||
) > 1
|
|
||||||
) or // Predecessor has multiple successors
|
|
||||||
exists(Instruction predecessor, EdgeKind kind |
|
|
||||||
instr = predecessor.getSuccessor(kind) and
|
|
||||||
not kind instanceof GotoEdge
|
|
||||||
) // Incoming edge is not a GotoEdge
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private newtype TIRBlock =
|
|
||||||
MkIRBlock(Instruction firstInstr) {
|
|
||||||
startsBasicBlock(firstInstr)
|
|
||||||
}
|
|
||||||
|
|
||||||
cached private predicate isEntryBlock(IRBlock block) {
|
|
||||||
block.getFirstInstruction() instanceof EnterFunctionInstruction
|
|
||||||
}
|
|
||||||
|
|
||||||
cached private predicate blockSuccessor(IRBlock pred, IRBlock succ) {
|
|
||||||
succ = pred.getASuccessor()
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate blockImmediatelyDominates(IRBlock dominator, IRBlock block) =
|
|
||||||
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
|
|
||||||
|
|
||||||
class IRBlock extends TIRBlock {
|
class IRBlock extends TIRBlock {
|
||||||
Instruction firstInstr;
|
|
||||||
|
|
||||||
IRBlock() {
|
|
||||||
this = MkIRBlock(firstInstr)
|
|
||||||
}
|
|
||||||
|
|
||||||
final string toString() {
|
final string toString() {
|
||||||
result = firstInstr.toString()
|
result = getFirstInstruction(this).toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
final Location getLocation() {
|
final Location getLocation() {
|
||||||
@@ -54,24 +13,15 @@ class IRBlock extends TIRBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final string getUniqueId() {
|
final string getUniqueId() {
|
||||||
result = firstInstr.getUniqueId()
|
result = getFirstInstruction(this).getUniqueId()
|
||||||
}
|
}
|
||||||
|
|
||||||
final cached Instruction getInstruction(int index) {
|
final Instruction getInstruction(int index) {
|
||||||
index = 0 and result = firstInstr or
|
result = getInstruction(this, index)
|
||||||
(
|
|
||||||
index > 0 and
|
|
||||||
not startsBasicBlock(result) and
|
|
||||||
exists(Instruction predecessor, GotoEdge edge |
|
|
||||||
predecessor = getInstruction(index - 1) and
|
|
||||||
result = predecessor.getSuccessor(edge)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final PhiInstruction getAPhiInstruction() {
|
final PhiInstruction getAPhiInstruction() {
|
||||||
Construction::getPhiInstructionBlockStart(result) =
|
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
|
||||||
getFirstInstruction()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Instruction getAnInstruction() {
|
final Instruction getAnInstruction() {
|
||||||
@@ -80,7 +30,7 @@ class IRBlock extends TIRBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final Instruction getFirstInstruction() {
|
final Instruction getFirstInstruction() {
|
||||||
result = firstInstr
|
result = getFirstInstruction(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
final Instruction getLastInstruction() {
|
final Instruction getLastInstruction() {
|
||||||
@@ -92,23 +42,23 @@ class IRBlock extends TIRBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final FunctionIR getFunctionIR() {
|
final FunctionIR getFunctionIR() {
|
||||||
result = firstInstr.getFunctionIR()
|
result = getFirstInstruction(this).getFunctionIR()
|
||||||
}
|
}
|
||||||
|
|
||||||
final Function getFunction() {
|
final Function getFunction() {
|
||||||
result = firstInstr.getFunction()
|
result = getFirstInstruction(this).getFunction()
|
||||||
}
|
}
|
||||||
|
|
||||||
final IRBlock getASuccessor() {
|
final IRBlock getASuccessor() {
|
||||||
result.getFirstInstruction() = getLastInstruction().getASuccessor()
|
blockSuccessor(this, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
final IRBlock getAPredecessor() {
|
final IRBlock getAPredecessor() {
|
||||||
firstInstr = result.getLastInstruction().getASuccessor()
|
blockSuccessor(result, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
final IRBlock getSuccessor(EdgeKind kind) {
|
final IRBlock getSuccessor(EdgeKind kind) {
|
||||||
result.getFirstInstruction() = getLastInstruction().getSuccessor(kind)
|
blockSuccessor(this, result, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
final predicate immediatelyDominates(IRBlock block) {
|
final predicate immediatelyDominates(IRBlock block) {
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
private import IRInternal
|
||||||
|
private import Construction::OldIR as OldIR
|
||||||
|
import Instruction
|
||||||
|
|
||||||
|
import Cached
|
||||||
|
private cached module Cached {
|
||||||
|
cached newtype TIRBlock = MkIRBlock(OldIR::IRBlock oldBlock)
|
||||||
|
|
||||||
|
private OldIR::IRBlock getOldBlock(TIRBlock block) {
|
||||||
|
block = MkIRBlock(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
cached Instruction getInstruction(TIRBlock block, int index) {
|
||||||
|
Construction::getOldInstruction(result) =
|
||||||
|
getOldBlock(block).getInstruction(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
cached int getInstructionCount(TIRBlock block) {
|
||||||
|
result = getOldBlock(block).getInstructionCount()
|
||||||
|
}
|
||||||
|
|
||||||
|
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ, EdgeKind kind) {
|
||||||
|
succ = MkIRBlock(getOldBlock(pred).getSuccessor(kind))
|
||||||
|
}
|
||||||
|
|
||||||
|
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ) {
|
||||||
|
blockSuccessor(pred, succ, _)
|
||||||
|
}
|
||||||
|
|
||||||
|
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) {
|
||||||
|
getOldBlock(dominator).immediatelyDominates(getOldBlock(block))
|
||||||
|
}
|
||||||
|
|
||||||
|
cached Instruction getFirstInstruction(TIRBlock block) {
|
||||||
|
Construction::getOldInstruction(result) =
|
||||||
|
getOldBlock(block).getFirstInstruction()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,7 +59,7 @@ cached private module Cached {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Instruction getNewInstruction(OldIR::Instruction instr) {
|
private Instruction getNewInstruction(OldIR::Instruction instr) {
|
||||||
result.getTag() = WrappedInstructionTag(instr)
|
getOldInstruction(result) = instr
|
||||||
}
|
}
|
||||||
|
|
||||||
private PhiInstruction getPhiInstruction(Function func, OldIR::IRBlock oldBlock,
|
private PhiInstruction getPhiInstruction(Function func, OldIR::IRBlock oldBlock,
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class FunctionIR extends TFunctionIR {
|
|||||||
/**
|
/**
|
||||||
* Gets the entry point for this function.
|
* Gets the entry point for this function.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final EnterFunctionInstruction getEnterFunctionInstruction() {
|
final EnterFunctionInstruction getEnterFunctionInstruction() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
@@ -45,10 +46,12 @@ class FunctionIR extends TFunctionIR {
|
|||||||
/**
|
/**
|
||||||
* Gets the exit point for this function.
|
* Gets the exit point for this function.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final ExitFunctionInstruction getExitFunctionInstruction() {
|
final ExitFunctionInstruction getExitFunctionInstruction() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
|
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
@@ -56,6 +59,7 @@ class FunctionIR extends TFunctionIR {
|
|||||||
/**
|
/**
|
||||||
* Gets the single return instruction for this function.
|
* Gets the single return instruction for this function.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final ReturnInstruction getReturnInstruction() {
|
final ReturnInstruction getReturnInstruction() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
@@ -64,6 +68,7 @@ class FunctionIR extends TFunctionIR {
|
|||||||
* Gets the variable used to hold the return value of this function. If this
|
* Gets the variable used to hold the return value of this function. If this
|
||||||
* function does not return a value, this predicate does not hold.
|
* function does not return a value, this predicate does not hold.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final IRReturnVariable getReturnVariable() {
|
final IRReturnVariable getReturnVariable() {
|
||||||
result.getFunctionIR() = this
|
result.getFunctionIR() = this
|
||||||
}
|
}
|
||||||
@@ -71,6 +76,7 @@ class FunctionIR extends TFunctionIR {
|
|||||||
/**
|
/**
|
||||||
* Gets the block containing the entry point of this function.
|
* Gets the block containing the entry point of this function.
|
||||||
*/
|
*/
|
||||||
|
pragma[noinline]
|
||||||
final IRBlock getEntryBlock() {
|
final IRBlock getEntryBlock() {
|
||||||
result.getFirstInstruction() = getEnterFunctionInstruction()
|
result.getFirstInstruction() = getEnterFunctionInstruction()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,11 @@
|
|||||||
private import IRInternal
|
private import IRInternal
|
||||||
|
private import IRBlockConstruction
|
||||||
import Instruction
|
import Instruction
|
||||||
import cpp
|
|
||||||
import semmle.code.cpp.ir.EdgeKind
|
import semmle.code.cpp.ir.EdgeKind
|
||||||
|
|
||||||
private predicate startsBasicBlock(Instruction instr) {
|
|
||||||
not instr instanceof PhiInstruction and
|
|
||||||
(
|
|
||||||
count(Instruction predecessor |
|
|
||||||
instr = predecessor.getASuccessor()
|
|
||||||
) != 1 or // Multiple predecessors or no predecessor
|
|
||||||
exists(Instruction predecessor |
|
|
||||||
instr = predecessor.getASuccessor() and
|
|
||||||
strictcount(Instruction other |
|
|
||||||
other = predecessor.getASuccessor()
|
|
||||||
) > 1
|
|
||||||
) or // Predecessor has multiple successors
|
|
||||||
exists(Instruction predecessor, EdgeKind kind |
|
|
||||||
instr = predecessor.getSuccessor(kind) and
|
|
||||||
not kind instanceof GotoEdge
|
|
||||||
) // Incoming edge is not a GotoEdge
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private newtype TIRBlock =
|
|
||||||
MkIRBlock(Instruction firstInstr) {
|
|
||||||
startsBasicBlock(firstInstr)
|
|
||||||
}
|
|
||||||
|
|
||||||
cached private predicate isEntryBlock(IRBlock block) {
|
|
||||||
block.getFirstInstruction() instanceof EnterFunctionInstruction
|
|
||||||
}
|
|
||||||
|
|
||||||
cached private predicate blockSuccessor(IRBlock pred, IRBlock succ) {
|
|
||||||
succ = pred.getASuccessor()
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate blockImmediatelyDominates(IRBlock dominator, IRBlock block) =
|
|
||||||
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
|
|
||||||
|
|
||||||
class IRBlock extends TIRBlock {
|
class IRBlock extends TIRBlock {
|
||||||
Instruction firstInstr;
|
|
||||||
|
|
||||||
IRBlock() {
|
|
||||||
this = MkIRBlock(firstInstr)
|
|
||||||
}
|
|
||||||
|
|
||||||
final string toString() {
|
final string toString() {
|
||||||
result = firstInstr.toString()
|
result = getFirstInstruction(this).toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
final Location getLocation() {
|
final Location getLocation() {
|
||||||
@@ -54,24 +13,15 @@ class IRBlock extends TIRBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final string getUniqueId() {
|
final string getUniqueId() {
|
||||||
result = firstInstr.getUniqueId()
|
result = getFirstInstruction(this).getUniqueId()
|
||||||
}
|
}
|
||||||
|
|
||||||
final cached Instruction getInstruction(int index) {
|
final Instruction getInstruction(int index) {
|
||||||
index = 0 and result = firstInstr or
|
result = getInstruction(this, index)
|
||||||
(
|
|
||||||
index > 0 and
|
|
||||||
not startsBasicBlock(result) and
|
|
||||||
exists(Instruction predecessor, GotoEdge edge |
|
|
||||||
predecessor = getInstruction(index - 1) and
|
|
||||||
result = predecessor.getSuccessor(edge)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final PhiInstruction getAPhiInstruction() {
|
final PhiInstruction getAPhiInstruction() {
|
||||||
Construction::getPhiInstructionBlockStart(result) =
|
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
|
||||||
getFirstInstruction()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Instruction getAnInstruction() {
|
final Instruction getAnInstruction() {
|
||||||
@@ -80,7 +30,7 @@ class IRBlock extends TIRBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final Instruction getFirstInstruction() {
|
final Instruction getFirstInstruction() {
|
||||||
result = firstInstr
|
result = getFirstInstruction(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
final Instruction getLastInstruction() {
|
final Instruction getLastInstruction() {
|
||||||
@@ -92,23 +42,23 @@ class IRBlock extends TIRBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final FunctionIR getFunctionIR() {
|
final FunctionIR getFunctionIR() {
|
||||||
result = firstInstr.getFunctionIR()
|
result = getFirstInstruction(this).getFunctionIR()
|
||||||
}
|
}
|
||||||
|
|
||||||
final Function getFunction() {
|
final Function getFunction() {
|
||||||
result = firstInstr.getFunction()
|
result = getFirstInstruction(this).getFunction()
|
||||||
}
|
}
|
||||||
|
|
||||||
final IRBlock getASuccessor() {
|
final IRBlock getASuccessor() {
|
||||||
result.getFirstInstruction() = getLastInstruction().getASuccessor()
|
blockSuccessor(this, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
final IRBlock getAPredecessor() {
|
final IRBlock getAPredecessor() {
|
||||||
firstInstr = result.getLastInstruction().getASuccessor()
|
blockSuccessor(result, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
final IRBlock getSuccessor(EdgeKind kind) {
|
final IRBlock getSuccessor(EdgeKind kind) {
|
||||||
result.getFirstInstruction() = getLastInstruction().getSuccessor(kind)
|
blockSuccessor(this, result, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
final predicate immediatelyDominates(IRBlock block) {
|
final predicate immediatelyDominates(IRBlock block) {
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
private import IRInternal
|
||||||
|
private import Construction::OldIR as OldIR
|
||||||
|
import Instruction
|
||||||
|
|
||||||
|
import Cached
|
||||||
|
private cached module Cached {
|
||||||
|
cached newtype TIRBlock = MkIRBlock(OldIR::IRBlock oldBlock)
|
||||||
|
|
||||||
|
private OldIR::IRBlock getOldBlock(TIRBlock block) {
|
||||||
|
block = MkIRBlock(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
cached Instruction getInstruction(TIRBlock block, int index) {
|
||||||
|
Construction::getOldInstruction(result) =
|
||||||
|
getOldBlock(block).getInstruction(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
cached int getInstructionCount(TIRBlock block) {
|
||||||
|
result = getOldBlock(block).getInstructionCount()
|
||||||
|
}
|
||||||
|
|
||||||
|
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ, EdgeKind kind) {
|
||||||
|
succ = MkIRBlock(getOldBlock(pred).getSuccessor(kind))
|
||||||
|
}
|
||||||
|
|
||||||
|
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ) {
|
||||||
|
blockSuccessor(pred, succ, _)
|
||||||
|
}
|
||||||
|
|
||||||
|
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) {
|
||||||
|
getOldBlock(dominator).immediatelyDominates(getOldBlock(block))
|
||||||
|
}
|
||||||
|
|
||||||
|
cached Instruction getFirstInstruction(TIRBlock block) {
|
||||||
|
Construction::getOldInstruction(result) =
|
||||||
|
getOldBlock(block).getFirstInstruction()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,7 +59,7 @@ cached private module Cached {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Instruction getNewInstruction(OldIR::Instruction instr) {
|
private Instruction getNewInstruction(OldIR::Instruction instr) {
|
||||||
result.getTag() = WrappedInstructionTag(instr)
|
getOldInstruction(result) = instr
|
||||||
}
|
}
|
||||||
|
|
||||||
private PhiInstruction getPhiInstruction(Function func, OldIR::IRBlock oldBlock,
|
private PhiInstruction getPhiInstruction(Function func, OldIR::IRBlock oldBlock,
|
||||||
|
|||||||
Reference in New Issue
Block a user