Skip to content

Commit 34267d7

Browse files
Merge pull request #40242 from aschwaighofer/chunk_opaque_storage_type_info
IRGen: Chunk OpaqueStorageTypeInfo into llvm::IntegerType::MAX_INT_BITS chunks
2 parents 6fa89b7 + 58a7bc9 commit 34267d7

File tree

1 file changed

+66
-17
lines changed

1 file changed

+66
-17
lines changed

lib/IRGen/GenType.cpp

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,16 +1117,16 @@ namespace {
11171117
class OpaqueStorageTypeInfo final :
11181118
public ScalarTypeInfo<OpaqueStorageTypeInfo, LoadableTypeInfo>
11191119
{
1120-
llvm::IntegerType *ScalarType;
1120+
std::vector<llvm::IntegerType *> ScalarTypes;
11211121
public:
11221122
OpaqueStorageTypeInfo(llvm::ArrayType *storage,
1123-
llvm::IntegerType *scalarType,
1123+
std::vector<llvm::IntegerType *> &&scalarTypes,
11241124
Size size,
11251125
SpareBitVector &&spareBits,
11261126
Alignment align)
11271127
: ScalarTypeInfo(storage, size, std::move(spareBits), align, IsPOD,
11281128
IsFixedSize),
1129-
ScalarType(scalarType)
1129+
ScalarTypes(std::move(scalarTypes))
11301130
{}
11311131

11321132
llvm::ArrayType *getStorageType() const {
@@ -1139,7 +1139,7 @@ namespace {
11391139
}
11401140

11411141
unsigned getExplosionSize() const override {
1142-
return 1;
1142+
return ScalarTypes.size();
11431143
}
11441144

11451145
void loadAsCopy(IRGenFunction &IGF, Address addr,
@@ -1149,8 +1149,18 @@ namespace {
11491149

11501150
void loadAsTake(IRGenFunction &IGF, Address addr,
11511151
Explosion &explosion) const override {
1152-
addr = IGF.Builder.CreateElementBitCast(addr, ScalarType);
1153-
explosion.add(IGF.Builder.CreateLoad(addr));
1152+
auto index = ScalarTypes.size();
1153+
for (auto scalarTy : ScalarTypes) {
1154+
addr = IGF.Builder.CreateElementBitCast(addr, scalarTy);
1155+
explosion.add(IGF.Builder.CreateLoad(addr));
1156+
--index;
1157+
// Advance to next scalar chunk.
1158+
if (index > 0) {
1159+
addr = IGF.Builder.CreateElementBitCast(addr, IGF.IGM.Int8Ty);
1160+
auto currentScalarTypeSize = Size(scalarTy->getIntegerBitWidth()/8);
1161+
addr = IGF.Builder.CreateConstByteArrayGEP(addr, currentScalarTypeSize);
1162+
}
1163+
}
11541164
}
11551165

11561166
void assign(IRGenFunction &IGF, Explosion &explosion, Address addr,
@@ -1160,13 +1170,26 @@ namespace {
11601170

11611171
void initialize(IRGenFunction &IGF, Explosion &explosion, Address addr,
11621172
bool isOutlined) const override {
1163-
addr = IGF.Builder.CreateElementBitCast(addr, ScalarType);
1164-
IGF.Builder.CreateStore(explosion.claimNext(), addr);
1173+
auto index = ScalarTypes.size();
1174+
for (auto scalarTy : ScalarTypes) {
1175+
addr = IGF.Builder.CreateElementBitCast(addr, scalarTy);
1176+
IGF.Builder.CreateStore(explosion.claimNext(), addr);
1177+
--index;
1178+
// Advance to next scalar chunk.
1179+
if (index > 0) {
1180+
addr = IGF.Builder.CreateElementBitCast(addr, IGF.IGM.Int8Ty);
1181+
auto currentScalarTypeSize = Size(scalarTy->getIntegerBitWidth()/8);
1182+
addr = IGF.Builder.CreateConstByteArrayGEP(addr, currentScalarTypeSize);
1183+
}
1184+
}
11651185
}
11661186

11671187
void reexplode(IRGenFunction &IGF, Explosion &sourceExplosion,
11681188
Explosion &targetExplosion) const override {
1169-
targetExplosion.add(sourceExplosion.claimNext());
1189+
for (auto scalarTy : ScalarTypes) {
1190+
(void)scalarTy;
1191+
targetExplosion.add(sourceExplosion.claimNext());
1192+
}
11701193
}
11711194

11721195
void copy(IRGenFunction &IGF, Explosion &sourceExplosion,
@@ -1176,11 +1199,11 @@ namespace {
11761199

11771200
void consume(IRGenFunction &IGF, Explosion &explosion,
11781201
Atomicity atomicity) const override {
1179-
explosion.claimNext();
1202+
(void)explosion.claimAll();
11801203
}
11811204

11821205
void fixLifetime(IRGenFunction &IGF, Explosion &explosion) const override {
1183-
explosion.claimNext();
1206+
(void)explosion.claimAll();
11841207
}
11851208

11861209
void destroy(IRGenFunction &IGF, Address address, SILType T,
@@ -1189,7 +1212,9 @@ namespace {
11891212
}
11901213

11911214
void getSchema(ExplosionSchema &schema) const override {
1192-
schema.add(ExplosionSchema::Element::forScalar(ScalarType));
1215+
for (auto scalarTy: ScalarTypes) {
1216+
schema.add(ExplosionSchema::Element::forScalar(scalarTy));
1217+
}
11931218
}
11941219

11951220
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
@@ -1202,14 +1227,20 @@ namespace {
12021227
EnumPayload &payload,
12031228
Explosion &source,
12041229
unsigned offset) const override {
1205-
payload.insertValue(IGF, source.claimNext(), offset);
1230+
for (auto scalarTy: ScalarTypes) {
1231+
payload.insertValue(IGF, source.claimNext(), offset);
1232+
offset += scalarTy->getIntegerBitWidth();
1233+
}
12061234
}
12071235

12081236
void unpackFromEnumPayload(IRGenFunction &IGF,
12091237
const EnumPayload &payload,
12101238
Explosion &target,
12111239
unsigned offset) const override {
1212-
target.add(payload.extractValue(IGF, ScalarType, offset));
1240+
for (auto scalarTy : ScalarTypes) {
1241+
target.add(payload.extractValue(IGF, scalarTy, offset));
1242+
offset += scalarTy->getIntegerBitWidth();
1243+
}
12131244
}
12141245
};
12151246

@@ -1946,10 +1977,28 @@ TypeConverter::getOpaqueStorageTypeInfo(Size size, Alignment align) {
19461977
// Use an [N x i8] array for storage, but load and store as a single iNNN
19471978
// scalar.
19481979
auto storageType = llvm::ArrayType::get(IGM.Int8Ty, size.getValue());
1949-
auto intType = llvm::IntegerType::get(IGM.getLLVMContext(),
1950-
size.getValueInBits());
1980+
1981+
// Create chunks of MAX_INT_BITS integer scalar types if neccessary.
1982+
std::vector<llvm::IntegerType*> scalarTypes;
1983+
Size chunkSize = size;
1984+
auto maxChunkSize = Size(llvm::IntegerType::MAX_INT_BITS/8);
1985+
while (chunkSize) {
1986+
if (chunkSize > maxChunkSize) {
1987+
auto intType = llvm::IntegerType::get(IGM.getLLVMContext(),
1988+
maxChunkSize.getValueInBits());
1989+
scalarTypes.push_back(intType);
1990+
chunkSize -= maxChunkSize;
1991+
continue;
1992+
}
1993+
auto intType = llvm::IntegerType::get(IGM.getLLVMContext(),
1994+
chunkSize.getValueInBits());
1995+
scalarTypes.push_back(intType);
1996+
chunkSize = Size(0);
1997+
}
1998+
19511999
// There are no spare bits in an opaque storage type.
1952-
auto type = new OpaqueStorageTypeInfo(storageType, intType, size,
2000+
auto type = new OpaqueStorageTypeInfo(storageType, std::move(scalarTypes),
2001+
size,
19532002
SpareBitVector::getConstant(size.getValueInBits(), false),
19542003
align);
19552004

0 commit comments

Comments
 (0)