Skip to content

Commit 3f18b5e

Browse files
committed
[AST] Stop using PointerIntPair for SIL params/results
The differentiability bit pushed the size of SILParameterInfo and SILResultInfo from 8 bytes to 16 bytes. Given that the low bits of the PointerIntPair are full and given that we do not want to over-align types, the PointerIntPair is not saving space anymore. Let's simplify these two data structures to make debugging easier (and the speed of debug builds slightly faster). In theory, release builds will also benefit due to fewer masking operations to extract the pointer or the low bits, but this will probably be "in the noise" for benchmarks. Note: this change is techinically not NFC because it fixes the SILResultInfo equality comparison function to check differentiability.
1 parent 9e85a39 commit 3f18b5e

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

include/swift/AST/Types.h

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3641,7 +3641,7 @@ inline CanGenericSignature CanAnyFunctionType::getOptGenericSignature() const {
36413641
}
36423642

36433643
/// Conventions for passing arguments as parameters.
3644-
enum class ParameterConvention {
3644+
enum class ParameterConvention : uint8_t {
36453645
/// This argument is passed indirectly, i.e. by directly passing the address
36463646
/// of an object in memory. The callee is responsible for destroying the
36473647
/// object. The callee may assume that the address does not alias any valid
@@ -3687,7 +3687,7 @@ enum class ParameterConvention {
36873687
};
36883688
// Check that the enum values fit inside Bits.SILFunctionType.
36893689
static_assert(unsigned(ParameterConvention::Direct_Guaranteed) < (1<<3),
3690-
"fits in Bits.SILFunctionType and SILParameterInfo");
3690+
"fits in Bits.SILFunctionType");
36913691

36923692
// Does this parameter convention require indirect storage? This reflects a
36933693
// SILFunctionType's formal (immutable) conventions, as opposed to the transient
@@ -3746,7 +3746,7 @@ inline bool isGuaranteedParameter(ParameterConvention conv) {
37463746
}
37473747

37483748
/// The differentiability of a SIL function type parameter.
3749-
enum class SILParameterDifferentiability : unsigned {
3749+
enum class SILParameterDifferentiability : bool {
37503750
/// Either differentiable or not applicable.
37513751
///
37523752
/// - If the function type is not `@differentiable`, parameter
@@ -3764,16 +3764,17 @@ enum class SILParameterDifferentiability : unsigned {
37643764

37653765
/// A parameter type and the rules for passing it.
37663766
class SILParameterInfo {
3767-
llvm::PointerIntPair<CanType, 3, ParameterConvention> TypeAndConvention;
3768-
SILParameterDifferentiability Differentiability : 1;
3767+
CanType Type;
3768+
ParameterConvention Convention;
3769+
SILParameterDifferentiability Differentiability;
37693770

37703771
public:
37713772
SILParameterInfo() = default;//: Ty(), Convention((ParameterConvention)0) {}
37723773
SILParameterInfo(
37733774
CanType type, ParameterConvention conv,
37743775
SILParameterDifferentiability differentiability =
37753776
SILParameterDifferentiability::DifferentiableOrNotApplicable)
3776-
: TypeAndConvention(type, conv), Differentiability(differentiability) {
3777+
: Type(type), Convention(conv), Differentiability(differentiability) {
37773778
assert(type->isLegalSILType() && "SILParameterInfo has illegal SIL type");
37783779
}
37793780

@@ -3782,15 +3783,15 @@ class SILParameterInfo {
37823783
///
37833784
/// For most purposes, you probably want \c getArgumentType .
37843785
CanType getInterfaceType() const {
3785-
return TypeAndConvention.getPointer();
3786+
return Type;
37863787
}
37873788

37883789
/// Return the type of a call argument matching this parameter.
37893790
///
37903791
/// \c t must refer back to the function type this is a parameter for.
37913792
CanType getArgumentType(SILModule &M, const SILFunctionType *t, TypeExpansionContext context) const;
37923793
ParameterConvention getConvention() const {
3793-
return TypeAndConvention.getInt();
3794+
return Convention;
37943795
}
37953796
// Does this parameter convention require indirect storage? This reflects a
37963797
// SILFunctionType's formal (immutable) conventions, as opposed to the
@@ -3909,7 +3910,7 @@ class SILParameterInfo {
39093910
};
39103911

39113912
/// Conventions for returning values.
3912-
enum class ResultConvention {
3913+
enum class ResultConvention : uint8_t {
39133914
/// This result is returned indirectly, i.e. by passing the address
39143915
/// of an uninitialized object in memory. The callee is responsible
39153916
/// for leaving an initialized object at this address. The callee
@@ -3944,7 +3945,7 @@ inline bool isIndirectFormalResult(ResultConvention convention) {
39443945
}
39453946

39463947
/// The differentiability of a SIL function type result.
3947-
enum class SILResultDifferentiability : unsigned {
3948+
enum class SILResultDifferentiability : bool {
39483949
/// Either differentiable or not applicable.
39493950
///
39503951
/// - If the function type is not `@differentiable`, result
@@ -3962,15 +3963,16 @@ enum class SILResultDifferentiability : unsigned {
39623963

39633964
/// A result type and the rules for returning it.
39643965
class SILResultInfo {
3965-
llvm::PointerIntPair<CanType, 3, ResultConvention> TypeAndConvention;
3966-
SILResultDifferentiability Differentiability : 1;
3966+
CanType Type;
3967+
ResultConvention Convention;
3968+
SILResultDifferentiability Differentiability;
39673969

39683970
public:
39693971
SILResultInfo() = default;
39703972
SILResultInfo(CanType type, ResultConvention conv,
39713973
SILResultDifferentiability differentiability =
39723974
SILResultDifferentiability::DifferentiableOrNotApplicable)
3973-
: TypeAndConvention(type, conv), Differentiability(differentiability) {
3975+
: Type(type), Convention(conv), Differentiability(differentiability) {
39743976
assert(type->isLegalSILType() && "SILResultInfo has illegal SIL type");
39753977
}
39763978

@@ -3979,7 +3981,7 @@ class SILResultInfo {
39793981
///
39803982
/// For most purposes, you probably want \c getReturnValueType .
39813983
CanType getInterfaceType() const {
3982-
return TypeAndConvention.getPointer();
3984+
return Type;
39833985
}
39843986

39853987
/// The type of a return value corresponding to this result.
@@ -3989,7 +3991,7 @@ class SILResultInfo {
39893991
TypeExpansionContext context) const;
39903992

39913993
ResultConvention getConvention() const {
3992-
return TypeAndConvention.getInt();
3994+
return Convention;
39933995
}
39943996

39953997
SILResultDifferentiability getDifferentiability() const {
@@ -4057,8 +4059,9 @@ class SILResultInfo {
40574059
}
40584060

40594061
void profile(llvm::FoldingSetNodeID &id) {
4060-
id.AddPointer(TypeAndConvention.getOpaqueValue());
4061-
id.AddInteger((unsigned)getDifferentiability());
4062+
id.AddPointer(Type.getPointer());
4063+
id.AddInteger(unsigned(getConvention()));
4064+
id.AddInteger(unsigned(getDifferentiability()));
40624065
}
40634066

40644067
SWIFT_DEBUG_DUMP;
@@ -4075,7 +4078,8 @@ class SILResultInfo {
40754078
getOwnershipKind(SILFunction &, CanSILFunctionType fTy) const; // in SILType.cpp
40764079

40774080
bool operator==(SILResultInfo rhs) const {
4078-
return TypeAndConvention == rhs.TypeAndConvention;
4081+
return Type == rhs.Type && Convention == rhs.Convention
4082+
&& Differentiability == rhs.Differentiability;
40794083
}
40804084
bool operator!=(SILResultInfo rhs) const {
40814085
return !(*this == rhs);

0 commit comments

Comments
 (0)