C++/C#: Add `AliasedUse` instruction to all functions

This new instruction is the dual of the existing `AliasedDefinition` instruction. Whereas that instruction defines the contents of aliased memory before the function was called, `AliasedUse` represents the potential use of all aliased memory after the function returns. This ensures that writes to aliased memory do not appear "dead", even if there are no further reads from aliased memory within the function itself.
This commit is contained in:
Dave Bartolomeo 2019-10-23 11:59:05 -07:00
Родитель 219fcb7889
Коммит d03a4f86e5
20 изменённых файлов: 315 добавлений и 186 удалений

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

@ -57,6 +57,7 @@ private newtype TOpcode =
TUnmodeledDefinition() or
TUnmodeledUse() or
TAliasedDefinition() or
TAliasedUse() or
TPhi() or
TBuiltIn() or
TVarArgsStart() or
@ -393,6 +394,10 @@ module Opcode {
final override string toString() { result = "AliasedDefinition" }
}
class AliasedUse extends Opcode, TAliasedUse {
final override string toString() { result = "AliasedUse" }
}
class Phi extends Opcode, TPhi {
final override string toString() { result = "Phi" }
}

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

@ -49,7 +49,8 @@ module InstructionSanity {
(
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect
opcode instanceof Opcode::CallSideEffect or
opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@ -260,6 +261,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@ -1423,6 +1425,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
}
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }

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

@ -388,6 +388,9 @@ class SideEffectOperand extends TypedOperand {
}
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof EscapedMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or

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

@ -49,7 +49,8 @@ module InstructionSanity {
(
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect
opcode instanceof Opcode::CallSideEffect or
opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@ -260,6 +261,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@ -1423,6 +1425,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
}
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }

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

@ -388,6 +388,9 @@ class SideEffectOperand extends TypedOperand {
}
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof EscapedMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or

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

@ -26,6 +26,7 @@ newtype TInstructionTag =
UnmodeledDefinitionTag() or
UnmodeledUseTag() or
AliasedDefinitionTag() or
AliasedUseTag() or
SwitchBranchTag() or
CallTargetTag() or
CallTag() or
@ -118,6 +119,8 @@ string getInstructionTagId(TInstructionTag tag) {
or
tag = AliasedDefinitionTag() and result = "AliasedDef"
or
tag = AliasedUseTag() and result = "AliasedUse"
or
tag = SwitchBranchTag() and result = "SwitchBranch"
or
tag = CallTargetTag() and result = "CallTarget"

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

@ -95,6 +95,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
result = getInstruction(UnmodeledUseTag())
or
tag = UnmodeledUseTag() and
result = getInstruction(AliasedUseTag())
or
tag = AliasedUseTag() and
result = getInstruction(ExitFunctionTag())
)
}
@ -176,6 +179,11 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
resultType instanceof VoidType and
isGLValue = false
or
tag = AliasedUseTag() and
opcode instanceof Opcode::AliasedUse and
resultType instanceof VoidType and
isGLValue = false
or
tag = ExitFunctionTag() and
opcode instanceof Opcode::ExitFunction and
resultType instanceof VoidType and
@ -197,6 +205,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
operandTag instanceof UnmodeledUseOperandTag and
result = getUnmodeledDefinitionInstruction()
or
tag = AliasedUseTag() and
operandTag instanceof SideEffectOperandTag and
result = getUnmodeledDefinitionInstruction()
or
tag = ReturnTag() and
not getReturnType() instanceof VoidType and
(
@ -213,6 +225,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
not getReturnType() instanceof VoidType and
operandTag instanceof LoadOperandTag and
result = getReturnType()
or
tag = AliasedUseTag() and
operandTag instanceof SideEffectOperandTag and
result instanceof UnknownType
}
final override IRVariable getInstructionVariable(InstructionTag tag) {

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

@ -49,7 +49,8 @@ module InstructionSanity {
(
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect
opcode instanceof Opcode::CallSideEffect or
opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@ -260,6 +261,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@ -1423,6 +1425,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
}
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }

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

@ -388,6 +388,9 @@ class SideEffectOperand extends TypedOperand {
}
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof EscapedMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or

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

@ -84,7 +84,8 @@ ssa.cpp:
# 13| r6_12(glval<int>) = VariableAddress[#return] :
# 13| v6_13(void) = ReturnValue : &:r6_12, m6_11
# 13| v6_14(void) = UnmodeledUse : mu*
# 13| v6_15(void) = ExitFunction :
# 13| v6_15(void) = AliasedUse : ~m6_0
# 13| v6_16(void) = ExitFunction :
# 31| int UnreachableViaGoto()
# 31| Block 0
@ -99,7 +100,8 @@ ssa.cpp:
# 31| r0_8(glval<int>) = VariableAddress[#return] :
# 31| v0_9(void) = ReturnValue : &:r0_8, m0_7
# 31| v0_10(void) = UnmodeledUse : mu*
# 31| v0_11(void) = ExitFunction :
# 31| v0_11(void) = AliasedUse : ~m0_1
# 31| v0_12(void) = ExitFunction :
# 38| int UnreachableIf(bool)
# 38| Block 0
@ -125,7 +127,8 @@ ssa.cpp:
# 38| r1_1(glval<int>) = VariableAddress[#return] :
# 38| v1_2(void) = ReturnValue : &:r1_1, m1_0
# 38| v1_3(void) = UnmodeledUse : mu*
# 38| v1_4(void) = ExitFunction :
# 38| v1_4(void) = AliasedUse : ~m0_1
# 38| v1_5(void) = ExitFunction :
# 42| Block 2
# 42| r2_0(glval<int>) = VariableAddress[x] :
@ -188,7 +191,8 @@ ssa.cpp:
# 59| r1_4(glval<int>) = VariableAddress[#return] :
# 59| v1_5(void) = ReturnValue : &:r1_4, m1_3
# 59| v1_6(void) = UnmodeledUse : mu*
# 59| v1_7(void) = ExitFunction :
# 59| v1_7(void) = AliasedUse : ~m0_1
# 59| v1_8(void) = ExitFunction :
# 59| Block 2
# 59| v2_0(void) = Unreached :
@ -219,7 +223,8 @@ ssa.cpp:
# 71| v2_0(void) = NoOp :
# 68| v2_1(void) = ReturnVoid :
# 68| v2_2(void) = UnmodeledUse : mu*
# 68| v2_3(void) = ExitFunction :
# 68| v2_3(void) = AliasedUse : ~m3_0
# 68| v2_4(void) = ExitFunction :
# 69| Block 3
# 69| m3_0(unknown) = Phi : from 0:~m0_1, from 1:~m1_7
@ -291,7 +296,8 @@ ssa.cpp:
# 89| v3_14(void) = NoOp :
# 75| v3_15(void) = ReturnVoid :
# 75| v3_16(void) = UnmodeledUse : mu*
# 75| v3_17(void) = ExitFunction :
# 75| v3_17(void) = AliasedUse : ~m0_1
# 75| v3_18(void) = ExitFunction :
# 91| void MustExactlyOverlap(Point)
# 91| Block 0
@ -307,7 +313,8 @@ ssa.cpp:
# 93| v0_9(void) = NoOp :
# 91| v0_10(void) = ReturnVoid :
# 91| v0_11(void) = UnmodeledUse : mu*
# 91| v0_12(void) = ExitFunction :
# 91| v0_12(void) = AliasedUse : ~m0_1
# 91| v0_13(void) = ExitFunction :
# 95| void MustExactlyOverlapEscaped(Point)
# 95| Block 0
@ -333,7 +340,8 @@ ssa.cpp:
# 98| v0_19(void) = NoOp :
# 95| v0_20(void) = ReturnVoid :
# 95| v0_21(void) = UnmodeledUse : mu*
# 95| v0_22(void) = ExitFunction :
# 95| v0_22(void) = AliasedUse : ~m0_18
# 95| v0_23(void) = ExitFunction :
# 100| void MustTotallyOverlap(Point)
# 100| Block 0
@ -355,7 +363,8 @@ ssa.cpp:
# 103| v0_15(void) = NoOp :
# 100| v0_16(void) = ReturnVoid :
# 100| v0_17(void) = UnmodeledUse : mu*
# 100| v0_18(void) = ExitFunction :
# 100| v0_18(void) = AliasedUse : ~m0_1
# 100| v0_19(void) = ExitFunction :
# 105| void MustTotallyOverlapEscaped(Point)
# 105| Block 0
@ -387,7 +396,8 @@ ssa.cpp:
# 109| v0_25(void) = NoOp :
# 105| v0_26(void) = ReturnVoid :
# 105| v0_27(void) = UnmodeledUse : mu*
# 105| v0_28(void) = ExitFunction :
# 105| v0_28(void) = AliasedUse : ~m0_24
# 105| v0_29(void) = ExitFunction :
# 111| void MayPartiallyOverlap(int, int)
# 111| Block 0
@ -417,7 +427,8 @@ ssa.cpp:
# 114| v0_23(void) = NoOp :
# 111| v0_24(void) = ReturnVoid :
# 111| v0_25(void) = UnmodeledUse : mu*
# 111| v0_26(void) = ExitFunction :
# 111| v0_26(void) = AliasedUse : ~m0_1
# 111| v0_27(void) = ExitFunction :
# 116| void MayPartiallyOverlapEscaped(int, int)
# 116| Block 0
@ -457,7 +468,8 @@ ssa.cpp:
# 120| v0_33(void) = NoOp :
# 116| v0_34(void) = ReturnVoid :
# 116| v0_35(void) = UnmodeledUse : mu*
# 116| v0_36(void) = ExitFunction :
# 116| v0_36(void) = AliasedUse : ~m0_32
# 116| v0_37(void) = ExitFunction :
# 122| void MergeMustExactlyOverlap(bool, int, int)
# 122| Block 0
@ -519,7 +531,8 @@ ssa.cpp:
# 132| v3_11(void) = NoOp :
# 122| v3_12(void) = ReturnVoid :
# 122| v3_13(void) = UnmodeledUse : mu*
# 122| v3_14(void) = ExitFunction :
# 122| v3_14(void) = AliasedUse : ~m0_1
# 122| v3_15(void) = ExitFunction :
# 134| void MergeMustExactlyWithMustTotallyOverlap(bool, Point, int)
# 134| Block 0
@ -575,7 +588,8 @@ ssa.cpp:
# 143| v3_7(void) = NoOp :
# 134| v3_8(void) = ReturnVoid :
# 134| v3_9(void) = UnmodeledUse : mu*
# 134| v3_10(void) = ExitFunction :
# 134| v3_10(void) = AliasedUse : ~m0_1
# 134| v3_11(void) = ExitFunction :
# 145| void MergeMustExactlyWithMayPartiallyOverlap(bool, Point, int)
# 145| Block 0
@ -629,7 +643,8 @@ ssa.cpp:
# 154| v3_5(void) = NoOp :
# 145| v3_6(void) = ReturnVoid :
# 145| v3_7(void) = UnmodeledUse : mu*
# 145| v3_8(void) = ExitFunction :
# 145| v3_8(void) = AliasedUse : ~m0_1
# 145| v3_9(void) = ExitFunction :
# 156| void MergeMustTotallyOverlapWithMayPartiallyOverlap(bool, Rect, int)
# 156| Block 0
@ -685,7 +700,8 @@ ssa.cpp:
# 165| v3_6(void) = NoOp :
# 156| v3_7(void) = ReturnVoid :
# 156| v3_8(void) = UnmodeledUse : mu*
# 156| v3_9(void) = ExitFunction :
# 156| v3_9(void) = AliasedUse : ~m0_1
# 156| v3_10(void) = ExitFunction :
# 171| void WrapperStruct(Wrapper)
# 171| Block 0
@ -719,7 +735,8 @@ ssa.cpp:
# 177| v0_27(void) = NoOp :
# 171| v0_28(void) = ReturnVoid :
# 171| v0_29(void) = UnmodeledUse : mu*
# 171| v0_30(void) = ExitFunction :
# 171| v0_30(void) = AliasedUse : ~m0_1
# 171| v0_31(void) = ExitFunction :
# 179| int AsmStmt(int*)
# 179| Block 0
@ -738,7 +755,8 @@ ssa.cpp:
# 179| r0_12(glval<int>) = VariableAddress[#return] :
# 179| v0_13(void) = ReturnValue : &:r0_12, m0_11
# 179| v0_14(void) = UnmodeledUse : mu*
# 179| v0_15(void) = ExitFunction :
# 179| v0_15(void) = AliasedUse : ~m0_6
# 179| v0_16(void) = ExitFunction :
# 184| void AsmStmtWithOutputs(unsigned int&, unsigned int&, unsigned int&, unsigned int&)
# 184| Block 0
@ -766,7 +784,8 @@ ssa.cpp:
# 192| v0_21(void) = NoOp :
# 184| v0_22(void) = ReturnVoid :
# 184| v0_23(void) = UnmodeledUse : mu*
# 184| v0_24(void) = ExitFunction :
# 184| v0_24(void) = AliasedUse : ~m0_20
# 184| v0_25(void) = ExitFunction :
# 198| int PureFunctions(char*, char*, int)
# 198| Block 0
@ -815,7 +834,8 @@ ssa.cpp:
# 198| r0_42(glval<int>) = VariableAddress[#return] :
# 198| v0_43(void) = ReturnValue : &:r0_42, m0_41
# 198| v0_44(void) = UnmodeledUse : mu*
# 198| v0_45(void) = ExitFunction :
# 198| v0_45(void) = AliasedUse : ~m0_1
# 198| v0_46(void) = ExitFunction :
# 207| int ModeledCallTarget(int)
# 207| Block 0
@ -845,4 +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) = ExitFunction :
# 207| v0_26(void) = AliasedUse : ~m0_18
# 207| v0_27(void) = ExitFunction :

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

@ -78,7 +78,8 @@ ssa.cpp:
# 13| r6_11(glval<int>) = VariableAddress[#return] :
# 13| v6_12(void) = ReturnValue : &:r6_11, m6_10
# 13| v6_13(void) = UnmodeledUse : mu*
# 13| v6_14(void) = ExitFunction :
# 13| v6_14(void) = AliasedUse : ~mu0_2
# 13| v6_15(void) = ExitFunction :
# 31| int UnreachableViaGoto()
# 31| Block 0
@ -93,7 +94,8 @@ ssa.cpp:
# 31| r0_8(glval<int>) = VariableAddress[#return] :
# 31| v0_9(void) = ReturnValue : &:r0_8, m0_7
# 31| v0_10(void) = UnmodeledUse : mu*
# 31| v0_11(void) = ExitFunction :
# 31| v0_11(void) = AliasedUse : ~mu0_2
# 31| v0_12(void) = ExitFunction :
# 38| int UnreachableIf(bool)
# 38| Block 0
@ -119,7 +121,8 @@ ssa.cpp:
# 38| r1_1(glval<int>) = VariableAddress[#return] :
# 38| v1_2(void) = ReturnValue : &:r1_1, m1_0
# 38| v1_3(void) = UnmodeledUse : mu*
# 38| v1_4(void) = ExitFunction :
# 38| v1_4(void) = AliasedUse : ~mu0_2
# 38| v1_5(void) = ExitFunction :
# 42| Block 2
# 42| r2_0(glval<int>) = VariableAddress[x] :
@ -191,7 +194,8 @@ ssa.cpp:
# 59| r1_4(glval<int>) = VariableAddress[#return] :
# 59| v1_5(void) = ReturnValue : &:r1_4, m1_3
# 59| v1_6(void) = UnmodeledUse : mu*
# 59| v1_7(void) = ExitFunction :
# 59| v1_7(void) = AliasedUse : ~mu0_2
# 59| v1_8(void) = ExitFunction :
# 59| Block 2
# 59| v2_0(void) = Unreached :
@ -221,7 +225,8 @@ ssa.cpp:
# 71| v2_0(void) = NoOp :
# 68| v2_1(void) = ReturnVoid :
# 68| v2_2(void) = UnmodeledUse : mu*
# 68| v2_3(void) = ExitFunction :
# 68| v2_3(void) = AliasedUse : ~mu0_2
# 68| v2_4(void) = ExitFunction :
# 69| Block 3
# 69| m3_0(int) = Phi : from 0:m0_4, from 1:m3_6
@ -292,7 +297,8 @@ ssa.cpp:
# 89| v3_14(void) = NoOp :
# 75| v3_15(void) = ReturnVoid :
# 75| v3_16(void) = UnmodeledUse : mu*
# 75| v3_17(void) = ExitFunction :
# 75| v3_17(void) = AliasedUse : ~mu0_2
# 75| v3_18(void) = ExitFunction :
# 91| void MustExactlyOverlap(Point)
# 91| Block 0
@ -308,7 +314,8 @@ ssa.cpp:
# 93| v0_9(void) = NoOp :
# 91| v0_10(void) = ReturnVoid :
# 91| v0_11(void) = UnmodeledUse : mu*
# 91| v0_12(void) = ExitFunction :
# 91| v0_12(void) = AliasedUse : ~mu0_2
# 91| v0_13(void) = ExitFunction :
# 95| void MustExactlyOverlapEscaped(Point)
# 95| Block 0
@ -331,7 +338,8 @@ ssa.cpp:
# 98| v0_16(void) = NoOp :
# 95| v0_17(void) = ReturnVoid :
# 95| v0_18(void) = UnmodeledUse : mu*
# 95| v0_19(void) = ExitFunction :
# 95| v0_19(void) = AliasedUse : ~mu0_2
# 95| v0_20(void) = ExitFunction :
# 100| void MustTotallyOverlap(Point)
# 100| Block 0
@ -353,7 +361,8 @@ ssa.cpp:
# 103| v0_15(void) = NoOp :
# 100| v0_16(void) = ReturnVoid :
# 100| v0_17(void) = UnmodeledUse : mu*
# 100| v0_18(void) = ExitFunction :
# 100| v0_18(void) = AliasedUse : ~mu0_2
# 100| v0_19(void) = ExitFunction :
# 105| void MustTotallyOverlapEscaped(Point)
# 105| Block 0
@ -382,7 +391,8 @@ ssa.cpp:
# 109| v0_22(void) = NoOp :
# 105| v0_23(void) = ReturnVoid :
# 105| v0_24(void) = UnmodeledUse : mu*
# 105| v0_25(void) = ExitFunction :
# 105| v0_25(void) = AliasedUse : ~mu0_2
# 105| v0_26(void) = ExitFunction :
# 111| void MayPartiallyOverlap(int, int)
# 111| Block 0
@ -410,7 +420,8 @@ ssa.cpp:
# 114| v0_21(void) = NoOp :
# 111| v0_22(void) = ReturnVoid :
# 111| v0_23(void) = UnmodeledUse : mu*
# 111| v0_24(void) = ExitFunction :
# 111| v0_24(void) = AliasedUse : ~mu0_2
# 111| v0_25(void) = ExitFunction :
# 116| void MayPartiallyOverlapEscaped(int, int)
# 116| Block 0
@ -445,7 +456,8 @@ ssa.cpp:
# 120| v0_28(void) = NoOp :
# 116| v0_29(void) = ReturnVoid :
# 116| v0_30(void) = UnmodeledUse : mu*
# 116| v0_31(void) = ExitFunction :
# 116| v0_31(void) = AliasedUse : ~mu0_2
# 116| v0_32(void) = ExitFunction :
# 122| void MergeMustExactlyOverlap(bool, int, int)
# 122| Block 0
@ -501,7 +513,8 @@ ssa.cpp:
# 132| v3_9(void) = NoOp :
# 122| v3_10(void) = ReturnVoid :
# 122| v3_11(void) = UnmodeledUse : mu*
# 122| v3_12(void) = ExitFunction :
# 122| v3_12(void) = AliasedUse : ~mu0_2
# 122| v3_13(void) = ExitFunction :
# 134| void MergeMustExactlyWithMustTotallyOverlap(bool, Point, int)
# 134| Block 0
@ -552,7 +565,8 @@ ssa.cpp:
# 143| v3_5(void) = NoOp :
# 134| v3_6(void) = ReturnVoid :
# 134| v3_7(void) = UnmodeledUse : mu*
# 134| v3_8(void) = ExitFunction :
# 134| v3_8(void) = AliasedUse : ~mu0_2
# 134| v3_9(void) = ExitFunction :
# 145| void MergeMustExactlyWithMayPartiallyOverlap(bool, Point, int)
# 145| Block 0
@ -602,7 +616,8 @@ ssa.cpp:
# 154| v3_4(void) = NoOp :
# 145| v3_5(void) = ReturnVoid :
# 145| v3_6(void) = UnmodeledUse : mu*
# 145| v3_7(void) = ExitFunction :
# 145| v3_7(void) = AliasedUse : ~mu0_2
# 145| v3_8(void) = ExitFunction :
# 156| void MergeMustTotallyOverlapWithMayPartiallyOverlap(bool, Rect, int)
# 156| Block 0
@ -654,7 +669,8 @@ ssa.cpp:
# 165| v3_5(void) = NoOp :
# 156| v3_6(void) = ReturnVoid :
# 156| v3_7(void) = UnmodeledUse : mu*
# 156| v3_8(void) = ExitFunction :
# 156| v3_8(void) = AliasedUse : ~mu0_2
# 156| v3_9(void) = ExitFunction :
# 171| void WrapperStruct(Wrapper)
# 171| Block 0
@ -688,7 +704,8 @@ ssa.cpp:
# 177| v0_27(void) = NoOp :
# 171| v0_28(void) = ReturnVoid :
# 171| v0_29(void) = UnmodeledUse : mu*
# 171| v0_30(void) = ExitFunction :
# 171| v0_30(void) = AliasedUse : ~mu0_2
# 171| v0_31(void) = ExitFunction :
# 179| int AsmStmt(int*)
# 179| Block 0
@ -706,7 +723,8 @@ ssa.cpp:
# 179| r0_11(glval<int>) = VariableAddress[#return] :
# 179| v0_12(void) = ReturnValue : &:r0_11, m0_10
# 179| v0_13(void) = UnmodeledUse : mu*
# 179| v0_14(void) = ExitFunction :
# 179| v0_14(void) = AliasedUse : ~mu0_2
# 179| v0_15(void) = ExitFunction :
# 184| void AsmStmtWithOutputs(unsigned int&, unsigned int&, unsigned int&, unsigned int&)
# 184| Block 0
@ -729,7 +747,8 @@ ssa.cpp:
# 192| v0_16(void) = NoOp :
# 184| v0_17(void) = ReturnVoid :
# 184| v0_18(void) = UnmodeledUse : mu*
# 184| v0_19(void) = ExitFunction :
# 184| v0_19(void) = AliasedUse : ~mu0_2
# 184| v0_20(void) = ExitFunction :
# 198| int PureFunctions(char*, char*, int)
# 198| Block 0
@ -778,7 +797,8 @@ ssa.cpp:
# 198| r0_42(glval<int>) = VariableAddress[#return] :
# 198| v0_43(void) = ReturnValue : &:r0_42, m0_41
# 198| v0_44(void) = UnmodeledUse : mu*
# 198| v0_45(void) = ExitFunction :
# 198| v0_45(void) = AliasedUse : ~mu0_2
# 198| v0_46(void) = ExitFunction :
# 207| int ModeledCallTarget(int)
# 207| Block 0
@ -805,4 +825,5 @@ ssa.cpp:
# 207| r0_20(glval<int>) = VariableAddress[#return] :
# 207| v0_21(void) = ReturnValue : &:r0_20, m0_19
# 207| v0_22(void) = UnmodeledUse : mu*
# 207| v0_23(void) = ExitFunction :
# 207| v0_23(void) = AliasedUse : ~mu0_2
# 207| v0_24(void) = ExitFunction :

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

@ -611,86 +611,6 @@ lostReachability
| range_analysis.c:371:37:371:39 | Constant: 500 |
backEdgeCountMismatch
useNotDominatedByDefinition
| VacuousDestructorCall.cpp:4:3:4:3 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | IR: CallDestructor | void CallDestructor<int>(int, int*) |
| assume0.cpp:11:2:11:2 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | assume0.cpp:5:6:5:6 | IR: h | void h() |
| condition_decls.cpp:16:15:16:15 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:16:15:16:16 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:16:15:16:16 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:17:5:17:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:17:11:17:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:20:5:20:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:20:11:20:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:26:19:26:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:26:19:26:20 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:26:19:26:20 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:28:5:28:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:28:11:28:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:31:5:31:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:31:11:31:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:34:5:34:18 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:34:9:34:13 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:41:18:41:18 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) |
| condition_decls.cpp:41:18:41:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) |
| condition_decls.cpp:41:18:41:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) |
| condition_decls.cpp:42:5:42:7 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) |
| condition_decls.cpp:44:3:44:5 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) |
| condition_decls.cpp:48:48:48:48 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) |
| condition_decls.cpp:48:48:48:49 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) |
| condition_decls.cpp:48:48:48:49 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) |
| condition_decls.cpp:48:56:48:61 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) |
| condition_decls.cpp:49:5:49:7 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) |
| condition_decls.cpp:51:3:51:5 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) |
| cpp11.cpp:28:21:28:21 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | cpp11.cpp:27:7:27:14 | IR: getFirst | int range_based_for_11::getFirst() |
| file://:0:0:0:0 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | cpp11.cpp:27:7:27:14 | IR: getFirst | int range_based_for_11::getFirst() |
| misc.c:68:16:68:16 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:70:13:70:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:72:11:72:11 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:82:5:82:12 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:83:5:83:12 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:83:14:83:14 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:83:17:83:17 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:84:6:84:13 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:84:6:84:13 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:84:16:84:16 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:84:19:84:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:85:9:85:13 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:86:9:86:9 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:87:10:87:10 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:88:9:88:9 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:88:9:88:17 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:171:15:171:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:168:6:168:8 | IR: vla | void vla() |
| misc.c:173:19:173:24 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:168:6:168:8 | IR: vla | void vla() |
| misc.c:174:17:174:22 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:168:6:168:8 | IR: vla | void vla() |
| misc.c:174:30:174:35 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:168:6:168:8 | IR: vla | void vla() |
| misc.c:219:5:219:26 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:219:5:219:26 | IR: assign_designated_init | int assign_designated_init(someStruct*) |
| misc.c:220:4:220:5 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:219:5:219:26 | IR: assign_designated_init | int assign_designated_init(someStruct*) |
| ms_try_except.cpp:9:19:9:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | IR: ms_try_except | void ms_try_except(int) |
| ms_try_except.cpp:19:17:19:17 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | IR: ms_try_except | void ms_try_except(int) |
| ms_try_mix.cpp:14:16:14:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) |
| ms_try_mix.cpp:15:13:15:14 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) |
| ms_try_mix.cpp:16:13:16:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) |
| ms_try_mix.cpp:18:16:18:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) |
| ms_try_mix.cpp:21:16:21:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) |
| ms_try_mix.cpp:24:12:24:15 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) |
| ms_try_mix.cpp:31:16:31:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) |
| ms_try_mix.cpp:32:13:32:14 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) |
| ms_try_mix.cpp:33:13:33:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) |
| ms_try_mix.cpp:35:16:35:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) |
| ms_try_mix.cpp:38:16:38:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) |
| ms_try_mix.cpp:41:12:41:15 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) |
| ms_try_mix.cpp:51:5:51:11 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:47:6:47:28 | IR: ms_empty_finally_at_end | void ms_empty_finally_at_end() |
| pointer_to_member.cpp:36:11:36:30 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | pointer_to_member.cpp:32:6:32:14 | IR: pmIsConst | void pmIsConst() |
| pointer_to_member.cpp:36:13:36:19 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | pointer_to_member.cpp:32:6:32:14 | IR: pmIsConst | void pmIsConst() |
| stmt_expr.cpp:30:20:30:21 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | stmt_expr.cpp:21:6:21:6 | IR: g | void stmtexpr::g(int) |
| stmt_expr.cpp:31:16:31:18 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | stmt_expr.cpp:21:6:21:6 | IR: g | void stmtexpr::g(int) |
| try_catch.cpp:21:13:21:24 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | try_catch.cpp:19:6:19:23 | IR: throw_from_nonstmt | void throw_from_nonstmt(int) |
| vla.c:3:5:3:8 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) |
| vla.c:5:16:5:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) |
| vla.c:5:22:5:25 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) |
| vla.c:5:27:5:30 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) |
| vla.c:5:27:5:33 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) |
| vla.c:12:37:12:42 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() |
| vla.c:12:55:12:60 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() |
| vla.c:14:40:14:45 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() |
| vla.c:14:58:14:63 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() |
| vla.c:14:74:14:79 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() |

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

@ -57,6 +57,7 @@ private newtype TOpcode =
TUnmodeledDefinition() or
TUnmodeledUse() or
TAliasedDefinition() or
TAliasedUse() or
TPhi() or
TBuiltIn() or
TVarArgsStart() or
@ -393,6 +394,10 @@ module Opcode {
final override string toString() { result = "AliasedDefinition" }
}
class AliasedUse extends Opcode, TAliasedUse {
final override string toString() { result = "AliasedUse" }
}
class Phi extends Opcode, TPhi {
final override string toString() { result = "Phi" }
}

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

@ -49,7 +49,8 @@ module InstructionSanity {
(
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect
opcode instanceof Opcode::CallSideEffect or
opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@ -260,6 +261,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@ -1423,6 +1425,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
}
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }

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

@ -388,6 +388,9 @@ class SideEffectOperand extends TypedOperand {
}
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof EscapedMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or

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

@ -32,6 +32,7 @@ newtype TInstructionTag =
UnmodeledDefinitionTag() or
UnmodeledUseTag() or
AliasedDefinitionTag() or
AliasedUseTag() or
SwitchBranchTag() or
CallTargetTag() or
CallTag() or
@ -131,6 +132,8 @@ string getInstructionTagId(TInstructionTag tag) {
or
tag = AliasedDefinitionTag() and result = "AliasedDef"
or
tag = AliasedUseTag() and result = "AliasedUse"
or
tag = SwitchBranchTag() and result = "SwitchBranch"
or
tag = CallTargetTag() and result = "CallTarget"

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

@ -98,6 +98,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
result = this.getInstruction(UnmodeledUseTag())
or
tag = UnmodeledUseTag() and
result = getInstruction(AliasedUseTag())
or
tag = AliasedUseTag() and
result = this.getInstruction(ExitFunctionTag())
)
}
@ -181,6 +184,11 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
resultType instanceof VoidType and
isLValue = false
or
tag = AliasedUseTag() and
opcode instanceof Opcode::AliasedUse and
resultType instanceof VoidType and
isLValue = false
or
tag = ExitFunctionTag() and
opcode instanceof Opcode::ExitFunction and
resultType instanceof VoidType and
@ -202,6 +210,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
operandTag instanceof UnmodeledUseOperandTag and
result = getUnmodeledDefinitionInstruction()
or
tag = AliasedUseTag() and
operandTag instanceof SideEffectOperandTag and
result = getUnmodeledDefinitionInstruction()
or
tag = ReturnTag() and
not this.getReturnType() instanceof VoidType and
(
@ -218,6 +230,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
not this.getReturnType() instanceof VoidType and
operandTag instanceof LoadOperandTag and
result = this.getReturnType()
or
tag = AliasedUseTag() and
operandTag instanceof SideEffectOperandTag and
result instanceof Language::UnknownType
}
final override IRVariable getInstructionVariable(InstructionTag tag) {

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

@ -49,7 +49,8 @@ module InstructionSanity {
(
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect
opcode instanceof Opcode::CallSideEffect or
opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@ -260,6 +261,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@ -1423,6 +1425,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
}
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }

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

@ -388,6 +388,9 @@ class SideEffectOperand extends TypedOperand {
}
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof EscapedMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or

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

@ -53,7 +53,8 @@ array.cs:
# 10| mu0_49(Int32) = Store : &:r0_48, r0_43
# 2| v0_50(Void) = ReturnVoid :
# 2| v0_51(Void) = UnmodeledUse : mu*
# 2| v0_52(Void) = ExitFunction :
# 2| v0_52(Void) = AliasedUse : ~mu0_2
# 2| v0_53(Void) = ExitFunction :
# 13| System.Void ArrayTest.twod_and_init_acc()
# 13| Block 0
@ -144,7 +145,8 @@ array.cs:
# 20| mu0_84(Int32) = Store : &:r0_83, r0_76
# 13| v0_85(Void) = ReturnVoid :
# 13| v0_86(Void) = UnmodeledUse : mu*
# 13| v0_87(Void) = ExitFunction :
# 13| v0_87(Void) = AliasedUse : ~mu0_2
# 13| v0_88(Void) = ExitFunction :
assignop.cs:
# 4| System.Void AssignOp.Main()
@ -215,7 +217,8 @@ assignop.cs:
# 17| mu0_63(Int32) = Store : &:r0_60, r0_62
# 4| v0_64(Void) = ReturnVoid :
# 4| v0_65(Void) = UnmodeledUse : mu*
# 4| v0_66(Void) = ExitFunction :
# 4| v0_66(Void) = AliasedUse : ~mu0_2
# 4| v0_67(Void) = ExitFunction :
casts.cs:
# 11| System.Void Casts.Main()
@ -241,7 +244,8 @@ casts.cs:
# 15| mu0_18(Casts_B) = Store : &:r0_14, r0_17
# 11| v0_19(Void) = ReturnVoid :
# 11| v0_20(Void) = UnmodeledUse : mu*
# 11| v0_21(Void) = ExitFunction :
# 11| v0_21(Void) = AliasedUse : ~mu0_2
# 11| v0_22(Void) = ExitFunction :
collections.cs:
# 11| System.Void Collections.Main()
@ -285,7 +289,8 @@ collections.cs:
# 13| mu0_36(Dictionary<Int32,MyClass>) = Store : &:r0_3, r0_4
# 11| v0_37(Void) = ReturnVoid :
# 11| v0_38(Void) = UnmodeledUse : mu*
# 11| v0_39(Void) = ExitFunction :
# 11| v0_39(Void) = AliasedUse : ~mu0_2
# 11| v0_40(Void) = ExitFunction :
constructor_init.cs:
# 5| System.Void BaseClass..ctor()
@ -297,7 +302,8 @@ constructor_init.cs:
# 6| v0_4(Void) = NoOp :
# 5| v0_5(Void) = ReturnVoid :
# 5| v0_6(Void) = UnmodeledUse : mu*
# 5| v0_7(Void) = ExitFunction :
# 5| v0_7(Void) = AliasedUse : ~mu0_2
# 5| v0_8(Void) = ExitFunction :
# 9| System.Void BaseClass..ctor(System.Int32)
# 9| Block 0
@ -314,7 +320,8 @@ constructor_init.cs:
# 11| mu0_10(Int32) = Store : &:r0_9, r0_7
# 9| v0_11(Void) = ReturnVoid :
# 9| v0_12(Void) = UnmodeledUse : mu*
# 9| v0_13(Void) = ExitFunction :
# 9| v0_13(Void) = AliasedUse : ~mu0_2
# 9| v0_14(Void) = ExitFunction :
# 17| System.Void DerivedClass..ctor()
# 17| Block 0
@ -329,7 +336,8 @@ constructor_init.cs:
# 18| v0_8(Void) = NoOp :
# 17| v0_9(Void) = ReturnVoid :
# 17| v0_10(Void) = UnmodeledUse : mu*
# 17| v0_11(Void) = ExitFunction :
# 17| v0_11(Void) = AliasedUse : ~mu0_2
# 17| v0_12(Void) = ExitFunction :
# 21| System.Void DerivedClass..ctor(System.Int32)
# 21| Block 0
@ -348,7 +356,8 @@ constructor_init.cs:
# 22| v0_12(Void) = NoOp :
# 21| v0_13(Void) = ReturnVoid :
# 21| v0_14(Void) = UnmodeledUse : mu*
# 21| v0_15(Void) = ExitFunction :
# 21| v0_15(Void) = AliasedUse : ~mu0_2
# 21| v0_16(Void) = ExitFunction :
# 25| System.Void DerivedClass..ctor(System.Int32,System.Int32)
# 25| Block 0
@ -368,7 +377,8 @@ constructor_init.cs:
# 26| v0_13(Void) = NoOp :
# 25| v0_14(Void) = ReturnVoid :
# 25| v0_15(Void) = UnmodeledUse : mu*
# 25| v0_16(Void) = ExitFunction :
# 25| v0_16(Void) = AliasedUse : ~mu0_2
# 25| v0_17(Void) = ExitFunction :
# 29| System.Void DerivedClass.Main()
# 29| Block 0
@ -398,7 +408,8 @@ constructor_init.cs:
# 33| mu0_23(DerivedClass) = Store : &:r0_16, r0_17
# 29| v0_24(Void) = ReturnVoid :
# 29| v0_25(Void) = UnmodeledUse : mu*
# 29| v0_26(Void) = ExitFunction :
# 29| v0_26(Void) = AliasedUse : ~mu0_2
# 29| v0_27(Void) = ExitFunction :
crement.cs:
# 3| System.Void CrementOpsTest.Main()
@ -439,7 +450,8 @@ crement.cs:
# 9| mu0_33(Int32) = Store : &:r0_32, r0_28
# 3| v0_34(Void) = ReturnVoid :
# 3| v0_35(Void) = UnmodeledUse : mu*
# 3| v0_36(Void) = ExitFunction :
# 3| v0_36(Void) = AliasedUse : ~mu0_2
# 3| v0_37(Void) = ExitFunction :
delegates.cs:
# 6| System.Int32 Delegates.returns(System.Int32)
@ -456,7 +468,8 @@ delegates.cs:
# 6| r0_9(glval<Int32>) = VariableAddress[#return] :
# 6| v0_10(Void) = ReturnValue : &:r0_9, ~mu0_2
# 6| v0_11(Void) = UnmodeledUse : mu*
# 6| v0_12(Void) = ExitFunction :
# 6| v0_12(Void) = AliasedUse : ~mu0_2
# 6| v0_13(Void) = ExitFunction :
# 11| System.Void Delegates.Main()
# 11| Block 0
@ -478,7 +491,8 @@ delegates.cs:
# 13| mu0_15(null) = ^CallSideEffect : ~mu0_2
# 11| v0_16(Void) = ReturnVoid :
# 11| v0_17(Void) = UnmodeledUse : mu*
# 11| v0_18(Void) = ExitFunction :
# 11| v0_18(Void) = AliasedUse : ~mu0_2
# 11| v0_19(Void) = ExitFunction :
events.cs:
# 8| System.Void Events..ctor()
@ -497,7 +511,8 @@ events.cs:
# 10| mu0_11(MyDel) = Store : &:r0_10, r0_4
# 8| v0_12(Void) = ReturnVoid :
# 8| v0_13(Void) = UnmodeledUse : mu*
# 8| v0_14(Void) = ExitFunction :
# 8| v0_14(Void) = AliasedUse : ~mu0_2
# 8| v0_15(Void) = ExitFunction :
# 13| System.Void Events.AddEvent()
# 13| Block 0
@ -514,7 +529,8 @@ events.cs:
# 15| mu0_10(null) = ^CallSideEffect : ~mu0_2
# 13| v0_11(Void) = ReturnVoid :
# 13| v0_12(Void) = UnmodeledUse : mu*
# 13| v0_13(Void) = ExitFunction :
# 13| v0_13(Void) = AliasedUse : ~mu0_2
# 13| v0_14(Void) = ExitFunction :
# 18| System.Void Events.RemoveEvent()
# 18| Block 0
@ -531,7 +547,8 @@ events.cs:
# 20| mu0_10(null) = ^CallSideEffect : ~mu0_2
# 18| v0_11(Void) = ReturnVoid :
# 18| v0_12(Void) = UnmodeledUse : mu*
# 18| v0_13(Void) = ExitFunction :
# 18| v0_13(Void) = AliasedUse : ~mu0_2
# 18| v0_14(Void) = ExitFunction :
# 23| System.String Events.Fun(System.String)
# 23| Block 0
@ -548,7 +565,8 @@ events.cs:
# 23| r0_10(glval<String>) = VariableAddress[#return] :
# 23| v0_11(Void) = ReturnValue : &:r0_10, ~mu0_2
# 23| v0_12(Void) = UnmodeledUse : mu*
# 23| v0_13(Void) = ExitFunction :
# 23| v0_13(Void) = AliasedUse : ~mu0_2
# 23| v0_14(Void) = ExitFunction :
# 28| System.Void Events.Main(System.String[])
# 28| Block 0
@ -583,7 +601,8 @@ events.cs:
# 33| mu0_28(null) = ^CallSideEffect : ~mu0_2
# 28| v0_29(Void) = ReturnVoid :
# 28| v0_30(Void) = UnmodeledUse : mu*
# 28| v0_31(Void) = ExitFunction :
# 28| v0_31(Void) = AliasedUse : ~mu0_2
# 28| v0_32(Void) = ExitFunction :
foreach.cs:
# 4| System.Void ForEach.Main()
@ -662,7 +681,8 @@ foreach.cs:
# 7| mu3_4(null) = ^CallSideEffect : ~mu0_2
# 4| v3_5(Void) = ReturnVoid :
# 4| v3_6(Void) = UnmodeledUse : mu*
# 4| v3_7(Void) = ExitFunction :
# 4| v3_7(Void) = AliasedUse : ~mu0_2
# 4| v3_8(Void) = ExitFunction :
func_with_param_call.cs:
# 5| System.Int32 test_call_with_param.f(System.Int32,System.Int32)
@ -684,7 +704,8 @@ func_with_param_call.cs:
# 5| r0_14(glval<Int32>) = VariableAddress[#return] :
# 5| v0_15(Void) = ReturnValue : &:r0_14, ~mu0_2
# 5| v0_16(Void) = UnmodeledUse : mu*
# 5| v0_17(Void) = ExitFunction :
# 5| v0_17(Void) = AliasedUse : ~mu0_2
# 5| v0_18(Void) = ExitFunction :
# 10| System.Int32 test_call_with_param.g()
# 10| Block 0
@ -701,7 +722,8 @@ func_with_param_call.cs:
# 10| r0_10(glval<Int32>) = VariableAddress[#return] :
# 10| v0_11(Void) = ReturnValue : &:r0_10, ~mu0_2
# 10| v0_12(Void) = UnmodeledUse : mu*
# 10| v0_13(Void) = ExitFunction :
# 10| v0_13(Void) = AliasedUse : ~mu0_2
# 10| v0_14(Void) = ExitFunction :
indexers.cs:
# 8| System.String Indexers.MyClass.get_Item(System.Int32)
@ -724,7 +746,8 @@ indexers.cs:
# 8| r0_15(glval<String>) = VariableAddress[#return] :
# 8| v0_16(Void) = ReturnValue : &:r0_15, ~mu0_2
# 8| v0_17(Void) = UnmodeledUse : mu*
# 8| v0_18(Void) = ExitFunction :
# 8| v0_18(Void) = AliasedUse : ~mu0_2
# 8| v0_19(Void) = ExitFunction :
# 12| System.Void Indexers.MyClass.set_Item(System.Int32,System.String)
# 12| Block 0
@ -747,7 +770,8 @@ indexers.cs:
# 14| mu0_16(String) = Store : &:r0_15, r0_9
# 12| v0_17(Void) = ReturnVoid :
# 12| v0_18(Void) = UnmodeledUse : mu*
# 12| v0_19(Void) = ExitFunction :
# 12| v0_19(Void) = AliasedUse : ~mu0_2
# 12| v0_20(Void) = ExitFunction :
# 19| System.Void Indexers.Main()
# 19| Block 0
@ -788,7 +812,8 @@ indexers.cs:
# 24| mu0_34(null) = ^CallSideEffect : ~mu0_2
# 19| v0_35(Void) = ReturnVoid :
# 19| v0_36(Void) = UnmodeledUse : mu*
# 19| v0_37(Void) = ExitFunction :
# 19| v0_37(Void) = AliasedUse : ~mu0_2
# 19| v0_38(Void) = ExitFunction :
inheritance_polymorphism.cs:
# 3| System.Int32 A.function()
@ -803,7 +828,8 @@ inheritance_polymorphism.cs:
# 3| r0_7(glval<Int32>) = VariableAddress[#return] :
# 3| v0_8(Void) = ReturnValue : &:r0_7, ~mu0_2
# 3| v0_9(Void) = UnmodeledUse : mu*
# 3| v0_10(Void) = ExitFunction :
# 3| v0_10(Void) = AliasedUse : ~mu0_2
# 3| v0_11(Void) = ExitFunction :
# 15| System.Int32 C.function()
# 15| Block 0
@ -817,7 +843,8 @@ inheritance_polymorphism.cs:
# 15| r0_7(glval<Int32>) = VariableAddress[#return] :
# 15| v0_8(Void) = ReturnValue : &:r0_7, ~mu0_2
# 15| v0_9(Void) = UnmodeledUse : mu*
# 15| v0_10(Void) = ExitFunction :
# 15| v0_10(Void) = AliasedUse : ~mu0_2
# 15| v0_11(Void) = ExitFunction :
# 23| System.Void Program.Main()
# 23| Block 0
@ -861,7 +888,8 @@ inheritance_polymorphism.cs:
# 34| mu0_37(null) = ^CallSideEffect : ~mu0_2
# 23| v0_38(Void) = ReturnVoid :
# 23| v0_39(Void) = UnmodeledUse : mu*
# 23| v0_40(Void) = ExitFunction :
# 23| v0_40(Void) = AliasedUse : ~mu0_2
# 23| v0_41(Void) = ExitFunction :
inoutref.cs:
# 11| System.Void InOutRef.set(MyClass,MyClass)
@ -880,7 +908,8 @@ inoutref.cs:
# 13| mu0_11(MyClass) = Store : &:r0_10, r0_8
# 11| v0_12(Void) = ReturnVoid :
# 11| v0_13(Void) = UnmodeledUse : mu*
# 11| v0_14(Void) = ExitFunction :
# 11| v0_14(Void) = AliasedUse : ~mu0_2
# 11| v0_15(Void) = ExitFunction :
# 16| System.Void InOutRef.F(System.Int32,MyStruct,MyStruct,MyClass,MyClass)
# 16| Block 0
@ -939,7 +968,8 @@ inoutref.cs:
# 26| mu0_52(null) = ^CallSideEffect : ~mu0_2
# 16| v0_53(Void) = ReturnVoid :
# 16| v0_54(Void) = UnmodeledUse : mu*
# 16| v0_55(Void) = ExitFunction :
# 16| v0_55(Void) = AliasedUse : ~mu0_2
# 16| v0_56(Void) = ExitFunction :
# 29| System.Void InOutRef.Main()
# 29| Block 0
@ -977,7 +1007,8 @@ inoutref.cs:
# 36| mu0_31(Int32) = Store : &:r0_27, r0_30
# 29| v0_32(Void) = ReturnVoid :
# 29| v0_33(Void) = UnmodeledUse : mu*
# 29| v0_34(Void) = ExitFunction :
# 29| v0_34(Void) = AliasedUse : ~mu0_2
# 29| v0_35(Void) = ExitFunction :
isexpr.cs:
# 8| System.Void IsExpr.Main()
@ -1008,7 +1039,8 @@ isexpr.cs:
# 8| Block 1
# 8| v1_0(Void) = ReturnVoid :
# 8| v1_1(Void) = UnmodeledUse : mu*
# 8| v1_2(Void) = ExitFunction :
# 8| v1_2(Void) = AliasedUse : ~mu0_2
# 8| v1_3(Void) = ExitFunction :
# 13| Block 2
# 13| v2_0(Void) = ConditionalBranch : r0_18
@ -1214,7 +1246,8 @@ jumps.cs:
# 38| mu22_4(null) = ^CallSideEffect : ~mu0_2
# 5| v22_5(Void) = ReturnVoid :
# 5| v22_6(Void) = UnmodeledUse : mu*
# 5| v22_7(Void) = ExitFunction :
# 5| v22_7(Void) = AliasedUse : ~mu0_2
# 5| v22_8(Void) = ExitFunction :
lock.cs:
# 5| System.Void LockTest.A()
@ -1258,7 +1291,8 @@ lock.cs:
# 5| Block 1
# 5| v1_0(Void) = ReturnVoid :
# 5| v1_1(Void) = UnmodeledUse : mu*
# 5| v1_2(Void) = ExitFunction :
# 5| v1_2(Void) = AliasedUse : ~mu0_2
# 5| v1_3(Void) = ExitFunction :
# 8| Block 2
# 8| r2_0(glval<null>) = FunctionAddress[Exit] :
@ -1278,7 +1312,8 @@ obj_creation.cs:
# 8| v0_4(Void) = NoOp :
# 7| v0_5(Void) = ReturnVoid :
# 7| v0_6(Void) = UnmodeledUse : mu*
# 7| v0_7(Void) = ExitFunction :
# 7| v0_7(Void) = AliasedUse : ~mu0_2
# 7| v0_8(Void) = ExitFunction :
# 11| System.Void ObjCreation.MyClass..ctor(System.Int32)
# 11| Block 0
@ -1295,7 +1330,8 @@ obj_creation.cs:
# 13| mu0_10(Int32) = Store : &:r0_9, r0_7
# 11| v0_11(Void) = ReturnVoid :
# 11| v0_12(Void) = UnmodeledUse : mu*
# 11| v0_13(Void) = ExitFunction :
# 11| v0_13(Void) = AliasedUse : ~mu0_2
# 11| v0_14(Void) = ExitFunction :
# 17| System.Void ObjCreation.SomeFun(ObjCreation.MyClass)
# 17| Block 0
@ -1307,7 +1343,8 @@ obj_creation.cs:
# 18| v0_5(Void) = NoOp :
# 17| v0_6(Void) = ReturnVoid :
# 17| v0_7(Void) = UnmodeledUse : mu*
# 17| v0_8(Void) = ExitFunction :
# 17| v0_8(Void) = AliasedUse : ~mu0_2
# 17| v0_9(Void) = ExitFunction :
# 21| System.Void ObjCreation.Main()
# 21| Block 0
@ -1346,7 +1383,8 @@ obj_creation.cs:
# 27| mu0_32(null) = ^CallSideEffect : ~mu0_2
# 21| v0_33(Void) = ReturnVoid :
# 21| v0_34(Void) = UnmodeledUse : mu*
# 21| v0_35(Void) = ExitFunction :
# 21| v0_35(Void) = AliasedUse : ~mu0_2
# 21| v0_36(Void) = ExitFunction :
pointers.cs:
# 3| System.Void Pointers.addone(System.Int32[])
@ -1380,7 +1418,8 @@ pointers.cs:
# 3| Block 1
# 3| v1_0(Void) = ReturnVoid :
# 3| v1_1(Void) = UnmodeledUse : mu*
# 3| v1_2(Void) = ExitFunction :
# 3| v1_2(Void) = AliasedUse : ~mu0_2
# 3| v1_3(Void) = ExitFunction :
# 9| Block 2
# 9| r2_0(glval<Int32>) = VariableAddress[i] :
@ -1475,7 +1514,8 @@ pointers.cs:
# 40| mu0_61(null) = ^CallSideEffect : ~mu0_2
# 25| v0_62(Void) = ReturnVoid :
# 25| v0_63(Void) = UnmodeledUse : mu*
# 25| v0_64(Void) = ExitFunction :
# 25| v0_64(Void) = AliasedUse : ~mu0_2
# 25| v0_65(Void) = ExitFunction :
prop.cs:
# 7| System.Int32 PropClass.get_Prop()
@ -1493,7 +1533,8 @@ prop.cs:
# 7| r0_10(glval<Int32>) = VariableAddress[#return] :
# 7| v0_11(Void) = ReturnValue : &:r0_10, ~mu0_2
# 7| v0_12(Void) = UnmodeledUse : mu*
# 7| v0_13(Void) = ExitFunction :
# 7| v0_13(Void) = AliasedUse : ~mu0_2
# 7| v0_14(Void) = ExitFunction :
# 12| System.Void PropClass.set_Prop(System.Int32)
# 12| Block 0
@ -1509,7 +1550,8 @@ prop.cs:
# 14| mu0_9(Int32) = Store : &:r0_8, r0_7
# 12| v0_10(Void) = ReturnVoid :
# 12| v0_11(Void) = UnmodeledUse : mu*
# 12| v0_12(Void) = ExitFunction :
# 12| v0_12(Void) = AliasedUse : ~mu0_2
# 12| v0_13(Void) = ExitFunction :
# 18| System.Int32 PropClass.func()
# 18| Block 0
@ -1523,7 +1565,8 @@ prop.cs:
# 18| r0_7(glval<Int32>) = VariableAddress[#return] :
# 18| v0_8(Void) = ReturnValue : &:r0_7, ~mu0_2
# 18| v0_9(Void) = UnmodeledUse : mu*
# 18| v0_10(Void) = ExitFunction :
# 18| v0_10(Void) = AliasedUse : ~mu0_2
# 18| v0_11(Void) = ExitFunction :
# 26| System.Void Prog.Main()
# 26| Block 0
@ -1551,7 +1594,8 @@ prop.cs:
# 30| mu0_21(Int32) = Store : &:r0_15, r0_19
# 26| v0_22(Void) = ReturnVoid :
# 26| v0_23(Void) = UnmodeledUse : mu*
# 26| v0_24(Void) = ExitFunction :
# 26| v0_24(Void) = AliasedUse : ~mu0_2
# 26| v0_25(Void) = ExitFunction :
simple_call.cs:
# 5| System.Int32 test_simple_call.f()
@ -1565,7 +1609,8 @@ simple_call.cs:
# 5| r0_6(glval<Int32>) = VariableAddress[#return] :
# 5| v0_7(Void) = ReturnValue : &:r0_6, ~mu0_2
# 5| v0_8(Void) = UnmodeledUse : mu*
# 5| v0_9(Void) = ExitFunction :
# 5| v0_9(Void) = AliasedUse : ~mu0_2
# 5| v0_10(Void) = ExitFunction :
# 10| System.Int32 test_simple_call.g()
# 10| Block 0
@ -1581,7 +1626,8 @@ simple_call.cs:
# 10| r0_9(glval<Int32>) = VariableAddress[#return] :
# 10| v0_10(Void) = ReturnValue : &:r0_9, ~mu0_2
# 10| v0_11(Void) = UnmodeledUse : mu*
# 10| v0_12(Void) = ExitFunction :
# 10| v0_12(Void) = AliasedUse : ~mu0_2
# 10| v0_13(Void) = ExitFunction :
simple_function.cs:
# 5| System.Int32 test_simple_function.f()
@ -1595,7 +1641,8 @@ simple_function.cs:
# 5| r0_6(glval<Int32>) = VariableAddress[#return] :
# 5| v0_7(Void) = ReturnValue : &:r0_6, ~mu0_2
# 5| v0_8(Void) = UnmodeledUse : mu*
# 5| v0_9(Void) = ExitFunction :
# 5| v0_9(Void) = AliasedUse : ~mu0_2
# 5| v0_10(Void) = ExitFunction :
stmts.cs:
# 5| System.Int32 test_stmts.ifStmt(System.Int32)
@ -1617,7 +1664,8 @@ stmts.cs:
# 5| r1_0(glval<Int32>) = VariableAddress[#return] :
# 5| v1_1(Void) = ReturnValue : &:r1_0, ~mu0_2
# 5| v1_2(Void) = UnmodeledUse : mu*
# 5| v1_3(Void) = ExitFunction :
# 5| v1_3(Void) = AliasedUse : ~mu0_2
# 5| v1_4(Void) = ExitFunction :
# 10| Block 2
# 10| r2_0(glval<Int32>) = VariableAddress[#return] :
@ -1646,7 +1694,8 @@ stmts.cs:
# 13| Block 1
# 13| v1_0(Void) = ReturnVoid :
# 13| v1_1(Void) = UnmodeledUse : mu*
# 13| v1_2(Void) = ExitFunction :
# 13| v1_2(Void) = AliasedUse : ~mu0_2
# 13| v1_3(Void) = ExitFunction :
# 16| Block 2
# 16| r2_0(glval<Int32>) = VariableAddress[i] :
@ -1693,7 +1742,8 @@ stmts.cs:
# 22| r1_0(glval<Int32>) = VariableAddress[#return] :
# 22| v1_1(Void) = ReturnValue : &:r1_0, ~mu0_2
# 22| v1_2(Void) = UnmodeledUse : mu*
# 22| v1_3(Void) = ExitFunction :
# 22| v1_3(Void) = AliasedUse : ~mu0_2
# 22| v1_4(Void) = ExitFunction :
# 29| Block 2
# 29| v2_0(Void) = NoOp :
@ -1750,7 +1800,8 @@ stmts.cs:
# 46| Block 1
# 46| v1_0(Void) = UnmodeledUse : mu*
# 46| v1_1(Void) = ExitFunction :
# 46| v1_1(Void) = AliasedUse : ~mu0_2
# 46| v1_2(Void) = ExitFunction :
# 46| Block 2
# 46| v2_0(Void) = Unwind :
@ -1816,7 +1867,8 @@ stmts.cs:
# 69| Block 1
# 69| v1_0(Void) = ReturnVoid :
# 69| v1_1(Void) = UnmodeledUse : mu*
# 69| v1_2(Void) = ExitFunction :
# 69| v1_2(Void) = AliasedUse : ~mu0_2
# 69| v1_3(Void) = ExitFunction :
# 72| Block 2
# 72| r2_0(glval<Int32>) = VariableAddress[i] :
@ -1893,7 +1945,8 @@ stmts.cs:
# 89| Block 1
# 89| v1_0(Void) = ReturnVoid :
# 89| v1_1(Void) = UnmodeledUse : mu*
# 89| v1_2(Void) = ExitFunction :
# 89| v1_2(Void) = AliasedUse : ~mu0_2
# 89| v1_3(Void) = ExitFunction :
# 94| Block 2
# 94| r2_0(glval<Int32>) = VariableAddress[x] :
@ -1933,7 +1986,8 @@ stmts.cs:
# 108| mu0_18(Int32) = Store : &:r0_17, r0_16
# 99| v0_19(Void) = ReturnVoid :
# 99| v0_20(Void) = UnmodeledUse : mu*
# 99| v0_21(Void) = ExitFunction :
# 99| v0_21(Void) = AliasedUse : ~mu0_2
# 99| v0_22(Void) = ExitFunction :
using.cs:
# 7| System.Void UsingStmt.MyDisposable..ctor()
@ -1945,7 +1999,8 @@ using.cs:
# 7| v0_4(Void) = NoOp :
# 7| v0_5(Void) = ReturnVoid :
# 7| v0_6(Void) = UnmodeledUse : mu*
# 7| v0_7(Void) = ExitFunction :
# 7| v0_7(Void) = AliasedUse : ~mu0_2
# 7| v0_8(Void) = ExitFunction :
# 8| System.Void UsingStmt.MyDisposable.DoSomething()
# 8| Block 0
@ -1956,7 +2011,8 @@ using.cs:
# 8| v0_4(Void) = NoOp :
# 8| v0_5(Void) = ReturnVoid :
# 8| v0_6(Void) = UnmodeledUse : mu*
# 8| v0_7(Void) = ExitFunction :
# 8| v0_7(Void) = AliasedUse : ~mu0_2
# 8| v0_8(Void) = ExitFunction :
# 9| System.Void UsingStmt.MyDisposable.Dispose()
# 9| Block 0
@ -1967,7 +2023,8 @@ using.cs:
# 9| v0_4(Void) = NoOp :
# 9| v0_5(Void) = ReturnVoid :
# 9| v0_6(Void) = UnmodeledUse : mu*
# 9| v0_7(Void) = ExitFunction :
# 9| v0_7(Void) = AliasedUse : ~mu0_2
# 9| v0_8(Void) = ExitFunction :
# 12| System.Void UsingStmt.Main()
# 12| Block 0
@ -2009,7 +2066,8 @@ using.cs:
# 26| mu0_35(null) = ^CallSideEffect : ~mu0_2
# 12| v0_36(Void) = ReturnVoid :
# 12| v0_37(Void) = UnmodeledUse : mu*
# 12| v0_38(Void) = ExitFunction :
# 12| v0_38(Void) = AliasedUse : ~mu0_2
# 12| v0_39(Void) = ExitFunction :
variables.cs:
# 5| System.Void test_variables.f()
@ -2035,4 +2093,5 @@ variables.cs:
# 10| mu0_18(Int32) = Store : &:r0_15, r0_17
# 5| v0_19(Void) = ReturnVoid :
# 5| v0_20(Void) = UnmodeledUse : mu*
# 5| v0_21(Void) = ExitFunction :
# 5| v0_21(Void) = AliasedUse : ~mu0_2
# 5| v0_22(Void) = ExitFunction :