C++: No InstructionTag in SSAConstruction

This does to `SSAConstruction` what the previous commit did to
`IRConstruction`. An instruction in `SSAConstruction` is now defined in
terms of how it was created rather than what it can be queried for.
Effectively, this defines `TInstruction` as `TInstructionTag` was
defined before and then removes `TInstructionTag` from
`SSAConstruction`. This also has the benefit of removing the concept of
an instruction tag from the public predicates on `Instruction`.
This commit is contained in:
Jonas Jensen
2019-02-01 21:22:52 +01:00
parent 8ae3551ec1
commit 3735cb69ce
7 changed files with 236 additions and 266 deletions

View File

@@ -10,8 +10,6 @@ import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
class InstructionTag = Construction::InstructionTagType;
module InstructionSanity {
/**
* Holds if the instruction `instr` should be expected to have an operand
@@ -463,10 +461,6 @@ class Instruction extends Construction::TInstruction {
result = Construction::getInstructionOpcode(this)
}
final InstructionTag getTag() {
result = Construction::getInstructionTag(this)
}
/**
* Gets all direct uses of the result of this instruction.
*/

View File

@@ -7,26 +7,6 @@ private import NewIR
private class OldBlock = Reachability::ReachableBlock;
private class OldInstruction = Reachability::ReachableInstruction;
InstructionTag getInstructionTag(Instruction instruction) {
instruction = MkInstruction(_, _, _, result, _, _)
}
Locatable getInstructionAST(Instruction instruction) {
instruction = MkInstruction(_, _, result, _, _, _)
}
predicate instructionHasType(Instruction instruction, Type type, boolean isGLValue) {
instruction = MkInstruction(_, _, _, _, type, isGLValue)
}
Opcode getInstructionOpcode(Instruction instruction) {
instruction = MkInstruction(_, result, _, _, _, _)
}
FunctionIR getInstructionEnclosingFunctionIR(Instruction instruction) {
instruction = MkInstruction(result, _, _, _, _, _)
}
import Cached
cached private module Cached {
@@ -34,25 +14,6 @@ cached private module Cached {
result.getFirstInstruction() = getNewInstruction(oldBlock.getFirstInstruction())
}
cached newtype TInstructionTag =
WrappedInstructionTag(OldInstruction oldInstruction) {
not oldInstruction instanceof OldIR::PhiInstruction
} or
PhiTag(Alias::VirtualVariable vvar, OldBlock block) {
hasPhiNode(vvar, block)
} or
ChiTag(OldInstruction oldInstruction) {
not oldInstruction instanceof OldIR::PhiInstruction and
hasChiNode(_, oldInstruction)
} or
UnreachedTag()
cached class InstructionTagType extends TInstructionTag {
cached final string toString() {
result = "Tag"
}
}
cached predicate functionHasIR(Function func) {
exists(OldIR::FunctionIR funcIR |
funcIR.getFunction() = func
@@ -60,7 +21,7 @@ cached private module Cached {
}
cached OldInstruction getOldInstruction(Instruction instr) {
instr.getTag() = WrappedInstructionTag(result)
instr = WrappedInstruction(result)
}
private Instruction getNewInstruction(OldInstruction instr) {
@@ -72,24 +33,12 @@ cached private module Cached {
* corresponding to `instr` if there is no `Chi` node.
*/
private Instruction getNewFinalInstruction(OldInstruction instr) {
result = getChiInstruction(instr)
result = Chi(instr)
or
not exists(getChiInstruction(instr)) and
not exists(Chi(instr)) and
result = getNewInstruction(instr)
}
private PhiInstruction getPhiInstruction(Function func, OldBlock oldBlock,
Alias::VirtualVariable vvar) {
result.getFunction() = func and
result.getAST() = oldBlock.getFirstInstruction().getAST() and
result.getTag() = PhiTag(vvar, oldBlock)
}
private ChiInstruction getChiInstruction (OldInstruction instr) {
hasChiNode(_, instr) and
result.getTag() = ChiTag(instr)
}
private IRVariable getNewIRVariable(OldIR::IRVariable var) {
result.getFunction() = var.getFunction() and
(
@@ -108,54 +57,23 @@ cached private module Cached {
}
cached newtype TInstruction =
MkInstruction(FunctionIR funcIR, Opcode opcode, Locatable ast,
InstructionTag tag, Type resultType, boolean isGLValue) {
hasInstruction(funcIR.getFunction(), opcode, ast, tag,
resultType, isGLValue)
WrappedInstruction(OldInstruction oldInstruction) {
not oldInstruction instanceof OldIR::PhiInstruction
} or
Phi(OldBlock block, Alias::VirtualVariable vvar) {
hasPhiNode(vvar, block)
} or
Chi(OldInstruction oldInstruction) {
not oldInstruction instanceof OldIR::PhiInstruction and
hasChiNode(_, oldInstruction)
} or
Unreached(Function function) {
exists(OldInstruction oldInstruction |
function = oldInstruction.getFunction() and
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
)
}
private predicate hasInstruction(Function func, Opcode opcode, Locatable ast,
InstructionTag tag, Type resultType, boolean isGLValue) {
exists(OldInstruction instr |
instr.getFunction() = func and
instr.getOpcode() = opcode and
instr.getAST() = ast and
WrappedInstructionTag(instr) = tag and
instr.getResultType() = resultType and
if instr.isGLValue() then
isGLValue = true
else
isGLValue = false
) or
exists(OldBlock block, Alias::VirtualVariable vvar |
hasPhiNode(vvar, block) and
block.getFunction() = func and
opcode instanceof Opcode::Phi and
ast = block.getFirstInstruction().getAST() and
tag = PhiTag(vvar, block) and
resultType = vvar.getType() and
isGLValue = false
) or
exists(OldInstruction instr, Alias::VirtualVariable vvar |
hasChiNode(vvar, instr) and
instr.getFunction() = func and
opcode instanceof Opcode::Chi and
ast = instr.getAST() and
tag = ChiTag(instr) and
resultType = vvar.getType() and
isGLValue = false
) or
exists(OldInstruction oldInstruction |
func = oldInstruction.getFunction() and
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _) and
tag = UnreachedTag() and
opcode instanceof Opcode::Unreached and
ast = func and
resultType instanceof VoidType and
isGLValue = false
)
}
cached predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag,
Type type) {
exists(OldIR::IRTempVariable var |
@@ -189,7 +107,7 @@ cached private module Cached {
if defIndex >= 0 then
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
else
result = getPhiInstruction(instruction.getFunction(), defBlock, vvar)
result = Phi(defBlock, vvar)
)
)
else (
@@ -209,7 +127,7 @@ cached private module Cached {
else
result = getNewInstruction(oldOperand.getDefinitionInstruction())
) or
instruction.getTag() = ChiTag(getOldInstruction(result)) and
instruction = Chi(getOldInstruction(result)) and
tag instanceof ChiPartialOperandTag
or
exists(FunctionIR f |
@@ -228,21 +146,21 @@ cached private module Cached {
OldBlock defBlock, int defRank, int defIndex, OldBlock predBlock |
hasPhiNode(vvar, phiBlock) and
predBlock = phiBlock.getAFeasiblePredecessor() and
instr.getTag() = PhiTag(vvar, phiBlock) and
instr = Phi(phiBlock, vvar) and
newPredecessorBlock = getNewBlock(predBlock) and
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
definitionReachesEndOfBlock(vvar, defBlock, defRank, predBlock) and
if defIndex >= 0 then
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
else
result = getPhiInstruction(instr.getFunction(), defBlock, vvar)
result = Phi(defBlock, vvar)
)
}
cached Instruction getChiInstructionTotalOperand(ChiInstruction chiInstr) {
exists(Alias::VirtualVariable vvar, OldInstruction oldInstr, OldBlock defBlock,
int defRank, int defIndex, OldBlock useBlock, int useRank |
ChiTag(oldInstr) = chiInstr.getTag() and
chiInstr = Chi(oldInstr) and
vvar = Alias::getResultMemoryAccess(oldInstr).getVirtualVariable() and
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
hasUseAtRank(vvar, useBlock, useRank, oldInstr) and
@@ -250,13 +168,13 @@ cached private module Cached {
if defIndex >= 0 then
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
else
result = getPhiInstruction(chiInstr.getFunction(), defBlock, vvar)
result = Phi(defBlock, vvar)
)
}
cached Instruction getPhiInstructionBlockStart(PhiInstruction instr) {
exists(OldBlock oldBlock |
instr.getTag() = PhiTag(_, oldBlock) and
instr = Phi(oldBlock, _) and
result = getNewInstruction(oldBlock.getFirstInstruction())
)
}
@@ -277,15 +195,14 @@ cached private module Cached {
cached Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {
if(hasChiNode(_, getOldInstruction(instruction)))
then
result = getChiInstruction(getOldInstruction(instruction)) and
result = Chi(getOldInstruction(instruction)) and
kind instanceof GotoEdge
else (
exists(OldInstruction oldInstruction |
oldInstruction = getOldInstruction(instruction) and
(
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind) then (
result.getTag() = UnreachedTag() and
result.getFunction() = instruction.getFunction()
result = Unreached(instruction.getFunction())
)
else (
result = getNewInstruction(oldInstruction.getSuccessor(kind))
@@ -293,7 +210,7 @@ cached private module Cached {
)
) or
exists(OldInstruction oldInstruction |
instruction = getChiInstruction(oldInstruction) and
instruction = Chi(oldInstruction) and
result = getNewInstruction(oldInstruction.getSuccessor(kind))
)
)
@@ -311,11 +228,88 @@ cached private module Cached {
// `oldInstruction`, in which case the back edge should come out of the
// chi node instead.
if hasChiNode(_, oldInstruction)
then instruction = getChiInstruction(oldInstruction)
then instruction = Chi(oldInstruction)
else instruction = getNewInstruction(oldInstruction)
)
}
cached Locatable getInstructionAST(Instruction instruction) {
exists(OldInstruction oldInstruction |
instruction = WrappedInstruction(oldInstruction)
or
instruction = Chi(oldInstruction)
|
result = oldInstruction.getAST()
)
or
exists(OldBlock block |
instruction = Phi(block, _) and
result = block.getFirstInstruction().getAST()
)
or
instruction = Unreached(result)
}
cached predicate instructionHasType(Instruction instruction, Type type, boolean isGLValue) {
exists(OldInstruction oldInstruction |
instruction = WrappedInstruction(oldInstruction) and
type = oldInstruction.getResultType() and
if oldInstruction.isGLValue()
then isGLValue = true
else isGLValue = false
)
or
exists(OldInstruction oldInstruction, Alias::VirtualVariable vvar |
instruction = Chi(oldInstruction) and
hasChiNode(vvar, oldInstruction) and
type = vvar.getType() and
isGLValue = false
)
or
exists(Alias::VirtualVariable vvar |
instruction = Phi(_, vvar) and
type = vvar.getType() and
isGLValue = false
)
or
instruction = Unreached(_) and
type instanceof VoidType and
isGLValue = false
}
cached Opcode getInstructionOpcode(Instruction instruction) {
exists(OldInstruction oldInstruction |
instruction = WrappedInstruction(oldInstruction) and
result = oldInstruction.getOpcode()
)
or
instruction instanceof Chi and
result instanceof Opcode::Chi
or
instruction instanceof Phi and
result instanceof Opcode::Phi
or
instruction instanceof Unreached and
result instanceof Opcode::Unreached
}
cached FunctionIR getInstructionEnclosingFunctionIR(Instruction instruction) {
exists(OldInstruction oldInstruction |
instruction = WrappedInstruction(oldInstruction)
or
instruction = Chi(oldInstruction)
|
result.getFunction() = oldInstruction.getFunction()
)
or
exists(OldBlock block |
instruction = Phi(block, _) and
result.getFunction() = block.getFunction()
)
or
instruction = Unreached(result.getFunction())
}
cached IRVariable getInstructionVariable(Instruction instruction) {
result = getNewIRVariable(getOldInstruction(instruction).(OldIR::VariableInstruction).getVariable())
}
@@ -366,7 +360,7 @@ cached private module Cached {
)
or
exists(OldIR::Instruction oldInstruction |
instruction.getTag() = ChiTag(oldInstruction) and
instruction = Chi(oldInstruction) and
result = getNewInstruction(oldInstruction)
)
}
@@ -555,11 +549,11 @@ cached private module CachedForDebugging {
result = "NonSSA: " + oldInstr.getUniqueId()
) or
exists(Alias::VirtualVariable vvar, OldBlock phiBlock |
instr.getTag() = PhiTag(vvar, phiBlock) and
instr = Phi(phiBlock, vvar) and
result = "Phi Block(" + phiBlock.getUniqueId() + "): " + vvar.getUniqueId()
) or
(
instr.getTag() = UnreachedTag() and
instr = Unreached(_) and
result = "Unreached"
)
}

View File

@@ -10,8 +10,6 @@ import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
class InstructionTag = Construction::InstructionTagType;
module InstructionSanity {
/**
* Holds if the instruction `instr` should be expected to have an operand
@@ -463,10 +461,6 @@ class Instruction extends Construction::TInstruction {
result = Construction::getInstructionOpcode(this)
}
final InstructionTag getTag() {
result = Construction::getInstructionTag(this)
}
/**
* Gets all direct uses of the result of this instruction.
*/

View File

@@ -8,12 +8,6 @@ private import TranslatedExpr
private import TranslatedStmt
private import TranslatedFunction
class InstructionTagType extends TInstructionTag {
final string toString() {
result = "Tag"
}
}
TranslatedElement getInstructionTranslatedElement(Instruction instruction) {
instruction = MkInstruction(result, _)
}
@@ -67,7 +61,7 @@ cached private module Cached {
cached Instruction getInstructionOperandDefinition(Instruction instruction, OperandTag tag) {
result = getInstructionTranslatedElement(instruction).getInstructionOperand(
instruction.getTag(), tag)
getInstructionTag(instruction), tag)
}
cached Instruction getPhiInstructionOperandDefinition(Instruction instruction,
@@ -81,7 +75,7 @@ cached private module Cached {
cached Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {
result = getInstructionTranslatedElement(instruction).getInstructionSuccessor(
instruction.getTag(), kind)
getInstructionTag(instruction), kind)
}
// This predicate has pragma[noopt] because otherwise the `getAChild*` calls
@@ -172,12 +166,12 @@ cached private module Cached {
cached predicate instructionHasType(Instruction instruction, Type type, boolean isGLValue) {
getInstructionTranslatedElement(instruction)
.hasInstruction(_, instruction.getTag(), type, isGLValue)
.hasInstruction(_, getInstructionTag(instruction), type, isGLValue)
}
cached Opcode getInstructionOpcode(Instruction instruction) {
getInstructionTranslatedElement(instruction)
.hasInstruction(result, instruction.getTag(), _, _)
.hasInstruction(result, getInstructionTag(instruction), _, _)
}
cached FunctionIR getInstructionEnclosingFunctionIR(Instruction instruction) {
@@ -186,7 +180,7 @@ cached private module Cached {
cached IRVariable getInstructionVariable(Instruction instruction) {
result = getInstructionTranslatedElement(instruction).getInstructionVariable(
instruction.getTag())
getInstructionTag(instruction))
}
cached Field getInstructionField(Instruction instruction) {
@@ -198,38 +192,38 @@ cached private module Cached {
cached Function getInstructionFunction(Instruction instruction) {
result = getInstructionTranslatedElement(instruction)
.getInstructionFunction(instruction.getTag())
.getInstructionFunction(getInstructionTag(instruction))
}
cached string getInstructionConstantValue(Instruction instruction) {
result =
getInstructionTranslatedElement(instruction).getInstructionConstantValue(
instruction.getTag())
getInstructionTag(instruction))
}
cached StringLiteral getInstructionStringLiteral(Instruction instruction) {
result =
getInstructionTranslatedElement(instruction).getInstructionStringLiteral(
instruction.getTag())
getInstructionTag(instruction))
}
cached Type getInstructionExceptionType(Instruction instruction) {
result =
getInstructionTranslatedElement(instruction).getInstructionExceptionType(
instruction.getTag())
getInstructionTag(instruction))
}
cached predicate getInstructionInheritance(Instruction instruction,
Class baseClass, Class derivedClass) {
getInstructionTranslatedElement(instruction).getInstructionInheritance(
instruction.getTag(), baseClass, derivedClass)
getInstructionTag(instruction), baseClass, derivedClass)
}
pragma[noinline]
private predicate instructionOrigin(Instruction instruction,
TranslatedElement element, InstructionTag tag) {
element = getInstructionTranslatedElement(instruction) and
tag = instruction.getTag()
tag = getInstructionTag(instruction)
}
cached int getInstructionElementSize(Instruction instruction) {
@@ -265,6 +259,6 @@ cached private module CachedForDebugging {
cached string getInstructionUniqueId(Instruction instruction) {
result = getInstructionTranslatedElement(instruction).getId() + ":" +
getInstructionTagId(instruction.getTag())
getInstructionTagId(getInstructionTag(instruction))
}
}

View File

@@ -86,6 +86,12 @@ newtype TInstructionTag =
elementIsInitialized(elementIndex)
}
class InstructionTag extends TInstructionTag {
final string toString() {
result = "Tag"
}
}
/**
* Gets a unique string for the instruction tag. Primarily used for generating
* instruction IDs to ensure stable IR dumps.

View File

@@ -10,8 +10,6 @@ import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
class InstructionTag = Construction::InstructionTagType;
module InstructionSanity {
/**
* Holds if the instruction `instr` should be expected to have an operand
@@ -463,10 +461,6 @@ class Instruction extends Construction::TInstruction {
result = Construction::getInstructionOpcode(this)
}
final InstructionTag getTag() {
result = Construction::getInstructionTag(this)
}
/**
* Gets all direct uses of the result of this instruction.
*/

View File

@@ -7,26 +7,6 @@ private import NewIR
private class OldBlock = Reachability::ReachableBlock;
private class OldInstruction = Reachability::ReachableInstruction;
InstructionTag getInstructionTag(Instruction instruction) {
instruction = MkInstruction(_, _, _, result, _, _)
}
Locatable getInstructionAST(Instruction instruction) {
instruction = MkInstruction(_, _, result, _, _, _)
}
predicate instructionHasType(Instruction instruction, Type type, boolean isGLValue) {
instruction = MkInstruction(_, _, _, _, type, isGLValue)
}
Opcode getInstructionOpcode(Instruction instruction) {
instruction = MkInstruction(_, result, _, _, _, _)
}
FunctionIR getInstructionEnclosingFunctionIR(Instruction instruction) {
instruction = MkInstruction(result, _, _, _, _, _)
}
import Cached
cached private module Cached {
@@ -34,25 +14,6 @@ cached private module Cached {
result.getFirstInstruction() = getNewInstruction(oldBlock.getFirstInstruction())
}
cached newtype TInstructionTag =
WrappedInstructionTag(OldInstruction oldInstruction) {
not oldInstruction instanceof OldIR::PhiInstruction
} or
PhiTag(Alias::VirtualVariable vvar, OldBlock block) {
hasPhiNode(vvar, block)
} or
ChiTag(OldInstruction oldInstruction) {
not oldInstruction instanceof OldIR::PhiInstruction and
hasChiNode(_, oldInstruction)
} or
UnreachedTag()
cached class InstructionTagType extends TInstructionTag {
cached final string toString() {
result = "Tag"
}
}
cached predicate functionHasIR(Function func) {
exists(OldIR::FunctionIR funcIR |
funcIR.getFunction() = func
@@ -60,7 +21,7 @@ cached private module Cached {
}
cached OldInstruction getOldInstruction(Instruction instr) {
instr.getTag() = WrappedInstructionTag(result)
instr = WrappedInstruction(result)
}
private Instruction getNewInstruction(OldInstruction instr) {
@@ -72,24 +33,12 @@ cached private module Cached {
* corresponding to `instr` if there is no `Chi` node.
*/
private Instruction getNewFinalInstruction(OldInstruction instr) {
result = getChiInstruction(instr)
result = Chi(instr)
or
not exists(getChiInstruction(instr)) and
not exists(Chi(instr)) and
result = getNewInstruction(instr)
}
private PhiInstruction getPhiInstruction(Function func, OldBlock oldBlock,
Alias::VirtualVariable vvar) {
result.getFunction() = func and
result.getAST() = oldBlock.getFirstInstruction().getAST() and
result.getTag() = PhiTag(vvar, oldBlock)
}
private ChiInstruction getChiInstruction (OldInstruction instr) {
hasChiNode(_, instr) and
result.getTag() = ChiTag(instr)
}
private IRVariable getNewIRVariable(OldIR::IRVariable var) {
result.getFunction() = var.getFunction() and
(
@@ -108,54 +57,23 @@ cached private module Cached {
}
cached newtype TInstruction =
MkInstruction(FunctionIR funcIR, Opcode opcode, Locatable ast,
InstructionTag tag, Type resultType, boolean isGLValue) {
hasInstruction(funcIR.getFunction(), opcode, ast, tag,
resultType, isGLValue)
WrappedInstruction(OldInstruction oldInstruction) {
not oldInstruction instanceof OldIR::PhiInstruction
} or
Phi(OldBlock block, Alias::VirtualVariable vvar) {
hasPhiNode(vvar, block)
} or
Chi(OldInstruction oldInstruction) {
not oldInstruction instanceof OldIR::PhiInstruction and
hasChiNode(_, oldInstruction)
} or
Unreached(Function function) {
exists(OldInstruction oldInstruction |
function = oldInstruction.getFunction() and
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
)
}
private predicate hasInstruction(Function func, Opcode opcode, Locatable ast,
InstructionTag tag, Type resultType, boolean isGLValue) {
exists(OldInstruction instr |
instr.getFunction() = func and
instr.getOpcode() = opcode and
instr.getAST() = ast and
WrappedInstructionTag(instr) = tag and
instr.getResultType() = resultType and
if instr.isGLValue() then
isGLValue = true
else
isGLValue = false
) or
exists(OldBlock block, Alias::VirtualVariable vvar |
hasPhiNode(vvar, block) and
block.getFunction() = func and
opcode instanceof Opcode::Phi and
ast = block.getFirstInstruction().getAST() and
tag = PhiTag(vvar, block) and
resultType = vvar.getType() and
isGLValue = false
) or
exists(OldInstruction instr, Alias::VirtualVariable vvar |
hasChiNode(vvar, instr) and
instr.getFunction() = func and
opcode instanceof Opcode::Chi and
ast = instr.getAST() and
tag = ChiTag(instr) and
resultType = vvar.getType() and
isGLValue = false
) or
exists(OldInstruction oldInstruction |
func = oldInstruction.getFunction() and
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _) and
tag = UnreachedTag() and
opcode instanceof Opcode::Unreached and
ast = func and
resultType instanceof VoidType and
isGLValue = false
)
}
cached predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag,
Type type) {
exists(OldIR::IRTempVariable var |
@@ -189,7 +107,7 @@ cached private module Cached {
if defIndex >= 0 then
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
else
result = getPhiInstruction(instruction.getFunction(), defBlock, vvar)
result = Phi(defBlock, vvar)
)
)
else (
@@ -209,7 +127,7 @@ cached private module Cached {
else
result = getNewInstruction(oldOperand.getDefinitionInstruction())
) or
instruction.getTag() = ChiTag(getOldInstruction(result)) and
instruction = Chi(getOldInstruction(result)) and
tag instanceof ChiPartialOperandTag
or
exists(FunctionIR f |
@@ -228,21 +146,21 @@ cached private module Cached {
OldBlock defBlock, int defRank, int defIndex, OldBlock predBlock |
hasPhiNode(vvar, phiBlock) and
predBlock = phiBlock.getAFeasiblePredecessor() and
instr.getTag() = PhiTag(vvar, phiBlock) and
instr = Phi(phiBlock, vvar) and
newPredecessorBlock = getNewBlock(predBlock) and
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
definitionReachesEndOfBlock(vvar, defBlock, defRank, predBlock) and
if defIndex >= 0 then
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
else
result = getPhiInstruction(instr.getFunction(), defBlock, vvar)
result = Phi(defBlock, vvar)
)
}
cached Instruction getChiInstructionTotalOperand(ChiInstruction chiInstr) {
exists(Alias::VirtualVariable vvar, OldInstruction oldInstr, OldBlock defBlock,
int defRank, int defIndex, OldBlock useBlock, int useRank |
ChiTag(oldInstr) = chiInstr.getTag() and
chiInstr = Chi(oldInstr) and
vvar = Alias::getResultMemoryAccess(oldInstr).getVirtualVariable() and
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
hasUseAtRank(vvar, useBlock, useRank, oldInstr) and
@@ -250,13 +168,13 @@ cached private module Cached {
if defIndex >= 0 then
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
else
result = getPhiInstruction(chiInstr.getFunction(), defBlock, vvar)
result = Phi(defBlock, vvar)
)
}
cached Instruction getPhiInstructionBlockStart(PhiInstruction instr) {
exists(OldBlock oldBlock |
instr.getTag() = PhiTag(_, oldBlock) and
instr = Phi(oldBlock, _) and
result = getNewInstruction(oldBlock.getFirstInstruction())
)
}
@@ -277,15 +195,14 @@ cached private module Cached {
cached Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {
if(hasChiNode(_, getOldInstruction(instruction)))
then
result = getChiInstruction(getOldInstruction(instruction)) and
result = Chi(getOldInstruction(instruction)) and
kind instanceof GotoEdge
else (
exists(OldInstruction oldInstruction |
oldInstruction = getOldInstruction(instruction) and
(
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind) then (
result.getTag() = UnreachedTag() and
result.getFunction() = instruction.getFunction()
result = Unreached(instruction.getFunction())
)
else (
result = getNewInstruction(oldInstruction.getSuccessor(kind))
@@ -293,7 +210,7 @@ cached private module Cached {
)
) or
exists(OldInstruction oldInstruction |
instruction = getChiInstruction(oldInstruction) and
instruction = Chi(oldInstruction) and
result = getNewInstruction(oldInstruction.getSuccessor(kind))
)
)
@@ -311,11 +228,88 @@ cached private module Cached {
// `oldInstruction`, in which case the back edge should come out of the
// chi node instead.
if hasChiNode(_, oldInstruction)
then instruction = getChiInstruction(oldInstruction)
then instruction = Chi(oldInstruction)
else instruction = getNewInstruction(oldInstruction)
)
}
cached Locatable getInstructionAST(Instruction instruction) {
exists(OldInstruction oldInstruction |
instruction = WrappedInstruction(oldInstruction)
or
instruction = Chi(oldInstruction)
|
result = oldInstruction.getAST()
)
or
exists(OldBlock block |
instruction = Phi(block, _) and
result = block.getFirstInstruction().getAST()
)
or
instruction = Unreached(result)
}
cached predicate instructionHasType(Instruction instruction, Type type, boolean isGLValue) {
exists(OldInstruction oldInstruction |
instruction = WrappedInstruction(oldInstruction) and
type = oldInstruction.getResultType() and
if oldInstruction.isGLValue()
then isGLValue = true
else isGLValue = false
)
or
exists(OldInstruction oldInstruction, Alias::VirtualVariable vvar |
instruction = Chi(oldInstruction) and
hasChiNode(vvar, oldInstruction) and
type = vvar.getType() and
isGLValue = false
)
or
exists(Alias::VirtualVariable vvar |
instruction = Phi(_, vvar) and
type = vvar.getType() and
isGLValue = false
)
or
instruction = Unreached(_) and
type instanceof VoidType and
isGLValue = false
}
cached Opcode getInstructionOpcode(Instruction instruction) {
exists(OldInstruction oldInstruction |
instruction = WrappedInstruction(oldInstruction) and
result = oldInstruction.getOpcode()
)
or
instruction instanceof Chi and
result instanceof Opcode::Chi
or
instruction instanceof Phi and
result instanceof Opcode::Phi
or
instruction instanceof Unreached and
result instanceof Opcode::Unreached
}
cached FunctionIR getInstructionEnclosingFunctionIR(Instruction instruction) {
exists(OldInstruction oldInstruction |
instruction = WrappedInstruction(oldInstruction)
or
instruction = Chi(oldInstruction)
|
result.getFunction() = oldInstruction.getFunction()
)
or
exists(OldBlock block |
instruction = Phi(block, _) and
result.getFunction() = block.getFunction()
)
or
instruction = Unreached(result.getFunction())
}
cached IRVariable getInstructionVariable(Instruction instruction) {
result = getNewIRVariable(getOldInstruction(instruction).(OldIR::VariableInstruction).getVariable())
}
@@ -366,7 +360,7 @@ cached private module Cached {
)
or
exists(OldIR::Instruction oldInstruction |
instruction.getTag() = ChiTag(oldInstruction) and
instruction = Chi(oldInstruction) and
result = getNewInstruction(oldInstruction)
)
}
@@ -555,11 +549,11 @@ cached private module CachedForDebugging {
result = "NonSSA: " + oldInstr.getUniqueId()
) or
exists(Alias::VirtualVariable vvar, OldBlock phiBlock |
instr.getTag() = PhiTag(vvar, phiBlock) and
instr = Phi(phiBlock, vvar) and
result = "Phi Block(" + phiBlock.getUniqueId() + "): " + vvar.getUniqueId()
) or
(
instr.getTag() = UnreachedTag() and
instr = Unreached(_) and
result = "Unreached"
)
}