C++/C#: Make `AliasedUse` access only non-local memory

The `AliasedUse` instruction is supposed to represent future uses of aliased memory after the function returns. Since local variables from that function are no longer allocated after the function returns, the `AliasedUse` instruction should access only the set of aliased locations that does not include locals from the current stack frame.
This commit is contained in:
Dave Bartolomeo 2019-10-25 13:10:39 -07:00
Родитель 1223388ab6
Коммит 56cbd0c152
9 изменённых файлов: 66 добавлений и 9 удалений

Просмотреть файл

@ -5,6 +5,7 @@ private newtype TMemoryAccessKind =
TBufferMayMemoryAccess() or
TEscapedMemoryAccess() or
TEscapedMayMemoryAccess() or
TNonLocalMayMemoryAccess() or
TPhiMemoryAccess() or
TUnmodeledMemoryAccess() or
TChiTotalMemoryAccess() or
@ -80,6 +81,14 @@ class EscapedMayMemoryAccess extends MemoryAccessKind, TEscapedMayMemoryAccess {
override string toString() { result = "escaped(may)" }
}
/**
* The operand or result may access all memory whose address has escaped, other than data on the
* stack frame of the current function.
*/
class NonLocalMayMemoryAccess extends MemoryAccessKind, TNonLocalMayMemoryAccess {
override string toString() { result = "nonlocal(may)" }
}
/**
* The operand is a Phi operand, which accesses the same memory as its
* definition.

Просмотреть файл

@ -389,7 +389,7 @@ class SideEffectOperand extends TypedOperand {
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof EscapedMayMemoryAccess
result instanceof NonLocalMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess

Просмотреть файл

@ -35,6 +35,7 @@ private newtype TMemoryLocation =
hasOperandMemoryAccess(_, var, type, startBitOffset, endBitOffset)
} or
TUnknownMemoryLocation(IRFunction irFunc) or
TUnknownNonLocalMemoryLocation(IRFunction irFunc) or
TUnknownVirtualVariable(IRFunction irFunc)
/**
@ -133,6 +134,24 @@ class UnknownMemoryLocation extends TUnknownMemoryLocation, MemoryLocation {
final override string getUniqueId() { result = "{Unknown}" }
}
/**
* An access to memory that is not known to be confined to a specific `IRVariable`, but is known to
* not access memory on the current function's stack frame.
*/
class UnknownNonLocalMemoryLocation extends TUnknownNonLocalMemoryLocation, MemoryLocation {
IRFunction irFunc;
UnknownNonLocalMemoryLocation() { this = TUnknownNonLocalMemoryLocation(irFunc) }
final override string toString() { result = "{UnknownNonLocal}" }
final override VirtualVariable getVirtualVariable() { result = TUnknownVirtualVariable(irFunc) }
final override Type getType() { result instanceof UnknownType }
final override string getUniqueId() { result = "{UnknownNonLocal}" }
}
/**
* An access to all aliased memory.
*/
@ -163,6 +182,13 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) {
def instanceof UnknownMemoryLocation and
result instanceof MayPartiallyOverlap
or
// An UnknownNonLocalMemoryLocation may partially overlap any location within the same virtual
// variable, except a local variable.
def.getVirtualVariable() = use.getVirtualVariable() and
def instanceof UnknownNonLocalMemoryLocation and
result instanceof MayPartiallyOverlap and
not use.(VariableMemoryLocation).getVariable() instanceof IRAutomaticVariable
or
exists(VariableMemoryLocation defVariableLocation |
defVariableLocation = def and
(
@ -171,6 +197,13 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) {
(use instanceof UnknownMemoryLocation or use instanceof UnknownVirtualVariable) and
result instanceof MayPartiallyOverlap
or
// A VariableMemoryLocation that is not a local variable may partially overlap an unknown
// non-local location within the same virtual variable.
def.getVirtualVariable() = use.getVirtualVariable() and
use instanceof UnknownNonLocalMemoryLocation and
result instanceof MayPartiallyOverlap and
not defVariableLocation.getVariable() instanceof IRAutomaticVariable
or
// A VariableMemoryLocation overlaps another location within the same variable based on the relationship
// of the two offset intervals.
exists(Overlap intervalOverlap |
@ -296,6 +329,9 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
or
kind instanceof EscapedMayMemoryAccess and
result = TUnknownMemoryLocation(instr.getEnclosingIRFunction())
or
kind instanceof NonLocalMayMemoryAccess and
result = TUnknownNonLocalMemoryLocation(instr.getEnclosingIRFunction())
)
)
}
@ -320,6 +356,9 @@ MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
or
kind instanceof EscapedMayMemoryAccess and
result = TUnknownMemoryLocation(operand.getEnclosingIRFunction())
or
kind instanceof NonLocalMayMemoryAccess and
result = TUnknownNonLocalMemoryLocation(operand.getEnclosingIRFunction())
)
)
}

Просмотреть файл

@ -389,7 +389,7 @@ class SideEffectOperand extends TypedOperand {
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof EscapedMayMemoryAccess
result instanceof NonLocalMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess

Просмотреть файл

@ -389,7 +389,7 @@ class SideEffectOperand extends TypedOperand {
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof EscapedMayMemoryAccess
result instanceof NonLocalMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess

Просмотреть файл

@ -340,7 +340,7 @@ ssa.cpp:
# 98| v0_19(void) = NoOp :
# 95| v0_20(void) = ReturnVoid :
# 95| v0_21(void) = UnmodeledUse : mu*
# 95| v0_22(void) = AliasedUse : ~m0_18
# 95| v0_22(void) = AliasedUse : ~m0_15
# 95| v0_23(void) = ExitFunction :
# 100| void MustTotallyOverlap(Point)
@ -396,7 +396,7 @@ ssa.cpp:
# 109| v0_25(void) = NoOp :
# 105| v0_26(void) = ReturnVoid :
# 105| v0_27(void) = UnmodeledUse : mu*
# 105| v0_28(void) = AliasedUse : ~m0_24
# 105| v0_28(void) = AliasedUse : ~m0_21
# 105| v0_29(void) = ExitFunction :
# 111| void MayPartiallyOverlap(int, int)
@ -468,7 +468,7 @@ ssa.cpp:
# 120| v0_33(void) = NoOp :
# 116| v0_34(void) = ReturnVoid :
# 116| v0_35(void) = UnmodeledUse : mu*
# 116| v0_36(void) = AliasedUse : ~m0_32
# 116| v0_36(void) = AliasedUse : ~m0_29
# 116| v0_37(void) = ExitFunction :
# 122| void MergeMustExactlyOverlap(bool, int, int)
@ -865,5 +865,5 @@ ssa.cpp:
# 207| r0_23(glval<int>) = VariableAddress[#return] :
# 207| v0_24(void) = ReturnValue : &:r0_23, m0_22
# 207| v0_25(void) = UnmodeledUse : mu*
# 207| v0_26(void) = AliasedUse : ~m0_18
# 207| v0_26(void) = AliasedUse : ~m0_1
# 207| v0_27(void) = ExitFunction :

Просмотреть файл

@ -5,6 +5,7 @@ private newtype TMemoryAccessKind =
TBufferMayMemoryAccess() or
TEscapedMemoryAccess() or
TEscapedMayMemoryAccess() or
TNonLocalMayMemoryAccess() or
TPhiMemoryAccess() or
TUnmodeledMemoryAccess() or
TChiTotalMemoryAccess() or
@ -80,6 +81,14 @@ class EscapedMayMemoryAccess extends MemoryAccessKind, TEscapedMayMemoryAccess {
override string toString() { result = "escaped(may)" }
}
/**
* The operand or result may access all memory whose address has escaped, other than data on the
* stack frame of the current function.
*/
class NonLocalMayMemoryAccess extends MemoryAccessKind, TNonLocalMayMemoryAccess {
override string toString() { result = "nonlocal(may)" }
}
/**
* The operand is a Phi operand, which accesses the same memory as its
* definition.

Просмотреть файл

@ -389,7 +389,7 @@ class SideEffectOperand extends TypedOperand {
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof EscapedMayMemoryAccess
result instanceof NonLocalMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess

Просмотреть файл

@ -389,7 +389,7 @@ class SideEffectOperand extends TypedOperand {
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof EscapedMayMemoryAccess
result instanceof NonLocalMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess