Skip to content

Commit 72e5f70

Browse files
authored
Merge pull request swiftlang#20099 from DougGregor/rountrip-builtin-type-metadata
[IRGen] Make (most) builtin type metadata round-trippable.
2 parents b76f1db + 57f8398 commit 72e5f70

File tree

6 files changed

+206
-96
lines changed

6 files changed

+206
-96
lines changed

include/swift/Runtime/BuiltinTypes.def

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,90 @@
1919
# define BUILTIN_TYPE(Symbol, Name)
2020
#endif
2121

22+
#ifndef BUILTIN_POINTER_TYPE
23+
# define BUILTIN_POINTER_TYPE(Symbol, Name) BUILTIN_TYPE(Symbol, Name)
24+
#endif
25+
26+
#define VECTOR_BUILTIN_SYMBOL_NAME(ElementSymbol, Width) \
27+
ElementSymbol##Bv##Width##_
28+
29+
#ifndef BUILTIN_VECTOR_TYPE
30+
# define BUILTIN_VECTOR_TYPE(ElementSymbol, ElementName, Width) \
31+
BUILTIN_TYPE(ElementSymbol##Bv##Width##_, \
32+
"Builtin.Vec" #Width "x" #ElementName)
33+
#endif
34+
35+
BUILTIN_TYPE(Bi1_, "Builtin.Int1")
2236
BUILTIN_TYPE(Bi8_, "Builtin.Int8")
2337
BUILTIN_TYPE(Bi16_, "Builtin.Int16")
2438
BUILTIN_TYPE(Bi32_, "Builtin.Int32")
39+
BUILTIN_TYPE(Bi63_, "Builtin.Int63")
2540
BUILTIN_TYPE(Bi64_, "Builtin.Int64")
2641
BUILTIN_TYPE(Bi128_, "Builtin.Int128")
2742
BUILTIN_TYPE(Bi256_, "Builtin.Int256")
2843
BUILTIN_TYPE(Bi512_, "Builtin.Int512")
2944

30-
BUILTIN_TYPE(Bo, "Builtin.NativeObject")
31-
BUILTIN_TYPE(Bb, "Builtin.BridgeObject")
32-
BUILTIN_TYPE(Bp, "Builtin.RawPointer")
45+
BUILTIN_TYPE(Bw, "Builtin.Word")
46+
47+
BUILTIN_TYPE(Bf16_, "Builtin.FPIEEE16")
48+
BUILTIN_TYPE(Bf32_, "Builtin.FPIEEE32")
49+
BUILTIN_TYPE(Bf64_, "Builtin.FPIEEE64")
50+
BUILTIN_TYPE(Bf80_, "Builtin.FPIEEE80")
51+
BUILTIN_TYPE(Bf128_, "Builtin.FPIEEE128")
52+
53+
BUILTIN_POINTER_TYPE(Bo, "Builtin.NativeObject")
54+
BUILTIN_POINTER_TYPE(Bb, "Builtin.BridgeObject")
55+
BUILTIN_POINTER_TYPE(Bp, "Builtin.RawPointer")
3356
BUILTIN_TYPE(BB, "Builtin.UnsafeValueBuffer")
3457

3558
#if SWIFT_OBJC_INTEROP
36-
BUILTIN_TYPE(BO, "Builtin.UnknownObject")
59+
BUILTIN_POINTER_TYPE(BO, "Builtin.UnknownObject")
3760
#endif
3861

62+
// Int8 vector types
63+
BUILTIN_VECTOR_TYPE(Bi8_, Int8, 2)
64+
BUILTIN_VECTOR_TYPE(Bi8_, Int8, 3)
65+
BUILTIN_VECTOR_TYPE(Bi8_, Int8, 4)
66+
BUILTIN_VECTOR_TYPE(Bi8_, Int8, 8)
67+
BUILTIN_VECTOR_TYPE(Bi8_, Int8, 16)
68+
BUILTIN_VECTOR_TYPE(Bi8_, Int8, 32)
69+
BUILTIN_VECTOR_TYPE(Bi8_, Int8, 64)
70+
71+
// Int16 vector types
72+
BUILTIN_VECTOR_TYPE(Bi16_, Int16, 2)
73+
BUILTIN_VECTOR_TYPE(Bi16_, Int16, 3)
74+
BUILTIN_VECTOR_TYPE(Bi16_, Int16, 4)
75+
BUILTIN_VECTOR_TYPE(Bi16_, Int16, 8)
76+
BUILTIN_VECTOR_TYPE(Bi16_, Int16, 16)
77+
BUILTIN_VECTOR_TYPE(Bi16_, Int16, 32)
78+
79+
// Int32 vector types
80+
BUILTIN_VECTOR_TYPE(Bi32_, Int32, 2)
81+
BUILTIN_VECTOR_TYPE(Bi32_, Int32, 3)
82+
BUILTIN_VECTOR_TYPE(Bi32_, Int32, 4)
83+
BUILTIN_VECTOR_TYPE(Bi32_, Int32, 8)
84+
BUILTIN_VECTOR_TYPE(Bi32_, Int32, 16)
85+
86+
// Int64 vector types
87+
BUILTIN_VECTOR_TYPE(Bi64_, Int64, 2)
88+
BUILTIN_VECTOR_TYPE(Bi64_, Int64, 3)
89+
BUILTIN_VECTOR_TYPE(Bi64_, Int64, 4)
90+
BUILTIN_VECTOR_TYPE(Bi64_, Int64, 8)
91+
92+
// Float32 vector types
93+
BUILTIN_VECTOR_TYPE(Bf32_, FPIEEE32, 2)
94+
BUILTIN_VECTOR_TYPE(Bf32_, FPIEEE32, 3)
95+
BUILTIN_VECTOR_TYPE(Bf32_, FPIEEE32, 4)
96+
BUILTIN_VECTOR_TYPE(Bf32_, FPIEEE32, 8)
97+
BUILTIN_VECTOR_TYPE(Bf32_, FPIEEE32, 16)
98+
99+
// Float64 vector types
100+
BUILTIN_VECTOR_TYPE(Bf64_, FPIEEE64, 2)
101+
BUILTIN_VECTOR_TYPE(Bf64_, FPIEEE64, 3)
102+
BUILTIN_VECTOR_TYPE(Bf64_, FPIEEE64, 4)
103+
BUILTIN_VECTOR_TYPE(Bf64_, FPIEEE64, 8)
104+
105+
#undef BUILTIN_VECTOR_TYPE
106+
#undef VECTOR_BUILTIN_SYMBOL_NAME
107+
#undef BUILTIN_POINTER_TYPE
39108
#undef BUILTIN_TYPE

include/swift/Runtime/Metadata.h

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -218,39 +218,11 @@ inline unsigned TypeLayout::getNumExtraInhabitants() const {
218218

219219
// Standard value-witness tables.
220220

221-
// The "Int" tables are used for arbitrary POD data with the matching
222-
// size/alignment characteristics.
223-
SWIFT_RUNTIME_EXPORT
224-
const ValueWitnessTable VALUE_WITNESS_SYM(Bi8_); // Builtin.Int8
225-
SWIFT_RUNTIME_EXPORT
226-
const ValueWitnessTable VALUE_WITNESS_SYM(Bi16_); // Builtin.Int16
227-
SWIFT_RUNTIME_EXPORT
228-
const ValueWitnessTable VALUE_WITNESS_SYM(Bi32_); // Builtin.Int32
229-
SWIFT_RUNTIME_EXPORT
230-
const ValueWitnessTable VALUE_WITNESS_SYM(Bi64_); // Builtin.Int64
231-
SWIFT_RUNTIME_EXPORT
232-
const ValueWitnessTable VALUE_WITNESS_SYM(Bi128_); // Builtin.Int128
233-
SWIFT_RUNTIME_EXPORT
234-
const ValueWitnessTable VALUE_WITNESS_SYM(Bi256_); // Builtin.Int256
235-
SWIFT_RUNTIME_EXPORT
236-
const ValueWitnessTable VALUE_WITNESS_SYM(Bi512_); // Builtin.Int512
237-
238-
// The object-pointer table can be used for arbitrary Swift refcounted
239-
// pointer types.
240-
SWIFT_RUNTIME_EXPORT
241-
const ExtraInhabitantsValueWitnessTable VALUE_WITNESS_SYM(Bo); // Builtin.NativeObject
242-
243-
SWIFT_RUNTIME_EXPORT
244-
const ExtraInhabitantsValueWitnessTable VALUE_WITNESS_SYM(Bb); // Builtin.BridgeObject
245-
246-
SWIFT_RUNTIME_EXPORT
247-
const ExtraInhabitantsValueWitnessTable VALUE_WITNESS_SYM(Bp); // Builtin.RawPointer
248-
249-
#if SWIFT_OBJC_INTEROP
250-
// The ObjC-pointer table can be used for arbitrary ObjC pointer types.
251-
SWIFT_RUNTIME_EXPORT
252-
const ExtraInhabitantsValueWitnessTable VALUE_WITNESS_SYM(BO); // Builtin.UnknownObject
253-
#endif
221+
#define BUILTIN_TYPE(Symbol, _) \
222+
SWIFT_RUNTIME_EXPORT const ValueWitnessTable VALUE_WITNESS_SYM(Symbol);
223+
#define BUILTIN_POINTER_TYPE(Symbol, _) \
224+
SWIFT_RUNTIME_EXPORT const ExtraInhabitantsValueWitnessTable VALUE_WITNESS_SYM(Symbol);
225+
#include "swift/Runtime/BuiltinTypes.def"
254226

255227
// The () -> () table can be used for arbitrary function types.
256228
SWIFT_RUNTIME_EXPORT

lib/IRGen/MetadataRequest.cpp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -843,31 +843,25 @@ namespace {
843843
public:
844844
EmitTypeMetadataRef(IRGenFunction &IGF) : IGF(IGF) {}
845845

846-
#define TREAT_AS_OPAQUE(KIND) \
847-
MetadataResponse visit##KIND##Type(Can##KIND##Type type, \
848-
DynamicMetadataRequest request) { \
849-
return visitOpaqueType(type); \
850-
}
851-
TREAT_AS_OPAQUE(BuiltinInteger)
852-
TREAT_AS_OPAQUE(BuiltinFloat)
853-
TREAT_AS_OPAQUE(BuiltinVector)
854-
TREAT_AS_OPAQUE(BuiltinRawPointer)
855-
#undef TREAT_AS_OPAQUE
856-
857846
MetadataResponse emitDirectMetadataRef(CanType type) {
858847
return MetadataResponse::forComplete(IGF.IGM.getAddrOfTypeMetadata(type));
859848
}
860849

861850
/// The given type should use opaque type info. We assume that
862-
/// the runtime always provides an entry for such a type; right
863-
/// now, that mapping is as one of the power-of-two integer types.
864-
MetadataResponse visitOpaqueType(CanType type) {
851+
/// the runtime always provides an entry for such a type.
852+
MetadataResponse visitBuiltinIntegerType(CanBuiltinIntegerType type,
853+
DynamicMetadataRequest request) {
854+
// If the size isn't a power up two, round up to the next power of two
855+
// and use the corresponding integer type.
865856
auto &opaqueTI = cast<FixedTypeInfo>(IGF.IGM.getTypeInfoForLowered(type));
866857
unsigned numBits = opaqueTI.getFixedSize().getValueInBits();
867-
if (!llvm::isPowerOf2_32(numBits))
858+
if (!llvm::isPowerOf2_32(numBits)) {
868859
numBits = llvm::NextPowerOf2(numBits);
869-
auto intTy = BuiltinIntegerType::get(numBits, IGF.IGM.Context);
870-
return emitDirectMetadataRef(CanType(intTy));
860+
type = CanBuiltinIntegerType(
861+
BuiltinIntegerType::get(numBits, IGF.IGM.Context));
862+
}
863+
864+
return emitDirectMetadataRef(type);
871865
}
872866

873867
MetadataResponse
@@ -894,6 +888,24 @@ namespace {
894888
return emitDirectMetadataRef(type);
895889
}
896890

891+
MetadataResponse
892+
visitBuiltinRawPointerType(CanBuiltinRawPointerType type,
893+
DynamicMetadataRequest request) {
894+
return emitDirectMetadataRef(type);
895+
}
896+
897+
MetadataResponse
898+
visitBuiltinFloatType(CanBuiltinFloatType type,
899+
DynamicMetadataRequest request) {
900+
return emitDirectMetadataRef(type);
901+
}
902+
903+
MetadataResponse
904+
visitBuiltinVectorType(CanBuiltinVectorType type,
905+
DynamicMetadataRequest request) {
906+
return emitDirectMetadataRef(type);
907+
}
908+
897909
MetadataResponse visitNominalType(CanNominalType type,
898910
DynamicMetadataRequest request) {
899911
assert(!type->isExistentialType());

stdlib/public/runtime/KnownMetadata.cpp

Lines changed: 92 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -44,59 +44,109 @@ namespace {
4444
struct alignas(64) int512_like {
4545
char data[64];
4646
};
47-
} // end anonymous namespace
4847

49-
// We use explicit sizes and alignments here just in case the C ABI
50-
// under-aligns any or all of them.
51-
const ValueWitnessTable swift::VALUE_WITNESS_SYM(Bi8_) =
52-
ValueWitnessTableForBox<NativeBox<uint8_t, 1>>::table;
53-
const ValueWitnessTable swift::VALUE_WITNESS_SYM(Bi16_) =
54-
ValueWitnessTableForBox<NativeBox<uint16_t, 2>>::table;
55-
const ValueWitnessTable swift::VALUE_WITNESS_SYM(Bi32_) =
56-
ValueWitnessTableForBox<NativeBox<uint32_t, 4>>::table;
57-
const ValueWitnessTable swift::VALUE_WITNESS_SYM(Bi64_) =
58-
ValueWitnessTableForBox<NativeBox<uint64_t, 8>>::table;
59-
const ValueWitnessTable swift::VALUE_WITNESS_SYM(Bi128_) =
60-
ValueWitnessTableForBox<NativeBox<int128_like, 16>>::table;
61-
const ValueWitnessTable swift::VALUE_WITNESS_SYM(Bi256_) =
62-
ValueWitnessTableForBox<NativeBox<int256_like, 32>>::table;
63-
const ValueWitnessTable swift::VALUE_WITNESS_SYM(Bi512_) =
64-
ValueWitnessTableForBox<NativeBox<int512_like, 64>>::table;
65-
66-
/// The basic value-witness table for Swift object pointers.
67-
const ExtraInhabitantsValueWitnessTable swift::VALUE_WITNESS_SYM(Bo) =
68-
ValueWitnessTableForBox<SwiftRetainableBox>::table;
48+
struct alignas(16) float80_like {
49+
char data[10];
50+
};
51+
} // end anonymous namespace
6952

70-
/// The value-witness table for pointer-aligned unmanaged pointer types.
71-
const ExtraInhabitantsValueWitnessTable swift::METATYPE_VALUE_WITNESS_SYM(Bo) =
72-
ValueWitnessTableForBox<PointerPointerBox>::table;
53+
namespace ctypes {
54+
namespace {
55+
// Type definitions that map each names Swift builtin type to their
56+
// C counterparts.
57+
using Bi1_ = uint8_t;
58+
using Bi8_ = uint8_t;
59+
using Bi16_ = uint16_t;
60+
using Bi32_ = uint32_t;
61+
using Bi63_ = uint64_t;
62+
using Bi64_ = uint64_t;
63+
using Bi128_ = int128_like;
64+
using Bi256_ = int256_like;
65+
using Bi512_ = int512_like;
66+
67+
using Bw = intptr_t;
68+
69+
using Bf16_ = uint16_t;
70+
using Bf32_ = float;
71+
using Bf64_ = double;
72+
using Bf80_ = float80_like;
73+
using Bf128_ = int128_like;
74+
75+
/// The value-witness table for UnsafeValueBuffer. You can do layout
76+
/// with this, but the type isn't copyable, so most of the value
77+
/// operations are meaningless.
78+
using BB = ValueBuffer;
79+
}
80+
}
7381

74-
/// The value-witness table for raw pointers.
75-
const ExtraInhabitantsValueWitnessTable swift::VALUE_WITNESS_SYM(Bp) =
76-
ValueWitnessTableForBox<RawPointerBox>::table;
82+
namespace pointer_types {
83+
namespace {
84+
/// The basic value-witness table for Swift object pointers.
85+
using Bo = SwiftRetainableBox;
7786

78-
/// The value-witness table for BridgeObject.
79-
const ExtraInhabitantsValueWitnessTable swift::VALUE_WITNESS_SYM(Bb) =
80-
ValueWitnessTableForBox<BridgeObjectBox>::table;
87+
/// The value-witness table for raw pointers.
88+
using Bp = RawPointerBox;
8189

82-
/// The value-witness table for UnsafeValueBuffer. You can do layout
83-
/// with this, but the type isn't copyable, so most of the value
84-
/// operations are meaningless.
85-
static const ValueWitnessTable VALUE_WITNESS_SYM(BB) =
86-
ValueWitnessTableForBox<NativeBox<ValueBuffer>>::table;
90+
/// The value-witness table for BridgeObject.
91+
using Bb = BridgeObjectBox;
8792

8893
#if SWIFT_OBJC_INTEROP
89-
/*** Objective-C pointers ****************************************************/
90-
91-
// This section can reasonably be suppressed in builds that don't
92-
// need to support Objective-C.
94+
/*** Objective-C pointers *************************************************/
9395

94-
/// The basic value-witness table for ObjC object pointers.
95-
const ExtraInhabitantsValueWitnessTable swift::VALUE_WITNESS_SYM(BO) =
96-
ValueWitnessTableForBox<ObjCRetainableBox>::table;
96+
// This section can reasonably be suppressed in builds that don't
97+
// need to support Objective-C.
9798

99+
/// The basic value-witness table for ObjC object pointers.
100+
using BO = ObjCRetainableBox;
98101
#endif
99102

103+
}
104+
}
105+
106+
namespace {
107+
template<typename T>
108+
constexpr size_t getAlignment() { return alignof(T); }
109+
110+
#define SET_FIXED_ALIGNMENT(Type, Align) \
111+
template<> constexpr size_t getAlignment<Type>() { return Align; }
112+
113+
SET_FIXED_ALIGNMENT(uint8_t, 1)
114+
SET_FIXED_ALIGNMENT(uint16_t, 2)
115+
SET_FIXED_ALIGNMENT(uint32_t, 4)
116+
SET_FIXED_ALIGNMENT(uint64_t, 8)
117+
SET_FIXED_ALIGNMENT(int128_like, 16)
118+
SET_FIXED_ALIGNMENT(int256_like, 32)
119+
SET_FIXED_ALIGNMENT(int512_like, 64)
120+
121+
#undef SET_FIXED_ALIGNMENT
122+
123+
template<typename T, unsigned N>
124+
struct SwiftVecT {
125+
typedef T type __attribute__((ext_vector_type(N)));
126+
};
127+
128+
template<typename T, unsigned N>
129+
using SwiftVec = typename SwiftVecT<T, N>::type;
130+
}
131+
132+
#define BUILTIN_TYPE(Symbol, Name) \
133+
const ValueWitnessTable swift::VALUE_WITNESS_SYM(Symbol) = \
134+
ValueWitnessTableForBox<NativeBox<ctypes::Symbol, \
135+
getAlignment<ctypes::Symbol>()>>::table;
136+
#define BUILTIN_POINTER_TYPE(Symbol, Name) \
137+
const ExtraInhabitantsValueWitnessTable swift::VALUE_WITNESS_SYM(Symbol) = \
138+
ValueWitnessTableForBox<pointer_types::Symbol>::table;
139+
#define BUILTIN_VECTOR_TYPE(ElementSymbol, _, Width) \
140+
const ValueWitnessTable \
141+
swift::VALUE_WITNESS_SYM(VECTOR_BUILTIN_SYMBOL_NAME(ElementSymbol,Width)) = \
142+
ValueWitnessTableForBox<NativeBox<SwiftVec<ctypes::ElementSymbol, \
143+
Width>>>::table;
144+
#include "swift/Runtime/BuiltinTypes.def"
145+
146+
/// The value-witness table for pointer-aligned unmanaged pointer types.
147+
const ExtraInhabitantsValueWitnessTable swift::METATYPE_VALUE_WITNESS_SYM(Bo) =
148+
ValueWitnessTableForBox<PointerPointerBox>::table;
149+
100150
/*** Functions ***************************************************************/
101151

102152
namespace {

test/Runtime/demangleToMetadata.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ DemangleToMetadataTests.test("demangle built-in types") {
241241
expectEqual(Builtin.NativeObject.self, _typeByMangledName("Bo")!)
242242
expectEqual(Builtin.BridgeObject.self, _typeByMangledName("Bb")!)
243243
expectEqual(Builtin.UnsafeValueBuffer.self, _typeByMangledName("BB")!)
244+
245+
expectEqual(Builtin.FPIEEE32.self, _typeByMangledName("Bf32_")!)
246+
expectEqual(Builtin.FPIEEE64.self, _typeByMangledName("Bf64_")!)
247+
248+
expectEqual(Builtin.Vec4xFPIEEE32.self, _typeByMangledName("Bf32_Bv4_")!)
244249
}
245250

246251
class CG4<T: P1, U: P2> {

validation-test/stdlib/MicroStdlib/Inputs/RuntimeStubs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
int $sBi32_N;
22
int $sBi64_N;
33
int $sBi8_N;
4+
int $sBwN;
5+
int $sBpN;
46
int $sBi32_WV;
57
int $sBi64_WV;
68
int $sBi8_WV;

0 commit comments

Comments
 (0)