[move-function] Add a new instruction called mark_unresolved_move_addr.

This instruction is similar to a copy_addr except that it marks a move of an
address that has to be checked. In order to keep the memory lifetime verifier
happy, the semantics before the checker runs are the mark_unresolved_move_addr is
equivalent to copy_addr [init] (not copy_addr [take][init]).

The use of this instruction is that Mandatory Inlining converts builtin "move"
to a mark_unresolved_move_addr when inlining the function "_move" (the only
place said builtin is invoked).

This is then run through a special checker (that is later in this PR) that
either proves that the mark_unresolved_move_addr can actually be a move in which
case it converts it to copy_addr [take][init] or if it can not be a move, emit
an error and convert the instruction to a copy_addr [init]. After this is done
for all instructions, we loop back through again and emit an error on any
mark_unresolved_move_addr that were not processed earlier allowing for us to
know that we have completeness.

NOTE: The move kills checker for addresses is going to run after Mandatory
Inlining, but before predictable memory opts and friends.
This commit is contained in:
Michael Gottesman
2021-11-11 13:46:52 -08:00
parent cce3e8a7f5
commit d74299e68d
26 changed files with 238 additions and 16 deletions

View File

@@ -171,6 +171,7 @@ public:
MemBehavior visitLoadInst(LoadInst *LI);
MemBehavior visitStoreInst(StoreInst *SI);
MemBehavior visitCopyAddrInst(CopyAddrInst *CAI);
MemBehavior visitMarkUnresolvedMoveAddrInst(MarkUnresolvedMoveAddrInst *MAI);
MemBehavior visitApplyInst(ApplyInst *AI);
MemBehavior visitTryApplyInst(TryApplyInst *AI);
MemBehavior visitBeginApplyInst(BeginApplyInst *AI);
@@ -301,6 +302,25 @@ MemBehavior MemoryBehaviorVisitor::visitCopyAddrInst(CopyAddrInst *CAI) {
return MemBehavior::None;
}
MemBehavior
MemoryBehaviorVisitor::visitMarkUnresolvedMoveAddrInst(MarkUnresolvedMoveAddrInst *MAI) {
bool mayWrite = mayAlias(MAI->getDest());
bool mayRead = mayAlias(MAI->getSrc());
if (mayRead) {
if (mayWrite)
return MemBehavior::MayReadWrite;
// mark_unresolved_move_addr doesn't semantically perform a take of src.
return MemBehavior::MayRead;
}
if (mayWrite)
return MemBehavior::MayWrite;
return MemBehavior::None;
}
MemBehavior MemoryBehaviorVisitor::visitBuiltinInst(BuiltinInst *BI) {
// If our callee is not a builtin, be conservative and return may have side
// effects.
@@ -368,6 +388,7 @@ static bool hasEscapingUses(SILValue address, int &numChecks) {
case SILInstructionKind::LoadInst:
case SILInstructionKind::StoreInst:
case SILInstructionKind::CopyAddrInst:
case SILInstructionKind::MarkUnresolvedMoveAddrInst:
case SILInstructionKind::DestroyAddrInst:
case SILInstructionKind::DeallocStackInst:
case SILInstructionKind::EndAccessInst: