C++: hook ChiInstructions into the operand graph

This commit is contained in:
Robert Marsh
2018-11-03 00:33:06 -07:00
committed by Dave Bartolomeo
parent a33b59103a
commit 927f935e62
11 changed files with 1356 additions and 1173 deletions

View File

@@ -84,9 +84,9 @@ class PhiMemoryAccess extends MemoryAccessKind, TPhiMemoryAccess {
* The operand is a ChiOld operand, which accesses the same memory as its
* definition.
*/
class ChiOldMemoryAccess extends MemoryAccessKind, TChiOldMemoryAccess {
class ChiTotalMemoryAccess extends MemoryAccessKind, TChiOldMemoryAccess {
override string toString() {
result = "chi(old)"
result = "chi(total)"
}
}
@@ -94,9 +94,9 @@ class ChiOldMemoryAccess extends MemoryAccessKind, TChiOldMemoryAccess {
* The operand is a ChiUpdate operand, which accesses the same memory as its
* definition.
*/
class ChiUpdateMemoryAccess extends MemoryAccessKind, TChiUpdateMemoryAccess {
class ChiPartialMemoryAccess extends MemoryAccessKind, TChiUpdateMemoryAccess {
override string toString() {
result = "chi(updated)"
result = "chi(partial)"
}
}
/**

View File

@@ -39,6 +39,8 @@ module InstructionSanity {
opcode instanceof Opcode::ThrowValue and tag instanceof ExceptionOperandTag 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
opcode instanceof Opcode::Chi and tag instanceof ChiPartialOperandTag or
(
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode) and
tag instanceof SideEffectOperandTag
@@ -1346,7 +1348,7 @@ class ChiInstruction extends Instruction {
}
override final MemoryAccessKind getResultMemoryAccess() {
result instanceof ChiUpdateMemoryAccess
result instanceof ChiTotalMemoryAccess
}
}

View File

@@ -85,9 +85,11 @@ class UnknownVirtualVariable extends VirtualVariable, TUnknownVirtualVariable {
private newtype TMemoryAccess =
TVariableMemoryAccess(VirtualIRVariable vvar, IntValue offset, IntValue size) {
exists(Instruction instr |
instr.getResultMemoryAccess() instanceof IndirectMemoryAccess and
exists(MemoryAccessKind mak | instr.getResultMemoryAccess() = mak and not mak instanceof PhiMemoryAccess) and
resultPointsTo(instr.getAnOperand().(AddressOperand).getDefinitionInstruction(), vvar.getIRVariable(), offset) and
instr.getResultSize() = size
if exists(instr.getResultSize())
then instr.getResultSize() = size
else size = Ints::unknown()
)
}
or
@@ -107,7 +109,7 @@ class MemoryAccess extends TMemoryAccess {
VirtualVariable getVirtualVariable() {
none()
}
predicate isPartialMemoryAccess() {
none()
}
@@ -148,6 +150,10 @@ class VariableMemoryAccess extends TVariableMemoryAccess, MemoryAccess {
class UnknownMemoryAccess extends TUnknownMemoryAccess, MemoryAccess {
UnknownVirtualVariable vvar;
UnknownMemoryAccess() {
this = TUnknownMemoryAccess(vvar)
}
final override string toString() {
result = vvar.toString()
}
@@ -201,7 +207,7 @@ Overlap getOverlap(MemoryAccess def, MemoryAccess use) {
}
MemoryAccess getResultMemoryAccess(Instruction instr) {
instr.getResultMemoryAccess() instanceof IndirectMemoryAccess and
exists(instr.getResultMemoryAccess()) and
if exists(IRVariable var, IntValue i |
resultPointsTo(instr.getAnOperand().(AddressOperand).getDefinitionInstruction(), var, i)
)
@@ -214,13 +220,13 @@ MemoryAccess getResultMemoryAccess(Instruction instr) {
}
MemoryAccess getOperandMemoryAccess(Operand operand) {
operand.getMemoryAccess() instanceof IndirectMemoryAccess and
exists(operand.getMemoryAccess()) and
if exists(IRVariable var, IntValue i |
resultPointsTo(operand.getAddressOperand().getDefinitionInstruction(), var, i)
)
then exists(IRVariable var, IntValue i |
resultPointsTo(operand.getAddressOperand().getDefinitionInstruction(), var, i) and
result = getVariableMemoryAccess(var, i, operand.getAddressOperand().getDefinitionInstruction().getResultSize())
result = getVariableMemoryAccess(var, i, operand.getDefinitionInstruction().getResultSize())
)
else
result = TUnknownMemoryAccess(TUnknownVirtualVariable(operand.getInstruction().getFunctionIR()))

View File

@@ -149,11 +149,11 @@ cached private module Cached {
hasUseAtRank(vvar, useBlock, useRank, oldInstruction) and
definitionReachesUse(vvar, defBlock, defRank, useBlock, useRank) and
if defIndex >= 0 then
result = getNewInstruction(defBlock.getInstruction(defIndex))
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
else
result = getPhiInstruction(instruction.getFunction(), defBlock, vvar)
result = getPhiInstruction(instruction.getFunction(), defBlock, vvar)
)
)
)
else (
result = instruction.getFunctionIR().getUnmodeledDefinitionInstruction()
)
@@ -168,9 +168,13 @@ cached private module Cached {
result = getNewInstruction(oldDefinition)
)
)
else
else
result = getNewInstruction(oldOperand.getDefinitionInstruction())
)
) or
instruction.getTag() = ChiTag(getOldInstruction(result)) and
tag instanceof ChiPartialOperandTag
or
result = getChiInstructionTotalOperand(instruction.(ChiInstruction), tag.(ChiTotalOperandTag))
}
cached Instruction getPhiInstructionOperandDefinition(PhiInstruction instr,
@@ -184,12 +188,24 @@ cached private module Cached {
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
definitionReachesEndOfBlock(vvar, defBlock, defRank, predBlock) and
if defIndex >= 0 then
result = getNewInstruction(defBlock.getInstruction(defIndex))
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
else
result = getPhiInstruction(instr.getFunction(), defBlock, vvar)
)
}
cached Instruction getChiInstructionTotalOperand(ChiInstruction chiInstr, ChiTotalOperandTag tag) {
exists(Alias::VirtualVariable vvar, OldIR::Instruction oldInstr, OldIR::IRBlock defBlock,
int defRank, int defIndex, OldIR::IRBlock useBlock, int useRank |
ChiTag(oldInstr) = chiInstr.getTag() and
vvar = Alias::getResultMemoryAccess(oldInstr).getVirtualVariable() and
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
hasUseAtRank(vvar, useBlock, useRank, oldInstr) and
definitionReachesUse(vvar, defBlock, defRank, useBlock, useRank) and
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
)
}
cached Instruction getPhiInstructionBlockStart(PhiInstruction instr) {
exists(OldIR::IRBlock oldBlock |
instr.getTag() = PhiTag(_, oldBlock) and
@@ -300,7 +316,12 @@ cached private module Cached {
private predicate hasUse(Alias::VirtualVariable vvar,
OldIR::Instruction use, OldIR::IRBlock block, int index) {
exists(Alias::MemoryAccess access |
access = Alias::getOperandMemoryAccess(use.getAnOperand()) and
(
access = Alias::getOperandMemoryAccess(use.getAnOperand())
or
access = Alias::getResultMemoryAccess(use) and
access.isPartialMemoryAccess()
) and
block.getInstruction(index) = use and
vvar = access.getVirtualVariable()
)
@@ -438,7 +459,8 @@ cached private module Cached {
ma = Alias::getResultMemoryAccess(def) and
ma.isPartialMemoryAccess() and
ma.getVirtualVariable() = vvar
)
) and
not def instanceof OldIR::UnmodeledDefinitionInstruction
}
}

View File

@@ -39,6 +39,8 @@ module InstructionSanity {
opcode instanceof Opcode::ThrowValue and tag instanceof ExceptionOperandTag 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
opcode instanceof Opcode::Chi and tag instanceof ChiPartialOperandTag or
(
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode) and
tag instanceof SideEffectOperandTag
@@ -1346,7 +1348,7 @@ class ChiInstruction extends Instruction {
}
override final MemoryAccessKind getResultMemoryAccess() {
result instanceof ChiUpdateMemoryAccess
result instanceof ChiTotalMemoryAccess
}
}

View File

@@ -39,6 +39,8 @@ module InstructionSanity {
opcode instanceof Opcode::ThrowValue and tag instanceof ExceptionOperandTag 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
opcode instanceof Opcode::Chi and tag instanceof ChiPartialOperandTag or
(
(opcode instanceof ReadSideEffectOpcode or opcode instanceof MayWriteSideEffectOpcode) and
tag instanceof SideEffectOperandTag
@@ -1346,7 +1348,7 @@ class ChiInstruction extends Instruction {
}
override final MemoryAccessKind getResultMemoryAccess() {
result instanceof ChiUpdateMemoryAccess
result instanceof ChiTotalMemoryAccess
}
}

View File

@@ -149,9 +149,9 @@ cached private module Cached {
hasUseAtRank(vvar, useBlock, useRank, oldInstruction) and
definitionReachesUse(vvar, defBlock, defRank, useBlock, useRank) and
if defIndex >= 0 then
result = getNewInstruction(defBlock.getInstruction(defIndex))
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
else
result = getPhiInstruction(instruction.getFunction(), defBlock, vvar)
result = getPhiInstruction(instruction.getFunction(), defBlock, vvar)
)
)
else (
@@ -170,7 +170,11 @@ cached private module Cached {
)
else
result = getNewInstruction(oldOperand.getDefinitionInstruction())
)
) or
instruction.getTag() = ChiTag(getOldInstruction(result)) and
tag instanceof ChiPartialOperandTag
or
result = getChiInstructionTotalOperand(instruction.(ChiInstruction), tag.(ChiTotalOperandTag))
}
cached Instruction getPhiInstructionOperandDefinition(PhiInstruction instr,
@@ -184,12 +188,24 @@ cached private module Cached {
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
definitionReachesEndOfBlock(vvar, defBlock, defRank, predBlock) and
if defIndex >= 0 then
result = getNewInstruction(defBlock.getInstruction(defIndex))
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
else
result = getPhiInstruction(instr.getFunction(), defBlock, vvar)
)
}
cached Instruction getChiInstructionTotalOperand(ChiInstruction chiInstr, ChiTotalOperandTag tag) {
exists(Alias::VirtualVariable vvar, OldIR::Instruction oldInstr, OldIR::IRBlock defBlock,
int defRank, int defIndex, OldIR::IRBlock useBlock, int useRank |
ChiTag(oldInstr) = chiInstr.getTag() and
vvar = Alias::getResultMemoryAccess(oldInstr).getVirtualVariable() and
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
hasUseAtRank(vvar, useBlock, useRank, oldInstr) and
definitionReachesUse(vvar, defBlock, defRank, useBlock, useRank) and
result = getNewFinalInstruction(defBlock.getInstruction(defIndex))
)
}
cached Instruction getPhiInstructionBlockStart(PhiInstruction instr) {
exists(OldIR::IRBlock oldBlock |
instr.getTag() = PhiTag(_, oldBlock) and
@@ -300,7 +316,12 @@ cached private module Cached {
private predicate hasUse(Alias::VirtualVariable vvar,
OldIR::Instruction use, OldIR::IRBlock block, int index) {
exists(Alias::MemoryAccess access |
access = Alias::getOperandMemoryAccess(use.getAnOperand()) and
(
access = Alias::getOperandMemoryAccess(use.getAnOperand())
or
access = Alias::getResultMemoryAccess(use) and
access.isPartialMemoryAccess()
) and
block.getInstruction(index) = use and
vvar = access.getVirtualVariable()
)
@@ -438,7 +459,8 @@ cached private module Cached {
ma = Alias::getResultMemoryAccess(def) and
ma.isPartialMemoryAccess() and
ma.getVirtualVariable() = vvar
)
) and
not def instanceof OldIR::UnmodeledDefinitionInstruction
}
}

View File

@@ -28,8 +28,8 @@ private newtype TOperandTag =
exists(op.getChild(argIndex))
)
} or
TChiOldOperand() or
TChiUpdateOperand()
TChiTotalOperand() or
TChiPartialOperand()
/**
* Identifies the kind of operand on an instruction. Each `Instruction` has at
@@ -315,9 +315,9 @@ PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
result = TPositionalArgumentOperand(argIndex)
}
class ChiOldOperand extends OperandTag, TChiOldOperand {
class ChiTotalOperandTag extends OperandTag, TChiTotalOperand {
override final string toString() {
result = "ChiOld"
result = "ChiTotal"
}
override final int getSortOrder() {
@@ -325,9 +325,9 @@ class ChiOldOperand extends OperandTag, TChiOldOperand {
}
}
class ChiUpdateOperand extends OperandTag, TChiUpdateOperand {
class ChiPartialOperandTag extends OperandTag, TChiPartialOperand {
override final string toString() {
result = "ChiUpdate"
result = "ChiPartial"
}
override final int getSortOrder() {

View File

@@ -1,3 +0,0 @@
| constant_func.cpp:1:5:1:18 | IR: ReturnConstant | 7 |
| constant_func.cpp:5:5:5:21 | IR: ReturnConstantPhi | 7 |
| constant_func.cpp:25:5:25:25 | IR: ReturnConstantPhiLoop | 7 |

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,18 @@
missingOperand
| ir.cpp:174:9:174:12 | Load: access to array | CopySource |
| ir.cpp:175:9:175:12 | Load: access to array | CopySource |
| ir.cpp:188:14:188:21 | Load: access to array | CopySource |
| ir.cpp:190:18:190:23 | Load: access to array | CopySource |
| ir.cpp:572:22:572:23 | Load: | CopySource |
| ir.cpp:676:12:676:12 | Load: (reference dereference) | CopySource |
| ir.cpp:894:14:894:43 | Load: __builtin_va_arg | CopySource |
| ir.cpp:895:30:895:33 | Load: __builtin_va_arg | CopySource |
| ir.cpp:265:6:265:14 | UnmodeledUse: For_Empty | UnmodeledUse |
| ir.cpp:272:6:272:13 | UnmodeledUse: For_Init | UnmodeledUse |
| ir.cpp:285:6:285:15 | UnmodeledUse: For_Update | UnmodeledUse |
| ir.cpp:298:6:298:19 | UnmodeledUse: For_InitUpdate | UnmodeledUse |
| ir.cpp:504:19:504:19 | Chi: x | ChiTotal |
| ir.cpp:505:19:505:19 | Chi: x | ChiTotal |
| ir.cpp:506:16:506:18 | Chi: {...} | ChiTotal |
| ir.cpp:513:14:513:16 | Chi: {...} | ChiTotal |
| ir.cpp:514:19:514:19 | Chi: x | ChiTotal |
| ir.cpp:515:19:515:19 | Chi: x | ChiTotal |
| ir.cpp:516:19:516:19 | Chi: x | ChiTotal |
| ir.cpp:736:5:736:19 | Chi: call to String | ChiTotal |
| ir.cpp:962:26:962:30 | Chi: 10002 | ChiTotal |
| ir.cpp:962:41:962:45 | Chi: 10900 | ChiTotal |
unexpectedOperand
duplicateOperand
missingPhiOperand