Skip to content

Commit f0f78a1

Browse files
committed
[sil] Templatize base class of FieldIndexCacheBase.
Previously FieldIndexCacheBase only had a parent class of SingleValueInstruction. I need to be able to in certain cases shim in a SingleValueInstruction subclass as a parent class instead. In my case it is to imbue ownership forwarding on StructExtractInst. This commit itself doesn't make that change and instead just always templatizes using SingleValueInstruction.
1 parent 8d479f1 commit f0f78a1

File tree

3 files changed

+48
-12
lines changed

3 files changed

+48
-12
lines changed

include/swift/Basic/InlineBitfield.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,32 @@ namespace swift {
8181
LLVM_PACKED_END \
8282
static_assert(sizeof(T##Bitfield) <= 8, "Bitfield overflow")
8383

84+
/// Define a full bitfield for type 'T' that uses all of the remaining bits in
85+
/// the inline bitfield. We allow for 'T' to have a single generic parameter.
86+
///
87+
/// For optimal code gen, place naturally sized fields at the end, with the
88+
/// largest naturally sized field at the very end. For example:
89+
///
90+
/// SWIFT_INLINE_BITFIELD_FULL(Foo, Bar, 1+8+16,
91+
/// flag : 1,
92+
/// : NumPadBits, // pad the center, not the end
93+
/// x : 8,
94+
/// y : 16
95+
/// );
96+
///
97+
/// NOTE: All instances of Foo will access via the same bitfield entry even if
98+
/// they differ in the templated value!
99+
#define SWIFT_INLINE_BITFIELD_FULL_TEMPLATE(T, U, C, ...) \
100+
LLVM_PACKED_START \
101+
class T##Bitfield { \
102+
template <typename TTy> \
103+
friend class T; \
104+
enum { NumPadBits = 64 - (Num##U##Bits + (C)) }; \
105+
uint64_t : Num##U##Bits, __VA_ARGS__; \
106+
} T; \
107+
LLVM_PACKED_END \
108+
static_assert(sizeof(T##Bitfield) <= 8, "Bitfield overflow")
109+
84110
/// Define an empty bitfield for type 'T'.
85111
#define SWIFT_INLINE_BITFIELD_EMPTY(T, U) \
86112
enum { Num##T##Bits = Num##U##Bits }

include/swift/SIL/SILInstruction.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5973,19 +5973,22 @@ VarDecl *getIndexedField(NominalTypeDecl *decl, unsigned index);
59735973
/// because it would allow constant time lookup of either the VarDecl or the
59745974
/// index from a single pointer without referring back to a projection
59755975
/// instruction.
5976-
class FieldIndexCacheBase : public SingleValueInstruction {
5976+
template <typename ParentTy>
5977+
class FieldIndexCacheBase : public ParentTy {
59775978
enum : unsigned { InvalidFieldIndex = ~unsigned(0) };
59785979

59795980
VarDecl *field;
59805981

59815982
public:
5983+
template <typename... ArgTys>
59825984
FieldIndexCacheBase(SILInstructionKind kind, SILDebugLocation loc,
5983-
SILType type, VarDecl *field)
5984-
: SingleValueInstruction(kind, loc, type), field(field) {
5985+
SILType type, VarDecl *field, ArgTys &&... extraArgs)
5986+
: ParentTy(kind, loc, type, std::forward<ArgTys>(extraArgs)...),
5987+
field(field) {
59855988
SILInstruction::Bits.FieldIndexCacheBase.FieldIndex = InvalidFieldIndex;
59865989
// This needs to be a concrete class to hold bitfield information. However,
59875990
// it should only be extended by UnaryInstructions.
5988-
assert(getNumOperands() == 1);
5991+
assert(ParentTy::getNumOperands() == 1);
59895992
}
59905993

59915994
VarDecl *getField() const { return field; }
@@ -5999,7 +6002,8 @@ class FieldIndexCacheBase : public SingleValueInstruction {
59996002
}
60006003

60016004
NominalTypeDecl *getParentDecl() const {
6002-
auto s = getOperand(0)->getType().getNominalOrBoundGenericNominal();
6005+
auto s =
6006+
ParentTy::getOperand(0)->getType().getNominalOrBoundGenericNominal();
60036007
assert(s);
60046008
return s;
60056009
}
@@ -6012,13 +6016,17 @@ class FieldIndexCacheBase : public SingleValueInstruction {
60126016
}
60136017

60146018
private:
6015-
unsigned cacheFieldIndex();
6019+
unsigned cacheFieldIndex() {
6020+
unsigned index = swift::getFieldIndex(getParentDecl(), getField());
6021+
SILInstruction::Bits.FieldIndexCacheBase.FieldIndex = index;
6022+
return index;
6023+
}
60166024
};
60176025

60186026
/// Extract a physical, fragile field out of a value of struct type.
60196027
class StructExtractInst
60206028
: public UnaryInstructionBase<SILInstructionKind::StructExtractInst,
6021-
FieldIndexCacheBase> {
6029+
FieldIndexCacheBase<SingleValueInstruction>> {
60226030
friend SILBuilder;
60236031

60246032
StructExtractInst(SILDebugLocation DebugLoc, SILValue Operand, VarDecl *Field,
@@ -6043,7 +6051,7 @@ class StructExtractInst
60436051
/// Derive the address of a physical field from the address of a struct.
60446052
class StructElementAddrInst
60456053
: public UnaryInstructionBase<SILInstructionKind::StructElementAddrInst,
6046-
FieldIndexCacheBase> {
6054+
FieldIndexCacheBase<SingleValueInstruction>> {
60476055
friend SILBuilder;
60486056

60496057
StructElementAddrInst(SILDebugLocation DebugLoc, SILValue Operand,
@@ -6060,7 +6068,7 @@ class StructElementAddrInst
60606068
/// type instance.
60616069
class RefElementAddrInst
60626070
: public UnaryInstructionBase<SILInstructionKind::RefElementAddrInst,
6063-
FieldIndexCacheBase> {
6071+
FieldIndexCacheBase<SingleValueInstruction>> {
60646072
friend SILBuilder;
60656073

60666074
RefElementAddrInst(SILDebugLocation DebugLoc, SILValue Operand,

include/swift/SIL/SILNode.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,11 @@ class alignas(8) SILNode {
317317
KeepUnique : 1
318318
);
319319

320-
SWIFT_INLINE_BITFIELD_FULL(FieldIndexCacheBase, SingleValueInstruction, 32,
321-
: NumPadBits,
322-
FieldIndex : 32);
320+
SWIFT_INLINE_BITFIELD_FULL_TEMPLATE(FieldIndexCacheBase,
321+
SingleValueInstruction, 32,
322+
: NumPadBits,
323+
FieldIndex : 32
324+
);
323325

324326
SWIFT_INLINE_BITFIELD_EMPTY(MethodInst, SingleValueInstruction);
325327
// Ensure that WitnessMethodInst bitfield does not overflow.

0 commit comments

Comments
 (0)