mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
C++: Rationalize RegisterOperand vs. MemoryOperand
This change does some shuffling to make the distinction between memory operands and register operands more clear in the IR API. First, any given type that extends `Operand` is now either always a `MemoryOperand` or always a `RegisterOperand`. This required getting rid of `CopySourceOperand`, which was used for both the `CopyValue` instruction (as a `RegisterOperand`) and for the `Load` instruction (as a `MemoryOperand`). `CopyValue` is now just a `UnaryInstruction`, `Store` has a `StoreValueOperand` (`RegisterOperand`), and all of the instructions that read a value from memory indirectly (`Load`, `ReturnValue`, and `ThrowValue`) all now have a `LoadOperand` (`MemoryOperand`). There are no diffs in the IR output for this commit, but this change is required for a subsequent commit that will make each `MemoryOperand` have a `Type`, which in turn is needed to fix a critical bug in aliased SSA construction.
This commit is contained in:
@@ -105,6 +105,11 @@ abstract class BuiltInOpcode extends Opcode {}
|
||||
|
||||
abstract class SideEffectOpcode extends Opcode {}
|
||||
|
||||
/**
|
||||
* An opcode that reads a value from memory.
|
||||
*/
|
||||
abstract class OpcodeWithLoad extends MemoryAccessOpcode {}
|
||||
|
||||
/**
|
||||
* An opcode that reads from a set of memory locations as a side effect.
|
||||
*/
|
||||
@@ -133,10 +138,10 @@ module Opcode {
|
||||
class InitializeThis extends Opcode, TInitializeThis { override final string toString() { result = "InitializeThis" } }
|
||||
class EnterFunction extends Opcode, TEnterFunction { override final string toString() { result = "EnterFunction" } }
|
||||
class ExitFunction extends Opcode, TExitFunction { override final string toString() { result = "ExitFunction" } }
|
||||
class ReturnValue extends ReturnOpcode, MemoryAccessOpcode, TReturnValue { override final string toString() { result = "ReturnValue" } }
|
||||
class ReturnValue extends ReturnOpcode, OpcodeWithLoad, TReturnValue { override final string toString() { result = "ReturnValue" } }
|
||||
class ReturnVoid extends ReturnOpcode, TReturnVoid { override final string toString() { result = "ReturnVoid" } }
|
||||
class CopyValue extends CopyOpcode, TCopyValue { override final string toString() { result = "CopyValue" } }
|
||||
class Load extends CopyOpcode, MemoryAccessOpcode, TLoad { override final string toString() { result = "Load" } }
|
||||
class CopyValue extends UnaryOpcode, CopyOpcode, TCopyValue { override final string toString() { result = "CopyValue" } }
|
||||
class Load extends CopyOpcode, OpcodeWithLoad, TLoad { override final string toString() { result = "Load" } }
|
||||
class Store extends CopyOpcode, MemoryAccessOpcode, TStore { override final string toString() { result = "Store" } }
|
||||
class Add extends BinaryOpcode, TAdd { override final string toString() { result = "Add" } }
|
||||
class Sub extends BinaryOpcode, TSub { override final string toString() { result = "Sub" } }
|
||||
@@ -177,7 +182,7 @@ module Opcode {
|
||||
class Call extends Opcode, TCall { override final string toString() { result = "Call" } }
|
||||
class CatchByType extends CatchOpcode, TCatchByType { override final string toString() { result = "CatchByType" } }
|
||||
class CatchAny extends CatchOpcode, TCatchAny { override final string toString() { result = "CatchAny" } }
|
||||
class ThrowValue extends ThrowOpcode, MemoryAccessOpcode, TThrowValue { override final string toString() { result = "ThrowValue" } }
|
||||
class ThrowValue extends ThrowOpcode, OpcodeWithLoad, TThrowValue { override final string toString() { result = "ThrowValue" } }
|
||||
class ReThrow extends ThrowOpcode, TReThrow { override final string toString() { result = "ReThrow" } }
|
||||
class Unwind extends Opcode, TUnwind { override final string toString() { result = "Unwind" } }
|
||||
class UnmodeledDefinition extends Opcode, TUnmodeledDefinition { override final string toString() { result = "UnmodeledDefinition" } }
|
||||
|
||||
@@ -29,12 +29,11 @@ module InstructionSanity {
|
||||
tag instanceof RightOperandTag
|
||||
)
|
||||
) or
|
||||
opcode instanceof CopyOpcode and tag instanceof CopySourceOperandTag or
|
||||
opcode instanceof MemoryAccessOpcode and tag instanceof AddressOperandTag or
|
||||
opcode instanceof BufferAccessOpcode and tag instanceof BufferSizeOperand or
|
||||
opcode instanceof OpcodeWithCondition and tag instanceof ConditionOperandTag or
|
||||
opcode instanceof Opcode::ReturnValue and tag instanceof ReturnValueOperandTag or
|
||||
opcode instanceof Opcode::ThrowValue and tag instanceof ExceptionOperandTag or
|
||||
opcode instanceof OpcodeWithLoad and tag instanceof LoadOperandTag or
|
||||
opcode instanceof Opcode::Store and tag instanceof StoreValueOperandTag or
|
||||
opcode instanceof Opcode::UnmodeledUse and tag instanceof UnmodeledUseOperandTag or
|
||||
opcode instanceof Opcode::Call and tag instanceof CallTargetOperandTag or
|
||||
opcode instanceof Opcode::Chi and tag instanceof ChiTotalOperandTag or
|
||||
@@ -714,7 +713,7 @@ class ReturnValueInstruction extends ReturnInstruction {
|
||||
getOpcode() instanceof Opcode::ReturnValue
|
||||
}
|
||||
|
||||
final ReturnValueOperand getReturnValueOperand() {
|
||||
final LoadOperand getReturnValueOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
|
||||
@@ -728,19 +727,23 @@ class CopyInstruction extends Instruction {
|
||||
getOpcode() instanceof CopyOpcode
|
||||
}
|
||||
|
||||
final CopySourceOperand getSourceValueOperand() {
|
||||
result = getAnOperand()
|
||||
Operand getSourceValueOperand() {
|
||||
none()
|
||||
}
|
||||
|
||||
|
||||
final Instruction getSourceValue() {
|
||||
result = getSourceValueOperand().getDefinitionInstruction()
|
||||
}
|
||||
}
|
||||
|
||||
class CopyValueInstruction extends CopyInstruction {
|
||||
class CopyValueInstruction extends CopyInstruction, UnaryInstruction {
|
||||
CopyValueInstruction() {
|
||||
getOpcode() instanceof Opcode::CopyValue
|
||||
}
|
||||
|
||||
override final UnaryOperand getSourceValueOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
}
|
||||
|
||||
class LoadInstruction extends CopyInstruction {
|
||||
@@ -755,6 +758,10 @@ class LoadInstruction extends CopyInstruction {
|
||||
final Instruction getSourceAddress() {
|
||||
result = getSourceAddressOperand().getDefinitionInstruction()
|
||||
}
|
||||
|
||||
override final LoadOperand getSourceValueOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
}
|
||||
|
||||
class StoreInstruction extends CopyInstruction {
|
||||
@@ -773,6 +780,10 @@ class StoreInstruction extends CopyInstruction {
|
||||
final Instruction getDestinationAddress() {
|
||||
result = getDestinationAddressOperand().getDefinitionInstruction()
|
||||
}
|
||||
|
||||
override final StoreValueOperand getSourceValueOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
}
|
||||
|
||||
class ConditionalBranchInstruction extends Instruction {
|
||||
@@ -1442,7 +1453,7 @@ class ThrowValueInstruction extends ThrowInstruction {
|
||||
/**
|
||||
* Gets the operand for the exception thrown by this instruction.
|
||||
*/
|
||||
final ExceptionOperand getExceptionOperand() {
|
||||
final LoadOperand getExceptionOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
|
||||
|
||||
@@ -63,9 +63,21 @@ class Operand extends TOperand {
|
||||
int getDumpSortOrder() {
|
||||
result = -1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that consumes a memory result (e.g. the `LoadOperand` on a `Load` instruction).
|
||||
*/
|
||||
class MemoryOperand extends Operand {
|
||||
MemoryOperand() {
|
||||
exists(MemoryOperandTag tag |
|
||||
this = TNonPhiOperand(_, tag, _)
|
||||
) or
|
||||
this = TPhiOperand(_, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the kind of memory access performed by the operand. Holds only for memory operands.
|
||||
* Gets the kind of memory access performed by the operand.
|
||||
*/
|
||||
MemoryAccessKind getMemoryAccess() {
|
||||
none()
|
||||
@@ -82,6 +94,17 @@ class Operand extends TOperand {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that consumes a register (non-memory) result.
|
||||
*/
|
||||
class RegisterOperand extends Operand {
|
||||
RegisterOperand() {
|
||||
exists(RegisterOperandTag tag |
|
||||
this = TNonPhiOperand(_, tag, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that is not an operand of a `PhiInstruction`.
|
||||
*/
|
||||
@@ -119,7 +142,7 @@ class NonPhiOperand extends Operand, TNonPhiOperand {
|
||||
* The address operand of an instruction that loads or stores a value from
|
||||
* memory (e.g. `Load`, `Store`).
|
||||
*/
|
||||
class AddressOperand extends NonPhiOperand {
|
||||
class AddressOperand extends NonPhiOperand, RegisterOperand {
|
||||
AddressOperand() {
|
||||
this = TNonPhiOperand(_, addressOperand(), _)
|
||||
}
|
||||
@@ -130,28 +153,40 @@ class AddressOperand extends NonPhiOperand {
|
||||
}
|
||||
|
||||
/**
|
||||
* The source value operand of an instruction that copies this value to its
|
||||
* result (e.g. `Copy`, `Load`, `Store`).
|
||||
* The source value operand of an instruction that loads a value from memory (e.g. `Load`,
|
||||
* `ReturnValue`, `ThrowValue`).
|
||||
*/
|
||||
class CopySourceOperand extends NonPhiOperand {
|
||||
CopySourceOperand() {
|
||||
this = TNonPhiOperand(_, copySourceOperand(), _)
|
||||
class LoadOperand extends NonPhiOperand, MemoryOperand {
|
||||
LoadOperand() {
|
||||
this = TNonPhiOperand(_, loadOperand(), _)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "CopySource"
|
||||
result = "Load"
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getMemoryAccess() {
|
||||
instr.getOpcode() instanceof Opcode::Load and
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The sole operand of a unary instruction (e.g. `Convert`, `Negate`).
|
||||
* The source value operand of a `Store` instruction.
|
||||
*/
|
||||
class UnaryOperand extends NonPhiOperand {
|
||||
class StoreValueOperand extends NonPhiOperand, RegisterOperand {
|
||||
StoreValueOperand() {
|
||||
this = TNonPhiOperand(_, storeValueOperand(), _)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "StoreValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The sole operand of a unary instruction (e.g. `Convert`, `Negate`, `Copy`).
|
||||
*/
|
||||
class UnaryOperand extends NonPhiOperand, RegisterOperand {
|
||||
UnaryOperand() {
|
||||
this = TNonPhiOperand(_, unaryOperand(), _)
|
||||
}
|
||||
@@ -164,7 +199,7 @@ class UnaryOperand extends NonPhiOperand {
|
||||
/**
|
||||
* The left operand of a binary instruction (e.g. `Add`, `CompareEQ`).
|
||||
*/
|
||||
class LeftOperand extends NonPhiOperand {
|
||||
class LeftOperand extends NonPhiOperand, RegisterOperand {
|
||||
LeftOperand() {
|
||||
this = TNonPhiOperand(_, leftOperand(), _)
|
||||
}
|
||||
@@ -177,7 +212,7 @@ class LeftOperand extends NonPhiOperand {
|
||||
/**
|
||||
* The right operand of a binary instruction (e.g. `Add`, `CompareEQ`).
|
||||
*/
|
||||
class RightOperand extends NonPhiOperand {
|
||||
class RightOperand extends NonPhiOperand, RegisterOperand {
|
||||
RightOperand() {
|
||||
this = TNonPhiOperand(_, rightOperand(), _)
|
||||
}
|
||||
@@ -187,44 +222,10 @@ class RightOperand extends NonPhiOperand {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The return value operand of a `ReturnValue` instruction.
|
||||
*/
|
||||
class ReturnValueOperand extends NonPhiOperand {
|
||||
ReturnValueOperand() {
|
||||
this = TNonPhiOperand(_, returnValueOperand(), _)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "ReturnValue"
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getMemoryAccess() {
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The exception thrown by a `ThrowValue` instruction.
|
||||
*/
|
||||
class ExceptionOperand extends NonPhiOperand {
|
||||
ExceptionOperand() {
|
||||
this = TNonPhiOperand(_, exceptionOperand(), _)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "Exception"
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getMemoryAccess() {
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The condition operand of a `ConditionalBranch` or `Switch` instruction.
|
||||
*/
|
||||
class ConditionOperand extends NonPhiOperand {
|
||||
class ConditionOperand extends NonPhiOperand, RegisterOperand {
|
||||
ConditionOperand() {
|
||||
this = TNonPhiOperand(_, conditionOperand(), _)
|
||||
}
|
||||
@@ -238,7 +239,7 @@ class ConditionOperand extends NonPhiOperand {
|
||||
* An operand of the special `UnmodeledUse` instruction, representing a value
|
||||
* whose set of uses is unknown.
|
||||
*/
|
||||
class UnmodeledUseOperand extends NonPhiOperand {
|
||||
class UnmodeledUseOperand extends NonPhiOperand, MemoryOperand {
|
||||
UnmodeledUseOperand() {
|
||||
this = TNonPhiOperand(_, unmodeledUseOperand(), _)
|
||||
}
|
||||
@@ -255,7 +256,7 @@ class UnmodeledUseOperand extends NonPhiOperand {
|
||||
/**
|
||||
* The operand representing the target function of an `Call` instruction.
|
||||
*/
|
||||
class CallTargetOperand extends NonPhiOperand {
|
||||
class CallTargetOperand extends NonPhiOperand, RegisterOperand {
|
||||
CallTargetOperand() {
|
||||
this = TNonPhiOperand(_, callTargetOperand(), _)
|
||||
}
|
||||
@@ -270,7 +271,7 @@ class CallTargetOperand extends NonPhiOperand {
|
||||
* positional arguments (represented by `PositionalArgumentOperand`) and the
|
||||
* implicit `this` argument, if any (represented by `ThisArgumentOperand`).
|
||||
*/
|
||||
class ArgumentOperand extends NonPhiOperand {
|
||||
class ArgumentOperand extends NonPhiOperand, RegisterOperand {
|
||||
ArgumentOperand() {
|
||||
exists(ArgumentOperandTag argTag |
|
||||
this = TNonPhiOperand(_, argTag, _)
|
||||
@@ -317,7 +318,7 @@ class PositionalArgumentOperand extends ArgumentOperand {
|
||||
}
|
||||
}
|
||||
|
||||
class SideEffectOperand extends NonPhiOperand {
|
||||
class SideEffectOperand extends NonPhiOperand, MemoryOperand {
|
||||
SideEffectOperand() {
|
||||
this = TNonPhiOperand(_, sideEffectOperand(), _)
|
||||
}
|
||||
@@ -352,7 +353,7 @@ class SideEffectOperand extends NonPhiOperand {
|
||||
/**
|
||||
* An operand of a `PhiInstruction`.
|
||||
*/
|
||||
class PhiOperand extends Operand, TPhiOperand {
|
||||
class PhiOperand extends MemoryOperand, TPhiOperand {
|
||||
PhiInstruction useInstr;
|
||||
Instruction defInstr;
|
||||
IRBlock predecessorBlock;
|
||||
@@ -393,19 +394,10 @@ class PhiOperand extends Operand, TPhiOperand {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that reads a value from memory.
|
||||
*/
|
||||
class MemoryOperand extends Operand {
|
||||
MemoryOperand() {
|
||||
exists(getMemoryAccess())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The total operand of a Chi node, representing the previous value of the memory.
|
||||
*/
|
||||
class ChiTotalOperand extends Operand {
|
||||
class ChiTotalOperand extends MemoryOperand {
|
||||
ChiTotalOperand() {
|
||||
this = TNonPhiOperand(_, chiTotalOperand(), _)
|
||||
}
|
||||
@@ -423,7 +415,7 @@ class ChiTotalOperand extends Operand {
|
||||
/**
|
||||
* The partial operand of a Chi node, representing the value being written to part of the memory.
|
||||
*/
|
||||
class ChiPartialOperand extends Operand {
|
||||
class ChiPartialOperand extends MemoryOperand {
|
||||
ChiPartialOperand() {
|
||||
this = TNonPhiOperand(_, chiPartialOperand(), _)
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
|
||||
// offset of the field.
|
||||
bitOffset = getFieldBitOffset(instr.(FieldAddressInstruction).getField()) or
|
||||
// A copy propagates the source value.
|
||||
operand instanceof CopySourceOperand and bitOffset = 0
|
||||
operand = instr.(CopyInstruction).getSourceValueOperand() and bitOffset = 0
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -263,8 +263,7 @@ MemoryAccess getResultMemoryAccess(Instruction instr) {
|
||||
)
|
||||
}
|
||||
|
||||
MemoryAccess getOperandMemoryAccess(Operand operand) {
|
||||
exists(operand.getMemoryAccess()) and
|
||||
MemoryAccess getOperandMemoryAccess(MemoryOperand operand) {
|
||||
if exists(IRVariable var, IntValue i |
|
||||
resultPointsTo(operand.getAddressOperand().getDefinitionInstruction(), var, i)
|
||||
)
|
||||
|
||||
@@ -29,12 +29,11 @@ module InstructionSanity {
|
||||
tag instanceof RightOperandTag
|
||||
)
|
||||
) or
|
||||
opcode instanceof CopyOpcode and tag instanceof CopySourceOperandTag or
|
||||
opcode instanceof MemoryAccessOpcode and tag instanceof AddressOperandTag or
|
||||
opcode instanceof BufferAccessOpcode and tag instanceof BufferSizeOperand or
|
||||
opcode instanceof OpcodeWithCondition and tag instanceof ConditionOperandTag or
|
||||
opcode instanceof Opcode::ReturnValue and tag instanceof ReturnValueOperandTag or
|
||||
opcode instanceof Opcode::ThrowValue and tag instanceof ExceptionOperandTag or
|
||||
opcode instanceof OpcodeWithLoad and tag instanceof LoadOperandTag or
|
||||
opcode instanceof Opcode::Store and tag instanceof StoreValueOperandTag or
|
||||
opcode instanceof Opcode::UnmodeledUse and tag instanceof UnmodeledUseOperandTag or
|
||||
opcode instanceof Opcode::Call and tag instanceof CallTargetOperandTag or
|
||||
opcode instanceof Opcode::Chi and tag instanceof ChiTotalOperandTag or
|
||||
@@ -714,7 +713,7 @@ class ReturnValueInstruction extends ReturnInstruction {
|
||||
getOpcode() instanceof Opcode::ReturnValue
|
||||
}
|
||||
|
||||
final ReturnValueOperand getReturnValueOperand() {
|
||||
final LoadOperand getReturnValueOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
|
||||
@@ -728,19 +727,23 @@ class CopyInstruction extends Instruction {
|
||||
getOpcode() instanceof CopyOpcode
|
||||
}
|
||||
|
||||
final CopySourceOperand getSourceValueOperand() {
|
||||
result = getAnOperand()
|
||||
Operand getSourceValueOperand() {
|
||||
none()
|
||||
}
|
||||
|
||||
|
||||
final Instruction getSourceValue() {
|
||||
result = getSourceValueOperand().getDefinitionInstruction()
|
||||
}
|
||||
}
|
||||
|
||||
class CopyValueInstruction extends CopyInstruction {
|
||||
class CopyValueInstruction extends CopyInstruction, UnaryInstruction {
|
||||
CopyValueInstruction() {
|
||||
getOpcode() instanceof Opcode::CopyValue
|
||||
}
|
||||
|
||||
override final UnaryOperand getSourceValueOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
}
|
||||
|
||||
class LoadInstruction extends CopyInstruction {
|
||||
@@ -755,6 +758,10 @@ class LoadInstruction extends CopyInstruction {
|
||||
final Instruction getSourceAddress() {
|
||||
result = getSourceAddressOperand().getDefinitionInstruction()
|
||||
}
|
||||
|
||||
override final LoadOperand getSourceValueOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
}
|
||||
|
||||
class StoreInstruction extends CopyInstruction {
|
||||
@@ -773,6 +780,10 @@ class StoreInstruction extends CopyInstruction {
|
||||
final Instruction getDestinationAddress() {
|
||||
result = getDestinationAddressOperand().getDefinitionInstruction()
|
||||
}
|
||||
|
||||
override final StoreValueOperand getSourceValueOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
}
|
||||
|
||||
class ConditionalBranchInstruction extends Instruction {
|
||||
@@ -1442,7 +1453,7 @@ class ThrowValueInstruction extends ThrowInstruction {
|
||||
/**
|
||||
* Gets the operand for the exception thrown by this instruction.
|
||||
*/
|
||||
final ExceptionOperand getExceptionOperand() {
|
||||
final LoadOperand getExceptionOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
|
||||
|
||||
@@ -63,9 +63,21 @@ class Operand extends TOperand {
|
||||
int getDumpSortOrder() {
|
||||
result = -1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that consumes a memory result (e.g. the `LoadOperand` on a `Load` instruction).
|
||||
*/
|
||||
class MemoryOperand extends Operand {
|
||||
MemoryOperand() {
|
||||
exists(MemoryOperandTag tag |
|
||||
this = TNonPhiOperand(_, tag, _)
|
||||
) or
|
||||
this = TPhiOperand(_, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the kind of memory access performed by the operand. Holds only for memory operands.
|
||||
* Gets the kind of memory access performed by the operand.
|
||||
*/
|
||||
MemoryAccessKind getMemoryAccess() {
|
||||
none()
|
||||
@@ -82,6 +94,17 @@ class Operand extends TOperand {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that consumes a register (non-memory) result.
|
||||
*/
|
||||
class RegisterOperand extends Operand {
|
||||
RegisterOperand() {
|
||||
exists(RegisterOperandTag tag |
|
||||
this = TNonPhiOperand(_, tag, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that is not an operand of a `PhiInstruction`.
|
||||
*/
|
||||
@@ -119,7 +142,7 @@ class NonPhiOperand extends Operand, TNonPhiOperand {
|
||||
* The address operand of an instruction that loads or stores a value from
|
||||
* memory (e.g. `Load`, `Store`).
|
||||
*/
|
||||
class AddressOperand extends NonPhiOperand {
|
||||
class AddressOperand extends NonPhiOperand, RegisterOperand {
|
||||
AddressOperand() {
|
||||
this = TNonPhiOperand(_, addressOperand(), _)
|
||||
}
|
||||
@@ -130,28 +153,40 @@ class AddressOperand extends NonPhiOperand {
|
||||
}
|
||||
|
||||
/**
|
||||
* The source value operand of an instruction that copies this value to its
|
||||
* result (e.g. `Copy`, `Load`, `Store`).
|
||||
* The source value operand of an instruction that loads a value from memory (e.g. `Load`,
|
||||
* `ReturnValue`, `ThrowValue`).
|
||||
*/
|
||||
class CopySourceOperand extends NonPhiOperand {
|
||||
CopySourceOperand() {
|
||||
this = TNonPhiOperand(_, copySourceOperand(), _)
|
||||
class LoadOperand extends NonPhiOperand, MemoryOperand {
|
||||
LoadOperand() {
|
||||
this = TNonPhiOperand(_, loadOperand(), _)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "CopySource"
|
||||
result = "Load"
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getMemoryAccess() {
|
||||
instr.getOpcode() instanceof Opcode::Load and
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The sole operand of a unary instruction (e.g. `Convert`, `Negate`).
|
||||
* The source value operand of a `Store` instruction.
|
||||
*/
|
||||
class UnaryOperand extends NonPhiOperand {
|
||||
class StoreValueOperand extends NonPhiOperand, RegisterOperand {
|
||||
StoreValueOperand() {
|
||||
this = TNonPhiOperand(_, storeValueOperand(), _)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "StoreValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The sole operand of a unary instruction (e.g. `Convert`, `Negate`, `Copy`).
|
||||
*/
|
||||
class UnaryOperand extends NonPhiOperand, RegisterOperand {
|
||||
UnaryOperand() {
|
||||
this = TNonPhiOperand(_, unaryOperand(), _)
|
||||
}
|
||||
@@ -164,7 +199,7 @@ class UnaryOperand extends NonPhiOperand {
|
||||
/**
|
||||
* The left operand of a binary instruction (e.g. `Add`, `CompareEQ`).
|
||||
*/
|
||||
class LeftOperand extends NonPhiOperand {
|
||||
class LeftOperand extends NonPhiOperand, RegisterOperand {
|
||||
LeftOperand() {
|
||||
this = TNonPhiOperand(_, leftOperand(), _)
|
||||
}
|
||||
@@ -177,7 +212,7 @@ class LeftOperand extends NonPhiOperand {
|
||||
/**
|
||||
* The right operand of a binary instruction (e.g. `Add`, `CompareEQ`).
|
||||
*/
|
||||
class RightOperand extends NonPhiOperand {
|
||||
class RightOperand extends NonPhiOperand, RegisterOperand {
|
||||
RightOperand() {
|
||||
this = TNonPhiOperand(_, rightOperand(), _)
|
||||
}
|
||||
@@ -187,44 +222,10 @@ class RightOperand extends NonPhiOperand {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The return value operand of a `ReturnValue` instruction.
|
||||
*/
|
||||
class ReturnValueOperand extends NonPhiOperand {
|
||||
ReturnValueOperand() {
|
||||
this = TNonPhiOperand(_, returnValueOperand(), _)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "ReturnValue"
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getMemoryAccess() {
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The exception thrown by a `ThrowValue` instruction.
|
||||
*/
|
||||
class ExceptionOperand extends NonPhiOperand {
|
||||
ExceptionOperand() {
|
||||
this = TNonPhiOperand(_, exceptionOperand(), _)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "Exception"
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getMemoryAccess() {
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The condition operand of a `ConditionalBranch` or `Switch` instruction.
|
||||
*/
|
||||
class ConditionOperand extends NonPhiOperand {
|
||||
class ConditionOperand extends NonPhiOperand, RegisterOperand {
|
||||
ConditionOperand() {
|
||||
this = TNonPhiOperand(_, conditionOperand(), _)
|
||||
}
|
||||
@@ -238,7 +239,7 @@ class ConditionOperand extends NonPhiOperand {
|
||||
* An operand of the special `UnmodeledUse` instruction, representing a value
|
||||
* whose set of uses is unknown.
|
||||
*/
|
||||
class UnmodeledUseOperand extends NonPhiOperand {
|
||||
class UnmodeledUseOperand extends NonPhiOperand, MemoryOperand {
|
||||
UnmodeledUseOperand() {
|
||||
this = TNonPhiOperand(_, unmodeledUseOperand(), _)
|
||||
}
|
||||
@@ -255,7 +256,7 @@ class UnmodeledUseOperand extends NonPhiOperand {
|
||||
/**
|
||||
* The operand representing the target function of an `Call` instruction.
|
||||
*/
|
||||
class CallTargetOperand extends NonPhiOperand {
|
||||
class CallTargetOperand extends NonPhiOperand, RegisterOperand {
|
||||
CallTargetOperand() {
|
||||
this = TNonPhiOperand(_, callTargetOperand(), _)
|
||||
}
|
||||
@@ -270,7 +271,7 @@ class CallTargetOperand extends NonPhiOperand {
|
||||
* positional arguments (represented by `PositionalArgumentOperand`) and the
|
||||
* implicit `this` argument, if any (represented by `ThisArgumentOperand`).
|
||||
*/
|
||||
class ArgumentOperand extends NonPhiOperand {
|
||||
class ArgumentOperand extends NonPhiOperand, RegisterOperand {
|
||||
ArgumentOperand() {
|
||||
exists(ArgumentOperandTag argTag |
|
||||
this = TNonPhiOperand(_, argTag, _)
|
||||
@@ -317,7 +318,7 @@ class PositionalArgumentOperand extends ArgumentOperand {
|
||||
}
|
||||
}
|
||||
|
||||
class SideEffectOperand extends NonPhiOperand {
|
||||
class SideEffectOperand extends NonPhiOperand, MemoryOperand {
|
||||
SideEffectOperand() {
|
||||
this = TNonPhiOperand(_, sideEffectOperand(), _)
|
||||
}
|
||||
@@ -352,7 +353,7 @@ class SideEffectOperand extends NonPhiOperand {
|
||||
/**
|
||||
* An operand of a `PhiInstruction`.
|
||||
*/
|
||||
class PhiOperand extends Operand, TPhiOperand {
|
||||
class PhiOperand extends MemoryOperand, TPhiOperand {
|
||||
PhiInstruction useInstr;
|
||||
Instruction defInstr;
|
||||
IRBlock predecessorBlock;
|
||||
@@ -393,19 +394,10 @@ class PhiOperand extends Operand, TPhiOperand {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that reads a value from memory.
|
||||
*/
|
||||
class MemoryOperand extends Operand {
|
||||
MemoryOperand() {
|
||||
exists(getMemoryAccess())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The total operand of a Chi node, representing the previous value of the memory.
|
||||
*/
|
||||
class ChiTotalOperand extends Operand {
|
||||
class ChiTotalOperand extends MemoryOperand {
|
||||
ChiTotalOperand() {
|
||||
this = TNonPhiOperand(_, chiTotalOperand(), _)
|
||||
}
|
||||
@@ -423,7 +415,7 @@ class ChiTotalOperand extends Operand {
|
||||
/**
|
||||
* The partial operand of a Chi node, representing the value being written to part of the memory.
|
||||
*/
|
||||
class ChiPartialOperand extends Operand {
|
||||
class ChiPartialOperand extends MemoryOperand {
|
||||
ChiPartialOperand() {
|
||||
this = TNonPhiOperand(_, chiPartialOperand(), _)
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext,
|
||||
result = getInstruction(ConditionValueTrueTempAddressTag())
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = getInstruction(ConditionValueTrueConstantTag())
|
||||
)
|
||||
)
|
||||
@@ -234,7 +234,7 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext,
|
||||
result = getInstruction(ConditionValueFalseTempAddressTag())
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = getInstruction(ConditionValueFalseConstantTag())
|
||||
)
|
||||
)
|
||||
@@ -247,7 +247,7 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext,
|
||||
result = getInstruction(ConditionValueResultTempAddressTag())
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof LoadOperandTag and
|
||||
result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
|
||||
)
|
||||
)
|
||||
@@ -352,7 +352,7 @@ class TranslatedLoad extends TranslatedExpr, TTranslatedLoad {
|
||||
result = getOperand().getResult()
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof LoadOperandTag and
|
||||
result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
|
||||
)
|
||||
)
|
||||
@@ -482,7 +482,7 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr {
|
||||
result = getOperand().getResult()
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof LoadOperandTag and
|
||||
result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
|
||||
)
|
||||
)
|
||||
@@ -508,7 +508,7 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr {
|
||||
result = getOperand().getResult()
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = getInstruction(CrementOpTag())
|
||||
)
|
||||
)
|
||||
@@ -785,9 +785,9 @@ class TranslatedThisExpr extends TranslatedNonConstantExpr {
|
||||
}
|
||||
|
||||
override final Instruction getInstructionOperand(InstructionTag tag,
|
||||
OperandTag operandTag) {
|
||||
OperandTag operandTag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof UnaryOperandTag and
|
||||
result = getInitializeThisInstruction()
|
||||
}
|
||||
|
||||
@@ -1069,10 +1069,7 @@ class TranslatedUnaryExpr extends TranslatedSingleInstructionExpr {
|
||||
OperandTag operandTag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = getOperand().getResult() and
|
||||
if getOpcode() instanceof Opcode::CopyValue then
|
||||
operandTag instanceof CopySourceOperandTag
|
||||
else
|
||||
operandTag instanceof UnaryOperandTag
|
||||
operandTag instanceof UnaryOperandTag
|
||||
}
|
||||
|
||||
override final Opcode getOpcode() {
|
||||
@@ -1508,7 +1505,7 @@ class TranslatedAssignExpr extends TranslatedAssignment {
|
||||
result = getLeftOperand().getResult()
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = getRightOperand().getResult()
|
||||
)
|
||||
)
|
||||
@@ -1667,7 +1664,7 @@ class TranslatedAssignOperation extends TranslatedAssignment {
|
||||
result = getLeftOperand().getResult()
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof LoadOperandTag and
|
||||
result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
|
||||
)
|
||||
)
|
||||
@@ -1708,7 +1705,7 @@ class TranslatedAssignOperation extends TranslatedAssignment {
|
||||
result = getLeftOperand().getResult()
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = getStoredValue()
|
||||
)
|
||||
)
|
||||
@@ -2107,7 +2104,7 @@ class TranslatedConditionalExpr extends TranslatedNonConstantExpr,
|
||||
result = getInstruction(ConditionValueTrueTempAddressTag())
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = getThen().getResult()
|
||||
)
|
||||
)
|
||||
@@ -2121,7 +2118,7 @@ class TranslatedConditionalExpr extends TranslatedNonConstantExpr,
|
||||
result = getInstruction(ConditionValueFalseTempAddressTag())
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = getElse().getResult()
|
||||
)
|
||||
)
|
||||
@@ -2134,7 +2131,7 @@ class TranslatedConditionalExpr extends TranslatedNonConstantExpr,
|
||||
result = getInstruction(ConditionValueResultTempAddressTag())
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof LoadOperandTag and
|
||||
result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
|
||||
)
|
||||
)
|
||||
@@ -2311,7 +2308,7 @@ class TranslatedThrowValueExpr extends TranslatedThrowExpr,
|
||||
result = getInstruction(InitializerVariableAddressTag())
|
||||
) or
|
||||
(
|
||||
operandTag instanceof ExceptionOperandTag and
|
||||
operandTag instanceof LoadOperandTag and
|
||||
result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
|
||||
)
|
||||
)
|
||||
|
||||
@@ -241,7 +241,7 @@ class TranslatedFunction extends TranslatedElement,
|
||||
result = getInstruction(ReturnValueAddressTag())
|
||||
) or
|
||||
(
|
||||
operandTag instanceof ReturnValueOperandTag and
|
||||
operandTag instanceof LoadOperandTag and
|
||||
result = getUnmodeledDefinitionInstruction()
|
||||
)
|
||||
)
|
||||
|
||||
@@ -210,7 +210,7 @@ class TranslatedSimpleDirectInitialization extends
|
||||
result = getContext().getTargetAddress()
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = getInitializer().getResult()
|
||||
)
|
||||
)
|
||||
@@ -331,7 +331,7 @@ class TranslatedStringLiteralInitialization extends
|
||||
result = getInitializer().getResult()
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof LoadOperandTag and
|
||||
result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
|
||||
)
|
||||
)
|
||||
@@ -344,7 +344,7 @@ class TranslatedStringLiteralInitialization extends
|
||||
result = getContext().getTargetAddress()
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = getInstruction(InitializerLoadStringTag())
|
||||
)
|
||||
)
|
||||
@@ -370,7 +370,7 @@ class TranslatedStringLiteralInitialization extends
|
||||
result = getInstruction(ZeroPadStringElementAddressTag())
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = getInstruction(ZeroPadStringConstantTag())
|
||||
)
|
||||
)
|
||||
@@ -634,7 +634,7 @@ class TranslatedFieldValueInitialization extends
|
||||
result = getInstruction(getFieldAddressTag())
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = getInstruction(getFieldDefaultValueTag())
|
||||
)
|
||||
)
|
||||
@@ -873,7 +873,7 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
|
||||
result = getInstruction(getElementAddressTag())
|
||||
) or
|
||||
(
|
||||
operandTag instanceof CopySourceOperandTag and
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = getInstruction(getElementDefaultValueTag())
|
||||
)
|
||||
)
|
||||
|
||||
@@ -29,12 +29,11 @@ module InstructionSanity {
|
||||
tag instanceof RightOperandTag
|
||||
)
|
||||
) or
|
||||
opcode instanceof CopyOpcode and tag instanceof CopySourceOperandTag or
|
||||
opcode instanceof MemoryAccessOpcode and tag instanceof AddressOperandTag or
|
||||
opcode instanceof BufferAccessOpcode and tag instanceof BufferSizeOperand or
|
||||
opcode instanceof OpcodeWithCondition and tag instanceof ConditionOperandTag or
|
||||
opcode instanceof Opcode::ReturnValue and tag instanceof ReturnValueOperandTag or
|
||||
opcode instanceof Opcode::ThrowValue and tag instanceof ExceptionOperandTag or
|
||||
opcode instanceof OpcodeWithLoad and tag instanceof LoadOperandTag or
|
||||
opcode instanceof Opcode::Store and tag instanceof StoreValueOperandTag or
|
||||
opcode instanceof Opcode::UnmodeledUse and tag instanceof UnmodeledUseOperandTag or
|
||||
opcode instanceof Opcode::Call and tag instanceof CallTargetOperandTag or
|
||||
opcode instanceof Opcode::Chi and tag instanceof ChiTotalOperandTag or
|
||||
@@ -714,7 +713,7 @@ class ReturnValueInstruction extends ReturnInstruction {
|
||||
getOpcode() instanceof Opcode::ReturnValue
|
||||
}
|
||||
|
||||
final ReturnValueOperand getReturnValueOperand() {
|
||||
final LoadOperand getReturnValueOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
|
||||
@@ -728,19 +727,23 @@ class CopyInstruction extends Instruction {
|
||||
getOpcode() instanceof CopyOpcode
|
||||
}
|
||||
|
||||
final CopySourceOperand getSourceValueOperand() {
|
||||
result = getAnOperand()
|
||||
Operand getSourceValueOperand() {
|
||||
none()
|
||||
}
|
||||
|
||||
|
||||
final Instruction getSourceValue() {
|
||||
result = getSourceValueOperand().getDefinitionInstruction()
|
||||
}
|
||||
}
|
||||
|
||||
class CopyValueInstruction extends CopyInstruction {
|
||||
class CopyValueInstruction extends CopyInstruction, UnaryInstruction {
|
||||
CopyValueInstruction() {
|
||||
getOpcode() instanceof Opcode::CopyValue
|
||||
}
|
||||
|
||||
override final UnaryOperand getSourceValueOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
}
|
||||
|
||||
class LoadInstruction extends CopyInstruction {
|
||||
@@ -755,6 +758,10 @@ class LoadInstruction extends CopyInstruction {
|
||||
final Instruction getSourceAddress() {
|
||||
result = getSourceAddressOperand().getDefinitionInstruction()
|
||||
}
|
||||
|
||||
override final LoadOperand getSourceValueOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
}
|
||||
|
||||
class StoreInstruction extends CopyInstruction {
|
||||
@@ -773,6 +780,10 @@ class StoreInstruction extends CopyInstruction {
|
||||
final Instruction getDestinationAddress() {
|
||||
result = getDestinationAddressOperand().getDefinitionInstruction()
|
||||
}
|
||||
|
||||
override final StoreValueOperand getSourceValueOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
}
|
||||
|
||||
class ConditionalBranchInstruction extends Instruction {
|
||||
@@ -1442,7 +1453,7 @@ class ThrowValueInstruction extends ThrowInstruction {
|
||||
/**
|
||||
* Gets the operand for the exception thrown by this instruction.
|
||||
*/
|
||||
final ExceptionOperand getExceptionOperand() {
|
||||
final LoadOperand getExceptionOperand() {
|
||||
result = getAnOperand()
|
||||
}
|
||||
|
||||
|
||||
@@ -63,9 +63,21 @@ class Operand extends TOperand {
|
||||
int getDumpSortOrder() {
|
||||
result = -1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that consumes a memory result (e.g. the `LoadOperand` on a `Load` instruction).
|
||||
*/
|
||||
class MemoryOperand extends Operand {
|
||||
MemoryOperand() {
|
||||
exists(MemoryOperandTag tag |
|
||||
this = TNonPhiOperand(_, tag, _)
|
||||
) or
|
||||
this = TPhiOperand(_, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the kind of memory access performed by the operand. Holds only for memory operands.
|
||||
* Gets the kind of memory access performed by the operand.
|
||||
*/
|
||||
MemoryAccessKind getMemoryAccess() {
|
||||
none()
|
||||
@@ -82,6 +94,17 @@ class Operand extends TOperand {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that consumes a register (non-memory) result.
|
||||
*/
|
||||
class RegisterOperand extends Operand {
|
||||
RegisterOperand() {
|
||||
exists(RegisterOperandTag tag |
|
||||
this = TNonPhiOperand(_, tag, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that is not an operand of a `PhiInstruction`.
|
||||
*/
|
||||
@@ -119,7 +142,7 @@ class NonPhiOperand extends Operand, TNonPhiOperand {
|
||||
* The address operand of an instruction that loads or stores a value from
|
||||
* memory (e.g. `Load`, `Store`).
|
||||
*/
|
||||
class AddressOperand extends NonPhiOperand {
|
||||
class AddressOperand extends NonPhiOperand, RegisterOperand {
|
||||
AddressOperand() {
|
||||
this = TNonPhiOperand(_, addressOperand(), _)
|
||||
}
|
||||
@@ -130,28 +153,40 @@ class AddressOperand extends NonPhiOperand {
|
||||
}
|
||||
|
||||
/**
|
||||
* The source value operand of an instruction that copies this value to its
|
||||
* result (e.g. `Copy`, `Load`, `Store`).
|
||||
* The source value operand of an instruction that loads a value from memory (e.g. `Load`,
|
||||
* `ReturnValue`, `ThrowValue`).
|
||||
*/
|
||||
class CopySourceOperand extends NonPhiOperand {
|
||||
CopySourceOperand() {
|
||||
this = TNonPhiOperand(_, copySourceOperand(), _)
|
||||
class LoadOperand extends NonPhiOperand, MemoryOperand {
|
||||
LoadOperand() {
|
||||
this = TNonPhiOperand(_, loadOperand(), _)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "CopySource"
|
||||
result = "Load"
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getMemoryAccess() {
|
||||
instr.getOpcode() instanceof Opcode::Load and
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The sole operand of a unary instruction (e.g. `Convert`, `Negate`).
|
||||
* The source value operand of a `Store` instruction.
|
||||
*/
|
||||
class UnaryOperand extends NonPhiOperand {
|
||||
class StoreValueOperand extends NonPhiOperand, RegisterOperand {
|
||||
StoreValueOperand() {
|
||||
this = TNonPhiOperand(_, storeValueOperand(), _)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "StoreValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The sole operand of a unary instruction (e.g. `Convert`, `Negate`, `Copy`).
|
||||
*/
|
||||
class UnaryOperand extends NonPhiOperand, RegisterOperand {
|
||||
UnaryOperand() {
|
||||
this = TNonPhiOperand(_, unaryOperand(), _)
|
||||
}
|
||||
@@ -164,7 +199,7 @@ class UnaryOperand extends NonPhiOperand {
|
||||
/**
|
||||
* The left operand of a binary instruction (e.g. `Add`, `CompareEQ`).
|
||||
*/
|
||||
class LeftOperand extends NonPhiOperand {
|
||||
class LeftOperand extends NonPhiOperand, RegisterOperand {
|
||||
LeftOperand() {
|
||||
this = TNonPhiOperand(_, leftOperand(), _)
|
||||
}
|
||||
@@ -177,7 +212,7 @@ class LeftOperand extends NonPhiOperand {
|
||||
/**
|
||||
* The right operand of a binary instruction (e.g. `Add`, `CompareEQ`).
|
||||
*/
|
||||
class RightOperand extends NonPhiOperand {
|
||||
class RightOperand extends NonPhiOperand, RegisterOperand {
|
||||
RightOperand() {
|
||||
this = TNonPhiOperand(_, rightOperand(), _)
|
||||
}
|
||||
@@ -187,44 +222,10 @@ class RightOperand extends NonPhiOperand {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The return value operand of a `ReturnValue` instruction.
|
||||
*/
|
||||
class ReturnValueOperand extends NonPhiOperand {
|
||||
ReturnValueOperand() {
|
||||
this = TNonPhiOperand(_, returnValueOperand(), _)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "ReturnValue"
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getMemoryAccess() {
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The exception thrown by a `ThrowValue` instruction.
|
||||
*/
|
||||
class ExceptionOperand extends NonPhiOperand {
|
||||
ExceptionOperand() {
|
||||
this = TNonPhiOperand(_, exceptionOperand(), _)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "Exception"
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getMemoryAccess() {
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The condition operand of a `ConditionalBranch` or `Switch` instruction.
|
||||
*/
|
||||
class ConditionOperand extends NonPhiOperand {
|
||||
class ConditionOperand extends NonPhiOperand, RegisterOperand {
|
||||
ConditionOperand() {
|
||||
this = TNonPhiOperand(_, conditionOperand(), _)
|
||||
}
|
||||
@@ -238,7 +239,7 @@ class ConditionOperand extends NonPhiOperand {
|
||||
* An operand of the special `UnmodeledUse` instruction, representing a value
|
||||
* whose set of uses is unknown.
|
||||
*/
|
||||
class UnmodeledUseOperand extends NonPhiOperand {
|
||||
class UnmodeledUseOperand extends NonPhiOperand, MemoryOperand {
|
||||
UnmodeledUseOperand() {
|
||||
this = TNonPhiOperand(_, unmodeledUseOperand(), _)
|
||||
}
|
||||
@@ -255,7 +256,7 @@ class UnmodeledUseOperand extends NonPhiOperand {
|
||||
/**
|
||||
* The operand representing the target function of an `Call` instruction.
|
||||
*/
|
||||
class CallTargetOperand extends NonPhiOperand {
|
||||
class CallTargetOperand extends NonPhiOperand, RegisterOperand {
|
||||
CallTargetOperand() {
|
||||
this = TNonPhiOperand(_, callTargetOperand(), _)
|
||||
}
|
||||
@@ -270,7 +271,7 @@ class CallTargetOperand extends NonPhiOperand {
|
||||
* positional arguments (represented by `PositionalArgumentOperand`) and the
|
||||
* implicit `this` argument, if any (represented by `ThisArgumentOperand`).
|
||||
*/
|
||||
class ArgumentOperand extends NonPhiOperand {
|
||||
class ArgumentOperand extends NonPhiOperand, RegisterOperand {
|
||||
ArgumentOperand() {
|
||||
exists(ArgumentOperandTag argTag |
|
||||
this = TNonPhiOperand(_, argTag, _)
|
||||
@@ -317,7 +318,7 @@ class PositionalArgumentOperand extends ArgumentOperand {
|
||||
}
|
||||
}
|
||||
|
||||
class SideEffectOperand extends NonPhiOperand {
|
||||
class SideEffectOperand extends NonPhiOperand, MemoryOperand {
|
||||
SideEffectOperand() {
|
||||
this = TNonPhiOperand(_, sideEffectOperand(), _)
|
||||
}
|
||||
@@ -352,7 +353,7 @@ class SideEffectOperand extends NonPhiOperand {
|
||||
/**
|
||||
* An operand of a `PhiInstruction`.
|
||||
*/
|
||||
class PhiOperand extends Operand, TPhiOperand {
|
||||
class PhiOperand extends MemoryOperand, TPhiOperand {
|
||||
PhiInstruction useInstr;
|
||||
Instruction defInstr;
|
||||
IRBlock predecessorBlock;
|
||||
@@ -393,19 +394,10 @@ class PhiOperand extends Operand, TPhiOperand {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that reads a value from memory.
|
||||
*/
|
||||
class MemoryOperand extends Operand {
|
||||
MemoryOperand() {
|
||||
exists(getMemoryAccess())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The total operand of a Chi node, representing the previous value of the memory.
|
||||
*/
|
||||
class ChiTotalOperand extends Operand {
|
||||
class ChiTotalOperand extends MemoryOperand {
|
||||
ChiTotalOperand() {
|
||||
this = TNonPhiOperand(_, chiTotalOperand(), _)
|
||||
}
|
||||
@@ -423,7 +415,7 @@ class ChiTotalOperand extends Operand {
|
||||
/**
|
||||
* The partial operand of a Chi node, representing the value being written to part of the memory.
|
||||
*/
|
||||
class ChiPartialOperand extends Operand {
|
||||
class ChiPartialOperand extends MemoryOperand {
|
||||
ChiPartialOperand() {
|
||||
this = TNonPhiOperand(_, chiPartialOperand(), _)
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
|
||||
// offset of the field.
|
||||
bitOffset = getFieldBitOffset(instr.(FieldAddressInstruction).getField()) or
|
||||
// A copy propagates the source value.
|
||||
operand instanceof CopySourceOperand and bitOffset = 0
|
||||
operand = instr.(CopyInstruction).getSourceValueOperand() and bitOffset = 0
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ MemoryAccess getResultMemoryAccess(Instruction instr) {
|
||||
)
|
||||
}
|
||||
|
||||
MemoryAccess getOperandMemoryAccess(Operand operand) {
|
||||
MemoryAccess getOperandMemoryAccess(MemoryOperand operand) {
|
||||
exists(IRVariable var |
|
||||
resultPointsTo(operand.getAddressOperand().getDefinitionInstruction(), var, 0) and
|
||||
result = getMemoryAccess(var)
|
||||
|
||||
@@ -12,12 +12,11 @@ private newtype TOperandTag =
|
||||
TAddressOperand() or
|
||||
TBufferSizeOperand() or
|
||||
TSideEffectOperand() or
|
||||
TCopySourceOperand() or
|
||||
TLoadOperand() or
|
||||
TStoreValueOperand() or
|
||||
TUnaryOperand() or
|
||||
TLeftOperand() or
|
||||
TRightOperand() or
|
||||
TReturnValueOperand() or
|
||||
TExceptionOperand() or
|
||||
TConditionOperand() or
|
||||
TUnmodeledUseOperand() or
|
||||
TCallTargetOperand() or
|
||||
@@ -46,6 +45,18 @@ abstract class OperandTag extends TOperandTag {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that consumes a memory result (e.g. the `LoadOperand` on a `Load` instruction).
|
||||
*/
|
||||
abstract class MemoryOperandTag extends OperandTag {
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that consumes a register (non-memory) result.
|
||||
*/
|
||||
abstract class RegisterOperandTag extends OperandTag {
|
||||
}
|
||||
|
||||
// Note: individual subtypes are listed in the order that the operands should
|
||||
// appear in the operand list of the instruction when printing.
|
||||
|
||||
@@ -53,7 +64,7 @@ abstract class OperandTag extends TOperandTag {
|
||||
* The address operand of an instruction that loads or stores a value from
|
||||
* memory (e.g. `Load`, `Store`, `InitializeParameter`, `IndirectReadSideEffect`).
|
||||
*/
|
||||
class AddressOperandTag extends OperandTag, TAddressOperand {
|
||||
class AddressOperandTag extends RegisterOperandTag, TAddressOperand {
|
||||
override final string toString() {
|
||||
result = "Address"
|
||||
}
|
||||
@@ -71,7 +82,7 @@ AddressOperandTag addressOperand() {
|
||||
* The buffer size operand of an instruction that represents a read or write of
|
||||
* a buffer.
|
||||
*/
|
||||
class BufferSizeOperand extends OperandTag, TBufferSizeOperand {
|
||||
class BufferSizeOperand extends RegisterOperandTag, TBufferSizeOperand {
|
||||
override final string toString() {
|
||||
result = "BufferSize"
|
||||
}
|
||||
@@ -84,7 +95,7 @@ class BufferSizeOperand extends OperandTag, TBufferSizeOperand {
|
||||
/**
|
||||
* The operand representing the read side effect of a `SideEffectInstruction`.
|
||||
*/
|
||||
class SideEffectOperandTag extends OperandTag, TSideEffectOperand {
|
||||
class SideEffectOperandTag extends MemoryOperandTag, TSideEffectOperand {
|
||||
override final string toString() {
|
||||
result = "SideEffect"
|
||||
}
|
||||
@@ -99,12 +110,12 @@ SideEffectOperandTag sideEffectOperand() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The source value operand of an instruction that copies this value to its
|
||||
* result (e.g. `Copy`, `Load`, `Store`).
|
||||
* The source value operand of an instruction that loads a value from memory (e.g. `Load`,
|
||||
* `ReturnValue`, `ThrowValue`).
|
||||
*/
|
||||
class CopySourceOperandTag extends OperandTag, TCopySourceOperand {
|
||||
class LoadOperandTag extends MemoryOperandTag, TLoadOperand {
|
||||
override final string toString() {
|
||||
result = "CopySource"
|
||||
result = "Load"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
@@ -112,20 +123,37 @@ class CopySourceOperandTag extends OperandTag, TCopySourceOperand {
|
||||
}
|
||||
}
|
||||
|
||||
CopySourceOperandTag copySourceOperand() {
|
||||
result = TCopySourceOperand()
|
||||
LoadOperandTag loadOperand() {
|
||||
result = TLoadOperand()
|
||||
}
|
||||
|
||||
/**
|
||||
* The sole operand of a unary instruction (e.g. `Convert`, `Negate`).
|
||||
* The source value operand of a `Store` instruction.
|
||||
*/
|
||||
class UnaryOperandTag extends OperandTag, TUnaryOperand {
|
||||
class StoreValueOperandTag extends RegisterOperandTag, TStoreValueOperand {
|
||||
override final string toString() {
|
||||
result = "StoreValue"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 4
|
||||
}
|
||||
}
|
||||
|
||||
StoreValueOperandTag storeValueOperand() {
|
||||
result = TStoreValueOperand()
|
||||
}
|
||||
|
||||
/**
|
||||
* The sole operand of a unary instruction (e.g. `Convert`, `Negate`, `Copy`).
|
||||
*/
|
||||
class UnaryOperandTag extends RegisterOperandTag, TUnaryOperand {
|
||||
override final string toString() {
|
||||
result = "Unary"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 4
|
||||
result = 5
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,13 +164,13 @@ UnaryOperandTag unaryOperand() {
|
||||
/**
|
||||
* The left operand of a binary instruction (e.g. `Add`, `CompareEQ`).
|
||||
*/
|
||||
class LeftOperandTag extends OperandTag, TLeftOperand {
|
||||
class LeftOperandTag extends RegisterOperandTag, TLeftOperand {
|
||||
override final string toString() {
|
||||
result = "Left"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 5
|
||||
result = 6
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,13 +181,13 @@ LeftOperandTag leftOperand() {
|
||||
/**
|
||||
* The right operand of a binary instruction (e.g. `Add`, `CompareEQ`).
|
||||
*/
|
||||
class RightOperandTag extends OperandTag, TRightOperand {
|
||||
class RightOperandTag extends RegisterOperandTag, TRightOperand {
|
||||
override final string toString() {
|
||||
result = "Right"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 6
|
||||
result = 7
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,50 +195,16 @@ RightOperandTag rightOperand() {
|
||||
result = TRightOperand()
|
||||
}
|
||||
|
||||
/**
|
||||
* The return value operand of a `ReturnValue` instruction.
|
||||
*/
|
||||
class ReturnValueOperandTag extends OperandTag, TReturnValueOperand {
|
||||
override final string toString() {
|
||||
result = "ReturnValue"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 7
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValueOperandTag returnValueOperand() {
|
||||
result = TReturnValueOperand()
|
||||
}
|
||||
|
||||
/**
|
||||
* The exception thrown by a `ThrowValue` instruction.
|
||||
*/
|
||||
class ExceptionOperandTag extends OperandTag, TExceptionOperand {
|
||||
override final string toString() {
|
||||
result = "Exception"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 8
|
||||
}
|
||||
}
|
||||
|
||||
ExceptionOperandTag exceptionOperand() {
|
||||
result = TExceptionOperand()
|
||||
}
|
||||
|
||||
/**
|
||||
* The condition operand of a `ConditionalBranch` or `Switch` instruction.
|
||||
*/
|
||||
class ConditionOperandTag extends OperandTag, TConditionOperand {
|
||||
class ConditionOperandTag extends RegisterOperandTag, TConditionOperand {
|
||||
override final string toString() {
|
||||
result = "Condition"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 9
|
||||
result = 8
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,13 +216,13 @@ ConditionOperandTag conditionOperand() {
|
||||
* An operand of the special `UnmodeledUse` instruction, representing a value
|
||||
* whose set of uses is unknown.
|
||||
*/
|
||||
class UnmodeledUseOperandTag extends OperandTag, TUnmodeledUseOperand {
|
||||
class UnmodeledUseOperandTag extends MemoryOperandTag, TUnmodeledUseOperand {
|
||||
override final string toString() {
|
||||
result = "UnmodeledUse"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 10
|
||||
result = 9
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,13 +233,13 @@ UnmodeledUseOperandTag unmodeledUseOperand() {
|
||||
/**
|
||||
* The operand representing the target function of an `Call` instruction.
|
||||
*/
|
||||
class CallTargetOperandTag extends OperandTag, TCallTargetOperand {
|
||||
class CallTargetOperandTag extends RegisterOperandTag, TCallTargetOperand {
|
||||
override final string toString() {
|
||||
result = "CallTarget"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 11
|
||||
result = 10
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +252,7 @@ CallTargetOperandTag callTargetOperand() {
|
||||
* positional arguments (represented by `PositionalArgumentOperand`) and the
|
||||
* implicit `this` argument, if any (represented by `ThisArgumentOperand`).
|
||||
*/
|
||||
abstract class ArgumentOperandTag extends OperandTag {
|
||||
abstract class ArgumentOperandTag extends RegisterOperandTag {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,7 +269,7 @@ class ThisArgumentOperandTag extends ArgumentOperandTag, TThisArgumentOperand {
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 12
|
||||
result = 11
|
||||
}
|
||||
|
||||
override final string getLabel() {
|
||||
@@ -303,7 +297,7 @@ class PositionalArgumentOperandTag extends ArgumentOperandTag,
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 14 + argIndex
|
||||
result = 12 + argIndex
|
||||
}
|
||||
|
||||
final int getArgIndex() {
|
||||
@@ -315,13 +309,13 @@ PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
|
||||
result = TPositionalArgumentOperand(argIndex)
|
||||
}
|
||||
|
||||
class ChiTotalOperandTag extends OperandTag, TChiTotalOperand {
|
||||
class ChiTotalOperandTag extends MemoryOperandTag, TChiTotalOperand {
|
||||
override final string toString() {
|
||||
result = "ChiTotal"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 14
|
||||
result = 13
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,13 +323,13 @@ ChiTotalOperandTag chiTotalOperand() {
|
||||
result = TChiTotalOperand()
|
||||
}
|
||||
|
||||
class ChiPartialOperandTag extends OperandTag, TChiPartialOperand {
|
||||
class ChiPartialOperandTag extends MemoryOperandTag, TChiPartialOperand {
|
||||
override final string toString() {
|
||||
result = "ChiPartial"
|
||||
}
|
||||
|
||||
override final int getSortOrder() {
|
||||
result = 15
|
||||
result = 14
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user