C++: Add getUpdatedInterval predicate to ChiInstructions, and getUsedInterval predicate to NonPhiMemoryOperands.

This commit is contained in:
Mathias Vorreiter Pedersen
2020-09-01 10:53:48 +02:00
parent 1221165792
commit 1e13a39932
11 changed files with 125 additions and 16 deletions

View File

@@ -1962,6 +1962,13 @@ class ChiInstruction extends Instruction {
* Gets the operand that represents the new value written by the memory write.
*/
final Instruction getPartial() { result = getPartialOperand().getDef() }
/**
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`.
*/
final predicate getUpdatedInterval(int startBit, int endBit) {
Construction::getIntervalUpdatedByChi(this, startBit, endBit)
}
}
/**

View File

@@ -328,6 +328,14 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOper
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
/**
* Holds if the operand totally overlaps with its definition and consumes the
* bit range `[startBitOffset, endBitOffset)`.
*/
predicate getUsedInterval(int startBitOffset, int endBitOffset) {
Construction::getUsedInterval(this, startBitOffset, endBitOffset)
}
}
/**

View File

@@ -556,22 +556,6 @@ private Overlap getVariableMemoryLocationOverlap(
use.getEndBitOffset())
}
predicate getDefInterval(Instruction defInstr, IntValue startBitDef, IntValue endBitDef) {
exists(VariableMemoryLocation def |
def = getResultMemoryLocation(defInstr) and
startBitDef = def.getStartBitOffset() and
endBitDef = def.getEndBitOffset()
)
}
predicate getUseInterval(Instruction useInstr, IntValue startBitUse, IntValue endBitUse) {
exists(VariableMemoryLocation use |
use = getOperandMemoryLocation(useInstr.getAnOperand()) and
startBitUse = use.getStartBitOffset() and
endBitUse = use.getEndBitOffset()
)
}
MemoryLocation getResultMemoryLocation(Instruction instr) {
exists(MemoryAccessKind kind, boolean isMayAccess |
kind = instr.getResultMemoryAccess() and
@@ -633,3 +617,9 @@ MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
)
)
}
/** Gets the start bit offset of a `MemoryLocation`, if any. */
int getStartBitOffset(VariableMemoryLocation location) { result = location.getStartBitOffset() }
/** Gets the end bit offset of a `MemoryLocation`, if any. */
int getEndBitOffset(VariableMemoryLocation location) { result = location.getEndBitOffset() }

View File

@@ -149,6 +149,34 @@ private module Cached {
)
}
/**
* Holds if the partial operand of this `ChiInstruction` updates the bit range
* `[startBitOffset, endBitOffset)` of the total operand.
*/
cached
predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBitOffset, int endBitOffset) {
exists(Alias::MemoryLocation location, OldInstruction oldInstruction |
oldInstruction = getOldInstruction(chi.getPartial()) and
location = Alias::getResultMemoryLocation(oldInstruction) and
startBitOffset = Alias::getStartBitOffset(location) and
endBitOffset = Alias::getEndBitOffset(location)
)
}
/**
* Holds if `operand` totally overlaps with its definition and consumes the bit range
* `[startBitOffset, endBitOffset)`.
*/
cached
predicate getUsedInterval(NonPhiMemoryOperand operand, int startBitOffset, int endBitOffset) {
exists(Alias::MemoryLocation location, OldIR::NonPhiMemoryOperand oldOperand |
oldOperand = operand.getUse().(OldInstruction).getAnOperand() and
location = Alias::getOperandMemoryLocation(oldOperand) and
startBitOffset = Alias::getStartBitOffset(location) and
endBitOffset = Alias::getEndBitOffset(location)
)
}
/**
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
* through a phi instruction and therefore should be impossible.

View File

@@ -1962,6 +1962,13 @@ class ChiInstruction extends Instruction {
* Gets the operand that represents the new value written by the memory write.
*/
final Instruction getPartial() { result = getPartialOperand().getDef() }
/**
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`.
*/
final predicate getUpdatedInterval(int startBit, int endBit) {
Construction::getIntervalUpdatedByChi(this, startBit, endBit)
}
}
/**

View File

@@ -328,6 +328,14 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOper
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
/**
* Holds if the operand totally overlaps with its definition and consumes the
* bit range `[startBitOffset, endBitOffset)`.
*/
predicate getUsedInterval(int startBitOffset, int endBitOffset) {
Construction::getUsedInterval(this, startBitOffset, endBitOffset)
}
}
/**

View File

@@ -182,6 +182,18 @@ Instruction getMemoryOperandDefinition(
none()
}
/**
* Holds if the partial operand of this `ChiInstruction` updates the bit range
* `[startBitOffset, endBitOffset)` of the total operand.
*/
predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBit, int endBit) { none() }
/**
* Holds if the operand totally overlaps with its definition and consumes the
* bit range `[startBitOffset, endBitOffset)`.
*/
predicate getUsedInterval(Operand operand, int startBit, int endBit) { none() }
/** Gets a non-phi instruction that defines an operand of `instr`. */
private Instruction getNonPhiOperandDef(Instruction instr) {
result = getRegisterOperandDefinition(instr, _)

View File

@@ -1962,6 +1962,13 @@ class ChiInstruction extends Instruction {
* Gets the operand that represents the new value written by the memory write.
*/
final Instruction getPartial() { result = getPartialOperand().getDef() }
/**
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`.
*/
final predicate getUpdatedInterval(int startBit, int endBit) {
Construction::getIntervalUpdatedByChi(this, startBit, endBit)
}
}
/**

View File

@@ -328,6 +328,14 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOper
not Construction::isInCycle(useInstr) and
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
}
/**
* Holds if the operand totally overlaps with its definition and consumes the
* bit range `[startBitOffset, endBitOffset)`.
*/
predicate getUsedInterval(int startBitOffset, int endBitOffset) {
Construction::getUsedInterval(this, startBitOffset, endBitOffset)
}
}
/**

View File

@@ -149,6 +149,34 @@ private module Cached {
)
}
/**
* Holds if the partial operand of this `ChiInstruction` updates the bit range
* `[startBitOffset, endBitOffset)` of the total operand.
*/
cached
predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBitOffset, int endBitOffset) {
exists(Alias::MemoryLocation location, OldInstruction oldInstruction |
oldInstruction = getOldInstruction(chi.getPartial()) and
location = Alias::getResultMemoryLocation(oldInstruction) and
startBitOffset = Alias::getStartBitOffset(location) and
endBitOffset = Alias::getEndBitOffset(location)
)
}
/**
* Holds if `operand` totally overlaps with its definition and consumes the bit range
* `[startBitOffset, endBitOffset)`.
*/
cached
predicate getUsedInterval(NonPhiMemoryOperand operand, int startBitOffset, int endBitOffset) {
exists(Alias::MemoryLocation location, OldIR::NonPhiMemoryOperand oldOperand |
oldOperand = operand.getUse().(OldInstruction).getAnOperand() and
location = Alias::getOperandMemoryLocation(oldOperand) and
startBitOffset = Alias::getStartBitOffset(location) and
endBitOffset = Alias::getEndBitOffset(location)
)
}
/**
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
* through a phi instruction and therefore should be impossible.

View File

@@ -79,3 +79,9 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
result = getMemoryLocation(getAddressOperandAllocation(operand.getAddressOperand()))
}
/** Gets the start bit offset of a `MemoryLocation`, if any. */
int getStartBitOffset(MemoryLocation location) { none() }
/** Gets the end bit offset of a `MemoryLocation`, if any. */
int getEndBitOffset(MemoryLocation location) { none() }