Skip to content

Commit 2f263a9

Browse files
Merge pull request swiftlang#29858 from aschwaighofer/irgen_enum_utils_factor
IRGen: Factor some code related to enum generation
2 parents c14a2ee + 5d3a5ae commit 2f263a9

File tree

2 files changed

+138
-31
lines changed

2 files changed

+138
-31
lines changed

lib/IRGen/FixedTypeInfo.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,32 @@ class FixedTypeInfo : public TypeInfo {
239239
static bool classof(const TypeInfo *type) { return type->isFixedSize(); }
240240
};
241241

242+
llvm::Value *getFixedTypeEnumTagSinglePayload(
243+
IRGenFunction &IGF, llvm::Value *numEmptyCases, Address enumAddr,
244+
llvm::Value *size, Size fixedSize, unsigned fixedExtraInhabitantCount,
245+
llvm::function_ref<llvm::Value *(Address)> getExtraInhabitantIndex,
246+
bool isOutlined);
247+
242248
llvm::Value *getFixedTypeEnumTagSinglePayload(IRGenFunction &IGF,
243249
const FixedTypeInfo &fixedTI,
244250
llvm::Value *numEmptyCases,
245251
Address enumAddr,
246252
SILType T, bool isOutlined);
253+
void storeFixedTypeEnumTagSinglePayload(
254+
IRGenFunction &IGF, llvm::Value *whichCase, llvm::Value *numEmptyCases,
255+
Address enumAddr, llvm::Value *size, Size fixedSize,
256+
unsigned fixedExtraInhabitantCount,
257+
llvm::function_ref<void(llvm::Value *, Address)> storeExtraInhabitant,
258+
bool isOutlined);
259+
260+
llvm::Value *emitLoad1to4Bytes(IRGenFunction &IGF, Address from,
261+
llvm::Value *size);
262+
void emitStore1to4Bytes(IRGenFunction &IGF, Address to, llvm::Value *val,
263+
llvm::Value *size);
264+
265+
llvm::Value *emitGetTag(IRGenFunction &IGF, Address from, llvm::Value *size);
266+
void emitSetTag(IRGenFunction &IGF, Address to, llvm::Value *val,
267+
llvm::Value *size);
247268

248269
void storeFixedTypeEnumTagSinglePayload(IRGenFunction &IGF,
249270
const FixedTypeInfo &fixedTI,

lib/IRGen/GenType.cpp

Lines changed: 117 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -435,18 +435,11 @@ static llvm::Value *computeExtraTagBytes(IRGenFunction &IGF, IRBuilder &Builder,
435435
static void emitSpecializedMemOperation(
436436
IRGenFunction &IGF,
437437
llvm::function_ref<void(IRBuilder &, Size)> emitMemOpFn,
438-
llvm::Value *size) {
438+
llvm::Value *size,
439+
const std::array<Size, 4> &sizes) {
439440
auto &Ctx = IGF.IGM.getLLVMContext();
440441
auto &Builder = IGF.Builder;
441442

442-
// Sizes to try. Tested in order.
443-
const std::array<Size, 4> sizes = {
444-
Size(0),
445-
Size(1),
446-
Size(2),
447-
Size(4),
448-
};
449-
450443
// Block to jump to after successful match.
451444
auto *returnBB = llvm::BasicBlock::Create(Ctx);
452445

@@ -488,12 +481,13 @@ static void emitSpecializedMemOperation(
488481
Builder.emitBlock(returnBB);
489482
}
490483

491-
/// Emit a load of a \p size byte integer value zero extended to 4 bytes.
492-
/// \p size may be 0, 1, 2 or 4.
493-
static llvm::Value *emitGetTag(IRGenFunction &IGF,
494-
Address from,
495-
llvm::Value *size) {
484+
/// Emit a load of the \p size byte integer values zero extended to 4 bytes. \p
485+
/// size maybe any of the four values specified in the \p sizes array.
486+
static llvm::Value *emitLoadBytes(IRGenFunction &IGF, Address from,
487+
llvm::Value *size,
488+
const std::array<Size, 4> &sizes) {
496489
auto *phi = llvm::PHINode::Create(IGF.IGM.Int32Ty, 4);
490+
497491
emitSpecializedMemOperation(IGF,
498492
[=](IRBuilder &B, Size s) {
499493
if (s == Size(0)) {
@@ -507,16 +501,45 @@ static llvm::Value *emitGetTag(IRGenFunction &IGF,
507501
auto *val = B.CreateZExtOrTrunc(B.CreateLoad(addr), B.getInt32Ty());
508502
phi->addIncoming(val, B.GetInsertBlock());
509503
},
510-
size);
504+
size,
505+
sizes);
511506
IGF.Builder.Insert(phi);
512507
return phi;
513508
}
514509

515-
/// Emit a store of \p val truncated to \p size bytes.
510+
/// Emit a load of a \p size byte integer value zero extended to 4 bytes \p size
511+
/// may be 1, 2, 3, or 4.
512+
llvm::Value *irgen::emitLoad1to4Bytes(IRGenFunction &IGF, Address from,
513+
llvm::Value *size) {
514+
// Sizes to try. Tested in order.
515+
const std::array<Size, 4> sizes = {
516+
Size(1),
517+
Size(2),
518+
Size(3),
519+
Size(4),
520+
};
521+
return emitLoadBytes(IGF, from, size, sizes);
522+
}
523+
524+
/// Emit a load of a \p size byte integer value zero extended to 4 bytes.
516525
/// \p size may be 0, 1, 2 or 4.
517-
static void emitSetTag(IRGenFunction &IGF,
518-
Address to, llvm::Value *val,
519-
llvm::Value *size) {
526+
llvm::Value *irgen::emitGetTag(IRGenFunction &IGF, Address from,
527+
llvm::Value *size) {
528+
// Sizes to try. Tested in order.
529+
const std::array<Size, 4> sizes = {
530+
Size(0),
531+
Size(1),
532+
Size(2),
533+
Size(4),
534+
};
535+
return emitLoadBytes(IGF, from, size, sizes);
536+
}
537+
538+
/// Emit a store of \p val truncated to \p size bytes.
539+
/// \p size may be one of the entries in the \p sizes array.
540+
static void emitStoreBytes(IRGenFunction &IGF, Address to, llvm::Value *val,
541+
llvm::Value *size,
542+
const std::array<Size, 4> &sizes) {
520543
emitSpecializedMemOperation(IGF,
521544
[=](IRBuilder &B, Size s) {
522545
if (s == Size(0)) {
@@ -529,7 +552,37 @@ static void emitSetTag(IRGenFunction &IGF,
529552
Address addr = B.CreateBitCast(to, type->getPointerTo());
530553
B.CreateStore(trunc, addr);
531554
},
532-
size);
555+
size,
556+
sizes);
557+
}
558+
559+
/// Emit a store of \p val truncated to \p size bytes.
560+
/// \p size may be 1, 2, 3, or 4.
561+
void irgen::emitStore1to4Bytes(IRGenFunction &IGF, Address to, llvm::Value *val,
562+
llvm::Value *size) {
563+
// Sizes to try. Tested in order.
564+
const std::array<Size, 4> sizes = {
565+
Size(1),
566+
Size(2),
567+
Size(3),
568+
Size(4),
569+
};
570+
emitStoreBytes(IGF, to, val, size, sizes);
571+
}
572+
573+
/// Emit a store of \p val truncated to \p size bytes.
574+
/// \p size may be 0, 1, 2 or 4.
575+
void irgen::emitSetTag(IRGenFunction &IGF,
576+
Address to, llvm::Value *val,
577+
llvm::Value *size) {
578+
// Sizes to try. Tested in order.
579+
const std::array<Size, 4> sizes = {
580+
Size(0),
581+
Size(1),
582+
Size(2),
583+
Size(4),
584+
};
585+
emitStoreBytes(IGF, to, val, size, sizes);
533586
}
534587

535588
llvm::Value *FixedTypeInfo::getEnumTagSinglePayload(IRGenFunction &IGF,
@@ -547,14 +600,30 @@ llvm::Value *irgen::getFixedTypeEnumTagSinglePayload(IRGenFunction &IGF,
547600
Address enumAddr,
548601
SILType T,
549602
bool isOutlined) {
603+
auto *size = ti.getSize(IGF, T);
604+
Size fixedSize = ti.getFixedSize();
605+
auto fixedExtraInhabitantCount = ti.getFixedExtraInhabitantCount(IGF.IGM);
606+
607+
return getFixedTypeEnumTagSinglePayload(
608+
IGF, numEmptyCases, enumAddr, size, fixedSize, fixedExtraInhabitantCount,
609+
[&](Address addr) -> llvm::Value * {
610+
return ti.getExtraInhabitantIndex(IGF, addr, T, false);
611+
},
612+
isOutlined);
613+
}
614+
615+
llvm::Value *irgen::getFixedTypeEnumTagSinglePayload(
616+
IRGenFunction &IGF, llvm::Value *numEmptyCases, Address enumAddr,
617+
llvm::Value *size, Size fixedSize, unsigned fixedExtraInhabitantCount,
618+
llvm::function_ref<llvm::Value *(Address)> getExtraInhabitantIndex,
619+
bool isOutlined) {
620+
550621
auto &IGM = IGF.IGM;
551622
auto &Ctx = IGF.IGM.getLLVMContext();
552623
auto &Builder = IGF.Builder;
553624

554-
auto *size = ti.getSize(IGF, T);
555-
Size fixedSize = ti.getFixedSize();
556625
auto *numExtraInhabitants =
557-
llvm::ConstantInt::get(IGM.Int32Ty, ti.getFixedExtraInhabitantCount(IGM));
626+
llvm::ConstantInt::get(IGM.Int32Ty, fixedExtraInhabitantCount);
558627

559628
auto *zero = llvm::ConstantInt::get(IGM.Int32Ty, 0U);
560629
auto *one = llvm::ConstantInt::get(IGM.Int32Ty, 1U);
@@ -632,8 +701,8 @@ llvm::Value *irgen::getFixedTypeEnumTagSinglePayload(IRGenFunction &IGF,
632701
Builder.emitBlock(noExtraTagBitsBB);
633702
// If there are extra inhabitants, see whether the payload is valid.
634703
llvm::Value *result0;
635-
if (ti.mayHaveExtraInhabitants(IGM)) {
636-
result0 = ti.getExtraInhabitantIndex(IGF, enumAddr, T, false);
704+
if (fixedExtraInhabitantCount > 0) {
705+
result0 = getExtraInhabitantIndex(enumAddr);
637706
noExtraTagBitsBB = Builder.GetInsertBlock();
638707
} else {
639708
result0 = llvm::ConstantInt::getSigned(IGM.Int32Ty, -1);
@@ -671,6 +740,26 @@ void irgen::storeFixedTypeEnumTagSinglePayload(IRGenFunction &IGF,
671740
Address enumAddr,
672741
SILType T,
673742
bool isOutlined) {
743+
auto fixedSize = ti.getFixedSize();
744+
auto *size = ti.getSize(IGF, T);
745+
auto fixedExtraInhabitantCount = ti.getFixedExtraInhabitantCount(IGF.IGM);
746+
storeFixedTypeEnumTagSinglePayload(
747+
IGF, whichCase, numEmptyCases, enumAddr, size, fixedSize,
748+
fixedExtraInhabitantCount,
749+
[&](llvm::Value *nonPayloadElementIndex, Address enumAddr) {
750+
ti.storeExtraInhabitant(IGF, nonPayloadElementIndex, enumAddr, T,
751+
/*outlined*/ false);
752+
},
753+
isOutlined);
754+
}
755+
756+
void irgen::storeFixedTypeEnumTagSinglePayload(
757+
IRGenFunction &IGF, llvm::Value *whichCase, llvm::Value *numEmptyCases,
758+
Address enumAddr, llvm::Value *size, Size fixedSize,
759+
unsigned fixedExtraInhabitantCount,
760+
llvm::function_ref<void(llvm::Value *, Address)> storeExtraInhabitant,
761+
bool isOutlined) {
762+
674763
auto &IGM = IGF.IGM;
675764
auto &Ctx = IGF.IGM.getLLVMContext();
676765
auto &Builder = IGF.Builder;
@@ -681,15 +770,13 @@ void irgen::storeFixedTypeEnumTagSinglePayload(IRGenFunction &IGF,
681770
auto *four = llvm::ConstantInt::get(int32Ty, 4U);
682771
auto *eight = llvm::ConstantInt::get(int32Ty, 8U);
683772

684-
auto fixedSize = ti.getFixedSize();
685773

686774
Address valueAddr = Builder.CreateElementBitCast(enumAddr, IGM.Int8Ty);
687775
Address extraTagBitsAddr =
688776
Builder.CreateConstByteArrayGEP(valueAddr, fixedSize);
689777

690778
auto *numExtraInhabitants =
691-
llvm::ConstantInt::get(IGM.Int32Ty, ti.getFixedExtraInhabitantCount(IGM));
692-
auto *size = ti.getSize(IGF, T);
779+
llvm::ConstantInt::get(IGM.Int32Ty, fixedExtraInhabitantCount);
693780

694781
// Do we need extra tag bytes.
695782
auto *entryBB = Builder.GetInsertBlock();
@@ -731,11 +818,10 @@ void irgen::storeFixedTypeEnumTagSinglePayload(IRGenFunction &IGF,
731818
Builder.CreateCondBr(isPayload, returnBB, storeInhabitantBB);
732819

733820
Builder.emitBlock(storeInhabitantBB);
734-
if (ti.mayHaveExtraInhabitants(IGM)) {
821+
if (fixedExtraInhabitantCount > 0) {
735822
// Store an index in the range [0..ElementsWithNoPayload-1].
736823
auto *nonPayloadElementIndex = Builder.CreateSub(whichCase, one);
737-
ti.storeExtraInhabitant(IGF, nonPayloadElementIndex, enumAddr, T,
738-
/*outlined*/ false);
824+
storeExtraInhabitant(nonPayloadElementIndex, enumAddr);
739825
}
740826
Builder.CreateBr(returnBB);
741827

0 commit comments

Comments
 (0)