Skip to content

Commit 85ea8b5

Browse files
committed
[move-only] Rename CheckKind::NoImplicitCopy -> CheckKind::ConsumableAndAssignable
This fits the name of the check better. The reason I am doing this renaming is b/c I am going to add a nonconsumable but assignable check for global_addr/ref_element_addr/captures with var semantics.
1 parent 87829aa commit 85ea8b5

25 files changed

+130
-119
lines changed

docs/SIL.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2730,7 +2730,7 @@ Today this codegens to the following Swift::
27302730
bb0(%0 : @noImplicitCopy $Int):
27312731
%1 = copyable_to_moveonlywrapper [owned] %0 : $Int
27322732
%2 = move_value [lexical] %1 : $@moveOnly Int
2733-
%3 = mark_must_check [no_implicit_copy] %2 : $@moveOnly Int
2733+
%3 = mark_must_check [consumable_and_assignable] %2 : $@moveOnly Int
27342734
%5 = begin_borrow %3 : $@moveOnly Int
27352735
%6 = begin_borrow %3 : $@moveOnly Int
27362736
%7 = function_ref @addIntegers : $@convention(method) (Int, Int Int.Type) -> Int
@@ -2789,7 +2789,7 @@ A hypothetical SILGen for this code is as follows::
27892789
%3 = begin_borrow [lexical] %0 : $Klass
27902790
%4 = copy_value %3 : $Klass
27912791
%5 = copyable_to_moveonlywrapper [owned] %4 : $Klass
2792-
%6 = mark_must_check [no_implicit_copy] %5 : $@moveOnly Klass
2792+
%6 = mark_must_check [consumable_and_assignable] %5 : $@moveOnly Klass
27932793
debug_value %6 : $@moveOnly Klass, let, name "value"
27942794
%8 = begin_borrow %6 : $@moveOnly Klass
27952795
%9 = copy_value %8 : $@moveOnly Klass
@@ -7823,7 +7823,7 @@ mark_must_check
78237823
sil-instruction ::= 'mark_must_check'
78247824
'[' sil-optimizer-analysis-marker ']'
78257825

7826-
sil-optimizer-analysis-marker ::= 'no_implicit_copy'
7826+
sil-optimizer-analysis-marker ::= 'consumable_and_assignable'
78277827
::= 'no_consume_or_assign'
78287828

78297829
A canary value inserted by a SIL generating frontend to signal to the move
@@ -7833,7 +7833,7 @@ relevant diagnostic. The idea here is that instead of needing to introduce
78337833
multiple "flagging" instructions for the optimizer, we can just reuse this one
78347834
instruction by varying the kind.
78357835

7836-
If the sil optimizer analysis marker is ``no_implicit_copy`` then the move
7836+
If the sil optimizer analysis marker is ``consumable_and_assignable`` then the move
78377837
checker is told to check that the result of this instruction is consumed at most
78387838
once. If the marker is ``no_consume_or_assign``, then the move checker will
78397839
validate that the result of this instruction is never consumed or assigned over.

include/swift/AST/DiagnosticsSIL.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,7 @@ NOTE(sil_moveonlychecker_nonconsuming_use_here, none,
767767
NOTE(sil_movekillscopyablevalue_value_cyclic_consumed_in_loop_here, none,
768768
"consuming in loop use here", ())
769769

770-
ERROR(sil_moveonlychecker_not_understand_no_implicit_copy, none,
770+
ERROR(sil_moveonlychecker_not_understand_consumable_and_assignable, none,
771771
"Usage of @noImplicitCopy that the move checker does not know how to "
772772
"check!", ())
773773
ERROR(sil_moveonlychecker_not_understand_moveonly, none,

include/swift/SIL/SILInstruction.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8208,10 +8208,12 @@ class MarkMustCheckInst
82088208
enum class CheckKind : unsigned {
82098209
Invalid = 0,
82108210

8211-
// A signal to the move only checker to perform no implicit copy checking on
8212-
// the result of this instruction. This implies that the result can be
8213-
// consumed at most once.
8214-
NoImplicitCopy,
8211+
// A signal to the move only checker to perform checking that allows for
8212+
// this value to be consumed along its boundary (in the case of let/var
8213+
// semantics) and also written over in the case of var semantics. NOTE: Of
8214+
// course this still implies the value cannot be copied and can be consumed
8215+
// only once along all program paths.
8216+
ConsumableAndAssignable,
82158217

82168218
// A signal to the move only checker to perform no consume or assign
82178219
// checking. This forces the result of this instruction owned value to never
@@ -8240,7 +8242,7 @@ class MarkMustCheckInst
82408242
switch (kind) {
82418243
case CheckKind::Invalid:
82428244
return false;
8243-
case CheckKind::NoImplicitCopy:
8245+
case CheckKind::ConsumableAndAssignable:
82448246
case CheckKind::NoConsumeOrAssign:
82458247
return true;
82468248
}

lib/SIL/IR/SILPrinter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,8 +1992,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
19921992
switch (I->getCheckKind()) {
19931993
case CheckKind::Invalid:
19941994
llvm_unreachable("Invalid?!");
1995-
case CheckKind::NoImplicitCopy:
1996-
*this << "[no_implicit_copy] ";
1995+
case CheckKind::ConsumableAndAssignable:
1996+
*this << "[consumable_and_assignable] ";
19971997
break;
19981998
case CheckKind::NoConsumeOrAssign:
19991999
*this << "[no_consume_or_assign] ";

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3661,10 +3661,12 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
36613661
}
36623662

36633663
using CheckKind = MarkMustCheckInst::CheckKind;
3664-
CheckKind CKind = llvm::StringSwitch<CheckKind>(AttrName)
3665-
.Case("no_implicit_copy", CheckKind::NoImplicitCopy)
3666-
.Case("no_consume_or_assign", CheckKind::NoConsumeOrAssign)
3667-
.Default(CheckKind::Invalid);
3664+
CheckKind CKind =
3665+
llvm::StringSwitch<CheckKind>(AttrName)
3666+
.Case("consumable_and_assignable",
3667+
CheckKind::ConsumableAndAssignable)
3668+
.Case("no_consume_or_assign", CheckKind::NoConsumeOrAssign)
3669+
.Default(CheckKind::Invalid);
36683670

36693671
if (CKind == CheckKind::Invalid) {
36703672
auto diag = diag::sil_markmustcheck_invalid_attribute;

lib/SILGen/SILGenConstructor.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,8 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
839839
if (selfArg.getType().isMoveOnly()) {
840840
assert(selfArg.getOwnershipKind() == OwnershipKind::Owned);
841841
selfArg = B.createMarkMustCheckInst(
842-
selfDecl, selfArg, MarkMustCheckInst::CheckKind::NoImplicitCopy);
842+
selfDecl, selfArg,
843+
MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
843844
}
844845
VarLocs[selfDecl] = VarLoc::get(selfArg.getValue());
845846
}

lib/SILGen/SILGenDecl.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ class LocalVariableInitialization : public SingleBufferInitialization {
380380
if (Addr->getType().isMoveOnly()) {
381381
// TODO: Handle no implicit copy here.
382382
Addr = SGF.B.createMarkMustCheckInst(
383-
decl, Addr, MarkMustCheckInst::CheckKind::NoImplicitCopy);
383+
decl, Addr, MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
384384
}
385385

386386
// Push a cleanup to destroy the local variable. This has to be
@@ -580,7 +580,8 @@ class LetValueInitialization : public Initialization {
580580
if (value->getType().isPureMoveOnly()) {
581581
value = SGF.B.createMoveValue(PrologueLoc, value, /*isLexical*/ true);
582582
return SGF.B.createMarkMustCheckInst(
583-
PrologueLoc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
583+
PrologueLoc, value,
584+
MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
584585
}
585586

586587
// Otherwise, if we don't have a no implicit copy trivial type, just
@@ -594,7 +595,8 @@ class LetValueInitialization : public Initialization {
594595
SGF.B.createOwnedCopyableToMoveOnlyWrapperValue(PrologueLoc, value);
595596
value = SGF.B.createMoveValue(PrologueLoc, value, /*isLexical*/ true);
596597
return SGF.B.createMarkMustCheckInst(
597-
PrologueLoc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
598+
PrologueLoc, value,
599+
MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
598600
}
599601

600602
// Then if we don't have move only, just perform a lexical borrow if the
@@ -636,7 +638,8 @@ class LetValueInitialization : public Initialization {
636638
!value->getType().isMoveOnlyWrapped()) {
637639
value = SGF.B.createMoveValue(PrologueLoc, value, true /*isLexical*/);
638640
return SGF.B.createMarkMustCheckInst(
639-
PrologueLoc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
641+
PrologueLoc, value,
642+
MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
640643
}
641644

642645
// Otherwise, if we do not have a no implicit copy variable, just follow
@@ -655,7 +658,8 @@ class LetValueInitialization : public Initialization {
655658
value = SGF.B.createCopyValue(PrologueLoc, value);
656659
value = SGF.B.createOwnedCopyableToMoveOnlyWrapperValue(PrologueLoc, value);
657660
return SGF.B.createMarkMustCheckInst(
658-
PrologueLoc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
661+
PrologueLoc, value,
662+
MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
659663
}
660664

661665
void bindValue(SILValue value, SILGenFunction &SGF, bool wasPlusOne) {

lib/SILGen/SILGenProlog.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ SILValue SILGenFunction::emitSelfDeclForDestructor(VarDecl *selfDecl) {
4949
// they cannot escape.
5050
if (selfValue->getOwnershipKind() == OwnershipKind::Owned) {
5151
selfValue = B.createMarkMustCheckInst(
52-
selfDecl, selfValue, MarkMustCheckInst::CheckKind::NoImplicitCopy);
52+
selfDecl, selfValue,
53+
MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
5354
}
5455
}
5556

@@ -129,7 +130,7 @@ class EmitBBArguments : public CanTypeVisitor<EmitBBArguments,
129130
// check ownership.
130131
if (mv.getType().isMoveOnly() && !mv.getType().isMoveOnlyWrapped())
131132
mv = SGF.B.createMarkMustCheckInst(
132-
loc, mv, MarkMustCheckInst::CheckKind::NoImplicitCopy);
133+
loc, mv, MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
133134
return mv;
134135
}
135136

@@ -322,7 +323,7 @@ struct ArgumentInitHelper {
322323
value = SGF.B.createMoveValue(loc, argrv.forward(SGF),
323324
/*isLexical*/ true);
324325
value = SGF.B.createMarkMustCheckInst(
325-
loc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
326+
loc, value, MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
326327
SGF.emitManagedRValueWithCleanup(value);
327328
return value;
328329
}
@@ -343,7 +344,7 @@ struct ArgumentInitHelper {
343344
// use no copy.
344345
auto kind = MarkMustCheckInst::CheckKind::NoConsumeOrAssign;
345346
if (pd->isOwned())
346-
kind = MarkMustCheckInst::CheckKind::NoImplicitCopy;
347+
kind = MarkMustCheckInst::CheckKind::ConsumableAndAssignable;
347348
value = SGF.B.createMarkMustCheckInst(loc, value, kind);
348349
SGF.emitManagedRValueWithCleanup(value);
349350
return value;
@@ -365,7 +366,7 @@ struct ArgumentInitHelper {
365366
loc, argrv.forward(SGF));
366367
value = SGF.B.createMoveValue(loc, value, true /*is lexical*/);
367368
value = SGF.B.createMarkMustCheckInst(
368-
loc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
369+
loc, value, MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
369370
SGF.emitManagedRValueWithCleanup(value);
370371
return value;
371372
}
@@ -585,7 +586,7 @@ static void emitCaptureArguments(SILGenFunction &SGF,
585586
SILValue addr = SGF.B.createProjectBox(VD, box, 0);
586587
if (addr->getType().isMoveOnly())
587588
addr = SGF.B.createMarkMustCheckInst(
588-
VD, addr, MarkMustCheckInst::CheckKind::NoImplicitCopy);
589+
VD, addr, MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
589590
SGF.VarLocs[VD] = SILGenFunction::VarLoc::get(addr, box);
590591
SILDebugVariable DbgVar(VD->isLet(), ArgNo);
591592
SGF.B.createDebugValueAddr(Loc, addr, DbgVar);
@@ -608,7 +609,7 @@ static void emitCaptureArguments(SILGenFunction &SGF,
608609
SILValue arg = SILValue(fArg);
609610
if (isInOut && (ty.isMoveOnly() && !ty.isMoveOnlyWrapped())) {
610611
arg = SGF.B.createMarkMustCheckInst(
611-
Loc, arg, MarkMustCheckInst::CheckKind::NoImplicitCopy);
612+
Loc, arg, MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
612613
}
613614
SGF.VarLocs[VD] = SILGenFunction::VarLoc::get(arg);
614615
SILDebugVariable DbgVar(VD->isLet(), ArgNo);

lib/SILOptimizer/Mandatory/MoveOnlyDiagnostics.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,9 @@ void DiagnosticEmitter::emitCheckerDoesntUnderstandDiagnostic(
9595
// that copy propagation did not understand. Emit a we did not understand
9696
// error.
9797
if (markedValue->getType().isMoveOnlyWrapped()) {
98-
diagnose(fn->getASTContext(), markedValue,
99-
diag::sil_moveonlychecker_not_understand_no_implicit_copy);
98+
diagnose(
99+
fn->getASTContext(), markedValue,
100+
diag::sil_moveonlychecker_not_understand_consumable_and_assignable);
100101
} else {
101102
diagnose(fn->getASTContext(), markedValue,
102103
diag::sil_moveonlychecker_not_understand_moveonly);

lib/SILOptimizer/Mandatory/MoveOnlyObjectChecker.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ bool swift::siloptimizer::searchForCandidateObjectMarkMustChecks(
9494
// This is forming a let or an argument.
9595
// bb0:
9696
// %1 = move_value [lexical] %0
97-
// %2 = mark_must_check [no_implicit_copy] %1
97+
// %2 = mark_must_check [consumable_and_assignable] %1
9898
//
9999
// This occurs when SILGen materializes a temporary move only value?
100100
// bb0:
@@ -170,7 +170,7 @@ bool swift::siloptimizer::searchForCandidateObjectMarkMustChecks(
170170
// bb0(%0 : $Trivial):
171171
// %1 = copyable_to_moveonlywrapper [owned] %0
172172
// %2 = move_value [lexical] %1
173-
// %3 = mark_must_check [no_implicit_copy] %2
173+
// %3 = mark_must_check [consumable_and_assignable] %2
174174
//
175175
// *OR*
176176
//
@@ -202,7 +202,7 @@ bool swift::siloptimizer::searchForCandidateObjectMarkMustChecks(
202202
// bb0(%0 : @owned $T):
203203
// %1 = copyable_to_moveonlywrapper [owned] %0
204204
// %2 = move_value [lexical] %1
205-
// %3 = mark_must_check [no_implicit_copy_owned] %2
205+
// %3 = mark_must_check [consumable_and_assignable_owned] %2
206206
if (auto *mvi = dyn_cast<MoveValueInst>(mmci->getOperand())) {
207207
if (mvi->isLexical()) {
208208
if (auto *cvt = dyn_cast<CopyableToMoveOnlyWrapperValueInst>(
@@ -224,7 +224,7 @@ bool swift::siloptimizer::searchForCandidateObjectMarkMustChecks(
224224
// %1 = begin_borrow [lexical] %0
225225
// %2 = copy_value %1
226226
// %3 = copyable_to_moveonlywrapper [owned] %2
227-
// %4 = mark_must_check [no_implicit_copy]
227+
// %4 = mark_must_check [consumable_and_assignable]
228228
//
229229
// Or for a move only type, we look for a move_value [lexical].
230230
if (auto *mvi = dyn_cast<CopyableToMoveOnlyWrapperValueInst>(
@@ -245,7 +245,7 @@ bool swift::siloptimizer::searchForCandidateObjectMarkMustChecks(
245245
//
246246
// %1 = copyable_to_moveonlywrapper [owned] %0
247247
// %2 = move_value [lexical] %1
248-
// %3 = mark_must_check [no_implicit_copy] %2
248+
// %3 = mark_must_check [consumable_and_assignable] %2
249249
if (auto *cvi = dyn_cast<ExplicitCopyValueInst>(mmci->getOperand())) {
250250
if (auto *bbi = dyn_cast<BeginBorrowInst>(cvi->getOperand())) {
251251
if (bbi->isLexical()) {

0 commit comments

Comments
 (0)