@@ -256,6 +256,87 @@ struct ArgumentInitHelper {
256256 return argEmitter.visit (canTy, origTy);
257257 }
258258
259+ SILValue updateArgumentValueForBinding (ManagedValue argrv, SILLocation loc,
260+ ParamDecl *pd, SILValue value,
261+ const SILDebugVariable &varinfo) {
262+ // If we do not need to support lexical lifetimes, just return value as the
263+ // updated value.
264+ if (!SGF.getASTContext ().SILOpts .supportsLexicalLifetimes (SGF.getModule ()))
265+ return value;
266+
267+ bool isNoImplicitCopy = false ;
268+ if (auto *arg = dyn_cast<SILFunctionArgument>(value))
269+ isNoImplicitCopy = arg->isNoImplicitCopy ();
270+
271+ // If we have a no implicit copy argument and the argument is trivial,
272+ // we need to use copyable to move only to convert it to its move only
273+ // form.
274+ if (!isNoImplicitCopy) {
275+ if (!value->getType ().isMoveOnly ()) {
276+ if (value->getOwnershipKind () == OwnershipKind::Owned) {
277+ value =
278+ SILValue (SGF.B .createBeginBorrow (loc, value, /* isLexical*/ true ));
279+ SGF.Cleanups .pushCleanup <EndBorrowCleanup>(value);
280+ }
281+ return value;
282+ }
283+
284+ // At this point, we have a move only type.
285+ if (value->getOwnershipKind () == OwnershipKind::Owned) {
286+ value = SGF.B .createMoveValue (loc, argrv.forward (SGF),
287+ /* isLexical*/ true );
288+ value = SGF.B .createMarkMustCheckInst (
289+ loc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
290+ SGF.emitManagedRValueWithCleanup (value);
291+ return value;
292+ }
293+
294+ assert (value->getOwnershipKind () == OwnershipKind::Guaranteed);
295+ value = SGF.B .createCopyValue (loc, value);
296+ value = SGF.B .createMarkMustCheckInst (
297+ loc, value, MarkMustCheckInst::CheckKind::NoCopy);
298+ SGF.emitManagedRValueWithCleanup (value);
299+ return value;
300+ }
301+
302+ if (value->getType ().isTrivial (SGF.F )) {
303+ value = SGF.B .createOwnedCopyableToMoveOnlyWrapperValue (loc, value);
304+ value = SGF.B .createMoveValue (loc, value, true /* is lexical*/ );
305+
306+ // If our argument was owned, we use no implicit copy. Otherwise, we
307+ // use no copy.
308+ auto kind = MarkMustCheckInst::CheckKind::NoCopy;
309+ if (pd->isOwned ())
310+ kind = MarkMustCheckInst::CheckKind::NoImplicitCopy;
311+ value = SGF.B .createMarkMustCheckInst (loc, value, kind);
312+ SGF.emitManagedRValueWithCleanup (value);
313+ return value;
314+ }
315+
316+ if (value->getOwnershipKind () == OwnershipKind::Guaranteed) {
317+ value = SGF.B .createGuaranteedCopyableToMoveOnlyWrapperValue (loc, value);
318+ value = SGF.B .createCopyValue (loc, value);
319+ value = SGF.B .createMarkMustCheckInst (
320+ loc, value, MarkMustCheckInst::CheckKind::NoCopy);
321+ SGF.emitManagedRValueWithCleanup (value);
322+ return value;
323+ }
324+
325+ if (value->getOwnershipKind () == OwnershipKind::Owned) {
326+ // If we have an owned value, forward it into the mark_must_check to
327+ // avoid an extra destroy_value.
328+ value = SGF.B .createOwnedCopyableToMoveOnlyWrapperValue (
329+ loc, argrv.forward (SGF));
330+ value = SGF.B .createMoveValue (loc, value, true /* is lexical*/ );
331+ value = SGF.B .createMarkMustCheckInst (
332+ loc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
333+ SGF.emitManagedRValueWithCleanup (value);
334+ return value;
335+ }
336+
337+ return value;
338+ }
339+
259340 // / Create a SILArgument and store its value into the given Initialization,
260341 // / if not null.
261342 void makeArgumentIntoBinding (Type ty, SILBasicBlock *parent, ParamDecl *pd) {
@@ -276,66 +357,7 @@ struct ArgumentInitHelper {
276357 SILValue value = argrv.getValue ();
277358 SILDebugVariable varinfo (pd->isImmutable (), ArgNo);
278359 if (!argrv.getType ().isAddress ()) {
279- if (SGF.getASTContext ().SILOpts .supportsLexicalLifetimes (
280- SGF.getModule ())) {
281- bool isNoImplicitCopy = false ;
282- if (auto *arg = dyn_cast<SILFunctionArgument>(value))
283- isNoImplicitCopy = arg->isNoImplicitCopy ();
284-
285- // If we have a no implicit copy argument and the argument is trivial,
286- // we need to use copyable to move only to convert it to its move only
287- // form.
288- if (isNoImplicitCopy) {
289- if (value->getType ().isTrivial (SGF.F )) {
290- value = SGF.B .createOwnedCopyableToMoveOnlyWrapperValue (loc, value);
291- value = SGF.B .createMoveValue (loc, value, true /* is lexical*/ );
292-
293- // If our argument was owned, we use no implicit copy. Otherwise, we
294- // use no copy.
295- auto kind = MarkMustCheckInst::CheckKind::NoCopy;
296- if (pd->isOwned ())
297- kind = MarkMustCheckInst::CheckKind::NoImplicitCopy;
298- value = SGF.B .createMarkMustCheckInst (loc, value, kind);
299- SGF.emitManagedRValueWithCleanup (value);
300- } else if (value->getOwnershipKind () == OwnershipKind::Guaranteed) {
301- value = SGF.B .createGuaranteedCopyableToMoveOnlyWrapperValue (loc,
302- value);
303- value = SGF.B .createCopyValue (loc, value);
304- value = SGF.B .createMarkMustCheckInst (
305- loc, value, MarkMustCheckInst::CheckKind::NoCopy);
306- SGF.emitManagedRValueWithCleanup (value);
307- } else if (value->getOwnershipKind () == OwnershipKind::Owned) {
308- // If we have an owned value, forward it into the mark_must_check to
309- // avoid an extra destroy_value.
310- value = SGF.B .createOwnedCopyableToMoveOnlyWrapperValue (
311- loc, argrv.forward (SGF));
312- value = SGF.B .createMoveValue (loc, value, true /* is lexical*/ );
313- value = SGF.B .createMarkMustCheckInst (
314- loc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
315- SGF.emitManagedRValueWithCleanup (value);
316- }
317- } else if (value->getType ().isMoveOnly ()) {
318- if (value->getOwnershipKind () == OwnershipKind::Owned) {
319- value = SGF.B .createMoveValue (loc, argrv.forward (SGF),
320- /* isLexical*/ true );
321- value = SGF.B .createMarkMustCheckInst (
322- loc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
323- SGF.emitManagedRValueWithCleanup (value);
324- } else {
325- assert (value->getOwnershipKind () == OwnershipKind::Guaranteed);
326- value = SGF.B .createCopyValue (loc, value);
327- value = SGF.B .createMarkMustCheckInst (
328- loc, value, MarkMustCheckInst::CheckKind::NoCopy);
329- SGF.emitManagedRValueWithCleanup (value);
330- }
331- } else {
332- if (value->getOwnershipKind () == OwnershipKind::Owned) {
333- value = SILValue (
334- SGF.B .createBeginBorrow (loc, value, /* isLexical*/ true ));
335- SGF.Cleanups .pushCleanup <EndBorrowCleanup>(value);
336- }
337- }
338- }
360+ value = updateArgumentValueForBinding (argrv, loc, pd, value, varinfo);
339361 SGF.B .createDebugValue (loc, value, varinfo);
340362 } else {
341363 if (auto *allocStack = dyn_cast<AllocStackInst>(value)) {
0 commit comments