mirror of
https://github.com/github/codeql.git
synced 2026-04-26 17:25:19 +02:00
Merge pull request #866 from jbj/ir-TInstruction-normalize
C++: Normalize TInstruction
This commit is contained in:
@@ -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
|
||||
@@ -211,17 +209,6 @@ module InstructionSanity {
|
||||
* Represents a single operation in the IR.
|
||||
*/
|
||||
class Instruction extends Construction::TInstruction {
|
||||
Opcode opcode;
|
||||
Locatable ast;
|
||||
InstructionTag instructionTag;
|
||||
Type resultType;
|
||||
FunctionIR funcIR;
|
||||
boolean glvalue;
|
||||
|
||||
Instruction() {
|
||||
this = Construction::MkInstruction(funcIR, opcode, ast, instructionTag, resultType, glvalue)
|
||||
}
|
||||
|
||||
final string toString() {
|
||||
result = getOpcode().toString() + ": " + getAST().toString()
|
||||
}
|
||||
@@ -244,9 +231,9 @@ class Instruction extends Construction::TInstruction {
|
||||
*/
|
||||
final string getOperationString() {
|
||||
if exists(getImmediateString()) then
|
||||
result = getOperationPrefix() + opcode.toString() + "[" + getImmediateString() + "]"
|
||||
result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
|
||||
else
|
||||
result = getOperationPrefix() + opcode.toString()
|
||||
result = getOperationPrefix() + getOpcode().toString()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,7 +251,7 @@ class Instruction extends Construction::TInstruction {
|
||||
}
|
||||
|
||||
private string getResultPrefix() {
|
||||
if resultType instanceof VoidType then
|
||||
if getResultType() instanceof VoidType then
|
||||
result = "v"
|
||||
else if hasMemoryResult() then
|
||||
if isResultModeled() then
|
||||
@@ -309,8 +296,8 @@ class Instruction extends Construction::TInstruction {
|
||||
|
||||
private string getResultTypeString() {
|
||||
exists(string valcat |
|
||||
valcat = getValueCategoryString(resultType.toString()) and
|
||||
if (resultType instanceof UnknownType and
|
||||
valcat = getValueCategoryString(getResultType().toString()) and
|
||||
if (getResultType() instanceof UnknownType and
|
||||
not isGLValue() and
|
||||
exists(getResultSize())) then (
|
||||
result = valcat + "[" + getResultSize().toString() + "]"
|
||||
@@ -378,28 +365,28 @@ class Instruction extends Construction::TInstruction {
|
||||
* Gets the function that contains this instruction.
|
||||
*/
|
||||
final Function getFunction() {
|
||||
result = funcIR.getFunction()
|
||||
result = getFunctionIR().getFunction()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the FunctionIR object that contains the IR for this instruction.
|
||||
*/
|
||||
final FunctionIR getFunctionIR() {
|
||||
result = funcIR
|
||||
result = Construction::getInstructionEnclosingFunctionIR(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the AST that caused this instruction to be generated.
|
||||
*/
|
||||
final Locatable getAST() {
|
||||
result = ast
|
||||
result = Construction::getInstructionAST(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location of the source code for this instruction.
|
||||
*/
|
||||
final Location getLocation() {
|
||||
result = ast.getLocation()
|
||||
result = getAST().getLocation()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -421,7 +408,7 @@ class Instruction extends Construction::TInstruction {
|
||||
* instruction does not produce a result, its result type will be `VoidType`.
|
||||
*/
|
||||
final Type getResultType() {
|
||||
result = resultType
|
||||
Construction::instructionHasType(this, result, _)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -443,7 +430,7 @@ class Instruction extends Construction::TInstruction {
|
||||
* the integer value loaded from variable `x`.
|
||||
*/
|
||||
final predicate isGLValue() {
|
||||
glvalue = true
|
||||
Construction::instructionHasType(this, _, true)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -460,10 +447,10 @@ class Instruction extends Construction::TInstruction {
|
||||
result = nullptr.getSize()
|
||||
)
|
||||
)
|
||||
else if resultType instanceof UnknownType then
|
||||
else if getResultType() instanceof UnknownType then
|
||||
result = Construction::getInstructionResultSize(this)
|
||||
else (
|
||||
result = resultType.getSize()
|
||||
result = getResultType().getSize()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -471,11 +458,7 @@ class Instruction extends Construction::TInstruction {
|
||||
* Gets the opcode that specifies the operation performed by this instruction.
|
||||
*/
|
||||
final Opcode getOpcode() {
|
||||
result = opcode
|
||||
}
|
||||
|
||||
final InstructionTag getTag() {
|
||||
result = instructionTag
|
||||
result = Construction::getInstructionOpcode(this)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -644,19 +627,19 @@ class ConstantValueInstruction extends Instruction {
|
||||
|
||||
class EnterFunctionInstruction extends Instruction {
|
||||
EnterFunctionInstruction() {
|
||||
opcode instanceof Opcode::EnterFunction
|
||||
getOpcode() instanceof Opcode::EnterFunction
|
||||
}
|
||||
}
|
||||
|
||||
class VariableAddressInstruction extends VariableInstruction {
|
||||
VariableAddressInstruction() {
|
||||
opcode instanceof Opcode::VariableAddress
|
||||
getOpcode() instanceof Opcode::VariableAddress
|
||||
}
|
||||
}
|
||||
|
||||
class InitializeParameterInstruction extends VariableInstruction {
|
||||
InitializeParameterInstruction() {
|
||||
opcode instanceof Opcode::InitializeParameter
|
||||
getOpcode() instanceof Opcode::InitializeParameter
|
||||
}
|
||||
|
||||
final Parameter getParameter() {
|
||||
@@ -673,13 +656,13 @@ class InitializeParameterInstruction extends VariableInstruction {
|
||||
*/
|
||||
class InitializeThisInstruction extends Instruction {
|
||||
InitializeThisInstruction() {
|
||||
opcode instanceof Opcode::InitializeThis
|
||||
getOpcode() instanceof Opcode::InitializeThis
|
||||
}
|
||||
}
|
||||
|
||||
class FieldAddressInstruction extends FieldInstruction {
|
||||
FieldAddressInstruction() {
|
||||
opcode instanceof Opcode::FieldAddress
|
||||
getOpcode() instanceof Opcode::FieldAddress
|
||||
}
|
||||
|
||||
final Instruction getObjectAddress() {
|
||||
@@ -689,7 +672,7 @@ class FieldAddressInstruction extends FieldInstruction {
|
||||
|
||||
class UninitializedInstruction extends VariableInstruction {
|
||||
UninitializedInstruction() {
|
||||
opcode instanceof Opcode::Uninitialized
|
||||
getOpcode() instanceof Opcode::Uninitialized
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -706,25 +689,25 @@ class UninitializedInstruction extends VariableInstruction {
|
||||
|
||||
class NoOpInstruction extends Instruction {
|
||||
NoOpInstruction() {
|
||||
opcode instanceof Opcode::NoOp
|
||||
getOpcode() instanceof Opcode::NoOp
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnInstruction extends Instruction {
|
||||
ReturnInstruction() {
|
||||
opcode instanceof ReturnOpcode
|
||||
getOpcode() instanceof ReturnOpcode
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnVoidInstruction extends ReturnInstruction {
|
||||
ReturnVoidInstruction() {
|
||||
opcode instanceof Opcode::ReturnVoid
|
||||
getOpcode() instanceof Opcode::ReturnVoid
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnValueInstruction extends ReturnInstruction {
|
||||
ReturnValueInstruction() {
|
||||
opcode instanceof Opcode::ReturnValue
|
||||
getOpcode() instanceof Opcode::ReturnValue
|
||||
}
|
||||
|
||||
final Instruction getReturnValue() {
|
||||
@@ -734,7 +717,7 @@ class ReturnValueInstruction extends ReturnInstruction {
|
||||
|
||||
class CopyInstruction extends Instruction {
|
||||
CopyInstruction() {
|
||||
opcode instanceof CopyOpcode
|
||||
getOpcode() instanceof CopyOpcode
|
||||
}
|
||||
|
||||
final Instruction getSourceValue() {
|
||||
@@ -744,13 +727,13 @@ class CopyInstruction extends Instruction {
|
||||
|
||||
class CopyValueInstruction extends CopyInstruction {
|
||||
CopyValueInstruction() {
|
||||
opcode instanceof Opcode::CopyValue
|
||||
getOpcode() instanceof Opcode::CopyValue
|
||||
}
|
||||
}
|
||||
|
||||
class LoadInstruction extends CopyInstruction {
|
||||
LoadInstruction() {
|
||||
opcode instanceof Opcode::Load
|
||||
getOpcode() instanceof Opcode::Load
|
||||
}
|
||||
|
||||
final Instruction getSourceAddress() {
|
||||
@@ -760,7 +743,7 @@ class LoadInstruction extends CopyInstruction {
|
||||
|
||||
class StoreInstruction extends CopyInstruction {
|
||||
StoreInstruction() {
|
||||
opcode instanceof Opcode::Store
|
||||
getOpcode() instanceof Opcode::Store
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -774,7 +757,7 @@ class StoreInstruction extends CopyInstruction {
|
||||
|
||||
class ConditionalBranchInstruction extends Instruction {
|
||||
ConditionalBranchInstruction() {
|
||||
opcode instanceof Opcode::ConditionalBranch
|
||||
getOpcode() instanceof Opcode::ConditionalBranch
|
||||
}
|
||||
|
||||
final Instruction getCondition() {
|
||||
@@ -792,25 +775,25 @@ class ConditionalBranchInstruction extends Instruction {
|
||||
|
||||
class ExitFunctionInstruction extends Instruction {
|
||||
ExitFunctionInstruction() {
|
||||
opcode instanceof Opcode::ExitFunction
|
||||
getOpcode() instanceof Opcode::ExitFunction
|
||||
}
|
||||
}
|
||||
|
||||
class ConstantInstruction extends ConstantValueInstruction {
|
||||
ConstantInstruction() {
|
||||
opcode instanceof Opcode::Constant
|
||||
getOpcode() instanceof Opcode::Constant
|
||||
}
|
||||
}
|
||||
|
||||
class IntegerConstantInstruction extends ConstantInstruction {
|
||||
IntegerConstantInstruction() {
|
||||
resultType instanceof IntegralType
|
||||
getResultType() instanceof IntegralType
|
||||
}
|
||||
}
|
||||
|
||||
class FloatConstantInstruction extends ConstantInstruction {
|
||||
FloatConstantInstruction() {
|
||||
resultType instanceof FloatingPointType
|
||||
getResultType() instanceof FloatingPointType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,7 +815,7 @@ class StringConstantInstruction extends Instruction {
|
||||
|
||||
class BinaryInstruction extends Instruction {
|
||||
BinaryInstruction() {
|
||||
opcode instanceof BinaryOpcode
|
||||
getOpcode() instanceof BinaryOpcode
|
||||
}
|
||||
|
||||
final Instruction getLeftOperand() {
|
||||
@@ -855,67 +838,67 @@ class BinaryInstruction extends Instruction {
|
||||
|
||||
class AddInstruction extends BinaryInstruction {
|
||||
AddInstruction() {
|
||||
opcode instanceof Opcode::Add
|
||||
getOpcode() instanceof Opcode::Add
|
||||
}
|
||||
}
|
||||
|
||||
class SubInstruction extends BinaryInstruction {
|
||||
SubInstruction() {
|
||||
opcode instanceof Opcode::Sub
|
||||
getOpcode() instanceof Opcode::Sub
|
||||
}
|
||||
}
|
||||
|
||||
class MulInstruction extends BinaryInstruction {
|
||||
MulInstruction() {
|
||||
opcode instanceof Opcode::Mul
|
||||
getOpcode() instanceof Opcode::Mul
|
||||
}
|
||||
}
|
||||
|
||||
class DivInstruction extends BinaryInstruction {
|
||||
DivInstruction() {
|
||||
opcode instanceof Opcode::Div
|
||||
getOpcode() instanceof Opcode::Div
|
||||
}
|
||||
}
|
||||
|
||||
class RemInstruction extends BinaryInstruction {
|
||||
RemInstruction() {
|
||||
opcode instanceof Opcode::Rem
|
||||
getOpcode() instanceof Opcode::Rem
|
||||
}
|
||||
}
|
||||
|
||||
class NegateInstruction extends UnaryInstruction {
|
||||
NegateInstruction() {
|
||||
opcode instanceof Opcode::Negate
|
||||
getOpcode() instanceof Opcode::Negate
|
||||
}
|
||||
}
|
||||
|
||||
class BitAndInstruction extends BinaryInstruction {
|
||||
BitAndInstruction() {
|
||||
opcode instanceof Opcode::BitAnd
|
||||
getOpcode() instanceof Opcode::BitAnd
|
||||
}
|
||||
}
|
||||
|
||||
class BitOrInstruction extends BinaryInstruction {
|
||||
BitOrInstruction() {
|
||||
opcode instanceof Opcode::BitOr
|
||||
getOpcode() instanceof Opcode::BitOr
|
||||
}
|
||||
}
|
||||
|
||||
class BitXorInstruction extends BinaryInstruction {
|
||||
BitXorInstruction() {
|
||||
opcode instanceof Opcode::BitXor
|
||||
getOpcode() instanceof Opcode::BitXor
|
||||
}
|
||||
}
|
||||
|
||||
class ShiftLeftInstruction extends BinaryInstruction {
|
||||
ShiftLeftInstruction() {
|
||||
opcode instanceof Opcode::ShiftLeft
|
||||
getOpcode() instanceof Opcode::ShiftLeft
|
||||
}
|
||||
}
|
||||
|
||||
class ShiftRightInstruction extends BinaryInstruction {
|
||||
ShiftRightInstruction() {
|
||||
opcode instanceof Opcode::ShiftRight
|
||||
getOpcode() instanceof Opcode::ShiftRight
|
||||
}
|
||||
}
|
||||
|
||||
@@ -923,7 +906,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
|
||||
int elementSize;
|
||||
|
||||
PointerArithmeticInstruction() {
|
||||
opcode instanceof PointerArithmeticOpcode and
|
||||
getOpcode() instanceof PointerArithmeticOpcode and
|
||||
elementSize = Construction::getInstructionElementSize(this)
|
||||
}
|
||||
|
||||
@@ -938,31 +921,31 @@ class PointerArithmeticInstruction extends BinaryInstruction {
|
||||
|
||||
class PointerOffsetInstruction extends PointerArithmeticInstruction {
|
||||
PointerOffsetInstruction() {
|
||||
opcode instanceof PointerOffsetOpcode
|
||||
getOpcode() instanceof PointerOffsetOpcode
|
||||
}
|
||||
}
|
||||
|
||||
class PointerAddInstruction extends PointerOffsetInstruction {
|
||||
PointerAddInstruction() {
|
||||
opcode instanceof Opcode::PointerAdd
|
||||
getOpcode() instanceof Opcode::PointerAdd
|
||||
}
|
||||
}
|
||||
|
||||
class PointerSubInstruction extends PointerOffsetInstruction {
|
||||
PointerSubInstruction() {
|
||||
opcode instanceof Opcode::PointerSub
|
||||
getOpcode() instanceof Opcode::PointerSub
|
||||
}
|
||||
}
|
||||
|
||||
class PointerDiffInstruction extends PointerArithmeticInstruction {
|
||||
PointerDiffInstruction() {
|
||||
opcode instanceof Opcode::PointerDiff
|
||||
getOpcode() instanceof Opcode::PointerDiff
|
||||
}
|
||||
}
|
||||
|
||||
class UnaryInstruction extends Instruction {
|
||||
UnaryInstruction() {
|
||||
opcode instanceof UnaryOpcode
|
||||
getOpcode() instanceof UnaryOpcode
|
||||
}
|
||||
|
||||
final Instruction getOperand() {
|
||||
@@ -972,7 +955,7 @@ class UnaryInstruction extends Instruction {
|
||||
|
||||
class ConvertInstruction extends UnaryInstruction {
|
||||
ConvertInstruction() {
|
||||
opcode instanceof Opcode::Convert
|
||||
getOpcode() instanceof Opcode::Convert
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1024,7 +1007,7 @@ class InheritanceConversionInstruction extends UnaryInstruction {
|
||||
*/
|
||||
class ConvertToBaseInstruction extends InheritanceConversionInstruction {
|
||||
ConvertToBaseInstruction() {
|
||||
opcode instanceof Opcode::ConvertToBase
|
||||
getOpcode() instanceof Opcode::ConvertToBase
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1034,7 +1017,7 @@ class ConvertToBaseInstruction extends InheritanceConversionInstruction {
|
||||
*/
|
||||
class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction {
|
||||
ConvertToVirtualBaseInstruction() {
|
||||
opcode instanceof Opcode::ConvertToVirtualBase
|
||||
getOpcode() instanceof Opcode::ConvertToVirtualBase
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1044,37 +1027,37 @@ class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction {
|
||||
*/
|
||||
class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
|
||||
ConvertToDerivedInstruction() {
|
||||
opcode instanceof Opcode::ConvertToDerived
|
||||
getOpcode() instanceof Opcode::ConvertToDerived
|
||||
}
|
||||
}
|
||||
|
||||
class BitComplementInstruction extends UnaryInstruction {
|
||||
BitComplementInstruction() {
|
||||
opcode instanceof Opcode::BitComplement
|
||||
getOpcode() instanceof Opcode::BitComplement
|
||||
}
|
||||
}
|
||||
|
||||
class LogicalNotInstruction extends UnaryInstruction {
|
||||
LogicalNotInstruction() {
|
||||
opcode instanceof Opcode::LogicalNot
|
||||
getOpcode() instanceof Opcode::LogicalNot
|
||||
}
|
||||
}
|
||||
|
||||
class CompareInstruction extends BinaryInstruction {
|
||||
CompareInstruction() {
|
||||
opcode instanceof CompareOpcode
|
||||
getOpcode() instanceof CompareOpcode
|
||||
}
|
||||
}
|
||||
|
||||
class CompareEQInstruction extends CompareInstruction {
|
||||
CompareEQInstruction() {
|
||||
opcode instanceof Opcode::CompareEQ
|
||||
getOpcode() instanceof Opcode::CompareEQ
|
||||
}
|
||||
}
|
||||
|
||||
class CompareNEInstruction extends CompareInstruction {
|
||||
CompareNEInstruction() {
|
||||
opcode instanceof Opcode::CompareNE
|
||||
getOpcode() instanceof Opcode::CompareNE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1083,7 +1066,7 @@ class CompareNEInstruction extends CompareInstruction {
|
||||
*/
|
||||
class RelationalInstruction extends CompareInstruction {
|
||||
RelationalInstruction() {
|
||||
opcode instanceof RelationalOpcode
|
||||
getOpcode() instanceof RelationalOpcode
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1116,7 +1099,7 @@ class RelationalInstruction extends CompareInstruction {
|
||||
|
||||
class CompareLTInstruction extends RelationalInstruction {
|
||||
CompareLTInstruction() {
|
||||
opcode instanceof Opcode::CompareLT
|
||||
getOpcode() instanceof Opcode::CompareLT
|
||||
}
|
||||
|
||||
override Instruction getLesserOperand() {
|
||||
@@ -1134,7 +1117,7 @@ class CompareLTInstruction extends RelationalInstruction {
|
||||
|
||||
class CompareGTInstruction extends RelationalInstruction {
|
||||
CompareGTInstruction() {
|
||||
opcode instanceof Opcode::CompareGT
|
||||
getOpcode() instanceof Opcode::CompareGT
|
||||
}
|
||||
|
||||
override Instruction getLesserOperand() {
|
||||
@@ -1152,7 +1135,7 @@ class CompareGTInstruction extends RelationalInstruction {
|
||||
|
||||
class CompareLEInstruction extends RelationalInstruction {
|
||||
CompareLEInstruction() {
|
||||
opcode instanceof Opcode::CompareLE
|
||||
getOpcode() instanceof Opcode::CompareLE
|
||||
}
|
||||
|
||||
override Instruction getLesserOperand() {
|
||||
@@ -1170,7 +1153,7 @@ class CompareLEInstruction extends RelationalInstruction {
|
||||
|
||||
class CompareGEInstruction extends RelationalInstruction {
|
||||
CompareGEInstruction() {
|
||||
opcode instanceof Opcode::CompareGE
|
||||
getOpcode() instanceof Opcode::CompareGE
|
||||
}
|
||||
|
||||
override Instruction getLesserOperand() {
|
||||
@@ -1188,7 +1171,7 @@ class CompareGEInstruction extends RelationalInstruction {
|
||||
|
||||
class SwitchInstruction extends Instruction {
|
||||
SwitchInstruction() {
|
||||
opcode instanceof Opcode::Switch
|
||||
getOpcode() instanceof Opcode::Switch
|
||||
}
|
||||
|
||||
final Instruction getExpression() {
|
||||
@@ -1211,7 +1194,7 @@ class SwitchInstruction extends Instruction {
|
||||
*/
|
||||
class CallInstruction extends Instruction {
|
||||
CallInstruction() {
|
||||
opcode instanceof Opcode::Call
|
||||
getOpcode() instanceof Opcode::Call
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1254,7 +1237,7 @@ class CallInstruction extends Instruction {
|
||||
*/
|
||||
class SideEffectInstruction extends Instruction {
|
||||
SideEffectInstruction() {
|
||||
opcode instanceof SideEffectOpcode
|
||||
getOpcode() instanceof SideEffectOpcode
|
||||
}
|
||||
|
||||
final Instruction getPrimaryInstruction() {
|
||||
@@ -1268,7 +1251,7 @@ class SideEffectInstruction extends Instruction {
|
||||
*/
|
||||
class CallSideEffectInstruction extends SideEffectInstruction {
|
||||
CallSideEffectInstruction() {
|
||||
opcode instanceof Opcode::CallSideEffect
|
||||
getOpcode() instanceof Opcode::CallSideEffect
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1282,7 +1265,7 @@ class CallSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||
CallReadSideEffectInstruction() {
|
||||
opcode instanceof Opcode::CallReadSideEffect
|
||||
getOpcode() instanceof Opcode::CallReadSideEffect
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1291,7 +1274,7 @@ class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class IndirectReadSideEffectInstruction extends SideEffectInstruction {
|
||||
IndirectReadSideEffectInstruction() {
|
||||
opcode instanceof Opcode::IndirectReadSideEffect
|
||||
getOpcode() instanceof Opcode::IndirectReadSideEffect
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1300,7 +1283,7 @@ class IndirectReadSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class BufferReadSideEffectInstruction extends SideEffectInstruction {
|
||||
BufferReadSideEffectInstruction() {
|
||||
opcode instanceof Opcode::BufferReadSideEffect
|
||||
getOpcode() instanceof Opcode::BufferReadSideEffect
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1309,7 +1292,7 @@ class BufferReadSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class IndirectWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
IndirectWriteSideEffectInstruction() {
|
||||
opcode instanceof Opcode::IndirectWriteSideEffect
|
||||
getOpcode() instanceof Opcode::IndirectWriteSideEffect
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1323,7 +1306,7 @@ class IndirectWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class BufferWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
BufferWriteSideEffectInstruction() {
|
||||
opcode instanceof Opcode::BufferWriteSideEffect
|
||||
getOpcode() instanceof Opcode::BufferWriteSideEffect
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1338,7 +1321,7 @@ class BufferWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class IndirectMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
IndirectMayWriteSideEffectInstruction() {
|
||||
opcode instanceof Opcode::IndirectMayWriteSideEffect
|
||||
getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1352,7 +1335,7 @@ class IndirectMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
BufferMayWriteSideEffectInstruction() {
|
||||
opcode instanceof Opcode::BufferMayWriteSideEffect
|
||||
getOpcode() instanceof Opcode::BufferMayWriteSideEffect
|
||||
}
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
result instanceof BufferMayMemoryAccess
|
||||
@@ -1364,7 +1347,7 @@ class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class ThrowInstruction extends Instruction {
|
||||
ThrowInstruction() {
|
||||
opcode instanceof ThrowOpcode
|
||||
getOpcode() instanceof ThrowOpcode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1373,7 +1356,7 @@ class ThrowInstruction extends Instruction {
|
||||
*/
|
||||
class ThrowValueInstruction extends ThrowInstruction {
|
||||
ThrowValueInstruction() {
|
||||
opcode instanceof Opcode::ThrowValue
|
||||
getOpcode() instanceof Opcode::ThrowValue
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1396,7 +1379,7 @@ class ThrowValueInstruction extends ThrowInstruction {
|
||||
*/
|
||||
class ReThrowInstruction extends ThrowInstruction {
|
||||
ReThrowInstruction() {
|
||||
opcode instanceof Opcode::ReThrow
|
||||
getOpcode() instanceof Opcode::ReThrow
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1405,7 +1388,7 @@ class ReThrowInstruction extends ThrowInstruction {
|
||||
*/
|
||||
class UnwindInstruction extends Instruction {
|
||||
UnwindInstruction() {
|
||||
opcode instanceof Opcode::Unwind
|
||||
getOpcode() instanceof Opcode::Unwind
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1414,7 +1397,7 @@ class UnwindInstruction extends Instruction {
|
||||
*/
|
||||
class CatchInstruction extends Instruction {
|
||||
CatchInstruction() {
|
||||
opcode instanceof CatchOpcode
|
||||
getOpcode() instanceof CatchOpcode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1425,7 +1408,7 @@ class CatchByTypeInstruction extends CatchInstruction {
|
||||
Type exceptionType;
|
||||
|
||||
CatchByTypeInstruction() {
|
||||
opcode instanceof Opcode::CatchByType and
|
||||
getOpcode() instanceof Opcode::CatchByType and
|
||||
exceptionType = Construction::getInstructionExceptionType(this)
|
||||
}
|
||||
|
||||
@@ -1446,13 +1429,13 @@ class CatchByTypeInstruction extends CatchInstruction {
|
||||
*/
|
||||
class CatchAnyInstruction extends CatchInstruction {
|
||||
CatchAnyInstruction() {
|
||||
opcode instanceof Opcode::CatchAny
|
||||
getOpcode() instanceof Opcode::CatchAny
|
||||
}
|
||||
}
|
||||
|
||||
class UnmodeledDefinitionInstruction extends Instruction {
|
||||
UnmodeledDefinitionInstruction() {
|
||||
opcode instanceof Opcode::UnmodeledDefinition
|
||||
getOpcode() instanceof Opcode::UnmodeledDefinition
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1465,7 +1448,7 @@ class UnmodeledDefinitionInstruction extends Instruction {
|
||||
*/
|
||||
class AliasedDefinitionInstruction extends Instruction {
|
||||
AliasedDefinitionInstruction() {
|
||||
opcode instanceof Opcode::AliasedDefinition
|
||||
getOpcode() instanceof Opcode::AliasedDefinition
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1475,7 +1458,7 @@ class AliasedDefinitionInstruction extends Instruction {
|
||||
|
||||
class UnmodeledUseInstruction extends Instruction {
|
||||
UnmodeledUseInstruction() {
|
||||
opcode instanceof Opcode::UnmodeledUse
|
||||
getOpcode() instanceof Opcode::UnmodeledUse
|
||||
}
|
||||
|
||||
override string getOperandsString() {
|
||||
@@ -1495,7 +1478,7 @@ class UnmodeledUseInstruction extends Instruction {
|
||||
*/
|
||||
class PhiInstruction extends Instruction {
|
||||
PhiInstruction() {
|
||||
opcode instanceof Opcode::Phi
|
||||
getOpcode() instanceof Opcode::Phi
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1547,7 +1530,7 @@ class PhiInstruction extends Instruction {
|
||||
*/
|
||||
class ChiInstruction extends Instruction {
|
||||
ChiInstruction() {
|
||||
opcode instanceof Opcode::Chi
|
||||
getOpcode() instanceof Opcode::Chi
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1577,7 +1560,7 @@ class ChiInstruction extends Instruction {
|
||||
*/
|
||||
class UnreachedInstruction extends Instruction {
|
||||
UnreachedInstruction() {
|
||||
opcode instanceof Opcode::Unreached
|
||||
getOpcode() instanceof Opcode::Unreached
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1587,6 +1570,6 @@ class UnreachedInstruction extends Instruction {
|
||||
*/
|
||||
class BuiltInInstruction extends Instruction {
|
||||
BuiltInInstruction() {
|
||||
opcode instanceof BuiltInOpcode
|
||||
getOpcode() instanceof BuiltInOpcode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,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
|
||||
@@ -40,7 +21,7 @@ cached private module Cached {
|
||||
}
|
||||
|
||||
cached OldInstruction getOldInstruction(Instruction instr) {
|
||||
instr.getTag() = WrappedInstructionTag(result)
|
||||
instr = WrappedInstruction(result)
|
||||
}
|
||||
|
||||
private Instruction getNewInstruction(OldInstruction instr) {
|
||||
@@ -52,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
|
||||
(
|
||||
@@ -88,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 |
|
||||
@@ -169,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 (
|
||||
@@ -189,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 |
|
||||
@@ -208,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
|
||||
@@ -230,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())
|
||||
)
|
||||
}
|
||||
@@ -257,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))
|
||||
@@ -273,7 +210,7 @@ cached private module Cached {
|
||||
)
|
||||
) or
|
||||
exists(OldInstruction oldInstruction |
|
||||
instruction = getChiInstruction(oldInstruction) and
|
||||
instruction = Chi(oldInstruction) and
|
||||
result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||
)
|
||||
)
|
||||
@@ -291,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())
|
||||
}
|
||||
@@ -346,7 +360,7 @@ cached private module Cached {
|
||||
)
|
||||
or
|
||||
exists(OldIR::Instruction oldInstruction |
|
||||
instruction.getTag() = ChiTag(oldInstruction) and
|
||||
instruction = Chi(oldInstruction) and
|
||||
result = getNewInstruction(oldInstruction)
|
||||
)
|
||||
}
|
||||
@@ -541,11 +555,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"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -211,17 +209,6 @@ module InstructionSanity {
|
||||
* Represents a single operation in the IR.
|
||||
*/
|
||||
class Instruction extends Construction::TInstruction {
|
||||
Opcode opcode;
|
||||
Locatable ast;
|
||||
InstructionTag instructionTag;
|
||||
Type resultType;
|
||||
FunctionIR funcIR;
|
||||
boolean glvalue;
|
||||
|
||||
Instruction() {
|
||||
this = Construction::MkInstruction(funcIR, opcode, ast, instructionTag, resultType, glvalue)
|
||||
}
|
||||
|
||||
final string toString() {
|
||||
result = getOpcode().toString() + ": " + getAST().toString()
|
||||
}
|
||||
@@ -244,9 +231,9 @@ class Instruction extends Construction::TInstruction {
|
||||
*/
|
||||
final string getOperationString() {
|
||||
if exists(getImmediateString()) then
|
||||
result = getOperationPrefix() + opcode.toString() + "[" + getImmediateString() + "]"
|
||||
result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
|
||||
else
|
||||
result = getOperationPrefix() + opcode.toString()
|
||||
result = getOperationPrefix() + getOpcode().toString()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,7 +251,7 @@ class Instruction extends Construction::TInstruction {
|
||||
}
|
||||
|
||||
private string getResultPrefix() {
|
||||
if resultType instanceof VoidType then
|
||||
if getResultType() instanceof VoidType then
|
||||
result = "v"
|
||||
else if hasMemoryResult() then
|
||||
if isResultModeled() then
|
||||
@@ -309,8 +296,8 @@ class Instruction extends Construction::TInstruction {
|
||||
|
||||
private string getResultTypeString() {
|
||||
exists(string valcat |
|
||||
valcat = getValueCategoryString(resultType.toString()) and
|
||||
if (resultType instanceof UnknownType and
|
||||
valcat = getValueCategoryString(getResultType().toString()) and
|
||||
if (getResultType() instanceof UnknownType and
|
||||
not isGLValue() and
|
||||
exists(getResultSize())) then (
|
||||
result = valcat + "[" + getResultSize().toString() + "]"
|
||||
@@ -378,28 +365,28 @@ class Instruction extends Construction::TInstruction {
|
||||
* Gets the function that contains this instruction.
|
||||
*/
|
||||
final Function getFunction() {
|
||||
result = funcIR.getFunction()
|
||||
result = getFunctionIR().getFunction()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the FunctionIR object that contains the IR for this instruction.
|
||||
*/
|
||||
final FunctionIR getFunctionIR() {
|
||||
result = funcIR
|
||||
result = Construction::getInstructionEnclosingFunctionIR(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the AST that caused this instruction to be generated.
|
||||
*/
|
||||
final Locatable getAST() {
|
||||
result = ast
|
||||
result = Construction::getInstructionAST(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location of the source code for this instruction.
|
||||
*/
|
||||
final Location getLocation() {
|
||||
result = ast.getLocation()
|
||||
result = getAST().getLocation()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -421,7 +408,7 @@ class Instruction extends Construction::TInstruction {
|
||||
* instruction does not produce a result, its result type will be `VoidType`.
|
||||
*/
|
||||
final Type getResultType() {
|
||||
result = resultType
|
||||
Construction::instructionHasType(this, result, _)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -443,7 +430,7 @@ class Instruction extends Construction::TInstruction {
|
||||
* the integer value loaded from variable `x`.
|
||||
*/
|
||||
final predicate isGLValue() {
|
||||
glvalue = true
|
||||
Construction::instructionHasType(this, _, true)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -460,10 +447,10 @@ class Instruction extends Construction::TInstruction {
|
||||
result = nullptr.getSize()
|
||||
)
|
||||
)
|
||||
else if resultType instanceof UnknownType then
|
||||
else if getResultType() instanceof UnknownType then
|
||||
result = Construction::getInstructionResultSize(this)
|
||||
else (
|
||||
result = resultType.getSize()
|
||||
result = getResultType().getSize()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -471,11 +458,7 @@ class Instruction extends Construction::TInstruction {
|
||||
* Gets the opcode that specifies the operation performed by this instruction.
|
||||
*/
|
||||
final Opcode getOpcode() {
|
||||
result = opcode
|
||||
}
|
||||
|
||||
final InstructionTag getTag() {
|
||||
result = instructionTag
|
||||
result = Construction::getInstructionOpcode(this)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -644,19 +627,19 @@ class ConstantValueInstruction extends Instruction {
|
||||
|
||||
class EnterFunctionInstruction extends Instruction {
|
||||
EnterFunctionInstruction() {
|
||||
opcode instanceof Opcode::EnterFunction
|
||||
getOpcode() instanceof Opcode::EnterFunction
|
||||
}
|
||||
}
|
||||
|
||||
class VariableAddressInstruction extends VariableInstruction {
|
||||
VariableAddressInstruction() {
|
||||
opcode instanceof Opcode::VariableAddress
|
||||
getOpcode() instanceof Opcode::VariableAddress
|
||||
}
|
||||
}
|
||||
|
||||
class InitializeParameterInstruction extends VariableInstruction {
|
||||
InitializeParameterInstruction() {
|
||||
opcode instanceof Opcode::InitializeParameter
|
||||
getOpcode() instanceof Opcode::InitializeParameter
|
||||
}
|
||||
|
||||
final Parameter getParameter() {
|
||||
@@ -673,13 +656,13 @@ class InitializeParameterInstruction extends VariableInstruction {
|
||||
*/
|
||||
class InitializeThisInstruction extends Instruction {
|
||||
InitializeThisInstruction() {
|
||||
opcode instanceof Opcode::InitializeThis
|
||||
getOpcode() instanceof Opcode::InitializeThis
|
||||
}
|
||||
}
|
||||
|
||||
class FieldAddressInstruction extends FieldInstruction {
|
||||
FieldAddressInstruction() {
|
||||
opcode instanceof Opcode::FieldAddress
|
||||
getOpcode() instanceof Opcode::FieldAddress
|
||||
}
|
||||
|
||||
final Instruction getObjectAddress() {
|
||||
@@ -689,7 +672,7 @@ class FieldAddressInstruction extends FieldInstruction {
|
||||
|
||||
class UninitializedInstruction extends VariableInstruction {
|
||||
UninitializedInstruction() {
|
||||
opcode instanceof Opcode::Uninitialized
|
||||
getOpcode() instanceof Opcode::Uninitialized
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -706,25 +689,25 @@ class UninitializedInstruction extends VariableInstruction {
|
||||
|
||||
class NoOpInstruction extends Instruction {
|
||||
NoOpInstruction() {
|
||||
opcode instanceof Opcode::NoOp
|
||||
getOpcode() instanceof Opcode::NoOp
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnInstruction extends Instruction {
|
||||
ReturnInstruction() {
|
||||
opcode instanceof ReturnOpcode
|
||||
getOpcode() instanceof ReturnOpcode
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnVoidInstruction extends ReturnInstruction {
|
||||
ReturnVoidInstruction() {
|
||||
opcode instanceof Opcode::ReturnVoid
|
||||
getOpcode() instanceof Opcode::ReturnVoid
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnValueInstruction extends ReturnInstruction {
|
||||
ReturnValueInstruction() {
|
||||
opcode instanceof Opcode::ReturnValue
|
||||
getOpcode() instanceof Opcode::ReturnValue
|
||||
}
|
||||
|
||||
final Instruction getReturnValue() {
|
||||
@@ -734,7 +717,7 @@ class ReturnValueInstruction extends ReturnInstruction {
|
||||
|
||||
class CopyInstruction extends Instruction {
|
||||
CopyInstruction() {
|
||||
opcode instanceof CopyOpcode
|
||||
getOpcode() instanceof CopyOpcode
|
||||
}
|
||||
|
||||
final Instruction getSourceValue() {
|
||||
@@ -744,13 +727,13 @@ class CopyInstruction extends Instruction {
|
||||
|
||||
class CopyValueInstruction extends CopyInstruction {
|
||||
CopyValueInstruction() {
|
||||
opcode instanceof Opcode::CopyValue
|
||||
getOpcode() instanceof Opcode::CopyValue
|
||||
}
|
||||
}
|
||||
|
||||
class LoadInstruction extends CopyInstruction {
|
||||
LoadInstruction() {
|
||||
opcode instanceof Opcode::Load
|
||||
getOpcode() instanceof Opcode::Load
|
||||
}
|
||||
|
||||
final Instruction getSourceAddress() {
|
||||
@@ -760,7 +743,7 @@ class LoadInstruction extends CopyInstruction {
|
||||
|
||||
class StoreInstruction extends CopyInstruction {
|
||||
StoreInstruction() {
|
||||
opcode instanceof Opcode::Store
|
||||
getOpcode() instanceof Opcode::Store
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -774,7 +757,7 @@ class StoreInstruction extends CopyInstruction {
|
||||
|
||||
class ConditionalBranchInstruction extends Instruction {
|
||||
ConditionalBranchInstruction() {
|
||||
opcode instanceof Opcode::ConditionalBranch
|
||||
getOpcode() instanceof Opcode::ConditionalBranch
|
||||
}
|
||||
|
||||
final Instruction getCondition() {
|
||||
@@ -792,25 +775,25 @@ class ConditionalBranchInstruction extends Instruction {
|
||||
|
||||
class ExitFunctionInstruction extends Instruction {
|
||||
ExitFunctionInstruction() {
|
||||
opcode instanceof Opcode::ExitFunction
|
||||
getOpcode() instanceof Opcode::ExitFunction
|
||||
}
|
||||
}
|
||||
|
||||
class ConstantInstruction extends ConstantValueInstruction {
|
||||
ConstantInstruction() {
|
||||
opcode instanceof Opcode::Constant
|
||||
getOpcode() instanceof Opcode::Constant
|
||||
}
|
||||
}
|
||||
|
||||
class IntegerConstantInstruction extends ConstantInstruction {
|
||||
IntegerConstantInstruction() {
|
||||
resultType instanceof IntegralType
|
||||
getResultType() instanceof IntegralType
|
||||
}
|
||||
}
|
||||
|
||||
class FloatConstantInstruction extends ConstantInstruction {
|
||||
FloatConstantInstruction() {
|
||||
resultType instanceof FloatingPointType
|
||||
getResultType() instanceof FloatingPointType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,7 +815,7 @@ class StringConstantInstruction extends Instruction {
|
||||
|
||||
class BinaryInstruction extends Instruction {
|
||||
BinaryInstruction() {
|
||||
opcode instanceof BinaryOpcode
|
||||
getOpcode() instanceof BinaryOpcode
|
||||
}
|
||||
|
||||
final Instruction getLeftOperand() {
|
||||
@@ -855,67 +838,67 @@ class BinaryInstruction extends Instruction {
|
||||
|
||||
class AddInstruction extends BinaryInstruction {
|
||||
AddInstruction() {
|
||||
opcode instanceof Opcode::Add
|
||||
getOpcode() instanceof Opcode::Add
|
||||
}
|
||||
}
|
||||
|
||||
class SubInstruction extends BinaryInstruction {
|
||||
SubInstruction() {
|
||||
opcode instanceof Opcode::Sub
|
||||
getOpcode() instanceof Opcode::Sub
|
||||
}
|
||||
}
|
||||
|
||||
class MulInstruction extends BinaryInstruction {
|
||||
MulInstruction() {
|
||||
opcode instanceof Opcode::Mul
|
||||
getOpcode() instanceof Opcode::Mul
|
||||
}
|
||||
}
|
||||
|
||||
class DivInstruction extends BinaryInstruction {
|
||||
DivInstruction() {
|
||||
opcode instanceof Opcode::Div
|
||||
getOpcode() instanceof Opcode::Div
|
||||
}
|
||||
}
|
||||
|
||||
class RemInstruction extends BinaryInstruction {
|
||||
RemInstruction() {
|
||||
opcode instanceof Opcode::Rem
|
||||
getOpcode() instanceof Opcode::Rem
|
||||
}
|
||||
}
|
||||
|
||||
class NegateInstruction extends UnaryInstruction {
|
||||
NegateInstruction() {
|
||||
opcode instanceof Opcode::Negate
|
||||
getOpcode() instanceof Opcode::Negate
|
||||
}
|
||||
}
|
||||
|
||||
class BitAndInstruction extends BinaryInstruction {
|
||||
BitAndInstruction() {
|
||||
opcode instanceof Opcode::BitAnd
|
||||
getOpcode() instanceof Opcode::BitAnd
|
||||
}
|
||||
}
|
||||
|
||||
class BitOrInstruction extends BinaryInstruction {
|
||||
BitOrInstruction() {
|
||||
opcode instanceof Opcode::BitOr
|
||||
getOpcode() instanceof Opcode::BitOr
|
||||
}
|
||||
}
|
||||
|
||||
class BitXorInstruction extends BinaryInstruction {
|
||||
BitXorInstruction() {
|
||||
opcode instanceof Opcode::BitXor
|
||||
getOpcode() instanceof Opcode::BitXor
|
||||
}
|
||||
}
|
||||
|
||||
class ShiftLeftInstruction extends BinaryInstruction {
|
||||
ShiftLeftInstruction() {
|
||||
opcode instanceof Opcode::ShiftLeft
|
||||
getOpcode() instanceof Opcode::ShiftLeft
|
||||
}
|
||||
}
|
||||
|
||||
class ShiftRightInstruction extends BinaryInstruction {
|
||||
ShiftRightInstruction() {
|
||||
opcode instanceof Opcode::ShiftRight
|
||||
getOpcode() instanceof Opcode::ShiftRight
|
||||
}
|
||||
}
|
||||
|
||||
@@ -923,7 +906,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
|
||||
int elementSize;
|
||||
|
||||
PointerArithmeticInstruction() {
|
||||
opcode instanceof PointerArithmeticOpcode and
|
||||
getOpcode() instanceof PointerArithmeticOpcode and
|
||||
elementSize = Construction::getInstructionElementSize(this)
|
||||
}
|
||||
|
||||
@@ -938,31 +921,31 @@ class PointerArithmeticInstruction extends BinaryInstruction {
|
||||
|
||||
class PointerOffsetInstruction extends PointerArithmeticInstruction {
|
||||
PointerOffsetInstruction() {
|
||||
opcode instanceof PointerOffsetOpcode
|
||||
getOpcode() instanceof PointerOffsetOpcode
|
||||
}
|
||||
}
|
||||
|
||||
class PointerAddInstruction extends PointerOffsetInstruction {
|
||||
PointerAddInstruction() {
|
||||
opcode instanceof Opcode::PointerAdd
|
||||
getOpcode() instanceof Opcode::PointerAdd
|
||||
}
|
||||
}
|
||||
|
||||
class PointerSubInstruction extends PointerOffsetInstruction {
|
||||
PointerSubInstruction() {
|
||||
opcode instanceof Opcode::PointerSub
|
||||
getOpcode() instanceof Opcode::PointerSub
|
||||
}
|
||||
}
|
||||
|
||||
class PointerDiffInstruction extends PointerArithmeticInstruction {
|
||||
PointerDiffInstruction() {
|
||||
opcode instanceof Opcode::PointerDiff
|
||||
getOpcode() instanceof Opcode::PointerDiff
|
||||
}
|
||||
}
|
||||
|
||||
class UnaryInstruction extends Instruction {
|
||||
UnaryInstruction() {
|
||||
opcode instanceof UnaryOpcode
|
||||
getOpcode() instanceof UnaryOpcode
|
||||
}
|
||||
|
||||
final Instruction getOperand() {
|
||||
@@ -972,7 +955,7 @@ class UnaryInstruction extends Instruction {
|
||||
|
||||
class ConvertInstruction extends UnaryInstruction {
|
||||
ConvertInstruction() {
|
||||
opcode instanceof Opcode::Convert
|
||||
getOpcode() instanceof Opcode::Convert
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1024,7 +1007,7 @@ class InheritanceConversionInstruction extends UnaryInstruction {
|
||||
*/
|
||||
class ConvertToBaseInstruction extends InheritanceConversionInstruction {
|
||||
ConvertToBaseInstruction() {
|
||||
opcode instanceof Opcode::ConvertToBase
|
||||
getOpcode() instanceof Opcode::ConvertToBase
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1034,7 +1017,7 @@ class ConvertToBaseInstruction extends InheritanceConversionInstruction {
|
||||
*/
|
||||
class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction {
|
||||
ConvertToVirtualBaseInstruction() {
|
||||
opcode instanceof Opcode::ConvertToVirtualBase
|
||||
getOpcode() instanceof Opcode::ConvertToVirtualBase
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1044,37 +1027,37 @@ class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction {
|
||||
*/
|
||||
class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
|
||||
ConvertToDerivedInstruction() {
|
||||
opcode instanceof Opcode::ConvertToDerived
|
||||
getOpcode() instanceof Opcode::ConvertToDerived
|
||||
}
|
||||
}
|
||||
|
||||
class BitComplementInstruction extends UnaryInstruction {
|
||||
BitComplementInstruction() {
|
||||
opcode instanceof Opcode::BitComplement
|
||||
getOpcode() instanceof Opcode::BitComplement
|
||||
}
|
||||
}
|
||||
|
||||
class LogicalNotInstruction extends UnaryInstruction {
|
||||
LogicalNotInstruction() {
|
||||
opcode instanceof Opcode::LogicalNot
|
||||
getOpcode() instanceof Opcode::LogicalNot
|
||||
}
|
||||
}
|
||||
|
||||
class CompareInstruction extends BinaryInstruction {
|
||||
CompareInstruction() {
|
||||
opcode instanceof CompareOpcode
|
||||
getOpcode() instanceof CompareOpcode
|
||||
}
|
||||
}
|
||||
|
||||
class CompareEQInstruction extends CompareInstruction {
|
||||
CompareEQInstruction() {
|
||||
opcode instanceof Opcode::CompareEQ
|
||||
getOpcode() instanceof Opcode::CompareEQ
|
||||
}
|
||||
}
|
||||
|
||||
class CompareNEInstruction extends CompareInstruction {
|
||||
CompareNEInstruction() {
|
||||
opcode instanceof Opcode::CompareNE
|
||||
getOpcode() instanceof Opcode::CompareNE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1083,7 +1066,7 @@ class CompareNEInstruction extends CompareInstruction {
|
||||
*/
|
||||
class RelationalInstruction extends CompareInstruction {
|
||||
RelationalInstruction() {
|
||||
opcode instanceof RelationalOpcode
|
||||
getOpcode() instanceof RelationalOpcode
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1116,7 +1099,7 @@ class RelationalInstruction extends CompareInstruction {
|
||||
|
||||
class CompareLTInstruction extends RelationalInstruction {
|
||||
CompareLTInstruction() {
|
||||
opcode instanceof Opcode::CompareLT
|
||||
getOpcode() instanceof Opcode::CompareLT
|
||||
}
|
||||
|
||||
override Instruction getLesserOperand() {
|
||||
@@ -1134,7 +1117,7 @@ class CompareLTInstruction extends RelationalInstruction {
|
||||
|
||||
class CompareGTInstruction extends RelationalInstruction {
|
||||
CompareGTInstruction() {
|
||||
opcode instanceof Opcode::CompareGT
|
||||
getOpcode() instanceof Opcode::CompareGT
|
||||
}
|
||||
|
||||
override Instruction getLesserOperand() {
|
||||
@@ -1152,7 +1135,7 @@ class CompareGTInstruction extends RelationalInstruction {
|
||||
|
||||
class CompareLEInstruction extends RelationalInstruction {
|
||||
CompareLEInstruction() {
|
||||
opcode instanceof Opcode::CompareLE
|
||||
getOpcode() instanceof Opcode::CompareLE
|
||||
}
|
||||
|
||||
override Instruction getLesserOperand() {
|
||||
@@ -1170,7 +1153,7 @@ class CompareLEInstruction extends RelationalInstruction {
|
||||
|
||||
class CompareGEInstruction extends RelationalInstruction {
|
||||
CompareGEInstruction() {
|
||||
opcode instanceof Opcode::CompareGE
|
||||
getOpcode() instanceof Opcode::CompareGE
|
||||
}
|
||||
|
||||
override Instruction getLesserOperand() {
|
||||
@@ -1188,7 +1171,7 @@ class CompareGEInstruction extends RelationalInstruction {
|
||||
|
||||
class SwitchInstruction extends Instruction {
|
||||
SwitchInstruction() {
|
||||
opcode instanceof Opcode::Switch
|
||||
getOpcode() instanceof Opcode::Switch
|
||||
}
|
||||
|
||||
final Instruction getExpression() {
|
||||
@@ -1211,7 +1194,7 @@ class SwitchInstruction extends Instruction {
|
||||
*/
|
||||
class CallInstruction extends Instruction {
|
||||
CallInstruction() {
|
||||
opcode instanceof Opcode::Call
|
||||
getOpcode() instanceof Opcode::Call
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1254,7 +1237,7 @@ class CallInstruction extends Instruction {
|
||||
*/
|
||||
class SideEffectInstruction extends Instruction {
|
||||
SideEffectInstruction() {
|
||||
opcode instanceof SideEffectOpcode
|
||||
getOpcode() instanceof SideEffectOpcode
|
||||
}
|
||||
|
||||
final Instruction getPrimaryInstruction() {
|
||||
@@ -1268,7 +1251,7 @@ class SideEffectInstruction extends Instruction {
|
||||
*/
|
||||
class CallSideEffectInstruction extends SideEffectInstruction {
|
||||
CallSideEffectInstruction() {
|
||||
opcode instanceof Opcode::CallSideEffect
|
||||
getOpcode() instanceof Opcode::CallSideEffect
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1282,7 +1265,7 @@ class CallSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||
CallReadSideEffectInstruction() {
|
||||
opcode instanceof Opcode::CallReadSideEffect
|
||||
getOpcode() instanceof Opcode::CallReadSideEffect
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1291,7 +1274,7 @@ class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class IndirectReadSideEffectInstruction extends SideEffectInstruction {
|
||||
IndirectReadSideEffectInstruction() {
|
||||
opcode instanceof Opcode::IndirectReadSideEffect
|
||||
getOpcode() instanceof Opcode::IndirectReadSideEffect
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1300,7 +1283,7 @@ class IndirectReadSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class BufferReadSideEffectInstruction extends SideEffectInstruction {
|
||||
BufferReadSideEffectInstruction() {
|
||||
opcode instanceof Opcode::BufferReadSideEffect
|
||||
getOpcode() instanceof Opcode::BufferReadSideEffect
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1309,7 +1292,7 @@ class BufferReadSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class IndirectWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
IndirectWriteSideEffectInstruction() {
|
||||
opcode instanceof Opcode::IndirectWriteSideEffect
|
||||
getOpcode() instanceof Opcode::IndirectWriteSideEffect
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1323,7 +1306,7 @@ class IndirectWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class BufferWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
BufferWriteSideEffectInstruction() {
|
||||
opcode instanceof Opcode::BufferWriteSideEffect
|
||||
getOpcode() instanceof Opcode::BufferWriteSideEffect
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1338,7 +1321,7 @@ class BufferWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class IndirectMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
IndirectMayWriteSideEffectInstruction() {
|
||||
opcode instanceof Opcode::IndirectMayWriteSideEffect
|
||||
getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1352,7 +1335,7 @@ class IndirectMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
BufferMayWriteSideEffectInstruction() {
|
||||
opcode instanceof Opcode::BufferMayWriteSideEffect
|
||||
getOpcode() instanceof Opcode::BufferMayWriteSideEffect
|
||||
}
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
result instanceof BufferMayMemoryAccess
|
||||
@@ -1364,7 +1347,7 @@ class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class ThrowInstruction extends Instruction {
|
||||
ThrowInstruction() {
|
||||
opcode instanceof ThrowOpcode
|
||||
getOpcode() instanceof ThrowOpcode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1373,7 +1356,7 @@ class ThrowInstruction extends Instruction {
|
||||
*/
|
||||
class ThrowValueInstruction extends ThrowInstruction {
|
||||
ThrowValueInstruction() {
|
||||
opcode instanceof Opcode::ThrowValue
|
||||
getOpcode() instanceof Opcode::ThrowValue
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1396,7 +1379,7 @@ class ThrowValueInstruction extends ThrowInstruction {
|
||||
*/
|
||||
class ReThrowInstruction extends ThrowInstruction {
|
||||
ReThrowInstruction() {
|
||||
opcode instanceof Opcode::ReThrow
|
||||
getOpcode() instanceof Opcode::ReThrow
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1405,7 +1388,7 @@ class ReThrowInstruction extends ThrowInstruction {
|
||||
*/
|
||||
class UnwindInstruction extends Instruction {
|
||||
UnwindInstruction() {
|
||||
opcode instanceof Opcode::Unwind
|
||||
getOpcode() instanceof Opcode::Unwind
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1414,7 +1397,7 @@ class UnwindInstruction extends Instruction {
|
||||
*/
|
||||
class CatchInstruction extends Instruction {
|
||||
CatchInstruction() {
|
||||
opcode instanceof CatchOpcode
|
||||
getOpcode() instanceof CatchOpcode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1425,7 +1408,7 @@ class CatchByTypeInstruction extends CatchInstruction {
|
||||
Type exceptionType;
|
||||
|
||||
CatchByTypeInstruction() {
|
||||
opcode instanceof Opcode::CatchByType and
|
||||
getOpcode() instanceof Opcode::CatchByType and
|
||||
exceptionType = Construction::getInstructionExceptionType(this)
|
||||
}
|
||||
|
||||
@@ -1446,13 +1429,13 @@ class CatchByTypeInstruction extends CatchInstruction {
|
||||
*/
|
||||
class CatchAnyInstruction extends CatchInstruction {
|
||||
CatchAnyInstruction() {
|
||||
opcode instanceof Opcode::CatchAny
|
||||
getOpcode() instanceof Opcode::CatchAny
|
||||
}
|
||||
}
|
||||
|
||||
class UnmodeledDefinitionInstruction extends Instruction {
|
||||
UnmodeledDefinitionInstruction() {
|
||||
opcode instanceof Opcode::UnmodeledDefinition
|
||||
getOpcode() instanceof Opcode::UnmodeledDefinition
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1465,7 +1448,7 @@ class UnmodeledDefinitionInstruction extends Instruction {
|
||||
*/
|
||||
class AliasedDefinitionInstruction extends Instruction {
|
||||
AliasedDefinitionInstruction() {
|
||||
opcode instanceof Opcode::AliasedDefinition
|
||||
getOpcode() instanceof Opcode::AliasedDefinition
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1475,7 +1458,7 @@ class AliasedDefinitionInstruction extends Instruction {
|
||||
|
||||
class UnmodeledUseInstruction extends Instruction {
|
||||
UnmodeledUseInstruction() {
|
||||
opcode instanceof Opcode::UnmodeledUse
|
||||
getOpcode() instanceof Opcode::UnmodeledUse
|
||||
}
|
||||
|
||||
override string getOperandsString() {
|
||||
@@ -1495,7 +1478,7 @@ class UnmodeledUseInstruction extends Instruction {
|
||||
*/
|
||||
class PhiInstruction extends Instruction {
|
||||
PhiInstruction() {
|
||||
opcode instanceof Opcode::Phi
|
||||
getOpcode() instanceof Opcode::Phi
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1547,7 +1530,7 @@ class PhiInstruction extends Instruction {
|
||||
*/
|
||||
class ChiInstruction extends Instruction {
|
||||
ChiInstruction() {
|
||||
opcode instanceof Opcode::Chi
|
||||
getOpcode() instanceof Opcode::Chi
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1577,7 +1560,7 @@ class ChiInstruction extends Instruction {
|
||||
*/
|
||||
class UnreachedInstruction extends Instruction {
|
||||
UnreachedInstruction() {
|
||||
opcode instanceof Opcode::Unreached
|
||||
getOpcode() instanceof Opcode::Unreached
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1587,6 +1570,6 @@ class UnreachedInstruction extends Instruction {
|
||||
*/
|
||||
class BuiltInInstruction extends Instruction {
|
||||
BuiltInInstruction() {
|
||||
opcode instanceof BuiltInOpcode
|
||||
getOpcode() instanceof BuiltInOpcode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,20 +8,12 @@ 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, _)
|
||||
}
|
||||
|
||||
private TranslatedElement getInstructionTranslatedElement(
|
||||
Instruction instruction) {
|
||||
instruction = result.getInstruction(_)
|
||||
}
|
||||
|
||||
private TranslatedElement getInstructionTranslatedElementAndTag(
|
||||
Instruction instruction, InstructionTag tag) {
|
||||
instruction = result.getInstruction(tag)
|
||||
InstructionTag getInstructionTag(Instruction instruction) {
|
||||
instruction = MkInstruction(_, result)
|
||||
}
|
||||
|
||||
import Cached
|
||||
@@ -31,21 +23,10 @@ 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)
|
||||
MkInstruction(TranslatedElement element, InstructionTag tag) {
|
||||
element.hasInstruction(_, tag, _, _)
|
||||
}
|
||||
|
||||
private predicate hasInstruction(Function func, Opcode opcode, Locatable ast,
|
||||
InstructionTag tag, Type resultType, boolean isGLValue) {
|
||||
exists(TranslatedElement element |
|
||||
element.getAST() = ast and
|
||||
func = element.getFunction() and
|
||||
element.hasInstruction(opcode, tag, resultType, isGLValue)
|
||||
)
|
||||
}
|
||||
|
||||
cached predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag,
|
||||
Type type) {
|
||||
exists(TranslatedElement element |
|
||||
@@ -80,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,
|
||||
@@ -94,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
|
||||
@@ -179,9 +160,27 @@ cached private module Cached {
|
||||
goto.getLocation().isBefore(goto.getTarget().getLocation())
|
||||
}
|
||||
|
||||
cached Locatable getInstructionAST(Instruction instruction) {
|
||||
result = getInstructionTranslatedElement(instruction).getAST()
|
||||
}
|
||||
|
||||
cached predicate instructionHasType(Instruction instruction, Type type, boolean isGLValue) {
|
||||
getInstructionTranslatedElement(instruction)
|
||||
.hasInstruction(_, getInstructionTag(instruction), type, isGLValue)
|
||||
}
|
||||
|
||||
cached Opcode getInstructionOpcode(Instruction instruction) {
|
||||
getInstructionTranslatedElement(instruction)
|
||||
.hasInstruction(result, getInstructionTag(instruction), _, _)
|
||||
}
|
||||
|
||||
cached FunctionIR getInstructionEnclosingFunctionIR(Instruction instruction) {
|
||||
result.getFunction() = getInstructionTranslatedElement(instruction).getFunction()
|
||||
}
|
||||
|
||||
cached IRVariable getInstructionVariable(Instruction instruction) {
|
||||
result = getInstructionTranslatedElement(instruction).getInstructionVariable(
|
||||
instruction.getTag())
|
||||
getInstructionTag(instruction))
|
||||
}
|
||||
|
||||
cached Field getInstructionField(Instruction instruction) {
|
||||
@@ -192,41 +191,39 @@ cached private module Cached {
|
||||
}
|
||||
|
||||
cached Function getInstructionFunction(Instruction instruction) {
|
||||
exists(InstructionTag tag |
|
||||
result = getInstructionTranslatedElementAndTag(instruction, tag)
|
||||
.getInstructionFunction(tag)
|
||||
)
|
||||
result = getInstructionTranslatedElement(instruction)
|
||||
.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) {
|
||||
@@ -262,6 +259,6 @@ cached private module CachedForDebugging {
|
||||
|
||||
cached string getInstructionUniqueId(Instruction instruction) {
|
||||
result = getInstructionTranslatedElement(instruction).getId() + ":" +
|
||||
getInstructionTagId(instruction.getTag())
|
||||
getInstructionTagId(getInstructionTag(instruction))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -9,6 +9,7 @@ private import InstructionTag
|
||||
private import TranslatedCondition
|
||||
private import TranslatedFunction
|
||||
private import TranslatedStmt
|
||||
private import IRConstruction
|
||||
|
||||
/**
|
||||
* Gets the built-in `int` type.
|
||||
@@ -623,18 +624,12 @@ abstract class TranslatedElement extends TTranslatedElement {
|
||||
none()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasInstructionWithTagAndAst(InstructionTag tag, Locatable ast) {
|
||||
hasInstruction(_, tag, _, _) and
|
||||
ast = getAST()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the instruction generated by this element with tag `tag`.
|
||||
*/
|
||||
final Instruction getInstruction(InstructionTag tag) {
|
||||
hasInstructionWithTagAndAst(tag, result.getAST()) and
|
||||
tag = result.getTag()
|
||||
getInstructionTranslatedElement(result) = this and
|
||||
getInstructionTag(result) = tag
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
@@ -211,17 +209,6 @@ module InstructionSanity {
|
||||
* Represents a single operation in the IR.
|
||||
*/
|
||||
class Instruction extends Construction::TInstruction {
|
||||
Opcode opcode;
|
||||
Locatable ast;
|
||||
InstructionTag instructionTag;
|
||||
Type resultType;
|
||||
FunctionIR funcIR;
|
||||
boolean glvalue;
|
||||
|
||||
Instruction() {
|
||||
this = Construction::MkInstruction(funcIR, opcode, ast, instructionTag, resultType, glvalue)
|
||||
}
|
||||
|
||||
final string toString() {
|
||||
result = getOpcode().toString() + ": " + getAST().toString()
|
||||
}
|
||||
@@ -244,9 +231,9 @@ class Instruction extends Construction::TInstruction {
|
||||
*/
|
||||
final string getOperationString() {
|
||||
if exists(getImmediateString()) then
|
||||
result = getOperationPrefix() + opcode.toString() + "[" + getImmediateString() + "]"
|
||||
result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
|
||||
else
|
||||
result = getOperationPrefix() + opcode.toString()
|
||||
result = getOperationPrefix() + getOpcode().toString()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,7 +251,7 @@ class Instruction extends Construction::TInstruction {
|
||||
}
|
||||
|
||||
private string getResultPrefix() {
|
||||
if resultType instanceof VoidType then
|
||||
if getResultType() instanceof VoidType then
|
||||
result = "v"
|
||||
else if hasMemoryResult() then
|
||||
if isResultModeled() then
|
||||
@@ -309,8 +296,8 @@ class Instruction extends Construction::TInstruction {
|
||||
|
||||
private string getResultTypeString() {
|
||||
exists(string valcat |
|
||||
valcat = getValueCategoryString(resultType.toString()) and
|
||||
if (resultType instanceof UnknownType and
|
||||
valcat = getValueCategoryString(getResultType().toString()) and
|
||||
if (getResultType() instanceof UnknownType and
|
||||
not isGLValue() and
|
||||
exists(getResultSize())) then (
|
||||
result = valcat + "[" + getResultSize().toString() + "]"
|
||||
@@ -378,28 +365,28 @@ class Instruction extends Construction::TInstruction {
|
||||
* Gets the function that contains this instruction.
|
||||
*/
|
||||
final Function getFunction() {
|
||||
result = funcIR.getFunction()
|
||||
result = getFunctionIR().getFunction()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the FunctionIR object that contains the IR for this instruction.
|
||||
*/
|
||||
final FunctionIR getFunctionIR() {
|
||||
result = funcIR
|
||||
result = Construction::getInstructionEnclosingFunctionIR(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the AST that caused this instruction to be generated.
|
||||
*/
|
||||
final Locatable getAST() {
|
||||
result = ast
|
||||
result = Construction::getInstructionAST(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location of the source code for this instruction.
|
||||
*/
|
||||
final Location getLocation() {
|
||||
result = ast.getLocation()
|
||||
result = getAST().getLocation()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -421,7 +408,7 @@ class Instruction extends Construction::TInstruction {
|
||||
* instruction does not produce a result, its result type will be `VoidType`.
|
||||
*/
|
||||
final Type getResultType() {
|
||||
result = resultType
|
||||
Construction::instructionHasType(this, result, _)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -443,7 +430,7 @@ class Instruction extends Construction::TInstruction {
|
||||
* the integer value loaded from variable `x`.
|
||||
*/
|
||||
final predicate isGLValue() {
|
||||
glvalue = true
|
||||
Construction::instructionHasType(this, _, true)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -460,10 +447,10 @@ class Instruction extends Construction::TInstruction {
|
||||
result = nullptr.getSize()
|
||||
)
|
||||
)
|
||||
else if resultType instanceof UnknownType then
|
||||
else if getResultType() instanceof UnknownType then
|
||||
result = Construction::getInstructionResultSize(this)
|
||||
else (
|
||||
result = resultType.getSize()
|
||||
result = getResultType().getSize()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -471,11 +458,7 @@ class Instruction extends Construction::TInstruction {
|
||||
* Gets the opcode that specifies the operation performed by this instruction.
|
||||
*/
|
||||
final Opcode getOpcode() {
|
||||
result = opcode
|
||||
}
|
||||
|
||||
final InstructionTag getTag() {
|
||||
result = instructionTag
|
||||
result = Construction::getInstructionOpcode(this)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -644,19 +627,19 @@ class ConstantValueInstruction extends Instruction {
|
||||
|
||||
class EnterFunctionInstruction extends Instruction {
|
||||
EnterFunctionInstruction() {
|
||||
opcode instanceof Opcode::EnterFunction
|
||||
getOpcode() instanceof Opcode::EnterFunction
|
||||
}
|
||||
}
|
||||
|
||||
class VariableAddressInstruction extends VariableInstruction {
|
||||
VariableAddressInstruction() {
|
||||
opcode instanceof Opcode::VariableAddress
|
||||
getOpcode() instanceof Opcode::VariableAddress
|
||||
}
|
||||
}
|
||||
|
||||
class InitializeParameterInstruction extends VariableInstruction {
|
||||
InitializeParameterInstruction() {
|
||||
opcode instanceof Opcode::InitializeParameter
|
||||
getOpcode() instanceof Opcode::InitializeParameter
|
||||
}
|
||||
|
||||
final Parameter getParameter() {
|
||||
@@ -673,13 +656,13 @@ class InitializeParameterInstruction extends VariableInstruction {
|
||||
*/
|
||||
class InitializeThisInstruction extends Instruction {
|
||||
InitializeThisInstruction() {
|
||||
opcode instanceof Opcode::InitializeThis
|
||||
getOpcode() instanceof Opcode::InitializeThis
|
||||
}
|
||||
}
|
||||
|
||||
class FieldAddressInstruction extends FieldInstruction {
|
||||
FieldAddressInstruction() {
|
||||
opcode instanceof Opcode::FieldAddress
|
||||
getOpcode() instanceof Opcode::FieldAddress
|
||||
}
|
||||
|
||||
final Instruction getObjectAddress() {
|
||||
@@ -689,7 +672,7 @@ class FieldAddressInstruction extends FieldInstruction {
|
||||
|
||||
class UninitializedInstruction extends VariableInstruction {
|
||||
UninitializedInstruction() {
|
||||
opcode instanceof Opcode::Uninitialized
|
||||
getOpcode() instanceof Opcode::Uninitialized
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -706,25 +689,25 @@ class UninitializedInstruction extends VariableInstruction {
|
||||
|
||||
class NoOpInstruction extends Instruction {
|
||||
NoOpInstruction() {
|
||||
opcode instanceof Opcode::NoOp
|
||||
getOpcode() instanceof Opcode::NoOp
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnInstruction extends Instruction {
|
||||
ReturnInstruction() {
|
||||
opcode instanceof ReturnOpcode
|
||||
getOpcode() instanceof ReturnOpcode
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnVoidInstruction extends ReturnInstruction {
|
||||
ReturnVoidInstruction() {
|
||||
opcode instanceof Opcode::ReturnVoid
|
||||
getOpcode() instanceof Opcode::ReturnVoid
|
||||
}
|
||||
}
|
||||
|
||||
class ReturnValueInstruction extends ReturnInstruction {
|
||||
ReturnValueInstruction() {
|
||||
opcode instanceof Opcode::ReturnValue
|
||||
getOpcode() instanceof Opcode::ReturnValue
|
||||
}
|
||||
|
||||
final Instruction getReturnValue() {
|
||||
@@ -734,7 +717,7 @@ class ReturnValueInstruction extends ReturnInstruction {
|
||||
|
||||
class CopyInstruction extends Instruction {
|
||||
CopyInstruction() {
|
||||
opcode instanceof CopyOpcode
|
||||
getOpcode() instanceof CopyOpcode
|
||||
}
|
||||
|
||||
final Instruction getSourceValue() {
|
||||
@@ -744,13 +727,13 @@ class CopyInstruction extends Instruction {
|
||||
|
||||
class CopyValueInstruction extends CopyInstruction {
|
||||
CopyValueInstruction() {
|
||||
opcode instanceof Opcode::CopyValue
|
||||
getOpcode() instanceof Opcode::CopyValue
|
||||
}
|
||||
}
|
||||
|
||||
class LoadInstruction extends CopyInstruction {
|
||||
LoadInstruction() {
|
||||
opcode instanceof Opcode::Load
|
||||
getOpcode() instanceof Opcode::Load
|
||||
}
|
||||
|
||||
final Instruction getSourceAddress() {
|
||||
@@ -760,7 +743,7 @@ class LoadInstruction extends CopyInstruction {
|
||||
|
||||
class StoreInstruction extends CopyInstruction {
|
||||
StoreInstruction() {
|
||||
opcode instanceof Opcode::Store
|
||||
getOpcode() instanceof Opcode::Store
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -774,7 +757,7 @@ class StoreInstruction extends CopyInstruction {
|
||||
|
||||
class ConditionalBranchInstruction extends Instruction {
|
||||
ConditionalBranchInstruction() {
|
||||
opcode instanceof Opcode::ConditionalBranch
|
||||
getOpcode() instanceof Opcode::ConditionalBranch
|
||||
}
|
||||
|
||||
final Instruction getCondition() {
|
||||
@@ -792,25 +775,25 @@ class ConditionalBranchInstruction extends Instruction {
|
||||
|
||||
class ExitFunctionInstruction extends Instruction {
|
||||
ExitFunctionInstruction() {
|
||||
opcode instanceof Opcode::ExitFunction
|
||||
getOpcode() instanceof Opcode::ExitFunction
|
||||
}
|
||||
}
|
||||
|
||||
class ConstantInstruction extends ConstantValueInstruction {
|
||||
ConstantInstruction() {
|
||||
opcode instanceof Opcode::Constant
|
||||
getOpcode() instanceof Opcode::Constant
|
||||
}
|
||||
}
|
||||
|
||||
class IntegerConstantInstruction extends ConstantInstruction {
|
||||
IntegerConstantInstruction() {
|
||||
resultType instanceof IntegralType
|
||||
getResultType() instanceof IntegralType
|
||||
}
|
||||
}
|
||||
|
||||
class FloatConstantInstruction extends ConstantInstruction {
|
||||
FloatConstantInstruction() {
|
||||
resultType instanceof FloatingPointType
|
||||
getResultType() instanceof FloatingPointType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,7 +815,7 @@ class StringConstantInstruction extends Instruction {
|
||||
|
||||
class BinaryInstruction extends Instruction {
|
||||
BinaryInstruction() {
|
||||
opcode instanceof BinaryOpcode
|
||||
getOpcode() instanceof BinaryOpcode
|
||||
}
|
||||
|
||||
final Instruction getLeftOperand() {
|
||||
@@ -855,67 +838,67 @@ class BinaryInstruction extends Instruction {
|
||||
|
||||
class AddInstruction extends BinaryInstruction {
|
||||
AddInstruction() {
|
||||
opcode instanceof Opcode::Add
|
||||
getOpcode() instanceof Opcode::Add
|
||||
}
|
||||
}
|
||||
|
||||
class SubInstruction extends BinaryInstruction {
|
||||
SubInstruction() {
|
||||
opcode instanceof Opcode::Sub
|
||||
getOpcode() instanceof Opcode::Sub
|
||||
}
|
||||
}
|
||||
|
||||
class MulInstruction extends BinaryInstruction {
|
||||
MulInstruction() {
|
||||
opcode instanceof Opcode::Mul
|
||||
getOpcode() instanceof Opcode::Mul
|
||||
}
|
||||
}
|
||||
|
||||
class DivInstruction extends BinaryInstruction {
|
||||
DivInstruction() {
|
||||
opcode instanceof Opcode::Div
|
||||
getOpcode() instanceof Opcode::Div
|
||||
}
|
||||
}
|
||||
|
||||
class RemInstruction extends BinaryInstruction {
|
||||
RemInstruction() {
|
||||
opcode instanceof Opcode::Rem
|
||||
getOpcode() instanceof Opcode::Rem
|
||||
}
|
||||
}
|
||||
|
||||
class NegateInstruction extends UnaryInstruction {
|
||||
NegateInstruction() {
|
||||
opcode instanceof Opcode::Negate
|
||||
getOpcode() instanceof Opcode::Negate
|
||||
}
|
||||
}
|
||||
|
||||
class BitAndInstruction extends BinaryInstruction {
|
||||
BitAndInstruction() {
|
||||
opcode instanceof Opcode::BitAnd
|
||||
getOpcode() instanceof Opcode::BitAnd
|
||||
}
|
||||
}
|
||||
|
||||
class BitOrInstruction extends BinaryInstruction {
|
||||
BitOrInstruction() {
|
||||
opcode instanceof Opcode::BitOr
|
||||
getOpcode() instanceof Opcode::BitOr
|
||||
}
|
||||
}
|
||||
|
||||
class BitXorInstruction extends BinaryInstruction {
|
||||
BitXorInstruction() {
|
||||
opcode instanceof Opcode::BitXor
|
||||
getOpcode() instanceof Opcode::BitXor
|
||||
}
|
||||
}
|
||||
|
||||
class ShiftLeftInstruction extends BinaryInstruction {
|
||||
ShiftLeftInstruction() {
|
||||
opcode instanceof Opcode::ShiftLeft
|
||||
getOpcode() instanceof Opcode::ShiftLeft
|
||||
}
|
||||
}
|
||||
|
||||
class ShiftRightInstruction extends BinaryInstruction {
|
||||
ShiftRightInstruction() {
|
||||
opcode instanceof Opcode::ShiftRight
|
||||
getOpcode() instanceof Opcode::ShiftRight
|
||||
}
|
||||
}
|
||||
|
||||
@@ -923,7 +906,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
|
||||
int elementSize;
|
||||
|
||||
PointerArithmeticInstruction() {
|
||||
opcode instanceof PointerArithmeticOpcode and
|
||||
getOpcode() instanceof PointerArithmeticOpcode and
|
||||
elementSize = Construction::getInstructionElementSize(this)
|
||||
}
|
||||
|
||||
@@ -938,31 +921,31 @@ class PointerArithmeticInstruction extends BinaryInstruction {
|
||||
|
||||
class PointerOffsetInstruction extends PointerArithmeticInstruction {
|
||||
PointerOffsetInstruction() {
|
||||
opcode instanceof PointerOffsetOpcode
|
||||
getOpcode() instanceof PointerOffsetOpcode
|
||||
}
|
||||
}
|
||||
|
||||
class PointerAddInstruction extends PointerOffsetInstruction {
|
||||
PointerAddInstruction() {
|
||||
opcode instanceof Opcode::PointerAdd
|
||||
getOpcode() instanceof Opcode::PointerAdd
|
||||
}
|
||||
}
|
||||
|
||||
class PointerSubInstruction extends PointerOffsetInstruction {
|
||||
PointerSubInstruction() {
|
||||
opcode instanceof Opcode::PointerSub
|
||||
getOpcode() instanceof Opcode::PointerSub
|
||||
}
|
||||
}
|
||||
|
||||
class PointerDiffInstruction extends PointerArithmeticInstruction {
|
||||
PointerDiffInstruction() {
|
||||
opcode instanceof Opcode::PointerDiff
|
||||
getOpcode() instanceof Opcode::PointerDiff
|
||||
}
|
||||
}
|
||||
|
||||
class UnaryInstruction extends Instruction {
|
||||
UnaryInstruction() {
|
||||
opcode instanceof UnaryOpcode
|
||||
getOpcode() instanceof UnaryOpcode
|
||||
}
|
||||
|
||||
final Instruction getOperand() {
|
||||
@@ -972,7 +955,7 @@ class UnaryInstruction extends Instruction {
|
||||
|
||||
class ConvertInstruction extends UnaryInstruction {
|
||||
ConvertInstruction() {
|
||||
opcode instanceof Opcode::Convert
|
||||
getOpcode() instanceof Opcode::Convert
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1024,7 +1007,7 @@ class InheritanceConversionInstruction extends UnaryInstruction {
|
||||
*/
|
||||
class ConvertToBaseInstruction extends InheritanceConversionInstruction {
|
||||
ConvertToBaseInstruction() {
|
||||
opcode instanceof Opcode::ConvertToBase
|
||||
getOpcode() instanceof Opcode::ConvertToBase
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1034,7 +1017,7 @@ class ConvertToBaseInstruction extends InheritanceConversionInstruction {
|
||||
*/
|
||||
class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction {
|
||||
ConvertToVirtualBaseInstruction() {
|
||||
opcode instanceof Opcode::ConvertToVirtualBase
|
||||
getOpcode() instanceof Opcode::ConvertToVirtualBase
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1044,37 +1027,37 @@ class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction {
|
||||
*/
|
||||
class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
|
||||
ConvertToDerivedInstruction() {
|
||||
opcode instanceof Opcode::ConvertToDerived
|
||||
getOpcode() instanceof Opcode::ConvertToDerived
|
||||
}
|
||||
}
|
||||
|
||||
class BitComplementInstruction extends UnaryInstruction {
|
||||
BitComplementInstruction() {
|
||||
opcode instanceof Opcode::BitComplement
|
||||
getOpcode() instanceof Opcode::BitComplement
|
||||
}
|
||||
}
|
||||
|
||||
class LogicalNotInstruction extends UnaryInstruction {
|
||||
LogicalNotInstruction() {
|
||||
opcode instanceof Opcode::LogicalNot
|
||||
getOpcode() instanceof Opcode::LogicalNot
|
||||
}
|
||||
}
|
||||
|
||||
class CompareInstruction extends BinaryInstruction {
|
||||
CompareInstruction() {
|
||||
opcode instanceof CompareOpcode
|
||||
getOpcode() instanceof CompareOpcode
|
||||
}
|
||||
}
|
||||
|
||||
class CompareEQInstruction extends CompareInstruction {
|
||||
CompareEQInstruction() {
|
||||
opcode instanceof Opcode::CompareEQ
|
||||
getOpcode() instanceof Opcode::CompareEQ
|
||||
}
|
||||
}
|
||||
|
||||
class CompareNEInstruction extends CompareInstruction {
|
||||
CompareNEInstruction() {
|
||||
opcode instanceof Opcode::CompareNE
|
||||
getOpcode() instanceof Opcode::CompareNE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1083,7 +1066,7 @@ class CompareNEInstruction extends CompareInstruction {
|
||||
*/
|
||||
class RelationalInstruction extends CompareInstruction {
|
||||
RelationalInstruction() {
|
||||
opcode instanceof RelationalOpcode
|
||||
getOpcode() instanceof RelationalOpcode
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1116,7 +1099,7 @@ class RelationalInstruction extends CompareInstruction {
|
||||
|
||||
class CompareLTInstruction extends RelationalInstruction {
|
||||
CompareLTInstruction() {
|
||||
opcode instanceof Opcode::CompareLT
|
||||
getOpcode() instanceof Opcode::CompareLT
|
||||
}
|
||||
|
||||
override Instruction getLesserOperand() {
|
||||
@@ -1134,7 +1117,7 @@ class CompareLTInstruction extends RelationalInstruction {
|
||||
|
||||
class CompareGTInstruction extends RelationalInstruction {
|
||||
CompareGTInstruction() {
|
||||
opcode instanceof Opcode::CompareGT
|
||||
getOpcode() instanceof Opcode::CompareGT
|
||||
}
|
||||
|
||||
override Instruction getLesserOperand() {
|
||||
@@ -1152,7 +1135,7 @@ class CompareGTInstruction extends RelationalInstruction {
|
||||
|
||||
class CompareLEInstruction extends RelationalInstruction {
|
||||
CompareLEInstruction() {
|
||||
opcode instanceof Opcode::CompareLE
|
||||
getOpcode() instanceof Opcode::CompareLE
|
||||
}
|
||||
|
||||
override Instruction getLesserOperand() {
|
||||
@@ -1170,7 +1153,7 @@ class CompareLEInstruction extends RelationalInstruction {
|
||||
|
||||
class CompareGEInstruction extends RelationalInstruction {
|
||||
CompareGEInstruction() {
|
||||
opcode instanceof Opcode::CompareGE
|
||||
getOpcode() instanceof Opcode::CompareGE
|
||||
}
|
||||
|
||||
override Instruction getLesserOperand() {
|
||||
@@ -1188,7 +1171,7 @@ class CompareGEInstruction extends RelationalInstruction {
|
||||
|
||||
class SwitchInstruction extends Instruction {
|
||||
SwitchInstruction() {
|
||||
opcode instanceof Opcode::Switch
|
||||
getOpcode() instanceof Opcode::Switch
|
||||
}
|
||||
|
||||
final Instruction getExpression() {
|
||||
@@ -1211,7 +1194,7 @@ class SwitchInstruction extends Instruction {
|
||||
*/
|
||||
class CallInstruction extends Instruction {
|
||||
CallInstruction() {
|
||||
opcode instanceof Opcode::Call
|
||||
getOpcode() instanceof Opcode::Call
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1254,7 +1237,7 @@ class CallInstruction extends Instruction {
|
||||
*/
|
||||
class SideEffectInstruction extends Instruction {
|
||||
SideEffectInstruction() {
|
||||
opcode instanceof SideEffectOpcode
|
||||
getOpcode() instanceof SideEffectOpcode
|
||||
}
|
||||
|
||||
final Instruction getPrimaryInstruction() {
|
||||
@@ -1268,7 +1251,7 @@ class SideEffectInstruction extends Instruction {
|
||||
*/
|
||||
class CallSideEffectInstruction extends SideEffectInstruction {
|
||||
CallSideEffectInstruction() {
|
||||
opcode instanceof Opcode::CallSideEffect
|
||||
getOpcode() instanceof Opcode::CallSideEffect
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1282,7 +1265,7 @@ class CallSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||
CallReadSideEffectInstruction() {
|
||||
opcode instanceof Opcode::CallReadSideEffect
|
||||
getOpcode() instanceof Opcode::CallReadSideEffect
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1291,7 +1274,7 @@ class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class IndirectReadSideEffectInstruction extends SideEffectInstruction {
|
||||
IndirectReadSideEffectInstruction() {
|
||||
opcode instanceof Opcode::IndirectReadSideEffect
|
||||
getOpcode() instanceof Opcode::IndirectReadSideEffect
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1300,7 +1283,7 @@ class IndirectReadSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class BufferReadSideEffectInstruction extends SideEffectInstruction {
|
||||
BufferReadSideEffectInstruction() {
|
||||
opcode instanceof Opcode::BufferReadSideEffect
|
||||
getOpcode() instanceof Opcode::BufferReadSideEffect
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1309,7 +1292,7 @@ class BufferReadSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class IndirectWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
IndirectWriteSideEffectInstruction() {
|
||||
opcode instanceof Opcode::IndirectWriteSideEffect
|
||||
getOpcode() instanceof Opcode::IndirectWriteSideEffect
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1323,7 +1306,7 @@ class IndirectWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class BufferWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
BufferWriteSideEffectInstruction() {
|
||||
opcode instanceof Opcode::BufferWriteSideEffect
|
||||
getOpcode() instanceof Opcode::BufferWriteSideEffect
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1338,7 +1321,7 @@ class BufferWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class IndirectMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
IndirectMayWriteSideEffectInstruction() {
|
||||
opcode instanceof Opcode::IndirectMayWriteSideEffect
|
||||
getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1352,7 +1335,7 @@ class IndirectMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
BufferMayWriteSideEffectInstruction() {
|
||||
opcode instanceof Opcode::BufferMayWriteSideEffect
|
||||
getOpcode() instanceof Opcode::BufferMayWriteSideEffect
|
||||
}
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
result instanceof BufferMayMemoryAccess
|
||||
@@ -1364,7 +1347,7 @@ class BufferMayWriteSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class ThrowInstruction extends Instruction {
|
||||
ThrowInstruction() {
|
||||
opcode instanceof ThrowOpcode
|
||||
getOpcode() instanceof ThrowOpcode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1373,7 +1356,7 @@ class ThrowInstruction extends Instruction {
|
||||
*/
|
||||
class ThrowValueInstruction extends ThrowInstruction {
|
||||
ThrowValueInstruction() {
|
||||
opcode instanceof Opcode::ThrowValue
|
||||
getOpcode() instanceof Opcode::ThrowValue
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1396,7 +1379,7 @@ class ThrowValueInstruction extends ThrowInstruction {
|
||||
*/
|
||||
class ReThrowInstruction extends ThrowInstruction {
|
||||
ReThrowInstruction() {
|
||||
opcode instanceof Opcode::ReThrow
|
||||
getOpcode() instanceof Opcode::ReThrow
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1405,7 +1388,7 @@ class ReThrowInstruction extends ThrowInstruction {
|
||||
*/
|
||||
class UnwindInstruction extends Instruction {
|
||||
UnwindInstruction() {
|
||||
opcode instanceof Opcode::Unwind
|
||||
getOpcode() instanceof Opcode::Unwind
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1414,7 +1397,7 @@ class UnwindInstruction extends Instruction {
|
||||
*/
|
||||
class CatchInstruction extends Instruction {
|
||||
CatchInstruction() {
|
||||
opcode instanceof CatchOpcode
|
||||
getOpcode() instanceof CatchOpcode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1425,7 +1408,7 @@ class CatchByTypeInstruction extends CatchInstruction {
|
||||
Type exceptionType;
|
||||
|
||||
CatchByTypeInstruction() {
|
||||
opcode instanceof Opcode::CatchByType and
|
||||
getOpcode() instanceof Opcode::CatchByType and
|
||||
exceptionType = Construction::getInstructionExceptionType(this)
|
||||
}
|
||||
|
||||
@@ -1446,13 +1429,13 @@ class CatchByTypeInstruction extends CatchInstruction {
|
||||
*/
|
||||
class CatchAnyInstruction extends CatchInstruction {
|
||||
CatchAnyInstruction() {
|
||||
opcode instanceof Opcode::CatchAny
|
||||
getOpcode() instanceof Opcode::CatchAny
|
||||
}
|
||||
}
|
||||
|
||||
class UnmodeledDefinitionInstruction extends Instruction {
|
||||
UnmodeledDefinitionInstruction() {
|
||||
opcode instanceof Opcode::UnmodeledDefinition
|
||||
getOpcode() instanceof Opcode::UnmodeledDefinition
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1465,7 +1448,7 @@ class UnmodeledDefinitionInstruction extends Instruction {
|
||||
*/
|
||||
class AliasedDefinitionInstruction extends Instruction {
|
||||
AliasedDefinitionInstruction() {
|
||||
opcode instanceof Opcode::AliasedDefinition
|
||||
getOpcode() instanceof Opcode::AliasedDefinition
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1475,7 +1458,7 @@ class AliasedDefinitionInstruction extends Instruction {
|
||||
|
||||
class UnmodeledUseInstruction extends Instruction {
|
||||
UnmodeledUseInstruction() {
|
||||
opcode instanceof Opcode::UnmodeledUse
|
||||
getOpcode() instanceof Opcode::UnmodeledUse
|
||||
}
|
||||
|
||||
override string getOperandsString() {
|
||||
@@ -1495,7 +1478,7 @@ class UnmodeledUseInstruction extends Instruction {
|
||||
*/
|
||||
class PhiInstruction extends Instruction {
|
||||
PhiInstruction() {
|
||||
opcode instanceof Opcode::Phi
|
||||
getOpcode() instanceof Opcode::Phi
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1547,7 +1530,7 @@ class PhiInstruction extends Instruction {
|
||||
*/
|
||||
class ChiInstruction extends Instruction {
|
||||
ChiInstruction() {
|
||||
opcode instanceof Opcode::Chi
|
||||
getOpcode() instanceof Opcode::Chi
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getResultMemoryAccess() {
|
||||
@@ -1577,7 +1560,7 @@ class ChiInstruction extends Instruction {
|
||||
*/
|
||||
class UnreachedInstruction extends Instruction {
|
||||
UnreachedInstruction() {
|
||||
opcode instanceof Opcode::Unreached
|
||||
getOpcode() instanceof Opcode::Unreached
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1587,6 +1570,6 @@ class UnreachedInstruction extends Instruction {
|
||||
*/
|
||||
class BuiltInInstruction extends Instruction {
|
||||
BuiltInInstruction() {
|
||||
opcode instanceof BuiltInOpcode
|
||||
getOpcode() instanceof BuiltInOpcode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,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
|
||||
@@ -40,7 +21,7 @@ cached private module Cached {
|
||||
}
|
||||
|
||||
cached OldInstruction getOldInstruction(Instruction instr) {
|
||||
instr.getTag() = WrappedInstructionTag(result)
|
||||
instr = WrappedInstruction(result)
|
||||
}
|
||||
|
||||
private Instruction getNewInstruction(OldInstruction instr) {
|
||||
@@ -52,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
|
||||
(
|
||||
@@ -88,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 |
|
||||
@@ -169,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 (
|
||||
@@ -189,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 |
|
||||
@@ -208,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
|
||||
@@ -230,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())
|
||||
)
|
||||
}
|
||||
@@ -257,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))
|
||||
@@ -273,7 +210,7 @@ cached private module Cached {
|
||||
)
|
||||
) or
|
||||
exists(OldInstruction oldInstruction |
|
||||
instruction = getChiInstruction(oldInstruction) and
|
||||
instruction = Chi(oldInstruction) and
|
||||
result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||
)
|
||||
)
|
||||
@@ -291,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())
|
||||
}
|
||||
@@ -346,7 +360,7 @@ cached private module Cached {
|
||||
)
|
||||
or
|
||||
exists(OldIR::Instruction oldInstruction |
|
||||
instruction.getTag() = ChiTag(oldInstruction) and
|
||||
instruction = Chi(oldInstruction) and
|
||||
result = getNewInstruction(oldInstruction)
|
||||
)
|
||||
}
|
||||
@@ -541,11 +555,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"
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user