Skip to content

IRGen: Use any field of fixed-layout structs for extra inhabitants. #18630

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lib/IRGen/FixedTypeInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ class FixedTypeInfo : public TypeInfo {
/// Map an extra inhabitant representation in memory to a unique 31-bit
/// identifier, and map a valid representation of the type to -1.
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
Address src, SILType T) const override {
Address src, SILType T,
bool isOutlined) const override {
return getSpareBitExtraInhabitantIndex(IGF, src);
}

Expand All @@ -180,7 +181,8 @@ class FixedTypeInfo : public TypeInfo {
/// to memory.
void storeExtraInhabitant(IRGenFunction &IGF,
llvm::Value *index,
Address dest, SILType T) const override {
Address dest, SILType T,
bool isOutlined) const override {
storeSpareBitExtraInhabitant(IGF, index, dest);
}

Expand Down
58 changes: 38 additions & 20 deletions lib/IRGen/GenEnum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,8 @@ namespace {
}

llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
Address src, SILType T)
Address src, SILType T,
bool isOutlined)
const override {
if (!getSingleton()) {
// Any empty value is a valid value.
Expand All @@ -650,19 +651,22 @@ namespace {

return getSingleton()->getExtraInhabitantIndex(IGF,
getSingletonAddress(IGF, src),
getSingletonType(IGF.IGM, T));
getSingletonType(IGF.IGM, T),
isOutlined);
}

void storeExtraInhabitant(IRGenFunction &IGF,
llvm::Value *index,
Address dest, SILType T) const override {
Address dest, SILType T,
bool isOutlined) const override {
if (!getSingleton()) {
// Nothing to store for empty singletons.
return;
}
getSingleton()->storeExtraInhabitant(IGF, index,
getSingletonAddress(IGF, dest),
getSingletonType(IGF.IGM, T));
getSingletonType(IGF.IGM, T),
isOutlined);
}

unsigned getFixedExtraInhabitantCount(IRGenModule &IGM) const override {
Expand Down Expand Up @@ -1014,7 +1018,8 @@ namespace {
}

llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
Address src, SILType T)
Address src, SILType T,
bool isOutlined)
const override {
auto &C = IGF.IGM.getLLVMContext();

Expand Down Expand Up @@ -1044,7 +1049,8 @@ namespace {

void storeExtraInhabitant(IRGenFunction &IGF,
llvm::Value *index,
Address dest, SILType T) const override {
Address dest, SILType T,
bool isOutlined) const override {
auto &C = IGF.IGM.getLLVMContext();
auto payloadTy = llvm::IntegerType::get(C,
cast<FixedTypeInfo>(TI)->getFixedSize().getValueInBits());
Expand Down Expand Up @@ -1119,13 +1125,15 @@ namespace {
}

llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
Address src, SILType T) const override {
Address src, SILType T,
bool isOutlined) const override {
llvm_unreachable("no extra inhabitants");
}

void storeExtraInhabitant(IRGenFunction &IGF,
llvm::Value *index,
Address dest, SILType T) const override {
Address dest, SILType T,
bool isOutlined) const override {
llvm_unreachable("no extra inhabitants");
}

Expand Down Expand Up @@ -2915,11 +2923,13 @@ namespace {

llvm::Value *
getExtraInhabitantIndex(IRGenFunction &IGF,
Address src, SILType T) const override {
Address src, SILType T,
bool isOutlined) const override {
auto payload = projectPayloadData(IGF, src);
llvm::Value *index
= getPayloadTypeInfo().getExtraInhabitantIndex(IGF, payload,
getPayloadType(IGF.IGM, T));
getPayloadType(IGF.IGM, T),
isOutlined);

// Offset the payload extra inhabitant index by the number of inhabitants
// we used. If less than zero, it's a valid value of the enum type.
Expand All @@ -2935,14 +2945,16 @@ namespace {

void storeExtraInhabitant(IRGenFunction &IGF,
llvm::Value *index,
Address dest, SILType T) const override {
Address dest, SILType T,
bool isOutlined) const override {
// Offset the index to skip the extra inhabitants we used.
index = IGF.Builder.CreateAdd(index,
llvm::ConstantInt::get(IGF.IGM.Int32Ty, ElementsWithNoPayload.size()));

auto payload = projectPayloadData(IGF, dest);
getPayloadTypeInfo().storeExtraInhabitant(IGF, index, payload,
getPayloadType(IGF.IGM, T));
getPayloadType(IGF.IGM, T),
isOutlined);
}

APInt
Expand Down Expand Up @@ -4811,14 +4823,16 @@ namespace {

llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
Address src,
SILType T) const override {
SILType T,
bool isOutlined) const override {
llvm_unreachable("extra inhabitants for multi-payload enums not implemented");
}

void storeExtraInhabitant(IRGenFunction &IGF,
llvm::Value *index,
Address dest,
SILType T) const override {
SILType T,
bool isOutlined) const override {
llvm_unreachable("extra inhabitants for multi-payload enums not implemented");
}

Expand Down Expand Up @@ -5204,14 +5218,16 @@ namespace {

llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
Address src,
SILType T) const override {
SILType T,
bool isOutlined) const override {
return emitGetExtraInhabitantIndexCall(IGF, T, src);
}

void storeExtraInhabitant(IRGenFunction &IGF,
llvm::Value *index,
Address dest,
SILType T) const override {
SILType T,
bool isOutlined) const override {
emitStoreExtraInhabitantCall(IGF, T, index, dest);
}

Expand Down Expand Up @@ -5436,14 +5452,16 @@ namespace {
}
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
Address src,
SILType T) const override {
return Strategy.getExtraInhabitantIndex(IGF, src, T);
SILType T,
bool isOutlined) const override {
return Strategy.getExtraInhabitantIndex(IGF, src, T, isOutlined);
}
void storeExtraInhabitant(IRGenFunction &IGF,
llvm::Value *index,
Address dest,
SILType T) const override {
return Strategy.storeExtraInhabitant(IGF, index, dest, T);
SILType T,
bool isOutlined) const override {
return Strategy.storeExtraInhabitant(IGF, index, dest, T, isOutlined);
}
bool isSingleRetainablePointer(ResilienceExpansion expansion,
ReferenceCounting *rc) const override {
Expand Down
6 changes: 4 additions & 2 deletions lib/IRGen/GenEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,11 +375,13 @@ class EnumImplStrategy {

virtual llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
Address src,
SILType T) const = 0;
SILType T,
bool isOutlined) const = 0;
virtual void storeExtraInhabitant(IRGenFunction &IGF,
llvm::Value *index,
Address dest,
SILType T) const = 0;
SILType T,
bool isOutlined) const = 0;

/// \group Delegated FixedTypeInfo operations

Expand Down
19 changes: 11 additions & 8 deletions lib/IRGen/GenExistential.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,20 +554,21 @@ namespace {
}

llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src,
SILType T)
SILType T, bool isOutlined)
const override {
// NB: We assume that the witness table slots are zero if an extra
// inhabitant is stored in the container.
src = projectValue(IGF, src);
return asDerived().getValueTypeInfoForExtraInhabitants(IGF.IGM)
.getExtraInhabitantIndex(IGF, src, SILType());
.getExtraInhabitantIndex(IGF, src, SILType(), isOutlined);
}

void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index,
Address dest, SILType T) const override {
Address dest, SILType T, bool isOutlined)
const override {
Address valueDest = projectValue(IGF, dest);
asDerived().getValueTypeInfoForExtraInhabitants(IGF.IGM)
.storeExtraInhabitant(IGF, index, valueDest, SILType());
.storeExtraInhabitant(IGF, index, valueDest, SILType(), isOutlined);
}

APInt getFixedExtraInhabitantMask(IRGenModule &IGM) const override {
Expand Down Expand Up @@ -615,23 +616,25 @@ namespace {
} \
} \
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, \
SILType T) const override { \
SILType T, bool isOutlined) \
const override { \
Address valueSrc = projectValue(IGF, src); \
if (shouldStoreExtraInhabitantsInRef(IGF.IGM)) { \
return IGF.getReferenceStorageExtraInhabitantIndex(valueSrc, \
ReferenceOwnership::Name, Refcounting); \
} else { \
return Super::getExtraInhabitantIndex(IGF, src, T); \
return Super::getExtraInhabitantIndex(IGF, src, T, isOutlined); \
} \
} \
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, \
Address dest, SILType T) const override { \
Address dest, SILType T, bool isOutlined) \
const override { \
Address valueDest = projectValue(IGF, dest); \
if (shouldStoreExtraInhabitantsInRef(IGF.IGM)) { \
return IGF.storeReferenceStorageExtraInhabitant(index, valueDest, \
ReferenceOwnership::Name, Refcounting); \
} else { \
return Super::storeExtraInhabitant(IGF, index, dest, T); \
return Super::storeExtraInhabitant(IGF, index, dest, T, isOutlined); \
} \
} \
APInt getFixedExtraInhabitantMask(IRGenModule &IGM) const override { \
Expand Down
11 changes: 7 additions & 4 deletions lib/IRGen/GenFunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,14 @@ namespace {
}

llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src,
SILType T)
SILType T, bool isOutlined)
const override {
return getFunctionPointerExtraInhabitantIndex(IGF, src);
}

void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index,
Address dest, SILType T) const override {
Address dest, SILType T, bool isOutlined)
const override {
return storeFunctionPointerExtraInhabitant(IGF, index, dest);
}
};
Expand Down Expand Up @@ -411,7 +412,8 @@ namespace {
}

llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src,
SILType T) const override {
SILType T, bool isOutlined)
const override {
src = projectFunction(IGF, src);
return getFunctionPointerExtraInhabitantIndex(IGF, src);
}
Expand All @@ -425,7 +427,8 @@ namespace {
}

void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index,
Address dest, SILType T) const override {
Address dest, SILType T, bool isOutlined)
const override {
dest = projectFunction(IGF, dest);
return storeFunctionPointerExtraInhabitant(IGF, index, dest);
}
Expand Down
17 changes: 11 additions & 6 deletions lib/IRGen/GenHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,15 @@ namespace {
ReferenceCounting::Nativeness); \
} \
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, \
SILType T) const override { \
SILType T, bool isOutlined) \
const override { \
return IGF.getReferenceStorageExtraInhabitantIndex(src, \
ReferenceOwnership::Name, \
ReferenceCounting::Nativeness); \
} \
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, \
Address dest, SILType T) const override { \
Address dest, SILType T, bool isOutlined) \
const override { \
return IGF.storeReferenceStorageExtraInhabitant(index, dest, \
ReferenceOwnership::Name, \
ReferenceCounting::Nativeness); \
Expand Down Expand Up @@ -166,13 +168,15 @@ namespace {
ReferenceCounting::Nativeness); \
} \
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, \
SILType T) const override { \
SILType T, bool isOutlined) \
const override { \
return IGF.getReferenceStorageExtraInhabitantIndex(src, \
ReferenceOwnership::Name, \
ReferenceCounting::Nativeness); \
} \
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, \
Address dest, SILType T) const override { \
Address dest, SILType T, bool isOutlined) \
const override { \
return IGF.storeReferenceStorageExtraInhabitant(index, dest, \
ReferenceOwnership::Name, \
ReferenceCounting::Nativeness); \
Expand Down Expand Up @@ -217,12 +221,13 @@ namespace {
index + IsOptional, 0); \
} \
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, \
SILType T) \
SILType T, bool isOutlined) \
const override { \
return getHeapObjectExtraInhabitantIndex(IGF, src); \
} \
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, \
Address dest, SILType T) const override { \
Address dest, SILType T, bool isOutlined) \
const override { \
return storeHeapObjectExtraInhabitant(IGF, index, dest); \
} \
};
Expand Down
6 changes: 4 additions & 2 deletions lib/IRGen/GenObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,8 @@ namespace {
return APInt(bits, 0);
}
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src,
SILType T) const override {
SILType T,
bool isOutlined) const override {
src = IGF.Builder.CreateBitCast(src, IGF.IGM.SizeTy->getPointerTo());
auto val = IGF.Builder.CreateLoad(src);
auto isNonzero = IGF.Builder.CreateICmpNE(val,
Expand All @@ -288,7 +289,8 @@ namespace {
return IGF.Builder.CreateSExt(isNonzero, IGF.IGM.Int32Ty);
}
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index,
Address dest, SILType T) const override {
Address dest, SILType T, bool isOutlined)
const override {
// There's only one extra inhabitant, 0.
dest = IGF.Builder.CreateBitCast(dest, IGF.IGM.SizeTy->getPointerTo());
IGF.Builder.CreateStore(llvm::ConstantInt::get(IGF.IGM.SizeTy, 0), dest);
Expand Down
Loading