diff --git a/docs/SIL.rst b/docs/SIL.rst index 86308e01492ba..f18dd3ab7c633 100644 --- a/docs/SIL.rst +++ b/docs/SIL.rst @@ -6100,6 +6100,14 @@ executing the ``begin_apply``) were being "called" by the ``yield``: or move the value from that position before ending or aborting the coroutine. +A coroutine optionally may produce normal results. These do not have +``@yields`` annotation in the result type tuple. +:: + (%float, %token) = begin_apply %0() : $@yield_once () -> (@yields Float, Int) + +Normal results of a coroutine are produced by the corresponding ``end_apply`` +instruction. + A ``begin_apply`` must be uniquely either ended or aborted before exiting the function or looping to an earlier portion of the function. @@ -6129,9 +6137,9 @@ end_apply ````````` :: - sil-instruction ::= 'end_apply' sil-value + sil-instruction ::= 'end_apply' sil-value 'as' sil-type - end_apply %token + end_apply %token as $() Ends the given coroutine activation, which is currently suspended at a ``yield`` instruction. Transfers control to the coroutine and takes @@ -6141,8 +6149,8 @@ when the coroutine reaches a ``return`` instruction. The operand must always be the token result of a ``begin_apply`` instruction, which is why it need not specify a type. -``end_apply`` currently has no instruction results. If coroutines were -allowed to have normal results, they would be producted by ``end_apply``. +The result of ``end_apply`` is the normal result of the coroutine function (the +operand of the ``return`` instruction)." When throwing coroutines are supported, there will need to be a ``try_end_apply`` instruction. diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 23937394784ab..182587fb2c5f9 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -4789,24 +4789,27 @@ class SILFunctionType final using Representation = SILExtInfoBuilder::Representation; private: - unsigned NumParameters; + unsigned NumParameters = 0; - // These are *normal* results if this is not a coroutine and *yield* results - // otherwise. - unsigned NumAnyResults; // Not including the ErrorResult. - unsigned NumAnyIndirectFormalResults; // Subset of NumAnyResults. - unsigned NumPackResults; // Subset of NumAnyIndirectFormalResults. + // These are *normal* results + unsigned NumAnyResults = 0; // Not including the ErrorResult. + unsigned NumAnyIndirectFormalResults = 0; // Subset of NumAnyResults. + unsigned NumPackResults = 0; // Subset of NumAnyIndirectFormalResults. + // These are *yield* results + unsigned NumAnyYieldResults = 0; // Not including the ErrorResult. + unsigned NumAnyIndirectFormalYieldResults = 0; // Subset of NumAnyYieldResults. + unsigned NumPackYieldResults = 0; // Subset of NumAnyIndirectFormalYieldResults. // [NOTE: SILFunctionType-layout] // The layout of a SILFunctionType in memory is: // SILFunctionType // SILParameterInfo[NumParameters] - // SILResultInfo[isCoroutine() ? 0 : NumAnyResults] + // SILResultInfo[NumAnyResults] // SILResultInfo? // if hasErrorResult() - // SILYieldInfo[isCoroutine() ? NumAnyResults : 0] + // SILYieldInfo[NumAnyYieldResults] // SubstitutionMap[HasPatternSubs + HasInvocationSubs] - // CanType? // if !isCoro && NumAnyResults > 1, formal result cache - // CanType? // if !isCoro && NumAnyResults > 1, all result cache + // CanType? // if NumAnyResults > 1, formal result cache + // CanType? // if NumAnyResults > 1, all result cache CanGenericSignature InvocationGenericSig; ProtocolConformanceRef WitnessMethodConformance; @@ -4845,7 +4848,7 @@ class SILFunctionType final /// Do we have slots for caches of the normal-result tuple type? bool hasResultCache() const { - return NumAnyResults > 1 && !isCoroutine(); + return NumAnyResults > 1; } CanType &getMutableFormalResultsCache() const { @@ -4945,14 +4948,14 @@ class SILFunctionType final ArrayRef getYields() const { return const_cast(this)->getMutableYields(); } - unsigned getNumYields() const { return isCoroutine() ? NumAnyResults : 0; } + unsigned getNumYields() const { return NumAnyYieldResults; } /// Return the array of all result information. This may contain inter-mingled /// direct and indirect results. ArrayRef getResults() const { return const_cast(this)->getMutableResults(); } - unsigned getNumResults() const { return isCoroutine() ? 0 : NumAnyResults; } + unsigned getNumResults() const { return NumAnyResults; } ArrayRef getResultsWithError() const { return const_cast(this)->getMutableResultsWithError(); @@ -4989,17 +4992,17 @@ class SILFunctionType final // indirect property, not the SIL indirect property, should be consulted to // determine whether function reabstraction is necessary. unsigned getNumIndirectFormalResults() const { - return isCoroutine() ? 0 : NumAnyIndirectFormalResults; + return NumAnyIndirectFormalResults; } /// Does this function have any formally indirect results? bool hasIndirectFormalResults() const { return getNumIndirectFormalResults() != 0; } unsigned getNumDirectFormalResults() const { - return isCoroutine() ? 0 : NumAnyResults - NumAnyIndirectFormalResults; + return NumAnyResults - NumAnyIndirectFormalResults; } unsigned getNumPackResults() const { - return isCoroutine() ? 0 : NumPackResults; + return NumPackResults; } bool hasIndirectErrorResult() const { return hasErrorResult() && getErrorResult().isFormalIndirect(); @@ -5057,17 +5060,17 @@ class SILFunctionType final TypeExpansionContext expansion); unsigned getNumIndirectFormalYields() const { - return isCoroutine() ? NumAnyIndirectFormalResults : 0; + return NumAnyIndirectFormalYieldResults; } /// Does this function have any formally indirect yields? bool hasIndirectFormalYields() const { return getNumIndirectFormalYields() != 0; } unsigned getNumDirectFormalYields() const { - return isCoroutine() ? NumAnyResults - NumAnyIndirectFormalResults : 0; + return NumAnyYieldResults - NumAnyIndirectFormalYieldResults; } unsigned getNumPackYields() const { - return isCoroutine() ? NumPackResults : 0; + return NumPackYieldResults; } struct IndirectFormalYieldFilter { diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h index 9d374f746ac8a..1d99dd44bdb73 100644 --- a/include/swift/SIL/SILBuilder.h +++ b/include/swift/SIL/SILBuilder.h @@ -589,11 +589,11 @@ class SILBuilder { beginApply)); } - EndApplyInst *createEndApply(SILLocation loc, SILValue beginApply) { + EndApplyInst *createEndApply(SILLocation loc, SILValue beginApply, SILType ResultType) { return insert(new (getModule()) EndApplyInst(getSILDebugLocation(loc), - beginApply)); + beginApply, ResultType)); } - + BuiltinInst *createBuiltin(SILLocation Loc, Identifier Name, SILType ResultTy, SubstitutionMap Subs, ArrayRef Args) { diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h index 37b26e7e528a6..879a08e86dfad 100644 --- a/include/swift/SIL/SILCloner.h +++ b/include/swift/SIL/SILCloner.h @@ -1077,7 +1077,8 @@ SILCloner::visitEndApplyInst(EndApplyInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); recordClonedInstruction( Inst, getBuilder().createEndApply(getOpLocation(Inst->getLoc()), - getOpValue(Inst->getOperand()))); + getOpValue(Inst->getOperand()), + getOpType(Inst->getType()))); } template diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h index 35c802d627e3d..a6999c8825454 100644 --- a/include/swift/SIL/SILInstruction.h +++ b/include/swift/SIL/SILInstruction.h @@ -3253,11 +3253,12 @@ class AbortApplyInst /// normally. class EndApplyInst : public UnaryInstructionBase { + SingleValueInstruction> { friend SILBuilder; - EndApplyInst(SILDebugLocation debugLoc, SILValue beginApplyToken) - : UnaryInstructionBase(debugLoc, beginApplyToken) { + EndApplyInst(SILDebugLocation debugLoc, SILValue beginApplyToken, + SILType Ty) + : UnaryInstructionBase(debugLoc, beginApplyToken, Ty) { assert(isaResultOf(beginApplyToken) && isaResultOf(beginApplyToken)->isBeginApplyToken()); } diff --git a/include/swift/SIL/SILNodes.def b/include/swift/SIL/SILNodes.def index 54ab59391d408..7a00efc4d2ceb 100644 --- a/include/swift/SIL/SILNodes.def +++ b/include/swift/SIL/SILNodes.def @@ -568,6 +568,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction) SingleValueInstruction, MayHaveSideEffects, MayRelease) SINGLE_VALUE_INST(PartialApplyInst, partial_apply, SingleValueInstruction, MayHaveSideEffects, DoesNotRelease) + SINGLE_VALUE_INST(EndApplyInst, end_apply, + SILInstruction, MayHaveSideEffects, MayRelease) SINGLE_VALUE_INST(FunctionExtractIsolationInst, function_extract_isolation, SingleValueInstruction, None, DoesNotRelease) @@ -873,8 +875,6 @@ NON_VALUE_INST(UncheckedRefCastAddrInst, unchecked_ref_cast_addr, SILInstruction, MayHaveSideEffects, DoesNotRelease) NON_VALUE_INST(AllocGlobalInst, alloc_global, SILInstruction, MayHaveSideEffects, DoesNotRelease) -NON_VALUE_INST(EndApplyInst, end_apply, - SILInstruction, MayHaveSideEffects, MayRelease) NON_VALUE_INST(AbortApplyInst, abort_apply, SILInstruction, MayHaveSideEffects, MayRelease) NON_VALUE_INST(PackElementSetInst, pack_element_set, diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 3e0e355c1ee4c..ba3e72342c82f 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -4524,29 +4524,29 @@ SILFunctionType::SILFunctionType( !ext.getLifetimeDependenceInfo().empty(); Bits.SILFunctionType.CoroutineKind = unsigned(coroutineKind); NumParameters = params.size(); - if (coroutineKind == SILCoroutineKind::None) { - assert(yields.empty()); - NumAnyResults = normalResults.size(); - NumAnyIndirectFormalResults = 0; - NumPackResults = 0; - for (auto &resultInfo : normalResults) { - if (resultInfo.isFormalIndirect()) - NumAnyIndirectFormalResults++; - if (resultInfo.isPack()) - NumPackResults++; - } - memcpy(getMutableResults().data(), normalResults.data(), - normalResults.size() * sizeof(SILResultInfo)); - } else { - assert(normalResults.empty()); - NumAnyResults = yields.size(); - NumAnyIndirectFormalResults = 0; + assert((coroutineKind == SILCoroutineKind::None && yields.empty()) || + coroutineKind != SILCoroutineKind::None); + + NumAnyResults = normalResults.size(); + NumAnyIndirectFormalResults = 0; + NumPackResults = 0; + for (auto &resultInfo : normalResults) { + if (resultInfo.isFormalIndirect()) + NumAnyIndirectFormalResults++; + if (resultInfo.isPack()) + NumPackResults++; + } + memcpy(getMutableResults().data(), normalResults.data(), + normalResults.size() * sizeof(SILResultInfo)); + if (coroutineKind != SILCoroutineKind::None) { + NumAnyYieldResults = yields.size(); + NumAnyIndirectFormalYieldResults = 0; NumPackResults = 0; for (auto &yieldInfo : yields) { if (yieldInfo.isFormalIndirect()) - NumAnyIndirectFormalResults++; + NumAnyIndirectFormalYieldResults++; if (yieldInfo.isPack()) - NumPackResults++; + NumPackYieldResults++; } memcpy(getMutableYields().data(), yields.data(), yields.size() * sizeof(SILYieldInfo)); @@ -4718,7 +4718,6 @@ CanSILFunctionType SILFunctionType::get( std::optional errorResult, SubstitutionMap patternSubs, SubstitutionMap invocationSubs, const ASTContext &ctx, ProtocolConformanceRef witnessMethodConformance) { - assert(coroutineKind == SILCoroutineKind::None || normalResults.empty()); assert(coroutineKind != SILCoroutineKind::None || yields.empty()); assert(!ext.isPseudogeneric() || genericSig || coroutineKind != SILCoroutineKind::None); diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index 4dceadb3c14cf..9cfa58e8078bf 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -661,9 +661,6 @@ namespace { } void SignatureExpansion::expandCoroutineResult(bool forContinuation) { - assert(FnType->getNumResults() == 0 && - "having both normal and yield results is currently unsupported"); - // The return type may be different for the ramp function vs. the // continuations. if (forContinuation) { @@ -671,14 +668,27 @@ void SignatureExpansion::expandCoroutineResult(bool forContinuation) { case SILCoroutineKind::None: llvm_unreachable("should have been filtered out before here"); - // Yield-once coroutines just return void from the continuation. - case SILCoroutineKind::YieldOnce: - ResultIRType = IGM.VoidTy; + // Yield-once coroutines may optionaly return a value from the continuation. + case SILCoroutineKind::YieldOnce: { + auto fnConv = getSILFuncConventions(); + + assert(fnConv.getNumIndirectSILResults() == 0); + // Ensure that no parameters were added before to correctly record their ABI + // details. + assert(ParamIRTypes.empty()); + + // Expand the direct result. + const TypeInfo *directResultTypeInfo; + std::tie(ResultIRType, directResultTypeInfo) = expandDirectResult(); + return; + } // Yield-many coroutines yield the same types from the continuation // as they do from the ramp function. case SILCoroutineKind::YieldMany: + assert(FnType->getNumResults() == 0 && + "having both normal and yield results is currently unsupported"); break; } } @@ -5703,6 +5713,117 @@ void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout, emitAsyncReturn(IGF, asyncLayout, fnType, nativeResults); } +void irgen::emitYieldOnceCoroutineResult(IRGenFunction &IGF, Explosion &result, + SILType funcResultType, SILType returnResultType) { + auto &Builder = IGF.Builder; + auto &IGM = IGF.IGM; + + // Prepare coroutine result values + auto &coroResults = IGF.coroutineResults; + assert(coroResults.empty() && "must only be single return"); + if (result.empty()) { + assert(IGM.getTypeInfo(returnResultType) + .nativeReturnValueSchema(IGM) + .empty() && + "Empty explosion must match the native calling convention"); + } else { + result = IGF.coerceValueTo(returnResultType, result, funcResultType); + auto &nativeSchema = + IGM.getTypeInfo(funcResultType).nativeReturnValueSchema(IGM); + assert(!nativeSchema.requiresIndirect()); + + Explosion native = nativeSchema.mapIntoNative(IGM, IGF, result, + funcResultType, + false /* isOutlined */); + for (unsigned i = 0, e = native.size(); i != e; ++i) + coroResults.push_back(native.claimNext()); + } + + auto coroEndBB = IGF.getCoroutineExitBlock(); + auto handle = IGF.getCoroutineHandle(); + bool newEndBlock = false; + if (!coroEndBB) { + coroEndBB = IGF.createBasicBlock("coro.end"); + IGF.setCoroutineExitBlock(coroEndBB); + newEndBlock = true; + } + + // If there are coroutine results, then we need to capture them via + // @llvm.coro_end_results intrinsics. However, since unwind blocks would + // jump to the same block, we wrap values into phi nodes. + Builder.CreateBr(coroEndBB); + + // Emit the end block. + llvm::BasicBlock *returnBB = Builder.GetInsertBlock(); + + if (newEndBlock) { + Builder.emitBlock(coroEndBB); + + llvm::Value *resultToken = nullptr; + if (coroResults.empty()) { + // No results: just use none token + resultToken = llvm::ConstantTokenNone::get(Builder.getContext()); + } else { + // Otherwise, wrap result values into singleton phi nodes + for (auto &val : coroResults) { + auto *phi = Builder.CreatePHI(val->getType(), 0); + phi->addIncoming(val, returnBB); + val = phi; + } + + // Capture results via result token + resultToken = + Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end_results, coroResults); + + Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end, + {handle, + /*is unwind*/ Builder.getFalse(), + resultToken}); + Builder.CreateUnreachable(); + } + } else { + if (coroResults.empty()) { + // No results, we do not need to change anything around existing coro.end + return; + } + + // Otherwise, we'd need to insert new coro.end.results intrinsics capturing + // result values. However, we'd need to wrap results into phi nodes adding + // undef for all values coming from incoming unwind blocks. + + // Find coro.end intrinsic + llvm::CallInst *coroEndCall = nullptr; + for (llvm::Instruction &inst : coroEndBB->instructionsWithoutDebug()) { + if (auto *CI = dyn_cast(&inst)) { + if (CI->getIntrinsicID() == llvm::Intrinsic::coro_end) { + coroEndCall = CI; + break; + } + } + } + + assert(coroEndCall && isa(coroEndCall->getArgOperand(2)) && + "invalid unwind coro.end call"); + + Builder.SetInsertPoint(&*coroEndBB->getFirstInsertionPt()); + + for (auto &val : coroResults) { + auto *phi = Builder.CreatePHI(val->getType(), llvm::pred_size(coroEndBB)); + for (auto *predBB : llvm::predecessors(coroEndBB)) + phi->addIncoming(predBB == returnBB ? val : llvm::UndefValue::get(val->getType()), + predBB); + + val = phi; + } + + // Capture results via result token and replace coro.end token operand + auto *resultToken = + Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end_results, coroResults); + coroEndCall->setArgOperand(2, resultToken); + Builder.SetInsertPoint(returnBB); + } +} + FunctionPointer IRGenFunction::getFunctionPointerForResumeIntrinsic(llvm::Value *resume) { auto *fnTy = llvm::FunctionType::get( diff --git a/lib/IRGen/GenCall.h b/lib/IRGen/GenCall.h index 557cae9023e01..7adca3f8afc39 100644 --- a/lib/IRGen/GenCall.h +++ b/lib/IRGen/GenCall.h @@ -247,6 +247,8 @@ namespace irgen { SILType funcResultTypeInContext, CanSILFunctionType fnType, Explosion &result, Explosion &error); + void emitYieldOnceCoroutineResult(IRGenFunction &IGF, Explosion &result, + SILType funcResultType, SILType returnResultType); Address emitAutoDiffCreateLinearMapContextWithType( IRGenFunction &IGF, llvm::Value *topLevelSubcontextMetatype); diff --git a/lib/IRGen/IRGenFunction.cpp b/lib/IRGen/IRGenFunction.cpp index e2baf08b3c703..69ad945f002d7 100644 --- a/lib/IRGen/IRGenFunction.cpp +++ b/lib/IRGen/IRGenFunction.cpp @@ -709,7 +709,7 @@ void IRGenFunction::emitAwaitAsyncContinuation( // because the continuation result is not available yet. When the // continuation is later resumed, the task will get scheduled // starting from the suspension point. - emitCoroutineOrAsyncExit(); + emitCoroutineOrAsyncExit(false); } Builder.emitBlock(contBB); diff --git a/lib/IRGen/IRGenFunction.h b/lib/IRGen/IRGenFunction.h index 16987e3d0d736..6575b646082fb 100644 --- a/lib/IRGen/IRGenFunction.h +++ b/lib/IRGen/IRGenFunction.h @@ -155,6 +155,18 @@ class IRGenFunction { CoroutineHandle = handle; } + llvm::BasicBlock *getCoroutineExitBlock() const { + return CoroutineExitBlock; + } + + SmallVector coroutineResults; + + void setCoroutineExitBlock(llvm::BasicBlock *block) { + assert(CoroutineExitBlock == nullptr && "already set exit BB"); + assert(block != nullptr && "setting a null exit BB"); + CoroutineExitBlock = block; + } + llvm::Value *getAsyncTask(); llvm::Value *getAsyncContext(); void storeCurrentAsyncContext(llvm::Value *context); @@ -236,7 +248,7 @@ class IRGenFunction { bool callsAnyAlwaysInlineThunksWithForeignExceptionTraps = false; public: - void emitCoroutineOrAsyncExit(); + void emitCoroutineOrAsyncExit(bool isUnwind); //--- Helper methods ----------------------------------------------------------- public: diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index ad795a76c77e6..918bd4c9d74c9 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -1429,7 +1429,7 @@ class IRGenSILFunction : void visitBeginApplyInst(BeginApplyInst *i); void visitEndApplyInst(EndApplyInst *i); void visitAbortApplyInst(AbortApplyInst *i); - void visitEndApply(BeginApplyInst *i, bool isAbort); + void visitEndApply(BeginApplyInst *i, EndApplyInst *ei = nullptr); void visitUnreachableInst(UnreachableInst *i); void visitBranchInst(BranchInst *i); @@ -4134,38 +4134,55 @@ void IRGenSILFunction::visitStringLiteralInst(swift::StringLiteralInst *i) { void IRGenSILFunction::visitUnreachableInst(swift::UnreachableInst *i) { if (isAsync()) { - emitCoroutineOrAsyncExit(); + emitCoroutineOrAsyncExit(false); return; } Builder.CreateUnreachable(); } -void IRGenFunction::emitCoroutineOrAsyncExit() { - // The LLVM coroutine representation demands that there be a - // unique call to llvm.coro.end. +void IRGenFunction::emitCoroutineOrAsyncExit(bool isUnwind) { + // LLVM's retcon lowering is a bit imcompatible with Swift + // model. Essentially it assumes that unwind destination is kind of terminal - + // it cannot return back to caller and must somehow terminate the process / + // thread. Therefore we are always use normal LLVM coroutine termination. + // However, for yield_once coroutines we need also specify undef results on + // unwind path. Eventually, we'd get rid of these crazy phis... // If the coroutine exit block already exists, just branch to it. - if (auto coroEndBB = CoroutineExitBlock) { + auto *coroEndBB = getCoroutineExitBlock(); + auto *unwindBB = Builder.GetInsertBlock(); + + // If the coroutine exit block already exists, just branch to it. + if (coroEndBB) { Builder.CreateBr(coroEndBB); + + if (!isAsync()) { + // If there are any result values we need to add undefs for all values + // coming from unwind block + for (auto &phi : coroutineResults) + cast(phi)->addIncoming(llvm::UndefValue::get(phi->getType()), + unwindBB); + } + return; } // Otherwise, create it and branch to it. - auto coroEndBB = createBasicBlock("coro.end"); - CoroutineExitBlock = coroEndBB; + coroEndBB = createBasicBlock("coro.end"); + setCoroutineExitBlock(coroEndBB); Builder.CreateBr(coroEndBB); - - // Emit the block. Builder.emitBlock(coroEndBB); - auto handle = getCoroutineHandle(); + if (isAsync()) Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end_async, - {handle, - /*is unwind*/ Builder.getFalse()}); + { getCoroutineHandle(), Builder.getFalse()}); else + // Do not bother about results here, normal result emission code would + // update token value. Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end, - {handle, - /*is unwind*/ Builder.getFalse()}); + { getCoroutineHandle(), Builder.getFalse(), + llvm::ConstantTokenNone::get(Builder.getContext())}); + Builder.CreateUnreachable(); } @@ -4173,13 +4190,6 @@ static void emitReturnInst(IRGenSILFunction &IGF, SILType resultTy, Explosion &result, CanSILFunctionType fnType) { - // If we're generating a coroutine, just call coro.end. - if (IGF.isCoroutine() && !IGF.isAsync()) { - assert(result.empty() && - "coroutines do not currently support non-void returns"); - IGF.emitCoroutineOrAsyncExit(); - return; - } SILFunctionConventions conv(IGF.CurSILFn->getLoweredFunctionType(), IGF.getSILModule()); @@ -4194,6 +4204,24 @@ static void emitReturnInst(IRGenSILFunction &IGF, return llvm::ConstantPointerNull::get(IGF.IGM.Int8PtrTy); }; + // If we're generating a coroutine, just call coro.end. + if (IGF.isCoroutine() && !IGF.isAsync()) { + if (fnType->getCoroutineKind() == SILCoroutineKind::YieldOnce) { + assert(IGF.CurSILFn->getLoweredFunctionType()->getLanguage() == + SILFunctionLanguage::Swift); + auto funcResultType = IGF.CurSILFn->mapTypeIntoContext( + conv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext())); + + emitYieldOnceCoroutineResult(IGF, result, funcResultType, resultTy); + return; + } + + assert(result.empty() && + "coroutines do not currently support non-void returns"); + IGF.emitCoroutineOrAsyncExit(false); + return; + } + // The invariant on the out-parameter is that it's always zeroed, so // there's nothing to do here. @@ -4352,9 +4380,8 @@ void IRGenSILFunction::visitThrowAddrInst(swift::ThrowAddrInst *i) { } void IRGenSILFunction::visitUnwindInst(swift::UnwindInst *i) { - // Just call coro.end; there's no need to distinguish 'unwind' - // and 'return' at the LLVM level. - emitCoroutineOrAsyncExit(); + // Call coro.end marking unwind return + emitCoroutineOrAsyncExit(true); } void IRGenSILFunction::visitYieldInst(swift::YieldInst *i) { @@ -4391,15 +4418,16 @@ void IRGenSILFunction::visitBeginApplyInst(BeginApplyInst *i) { } void IRGenSILFunction::visitEndApplyInst(EndApplyInst *i) { - visitEndApply(i->getBeginApply(), false); + visitEndApply(i->getBeginApply(), i); } void IRGenSILFunction::visitAbortApplyInst(AbortApplyInst *i) { - visitEndApply(i->getBeginApply(), true); + visitEndApply(i->getBeginApply()); } -void IRGenSILFunction::visitEndApply(BeginApplyInst *i, bool isAbort) { +void IRGenSILFunction::visitEndApply(BeginApplyInst *i, EndApplyInst *ei) { const auto &coroutine = getLoweredCoroutine(i->getTokenResult()); + bool isAbort = ei == nullptr; auto sig = Signature::forCoroutineContinuation(IGM, i->getOrigCalleeType()); @@ -4408,7 +4436,6 @@ void IRGenSILFunction::visitEndApply(BeginApplyInst *i, bool isAbort) { continuation = Builder.CreateBitCast(continuation, sig.getType()->getPointerTo()); - auto schemaAndEntity = getCoroutineResumeFunctionPointerAuth(IGM, i->getOrigCalleeType()); auto pointerAuth = PointerAuthInfo::emit(*this, schemaAndEntity.first, @@ -4417,10 +4444,21 @@ void IRGenSILFunction::visitEndApply(BeginApplyInst *i, bool isAbort) { auto callee = FunctionPointer::createSigned(i->getOrigCalleeType(), continuation, pointerAuth, sig); - Builder.CreateCall(callee, { - coroutine.Buffer.getAddress(), - llvm::ConstantInt::get(IGM.Int1Ty, isAbort) - }); + auto *call = Builder.CreateCall(callee, { + coroutine.Buffer.getAddress(), + llvm::ConstantInt::get(IGM.Int1Ty, isAbort) + }); + + if (!isAbort) { + auto resultType = call->getType(); + if (!resultType->isVoidTy()) { + Explosion e; + // FIXME: Do we need to handle ABI-related conversions here? + // It seems we cannot have C function convention for coroutines, etc. + extractScalarResults(*this, resultType, call, e); + setLoweredExplosion(ei, e); + } + } coroutine.Temporaries.destroyAll(*this); diff --git a/lib/SIL/IR/SILPrinter.cpp b/lib/SIL/IR/SILPrinter.cpp index c90d896dd574b..08362e337ff96 100644 --- a/lib/SIL/IR/SILPrinter.cpp +++ b/lib/SIL/IR/SILPrinter.cpp @@ -1613,7 +1613,7 @@ class SILPrinter : public SILInstructionVisitor { } void visitEndApplyInst(EndApplyInst *AI) { - *this << Ctx.getID(AI->getOperand()); + *this << Ctx.getID(AI->getOperand()) << " as " << AI->getType(); } void visitFunctionRefInst(FunctionRefInst *FRI) { diff --git a/lib/SIL/IR/ValueOwnership.cpp b/lib/SIL/IR/ValueOwnership.cpp index 3d38a375767bd..932dbee4ee2d8 100644 --- a/lib/SIL/IR/ValueOwnership.cpp +++ b/lib/SIL/IR/ValueOwnership.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "swift/SIL/ApplySite.h" #include "swift/SIL/SILBuiltinVisitor.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/SILVisitor.h" @@ -348,14 +349,18 @@ ValueOwnershipKind ValueOwnershipKindClassifier::visitSILFunctionArgument( return Arg->getOwnershipKind(); } -ValueOwnershipKind ValueOwnershipKindClassifier::visitApplyInst(ApplyInst *ai) { - auto *f = ai->getFunction(); - bool isTrivial = ai->getType().isTrivial(*f); +// We have to separate out ResultType here as `begin_apply` does not produce +// normal results, `end_apply` does and there might be multiple `end_apply`'s +// that correspond to a single `begin_apply`. +static ValueOwnershipKind visitFullApplySite(FullApplySite fai, + SILType ResultType) { + auto *f = fai->getFunction(); + bool isTrivial = ResultType.isTrivial(*f); // Quick is trivial check. if (isTrivial) return OwnershipKind::None; - SILFunctionConventions fnConv(ai->getSubstCalleeType(), f->getModule()); + SILFunctionConventions fnConv(fai.getSubstCalleeType(), f->getModule()); auto results = fnConv.getDirectSILResults(); // No results => None. if (results.empty()) @@ -364,7 +369,7 @@ ValueOwnershipKind ValueOwnershipKindClassifier::visitApplyInst(ApplyInst *ai) { // Otherwise, map our results to their ownership kinds and then merge them! auto resultOwnershipKinds = makeTransformRange(results, [&](const SILResultInfo &info) { - return info.getOwnershipKind(*f, ai->getSubstCalleeType()); + return info.getOwnershipKind(*f, fai.getSubstCalleeType()); }); auto mergedOwnershipKind = ValueOwnershipKind::merge(resultOwnershipKinds); if (!mergedOwnershipKind) { @@ -374,6 +379,14 @@ ValueOwnershipKind ValueOwnershipKindClassifier::visitApplyInst(ApplyInst *ai) { return mergedOwnershipKind; } +ValueOwnershipKind ValueOwnershipKindClassifier::visitApplyInst(ApplyInst *ai) { + return visitFullApplySite(ai, ai->getType()); +} + +ValueOwnershipKind ValueOwnershipKindClassifier::visitEndApplyInst(EndApplyInst *eai) { + return visitFullApplySite(eai->getBeginApply(), eai->getType()); +} + ValueOwnershipKind ValueOwnershipKindClassifier::visitLoadInst(LoadInst *LI) { switch (LI->getOwnershipQualifier()) { case LoadOwnershipQualifier::Take: diff --git a/lib/SIL/Parser/ParseSIL.cpp b/lib/SIL/Parser/ParseSIL.cpp index 14ff7c056d513..c9a66594f813a 100644 --- a/lib/SIL/Parser/ParseSIL.cpp +++ b/lib/SIL/Parser/ParseSIL.cpp @@ -2652,8 +2652,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B, if (parseCallInstruction(InstLoc, Opcode, B, ResultVal)) return true; break; - case SILInstructionKind::AbortApplyInst: - case SILInstructionKind::EndApplyInst: { + case SILInstructionKind::AbortApplyInst: { UnresolvedValueName argName; if (parseValueName(argName)) return true; @@ -2663,12 +2662,21 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B, SILType expectedTy = SILType::getSILTokenType(P.Context); SILValue op = getLocalValue(argName, expectedTy, InstLoc, B); + ResultVal = B.createAbortApply(InstLoc, op); + break; + } + case SILInstructionKind::EndApplyInst: { + UnresolvedValueName argName; + SILType ResultTy; - if (Opcode == SILInstructionKind::AbortApplyInst) { - ResultVal = B.createAbortApply(InstLoc, op); - } else { - ResultVal = B.createEndApply(InstLoc, op); - } + if (parseValueName(argName) || parseVerbatim("as") || + parseSILType(ResultTy) || parseSILDebugLocation(InstLoc, B)) + return true; + + SILType expectedTy = SILType::getSILTokenType(P.Context); + SILValue op = getLocalValue(argName, expectedTy, InstLoc, B); + + ResultVal = B.createEndApply(InstLoc, op, ResultTy); break; } case SILInstructionKind::IntegerLiteralInst: { diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index 90a95a1f9a139..dd9fca7e1ed5a 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -2031,6 +2031,13 @@ class SILVerifier : public SILVerifierBase { void checkEndApplyInst(EndApplyInst *AI) { require(getAsResultOf(AI->getOperand())->isBeginApplyToken(), "operand of end_apply must be a begin_apply"); + + BeginApplyInst *bai = AI->getBeginApply(); + SILFunctionConventions calleeConv(bai->getSubstCalleeType(), F.getModule()); + + requireSameType( + AI->getType(), calleeConv.getSILResultType(F.getTypeExpansionContext()), + "callee result type does not match end_apply result type"); } void verifyLLVMIntrinsic(BuiltinInst *BI, llvm::Intrinsic::ID ID) { diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index a3372c6f0ee3f..05d7299538764 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -4973,7 +4973,8 @@ class EndCoroutineApply : public Cleanup { if (forUnwind) { SGF.B.createAbortApply(l, ApplyToken); } else { - SGF.B.createEndApply(l, ApplyToken); + SGF.B.createEndApply(l, ApplyToken, + SILType::getEmptyTupleType(SGF.getASTContext())); } } @@ -5989,7 +5990,8 @@ void SILGenFunction::emitEndApplyWithRethrow(SILLocation loc, // TODO: adjust this to handle results of TryBeginApplyInst. assert(token->isBeginApplyToken()); - B.createEndApply(loc, token); + B.createEndApply(loc, token, + SILType::getEmptyTupleType(getASTContext())); } void SILGenFunction::emitYield(SILLocation loc, diff --git a/lib/SILGen/SILGenBackDeploy.cpp b/lib/SILGen/SILGenBackDeploy.cpp index 4df614b40dc7a..26dbf30de19d9 100644 --- a/lib/SILGen/SILGenBackDeploy.cpp +++ b/lib/SILGen/SILGenBackDeploy.cpp @@ -121,12 +121,14 @@ static void emitBackDeployForwardApplyAndReturnOrThrow( // Emit resume block. SGF.B.emitBlock(resumeBB); - SGF.B.createEndApply(loc, token); + SGF.B.createEndApply(loc, token, + SILType::getEmptyTupleType(SGF.getASTContext())); SGF.B.createBranch(loc, SGF.ReturnDest.getBlock()); // Emit unwind block. SGF.B.emitBlock(unwindBB); - SGF.B.createEndApply(loc, token); + SGF.B.createEndApply(loc, token, + SILType::getEmptyTupleType(SGF.getASTContext())); SGF.B.createBranch(loc, SGF.CoroutineUnwindDest.getBlock()); return; } diff --git a/lib/SILOptimizer/Utils/SILInliner.cpp b/lib/SILOptimizer/Utils/SILInliner.cpp index 49bc723cd0263..c422168994dfa 100644 --- a/lib/SILOptimizer/Utils/SILInliner.cpp +++ b/lib/SILOptimizer/Utils/SILInliner.cpp @@ -207,13 +207,16 @@ class BeginApplySite { // instructions in the caller. That means this entire path is // unreachable. if (isa(terminator) || isa(terminator)) { - bool isNormal = isa(terminator); - auto returnBB = isNormal ? EndApplyReturnBB : AbortApplyReturnBB; + ReturnInst *retInst = dyn_cast(terminator); + auto *returnBB = retInst ? EndApplyReturnBB : AbortApplyReturnBB; + if (retInst && EndApply) + EndApply->replaceAllUsesWith(getMappedValue(retInst->getOperand())); if (returnBB) { Builder->createBranch(Loc, returnBB); } else { Builder->createUnreachable(Loc); } + return true; } diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp index bdc1b9fb720e1..09cca5520bc90 100644 --- a/lib/Serialization/DeserializeSIL.cpp +++ b/lib/Serialization/DeserializeSIL.cpp @@ -1607,6 +1607,7 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, ONEOPERAND_ONETYPE_INST(ObjCMetatypeToObject) ONEOPERAND_ONETYPE_INST(ObjCExistentialMetatypeToObject) ONEOPERAND_ONETYPE_INST(ProjectBlockStorage) + ONEOPERAND_ONETYPE_INST(EndApply) #undef ONEOPERAND_ONETYPE_INST case SILInstructionKind::AddressToPointerInst: { @@ -2263,7 +2264,6 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, REFCOUNTING_INSTRUCTION(StrongRelease) UNARY_INSTRUCTION(IsUnique) UNARY_INSTRUCTION(AbortApply) - UNARY_INSTRUCTION(EndApply) UNARY_INSTRUCTION(ExtractExecutor) UNARY_INSTRUCTION(FunctionExtractIsolation) #undef UNARY_INSTRUCTION diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index a0a5466e9f386..ca6e428f0e472 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 867; // _distributed_get accessor for distributed thunks +const uint16_t SWIFTMODULE_VERSION_MINOR = 868; // end_apply result /// A standard hash seed used for all string hashes in a serialized module. /// diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp index 4ff6c5d9f51c7..e34537a7083b5 100644 --- a/lib/Serialization/SerializeSIL.cpp +++ b/lib/Serialization/SerializeSIL.cpp @@ -1550,7 +1550,6 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) { case SILInstructionKind::ExtractExecutorInst: case SILInstructionKind::FunctionExtractIsolationInst: case SILInstructionKind::AbortApplyInst: - case SILInstructionKind::EndApplyInst: case SILInstructionKind::ReturnInst: case SILInstructionKind::UncheckedOwnershipConversionInst: case SILInstructionKind::IsEscapingClosureInst: @@ -1602,6 +1601,12 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) { writeOneOperandLayout(SI.getKind(), Attr, SI.getOperand(0)); break; } + case SILInstructionKind::EndApplyInst: { + const auto *eai = cast(&SI); + writeOneTypeOneOperandLayout( + eai->getKind(), 0, eai->getType(), eai->getOperand()); + break; + } case SILInstructionKind::MarkUnresolvedNonCopyableValueInst: { unsigned Attr = unsigned(cast(&SI)->getCheckKind()); diff --git a/test/IRGen/big_types.sil b/test/IRGen/big_types.sil index 219602e9e30c9..2dc4887943472 100644 --- a/test/IRGen/big_types.sil +++ b/test/IRGen/big_types.sil @@ -89,8 +89,7 @@ unwind: // CHECK-NEXT: // function_ref // CHECK-NEXT: [[USE:%.*]] = function_ref @use_big_struct : $@convention(thin) (@in_guaranteed BigStruct) -> () // CHECK-NEXT: apply [[USE]]([[TEMP]]) -// CHECK-NEXT: end_apply [[TOKEN]] -// CHECK-NEXT: [[RET:%.*]] = tuple () +// CHECK-NEXT: [[RET:%.*]] = end_apply [[TOKEN]] as $() // CHECK-NEXT: dealloc_stack [[TEMP]] : $*BigStruct // CHECK-NEXT: return [[RET]] : $() sil @use_yield_big : $@convention(thin) () -> () { @@ -99,8 +98,7 @@ entry: (%big, %token) = begin_apply %yield_big() : $@convention(thin) @yield_once() -> (@yields BigStruct) %use_big = function_ref @use_big_struct : $@convention(thin) (BigStruct) -> () apply %use_big(%big) : $@convention(thin) (BigStruct) -> () - end_apply %token - %ret = tuple () + %ret = end_apply %token as $() return %ret : $() } @@ -116,7 +114,7 @@ bb0: yield %3 : $*Optional<@callee_guaranteed (@guaranteed BigStruct) -> ()>, resume bb1, unwind bb2 bb1: - end_apply %4 + end_apply %4 as $() %7 = tuple () return %7 : $() diff --git a/test/IRGen/ptrauth-functions.sil b/test/IRGen/ptrauth-functions.sil index 302304756f1dd..978625aa51adc 100644 --- a/test/IRGen/ptrauth-functions.sil +++ b/test/IRGen/ptrauth-functions.sil @@ -77,7 +77,7 @@ sil @test_generic_return : $@convention(thin) (@guaranteed T) -> () { bb0(%0 : $T): %1 = function_ref @generic_return : $@convention(thin) @yield_once (@guaranteed T) -> (@yields @guaranteed T) (%value, %token) = begin_apply %1(%0) : $@convention(thin) @yield_once (@guaranteed T) -> (@yields @guaranteed T) - end_apply %token + end_apply %token as $() %ret = tuple () return %ret : $() } diff --git a/test/IRGen/yield_once.sil b/test/IRGen/yield_once.sil index 10ba0a51edd53..f3282a6ef4e76 100644 --- a/test/IRGen/yield_once.sil +++ b/test/IRGen/yield_once.sil @@ -39,7 +39,7 @@ unwind: unwind // CHECK: coro.end: - // CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false) + // CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false, token none) // CHECK-NEXT: unreachable } @@ -70,7 +70,7 @@ yes: // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK: call swiftcc void [[CONTINUATION]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false) // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]]) - end_apply %token + end_apply %token as $() // CHECK-NEXT: br label br cont @@ -120,7 +120,7 @@ entry: // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK-NEXT: call swiftcc void [[CONTINUATION]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false) // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]]) - end_apply %token + end_apply %token as $() // CHECK-NEXT: call swiftcc void @marker(i32 [[SECOND]]) apply %marker(%second) : $@convention(thin) (Builtin.Int32) -> () diff --git a/test/IRGen/yield_once_big.sil b/test/IRGen/yield_once_big.sil index 0e23ab578a834..84578a1b17b00 100644 --- a/test/IRGen/yield_once_big.sil +++ b/test/IRGen/yield_once_big.sil @@ -85,7 +85,7 @@ unwind: unwind // CHECK: coro.end: - // CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false) + // CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false, token none) // CHECK-NEXT: unreachable } @@ -139,7 +139,7 @@ yes: // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK: call swiftcc void [[CONTINUATION]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false) // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]]) - end_apply %token + end_apply %token as $() // CHECK-NEXT: br label br cont @@ -233,6 +233,6 @@ unwind: unwind // CHECK: coro.end: - // CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false) + // CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false, token none) // CHECK-NEXT: unreachable } diff --git a/test/IRGen/yield_once_biggish.sil b/test/IRGen/yield_once_biggish.sil index 087215761b422..72e09248f110f 100644 --- a/test/IRGen/yield_once_biggish.sil +++ b/test/IRGen/yield_once_biggish.sil @@ -89,7 +89,7 @@ unwind: unwind // CHECK: coro.end: - // CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false) + // CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false, token none) // CHECK-NEXT: unreachable } @@ -131,7 +131,7 @@ yes: // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK: call swiftcc void [[CONTINUATION]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false) // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]]) - end_apply %token + end_apply %token as $() // CHECK-NEXT: br label br cont diff --git a/test/IRGen/yield_once_indirect.sil b/test/IRGen/yield_once_indirect.sil index c6f5104edcfa3..28af3ed2389c7 100644 --- a/test/IRGen/yield_once_indirect.sil +++ b/test/IRGen/yield_once_indirect.sil @@ -76,7 +76,7 @@ unwind: unwind // CHECK: coro.end: - // CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false) + // CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false, token none) // CHECK-NEXT: unreachable } @@ -116,7 +116,7 @@ yes: // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK: call swiftcc void [[CONTINUATION]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false) // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]]) - end_apply %token + end_apply %token as $() // CHECK-NEXT: br label br cont diff --git a/test/IRGen/yield_result.sil b/test/IRGen/yield_result.sil new file mode 100644 index 0000000000000..f41c9c7d77318 --- /dev/null +++ b/test/IRGen/yield_result.sil @@ -0,0 +1,93 @@ +// RUN: %target-swift-frontend -emit-irgen %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize + +import Builtin + +sil @marker : $(Builtin.Int64) -> () + +sil @coro_ret : $@yield_once @convention(thin) () -> (@yields Builtin.Int64, Builtin.Int64) +sil @coro_ret_pair : $@yield_once @convention(thin) () -> (@yields Builtin.Int64, Builtin.Int64, Builtin.Int64) + +// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @test_simple +// CHECK-32-SAME: ptr noalias dereferenceable([[BUFFER_SIZE:16]]) %0) +// CHECK-64-SAME: (ptr noalias dereferenceable([[BUFFER_SIZE:32]]) %0) +// CHECK-SAME: [[CORO_ATTRIBUTES:#[0-9]+]] +sil @test_simple : $@yield_once () -> (Builtin.Int64) { +entry: + // CHECK-32: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$sBi64_IetAd_TC", ptr @malloc, ptr @free) + // CHECK-64: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$sBi64_IetAd_TC", ptr @malloc, ptr @free) + // CHECK-NEXT: [[BEGIN:%.*]] = call ptr @llvm.coro.begin(token [[ID]], ptr null) + + // CHECK-NEXT: call swiftcc void @marker(i64 1000) + %marker = function_ref @marker : $@convention(thin) (Builtin.Int64) -> () + %1000 = integer_literal $Builtin.Int64, 1000 + apply %marker(%1000) : $@convention(thin) (Builtin.Int64) -> () + + // CHECK-NEXT: [[IS_UNWIND:%.*]] = call i1 (...) @llvm.coro.suspend.retcon.i1() + // CHECK-NEXT: br i1 [[IS_UNWIND]], label [[UNWIND_BB:%.*]], label [[RESUME_BB:%.*]] + yield (), resume resume, unwind unwind + +resume: + // CHECK: call swiftcc void @marker(i64 2000) + %2000 = integer_literal $Builtin.Int64, 2000 + apply %marker(%2000) : $@convention(thin) (Builtin.Int64) -> () + // CHECK: br label %coro.end + return %2000 : $Builtin.Int64 + +unwind: + // CHECK: call swiftcc void @marker(i64 3000) + %3000 = integer_literal $Builtin.Int64, 3000 + apply %marker(%3000) : $@convention(thin) (Builtin.Int64) -> () + // CHECK: br label %coro.end + unwind + + // CHECK: coro.end: + // CHECK: [[RESULT:%.*]] = phi i64 [ 2000, [[RESUME_BB]] ], [ undef, [[UNWIND_BB]] ] + // CHECK: [[TOKEN:%.*]] = call token (...) @llvm.coro.end.results(i64 [[RESULT]]) + // CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false, token [[TOKEN]]) + // CHECK-NEXT: unreachable +} + + +// CHECK-LABEL: test_coro_ret +sil @test_coro_ret : $() -> (Builtin.Int64, Builtin.Int64, Builtin.Int64) { +entry: + %marker = function_ref @marker : $@convention(thin) (Builtin.Int64) -> () + + %coro1 = function_ref @coro_ret : $@yield_once @convention(thin) () -> (@yields Builtin.Int64, Builtin.Int64) + (%first, %token1) = begin_apply %coro1() : $@yield_once @convention(thin) () -> (@yields Builtin.Int64, Builtin.Int64) + +// CHECK: [[T0:%.*]] = alloca {{\[}}[[BUFFER_SIZE1:.*]] x i8 +// CHECK: [[T1:%.*]] = alloca {{\[}}[[BUFFER_SIZE2:.*]] x i8 +// CHECK: [[BUFFER1:%.*]] = getelementptr inbounds {{\[}}[[BUFFER_SIZE1]] x i8], ptr [[T0]], i32 0, i32 0 +// CHECK: [[CORO1:%.*]] = call ptr @llvm.coro.prepare.retcon(ptr @coro_ret) +// CHECK: [[FRAME1:%.*]] = call swiftcc { ptr, i64 } [[CORO1]](ptr noalias dereferenceable([[BUFFER_SIZE1]]) [[BUFFER1]] +// CHECK: [[CONT1:%.*]] = extractvalue { ptr, i64 } [[FRAME1]], 0 + + apply %marker(%first) : $@convention(thin) (Builtin.Int64) -> () + + %ret = end_apply %token1 as $Builtin.Int64 + +// CHECK: call swiftcc i64 [[CONT1]](ptr noalias dereferenceable([[BUFFER_SIZE1]]) [[BUFFER1]], i1 false) + + apply %marker(%ret) : $@convention(thin) (Builtin.Int64) -> () + + %coro2 = function_ref @coro_ret_pair : $@yield_once @convention(thin) () -> (@yields Builtin.Int64, Builtin.Int64, Builtin.Int64) + (%second, %token2) = begin_apply %coro2() : $@yield_once @convention(thin) () -> (@yields Builtin.Int64, Builtin.Int64, Builtin.Int64) + +// CHECK: [[BUFFER2:%.*]] = getelementptr inbounds {{\[}}[[BUFFER_SIZE2]] x i8], ptr [[T1]], i32 0, i32 0 +// CHECK: [[CORO2:%.*]] = call ptr @llvm.coro.prepare.retcon(ptr @coro_ret_pair) +// CHECK: [[FRAME2:%.*]] = call swiftcc { ptr, i64 } [[CORO2]](ptr noalias dereferenceable([[BUFFER_SIZE2]]) [[BUFFER2]] +// CHECK: [[CONT2:%.*]] = extractvalue { ptr, i64 } [[FRAME2]], 0 + + %ret2 = end_apply %token2 as $(Builtin.Int64, Builtin.Int64) + +// CHECK: call swiftcc { i64, i64 } [[CONT2]](ptr noalias dereferenceable([[BUFFER_SIZE2]]) [[BUFFER2]], i1 false) + + %ret2_1 = tuple_extract %ret2 : $(Builtin.Int64, Builtin.Int64), 0 + %ret2_2 = tuple_extract %ret2 : $(Builtin.Int64, Builtin.Int64), 1 + + apply %marker(%second) : $@convention(thin) (Builtin.Int64) -> () + + %retf = tuple (%ret : $Builtin.Int64, %ret2_1 : $Builtin.Int64, %ret2_2 : $Builtin.Int64) + return %retf : $(Builtin.Int64, Builtin.Int64, Builtin.Int64) +} diff --git a/test/SIL/OwnershipVerifier/begin_apply_use_after_end_apply.sil b/test/SIL/OwnershipVerifier/begin_apply_use_after_end_apply.sil index 898c39decd9c0..ec9ac989cfec0 100644 --- a/test/SIL/OwnershipVerifier/begin_apply_use_after_end_apply.sil +++ b/test/SIL/OwnershipVerifier/begin_apply_use_after_end_apply.sil @@ -15,7 +15,7 @@ sil @use_klass : $@convention(thin) (@guaranteed Klass) -> () // CHECK-LABEL: Error#: 0. Begin Error in Function: 'guaranteed_coroutine_caller' // CHECK: Found outside of lifetime use?! // CHECK: Value: (**%3**, %4) = begin_apply %0() : $@yield_once @convention(thin) () -> @yields @guaranteed Klass // user: %6 -// CHECK: Consuming User: end_apply %4 // id: %5 +// CHECK: Consuming User: %5 = end_apply %4 as $() // CHECK: Non Consuming User: %6 = apply %2(%3) : $@convention(thin) (@guaranteed Klass) -> () // CHECK: Block: bb0 // CHECK: Error#: 0. End Error in Function: 'guaranteed_coroutine_caller' @@ -46,22 +46,22 @@ bb0: %user_func = function_ref @use_klass : $@convention(thin) (@guaranteed Klass) -> () (%0a, %0b) = begin_apply %0() : $@yield_once @convention(thin) () -> @yields @guaranteed Klass - end_apply %0b + end_apply %0b as $() apply %user_func(%0a) : $@convention(thin) (@guaranteed Klass) -> () (%val1, %tok1) = begin_apply %1() : $@yield_once @convention(thin) () -> @yields @owned Klass - end_apply %tok1 + end_apply %tok1 as $() apply %user_func(%val1) : $@convention(thin) (@guaranteed Klass) -> () (%val2, %tok2) = begin_apply %1() : $@yield_once @convention(thin) () -> @yields @owned Klass destroy_value %val2 : $Klass - end_apply %tok2 + end_apply %tok2 as $() apply %user_func(%val2) : $@convention(thin) (@guaranteed Klass) -> () (%val3, %tok3) = begin_apply %1() : $@yield_once @convention(thin) () -> @yields @owned Klass apply %user_func(%val3) : $@convention(thin) (@guaranteed Klass) -> () - end_apply %tok3 + end_apply %tok3 as $() %9999 = tuple() return %9999 : $() -} \ No newline at end of file +} diff --git a/test/SIL/OwnershipVerifier/borrow_scope_introducing_operands.sil b/test/SIL/OwnershipVerifier/borrow_scope_introducing_operands.sil index 6db92550cb6e3..6f356f9c76710 100644 --- a/test/SIL/OwnershipVerifier/borrow_scope_introducing_operands.sil +++ b/test/SIL/OwnershipVerifier/borrow_scope_introducing_operands.sil @@ -39,7 +39,7 @@ bb0(%0 : @owned $Builtin.NativeObject): // CHECK: Found outside of lifetime use?! // CHECK: Value: %0 = argument of bb0 : $Builtin.NativeObject // CHECK: Consuming User: destroy_value %0 : $Builtin.NativeObject -// CHECK: Non Consuming User: end_apply %2 +// CHECK: Non Consuming User: %4 = end_apply %2 as $() // CHECK: Block: bb0 // CHECK: Error#: 0. End Error in Function: 'destroy_value_before_end_borrow_coroutine' // @@ -49,7 +49,7 @@ bb0(%0 : @owned $Builtin.NativeObject): %coro = function_ref @coroutine_callee : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> () %token = begin_apply %coro(%0) : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> () destroy_value %0 : $Builtin.NativeObject - end_apply %token + end_apply %token as $() %r = tuple () return %r : $() } @@ -94,7 +94,7 @@ bb1: br bb3 bb2: - end_apply %token + end_apply %token as $() destroy_value %0 : $Builtin.NativeObject br bb3 @@ -107,7 +107,7 @@ bb3: // CHECK: Found outside of lifetime use?! // CHECK: Value: %1 = begin_borrow %0 : $Builtin.NativeObject // CHECK: Consuming User: end_borrow %1 : $Builtin.NativeObject -// CHECK: Non Consuming User: end_apply %3 +// CHECK: Non Consuming User: %5 = end_apply %3 as $() // CHECK: Block: bb0 // CHECK: Error#: 0. End Error in Function: 'parent_borrow_scope_end_before_end_borrow_coroutine' // @@ -118,7 +118,7 @@ bb0(%0 : @owned $Builtin.NativeObject): %coro = function_ref @coroutine_callee : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> () %token = begin_apply %coro(%1) : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> () end_borrow %1 : $Builtin.NativeObject - end_apply %token + end_apply %token as $() destroy_value %0 : $Builtin.NativeObject %r = tuple () return %r : $() @@ -167,7 +167,7 @@ bb1: br bb3 bb2: - end_apply %token + end_apply %token as $() end_borrow %1 : $Builtin.NativeObject br bb3 diff --git a/test/SIL/OwnershipVerifier/borrow_scope_introducing_operands_positive.sil b/test/SIL/OwnershipVerifier/borrow_scope_introducing_operands_positive.sil index 894a6bf56e565..e132a058d34b4 100644 --- a/test/SIL/OwnershipVerifier/borrow_scope_introducing_operands_positive.sil +++ b/test/SIL/OwnershipVerifier/borrow_scope_introducing_operands_positive.sil @@ -36,7 +36,7 @@ sil [ossa] @destroy_value_before_end_borrow_coroutine : $@convention(thin) (@own bb0(%0 : @owned $Builtin.NativeObject): %coro = function_ref @coroutine_callee : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> () %token = begin_apply %coro(%0) : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> () - end_apply %token + end_apply %token as $() destroy_value %0 : $Builtin.NativeObject %r = tuple () return %r : $() @@ -46,7 +46,7 @@ sil [ossa] @destroy_value_before_end_borrow_coroutine_1a : $@convention(thin) (@ bb0(%0 : @owned $Builtin.NativeObject): %coro = function_ref @coroutine_callee : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> () %token = begin_apply %coro(%0) : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> () - end_apply %token + end_apply %token as $() br bb1 bb1: @@ -90,7 +90,7 @@ bb1: br bb3 bb2: - end_apply %token + end_apply %token as $() destroy_value %0 : $Builtin.NativeObject br bb3 @@ -104,7 +104,7 @@ bb0(%0 : @owned $Builtin.NativeObject): %1 = begin_borrow %0 : $Builtin.NativeObject %coro = function_ref @coroutine_callee : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> () %token = begin_apply %coro(%1) : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> () - end_apply %token + end_apply %token as $() end_borrow %1 : $Builtin.NativeObject destroy_value %0 : $Builtin.NativeObject %r = tuple () @@ -116,7 +116,7 @@ bb0(%0 : @owned $Builtin.NativeObject): %1 = begin_borrow %0 : $Builtin.NativeObject %coro = function_ref @coroutine_callee : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> () %token = begin_apply %coro(%1) : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> () - end_apply %token + end_apply %token as $() br bb1 bb1: @@ -167,7 +167,7 @@ bb1: br bb3 bb2: - end_apply %token + end_apply %token as $() end_borrow %1 : $Builtin.NativeObject destroy_value %0 : $Builtin.NativeObject br bb3 diff --git a/test/SIL/Parser/coroutines.sil b/test/SIL/Parser/coroutines.sil index 4095e5e62b10b..08cd7003dcf0d 100644 --- a/test/SIL/Parser/coroutines.sil +++ b/test/SIL/Parser/coroutines.sil @@ -57,7 +57,7 @@ bb0(%0 : $Int, %1 : $Float): %coro = function_ref @yield : $@convention(thin) @yield_once (Int, Float) -> (@yields Int, @yields Float) (%int, %float, %token) = begin_apply %coro(%0, %1) : $@convention(thin) @yield_once (Int, Float) -> (@yields Int, @yields Float) - end_apply %token + end_apply %token as $() %r = tuple () return %r : $() } diff --git a/test/SIL/Parser/overloaded_member.sil b/test/SIL/Parser/overloaded_member.sil index 295b18afd9366..cfec97ad8078f 100644 --- a/test/SIL/Parser/overloaded_member.sil +++ b/test/SIL/Parser/overloaded_member.sil @@ -55,7 +55,7 @@ sil [ossa] @test_overloaded_subscript : $@convention(thin) (@guaranteed B, B.Ind bb0(%0 : @guaranteed $B, %1 : $B.Index): %reader = class_method %0 : $B, #B.subscript!read : (B) -> (B.Index) -> (), $@convention(method) @yield_once (B.Index, @guaranteed B) -> @yields @guaranteed B.Element (%element, %token) = begin_apply %reader(%1, %0) : $@convention(method) @yield_once (B.Index, @guaranteed B) -> @yields @guaranteed B.Element - end_apply %token + end_apply %token as $() %result = tuple () return %result : $() diff --git a/test/SIL/concurrentclosure_capture_verify_canonical_addressonly.sil b/test/SIL/concurrentclosure_capture_verify_canonical_addressonly.sil index e1a61d9c01ddf..d1233950cbeae 100644 --- a/test/SIL/concurrentclosure_capture_verify_canonical_addressonly.sil +++ b/test/SIL/concurrentclosure_capture_verify_canonical_addressonly.sil @@ -79,7 +79,7 @@ bb0(%0 : $*T): // function_ref inoutUserOptKlass(_:) %28 = function_ref @$s37concurrentfunction_capturediagnostics17inoutUserOptKlassyyAA0F0CSgzF : $@convention(thin) (@inout FakeOptional) -> () // user: %29 %29 = apply %28(%26) : $@convention(thin) (@inout FakeOptional) -> () - end_apply %27 // id: %30 + end_apply %27 as $() // id: %30 end_access %24 : $*T // id: %31 destroy_value %8 : $<τ_0_0 where τ_0_0 : MyProt> { var τ_0_0 } // id: %32 destroy_addr %2 : $*F // id: %33 diff --git a/test/SIL/concurrentclosure_capture_verify_raw.sil b/test/SIL/concurrentclosure_capture_verify_raw.sil index a32f2e1730957..7b5421f7309a7 100644 --- a/test/SIL/concurrentclosure_capture_verify_raw.sil +++ b/test/SIL/concurrentclosure_capture_verify_raw.sil @@ -112,7 +112,7 @@ bb0(%0 : $*T): // function_ref inoutUserOptKlass(_:) %28 = function_ref @$s37concurrentfunction_capturediagnostics17inoutUserOptKlassyyAA0F0CSgzF : $@convention(thin) (@inout FakeOptional) -> () // user: %29 %29 = apply %28(%26) : $@convention(thin) (@inout FakeOptional) -> () - end_apply %27 // id: %30 + end_apply %27 as $() // id: %30 end_access %24 : $*T // id: %31 destroy_value %8 : $<τ_0_0 where τ_0_0 : MyProt> { var τ_0_0 } // id: %32 destroy_addr %2 : $*F // id: %33 diff --git a/test/SIL/memory_lifetime.sil b/test/SIL/memory_lifetime.sil index e813389685406..7a12bdc16b0f4 100644 --- a/test/SIL/memory_lifetime.sil +++ b/test/SIL/memory_lifetime.sil @@ -694,7 +694,7 @@ sil [ossa] @begin_apply_in_destroy : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @in U destroy_addr %instance : $*Inner - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() } @@ -703,7 +703,7 @@ sil [ossa] @begin_apply_in_constant_destroy : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @in_constant U destroy_addr %instance : $*Inner - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() } @@ -711,7 +711,7 @@ entry: sil [ossa] @begin_apply_in_guaranteed_no_destroy : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @in_guaranteed U - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() } diff --git a/test/SIL/memory_lifetime_failures.sil b/test/SIL/memory_lifetime_failures.sil index 31a4412948de4..83e507c68388b 100644 --- a/test/SIL/memory_lifetime_failures.sil +++ b/test/SIL/memory_lifetime_failures.sil @@ -663,7 +663,7 @@ bb0(%0 : $*Optional): sil [ossa] @begin_apply_in_no_destroy : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @in U - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() } @@ -672,7 +672,7 @@ entry: sil [ossa] @begin_apply_in_use_after_end_apply : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @in U - end_apply %token + end_apply %token as $() apply undef(%instance) : $@convention(thin) (@in U) -> () %retval = tuple () return %retval : $() @@ -682,7 +682,7 @@ entry: sil [ossa] @begin_apply_in_constant_no_destroy : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @in_constant U - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() } @@ -691,7 +691,7 @@ entry: sil [ossa] @begin_apply_in_constant_use_after_end_apply : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @in_constant U - end_apply %token + end_apply %token as $() apply undef(%instance) : $@convention(thin) (@in_constant U) -> () %retval = tuple () return %retval : $() @@ -702,7 +702,7 @@ sil [ossa] @begin_apply_in_guaranteed_destroy : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @in_guaranteed U destroy_addr %instance : $*Inner - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() } @@ -711,7 +711,7 @@ entry: sil [ossa] @begin_apply_in_guaranteed_use_after_end_apply : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @in_guaranteed U - end_apply %token + end_apply %token as $() apply undef(%instance) : $@convention(thin) (@in_guaranteed U) -> () %retval = tuple () return %retval : $() @@ -722,7 +722,7 @@ sil [ossa] @begin_apply_inout_destroy : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @inout U destroy_addr %instance : $*Inner - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() } @@ -731,7 +731,7 @@ entry: sil [ossa] @begin_apply_inout_use_after_end_apply : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @inout U - end_apply %token + end_apply %token as $() apply undef(%instance) : $@convention(thin) (@inout U) -> () %retval = tuple () return %retval : $() @@ -742,7 +742,7 @@ sil [ossa] @begin_apply_inout_aliasable_destroy : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @inout_aliasable U destroy_addr %instance : $*Inner - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() } @@ -751,7 +751,7 @@ entry: sil [ossa] @begin_apply_inout_aliasable_use_after_end_apply : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @inout_aliasable U - end_apply %token + end_apply %token as $() apply undef(%instance) : $@convention(thin) (@inout_aliasable U) -> () %retval = tuple () return %retval : $() @@ -761,7 +761,7 @@ entry: sil [ossa] @begin_apply_inout_no_destroy : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @inout U - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() } @@ -770,7 +770,7 @@ entry: sil [ossa] @begin_apply_inout_aliasable_no_destroy : $@convention(thin) () -> () { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @inout_aliasable U - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() } diff --git a/test/SILOptimizer/access_dom_call.sil b/test/SILOptimizer/access_dom_call.sil index f7de484fb45eb..cf163b676995a 100644 --- a/test/SILOptimizer/access_dom_call.sil +++ b/test/SILOptimizer/access_dom_call.sil @@ -138,7 +138,7 @@ bb0(%0 : $C): (%3, %4) = begin_apply %m(%0) : $@yield_once @convention(method) (@guaranteed C) -> @yields @inout Int64 %a2 = begin_access [read] [dynamic] [no_nested_conflict] %ra : $*Int64 end_access %a2 : $*Int64 - end_apply %4 + end_apply %4 as $() %v = tuple () return %v : $() } @@ -155,7 +155,7 @@ bb0(%0 : $C): %ra = ref_element_addr %0 : $C, #C.field // user: %3 %a1 = begin_access [read] [dynamic] %ra : $*Int64 end_access %a1 : $*Int64 - end_apply %4 + end_apply %4 as $() %a2 = begin_access [read] [dynamic] [no_nested_conflict] %ra : $*Int64 end_access %a2 : $*Int64 %v = tuple () @@ -174,7 +174,7 @@ bb0(%0 : $C): %ra = ref_element_addr %0 : $C, #C.field // user: %3 %a1 = begin_access [read] [dynamic] %ra : $*Int64 end_access %a1 : $*Int64 - end_apply %4 + end_apply %4 as $() %a2 = begin_access [modify] [dynamic] [no_nested_conflict] %ra : $*Int64 end_access %a2 : $*Int64 %v = tuple () @@ -203,7 +203,7 @@ bb3: %ra = ref_element_addr %0 : $C, #C.field // user: %3 %a1 = begin_access [modify] [dynamic] [no_nested_conflict] %ra : $*Int64 end_access %a1 : $*Int64 - end_apply %4 + end_apply %4 as $() %cond = integer_literal $Builtin.Int1, 1 cond_br %cond, bb2, bb4 diff --git a/test/SILOptimizer/accessutils.sil b/test/SILOptimizer/accessutils.sil index 656a37a90181d..e259f0ad488a3 100644 --- a/test/SILOptimizer/accessutils.sil +++ b/test/SILOptimizer/accessutils.sil @@ -362,7 +362,7 @@ bb0: (%1, %2, %3) = begin_apply %0() : $@yield_once @convention(thin) () -> (@yields @in_guaranteed String, @yields @in_guaranteed Int64) %4 = load %1 : $*String %5 = load %2 : $*Int64 - end_apply %3 + end_apply %3 as $() %7 = tuple () return %7 : $() } @@ -413,9 +413,9 @@ bb0(%inoutArg : $*Int64, %aliasableArg1 : $*Int64, %aliasableArg2 : $*Int64, %3 %50 = function_ref @coro : $@yield_once @convention(thin) () -> @yields @inout Int64 (%yield1, %52) = begin_apply %50() : $@yield_once @convention(thin) () -> @yields @inout Int64 - end_apply %52 + end_apply %52 as $() (%yield2, %55) = begin_apply %50() : $@yield_once @convention(thin) () -> @yields @inout Int64 - end_apply %55 + end_apply %55 as $() %isDistinct = function_ref @_isDistinct : $@convention(thin) <τ_0_0, τ_0_1> (@inout τ_0_0, @inout τ_0_1) -> () %isNotDistinct = function_ref @_isNotDistinct : $@convention(thin) <τ_0_0, τ_0_1> (@inout τ_0_0, @inout τ_0_1) -> () diff --git a/test/SILOptimizer/addr_escape_info.sil b/test/SILOptimizer/addr_escape_info.sil index a40fdbbc36fde..edde9c9422224 100644 --- a/test/SILOptimizer/addr_escape_info.sil +++ b/test/SILOptimizer/addr_escape_info.sil @@ -293,7 +293,7 @@ bb0(%0 : $X): %6 = function_ref @inout_class_argument : $@convention(thin) (@inout X) -> () %7 = apply %6(%4) : $@convention(thin) (@inout X) -> () - end_apply %5 + end_apply %5 as $() dealloc_stack %1 : $*X %r = tuple () return %r : $() diff --git a/test/SILOptimizer/address_lowering.sil b/test/SILOptimizer/address_lowering.sil index e9cbb542edad7..264cf2d8e93b6 100644 --- a/test/SILOptimizer/address_lowering.sil +++ b/test/SILOptimizer/address_lowering.sil @@ -1585,7 +1585,7 @@ sil hidden [ossa] @testBeginApply1DeadYield : $@convention(thin) (@guarantee bb0(%0 : @guaranteed $TestGeneric): %2 = class_method %0 : $TestGeneric, #TestGeneric.borrowedGeneric!read : (TestGeneric) -> () -> (), $@yield_once @convention(method) <τ_0_0> (@guaranteed TestGeneric<τ_0_0>) -> @yields @in_guaranteed τ_0_0 (%3, %4) = begin_apply %2(%0) : $@yield_once @convention(method) <τ_0_0> (@guaranteed TestGeneric<τ_0_0>) -> @yields @in_guaranteed τ_0_0 - end_apply %4 + end_apply %4 as $() %10 = tuple () return %10 : $() } @@ -1596,7 +1596,7 @@ bb0(%0 : @guaranteed $TestGeneric): // CHECK: [[METH:%.*]] = class_method %0 : $TestGeneric, #TestGeneric.borrowedGeneric!read : (TestGeneric) -> () -> (), $@yield_once @convention(method) <τ_0_0> (@guaranteed TestGeneric<τ_0_0>) -> @yields @in_guaranteed τ_0_0 // CHECK: ([[Y:%.*]], [[TOK:%.*]]) = begin_apply [[METH]](%0) : $@yield_once @convention(method) <τ_0_0> (@guaranteed TestGeneric<τ_0_0>) -> @yields @in_guaranteed τ_0_0 // CHECK: copy_addr [[Y]] to [init] [[STK]] : $*Klass -// CHECK: end_apply [[TOK]] +// CHECK: end_apply [[TOK]] as $() // CHECK: destroy_addr [[STK]] : $*Klass // CHECK-LABEL: } sil hidden [ossa] @testBeginApply2LoadableYieldWithIndirectConv : $@convention(thin) (@guaranteed TestGeneric) -> () { @@ -1604,7 +1604,7 @@ bb0(%0 : @guaranteed $TestGeneric): %2 = class_method %0 : $TestGeneric, #TestGeneric.borrowedGeneric!read : (TestGeneric) -> () -> (), $@yield_once @convention(method) <τ_0_0> (@guaranteed TestGeneric<τ_0_0>) -> @yields @in_guaranteed τ_0_0 (%3, %4) = begin_apply %2(%0) : $@yield_once @convention(method) <τ_0_0> (@guaranteed TestGeneric<τ_0_0>) -> @yields @in_guaranteed τ_0_0 %5 = copy_value %3 : $Klass - end_apply %4 + end_apply %4 as $() destroy_value %5 : $Klass %10 = tuple () return %10 : $() @@ -1616,7 +1616,7 @@ bb0(%0 : @guaranteed $TestGeneric): // CHECK: [[M:%.*]] = class_method %0 : $TestGeneric, #TestGeneric.borrowedGeneric!read : (TestGeneric) -> () -> (), $@yield_once @convention(method) <τ_0_0> (@guaranteed TestGeneric<τ_0_0>) -> @yields @in_guaranteed τ_0_0 // CHECK: ([[Y:%.*]], [[TOK:%.*]]) = begin_apply %2(%0) : $@yield_once @convention(method) <τ_0_0> (@guaranteed TestGeneric<τ_0_0>) -> @yields @in_guaranteed τ_0_0 // CHECK: copy_addr [[Y]] to [init] [[STK]] : $*T -// CHECK: end_apply [[TOK]] +// CHECK: end_apply [[TOK]] as $() // CHECK: destroy_addr [[STK]] : $*T // CHECK-LABEL: } // end sil function 'testBeginApply3OpaqueYield' sil hidden [ossa] @testBeginApply3OpaqueYield : $@convention(thin) (@guaranteed TestGeneric) -> () { @@ -1624,7 +1624,7 @@ bb0(%0 : @guaranteed $TestGeneric): %2 = class_method %0 : $TestGeneric, #TestGeneric.borrowedGeneric!read : (TestGeneric) -> () -> (), $@yield_once @convention(method) <τ_0_0> (@guaranteed TestGeneric<τ_0_0>) -> @yields @in_guaranteed τ_0_0 (%3, %4) = begin_apply %2(%0) : $@yield_once @convention(method) <τ_0_0> (@guaranteed TestGeneric<τ_0_0>) -> @yields @in_guaranteed τ_0_0 %5 = copy_value %3 : $T - end_apply %4 + end_apply %4 as $() destroy_value %5 : $T %10 = tuple () return %10 : $() @@ -1639,7 +1639,7 @@ sil [ossa] @testBeginApply4YieldLoadableTrivial : $@convention(thin) () -> I { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @in_guaranteed U %extract = struct_extract %instance : $LoadableTrivialExtractable, #LoadableTrivialExtractable.i - end_apply %token + end_apply %token as $() return %extract : $I } @@ -1655,7 +1655,7 @@ entry: (%instance_1, %instance_2, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> (@yields @in_guaranteed U, @yields @in_guaranteed U) %i_1 = struct_extract %instance_1 : $LoadableTrivialExtractable, #LoadableTrivialExtractable.i %i_2 = struct_extract %instance_2 : $LoadableTrivialExtractable, #LoadableTrivialExtractable.i - end_apply %token + end_apply %token as $() %tuple = tuple (%i_1 : $I, %i_2 : $I) return %tuple : $(I, I) } @@ -1673,7 +1673,7 @@ entry: (%instance_1, %instance_2, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> (@yields @in_guaranteed U, @yields @in_guaranteed T) %copy = copy_value %instance_2 : $T %i = struct_extract %instance_1 : $LoadableTrivialExtractable, #LoadableTrivialExtractable.i - end_apply %token + end_apply %token as $() %tuple = tuple (%i : $I, %copy : $T) return %tuple : $(I, T) } @@ -1688,7 +1688,7 @@ entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @in_guaranteed U %extract = struct_extract %instance : $LoadableNontrivial, #LoadableNontrivial.x %retval = copy_value %extract : $Klass - end_apply %token + end_apply %token as $() return %retval : $Klass } @@ -1708,7 +1708,7 @@ entry: %extract_2 = struct_extract %instance_2 : $LoadableNontrivial, #LoadableNontrivial.x %copy_1 = copy_value %extract_1 : $Klass %copy_2 = copy_value %extract_2 : $Klass - end_apply %token + end_apply %token as $() %retval = tuple (%copy_1 : $Klass, %copy_2 : $Klass) return %retval : $(Klass, Klass) } @@ -1727,7 +1727,7 @@ entry: %extract_1 = struct_extract %instance_1 : $LoadableNontrivial, #LoadableNontrivial.x %copy_1 = copy_value %extract_1 : $Klass %copy_2 = copy_value %instance_2 : $T - end_apply %token + end_apply %token as $() %retval = tuple (%copy_1 : $Klass, %copy_2 : $T) return %retval : $(Klass, T) } @@ -1742,7 +1742,7 @@ entry: sil [ossa] @testBeginApplyAYieldLoadableNontrivialOwned : $@convention(thin) () -> @owned Klass { entry: (%instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> @yields @in U - end_apply %token + end_apply %token as $() %borrow = begin_borrow %instance : $LoadableNontrivial %extract = struct_extract %borrow : $LoadableNontrivial, #LoadableNontrivial.x %retval = copy_value %extract : $Klass @@ -1761,7 +1761,7 @@ entry: sil [ossa] @testBeginApplyBYield2LoadableNontrivialOwned : $@convention(thin) () -> @owned (Klass, Klass) { entry: (%instance_1, %instance_2, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> (@yields @in U, @yields @in U) - end_apply %token + end_apply %token as $() %borrow_1 = begin_borrow %instance_1 : $LoadableNontrivial %extract_1 = struct_extract %borrow_1 : $LoadableNontrivial, #LoadableNontrivial.x %copy_1 = copy_value %extract_1 : $Klass @@ -1791,7 +1791,7 @@ entry: %copy_1 = copy_value %extract_1 : $Klass end_borrow %borrow_1 : $LoadableNontrivial destroy_value %instance_1 : $LoadableNontrivial - end_apply %token + end_apply %token as $() %retval = tuple (%copy_1 : $Klass, %instance_2 : $T) return %retval : $(Klass, T) } @@ -1802,7 +1802,7 @@ entry: sil [ossa] @testBeginApplyDYieldOpaqueInout : $@yield_once @convention(thin) () -> () { entry: (%addr, %token) = begin_apply undef() : $@yield_once @convention(method) () -> @yields @inout U - end_apply %token + end_apply %token as $() %8 = tuple () return %8 : $() } @@ -1817,7 +1817,7 @@ entry: yield %addr : $*T, resume bb1, unwind bb2 bb1: - end_apply %token + end_apply %token as $() %8 = tuple () return %8 : $() @@ -1831,14 +1831,14 @@ bb2: // CHECK: ([[OWNED_INSTANCE:%[^,]+]], [[ADDR:%[^,]+]], [[TOKEN:%[^,]+]]) = begin_apply // CHECK: destroy_value [[OWNED_INSTANCE]] // CHECK: copy_addr [[ADDR]] to [init] [[OUT_ADDR]] -// CHECK: end_apply [[TOKEN]] +// CHECK: end_apply [[TOKEN]] as $() // CHECK-LABEL: } // end sil function 'testBeginApplyFYieldDirectOwnedAndAddressOnlyGuaranteed' sil [ossa] @testBeginApplyFYieldDirectOwnedAndAddressOnlyGuaranteed : $@convention(thin) () -> @out T { entry: (%klass, %instance, %token) = begin_apply undef() : $@yield_once @convention(thin) () -> (@yields @owned Klass, @yields @in_guaranteed T) destroy_value %klass : $Klass %retval = copy_value %instance : $T - end_apply %token + end_apply %token as $() return %retval : $T } @@ -1848,7 +1848,7 @@ entry: // CHECK: [[COPY_STORAGE:%[^,]+]] = alloc_stack $T // CHECK: ([[YIELD_STORAGE:%[^,]+]], [[TOKEN:%[^,]+]]) = begin_apply // CHECK: copy_addr [[YIELD_STORAGE]] to [init] [[COPY_STORAGE]] -// CHECK: end_apply [[TOKEN]] +// CHECK: end_apply [[TOKEN]] as $() // CHECK: apply undef([[COPY_STORAGE]]) // CHECK: dealloc_stack [[COPY_STORAGE]] // CHECK-LABEL: } // end sil function 'testBeginApplyGCopyConsumeInGuaranteedValue' @@ -1856,7 +1856,7 @@ sil [ossa] @testBeginApplyGCopyConsumeInGuaranteedValue : $@convention(thin) entry: (%yield, %token) = begin_apply undef() : $@yield_once @convention(thin) <τ_0_0> () -> @yields @in_guaranteed τ_0_0 %copy = copy_value %yield : $T - end_apply %token + end_apply %token as $() apply undef(%copy) : $@convention(thin) (@in T) -> () %retval = tuple () return %retval : $() @@ -1868,7 +1868,7 @@ entry: // CHECK: [[COPY_STORAGE:%[^,]+]] = alloc_stack $T // CHECK: ([[YIELD_STORAGE:%[^,]+]], [[TOKEN:%[^,]+]]) = begin_apply // CHECK: copy_addr [[YIELD_STORAGE]] to [init] [[COPY_STORAGE]] -// CHECK: end_apply [[TOKEN]] +// CHECK: end_apply [[TOKEN]] as $() // CHECK: [[PTR:%[^,]+]] = apply undef // CHECK: [[ADDR:%[^,]+]] = pointer_to_address [[PTR:%[^,]+]] // CHECK: copy_addr [take] [[COPY_STORAGE]] to [[ADDR]] @@ -1877,7 +1877,7 @@ sil [ossa] @testBeginApplyH1CopyStoreInGuaranteedValue : $@convention(thin) entry: (%yield, %token) = begin_apply undef() : $@yield_once @convention(thin) <τ_0_0> () -> @yields @in_guaranteed τ_0_0 %copy = copy_value %yield : $T - end_apply %token + end_apply %token as $() %ptr = apply undef() : $@convention(method) <τ_0_0> () -> Builtin.RawPointer %addr = pointer_to_address %ptr : $Builtin.RawPointer to [strict] $*T store %copy to [assign] %addr : $*T @@ -1892,7 +1892,7 @@ entry: // CHECK: [[COPY_STORAGE:%[^,]+]] = alloc_stack $T // CHECK: ([[YIELD_STORAGE:%[^,]+]], [[TOKEN:%[^,]+]]) = begin_apply undef // CHECK: copy_addr [[YIELD_STORAGE]] to [init] [[COPY_STORAGE]] : $*T -// CHECK: end_apply [[TOKEN]] +// CHECK: end_apply [[TOKEN]] as $() // CHECK: [[PTR:%[^,]+]] = apply undef // CHECK: [[ADDR:%[^,]+]] = pointer_to_address [[PTR]] // CHECK: copy_addr [take] [[COPY_STORAGE]] to [[ADDR]] @@ -1904,7 +1904,7 @@ entry: apply undef(%borrow) : $@convention(thin) <τ> (@in_guaranteed τ) -> () %copy = copy_value %borrow : $T end_borrow %borrow : $T - end_apply %token + end_apply %token as $() %ptr = apply undef() : $@convention(method) <τ_0_0> () -> Builtin.RawPointer %addr = pointer_to_address %ptr : $Builtin.RawPointer to [strict] $*T store %copy to [assign] %addr : $*T @@ -1917,13 +1917,13 @@ entry: // [[IN_STORAGE:%[^,]+]] = alloc_stack $T // ([[YIELD_STORAGE:%[^,]+]], [[TOKEN:%[^,]+]]) = begin_apply undef() // copy_addr [take] [[YIELD_STORAGE]] to [init] [[IN_STORAGE]] -// end_apply [[TOKEN]] +// end_apply [[TOKEN]] as $() // apply undef([[IN_STORAGE]]) // } // end sil function 'testBeginApplyIConsumeInValue' sil [ossa] @testBeginApplyIConsumeInValue : $@convention(thin) () -> () { entry: (%yield, %token) = begin_apply undef() : $@yield_once @convention(thin) <τ_0_0> () -> @yields @in τ_0_0 - end_apply %token + end_apply %token as $() apply undef(%yield) : $@convention(thin) (@in T) -> () %retval = tuple () return %retval : $() @@ -1933,7 +1933,7 @@ entry: // [[IN_STORAGE:%[^,]+]] = alloc_stack $T // ([[YIELD_STORAGE:%[^,]+]], [[TOKEN:%[^,]+]]) = begin_apply // copy_addr [take] [[YIELD_STORAGE]] to [init] [[IN_STORAGE]] -// end_apply [[TOKEN]] +// end_apply [[TOKEN]] as $() // [[PTR:%[^,]+]] = apply // [[ADDR:%[^,]+]] = pointer_to_address [[PTR:%[^,]+]] // copy_addr [take] [[IN_STORAGE]] to [[ADDR]] @@ -1941,7 +1941,7 @@ entry: sil [ossa] @testBeginApplyJStoreInValue : $@convention(thin) () -> () { entry: (%yield, %token) = begin_apply undef() : $@yield_once @convention(thin) <τ_0_0> () -> @yields @in τ_0_0 - end_apply %token + end_apply %token as $() %ptr = apply undef() : $@convention(method) <τ_0_0> () -> Builtin.RawPointer %addr = pointer_to_address %ptr : $Builtin.RawPointer to [strict] $*T store %yield to [assign] %addr : $*T @@ -1954,13 +1954,13 @@ entry: // [[IN_CONSTANT_STORAGE:%[^,]+]] = alloc_stack $T // ([[YIELD_STORAGE:%[^,]+]], [[TOKEN:%[^,]+]]) = begin_apply undef() // copy_addr [take] [[YIELD_STORAGE]] to [init] [[IN_CONSTANT_STORAGE]] -// end_apply [[TOKEN]] +// end_apply [[TOKEN]] as $() // apply undef([[IN_CONSTANT_STORAGE]]) // } // end sil function 'testBeginApplyKConsumeInConstantValue' sil [ossa] @testBeginApplyKConsumeInConstantValue : $@convention(thin) () -> () { entry: (%yield, %token) = begin_apply undef() : $@yield_once @convention(thin) <τ_0_0> () -> @yields @in_constant τ_0_0 - end_apply %token + end_apply %token as $() apply undef(%yield) : $@convention(thin) (@in_constant T) -> () %retval = tuple () return %retval : $() @@ -1970,7 +1970,7 @@ entry: // [[IN_CONSTANT_STORAGE:%[^,]+]] = alloc_stack $T // ([[YIELD_STORAGE:%[^,]+]], [[TOKEN:%[^,]+]]) = begin_apply // copy_addr [take] [[YIELD_STORAGE]] to [init] [[IN_CONSTANT_STORAGE]] -// end_apply [[TOKEN]] +// end_apply [[TOKEN]] as $() // [[PTR:%[^,]+]] = apply // [[ADDR:%[^,]+]] = pointer_to_address [[PTR:%[^,]+]] // copy_addr [take] [[IN_CONSTANT_STORAGE]] to [[ADDR]] @@ -1978,7 +1978,7 @@ entry: sil [ossa] @testBeginApplyLStoreInConstantValue : $@convention(thin) () -> () { entry: (%yield, %token) = begin_apply undef() : $@yield_once @convention(thin) <τ_0_0> () -> @yields @in_constant τ_0_0 - end_apply %token + end_apply %token as $() %ptr = apply undef() : $@convention(method) <τ_0_0> () -> Builtin.RawPointer %addr = pointer_to_address %ptr : $Builtin.RawPointer to [strict] $*T store %yield to [assign] %addr : $*T @@ -3070,7 +3070,7 @@ entry: yield %instance : $AnyObject, resume resumebb, unwind unwindbb resumebb: - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() @@ -3311,7 +3311,7 @@ entry: yield (%instance_1 : $AnyObject, %instance_2 : $T), resume resumebb, unwind unwindbb resumebb: - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() @@ -3336,7 +3336,7 @@ bb0: yield %3 : $LoadableNontrivialGeneric, resume bb1, unwind bb2 bb1: - end_apply %4 + end_apply %4 as $() %7 = tuple () return %7 : $() diff --git a/test/SILOptimizer/allocboxtostack_localapply.sil b/test/SILOptimizer/allocboxtostack_localapply.sil index 48f697e630074..1f926d2fe216c 100644 --- a/test/SILOptimizer/allocboxtostack_localapply.sil +++ b/test/SILOptimizer/allocboxtostack_localapply.sil @@ -314,7 +314,7 @@ bb0: store %3 to %1 : $*Int64 %5 = function_ref @$testbeginapplybas : $@yield_once @convention(thin) (@guaranteed { var Int64 }) -> @yields () (%addr, %token) = begin_apply %5(%0) : $@yield_once @convention(thin) (@guaranteed { var Int64 }) -> @yields () - end_apply %token + end_apply %token as $() strong_release %0 : ${ var Int64 } %8 = tuple () return %8 : $() diff --git a/test/SILOptimizer/allocboxtostack_localapply_ossa.sil b/test/SILOptimizer/allocboxtostack_localapply_ossa.sil index 6cb40981e8d22..8f17660cae5a4 100644 --- a/test/SILOptimizer/allocboxtostack_localapply_ossa.sil +++ b/test/SILOptimizer/allocboxtostack_localapply_ossa.sil @@ -314,7 +314,7 @@ bb0: store %3 to [trivial] %1 : $*Int64 %5 = function_ref @$testbeginapplybas : $@yield_once @convention(thin) (@guaranteed { var Int64 }) -> @yields () (%addr, %token) = begin_apply %5(%0) : $@yield_once @convention(thin) (@guaranteed { var Int64 }) -> @yields () - end_apply %token + end_apply %token as $() destroy_value %0 : ${ var Int64 } %8 = tuple () return %8 : $() diff --git a/test/SILOptimizer/borrow_introducer_unit.sil b/test/SILOptimizer/borrow_introducer_unit.sil index bd73ac2942957..00fcd8c387fbc 100644 --- a/test/SILOptimizer/borrow_introducer_unit.sil +++ b/test/SILOptimizer/borrow_introducer_unit.sil @@ -332,7 +332,7 @@ bb0(%0 : $Builtin.Word): %bridge = ref_to_bridge_object %c : $C, %0 : $Builtin.Word cond_br undef, bb1, bb2 bb1: - end_apply %t + end_apply %t as $() %r = tuple () return %r : $() bb2: diff --git a/test/SILOptimizer/closure_specialize.sil b/test/SILOptimizer/closure_specialize.sil index f00b5cb5eb434..7f3c46aaf4461 100644 --- a/test/SILOptimizer/closure_specialize.sil +++ b/test/SILOptimizer/closure_specialize.sil @@ -907,7 +907,7 @@ bb0(%0 : $Int): cond_br undef, bb1, bb2 bb1: - end_apply %token + end_apply %token as $() br bb3 bb2: diff --git a/test/SILOptimizer/copy_propagation.sil b/test/SILOptimizer/copy_propagation.sil index 3927f84b1edfe..e210de9f320ce 100644 --- a/test/SILOptimizer/copy_propagation.sil +++ b/test/SILOptimizer/copy_propagation.sil @@ -275,7 +275,7 @@ bb0(%0 : $*Struct): (%6, %7) = begin_apply %5(%0, %4) : $@yield_once @convention(thin) <τ_0_0, τ_0_1> (@inout τ_0_0, @guaranteed WritableKeyPath<τ_0_0, τ_0_1>) -> @yields @inout τ_0_1 %8 = function_ref @modifyInt : $@convention(thin) (@inout Int) -> () %9 = apply %8(%6) : $@convention(thin) (@inout Int) -> () - end_apply %7 + end_apply %7 as $() destroy_value %4 : $WritableKeyPath destroy_value %2 : $WritableKeyPath %13 = tuple () diff --git a/test/SILOptimizer/debuginfo_canonicalizer.sil b/test/SILOptimizer/debuginfo_canonicalizer.sil index bd4f7bce5a2a6..44da294ad3fa3 100644 --- a/test/SILOptimizer/debuginfo_canonicalizer.sil +++ b/test/SILOptimizer/debuginfo_canonicalizer.sil @@ -58,7 +58,7 @@ bb0(%0 : $Klass): %f = function_ref @yieldOnceCoroutine : $@yield_once @convention(method) (@guaranteed Klass) -> @yields @inout Int64 (%3, %4) = begin_apply %f(%0) : $@yield_once @convention(method) (@guaranteed Klass) -> @yields @inout Int64 %9999 = tuple() - end_apply %4 + end_apply %4 as $() return %9999 : $() } @@ -86,7 +86,7 @@ bb0(%0 : $Klass): cond_br undef, bb1, bb2 bb1: - end_apply %token + end_apply %token as $() br bb3 bb2: @@ -124,7 +124,7 @@ bb0(%0 : $Klass): cond_br undef, bb1, bb2 bb1: - end_apply %token + end_apply %token as $() br bb3 bb2: diff --git a/test/SILOptimizer/deinit_barrier.sil b/test/SILOptimizer/deinit_barrier.sil index 74c328b5d896e..49fb7c7873ea2 100644 --- a/test/SILOptimizer/deinit_barrier.sil +++ b/test/SILOptimizer/deinit_barrier.sil @@ -106,7 +106,7 @@ sil [ossa] @test_hop_to_executor : $@convention(thin) () -> () { (%a, %token) = begin_apply %borrowA() : $@yield_once @convention(thin) () -> @yields @guaranteed A specify_test "is-deinit-barrier @instruction" hop_to_executor %a : $A - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() } diff --git a/test/SILOptimizer/exclusivity_static_diagnostics.sil b/test/SILOptimizer/exclusivity_static_diagnostics.sil index 197bcdfd0abf9..c9be10afe1044 100644 --- a/test/SILOptimizer/exclusivity_static_diagnostics.sil +++ b/test/SILOptimizer/exclusivity_static_diagnostics.sil @@ -1526,7 +1526,7 @@ bb0(%0 : $*Int, %1 : $*Dictionary): %mod = function_ref @$sSD_7defaultq_x_q_yXKtciM : $@yield_once @convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in_guaranteed τ_0_0, @noescape @callee_guaranteed () -> @out τ_0_1, @inout Dictionary<τ_0_0, τ_0_1>) -> @yields @inout τ_0_1 %access = begin_access [modify] [static] %0 : $*Int // expected-error {{overlapping accesses, but modification requires exclusive access; consider copying to a local variable}} (%yield, %token) = begin_apply %mod(%access, %cvt, %1) : $@yield_once @convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in_guaranteed τ_0_0, @noescape @callee_guaranteed () -> @out τ_0_1, @inout Dictionary<τ_0_0, τ_0_1>) -> @yields @inout τ_0_1 - end_apply %token + end_apply %token as $() end_access %access : $*Int destroy_value %cvt : $@noescape @callee_guaranteed () -> @out Int destroy_value %pa : $@callee_guaranteed () -> @out Int @@ -1579,7 +1579,7 @@ bb0(%0 : $*Dictionary, %1 : $Int, %2 : $*Int): %20 = function_ref @$sSD_7defaultq_x_q_yXKtciM : $@yield_once @convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in_guaranteed τ_0_0, @noescape @callee_guaranteed () -> @out τ_0_1, @inout Dictionary<τ_0_0, τ_0_1>) -> @yields @inout τ_0_1 (%21, %22) = begin_apply %20(%14, %18, %13) : $@yield_once @convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in_guaranteed τ_0_0, @noescape @callee_guaranteed () -> @out τ_0_1, @inout Dictionary<τ_0_0, τ_0_1>) -> @yields @inout τ_0_1 assign %1 to %21 : $*Int - end_apply %22 + end_apply %22 as $() destroy_value %18 : $@noescape @callee_guaranteed () -> @out Int end_access %13 : $*Dictionary dealloc_stack %14 : $*Int diff --git a/test/SILOptimizer/hoist_destroy_addr.sil b/test/SILOptimizer/hoist_destroy_addr.sil index 6603959ee92ca..340b9e824ea67 100644 --- a/test/SILOptimizer/hoist_destroy_addr.sil +++ b/test/SILOptimizer/hoist_destroy_addr.sil @@ -602,7 +602,7 @@ sil [ossa] @nohoist_over_end_apply_use : $@convention(thin) (@inout X, @owned X) entry(%addr : $*X, %instance : @owned $X): %coro = function_ref @coro : $@yield_once @convention(thin) (@inout X) -> @yields () (%empty, %continuation) = begin_apply %coro(%addr) : $@yield_once @convention(thin) (@inout X) -> @yields () - end_apply %continuation + end_apply %continuation as $() %retval = tuple () store %instance to [assign] %addr : $*X return %retval : $() diff --git a/test/SILOptimizer/inline_begin_apply.sil b/test/SILOptimizer/inline_begin_apply.sil index 5736a1cfda4e3..244c16923f726 100644 --- a/test/SILOptimizer/inline_begin_apply.sil +++ b/test/SILOptimizer/inline_begin_apply.sil @@ -113,7 +113,7 @@ entry(%flag : $Builtin.Int1): yes: %10 = integer_literal $Builtin.Int32, 10 apply %marker(%10) : $@convention(thin) (Builtin.Int32) -> () - end_apply %token + end_apply %token as $() %20 = integer_literal $Builtin.Int32, 20 apply %marker(%20) : $@convention(thin) (Builtin.Int32) -> () br cont @@ -147,7 +147,7 @@ entry(%flag : $Builtin.Int1): yes: %10 = integer_literal $Builtin.Int32, 10 apply %marker(%10) : $@convention(thin) (Builtin.Int32) -> () - end_apply %token + end_apply %token as $() %20 = integer_literal $Builtin.Int32, 20 apply %marker(%20) : $@convention(thin) (Builtin.Int32) -> () br cont @@ -223,7 +223,7 @@ entry(%flag : $Builtin.Int1, %flag2 : $Builtin.Int1): cond_br %flag2, yes, no yes: - end_apply %token + end_apply %token as $() br cont no: @@ -283,7 +283,7 @@ entry(%flag : $Builtin.Int1, %c: @owned $SomeClass): cond_br %flag, yes, no yes: - end_apply %token + end_apply %token as $() br cont no: @@ -359,7 +359,7 @@ entry(%flag : $Builtin.Int1): yes: %8 = integer_literal $Builtin.Int8, 8 store %8 to [trivial] %addr : $*Builtin.Int8 - end_apply %token + end_apply %token as $() br cont no: @@ -371,6 +371,79 @@ cont: return %ret : $() } +sil [transparent] [ossa] [ossa] @yield_inout_result : $@yield_once() -> (@yields @inout Builtin.Int8, Builtin.Int32) { +entry: + %addr = alloc_stack $Builtin.Int8 + %8 = integer_literal $Builtin.Int8, 8 + store %8 to [trivial] %addr : $*Builtin.Int8 + yield %addr : $*Builtin.Int8, resume resume, unwind unwind + +resume: + %use = function_ref @use : $@convention(thin) (@in Builtin.Int8) -> () + apply %use(%addr) : $@convention(thin) (@in Builtin.Int8) -> () + dealloc_stack %addr: $*Builtin.Int8 + %42 = integer_literal $Builtin.Int32, 42 + return %42 : $Builtin.Int32 + +unwind: + %3000 = integer_literal $Builtin.Int32, 3000 + %marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> () + apply %marker(%3000) : $@convention(thin) (Builtin.Int32) -> () + dealloc_stack %addr: $*Builtin.Int8 + unwind +} + +sil [ossa] @test_simple_call_yield_inout_result : $(Builtin.Int1) -> Builtin.Int32 { +entry(%flag : $Builtin.Int1): + %0 = function_ref @yield_inout_result : $@convention(thin) @yield_once() -> (@yields @inout Builtin.Int8, Builtin.Int32) + (%addr, %token) = begin_apply %0() : $@convention(thin) @yield_once() -> (@yields @inout Builtin.Int8, Builtin.Int32) + cond_br %flag, yes, no + +yes: + %8 = integer_literal $Builtin.Int8, 8 + store %8 to [trivial] %addr : $*Builtin.Int8 + %42 = end_apply %token as $Builtin.Int32 + br cont(%42 : $Builtin.Int32) + +no: + abort_apply %token + %0val = integer_literal $Builtin.Int32, 0 + br cont(%0val : $Builtin.Int32) + +cont(%ret : $Builtin.Int32): + return %ret : $Builtin.Int32 +} + +// CHECK-LABEL: sil [ossa] @test_simple_call_yield_inout_result : $@convention(thin) (Builtin.Int1) -> Builtin.Int32 { +// CHECK: bb0(%0 : $Builtin.Int1): +// CHECK-NEXT: %1 = alloc_stack $Builtin.Int8 +// CHECK-NEXT: %2 = integer_literal $Builtin.Int8, 8 +// CHECK-NEXT: store %2 to [trivial] %1 : $*Builtin.Int8 +// CHECK-NEXT: cond_br %0, bb1, bb2 + +// CHECK: bb1: +// CHECK-NEXT: [[T0:%.*]] = integer_literal $Builtin.Int8, 8 +// CHECK-NEXT: store [[T0]] to [trivial] %1 : $*Builtin.Int8 +// CHECK-NEXT: // function_ref +// CHECK-NEXT: [[USE:%.*]] = function_ref @use : $@convention(thin) (@in Builtin.Int8) -> () +// CHECK-NEXT: apply [[USE]](%1) : $@convention(thin) (@in Builtin.Int8) -> () +// CHECK-NEXT: dealloc_stack %1 : $*Builtin.Int8 +// CHECK-NEXT: [[NORMAL_RES:%.*]] = integer_literal $Builtin.Int32, 42 +// CHECK-NEXT: br bb3([[NORMAL_RES]] : $Builtin.Int32) + +// CHECK: bb2: +// CHECK-NEXT: [[T0:%.*]] = integer_literal $Builtin.Int32, 3000 +// CHECK-NEXT: // function_ref +// CHECK-NEXT: [[MARKER:%.*]] = function_ref @marker : $@convention(thin) (Builtin.Int32) -> () +// CHECK-NEXT: apply [[MARKER]]([[T0]]) : $@convention(thin) (Builtin.Int32) -> () +// CHECK-NEXT: dealloc_stack %1 : $*Builtin.Int8 +// CHECK-NEXT: [[UNWIND_RES:%.*]] = integer_literal $Builtin.Int32, 0 +// CHECK-NEXT: br bb3([[UNWIND_RES]] : $Builtin.Int32) + +// CHECK: bb3([[RES:%.*]] : $Builtin.Int32): +// CHECK-NEXT: return [[RES]] : $Builtin.Int32 +// CHECK: } + // We can't inline yet if there are multiple ends. // CHECK-LABEL: sil [ossa] @test_multi_end_yield_inout : $@convention(thin) (Builtin.Int1) -> () { // CHECK: [[T0:%.*]] = function_ref @yield_inout @@ -382,11 +455,11 @@ entry(%flag : $Builtin.Int1): cond_br %flag, yes, no yes: - end_apply %token + end_apply %token as $() br cont no: - end_apply %token + end_apply %token as $() br cont cont: @@ -447,7 +520,7 @@ entry: (%addr, %token) = begin_apply %0() : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int8) %use = function_ref @use : $@convention(thin) (@in Builtin.Int8) -> () apply %use(%addr) : $@convention(thin) (@in Builtin.Int8) -> () - end_apply %token + end_apply %token as $() %ret = tuple () return %ret : $() } @@ -503,7 +576,7 @@ bb0: %0 = function_ref @stack_overlap : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32) (%value, %token) = begin_apply %0() : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32) dealloc_stack %stack : $*Builtin.Int16 - end_apply %token + end_apply %token as $() %ret = tuple () return %ret : $() } @@ -534,7 +607,7 @@ bb0: %0 = function_ref @stack_overlap : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32) (%value, %token) = begin_apply %0() : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32) %stack = alloc_stack $Builtin.Int16 - end_apply %token + end_apply %token as $() dealloc_stack %stack : $*Builtin.Int16 %ret = tuple () return %ret : $() @@ -566,7 +639,7 @@ bb1: unreachable bb2: - end_apply %token + end_apply %token as $() dealloc_stack %stack : $*Builtin.Int16 %ret = tuple () return %ret : $() @@ -606,7 +679,7 @@ entry: bb_resume: end_borrow %borrow : $*SomeClass dealloc_stack %addr : $*SomeClass - end_apply %token + end_apply %token as $() %retval = tuple () return %retval : $() diff --git a/test/SILOptimizer/inline_lifetime.sil b/test/SILOptimizer/inline_lifetime.sil index 22782528434d1..f4a887f3888b3 100644 --- a/test/SILOptimizer/inline_lifetime.sil +++ b/test/SILOptimizer/inline_lifetime.sil @@ -666,7 +666,7 @@ sil [ossa] @caller_owned_callee_coro_owned : $@convention(thin) (@owned C) -> () bb0(%instance : @owned $C): %callee_coro_owned = function_ref @callee_coro_owned : $@yield_once @convention(thin) (@owned C) -> @yields @inout C (%addr, %continuation) = begin_apply %callee_coro_owned(%instance) : $@yield_once @convention(thin) (@owned C) -> @yields @inout C - end_apply %continuation + end_apply %continuation as $() %retval = tuple () return %retval : $() } @@ -693,7 +693,7 @@ sil [ossa] @caller_owned_callee_coro_guaranteed : $@convention(thin) (@owned C) bb0(%instance : @owned $C): %callee_coro_guaranteed = function_ref @callee_coro_guaranteed : $@yield_once @convention(thin) (@guaranteed C) -> @yields @inout C (%addr, %continuation) = begin_apply %callee_coro_guaranteed(%instance) : $@yield_once @convention(thin) (@guaranteed C) -> @yields @inout C - end_apply %continuation + end_apply %continuation as $() destroy_value %instance : $C %retval = tuple () return %retval : $() @@ -707,7 +707,7 @@ bb0(%instance : @guaranteed $C): %copy = copy_value %instance : $C %callee_coro_owned = function_ref @callee_coro_owned : $@yield_once @convention(thin) (@owned C) -> @yields @inout C (%addr, %continuation) = begin_apply %callee_coro_owned(%copy) : $@yield_once @convention(thin) (@owned C) -> @yields @inout C - end_apply %continuation + end_apply %continuation as $() %retval = tuple () return %retval : $() } @@ -733,7 +733,7 @@ sil [ossa] @caller_guaranteed_callee_coro_guaranteed : $@convention(thin) (@guar bb0(%instance : @guaranteed $C): %callee_coro_guaranteed = function_ref @callee_coro_guaranteed : $@yield_once @convention(thin) (@guaranteed C) -> @yields @inout C (%addr, %continuation) = begin_apply %callee_coro_guaranteed(%instance) : $@yield_once @convention(thin) (@guaranteed C) -> @yields @inout C - end_apply %continuation + end_apply %continuation as $() %retval = tuple () return %retval : $() } @@ -754,7 +754,7 @@ sil hidden [ossa] @caller_trivial_callee_coro_trivial : $@convention(thin) (S) - bb0(%instance : $S): %callee_coro_trivial = function_ref @callee_coro_trivial : $@yield_once @convention(thin) (S) -> @yields @inout S (%addr, %continuation) = begin_apply %callee_coro_trivial(%instance) : $@yield_once @convention(thin) (S) -> @yields @inout S - end_apply %continuation + end_apply %continuation as $() %retval = tuple () return %retval : $() } @@ -771,7 +771,7 @@ sil hidden [ossa] @caller_in_callee_coro_in : $@convention(thin) (@in S) -> () { bb0(%instance : $*S): %callee_coro_in = function_ref @callee_coro_in : $@yield_once @convention(thin) (@in S) -> @yields @inout S (%addr, %continuation) = begin_apply %callee_coro_in(%instance) : $@yield_once @convention(thin) (@in S) -> @yields @inout S - end_apply %continuation + end_apply %continuation as $() %retval = tuple () return %retval : $() } @@ -783,7 +783,7 @@ sil hidden [ossa] @caller_inguaranteed_callee_coro_inguaranteed : $@convention(t bb0(%instance : $*T): %callee_coro_inguaranteed = function_ref @callee_coro_inguaranteed : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @inout T (%addr_out, %continuation) = begin_apply %callee_coro_inguaranteed(%instance) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @inout T - end_apply %continuation + end_apply %continuation as $() %retval = tuple () return %retval : $() } diff --git a/test/SILOptimizer/lexical_destroy_hoisting.sil b/test/SILOptimizer/lexical_destroy_hoisting.sil index a6481479d48a2..a1f89f242269a 100644 --- a/test/SILOptimizer/lexical_destroy_hoisting.sil +++ b/test/SILOptimizer/lexical_destroy_hoisting.sil @@ -458,7 +458,7 @@ entry(%instance : @owned $C, %input : $S): %modify_s = function_ref @modify_s : $@yield_once @convention(thin) () -> @yields @inout S (%addr, %continuation) = begin_apply %modify_s() : $@yield_once @convention(thin) () -> @yields @inout S store %input to [trivial] %addr : $*S - end_apply %continuation + end_apply %continuation as $() destroy_value %instance : $C %retval = tuple () return %retval : $() diff --git a/test/SILOptimizer/lifetime_dependence_util.sil b/test/SILOptimizer/lifetime_dependence_util.sil index ef78a8d1c7cd5..21fedb1037957 100644 --- a/test/SILOptimizer/lifetime_dependence_util.sil +++ b/test/SILOptimizer/lifetime_dependence_util.sil @@ -111,7 +111,7 @@ entry(%0 : @owned $C, %1 : @owned $D, %2 : @guaranteed $D, %3 : $*D, %4 : $*D): // CHECK-NEXT: Yield: (**%{{.*}}**, %{{.*}}) = begin_apply %{{.*}}(%{{.*}}) : $@yield_once @convention(method) (@guaranteed D) -> @yields @guaranteed C // CHECK-NEXT: Dependent: %{{.*}} = mark_dependence [nonescaping] %{{.*}} : $C on %{{.*}} : $C // CHECK-NEXT: begin: (%{{.*}}, %{{.*}}) = begin_apply %{{.*}}(%{{.*}}) : $@yield_once @convention(method) (@guaranteed D) -> @yields @guaranteed C -// CHECK-NEXT: ends: end_apply %{{.*}} +// CHECK-NEXT: ends: %{{.*}} = end_apply %{{.*}} as $() // CHECK: dependence_scope: lifetime_dependence_scope with: %yield_mark %zero = integer_literal $Builtin.Int1, 0 @@ -161,7 +161,7 @@ entry(%0 : @owned $C, %1 : @owned $D, %2 : @guaranteed $D, %3 : $*D, %4 : $*D): destroy_value %inout_arg_mark : $C end_access %access : $*C - end_apply %token + end_apply %token as $() end_borrow %borrow : $D destroy_value %move : $D %99 = tuple() @@ -242,7 +242,7 @@ bb0(%0 : @guaranteed $NE): // CHECK-LABEL: dependence_coroutine: lifetime_dependence_use with: %0 // CHECK: LifetimeDependence uses of: %0 = argument of bb0 : $NE -// CHECK-NEXT: Leaf use: operand #0 of end_apply %{{.*}} +// CHECK-NEXT: Leaf use: operand #0 of %{{.*}} = end_apply %{{.*}} as $() // CHECK-NEXT: dependence_coroutine: lifetime_dependence_use with: %0 sil [ossa] @dependence_coroutine : $@convention(thin) (@guaranteed NE) -> () { bb0(%0 : @guaranteed $NE): @@ -250,7 +250,7 @@ bb0(%0 : @guaranteed $NE): %coroutine = function_ref @coroutine : $@yield_once @convention(method) (@guaranteed NE) -> @yields @guaranteed NE (%yield, %token) = begin_apply %coroutine(%0) : $@yield_once @convention(method) (@guaranteed NE) -> @yields @guaranteed NE %copy = copy_value %yield : $NE - end_apply %token + end_apply %token as $() destroy_value %copy : $NE %99 = tuple() return %99 : $() diff --git a/test/SILOptimizer/liveness_unit.sil b/test/SILOptimizer/liveness_unit.sil index 543173287c19c..3baa4c7bda6dc 100644 --- a/test/SILOptimizer/liveness_unit.sil +++ b/test/SILOptimizer/liveness_unit.sil @@ -136,13 +136,13 @@ bb0(%0 : @owned $D): // CHECK-LABEL: testGuaranteedResult: ssa_liveness // CHECK: SSA lifetime analysis: %0 = argument of bb0 : $D // CHECK: bb0: LiveWithin -// CHECK: last user: end_apply +// CHECK: last user: %{{.*}} = end_apply sil [ossa] @testGuaranteedResult : $@convention(thin) (@guaranteed D) -> () { bb0(%0 : @guaranteed $D): specify_test "ssa_liveness @argument[0]" %2 = class_method %0 : $D, #D.borrowed!read : (D) -> () -> (), $@yield_once @convention(method) (@guaranteed D) -> @yields @guaranteed C (%3, %4) = begin_apply %2(%0) : $@yield_once @convention(method) (@guaranteed D) -> @yields @guaranteed C - end_apply %4 + end_apply %4 as $() %99 = tuple() return %99 : $() } diff --git a/test/SILOptimizer/mandatory_combiner_opt.sil b/test/SILOptimizer/mandatory_combiner_opt.sil index c07c76858cdb1..cfe2b4d630f7a 100644 --- a/test/SILOptimizer/mandatory_combiner_opt.sil +++ b/test/SILOptimizer/mandatory_combiner_opt.sil @@ -129,7 +129,7 @@ bb0(%0 : @owned $C, %1 : $Builtin.Int64): %15 = class_method %14 : $C, #C.float!modify : (C) -> () -> (), $@yield_once @convention(method) (@guaranteed C) -> @yields @inout Builtin.Int64 (%16, %17) = begin_apply %15(%14) : $@yield_once @convention(method) (@guaranteed C) -> @yields @inout Builtin.Int64 store %1 to [trivial] %16 : $*Builtin.Int64 - end_apply %17 + end_apply %17 as $() end_borrow %14 : $C destroy_value %0 : $C %23 = tuple () diff --git a/test/SILOptimizer/mandatory_inlining_ownership.sil b/test/SILOptimizer/mandatory_inlining_ownership.sil index abe90a120aae4..6d0385017462f 100644 --- a/test/SILOptimizer/mandatory_inlining_ownership.sil +++ b/test/SILOptimizer/mandatory_inlining_ownership.sil @@ -501,7 +501,7 @@ bb0(%0 : @guaranteed $Klass): %6 = copy_value %0 : $Klass %12 = function_ref @begin_apply_callee : $@yield_once @convention(method) (@guaranteed Klass) -> @yields @inout Builtin.Int32 (%13, %14) = begin_apply %12(%6) : $@yield_once @convention(method) (@guaranteed Klass) -> @yields @inout Builtin.Int32 - end_apply %14 + end_apply %14 as $() destroy_value %6 : $Klass %19 = tuple () return %19 : $() @@ -532,7 +532,7 @@ bb0(%0 : @guaranteed $Klass): cond_br undef, bb1, bb2 bb1: - end_apply %14 + end_apply %14 as $() br bb3 bb2: @@ -574,7 +574,7 @@ bb0(%0 : @owned $C2): br bb1 bb1: - end_apply %tok + end_apply %tok as $() destroy_value %0 : $C2 %9999 = tuple() return %9999 : $() @@ -606,7 +606,7 @@ bb0(%0 : @owned $C2): cond_br undef, bb1, bb2 bb1: - end_apply %tok + end_apply %tok as $() br bb3 bb2: diff --git a/test/SILOptimizer/mandatory_performance_optimizations.sil b/test/SILOptimizer/mandatory_performance_optimizations.sil index 4564548dc5f46..b1c14896eda70 100644 --- a/test/SILOptimizer/mandatory_performance_optimizations.sil +++ b/test/SILOptimizer/mandatory_performance_optimizations.sil @@ -186,7 +186,7 @@ sil [no_locks] @inline_begin_apply : $@convention(thin) () -> Int32 { bb0: %0 = function_ref @yield_int_value : $@convention(thin) @yield_once () -> (@yields Int32) (%1, %2) = begin_apply %0() : $@convention(thin) @yield_once () -> (@yields Int32) - end_apply %2 + end_apply %2 as $() return %1 : $Int32 } @@ -199,10 +199,10 @@ bb0: (%1, %2) = begin_apply %0() : $@convention(thin) @yield_once () -> (@yields Int32) cond_br undef, bb1, bb2 bb1: - end_apply %2 + end_apply %2 as $() br bb3 bb2: - end_apply %2 + end_apply %2 as $() br bb3 bb3: return %1 : $Int32 diff --git a/test/SILOptimizer/mem-behavior.sil b/test/SILOptimizer/mem-behavior.sil index 3438d181ce43a..b76bb7348d49b 100644 --- a/test/SILOptimizer/mem-behavior.sil +++ b/test/SILOptimizer/mem-behavior.sil @@ -372,7 +372,7 @@ bb0(%0 : $*Int32): (%4, %5) = begin_apply %3(%0) : $@yield_once @convention(thin) (@in Int32) -> @yields Int32 cond_br undef, bb1, bb2 bb1: - end_apply %5 + end_apply %5 as $() dealloc_stack %1 : $*Int32 return %4 : $Int32 bb2: diff --git a/test/SILOptimizer/moveonly_addresschecker_diagnostics.sil b/test/SILOptimizer/moveonly_addresschecker_diagnostics.sil index dbef26f143556..de13f824762f2 100644 --- a/test/SILOptimizer/moveonly_addresschecker_diagnostics.sil +++ b/test/SILOptimizer/moveonly_addresschecker_diagnostics.sil @@ -411,7 +411,7 @@ bb0(%0 : @owned $NonTrivialStruct): (%9, %10) = begin_apply %8(%6) : $@yield_once @convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> @yields () %11 = load [copy] %2 : $*NonTrivialStruct // expected-note {{consumed here}} %12 = apply %7(%11) : $@convention(thin) (@owned NonTrivialStruct) -> () - end_apply %10 // expected-note {{used here}} + end_apply %10 as $() // expected-note {{used here}} destroy_value %6 : $@callee_guaranteed () -> () destroy_addr %2 : $*NonTrivialStruct dealloc_stack %1 : $*NonTrivialStruct @@ -499,7 +499,7 @@ bb1: bb2: %16 = load [copy] %2 : $*NonTrivialStruct // expected-note {{consumed here}} %17 = apply %7(%16) : $@convention(thin) (@owned NonTrivialStruct) -> () - end_apply %10 // expected-note {{used here}} + end_apply %10 as $() // expected-note {{used here}} br bb3 bb3: diff --git a/test/SILOptimizer/redundant_load_elim.sil b/test/SILOptimizer/redundant_load_elim.sil index 0c90487e3057a..b3e8302d6a032 100644 --- a/test/SILOptimizer/redundant_load_elim.sil +++ b/test/SILOptimizer/redundant_load_elim.sil @@ -1292,7 +1292,7 @@ bb0: (%1, %2, %3) = begin_apply %0() : $@yield_once @convention(thin) () -> (@yields @in_guaranteed String, @yields @in_guaranteed Int64) %4 = load %1 : $*String %5 = load %2 : $*Int64 - end_apply %3 + end_apply %3 as $() %7 = tuple (%4 : $String, %5 : $Int64) return %7 : $(String, Int64) } diff --git a/test/SILOptimizer/shrink_borrow_scope.sil b/test/SILOptimizer/shrink_borrow_scope.sil index 808f936d604fa..2100ae5d67587 100644 --- a/test/SILOptimizer/shrink_borrow_scope.sil +++ b/test/SILOptimizer/shrink_borrow_scope.sil @@ -923,7 +923,7 @@ entry(%instance : @owned $C, %input : $S): %modify_s = function_ref @modify_s : $@yield_once @convention(thin) () -> @yields @inout S (%addr, %continuation) = begin_apply %modify_s() : $@yield_once @convention(thin) () -> @yields @inout S store %input to [trivial] %addr : $*S - end_apply %continuation + end_apply %continuation as $() end_borrow %lifetime : $C destroy_value %instance : $C %retval = tuple () @@ -952,7 +952,7 @@ entry(%instance : @owned $C, %input : $S): try_apply %failable() : $@convention(thin) () -> @error Error, normal success, error failure success(%retval : $()): store %input to [trivial] %addr : $*S - end_apply %continuation + end_apply %continuation as $() end_borrow %lifetime : $C destroy_value %instance : $C return %retval : $() diff --git a/test/SILOptimizer/simplify_begin_apply.sil b/test/SILOptimizer/simplify_begin_apply.sil index b3308b3648b8d..33d5bf6aebe92 100644 --- a/test/SILOptimizer/simplify_begin_apply.sil +++ b/test/SILOptimizer/simplify_begin_apply.sil @@ -22,7 +22,7 @@ bb0: %0 = alloc_ref $Bar %1 = class_method %0 : $Bar, #Bar.field!read : (Bar) -> () -> (), $@yield_once @convention(method) (@guaranteed Bar) -> @yields Int (%2, %3) = begin_apply %1(%0) : $@yield_once @convention(method) (@guaranteed Bar) -> @yields Int - end_apply %3 + end_apply %3 as $() return %2 : $Int } diff --git a/test/SILOptimizer/simplify_cfg.sil b/test/SILOptimizer/simplify_cfg.sil index bb2e6e588ecca..dbef7bd8c924f 100644 --- a/test/SILOptimizer/simplify_cfg.sil +++ b/test/SILOptimizer/simplify_cfg.sil @@ -3126,7 +3126,7 @@ bb4: bb5: br bb6 bb6: - end_apply %token + end_apply %token as $() %rv = tuple () return %rv : $() } diff --git a/test/SILOptimizer/simplify_cfg_ossa.sil b/test/SILOptimizer/simplify_cfg_ossa.sil index 00f167cda828e..06a1759e8c1a9 100644 --- a/test/SILOptimizer/simplify_cfg_ossa.sil +++ b/test/SILOptimizer/simplify_cfg_ossa.sil @@ -1696,7 +1696,7 @@ bb4: bb5: br bb6 bb6: - end_apply %token + end_apply %token as $() %rv = tuple () return %rv : $() } diff --git a/test/SILOptimizer/specialize_opaque_result_types.sil b/test/SILOptimizer/specialize_opaque_result_types.sil index 711869e394cd9..e4b4343413d23 100644 --- a/test/SILOptimizer/specialize_opaque_result_types.sil +++ b/test/SILOptimizer/specialize_opaque_result_types.sil @@ -62,7 +62,7 @@ bb0(%0 : $*Optional<τ_0_0.Element>, %1 : $*IndexingIterator<τ_0_0>): %29 = init_enum_data_addr %0 : $*Optional<τ_0_0.Element>, #Optional.some!enumelt copy_addr %27 to [init] %29 : $*τ_0_0.Element - end_apply %28 + end_apply %28 as $() destroy_addr %22 : $*τ_0_0.Index destroy_addr %24 : $*τ_0_0 dealloc_stack %24 : $*τ_0_0 diff --git a/test/SILOptimizer/specialize_opaque_result_types_ossa.sil b/test/SILOptimizer/specialize_opaque_result_types_ossa.sil index 065004bd4cf0c..5cdfe2591d606 100644 --- a/test/SILOptimizer/specialize_opaque_result_types_ossa.sil +++ b/test/SILOptimizer/specialize_opaque_result_types_ossa.sil @@ -61,7 +61,7 @@ bb0(%0 : $*Optional<τ_0_0.Element>, %1 : $*IndexingIterator<τ_0_0>): %29 = init_enum_data_addr %0 : $*Optional<τ_0_0.Element>, #Optional.some!enumelt copy_addr %27 to [init] %29 : $*τ_0_0.Element - end_apply %28 + end_apply %28 as $() destroy_addr %22 : $*τ_0_0.Index destroy_addr %24 : $*τ_0_0 dealloc_stack %24 : $*τ_0_0 diff --git a/test/SILOptimizer/specialize_ossa.sil b/test/SILOptimizer/specialize_ossa.sil index ab781da1763e7..46c0d7dcaacdc 100644 --- a/test/SILOptimizer/specialize_ossa.sil +++ b/test/SILOptimizer/specialize_ossa.sil @@ -1226,7 +1226,7 @@ bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject): %0a = alloc_stack $Builtin.Int32 store %0 to [trivial] %0a : $*Builtin.Int32 (%0r, %0token) = begin_apply %f(%0a) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @in_guaranteed T - end_apply %0token + end_apply %0token as $() dealloc_stack %0a : $*Builtin.Int32 %1b = alloc_stack $Builtin.NativeObject @@ -1234,7 +1234,7 @@ bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject): store %1c to [init] %1b : $*Builtin.NativeObject (%1result, %1token) = begin_apply %f(%1b) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @in_guaranteed T - end_apply %1token + end_apply %1token as $() destroy_addr %1b : $*Builtin.NativeObject dealloc_stack %1b : $*Builtin.NativeObject @@ -1253,7 +1253,7 @@ bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject): %0a = alloc_stack $Builtin.Int32 store %0 to [trivial] %0a : $*Builtin.Int32 (%0r, %0token) = begin_apply %f(%0a) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @in T - end_apply %0token + end_apply %0token as $() dealloc_stack %0a : $*Builtin.Int32 %1b = alloc_stack $Builtin.NativeObject @@ -1262,7 +1262,7 @@ bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject): (%1result, %1token) = begin_apply %f(%1b) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @in T destroy_addr %1result : $*Builtin.NativeObject - end_apply %1token + end_apply %1token as $() destroy_addr %1b : $*Builtin.NativeObject dealloc_stack %1b : $*Builtin.NativeObject @@ -1281,7 +1281,7 @@ bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject): %0a = alloc_stack $Builtin.Int32 store %0 to [trivial] %0a : $*Builtin.Int32 (%0r, %0token) = begin_apply %f(%0a) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @inout T - end_apply %0token + end_apply %0token as $() dealloc_stack %0a : $*Builtin.Int32 %1b = alloc_stack $Builtin.NativeObject @@ -1289,7 +1289,7 @@ bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject): store %1c to [init] %1b : $*Builtin.NativeObject (%1result, %1token) = begin_apply %f(%1b) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @inout T - end_apply %1token + end_apply %1token as $() destroy_addr %1b : $*Builtin.NativeObject dealloc_stack %1b : $*Builtin.NativeObject diff --git a/test/SILOptimizer/specialize_reabstraction.sil b/test/SILOptimizer/specialize_reabstraction.sil index 5044ce37d835f..04e0b5fb1da57 100644 --- a/test/SILOptimizer/specialize_reabstraction.sil +++ b/test/SILOptimizer/specialize_reabstraction.sil @@ -118,7 +118,7 @@ bb2: // CHECK-NEXT: [[CORO:%.*]] = function_ref @$s9coroutineSb_Tg5 : $@yield_once @convention(thin) (Bool) -> @yields @inout Bool // CHECK-NEXT: [[LOAD:%.*]] = load [[TEMP]] : $*Bool // CHECK-NEXT: ([[ADDR:%.*]], [[TOKEN:%.*]]) = begin_apply [[CORO]]([[LOAD]]) -// CHECK-NEXT: end_apply [[TOKEN]] +// CHECK-NEXT: end_apply [[TOKEN]] as $() // CHECK-NEXT: dealloc_stack [[TEMP]] : $*Bool // CHECK-NEXT: [[RV:%.*]] = tuple () // CHECK-NEXT: return [[RV]] : $() @@ -129,7 +129,7 @@ bb0(%0 : $Bool): %temp = alloc_stack $Bool store %0 to %temp : $*Bool (%addr, %token) = begin_apply %coro(%temp) : $@yield_once @convention(thin) (@in T) -> @yields @inout T - end_apply %token + end_apply %token as $() dealloc_stack %temp : $*Bool %rv = tuple () return %rv : $() diff --git a/test/SILOptimizer/specialize_reabstraction_ossa.sil b/test/SILOptimizer/specialize_reabstraction_ossa.sil index 4f7de626cb521..ba05b86d91385 100644 --- a/test/SILOptimizer/specialize_reabstraction_ossa.sil +++ b/test/SILOptimizer/specialize_reabstraction_ossa.sil @@ -126,7 +126,7 @@ bb2: // CHECK-NEXT: [[CORO:%.*]] = function_ref @$s9coroutineSb_Tg5 : $@yield_once @convention(thin) (Bool) -> @yields @inout Bool // CHECK-NEXT: [[LOAD:%.*]] = load [trivial] [[TEMP]] : $*Bool // CHECK-NEXT: ([[ADDR:%.*]], [[TOKEN:%.*]]) = begin_apply [[CORO]]([[LOAD]]) -// CHECK-NEXT: end_apply [[TOKEN]] +// CHECK-NEXT: end_apply [[TOKEN]] as $() // CHECK-NEXT: dealloc_stack [[TEMP]] : $*Bool // CHECK-NEXT: [[RV:%.*]] = tuple () // CHECK-NEXT: return [[RV]] : $() @@ -137,7 +137,7 @@ bb0(%0 : $Bool): %temp = alloc_stack $Bool store %0 to [trivial] %temp : $*Bool (%addr, %token) = begin_apply %coro(%temp) : $@yield_once @convention(thin) (@in T) -> @yields @inout T - end_apply %token + end_apply %token as $() dealloc_stack %temp : $*Bool %rv = tuple () return %rv : $()