Skip to content

Commit f944d91

Browse files
committed
Teach LoadableTypeInfos how to add themselves to a SwiftAggLowering. NFC.
1 parent 1878be2 commit f944d91

File tree

11 files changed

+167
-10
lines changed

11 files changed

+167
-10
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ llvm::CallingConv::ID irgen::expandCallingConv(IRGenModule &IGM,
150150

151151
case SILFunctionTypeRepresentation::Method:
152152
case SILFunctionTypeRepresentation::WitnessMethod:
153-
// TODO: maybe add 'inreg' to the first non-result argument.
154153
SWIFT_FALLTHROUGH;
155154
case SILFunctionTypeRepresentation::Thin:
156155
case SILFunctionTypeRepresentation::Thick:

lib/IRGen/GenEnum.cpp

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
#include "llvm/IR/Function.h"
112112
#include "llvm/IR/GlobalVariable.h"
113113
#include "llvm/Analysis/CFG.h"
114+
#include "clang/CodeGen/SwiftCallingConv.h"
114115

115116
#include "IRGenModule.h"
116117
#include "LoadableTypeInfo.h"
@@ -390,6 +391,12 @@ namespace {
390391
getSingleton()->getBestKnownAlignment()));
391392
}
392393

394+
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
395+
Size offset) const override {
396+
if (auto singleton = getLoadableSingleton())
397+
singleton->addToAggLowering(IGM, lowering, offset);
398+
}
399+
393400
unsigned getExplosionSize() const override {
394401
if (!getLoadableSingleton()) return 0;
395402
return getLoadableSingleton()->getExplosionSize();
@@ -700,6 +707,10 @@ namespace {
700707

701708
bool needsPayloadSizeInMetadata() const override { return false; }
702709

710+
Size getFixedSize() const {
711+
return Size((getDiscriminatorType()->getBitWidth() + 7) / 8);
712+
}
713+
703714
llvm::Value *
704715
emitGetEnumTag(IRGenFunction &IGF, SILType T, Address enumAddr)
705716
const override {
@@ -833,6 +844,12 @@ namespace {
833844
return IGF.Builder.CreateStructGEP(addr, 0, Size(0));
834845
}
835846

847+
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
848+
Size offset) const override {
849+
lowering.addOpaqueData(offset.asCharUnits(),
850+
getFixedSize().asCharUnits());
851+
}
852+
836853
void emitScalarRetain(IRGenFunction &IGF, llvm::Value *value,
837854
Atomicity atomicity) const {}
838855
void emitScalarRelease(IRGenFunction &IGF, llvm::Value *value,
@@ -1159,6 +1176,23 @@ namespace {
11591176
schema.add(ExplosionSchema::Element::forScalar(extraTagTy));
11601177
}
11611178

1179+
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
1180+
Size offset) const override {
1181+
for (auto &elt : ElementsWithPayload) {
1182+
// Elements are always stored at offset 0.
1183+
// This will only be called on strategies for loadable types.
1184+
cast<LoadableTypeInfo>(elt.ti)->addToAggLowering(IGM, lowering, offset);
1185+
}
1186+
1187+
// Add the extra tag bits.
1188+
if (ExtraTagBitCount > 0) {
1189+
auto tagStoreSize = IGM.DataLayout.getTypeStoreSize(extraTagTy);
1190+
auto tagOffset = offset + getOffsetOfExtraTagBits();
1191+
lowering.addOpaqueData(tagOffset.asCharUnits(),
1192+
Size(tagStoreSize).asCharUnits());
1193+
}
1194+
}
1195+
11621196
unsigned getExplosionSize() const override {
11631197
return unsigned(ExtraTagBitCount > 0) + PayloadElementCount;
11641198
}
@@ -1175,8 +1209,12 @@ namespace {
11751209
return IGF.Builder.CreateBitCast(addr, extraTagTy->getPointerTo());
11761210
}
11771211

1178-
addr = IGF.Builder.CreateStructGEP(addr, 1, Size(PayloadBitCount/8U));
1179-
return IGF.Builder.CreateBitCast(addr, extraTagTy->getPointerTo());
1212+
addr = IGF.Builder.CreateStructGEP(addr, 1, getOffsetOfExtraTagBits());
1213+
return IGF.Builder.CreateElementBitCast(addr, extraTagTy);
1214+
}
1215+
1216+
Size getOffsetOfExtraTagBits() const {
1217+
return Size(PayloadBitCount / 8U);
11801218
}
11811219

11821220
void loadForSwitch(IRGenFunction &IGF, Address addr, Explosion &e)
@@ -4450,14 +4488,19 @@ namespace {
44504488
void destroy(IRGenFunction &IGF, Address addr, SILType T) const override {
44514489
emitDestroyCall(IGF, T, addr);
44524490
}
4453-
4491+
44544492
void getSchema(ExplosionSchema &schema) const override {
44554493
schema.add(ExplosionSchema::Element::forAggregate(getStorageType(),
44564494
TI->getBestKnownAlignment()));
44574495
}
44584496

44594497
// \group Operations for loadable enums
44604498

4499+
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
4500+
Size offset) const override {
4501+
llvm_unreachable("resilient enums are never loadable");
4502+
}
4503+
44614504
ClusteredBitVector
44624505
getTagBitsForPayloads() const override {
44634506
llvm_unreachable("resilient enums are always indirect");
@@ -4879,6 +4922,11 @@ namespace {
48794922
: EnumTypeInfoBase(strategy, T, S, std::move(SB), A, isPOD,
48804923
alwaysFixedSize) {}
48814924

4925+
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
4926+
Size offset) const override {
4927+
Strategy.addToAggLowering(IGM, lowering, offset);
4928+
}
4929+
48824930
unsigned getExplosionSize() const override {
48834931
return Strategy.getExplosionSize();
48844932
}

lib/IRGen/GenEnum.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ namespace llvm {
2323
class Value;
2424
}
2525

26+
namespace clang {
27+
namespace CodeGen {
28+
namespace swiftcall {
29+
class SwiftAggLowering;
30+
}
31+
}
32+
}
33+
2634
namespace swift {
2735
class EnumElementDecl;
2836

@@ -31,6 +39,7 @@ namespace irgen {
3139
class EnumPayloadSchema;
3240
class IRGenFunction;
3341
class TypeConverter;
42+
using clang::CodeGen::swiftcall::SwiftAggLowering;
3443

3544
/// \brief Emit the dispatch branch(es) for an address-only enum.
3645
void emitSwitchAddressOnlyEnumDispatch(IRGenFunction &IGF,
@@ -342,6 +351,8 @@ class EnumImplStrategy {
342351

343352
/// \group Delegated TypeInfo operations
344353

354+
virtual void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
355+
Size offset) const = 0;
345356
virtual void getSchema(ExplosionSchema &schema) const = 0;
346357
virtual void destroy(IRGenFunction &IGF, Address addr, SILType T) const = 0;
347358

lib/IRGen/GenExistential.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,20 @@ class ScalarExistentialTypeInfoBase :
679679
schema.add(ExplosionSchema::Element::forScalar(ty->getElementType(i)));
680680
}
681681

682+
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
683+
Size offset) const override {
684+
auto ptrSize = IGM.getPointerSize();
685+
LoadableTypeInfo::addScalarToAggLowering(IGM, lowering,
686+
asDerived().getValueType(),
687+
offset, ptrSize);
688+
689+
llvm::StructType *ty = getStorageType();
690+
for (unsigned i = 1, e = getExplosionSize(); i != e; ++i)
691+
LoadableTypeInfo::addScalarToAggLowering(IGM, lowering,
692+
ty->getElementType(i),
693+
offset + i * ptrSize, ptrSize);
694+
}
695+
682696
/// Given the address of a class existential container, returns
683697
/// the address of a witness table pointer.
684698
Address projectWitnessTable(IRGenFunction &IGF, Address address,

lib/IRGen/GenFunc.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,21 @@ namespace {
214214
}
215215

216216
void getSchema(ExplosionSchema &schema) const override {
217-
llvm::StructType *structTy = cast<llvm::StructType>(getStorageType());
217+
llvm::StructType *structTy = getStorageType();
218218
schema.add(ExplosionSchema::Element::forScalar(structTy->getElementType(0)));
219219
schema.add(ExplosionSchema::Element::forScalar(structTy->getElementType(1)));
220220
}
221221

222+
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
223+
Size offset) const override {
224+
auto ptrSize = IGM.getPointerSize();
225+
llvm::StructType *structTy = getStorageType();
226+
addScalarToAggLowering(IGM, lowering, structTy->getElementType(0),
227+
offset, ptrSize);
228+
addScalarToAggLowering(IGM, lowering, structTy->getElementType(1),
229+
offset + ptrSize, ptrSize);
230+
}
231+
222232
Address projectFunction(IRGenFunction &IGF, Address address) const {
223233
return IGF.Builder.CreateStructGEP(address, 0, Size(0),
224234
address->getName() + ".fn");

lib/IRGen/GenStruct.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "clang/AST/ASTContext.h"
2727
#include "clang/AST/Decl.h"
2828
#include "clang/AST/RecordLayout.h"
29+
#include "clang/CodeGen/SwiftCallingConv.h"
2930

3031
#include "GenMeta.h"
3132
#include "GenRecord.h"
@@ -252,22 +253,30 @@ namespace {
252253
class ClangRecordTypeInfo final :
253254
public StructTypeInfoBase<ClangRecordTypeInfo, LoadableTypeInfo,
254255
ClangFieldInfo> {
256+
const clang::RecordDecl *ClangDecl;
255257
public:
256258
ClangRecordTypeInfo(ArrayRef<ClangFieldInfo> fields,
257259
unsigned explosionSize,
258260
llvm::Type *storageType, Size size,
259-
SpareBitVector &&spareBits, Alignment align)
261+
SpareBitVector &&spareBits, Alignment align,
262+
const clang::RecordDecl *clangDecl)
260263
: StructTypeInfoBase(StructTypeInfoKind::ClangRecordTypeInfo,
261264
fields, explosionSize,
262265
storageType, size, std::move(spareBits),
263-
align, IsPOD, IsFixedSize) {
266+
align, IsPOD, IsFixedSize),
267+
ClangDecl(clangDecl) {
264268
}
265269

266270
void initializeFromParams(IRGenFunction &IGF, Explosion &params,
267271
Address addr, SILType T) const override {
268272
ClangRecordTypeInfo::initialize(IGF, params, addr);
269273
}
270274

275+
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
276+
Size offset) const override {
277+
lowering.addTypedData(ClangDecl, offset.asCharUnits());
278+
}
279+
271280
llvm::NoneType getNonFixedOffsets(IRGenFunction &IGF) const {
272281
return None;
273282
}
@@ -298,6 +307,15 @@ namespace {
298307
align, isPOD, alwaysFixedSize)
299308
{}
300309

310+
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
311+
Size offset) const override {
312+
for (auto &field : getFields()) {
313+
auto fieldOffset = offset + field.getFixedByteOffset();
314+
cast<LoadableTypeInfo>(field.getTypeInfo())
315+
.addToAggLowering(IGM, lowering, fieldOffset);
316+
}
317+
}
318+
301319
void initializeFromParams(IRGenFunction &IGF, Explosion &params,
302320
Address addr, SILType T) const override {
303321
LoadableStructTypeInfo::initialize(IGF, params, addr);
@@ -599,7 +617,8 @@ class ClangRecordLowering {
599617
llvmType->setBody(LLVMFields, /*packed*/ true);
600618
return ClangRecordTypeInfo::create(FieldInfos, NextExplosionIndex,
601619
llvmType, TotalSize,
602-
std::move(SpareBits), TotalAlignment);
620+
std::move(SpareBits), TotalAlignment,
621+
ClangDecl);
603622
}
604623

605624
private:

lib/IRGen/GenTuple.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,15 @@ namespace {
210210
alwaysFixedSize)
211211
{}
212212

213+
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
214+
Size offset) const override {
215+
for (auto &field : getFields()) {
216+
auto fieldOffset = offset + field.getFixedByteOffset();
217+
cast<LoadableTypeInfo>(field.getTypeInfo())
218+
.addToAggLowering(IGM, lowering, fieldOffset);
219+
}
220+
}
221+
213222
llvm::NoneType getNonFixedOffsets(IRGenFunction &IGF) const {
214223
return None;
215224
}

lib/IRGen/GenType.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "llvm/IR/DerivedTypes.h"
2424
#include "llvm/ADT/SmallString.h"
2525
#include "llvm/Support/ErrorHandling.h"
26+
#include "clang/CodeGen/SwiftCallingConv.h"
2627

2728
#include "EnumPayload.h"
2829
#include "LoadableTypeInfo.h"
@@ -146,6 +147,13 @@ LoadedRef LoadableTypeInfo::loadRefcountedPtr(IRGenFunction &IGF,
146147
llvm::report_fatal_error("loadRefcountedPtr: Invalid SIL in IRGen");
147148
}
148149

150+
void LoadableTypeInfo::addScalarToAggLowering(IRGenModule &IGM,
151+
SwiftAggLowering &lowering,
152+
llvm::Type *type, Size offset,
153+
Size storageSize) {
154+
lowering.addTypedData(type, offset.asCharUnits(), storageSize.asCharUnits());
155+
}
156+
149157
static llvm::Constant *asSizeConstant(IRGenModule &IGM, Size size) {
150158
return llvm::ConstantInt::get(IGM.SizeTy, size.getValue());
151159
}
@@ -379,6 +387,8 @@ namespace {
379387
IsFixedSize) {}
380388
unsigned getExplosionSize() const override { return 0; }
381389
void getSchema(ExplosionSchema &schema) const override {}
390+
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
391+
Size offset) const override {}
382392
void loadAsCopy(IRGenFunction &IGF, Address addr,
383393
Explosion &e) const override {}
384394
void loadAsTake(IRGenFunction &IGF, Address addr,
@@ -491,7 +501,7 @@ namespace {
491501

492502
void loadAsTake(IRGenFunction &IGF, Address addr,
493503
Explosion &explosion) const override {
494-
addr = IGF.Builder.CreateBitCast(addr, ScalarType->getPointerTo());
504+
addr = IGF.Builder.CreateElementBitCast(addr, ScalarType);
495505
explosion.add(IGF.Builder.CreateLoad(addr));
496506
}
497507

@@ -502,7 +512,7 @@ namespace {
502512

503513
void initialize(IRGenFunction &IGF, Explosion &explosion,
504514
Address addr) const override {
505-
addr = IGF.Builder.CreateBitCast(addr, ScalarType->getPointerTo());
515+
addr = IGF.Builder.CreateElementBitCast(addr, ScalarType);
506516
IGF.Builder.CreateStore(explosion.claimNext(), addr);
507517
}
508518

@@ -532,6 +542,12 @@ namespace {
532542
void getSchema(ExplosionSchema &schema) const override {
533543
schema.add(ExplosionSchema::Element::forScalar(ScalarType));
534544
}
545+
546+
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
547+
Size offset) const override {
548+
lowering.addOpaqueData(offset.asCharUnits(),
549+
getFixedSize().asCharUnits());
550+
}
535551

536552
void packIntoEnumPayload(IRGenFunction &IGF,
537553
EnumPayload &payload,

lib/IRGen/IRGen.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define SWIFT_IRGEN_IRGEN_H
2020

2121
#include "llvm/Support/DataTypes.h"
22+
#include "clang/AST/CharUnits.h"
2223
#include "swift/AST/ResilienceExpansion.h"
2324
#include "swift/SIL/AbstractionPattern.h"
2425
#include <cassert>
@@ -325,6 +326,10 @@ class Size {
325326
return llvm::Log2_64(Value);
326327
}
327328

329+
clang::CharUnits asCharUnits() const {
330+
return clang::CharUnits::fromQuantity(getValue());
331+
}
332+
328333
friend bool operator< (Size L, Size R) { return L.Value < R.Value; }
329334
friend bool operator<=(Size L, Size R) { return L.Value <= R.Value; }
330335
friend bool operator> (Size L, Size R) { return L.Value > R.Value; }

lib/IRGen/LoadableTypeInfo.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,18 @@
2121

2222
#include "FixedTypeInfo.h"
2323

24+
namespace clang {
25+
namespace CodeGen {
26+
namespace swiftcall {
27+
class SwiftAggLowering;
28+
}
29+
}
30+
}
31+
2432
namespace swift {
2533
namespace irgen {
2634
class EnumPayload;
35+
using clang::CodeGen::swiftcall::SwiftAggLowering;
2736

2837
struct LoadedRef {
2938
llvm::PointerIntPair<llvm::Value*, 1> ValAndNonNull;
@@ -135,6 +144,15 @@ class LoadableTypeInfo : public FixedTypeInfo {
135144
virtual LoadedRef loadRefcountedPtr(IRGenFunction &IGF, SourceLoc loc,
136145
Address addr) const;
137146

147+
/// Add this type to the given aggregate lowering.
148+
virtual void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
149+
Size offset) const = 0;
150+
151+
static void addScalarToAggLowering(IRGenModule &IGM,
152+
SwiftAggLowering &lowering,
153+
llvm::Type *type, Size offset,
154+
Size storageSize);
155+
138156
static bool classof(const LoadableTypeInfo *type) { return true; }
139157
static bool classof(const TypeInfo *type) { return type->isLoadable(); }
140158
};

0 commit comments

Comments
 (0)