Skip to content

Commit 9069cc7

Browse files
authored
Merge pull request #40423 from gottesmm/address-only-let-checker
[move-function] Implement move checking for address only lets
2 parents 0398252 + 6f7f235 commit 9069cc7

35 files changed

+1557
-41
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,7 @@ NOTE(sil_movekillscopyablevalue_use_here, none,
741741
NOTE(sil_movekillscopyablevalue_value_consumed_in_loop, none,
742742
"cyclic move here. move will occur multiple times in the loop", ())
743743
ERROR(sil_movekillscopyablevalue_move_applied_to_unsupported_move, none,
744-
"_move applied to value that the compiler does not supporting checking.",
744+
"_move applied to value that the compiler does not support checking",
745745
())
746746

747747
#define UNDEFINE_DIAGNOSTIC_MACROS

include/swift/SIL/BasicBlockDatastructures.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ class BasicBlockSetVector {
4343
iterator begin() const { return vector.begin(); }
4444
iterator end() const { return vector.end(); }
4545

46+
llvm::iterator_range<iterator> getRange() const {
47+
return llvm::make_range(begin(), end());
48+
}
49+
4650
bool empty() const { return vector.empty(); }
4751

4852
bool contains(SILBasicBlock *block) const { return set.contains(block); }

include/swift/SIL/SILBuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,13 @@ class SILBuilder {
12711271
MoveValueInst(getSILDebugLocation(loc), operand));
12721272
}
12731273

1274+
MarkUnresolvedMoveAddrInst *createMarkUnresolvedMoveAddr(SILLocation loc,
1275+
SILValue srcAddr,
1276+
SILValue takeAddr) {
1277+
return insert(new (getModule()) MarkUnresolvedMoveAddrInst(
1278+
getSILDebugLocation(loc), srcAddr, takeAddr));
1279+
}
1280+
12741281
UnconditionalCheckedCastInst *
12751282
createUnconditionalCheckedCast(SILLocation Loc, SILValue op,
12761283
SILType destLoweredTy,

include/swift/SIL/SILCloner.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,16 @@ SILCloner<ImplClass>::visitCopyAddrInst(CopyAddrInst *Inst) {
13411341
Inst->isInitializationOfDest()));
13421342
}
13431343

1344+
template <typename ImplClass>
1345+
void SILCloner<ImplClass>::visitMarkUnresolvedMoveAddrInst(
1346+
MarkUnresolvedMoveAddrInst *Inst) {
1347+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1348+
auto *MVI = getBuilder().createMarkUnresolvedMoveAddr(
1349+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()),
1350+
getOpValue(Inst->getDest()));
1351+
recordClonedInstruction(Inst, MVI);
1352+
}
1353+
13441354
template<typename ImplClass>
13451355
void
13461356
SILCloner<ImplClass>::visitBindMemoryInst(BindMemoryInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,10 @@ struct SILDebugVariable {
17931793
Implicit == V.Implicit && Type == V.Type && Loc == V.Loc &&
17941794
Scope == V.Scope;
17951795
}
1796+
1797+
bool isLet() const { return Name.size() && Constant; }
1798+
1799+
bool isVar() const { return Name.size() && !Constant; }
17961800
};
17971801

17981802
/// A DebugVariable where storage for the strings has been
@@ -2004,7 +2008,20 @@ class AllocStackInst final
20042008
auto VI = TailAllocatedDebugVariable(RawValue);
20052009
return VI.get(getDecl(), getTrailingObjects<char>(), AuxVarType, VarDeclLoc,
20062010
VarDeclScope, DIExprElements);
2007-
};
2011+
}
2012+
2013+
bool isLet() const {
2014+
if (auto varInfo = getVarInfo())
2015+
return varInfo->isLet();
2016+
return false;
2017+
}
2018+
2019+
bool isVar() const {
2020+
if (auto varInfo = getVarInfo())
2021+
return varInfo->isVar();
2022+
return false;
2023+
}
2024+
20082025
void setArgNo(unsigned N) {
20092026
auto RawValue = SILNode::Bits.AllocStackInst.VarInfo;
20102027
auto VI = TailAllocatedDebugVariable(RawValue);
@@ -7424,6 +7441,35 @@ class MoveValueInst
74247441
void setAllowsDiagnostics(bool newValue) { allowDiagnostics = newValue; }
74257442
};
74267443

7444+
/// Equivalent to a copy_addr to [init] except that it is used for diagnostics
7445+
/// and should not be pattern matched. During the diagnostic passes, the "move
7446+
/// function" checker for addresses always converts this to a copy_addr [init]
7447+
/// (if we emitted a diagnostic and proved we could not emit a move here) or a
7448+
/// copy_addr [take][init] if we can. So this should never occur in canonical
7449+
/// SIL.
7450+
class MarkUnresolvedMoveAddrInst
7451+
: public InstructionBase<SILInstructionKind::MarkUnresolvedMoveAddrInst,
7452+
NonValueInstruction>,
7453+
public CopyLikeInstruction {
7454+
friend class SILBuilder;
7455+
7456+
FixedOperandList<2> Operands;
7457+
7458+
MarkUnresolvedMoveAddrInst(SILDebugLocation DebugLoc, SILValue srcAddr,
7459+
SILValue takeAddr)
7460+
: InstructionBase(DebugLoc), Operands(this, srcAddr, takeAddr) {}
7461+
7462+
public:
7463+
SILValue getSrc() const { return Operands[Src].get(); }
7464+
SILValue getDest() const { return Operands[Dest].get(); }
7465+
7466+
void setSrc(SILValue V) { Operands[Src].set(V); }
7467+
void setDest(SILValue V) { Operands[Dest].set(V); }
7468+
7469+
ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
7470+
MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
7471+
};
7472+
74277473
/// Given an object reference, return true iff it is non-nil and refers
74287474
/// to a native swift object with strong reference count of 1.
74297475
class IsUniqueInst

include/swift/SIL/SILNodes.def

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -591,8 +591,15 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
591591
SingleValueInstruction, None, MayRelease)
592592
// A move_value is an OSSA only instruction. Its result does not have any side
593593
// effects relative to other OSSA values like copy_value.
594-
SINGLE_VALUE_INST(MoveValueInst, move_value,
595-
SingleValueInstruction, None, DoesNotRelease)
594+
SINGLE_VALUE_INST(MoveValueInst, move_value, SingleValueInstruction, None,
595+
DoesNotRelease)
596+
597+
// A move_addr is a Raw SIL only instruction that is equivalent to a copy_addr
598+
// [init]. It is lowered during the diagnostic passes to a copy_addr [init] if
599+
// the move checker found uses that prevented us from converting this to a
600+
// move or if we do not find such uses, a copy_addr [init] [take].
601+
NON_VALUE_INST(MarkUnresolvedMoveAddrInst, mark_unresolved_move_addr,
602+
SILInstruction, None, DoesNotRelease)
596603

597604
// IsUnique does not actually write to memory but should be modeled
598605
// as such. Its operand is a pointer to an object reference. The

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,9 @@ PASS(MoveKillsCopyableValuesChecker, "sil-move-kills-copyable-values-checker",
427427
"to _move do not have any uses later than the _move")
428428
PASS(LexicalLifetimeEliminator, "sil-lexical-lifetime-eliminator",
429429
"Pass that removes lexical lifetime markers from borrows and alloc stack")
430+
PASS(MoveKillsCopyableAddressesChecker, "sil-move-kills-copyable-addresses-checker",
431+
"Pass that checks that any copyable (non-move only) address that is passed "
432+
"to _move do not have any uses later than the _move")
430433
PASS(PruneVTables, "prune-vtables",
431434
"Mark class methods that do not require vtable dispatch")
432435
PASS_RANGE(AllPasses, AADumper, PruneVTables)

lib/IRGen/IRGenSIL.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,9 @@ class IRGenSILFunction :
12621262
void visitDeallocPartialRefInst(DeallocPartialRefInst *i);
12631263

12641264
void visitCopyAddrInst(CopyAddrInst *i);
1265+
void visitMarkUnresolvedMoveAddrInst(MarkUnresolvedMoveAddrInst *mai) {
1266+
llvm_unreachable("Valid only when ownership is enabled");
1267+
}
12651268
void visitDestroyAddrInst(DestroyAddrInst *i);
12661269

12671270
void visitBindMemoryInst(BindMemoryInst *i);

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ OPERAND_OWNERSHIP(TrivialUse, CheckedCastAddrBranch)
143143
OPERAND_OWNERSHIP(TrivialUse, CondBranch)
144144
OPERAND_OWNERSHIP(TrivialUse, CondFail)
145145
OPERAND_OWNERSHIP(TrivialUse, CopyAddr)
146+
OPERAND_OWNERSHIP(TrivialUse, MarkUnresolvedMoveAddr)
146147
OPERAND_OWNERSHIP(TrivialUse, DeallocStack)
147148
OPERAND_OWNERSHIP(TrivialUse, DeinitExistentialAddr)
148149
OPERAND_OWNERSHIP(TrivialUse, DestroyAddr)

lib/SIL/IR/SILInstruction.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,10 @@ bool SILInstruction::mayRelease() const {
11671167
return CopyAddr->isInitializationOfDest() ==
11681168
IsInitialization_t::IsNotInitialization;
11691169
}
1170+
// mark_unresolved_move_addr is equivalent to a copy_addr [init], so a release
1171+
// does not occur.
1172+
case SILInstructionKind::MarkUnresolvedMoveAddrInst:
1173+
return false;
11701174

11711175
case SILInstructionKind::BuiltinInst: {
11721176
auto *BI = cast<BuiltinInst>(this);

0 commit comments

Comments
 (0)