mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
IRGen: Forward spare bits through aggregates.
When doing struct layout for fixed-layout structs or tuples, combine the spare bit masks of their elements to form the spare bit mask of the aggregate, treating padding between elements as spare bits as well.
For now, disable using these spare bits to form extra inhabitants for structs and tuples; we would need additional runtime work to expose these extra inhabitants for correct generic runtime behavior. This puts us in a weird situation where 'enum { case A(Struct), B, C }' spills a bit but 'enum { case A(Struct), B(Struct), C }' doesn't, but the work to make the former happen isn't immediately critical for String optimization.
Swift SVN r12165
This commit is contained in:
@@ -132,8 +132,10 @@ namespace {
|
||||
public:
|
||||
// FIXME: Spare bits between struct members.
|
||||
LoadableStructTypeInfo(unsigned numFields, llvm::Type *T, Size size,
|
||||
llvm::BitVector spareBits,
|
||||
Alignment align, IsPOD_t isPOD)
|
||||
: StructTypeInfoBase(numFields, T, size, llvm::BitVector{}, align, isPOD)
|
||||
: StructTypeInfoBase(numFields, T, size, std::move(spareBits),
|
||||
align, isPOD)
|
||||
{}
|
||||
|
||||
bool isIndirectArgument(ExplosionKind kind) const override { return false; }
|
||||
@@ -147,6 +149,14 @@ namespace {
|
||||
Nothing_t getNonFixedOffsets(IRGenFunction &IGF) const {
|
||||
return Nothing;
|
||||
}
|
||||
|
||||
// FIXME: Suppress use of extra inhabitants for single-payload enum layout
|
||||
// until we're ready to handle the runtime logic for exporting extra
|
||||
// inhabitants through generic structs.
|
||||
bool mayHaveExtraInhabitants(IRGenModule&) const override { return false; }
|
||||
unsigned getFixedExtraInhabitantCount(IRGenModule&) const override {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/// A type implementation for non-loadable but fixed-size struct types.
|
||||
@@ -157,13 +167,23 @@ namespace {
|
||||
public:
|
||||
// FIXME: Spare bits between struct members.
|
||||
FixedStructTypeInfo(unsigned numFields, llvm::Type *T, Size size,
|
||||
llvm::BitVector spareBits,
|
||||
Alignment align, IsPOD_t isPOD)
|
||||
: StructTypeInfoBase(numFields, T, size, llvm::BitVector{}, align, isPOD)
|
||||
: StructTypeInfoBase(numFields, T, size, std::move(spareBits), align,
|
||||
isPOD)
|
||||
{}
|
||||
Nothing_t getNonFixedOffsets(IRGenFunction &IGF, CanType T) const {
|
||||
return Nothing;
|
||||
}
|
||||
Nothing_t getNonFixedOffsets(IRGenFunction &IGF) const { return Nothing; }
|
||||
|
||||
// FIXME: Suppress use of extra inhabitants for single-payload enum layout
|
||||
// until we're ready to handle the runtime logic for exporting extra
|
||||
// inhabitants through generic structs.
|
||||
bool mayHaveExtraInhabitants(IRGenModule&) const override { return false; }
|
||||
unsigned getFixedExtraInhabitantCount(IRGenModule&) const override {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/// Find the beginning of the field offset vector in a struct's metadata.
|
||||
@@ -304,6 +324,7 @@ namespace {
|
||||
const StructLayout &layout) {
|
||||
return create<LoadableStructTypeInfo>(fields, layout.getType(),
|
||||
layout.getSize(),
|
||||
layout.getSpareBits(),
|
||||
layout.getAlignment(),
|
||||
layout.isKnownPOD());
|
||||
}
|
||||
@@ -312,6 +333,7 @@ namespace {
|
||||
const StructLayout &layout) {
|
||||
return create<FixedStructTypeInfo>(fields, layout.getType(),
|
||||
layout.getSize(),
|
||||
layout.getSpareBits(),
|
||||
layout.getAlignment(),
|
||||
layout.isKnownPOD());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user