Skip to content

Commit 5634280

Browse files
committed
Use the inline value buffer for allocate/project/deallocateValueBuffer functions
Also handle fixed size types.
1 parent 7092262 commit 5634280

File tree

1 file changed

+153
-32
lines changed

1 file changed

+153
-32
lines changed

lib/IRGen/GenOpaque.cpp

Lines changed: 153 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/Support/raw_ostream.h"
2525
#include "llvm/IR/DerivedTypes.h"
2626

27+
#include "FixedTypeInfo.h"
2728
#include "IRGenFunction.h"
2829
#include "IRGenModule.h"
2930
#include "ProtocolInfo.h"
@@ -948,41 +949,161 @@ void irgen::emitDestroyCall(IRGenFunction &IGF, llvm::Value *metadata,
948949

949950
Address irgen::emitAllocateValueInBuffer(IRGenFunction &IGF, SILType type,
950951
Address buffer) {
951-
auto *size = emitLoadOfSize(IGF, type);
952-
auto *alignMask = emitLoadOfAlignmentMask(IGF, type);
953-
// TODO: check whether we fit in the inline value buffer.
954-
auto valueAddr = IGF.emitAllocRawCall(size, alignMask, "outline.ValueBuffer");
955-
IGF.Builder.CreateStore(
956-
valueAddr,
957-
Address(IGF.Builder.CreateBitCast(buffer.getAddress(),
958-
valueAddr->getType()->getPointerTo()),
959-
Alignment(1)));
960-
valueAddr =
961-
IGF.Builder.CreateBitCast(valueAddr, IGF.IGM.getStoragePointerType(type));
962-
return Address(valueAddr, Alignment(1));
963-
964-
}
965-
966-
Address irgen::emitProjectValueInBuffer(IRGenFunction &IGF,
967-
SILType type,
968-
Address buffer) {
969-
// TODO: check whether we fit in the inline value buffer.
970-
auto ptr = IGF.Builder.CreateLoad(Address(
971-
IGF.Builder.CreateBitCast(buffer.getAddress(), IGF.IGM.Int8PtrPtrTy),
972-
Alignment(1)));
973-
auto valueAddr =
974-
IGF.Builder.CreateBitCast(ptr, IGF.IGM.getStoragePointerType(type));
975-
return Address(valueAddr, Alignment(1));
952+
// Handle FixedSize types.
953+
auto &IGM = IGF.IGM;
954+
auto storagePtrTy = IGM.getStoragePointerType(type);
955+
if (auto *fixedTI = dyn_cast<FixedTypeInfo>(&IGF.getTypeInfo(type))) {
956+
auto packing = fixedTI->getFixedPacking(IGM);
957+
958+
// Inline representation.
959+
if (packing == FixedPacking::OffsetZero) {
960+
return Address(
961+
IGF.Builder.CreateBitCast(buffer.getAddress(), storagePtrTy),
962+
buffer.getAlignment());
963+
}
964+
965+
// Outline representation.
966+
assert(packing == FixedPacking::Allocate && "Expect non dynamic packing");
967+
auto size = fixedTI->getStaticSize(IGM);
968+
auto alignMask = fixedTI->getStaticAlignmentMask(IGM);
969+
auto valueAddr =
970+
IGF.emitAllocRawCall(size, alignMask, "outline.ValueBuffer");
971+
IGF.Builder.CreateStore(
972+
valueAddr,
973+
Address(IGF.Builder.CreateBitCast(buffer.getAddress(),
974+
valueAddr->getType()->getPointerTo()),
975+
buffer.getAlignment()));
976+
return Address(IGF.Builder.CreateBitCast(valueAddr, storagePtrTy),
977+
buffer.getAlignment());
978+
}
979+
980+
// Dynamic packing.
981+
llvm::Value *isInline = emitLoadOfIsInline(IGF, type);
982+
auto *outlineBB = IGF.createBasicBlock("outline.allocateValueInBuffer");
983+
auto *doneBB = IGF.createBasicBlock("done");
984+
llvm::Value *addressInline, *addressOutline;
985+
auto *origBB = IGF.Builder.GetInsertBlock();
986+
addressInline = IGF.Builder.CreateBitCast(buffer.getAddress(), storagePtrTy);
987+
IGF.Builder.CreateCondBr(isInline, doneBB, outlineBB);
988+
989+
IGF.Builder.emitBlock(outlineBB);
990+
{
991+
ConditionalDominanceScope scope(IGF);
992+
auto *size = emitLoadOfSize(IGF, type);
993+
auto *alignMask = emitLoadOfAlignmentMask(IGF, type);
994+
auto valueAddr =
995+
IGF.emitAllocRawCall(size, alignMask, "outline.ValueBuffer");
996+
IGF.Builder.CreateStore(
997+
valueAddr,
998+
Address(IGF.Builder.CreateBitCast(buffer.getAddress(),
999+
valueAddr->getType()->getPointerTo()),
1000+
Alignment(1)));
1001+
addressOutline = IGF.Builder.CreateBitCast(valueAddr, storagePtrTy);
1002+
IGF.Builder.CreateBr(doneBB);
1003+
}
1004+
1005+
IGF.Builder.emitBlock(doneBB);
1006+
auto *addressOfValue = IGF.Builder.CreatePHI(storagePtrTy, 2);
1007+
addressOfValue->addIncoming(addressInline, origBB);
1008+
addressOfValue->addIncoming(addressOutline, outlineBB);
1009+
1010+
return Address(addressOfValue, Alignment(1));
1011+
}
1012+
1013+
Address irgen::emitProjectValueInBuffer(IRGenFunction &IGF, SILType type,
1014+
Address buffer) {
1015+
// Handle FixedSize types.
1016+
auto &IGM = IGF.IGM;
1017+
auto storagePtrTy = IGM.getStoragePointerType(type);
1018+
if (auto *fixedTI = dyn_cast<FixedTypeInfo>(&IGF.getTypeInfo(type))) {
1019+
auto packing = fixedTI->getFixedPacking(IGM);
1020+
1021+
// Inline representation.
1022+
if (packing == FixedPacking::OffsetZero) {
1023+
return Address(
1024+
IGF.Builder.CreateBitCast(buffer.getAddress(), storagePtrTy),
1025+
buffer.getAlignment());
1026+
}
1027+
1028+
// Outline representation.
1029+
assert(packing == FixedPacking::Allocate && "Expect non dynamic packing");
1030+
auto valueAddr = IGF.Builder.CreateLoad(
1031+
Address(IGF.Builder.CreateBitCast(buffer.getAddress(),
1032+
storagePtrTy->getPointerTo()),
1033+
buffer.getAlignment()));
1034+
return Address(IGF.Builder.CreateBitCast(valueAddr, storagePtrTy),
1035+
buffer.getAlignment());
1036+
}
1037+
1038+
// Dynamic packing.
1039+
llvm::Value *isInline = emitLoadOfIsInline(IGF, type);
1040+
auto *outlineBB = IGF.createBasicBlock("outline.projectValueInBuffer");
1041+
auto *doneBB = IGF.createBasicBlock("done");
1042+
llvm::Value *addressInline, *addressOutline;
1043+
auto *origBB = IGF.Builder.GetInsertBlock();
1044+
addressInline = IGF.Builder.CreateBitCast(buffer.getAddress(), storagePtrTy);
1045+
1046+
IGF.Builder.CreateCondBr(isInline, doneBB, outlineBB);
1047+
1048+
IGF.Builder.emitBlock(outlineBB);
1049+
{
1050+
auto ptr = IGF.Builder.CreateLoad(
1051+
Address(IGF.Builder.CreateBitCast(buffer.getAddress(),
1052+
storagePtrTy->getPointerTo()),
1053+
Alignment(1)));
1054+
addressOutline = IGF.Builder.CreateBitCast(ptr, storagePtrTy);
1055+
IGF.Builder.CreateBr(doneBB);
1056+
}
1057+
1058+
IGF.Builder.emitBlock(doneBB);
1059+
auto *addressOfValue = IGF.Builder.CreatePHI(storagePtrTy, 2);
1060+
addressOfValue->addIncoming(addressInline, origBB);
1061+
addressOfValue->addIncoming(addressOutline, outlineBB);
1062+
1063+
return Address(addressOfValue, Alignment(1));
9761064
}
9771065

9781066
void irgen::emitDeallocateValueInBuffer(IRGenFunction &IGF,
9791067
SILType type,
9801068
Address buffer) {
981-
auto *size = emitLoadOfSize(IGF, type);
982-
auto *alignMask = emitLoadOfAlignmentMask(IGF, type);
983-
auto *ptr = IGF.Builder.CreateLoad(Address(
984-
IGF.Builder.CreateBitCast(buffer.getAddress(), IGF.IGM.Int8PtrPtrTy),
985-
Alignment(1)));
986-
// TODO: check whether we fit in the inline value buffer.
987-
IGF.emitDeallocRawCall(ptr, size, alignMask);
1069+
// Handle FixedSize types.
1070+
auto &IGM = IGF.IGM;
1071+
if (auto *fixedTI = dyn_cast<FixedTypeInfo>(&IGF.getTypeInfo(type))) {
1072+
auto packing = fixedTI->getFixedPacking(IGM);
1073+
1074+
// Inline representation.
1075+
if (packing == FixedPacking::OffsetZero)
1076+
return;
1077+
1078+
// Outline representation.
1079+
assert(packing == FixedPacking::Allocate && "Expect non dynamic packing");
1080+
auto size = fixedTI->getStaticSize(IGM);
1081+
auto alignMask = fixedTI->getStaticAlignmentMask(IGM);
1082+
auto *ptr = IGF.Builder.CreateLoad(Address(
1083+
IGF.Builder.CreateBitCast(buffer.getAddress(), IGM.Int8PtrPtrTy),
1084+
buffer.getAlignment()));
1085+
IGF.emitDeallocRawCall(ptr, size, alignMask);
1086+
return;
1087+
}
1088+
1089+
// Dynamic packing.
1090+
llvm::Value *isInline = emitLoadOfIsInline(IGF, type);
1091+
auto *outlineBB = IGF.createBasicBlock("outline.projectValueInBuffer");
1092+
auto *doneBB = IGF.createBasicBlock("done");
1093+
1094+
IGF.Builder.CreateCondBr(isInline, doneBB, outlineBB);
1095+
1096+
IGF.Builder.emitBlock(outlineBB);
1097+
{
1098+
ConditionalDominanceScope scope(IGF);
1099+
auto *size = emitLoadOfSize(IGF, type);
1100+
auto *alignMask = emitLoadOfAlignmentMask(IGF, type);
1101+
auto *ptr = IGF.Builder.CreateLoad(Address(
1102+
IGF.Builder.CreateBitCast(buffer.getAddress(), IGM.Int8PtrPtrTy),
1103+
buffer.getAlignment()));
1104+
IGF.emitDeallocRawCall(ptr, size, alignMask);
1105+
IGF.Builder.CreateBr(doneBB);
1106+
}
1107+
1108+
IGF.Builder.emitBlock(doneBB);
9881109
}

0 commit comments

Comments
 (0)