Merge pull request #47 from jbj/ir-perf-blocks-etc

Approved by dave-bartolomeo
This commit is contained in:
semmle-qlci
2018-08-15 12:53:43 +01:00
committed by GitHub
12 changed files with 202 additions and 189 deletions

View File

@@ -38,6 +38,7 @@ class FunctionIR extends TFunctionIR {
/**
* Gets the entry point for this function.
*/
pragma[noinline]
final EnterFunctionInstruction getEnterFunctionInstruction() {
result.getFunctionIR() = this
}
@@ -45,10 +46,12 @@ class FunctionIR extends TFunctionIR {
/**
* Gets the exit point for this function.
*/
pragma[noinline]
final ExitFunctionInstruction getExitFunctionInstruction() {
result.getFunctionIR() = this
}
pragma[noinline]
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
result.getFunctionIR() = this
}
@@ -56,6 +59,7 @@ class FunctionIR extends TFunctionIR {
/**
* Gets the single return instruction for this function.
*/
pragma[noinline]
final ReturnInstruction getReturnInstruction() {
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
* function does not return a value, this predicate does not hold.
*/
pragma[noinline]
final IRReturnVariable getReturnVariable() {
result.getFunctionIR() = this
}
@@ -71,6 +76,7 @@ class FunctionIR extends TFunctionIR {
/**
* Gets the block containing the entry point of this function.
*/
pragma[noinline]
final IRBlock getEntryBlock() {
result.getFirstInstruction() = getEnterFunctionInstruction()
}

View File

@@ -1,52 +1,11 @@
private import IRInternal
private import IRBlockConstruction
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 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 {
Instruction firstInstr;
IRBlock() {
this = MkIRBlock(firstInstr)
}
final string toString() {
result = firstInstr.toString()
result = getFirstInstruction(this).toString()
}
final Location getLocation() {
@@ -54,24 +13,15 @@ class IRBlock extends TIRBlock {
}
final string getUniqueId() {
result = firstInstr.getUniqueId()
result = getFirstInstruction(this).getUniqueId()
}
final cached Instruction getInstruction(int index) {
index = 0 and result = firstInstr or
(
index > 0 and
not startsBasicBlock(result) and
exists(Instruction predecessor, GotoEdge edge |
predecessor = getInstruction(index - 1) and
result = predecessor.getSuccessor(edge)
)
)
final Instruction getInstruction(int index) {
result = getInstruction(this, index)
}
final PhiInstruction getAPhiInstruction() {
Construction::getPhiInstructionBlockStart(result) =
getFirstInstruction()
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
}
final Instruction getAnInstruction() {
@@ -80,7 +30,7 @@ class IRBlock extends TIRBlock {
}
final Instruction getFirstInstruction() {
result = firstInstr
result = getFirstInstruction(this)
}
final Instruction getLastInstruction() {
@@ -92,23 +42,23 @@ class IRBlock extends TIRBlock {
}
final FunctionIR getFunctionIR() {
result = firstInstr.getFunctionIR()
result = getFirstInstruction(this).getFunctionIR()
}
final Function getFunction() {
result = firstInstr.getFunction()
result = getFirstInstruction(this).getFunction()
}
final IRBlock getASuccessor() {
result.getFirstInstruction() = getLastInstruction().getASuccessor()
blockSuccessor(this, result)
}
final IRBlock getAPredecessor() {
firstInstr = result.getLastInstruction().getASuccessor()
blockSuccessor(result, this)
}
final IRBlock getSuccessor(EdgeKind kind) {
result.getFirstInstruction() = getLastInstruction().getSuccessor(kind)
blockSuccessor(this, result, kind)
}
final predicate immediatelyDominates(IRBlock block) {

View File

@@ -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)
}

View File

@@ -1,7 +1,6 @@
import cpp
import semmle.code.cpp.ir.IR
private import InstructionTag
private import Opcode
private import TempVariableTag
private import TranslatedElement
private import TranslatedFunction

View File

@@ -38,6 +38,7 @@ class FunctionIR extends TFunctionIR {
/**
* Gets the entry point for this function.
*/
pragma[noinline]
final EnterFunctionInstruction getEnterFunctionInstruction() {
result.getFunctionIR() = this
}
@@ -45,10 +46,12 @@ class FunctionIR extends TFunctionIR {
/**
* Gets the exit point for this function.
*/
pragma[noinline]
final ExitFunctionInstruction getExitFunctionInstruction() {
result.getFunctionIR() = this
}
pragma[noinline]
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
result.getFunctionIR() = this
}
@@ -56,6 +59,7 @@ class FunctionIR extends TFunctionIR {
/**
* Gets the single return instruction for this function.
*/
pragma[noinline]
final ReturnInstruction getReturnInstruction() {
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
* function does not return a value, this predicate does not hold.
*/
pragma[noinline]
final IRReturnVariable getReturnVariable() {
result.getFunctionIR() = this
}
@@ -71,6 +76,7 @@ class FunctionIR extends TFunctionIR {
/**
* Gets the block containing the entry point of this function.
*/
pragma[noinline]
final IRBlock getEntryBlock() {
result.getFirstInstruction() = getEnterFunctionInstruction()
}

View File

@@ -1,52 +1,11 @@
private import IRInternal
private import IRBlockConstruction
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 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 {
Instruction firstInstr;
IRBlock() {
this = MkIRBlock(firstInstr)
}
final string toString() {
result = firstInstr.toString()
result = getFirstInstruction(this).toString()
}
final Location getLocation() {
@@ -54,24 +13,15 @@ class IRBlock extends TIRBlock {
}
final string getUniqueId() {
result = firstInstr.getUniqueId()
result = getFirstInstruction(this).getUniqueId()
}
final cached Instruction getInstruction(int index) {
index = 0 and result = firstInstr or
(
index > 0 and
not startsBasicBlock(result) and
exists(Instruction predecessor, GotoEdge edge |
predecessor = getInstruction(index - 1) and
result = predecessor.getSuccessor(edge)
)
)
final Instruction getInstruction(int index) {
result = getInstruction(this, index)
}
final PhiInstruction getAPhiInstruction() {
Construction::getPhiInstructionBlockStart(result) =
getFirstInstruction()
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
}
final Instruction getAnInstruction() {
@@ -80,7 +30,7 @@ class IRBlock extends TIRBlock {
}
final Instruction getFirstInstruction() {
result = firstInstr
result = getFirstInstruction(this)
}
final Instruction getLastInstruction() {
@@ -92,23 +42,23 @@ class IRBlock extends TIRBlock {
}
final FunctionIR getFunctionIR() {
result = firstInstr.getFunctionIR()
result = getFirstInstruction(this).getFunctionIR()
}
final Function getFunction() {
result = firstInstr.getFunction()
result = getFirstInstruction(this).getFunction()
}
final IRBlock getASuccessor() {
result.getFirstInstruction() = getLastInstruction().getASuccessor()
blockSuccessor(this, result)
}
final IRBlock getAPredecessor() {
firstInstr = result.getLastInstruction().getASuccessor()
blockSuccessor(result, this)
}
final IRBlock getSuccessor(EdgeKind kind) {
result.getFirstInstruction() = getLastInstruction().getSuccessor(kind)
blockSuccessor(this, result, kind)
}
final predicate immediatelyDominates(IRBlock block) {

View File

@@ -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()
}
}

View File

@@ -59,7 +59,7 @@ cached private module Cached {
}
private Instruction getNewInstruction(OldIR::Instruction instr) {
result.getTag() = WrappedInstructionTag(instr)
getOldInstruction(result) = instr
}
private PhiInstruction getPhiInstruction(Function func, OldIR::IRBlock oldBlock,

View File

@@ -38,6 +38,7 @@ class FunctionIR extends TFunctionIR {
/**
* Gets the entry point for this function.
*/
pragma[noinline]
final EnterFunctionInstruction getEnterFunctionInstruction() {
result.getFunctionIR() = this
}
@@ -45,10 +46,12 @@ class FunctionIR extends TFunctionIR {
/**
* Gets the exit point for this function.
*/
pragma[noinline]
final ExitFunctionInstruction getExitFunctionInstruction() {
result.getFunctionIR() = this
}
pragma[noinline]
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
result.getFunctionIR() = this
}
@@ -56,6 +59,7 @@ class FunctionIR extends TFunctionIR {
/**
* Gets the single return instruction for this function.
*/
pragma[noinline]
final ReturnInstruction getReturnInstruction() {
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
* function does not return a value, this predicate does not hold.
*/
pragma[noinline]
final IRReturnVariable getReturnVariable() {
result.getFunctionIR() = this
}
@@ -71,6 +76,7 @@ class FunctionIR extends TFunctionIR {
/**
* Gets the block containing the entry point of this function.
*/
pragma[noinline]
final IRBlock getEntryBlock() {
result.getFirstInstruction() = getEnterFunctionInstruction()
}

View File

@@ -1,52 +1,11 @@
private import IRInternal
private import IRBlockConstruction
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 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 {
Instruction firstInstr;
IRBlock() {
this = MkIRBlock(firstInstr)
}
final string toString() {
result = firstInstr.toString()
result = getFirstInstruction(this).toString()
}
final Location getLocation() {
@@ -54,24 +13,15 @@ class IRBlock extends TIRBlock {
}
final string getUniqueId() {
result = firstInstr.getUniqueId()
result = getFirstInstruction(this).getUniqueId()
}
final cached Instruction getInstruction(int index) {
index = 0 and result = firstInstr or
(
index > 0 and
not startsBasicBlock(result) and
exists(Instruction predecessor, GotoEdge edge |
predecessor = getInstruction(index - 1) and
result = predecessor.getSuccessor(edge)
)
)
final Instruction getInstruction(int index) {
result = getInstruction(this, index)
}
final PhiInstruction getAPhiInstruction() {
Construction::getPhiInstructionBlockStart(result) =
getFirstInstruction()
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
}
final Instruction getAnInstruction() {
@@ -80,7 +30,7 @@ class IRBlock extends TIRBlock {
}
final Instruction getFirstInstruction() {
result = firstInstr
result = getFirstInstruction(this)
}
final Instruction getLastInstruction() {
@@ -92,23 +42,23 @@ class IRBlock extends TIRBlock {
}
final FunctionIR getFunctionIR() {
result = firstInstr.getFunctionIR()
result = getFirstInstruction(this).getFunctionIR()
}
final Function getFunction() {
result = firstInstr.getFunction()
result = getFirstInstruction(this).getFunction()
}
final IRBlock getASuccessor() {
result.getFirstInstruction() = getLastInstruction().getASuccessor()
blockSuccessor(this, result)
}
final IRBlock getAPredecessor() {
firstInstr = result.getLastInstruction().getASuccessor()
blockSuccessor(result, this)
}
final IRBlock getSuccessor(EdgeKind kind) {
result.getFirstInstruction() = getLastInstruction().getSuccessor(kind)
blockSuccessor(this, result, kind)
}
final predicate immediatelyDominates(IRBlock block) {

View File

@@ -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()
}
}

View File

@@ -59,7 +59,7 @@ cached private module Cached {
}
private Instruction getNewInstruction(OldIR::Instruction instr) {
result.getTag() = WrappedInstructionTag(instr)
getOldInstruction(result) = instr
}
private PhiInstruction getPhiInstruction(Function func, OldIR::IRBlock oldBlock,