Skip to content

Commit 0a5cb1e

Browse files
Merge pull request llvm#69160 from aschwaighofer/wip_partial_sil_support_for_generic_throws
Preliminary SIL and IRGen support for error_indirect
2 parents 6a699b6 + 9482b0c commit 0a5cb1e

File tree

15 files changed

+426
-57
lines changed

15 files changed

+426
-57
lines changed

include/swift/AST/Attr.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ TYPE_ATTR(dynamic_self)
6767
#define REF_STORAGE(Name, name, ...) TYPE_ATTR(sil_##name)
6868
#include "swift/AST/ReferenceStorage.def"
6969
TYPE_ATTR(error)
70+
TYPE_ATTR(error_indirect)
71+
TYPE_ATTR(error_unowned)
7072
TYPE_ATTR(out)
7173
TYPE_ATTR(direct)
7274
TYPE_ATTR(in)

include/swift/AST/CASTBridging.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ typedef enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedTypeAttrKind : size_t {
165165
BridgedTypeAttrKind_sil_unowned,
166166
BridgedTypeAttrKind_sil_unmanaged,
167167
BridgedTypeAttrKind_error,
168+
BridgedTypeAttrKind_error_indirect,
169+
BridgedTypeAttrKind_error_unowned,
168170
BridgedTypeAttrKind_out,
169171
BridgedTypeAttrKind_direct,
170172
BridgedTypeAttrKind_in,

include/swift/SIL/ApplySite.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,12 +679,17 @@ class FullApplySite : public ApplySite {
679679
return getSubstCalleeConv().getNumIndirectSILResults();
680680
}
681681

682+
unsigned getNumIndirectSILErrorResults() const {
683+
return getSubstCalleeConv().getNumIndirectSILErrorResults();
684+
}
685+
682686
OperandValueArrayRef getIndirectSILResults() const {
683687
return getArguments().slice(0, getNumIndirectSILResults());
684688
}
685689

686690
OperandValueArrayRef getArgumentsWithoutIndirectResults() const {
687-
return getArguments().slice(getNumIndirectSILResults());
691+
return getArguments().slice(getNumIndirectSILResults() +
692+
getNumIndirectSILErrorResults());
688693
}
689694

690695
InoutArgumentRange getInoutArguments() const {

include/swift/SIL/SILFunctionConventions.h

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,20 @@ class SILFunctionConventions {
232232
: funcTy->getNumPackResults();
233233
}
234234

235+
/// Get the number of SIL error results passed as address-typed arguments.
236+
unsigned getNumIndirectSILErrorResults() const {
237+
if (!silConv.loweredAddresses)
238+
return 0;
239+
if (auto errorResultInfo = funcTy->getOptionalErrorResult()) {
240+
return errorResultInfo->getConvention() == ResultConvention::Indirect ? 1 : 0;
241+
}
242+
243+
return 0;
244+
}
245+
235246
/// Are any SIL results passed as address-typed arguments?
236247
bool hasIndirectSILResults() const { return getNumIndirectSILResults() != 0; }
248+
bool hasIndirectSILErrorResults() const { return getNumIndirectSILErrorResults() != 0; }
237249

238250
struct IndirectSILResultFilter {
239251
bool loweredAddresses;
@@ -381,7 +393,7 @@ class SILFunctionConventions {
381393
unsigned getSILArgIndexOfFirstIndirectResult() const { return 0; }
382394

383395
unsigned getSILArgIndexOfFirstParam() const {
384-
return getNumIndirectSILResults();
396+
return getNumIndirectSILResults() + getNumIndirectSILErrorResults();
385397
}
386398

387399
/// Returns the index of self.
@@ -410,13 +422,15 @@ class SILFunctionConventions {
410422
/// this function type. This is also the total number of SILArguments
411423
/// in the entry block.
412424
unsigned getNumSILArguments() const {
413-
return getNumIndirectSILResults() + funcTy->getNumParameters();
425+
return getNumIndirectSILResults() + getNumIndirectSILErrorResults() +
426+
funcTy->getNumParameters();
414427
}
415428

416429
SILParameterInfo getParamInfoForSILArg(unsigned index) const {
417-
assert(index >= getNumIndirectSILResults()
430+
assert(index >= (getNumIndirectSILResults() + getNumIndirectSILErrorResults())
418431
&& index <= getNumSILArguments());
419-
return funcTy->getParameters()[index - getNumIndirectSILResults()];
432+
return funcTy->getParameters()[index - getNumIndirectSILResults()
433+
- getNumIndirectSILErrorResults()];
420434
}
421435

422436
/// Return the SIL argument convention of apply/entry argument at
@@ -518,11 +532,20 @@ inline SILType
518532
SILFunctionConventions::getSILArgumentType(unsigned index,
519533
TypeExpansionContext context) const {
520534
assert(index <= getNumSILArguments());
521-
if (index < getNumIndirectSILResults()) {
535+
auto numIndirectSILResults = getNumIndirectSILResults();
536+
if (index < numIndirectSILResults) {
522537
return *std::next(getIndirectSILResultTypes(context).begin(), index);
523538
}
539+
540+
auto numIndirectSILErrorResults = getNumIndirectSILErrorResults();
541+
if (numIndirectSILErrorResults &&
542+
(index < (numIndirectSILResults + numIndirectSILErrorResults))) {
543+
return getSILType(funcTy->getErrorResult(), context);
544+
}
545+
524546
return getSILType(
525-
funcTy->getParameters()[index - getNumIndirectSILResults()], context);
547+
funcTy->getParameters()[index - numIndirectSILResults -
548+
numIndirectSILErrorResults], context);
526549
}
527550

528551
inline bool

lib/AST/ASTPrinter.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6952,10 +6952,18 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
69526952
}
69536953

69546954
if (T->hasErrorResult()) {
6955-
// The error result is implicitly @owned; don't print that.
6956-
assert(T->getErrorResult().getConvention() == ResultConvention::Owned);
69576955
sub->Printer.printSeparator(first, ", ");
6958-
sub->Printer << "@error ";
6956+
if (T->getErrorResult().getConvention() == ResultConvention::Owned)
6957+
sub->Printer << "@error ";
6958+
else if (T->getErrorResult().getConvention() == ResultConvention::Indirect)
6959+
sub->Printer << "@error_indirect ";
6960+
else if (T->getErrorResult().getConvention() == ResultConvention::Unowned)
6961+
sub->Printer << "@error_unowned ";
6962+
else {
6963+
assert(false && "Should have error, error_indirect, or error_unowned");
6964+
}
6965+
6966+
69596967
T->getErrorResult().getInterfaceType().print(sub->Printer, subOptions);
69606968
}
69616969

lib/ASTGen/Sources/ASTGen/Types.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ extension ASTGenVisitor {
241241
case .out, .in, .owned, .unowned_inner_pointer, .guaranteed,
242242
.autoreleased, .callee_owned, .callee_guaranteed, .objc_metatype,
243243
.sil_weak, .sil_unowned, .inout, .block_storage, .box,
244-
.dynamic_self, .sil_unmanaged, .error, .direct, .inout_aliasable,
244+
.dynamic_self, .sil_unmanaged, .error, .error_indirect,
245+
.error_unowned, .direct, .inout_aliasable,
245246
.in_guaranteed, .in_constant, .captures_generics, .moveOnly:
246247
fallthrough
247248

lib/IRGen/CallEmission.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ class CallEmission {
7777
/// invocation of the call.
7878
llvm::BasicBlock *invokeUnwindDest = nullptr;
7979

80+
unsigned IndirectTypedErrorArgIdx = 0;
81+
82+
8083
virtual void setFromCallee();
8184
void emitToUnmappedMemory(Address addr);
8285
void emitToUnmappedExplosion(Explosion &out);
@@ -141,6 +144,15 @@ class CallEmission {
141144

142145
virtual llvm::Value *getResumeFunctionPointer() = 0;
143146
virtual llvm::Value *getAsyncContext() = 0;
147+
148+
void setIndirectTypedErrorResultSlot(llvm::Value *addr) {
149+
Args[IndirectTypedErrorArgIdx] = addr;
150+
}
151+
152+
void setIndirectTypedErrorResultSlotArgsIndex(unsigned idx) {
153+
assert(idx != 0);
154+
IndirectTypedErrorArgIdx = idx;
155+
}
144156
};
145157

146158
std::unique_ptr<CallEmission>

lib/IRGen/GenCall.cpp

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,9 +1860,9 @@ void SignatureExpansion::expandParameters(
18601860
recordedABIDetails->hasErrorResult = true;
18611861
if (getSILFuncConventions().isTypedError()) {
18621862
ParamIRTypes.push_back(
1863-
IGM.getStorageType(getSILFuncConventions().getSILType(
1864-
FnType->getErrorResult(), IGM.getMaximalTypeExpansionContext())
1865-
)->getPointerTo());
1863+
IGM.getStorageType(getSILFuncConventions().getSILType(
1864+
FnType->getErrorResult(), IGM.getMaximalTypeExpansionContext())
1865+
)->getPointerTo());
18661866
}
18671867
}
18681868

@@ -1962,7 +1962,7 @@ void SignatureExpansion::addIndirectThrowingResult() {
19621962
getSILFuncConventions().isTypedError()) {
19631963
auto resultType = getSILFuncConventions().getSILErrorType(
19641964
IGM.getMaximalTypeExpansionContext());
1965-
const TypeInfo &resultTI = cast<LoadableTypeInfo>(IGM.getTypeInfo(resultType));
1965+
const TypeInfo &resultTI = IGM.getTypeInfo(resultType);
19661966
auto storageTy = resultTI.getStorageType();
19671967
ParamIRTypes.push_back(storageTy->getPointerTo());
19681968
}
@@ -2401,17 +2401,24 @@ class SyncCallEmission final : public CallEmission {
24012401
if (fnType->hasErrorResult()) {
24022402
// The invariant is that this is always zero-initialized, so we
24032403
// don't need to do anything extra here.
2404-
SILFunctionConventions fnConv(fnType, IGF.getSILModule());
2404+
auto substFnType = CurCallee.getSubstFunctionType();
2405+
SILFunctionConventions fnConv(substFnType, IGF.getSILModule());
24052406
Address errorResultSlot = IGF.getCalleeErrorResultSlot(
24062407
fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()),
24072408
fnConv.isTypedError());
24082409

24092410
assert(LastArgWritten > 0);
24102411
if (fnConv.isTypedError()) {
2411-
// Return the error indirectly.
2412-
auto buf = IGF.getCalleeTypedErrorResultSlot(
2413-
fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()));
2414-
Args[--LastArgWritten] = buf.getAddress();
2412+
if (fnConv.hasIndirectSILErrorResults()) {
2413+
// We will set the value later when lowering the arguments.
2414+
setIndirectTypedErrorResultSlotArgsIndex(--LastArgWritten);
2415+
Args[LastArgWritten] = nullptr;
2416+
} else {
2417+
// Return the error indirectly.
2418+
auto buf = IGF.getCalleeTypedErrorResultSlot(
2419+
fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()));
2420+
Args[--LastArgWritten] = buf.getAddress();
2421+
}
24152422
}
24162423
Args[--LastArgWritten] = errorResultSlot.getAddress();
24172424
addParamAttribute(LastArgWritten, llvm::Attribute::NoCapture);
@@ -2718,9 +2725,15 @@ class AsyncCallEmission final : public CallEmission {
27182725
// don't need to do anything extra here.
27192726
assert(LastArgWritten > 0);
27202727
// Return the error indirectly.
2721-
auto buf = IGF.getCalleeTypedErrorResultSlot(
2722-
fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()));
2723-
Args[--LastArgWritten] = buf.getAddress();
2728+
if (fnConv.hasIndirectSILErrorResults()) {
2729+
// We will set the value later when lowering the arguments.
2730+
setIndirectTypedErrorResultSlotArgsIndex(--LastArgWritten);
2731+
Args[LastArgWritten] = nullptr;
2732+
} else {
2733+
auto buf = IGF.getCalleeTypedErrorResultSlot(
2734+
fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()));
2735+
Args[--LastArgWritten] = buf.getAddress();
2736+
}
27242737
}
27252738

27262739
llvm::Value *contextPtr = CurCallee.getSwiftContext();
@@ -4718,14 +4731,15 @@ Explosion IRGenFunction::collectParameters() {
47184731
Address IRGenFunction::createErrorResultSlot(SILType errorType, bool isAsync,
47194732
bool setSwiftErrorFlag,
47204733
bool isTypedError) {
4721-
auto &errorTI = cast<FixedTypeInfo>(getTypeInfo(errorType));
47224734

47234735
IRBuilder builder(IGM.getLLVMContext(), IGM.DebugInfo != nullptr);
47244736
builder.SetInsertPoint(AllocaIP->getParent(), AllocaIP->getIterator());
4737+
47254738
auto errorStorageType = isTypedError ? IGM.Int8PtrTy :
4726-
errorTI.getStorageType();
4739+
cast<FixedTypeInfo>(getTypeInfo(errorType)).getStorageType();
47274740
auto errorAlignment = isTypedError ? IGM.getPointerAlignment() :
4728-
errorTI.getFixedAlignment();
4741+
cast<FixedTypeInfo>(getTypeInfo(errorType)).getFixedAlignment();
4742+
47294743
// Create the alloca. We don't use allocateStack because we're
47304744
// not allocating this in stack order.
47314745
auto addr = createAlloca(errorStorageType,

lib/IRGen/IRGenSIL.cpp

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,18 +2161,35 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF,
21612161
if (funcTy->hasErrorResult()) {
21622162
auto errorType =
21632163
fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext());
2164-
auto &errorTI = cast<FixedTypeInfo>(IGF.getTypeInfo(errorType));
2164+
auto inContextErrorType =
2165+
IGF.CurSILFn->mapTypeIntoContext(errorType);
21652166
bool isTypedError = fnConv.isTypedError();
2166-
if (isTypedError) {
2167+
bool isIndirectError = fnConv.hasIndirectSILErrorResults();
2168+
2169+
if (isTypedError && !isIndirectError) {
2170+
auto &errorTI = cast<FixedTypeInfo>(IGF.getTypeInfo(errorType));
21672171
IGF.setCallerTypedErrorResultSlot(Address(
21682172
emission->getCallerTypedErrorResultArgument(),
21692173
errorTI.getStorageType(),
21702174
errorTI.getFixedAlignment()));
2175+
2176+
} else if (isTypedError && isIndirectError) {
2177+
2178+
auto &errorTI = IGF.getTypeInfo(inContextErrorType);
2179+
auto ptr = emission->getCallerTypedErrorResultArgument();
2180+
auto addr = errorTI.getAddressForPointer(ptr);
2181+
auto indirectErrorArgIdx = fnConv.getNumIndirectSILResults();
2182+
auto errorArg = entry->getArguments()[indirectErrorArgIdx];
2183+
IGF.setLoweredAddress(errorArg, addr);
2184+
params = params.slice(1);
21712185
}
2186+
21722187
if (!funcTy->isAsync()) {
2188+
auto &errorTI = IGF.getTypeInfo(inContextErrorType);
21732189
IGF.setCallerErrorResultSlot(
21742190
Address(emission->getCallerErrorResultArgument(),
2175-
isTypedError ? IGF.IGM.Int8PtrTy : errorTI.getStorageType(),
2191+
isTypedError ? IGF.IGM.Int8PtrTy :
2192+
cast<FixedTypeInfo>(errorTI).getStorageType(),
21762193
IGF.IGM.getPointerAlignment()));
21772194
}
21782195
}
@@ -3685,6 +3702,12 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) {
36853702

36863703
// Turn the formal SIL parameters into IR-gen things.
36873704
for (auto index : indices(args)) {
3705+
if (origConv.hasIndirectSILErrorResults() &&
3706+
index == origConv.getNumIndirectSILResults()) {
3707+
auto addr = getLoweredAddress(args[index]);
3708+
emission->setIndirectTypedErrorResultSlot(addr.getAddress());
3709+
continue;
3710+
}
36883711
emitApplyArgument(*this, args[index], emission->getParameterType(index),
36893712
llArgs);
36903713
}
@@ -3752,9 +3775,10 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) {
37523775
// See below.
37533776
Builder.CreateStore(nullError, calleeErrorSlot);
37543777
}
3755-
auto hasTypedError = substConv.isTypedError();
3778+
auto hasTypedDirectError = substConv.isTypedError() &&
3779+
!substConv.hasIndirectSILErrorResults();
37563780
llvm::BasicBlock *typedErrorLoadBB = nullptr;
3757-
if (hasTypedError) {
3781+
if (hasTypedDirectError) {
37583782
typedErrorLoadBB = createBasicBlock("typed.error.load");
37593783
}
37603784

@@ -3771,8 +3795,11 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) {
37713795

37723796
// Set up the PHI nodes on the error edge.
37733797
if (!typedErrorLoadBB) {
3774-
assert(errorDest.phis.size() == 1);
3775-
errorDest.phis[0]->addIncoming(errorValue, Builder.GetInsertBlock());
3798+
assert(errorDest.phis.size() == 1 ||
3799+
(substConv.hasIndirectSILErrorResults() &&
3800+
errorDest.phis.empty()));
3801+
if (errorDest.phis.size() == 1)
3802+
errorDest.phis[0]->addIncoming(errorValue, Builder.GetInsertBlock());
37763803
} else {
37773804
Builder.emitBlock(typedErrorLoadBB);
37783805

@@ -4226,16 +4253,18 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) {
42264253
SILFunctionConventions conv(CurSILFn->getLoweredFunctionType(),
42274254
getSILModule());
42284255
if (!isAsync()) {
4229-
Explosion errorResult = getLoweredExplosion(i->getOperand());
42304256
if (conv.isTypedError()) {
4231-
auto &ti = cast<LoadableTypeInfo>(IGM.getTypeInfo(conv.getSILErrorType(
4232-
IGM.getMaximalTypeExpansionContext())));
42334257
llvm::Constant *flag = llvm::ConstantInt::get(IGM.IntPtrTy, 1);
42344258
flag = llvm::ConstantExpr::getIntToPtr(flag, IGM.Int8PtrTy);
4235-
Builder.CreateStore(flag,
4236-
getCallerErrorResultSlot());
4237-
ti.initialize(*this, errorResult, getCallerTypedErrorResultSlot(), false);
4259+
if (!conv.hasIndirectSILErrorResults()) {
4260+
Explosion errorResult = getLoweredExplosion(i->getOperand());
4261+
auto &ti = cast<LoadableTypeInfo>(IGM.getTypeInfo(conv.getSILErrorType(
4262+
IGM.getMaximalTypeExpansionContext())));
4263+
ti.initialize(*this, errorResult, getCallerTypedErrorResultSlot(), false);
4264+
}
4265+
Builder.CreateStore(flag, getCallerErrorResultSlot());
42384266
} else {
4267+
Explosion errorResult = getLoweredExplosion(i->getOperand());
42394268
Builder.CreateStore(errorResult.claimNext(), getCallerErrorResultSlot());
42404269
}
42414270
// Async functions just return to the continuation.
@@ -4248,9 +4277,13 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) {
42484277
conv.getSILResultType(IGM.getMaximalTypeExpansionContext()));
42494278

42504279
if (conv.isTypedError()) {
4251-
auto &ti = cast<LoadableTypeInfo>(IGM.getTypeInfo(conv.getSILErrorType(
4252-
IGM.getMaximalTypeExpansionContext())));
4253-
ti.initialize(*this, exn, getCallerTypedErrorResultSlot(), false);
4280+
if (conv.hasIndirectSILErrorResults()) {
4281+
(void)exn.claimAll();
4282+
} else {
4283+
auto &ti = cast<LoadableTypeInfo>(IGM.getTypeInfo(conv.getSILErrorType(
4284+
IGM.getMaximalTypeExpansionContext())));
4285+
ti.initialize(*this, exn, getCallerTypedErrorResultSlot(), false);
4286+
}
42544287
llvm::Constant *flag = llvm::ConstantInt::get(IGM.IntPtrTy, 1);
42554288
flag = llvm::ConstantExpr::getIntToPtr(flag, IGM.Int8PtrTy);
42564289
assert(exn.empty() && "Unclaimed typed error results");

0 commit comments

Comments
 (0)