Skip to content

Commit 4cba763

Browse files
committed
IRGen: Add TypeExpansionContext to IRGen
1 parent 8aaa7b4 commit 4cba763

20 files changed

+313
-175
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3347,10 +3347,43 @@ Explosion NativeConventionSchema::mapIntoNative(IRGenModule &IGM,
33473347
return nativeExplosion;
33483348
}
33493349

3350-
void IRGenFunction::emitScalarReturn(SILType resultType, Explosion &result,
3350+
Explosion IRGenFunction::coerceValueTo(SILType fromTy, Explosion &from,
3351+
SILType toTy) {
3352+
if (fromTy == toTy)
3353+
return std::move(from);
3354+
3355+
auto &fromTI = cast<LoadableTypeInfo>(IGM.getTypeInfo(fromTy));
3356+
auto &toTI = cast<LoadableTypeInfo>(IGM.getTypeInfo(toTy));
3357+
3358+
Explosion result;
3359+
if (fromTI.getStorageType()->isPointerTy() &&
3360+
toTI.getStorageType()->isPointerTy()) {
3361+
auto ptr = from.claimNext();
3362+
ptr = Builder.CreateBitCast(ptr, toTI.getStorageType());
3363+
result.add(ptr);
3364+
return result;
3365+
}
3366+
3367+
auto temporary = toTI.allocateStack(*this, toTy, "coerce.temp");
3368+
3369+
auto addr =
3370+
Address(Builder.CreateBitCast(temporary.getAddressPointer(),
3371+
fromTI.getStorageType()->getPointerTo()),
3372+
temporary.getAlignment());
3373+
fromTI.initialize(*this, from, addr, false);
3374+
3375+
toTI.loadAsTake(*this, temporary.getAddress(), result);
3376+
toTI.deallocateStack(*this, temporary, toTy);
3377+
return result;
3378+
}
3379+
3380+
void IRGenFunction::emitScalarReturn(SILType returnResultType,
3381+
SILType funcResultType, Explosion &result,
33513382
bool isSwiftCCReturn, bool isOutlined) {
33523383
if (result.empty()) {
3353-
assert(IGM.getTypeInfo(resultType).nativeReturnValueSchema(IGM).empty() &&
3384+
assert(IGM.getTypeInfo(returnResultType)
3385+
.nativeReturnValueSchema(IGM)
3386+
.empty() &&
33543387
"Empty explosion must match the native calling convention");
33553388

33563389
Builder.CreateRetVoid();
@@ -3359,12 +3392,13 @@ void IRGenFunction::emitScalarReturn(SILType resultType, Explosion &result,
33593392

33603393
// In the native case no coercion is needed.
33613394
if (isSwiftCCReturn) {
3395+
result = coerceValueTo(returnResultType, result, funcResultType);
33623396
auto &nativeSchema =
3363-
IGM.getTypeInfo(resultType).nativeReturnValueSchema(IGM);
3397+
IGM.getTypeInfo(funcResultType).nativeReturnValueSchema(IGM);
33643398
assert(!nativeSchema.requiresIndirect());
33653399

3366-
Explosion native =
3367-
nativeSchema.mapIntoNative(IGM, *this, result, resultType, isOutlined);
3400+
Explosion native = nativeSchema.mapIntoNative(IGM, *this, result,
3401+
funcResultType, isOutlined);
33683402
if (native.size() == 1) {
33693403
Builder.CreateRet(native.claimNext());
33703404
return;
@@ -3391,7 +3425,7 @@ void IRGenFunction::emitScalarReturn(SILType resultType, Explosion &result,
33913425
return;
33923426
}
33933427

3394-
auto &resultTI = IGM.getTypeInfo(resultType);
3428+
auto &resultTI = IGM.getTypeInfo(returnResultType);
33953429
auto schema = resultTI.getSchema();
33963430
auto *bodyType = schema.getScalarResultType(IGM);
33973431

lib/IRGen/GenClass.cpp

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,8 @@ namespace {
297297
SILType classType,
298298
bool superclass) {
299299
for (VarDecl *var : theClass->getStoredProperties()) {
300-
SILType type = classType.getFieldType(var, IGM.getSILModule());
300+
SILType type = classType.getFieldType(var, IGM.getSILModule(),
301+
TypeExpansionContext::minimal());
301302

302303
// Lower the field type.
303304
auto *eltType = &IGM.getTypeInfo(type);
@@ -500,23 +501,21 @@ Address IRGenFunction::emitByteOffsetGEP(llvm::Value *base,
500501
}
501502

502503
/// Emit a field l-value by applying the given offset to the given base.
503-
static OwnedAddress emitAddressAtOffset(IRGenFunction &IGF,
504-
SILType baseType,
505-
llvm::Value *base,
506-
llvm::Value *offset,
504+
static OwnedAddress emitAddressAtOffset(TypeExpansionContext context,
505+
IRGenFunction &IGF, SILType baseType,
506+
llvm::Value *base, llvm::Value *offset,
507507
VarDecl *field) {
508-
auto &fieldTI =
509-
IGF.getTypeInfo(baseType.getFieldType(field, IGF.getSILModule()));
508+
auto &fieldTI = IGF.getTypeInfo(
509+
baseType.getFieldType(field, IGF.getSILModule(), context));
510510
auto addr = IGF.emitByteOffsetGEP(base, offset, fieldTI,
511511
base->getName() + "." + field->getName().str());
512512
return OwnedAddress(addr, base);
513513
}
514514

515-
llvm::Constant *
516-
irgen::tryEmitConstantClassFragilePhysicalMemberOffset(IRGenModule &IGM,
517-
SILType baseType,
518-
VarDecl *field) {
519-
auto fieldType = baseType.getFieldType(field, IGM.getSILModule());
515+
llvm::Constant *irgen::tryEmitConstantClassFragilePhysicalMemberOffset(
516+
TypeExpansionContext context, IRGenModule &IGM, SILType baseType,
517+
VarDecl *field) {
518+
auto fieldType = baseType.getFieldType(field, IGM.getSILModule(), context);
520519
// If the field is empty, its address doesn't matter.
521520
auto &fieldTI = IGM.getTypeInfo(fieldType);
522521
if (fieldTI.isKnownEmpty(ResilienceExpansion::Maximal)) {
@@ -572,11 +571,9 @@ irgen::getClassLayoutWithTailElems(IRGenModule &IGM, SILType classType,
572571
return ClassTI.createLayoutWithTailElems(IGM, classType, tailTypes);
573572
}
574573

575-
OwnedAddress irgen::projectPhysicalClassMemberAddress(IRGenFunction &IGF,
576-
llvm::Value *base,
577-
SILType baseType,
578-
SILType fieldType,
579-
VarDecl *field) {
574+
OwnedAddress irgen::projectPhysicalClassMemberAddress(
575+
TypeExpansionContext context, IRGenFunction &IGF, llvm::Value *base,
576+
SILType baseType, SILType fieldType, VarDecl *field) {
580577
// If the field is empty, its address doesn't matter.
581578
auto &fieldTI = IGF.getTypeInfo(fieldType);
582579
if (fieldTI.isKnownEmpty(ResilienceExpansion::Maximal)) {
@@ -606,13 +603,13 @@ OwnedAddress irgen::projectPhysicalClassMemberAddress(IRGenFunction &IGF,
606603
case FieldAccess::NonConstantDirect: {
607604
Address offsetA = IGF.IGM.getAddrOfFieldOffset(field, NotForDefinition);
608605
auto offset = IGF.Builder.CreateLoad(offsetA, "offset");
609-
return emitAddressAtOffset(IGF, baseType, base, offset, field);
606+
return emitAddressAtOffset(context, IGF, baseType, base, offset, field);
610607
}
611608

612609
case FieldAccess::ConstantIndirect: {
613610
auto metadata = emitHeapMetadataRefForHeapObject(IGF, base, baseType);
614611
auto offset = emitClassFieldOffset(IGF, baseClass, field, metadata);
615-
return emitAddressAtOffset(IGF, baseType, base, offset, field);
612+
return emitAddressAtOffset(context, IGF, baseType, base, offset, field);
616613
}
617614
}
618615
llvm_unreachable("bad field-access strategy");
@@ -2423,12 +2420,13 @@ FunctionPointer irgen::emitVirtualMethodValue(IRGenFunction &IGF,
24232420
return FunctionPointer(fnPtr, signature);
24242421
}
24252422

2426-
FunctionPointer irgen::emitVirtualMethodValue(IRGenFunction &IGF,
2427-
llvm::Value *base,
2428-
SILType baseType,
2429-
SILDeclRef method,
2430-
CanSILFunctionType methodType,
2431-
bool useSuperVTable) {
2423+
FunctionPointer
2424+
irgen::emitVirtualMethodValue(IRGenFunction &IGF,
2425+
llvm::Value *base,
2426+
SILType baseType,
2427+
SILDeclRef method,
2428+
CanSILFunctionType methodType,
2429+
bool useSuperVTable) {
24322430
// Find the metadata.
24332431
llvm::Value *metadata;
24342432
if (useSuperVTable) {

lib/IRGen/GenClass.h

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,10 @@ namespace irgen {
5050

5151
enum class ClassDeallocationKind : unsigned char;
5252
enum class FieldAccess : uint8_t;
53-
54-
OwnedAddress projectPhysicalClassMemberAddress(IRGenFunction &IGF,
55-
llvm::Value *base,
56-
SILType baseType,
57-
SILType fieldType,
58-
VarDecl *field);
53+
54+
OwnedAddress projectPhysicalClassMemberAddress(
55+
TypeExpansionContext context, IRGenFunction &IGF, llvm::Value *base,
56+
SILType baseType, SILType fieldType, VarDecl *field);
5957

6058
/// Return a strategy for accessing the given stored class property.
6159
///
@@ -180,11 +178,10 @@ namespace irgen {
180178

181179
/// Emit the constant fragile offset of the given property inside an instance
182180
/// of the class.
183-
llvm::Constant *
184-
tryEmitConstantClassFragilePhysicalMemberOffset(IRGenModule &IGM,
185-
SILType baseType,
186-
VarDecl *field);
187-
181+
llvm::Constant *tryEmitConstantClassFragilePhysicalMemberOffset(
182+
TypeExpansionContext context, IRGenModule &IGM, SILType baseType,
183+
VarDecl *field);
184+
188185
FieldAccess getClassFieldAccess(IRGenModule &IGM,
189186
SILType baseType,
190187
VarDecl *field);
@@ -208,10 +205,8 @@ namespace irgen {
208205

209206
/// Given an instance pointer (or, for a static method, a class
210207
/// pointer), emit the callee for the given method.
211-
FunctionPointer emitVirtualMethodValue(IRGenFunction &IGF,
212-
llvm::Value *base,
213-
SILType baseType,
214-
SILDeclRef method,
208+
FunctionPointer emitVirtualMethodValue(IRGenFunction &IGF, llvm::Value *base,
209+
SILType baseType, SILDeclRef method,
215210
CanSILFunctionType methodType,
216211
bool useSuperVTable);
217212

lib/IRGen/GenEnum.cpp

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,10 @@ namespace {
315315

316316
SILType getSingletonType(IRGenModule &IGM, SILType T) const {
317317
assert(!ElementsWithPayload.empty());
318-
318+
319319
return T.getEnumElementType(ElementsWithPayload[0].decl,
320-
IGM.getSILModule());
320+
IGM.getSILModule(),
321+
IGM.getMaximalTypeExpansionContext());
321322
}
322323

323324
public:
@@ -614,8 +615,9 @@ namespace {
614615
assert(ElementsWithPayload.size() == 1 &&
615616
"empty singleton enum should not be dynamic!");
616617

617-
auto payloadTy = T.getEnumElementType(ElementsWithPayload[0].decl,
618-
IGM.getSILModule());
618+
auto payloadTy = T.getEnumElementType(
619+
ElementsWithPayload[0].decl, IGM.getSILModule(),
620+
IGM.getMaximalTypeExpansionContext());
619621
auto payloadLayout = emitTypeLayoutRef(IGF, payloadTy, collector);
620622
auto flags = emitEnumLayoutFlags(IGF.IGM, isVWTMutable);
621623
IGF.Builder.CreateCall(
@@ -1567,7 +1569,8 @@ namespace {
15671569

15681570
SILType getPayloadType(IRGenModule &IGM, SILType T) const {
15691571
return T.getEnumElementType(ElementsWithPayload[0].decl,
1570-
IGM.getSILModule());
1572+
IGM.getSILModule(),
1573+
IGM.getMaximalTypeExpansionContext());
15711574
}
15721575

15731576
const TypeInfo &getPayloadTypeInfo() const {
@@ -2957,8 +2960,9 @@ namespace {
29572960

29582961
// Ask the runtime to do our layout using the payload metadata and number
29592962
// of empty cases.
2960-
auto payloadTy = T.getEnumElementType(ElementsWithPayload[0].decl,
2961-
IGM.getSILModule());
2963+
auto payloadTy =
2964+
T.getEnumElementType(ElementsWithPayload[0].decl, IGM.getSILModule(),
2965+
IGM.getMaximalTypeExpansionContext());
29622966
auto payloadLayout = emitTypeLayoutRef(IGF, payloadTy, collector);
29632967
auto emptyCasesVal = llvm::ConstantInt::get(IGM.Int32Ty,
29642968
ElementsWithNoPayload.size());
@@ -4575,8 +4579,9 @@ namespace {
45754579

45764580
unsigned tagIndex = 0;
45774581
for (auto &payloadCasePair : ElementsWithPayload) {
4578-
SILType PayloadT = T.getEnumElementType(payloadCasePair.decl,
4579-
IGF.getSILModule());
4582+
SILType PayloadT =
4583+
T.getEnumElementType(payloadCasePair.decl, IGF.getSILModule(),
4584+
IGF.IGM.getMaximalTypeExpansionContext());
45804585
auto &payloadTI = *payloadCasePair.ti;
45814586
// Trivial and, in the case of a take, bitwise-takable payloads,
45824587
// can all share the default path.
@@ -4692,9 +4697,9 @@ namespace {
46924697
}
46934698

46944699
for (auto &payloadCasePair : ElementsWithPayload) {
4695-
SILType payloadT =
4696-
T.getEnumElementType(payloadCasePair.decl,
4697-
collector.IGF.getSILModule());
4700+
SILType payloadT = T.getEnumElementType(
4701+
payloadCasePair.decl, collector.IGF.getSILModule(),
4702+
collector.IGF.IGM.getMaximalTypeExpansionContext());
46984703
auto &payloadTI = *payloadCasePair.ti;
46994704
payloadTI.collectMetadataForOutlining(collector, payloadT);
47004705
}
@@ -4737,8 +4742,9 @@ namespace {
47374742
// Destroy the data.
47384743
Address dataAddr = IGF.Builder.CreateBitCast(
47394744
addr, elt.ti->getStorageType()->getPointerTo());
4740-
SILType payloadT =
4741-
T.getEnumElementType(elt.decl, IGF.getSILModule());
4745+
SILType payloadT = T.getEnumElementType(
4746+
elt.decl, IGF.getSILModule(),
4747+
IGF.IGM.getMaximalTypeExpansionContext());
47424748
elt.ti->destroy(IGF, dataAddr, payloadT, true /*isOutlined*/);
47434749
});
47444750
return;
@@ -4977,9 +4983,11 @@ namespace {
49774983
Address eltAddr = IGF.Builder.CreateStructGEP(metadataBuffer, i,
49784984
IGM.getPointerSize() * i);
49794985
if (i == 0) firstAddr = eltAddr.getAddress();
4980-
4981-
auto payloadTy = T.getEnumElementType(elt.decl, IGF.getSILModule());
4982-
4986+
4987+
auto payloadTy =
4988+
T.getEnumElementType(elt.decl, IGF.getSILModule(),
4989+
IGF.IGM.getMaximalTypeExpansionContext());
4990+
49834991
auto metadata = emitTypeLayoutRef(IGF, payloadTy, collector);
49844992

49854993
IGF.Builder.CreateStore(metadata, eltAddr);
@@ -5809,7 +5817,8 @@ EnumImplStrategy::get(TypeConverter &TC, SILType type, EnumDecl *theEnum) {
58095817
// *Now* apply the substitutions and get the type info for the instance's
58105818
// payload type, since we know this case carries an apparent payload in
58115819
// the generic case.
5812-
SILType fieldTy = type.getEnumElementType(elt, TC.IGM.getSILModule());
5820+
SILType fieldTy = type.getEnumElementType(
5821+
elt, TC.IGM.getSILModule(), TC.IGM.getMaximalTypeExpansionContext());
58135822
auto *substArgTI = &TC.IGM.getTypeInfo(fieldTy);
58145823

58155824
elementsWithPayload.push_back({elt, substArgTI, origArgTI});

lib/IRGen/GenFunc.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,8 +1138,11 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM,
11381138
FunctionPointer fnPtr = [&]() -> FunctionPointer {
11391139
// If we found a function pointer statically, great.
11401140
if (staticFnPtr) {
1141-
assert(staticFnPtr->getPointer()->getType() == fnTy &&
1142-
"static function type mismatch?!");
1141+
if (staticFnPtr->getPointer()->getType() != fnTy) {
1142+
auto fnPtr = staticFnPtr->getPointer();
1143+
fnPtr = subIGF.Builder.CreateBitCast(fnPtr, fnTy);
1144+
return FunctionPointer(fnPtr, origSig);
1145+
}
11431146
return *staticFnPtr;
11441147
}
11451148

lib/IRGen/GenHeap.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,8 +1528,8 @@ const TypeInfo *TypeConverter::convertBoxType(SILBoxType *T) {
15281528
// TODO: Multi-field boxes
15291529
assert(T->getLayout()->getFields().size() == 1
15301530
&& "multi-field boxes not implemented yet");
1531-
auto &eltTI = IGM.getTypeInfoForLowered(
1532-
getSILBoxFieldLoweredType(T, IGM.getSILModule().Types, 0));
1531+
auto &eltTI = IGM.getTypeInfoForLowered(getSILBoxFieldLoweredType(
1532+
IGM.getMaximalTypeExpansionContext(), T, IGM.getSILModule().Types, 0));
15331533
if (!eltTI.isFixedSize()) {
15341534
if (!NonFixedBoxTI)
15351535
NonFixedBoxTI = new NonFixedBoxTypeInfo(IGM);
@@ -1577,8 +1577,9 @@ const TypeInfo *TypeConverter::convertBoxType(SILBoxType *T) {
15771577
// Produce a tailored box metadata for the type.
15781578
assert(T->getLayout()->getFields().size() == 1
15791579
&& "multi-field boxes not implemented yet");
1580-
return new FixedBoxTypeInfo(IGM,
1581-
getSILBoxFieldType(T, IGM.getSILModule().Types, 0));
1580+
return new FixedBoxTypeInfo(
1581+
IGM, getSILBoxFieldType(IGM.getMaximalTypeExpansionContext(),
1582+
T, IGM.getSILModule().Types, 0));
15821583
}
15831584

15841585
OwnedAddress
@@ -1588,9 +1589,12 @@ irgen::emitAllocateBox(IRGenFunction &IGF, CanSILBoxType boxType,
15881589
auto &boxTI = IGF.getTypeInfoForLowered(boxType).as<BoxTypeInfo>();
15891590
assert(boxType->getLayout()->getFields().size() == 1
15901591
&& "multi-field boxes not implemented yet");
1591-
return boxTI.allocate(IGF,
1592-
getSILBoxFieldType(boxType, IGF.IGM.getSILModule().Types, 0),
1593-
env, name);
1592+
return boxTI.allocate(
1593+
IGF,
1594+
getSILBoxFieldType(
1595+
IGF.IGM.getMaximalTypeExpansionContext(),
1596+
boxType, IGF.IGM.getSILModule().Types, 0),
1597+
env, name);
15941598
}
15951599

15961600
void irgen::emitDeallocateBox(IRGenFunction &IGF,
@@ -1599,8 +1603,10 @@ void irgen::emitDeallocateBox(IRGenFunction &IGF,
15991603
auto &boxTI = IGF.getTypeInfoForLowered(boxType).as<BoxTypeInfo>();
16001604
assert(boxType->getLayout()->getFields().size() == 1
16011605
&& "multi-field boxes not implemented yet");
1602-
return boxTI.deallocate(IGF, box,
1603-
getSILBoxFieldType(boxType, IGF.IGM.getSILModule().Types, 0));
1606+
return boxTI.deallocate(
1607+
IGF, box,
1608+
getSILBoxFieldType(IGF.IGM.getMaximalTypeExpansionContext(), boxType,
1609+
IGF.IGM.getSILModule().Types, 0));
16041610
}
16051611

16061612
Address irgen::emitProjectBox(IRGenFunction &IGF,
@@ -1609,8 +1615,10 @@ Address irgen::emitProjectBox(IRGenFunction &IGF,
16091615
auto &boxTI = IGF.getTypeInfoForLowered(boxType).as<BoxTypeInfo>();
16101616
assert(boxType->getLayout()->getFields().size() == 1
16111617
&& "multi-field boxes not implemented yet");
1612-
return boxTI.project(IGF, box,
1613-
getSILBoxFieldType(boxType, IGF.IGM.getSILModule().Types, 0));
1618+
return boxTI.project(
1619+
IGF, box,
1620+
getSILBoxFieldType(IGF.IGM.getMaximalTypeExpansionContext(), boxType,
1621+
IGF.IGM.getSILModule().Types, 0));
16141622
}
16151623

16161624
Address irgen::emitAllocateExistentialBoxInBuffer(

0 commit comments

Comments
 (0)