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

View File

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

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 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

View File

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

View File

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

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) { 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,

View File

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

View File

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

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) { 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,