Skip to content

Commit 01e0f37

Browse files
committed
[NFC] Infrastructure to avoid storing simple generic params in metadata
The vast majority of generic parameters follow a simple pattern (type parameter that defines a key argument), which we can take advantage of to avoid actually representing them in type metadata: if all the type arguments is the simple pattern, and there's not more than some preset number, simply use a pre-allocated array in the runtime. Actually doing this for generic types will require some care around back-deployment, as well as finding a bit to store that we've done it. But we can at least start doing this for new ABI, such as the extended existential shape descriptors.
1 parent 21c5b88 commit 01e0f37

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/AST/Ownership.h"
2525
#include "swift/Basic/LLVM.h"
2626
#include "swift/Basic/FlagSet.h"
27+
#include "llvm/ADT/ArrayRef.h"
2728

2829
#include <stdlib.h>
2930
#include <stdint.h>
@@ -55,6 +56,10 @@ enum {
5556

5657
/// The number of words in an AsyncLet (flags + child task context & allocation)
5758
NumWords_AsyncLet = 80, // 640 bytes ought to be enough for anyone
59+
60+
/// The maximum number of generic parameters that can be
61+
/// implicitly declared, for generic signatures that support that.
62+
MaxNumImplicitGenericParamDescriptors = 64,
5863
};
5964

6065
struct InProcess;
@@ -1652,8 +1657,40 @@ class GenericParamDescriptor {
16521657
constexpr uint8_t getIntValue() const {
16531658
return Value;
16541659
}
1660+
1661+
friend bool operator==(GenericParamDescriptor lhs,
1662+
GenericParamDescriptor rhs) {
1663+
return lhs.getIntValue() == rhs.getIntValue();
1664+
}
1665+
friend bool operator!=(GenericParamDescriptor lhs,
1666+
GenericParamDescriptor rhs) {
1667+
return !(lhs == rhs);
1668+
}
1669+
1670+
/// The default parameter descriptor for an implicit parameter.
1671+
static constexpr GenericParamDescriptor implicit() {
1672+
return GenericParamDescriptor(GenericParamKind::Type,
1673+
/*key argument*/ true,
1674+
/*extra argument*/ false);
1675+
}
16551676
};
16561677

1678+
/// Can the given generic parameter array be implicit, for places in
1679+
/// the ABI which support that?
1680+
inline bool canGenericParamsBeImplicit(
1681+
llvm::ArrayRef<GenericParamDescriptor> params) {
1682+
// If there are more parameters than the maximum, they cannot be implicit.
1683+
if (params.size() > MaxNumImplicitGenericParamDescriptors)
1684+
return false;
1685+
1686+
// If any parameter is not the implicit pattern, they cannot be implicit.
1687+
for (auto param : params)
1688+
if (param != GenericParamDescriptor::implicit())
1689+
return false;
1690+
1691+
return true;
1692+
}
1693+
16571694
enum class GenericRequirementKind : uint8_t {
16581695
/// A protocol requirement.
16591696
Protocol = 0,

0 commit comments

Comments
 (0)