C++: Factor out IRBlock.qll differences

All three `IRBlock.qll` files are now identical again, and they are just
a thin object-oriented layer on top of the three
`IRBlockConstruction.qll` files, two of which are identical.
This commit is contained in:
Jonas Jensen
2018-08-14 14:12:26 +02:00
parent d88c9c67f1
commit dc22833259
7 changed files with 190 additions and 146 deletions

View File

@@ -1,78 +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 predicate isEntryBlock(TIRBlock block) {
block = MkIRBlock(any(EnterFunctionInstruction enter))
}
private 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)
}
class IRBlock extends TIRBlock {
Instruction firstInstr;
IRBlock() {
this = MkIRBlock(firstInstr)
}
final string toString() {
result = firstInstr.toString()
result = getFirstInstruction(this).toString()
}
final Location getLocation() {
@@ -80,7 +13,7 @@ class IRBlock extends TIRBlock {
}
final string getUniqueId() {
result = firstInstr.getUniqueId()
result = getFirstInstruction(this).getUniqueId()
}
final Instruction getInstruction(int index) {
@@ -88,7 +21,7 @@ class IRBlock extends TIRBlock {
}
final PhiInstruction getAPhiInstruction() {
none()
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
}
final Instruction getAnInstruction() {
@@ -97,7 +30,7 @@ class IRBlock extends TIRBlock {
}
final Instruction getFirstInstruction() {
result = firstInstr
result = getFirstInstruction(this)
}
final Instruction getLastInstruction() {
@@ -109,11 +42,11 @@ 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() {

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

@@ -1,36 +1,27 @@
private import IRInternal
private import Construction::OldIR as OldIR
private import IRBlockConstruction
import Instruction
import semmle.code.cpp.ir.EdgeKind
cached newtype TIRBlock = MkIRBlock(OldIR::IRBlock oldBlock)
class IRBlock extends TIRBlock {
OldIR::IRBlock oldBlock;
IRBlock() {
this = MkIRBlock(oldBlock)
}
final string toString() {
result = oldBlock.toString()
result = getFirstInstruction(this).toString()
}
final Location getLocation() {
result = oldBlock.getLocation()
result = getFirstInstruction().getLocation()
}
final string getUniqueId() {
result = oldBlock.getUniqueId()
result = getFirstInstruction(this).getUniqueId()
}
final Instruction getInstruction(int index) {
Construction::getOldInstruction(result) = oldBlock.getInstruction(index)
result = getInstruction(this, index)
}
final PhiInstruction getAPhiInstruction() {
Construction::getPhiInstructionBlockStart(result) =
getFirstInstruction()
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
}
final Instruction getAnInstruction() {
@@ -39,47 +30,43 @@ class IRBlock extends TIRBlock {
}
final Instruction getFirstInstruction() {
Construction::getOldInstruction(result) = oldBlock.getFirstInstruction()
result = getFirstInstruction(this)
}
final Instruction getLastInstruction() {
Construction::getOldInstruction(result) = oldBlock.getLastInstruction()
result = getInstruction(getInstructionCount() - 1)
}
final int getInstructionCount() {
result = oldBlock.getInstructionCount()
result = strictcount(getInstruction(_))
}
final FunctionIR getFunctionIR() {
result = getFirstInstruction().getFunctionIR()
result = getFirstInstruction(this).getFunctionIR()
}
final Function getFunction() {
result = getFirstInstruction().getFunction()
result = getFirstInstruction(this).getFunction()
}
final IRBlock getASuccessor() {
result = MkIRBlock(oldBlock.getASuccessor())
blockSuccessor(this, result)
}
final IRBlock getAPredecessor() {
result.getASuccessor() = this
blockSuccessor(result, this)
}
final IRBlock getSuccessor(EdgeKind kind) {
result = MkIRBlock(oldBlock.getSuccessor(kind))
blockSuccessor(this, result, kind)
}
final predicate immediatelyDominates(IRBlock block) {
oldBlock.immediatelyDominates(block.getOldBlock())
blockImmediatelyDominates(this, block)
}
final predicate strictlyDominates(IRBlock block) {
// This is recomputed from scratch rather than reusing the corresponding
// predicate of `getOldBlock` because `getOldBlock.strictlyDominates/1` may
// at run time be a compactly stored transitive closure that we don't want
// to risk materializing in order to join with `MkIRBlock`.
immediatelyDominates+(block)
blockImmediatelyDominates+(this, block)
}
final predicate dominates(IRBlock block) {
@@ -91,8 +78,4 @@ class IRBlock extends TIRBlock {
dominates(result.getAPredecessor()) and
not strictlyDominates(result)
}
private OldIR::IRBlock getOldBlock() {
result = oldBlock
}
}

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

@@ -1,36 +1,27 @@
private import IRInternal
private import Construction::OldIR as OldIR
private import IRBlockConstruction
import Instruction
import semmle.code.cpp.ir.EdgeKind
cached newtype TIRBlock = MkIRBlock(OldIR::IRBlock oldBlock)
class IRBlock extends TIRBlock {
OldIR::IRBlock oldBlock;
IRBlock() {
this = MkIRBlock(oldBlock)
}
final string toString() {
result = oldBlock.toString()
result = getFirstInstruction(this).toString()
}
final Location getLocation() {
result = oldBlock.getLocation()
result = getFirstInstruction().getLocation()
}
final string getUniqueId() {
result = oldBlock.getUniqueId()
result = getFirstInstruction(this).getUniqueId()
}
final Instruction getInstruction(int index) {
Construction::getOldInstruction(result) = oldBlock.getInstruction(index)
result = getInstruction(this, index)
}
final PhiInstruction getAPhiInstruction() {
Construction::getPhiInstructionBlockStart(result) =
getFirstInstruction()
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
}
final Instruction getAnInstruction() {
@@ -39,47 +30,43 @@ class IRBlock extends TIRBlock {
}
final Instruction getFirstInstruction() {
Construction::getOldInstruction(result) = oldBlock.getFirstInstruction()
result = getFirstInstruction(this)
}
final Instruction getLastInstruction() {
Construction::getOldInstruction(result) = oldBlock.getLastInstruction()
result = getInstruction(getInstructionCount() - 1)
}
final int getInstructionCount() {
result = oldBlock.getInstructionCount()
result = strictcount(getInstruction(_))
}
final FunctionIR getFunctionIR() {
result = getFirstInstruction().getFunctionIR()
result = getFirstInstruction(this).getFunctionIR()
}
final Function getFunction() {
result = getFirstInstruction().getFunction()
result = getFirstInstruction(this).getFunction()
}
final IRBlock getASuccessor() {
result = MkIRBlock(oldBlock.getASuccessor())
blockSuccessor(this, result)
}
final IRBlock getAPredecessor() {
result.getASuccessor() = this
blockSuccessor(result, this)
}
final IRBlock getSuccessor(EdgeKind kind) {
result = MkIRBlock(oldBlock.getSuccessor(kind))
blockSuccessor(this, result, kind)
}
final predicate immediatelyDominates(IRBlock block) {
oldBlock.immediatelyDominates(block.getOldBlock())
blockImmediatelyDominates(this, block)
}
final predicate strictlyDominates(IRBlock block) {
// This is recomputed from scratch rather than reusing the corresponding
// predicate of `getOldBlock` because `getOldBlock.strictlyDominates/1` may
// at run time be a compactly stored transitive closure that we don't want
// to risk materializing in order to join with `MkIRBlock`.
immediatelyDominates+(block)
blockImmediatelyDominates+(this, block)
}
final predicate dominates(IRBlock block) {
@@ -91,8 +78,4 @@ class IRBlock extends TIRBlock {
dominates(result.getAPredecessor()) and
not strictlyDominates(result)
}
private OldIR::IRBlock getOldBlock() {
result = oldBlock
}
}

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