mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #83490 from rjmccall/sil-type-properties
Extract and use SILTypeProperties without a TypeLowering
This commit is contained in:
@@ -26,7 +26,7 @@ namespace swift {
|
||||
/// aggressively its destroys may be hoisted.
|
||||
///
|
||||
/// By default, types have lifetimes inferred from their structure, see
|
||||
/// TypeLowering::RecursiveProperties::isLexical. It can be overridden both on
|
||||
/// SILTypeProperties::isLexical. It can be overridden both on
|
||||
/// the type level and the value level via attributes.
|
||||
struct Lifetime {
|
||||
enum Storage : uint8_t {
|
||||
|
||||
@@ -210,7 +210,8 @@ public:
|
||||
|
||||
TypeExpansionContext getTypeExpansionContext() const {
|
||||
if (!F)
|
||||
return TypeExpansionContext::minimal();
|
||||
return TypeExpansionContext::maximal(getModule().getSwiftModule(),
|
||||
getModule().isWholeModule());
|
||||
return TypeExpansionContext(getFunction());
|
||||
}
|
||||
|
||||
@@ -223,15 +224,10 @@ public:
|
||||
}
|
||||
ASTContext &getASTContext() const { return getModule().getASTContext(); }
|
||||
const Lowering::TypeLowering &getTypeLowering(SILType T) const {
|
||||
|
||||
auto expansion = TypeExpansionContext::maximal(getModule().getSwiftModule(),
|
||||
getModule().isWholeModule());
|
||||
// If there's no current SILFunction, we're inserting into a global
|
||||
// variable initializer.
|
||||
if (F) {
|
||||
expansion = TypeExpansionContext(getFunction());
|
||||
}
|
||||
return getModule().Types.getTypeLowering(T, expansion);
|
||||
return getModule().Types.getTypeLowering(T, getTypeExpansionContext());
|
||||
}
|
||||
SILTypeProperties getTypeProperties(SILType T) const {
|
||||
return getModule().Types.getTypeProperties(T, getTypeExpansionContext());
|
||||
}
|
||||
|
||||
void setCurrentDebugScope(const SILDebugScope *DS) { CurDebugScope = DS; }
|
||||
@@ -2346,7 +2342,7 @@ public:
|
||||
FixLifetimeInst(getSILDebugLocation(Loc), Operand));
|
||||
}
|
||||
void emitFixLifetime(SILLocation Loc, SILValue Operand) {
|
||||
if (getTypeLowering(Operand->getType()).isTrivial())
|
||||
if (getTypeProperties(Operand->getType()).isTrivial())
|
||||
return;
|
||||
createFixLifetime(Loc, Operand);
|
||||
}
|
||||
@@ -3187,7 +3183,7 @@ private:
|
||||
if (!SILModuleConventions(M).useLoweredAddresses())
|
||||
return true;
|
||||
|
||||
return getTypeLowering(Ty).isLoadable();
|
||||
return getTypeProperties(Ty).isLoadable();
|
||||
}
|
||||
|
||||
void appendOperandTypeName(SILType OpdTy, llvm::SmallString<16> &Name) {
|
||||
|
||||
@@ -42,6 +42,7 @@ class BasicBlockBitfield;
|
||||
class NodeBitfield;
|
||||
class OperandBitfield;
|
||||
class CalleeCache;
|
||||
class SILTypeProperties;
|
||||
class SILUndef;
|
||||
|
||||
namespace Lowering {
|
||||
@@ -784,11 +785,18 @@ public:
|
||||
return TypeExpansionContext(*this);
|
||||
}
|
||||
|
||||
SILTypeProperties getTypeProperties(Lowering::AbstractionPattern orig,
|
||||
Type subst) const;
|
||||
SILTypeProperties getTypeProperties(Type subst) const;
|
||||
SILTypeProperties getTypeProperties(SILType type) const;
|
||||
|
||||
const Lowering::TypeLowering &
|
||||
getTypeLowering(Lowering::AbstractionPattern orig, Type subst);
|
||||
getTypeLowering(Lowering::AbstractionPattern orig, Type subst) const;
|
||||
|
||||
const Lowering::TypeLowering &getTypeLowering(Type t) const;
|
||||
|
||||
const Lowering::TypeLowering &getTypeLowering(SILType type) const;
|
||||
|
||||
SILType getLoweredType(Lowering::AbstractionPattern orig, Type subst) const;
|
||||
|
||||
SILType getLoweredType(Type t) const;
|
||||
@@ -801,8 +809,6 @@ public:
|
||||
|
||||
SILType getLoweredType(SILType t) const;
|
||||
|
||||
const Lowering::TypeLowering &getTypeLowering(SILType type) const;
|
||||
|
||||
bool isTypeABIAccessible(SILType type) const;
|
||||
|
||||
/// Returns true if this function has a calling convention that has a self
|
||||
|
||||
254
include/swift/SIL/SILTypeProperties.h
Normal file
254
include/swift/SIL/SILTypeProperties.h
Normal file
@@ -0,0 +1,254 @@
|
||||
//===--- SILTypeProperties.h - Properties of SIL types ----------*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_SIL_SILTYPEPROPERTIES_H
|
||||
#define SWIFT_SIL_SILTYPEPROPERTIES_H
|
||||
|
||||
namespace swift {
|
||||
|
||||
/// Is a lowered SIL type trivial? That is, are copies ultimately just
|
||||
/// bit-copies, and it takes no work to destroy a value?
|
||||
enum IsTrivial_t : bool {
|
||||
IsNotTrivial = false,
|
||||
IsTrivial = true
|
||||
};
|
||||
|
||||
/// Is a lowered SIL type the Builtin.RawPointer or a struct/tuple/enum which
|
||||
/// contains a Builtin.RawPointer?
|
||||
/// HasRawPointer is true only for types that are known to contain
|
||||
/// Builtin.RawPointer. It is not assumed true for generic or resilient types.
|
||||
enum HasRawPointer_t : bool {
|
||||
DoesNotHaveRawPointer = false,
|
||||
HasRawPointer = true
|
||||
};
|
||||
|
||||
/// Is a lowered SIL type fixed-ABI? That is, can the current context
|
||||
/// assign it a fixed size and alignment and perform value operations on it
|
||||
/// (such as copies, destroys, constructions, and projections) without
|
||||
/// metadata?
|
||||
///
|
||||
/// Note that a fully concrete type can be non-fixed-ABI without being
|
||||
/// itself resilient if it contains a subobject which is not fixed-ABI.
|
||||
///
|
||||
/// Also note that we're only concerned with the external value ABI here:
|
||||
/// resilient class types are still fixed-ABI, indirect enum cases do not
|
||||
/// affect the fixed-ABI-ness of the enum, and so on.
|
||||
enum IsFixedABI_t : bool {
|
||||
IsNotFixedABI = false,
|
||||
IsFixedABI = true
|
||||
};
|
||||
|
||||
/// Is a lowered SIL type address-only? That is, is the current context
|
||||
/// required to keep the value in memory for some reason?
|
||||
///
|
||||
/// A type might be address-only because:
|
||||
///
|
||||
/// - it is not fixed-size (e.g. because it is a resilient type) and
|
||||
/// therefore cannot be loaded into a statically-boundable set of
|
||||
/// registers; or
|
||||
///
|
||||
/// - it is semantically bound to memory, either because its storage
|
||||
/// address is used by the language runtime to implement its semantics
|
||||
/// (as with a weak reference) or because its representation is somehow
|
||||
/// address-dependent (as with something like a relative pointer).
|
||||
///
|
||||
/// An address-only type can be fixed-layout and/or trivial.
|
||||
/// A non-fixed-layout type is always address-only.
|
||||
enum IsAddressOnly_t : bool {
|
||||
IsNotAddressOnly = false,
|
||||
IsAddressOnly = true
|
||||
};
|
||||
|
||||
/// Is this type somewhat like a reference-counted type?
|
||||
enum IsReferenceCounted_t : bool {
|
||||
IsNotReferenceCounted = false,
|
||||
IsReferenceCounted = true
|
||||
};
|
||||
|
||||
/// Is this type address only because it's resilient?
|
||||
enum IsResilient_t : bool {
|
||||
IsNotResilient = false,
|
||||
IsResilient = true
|
||||
};
|
||||
|
||||
/// Does this type contain an opaque result type that affects type lowering?
|
||||
enum IsTypeExpansionSensitive_t : bool {
|
||||
IsNotTypeExpansionSensitive = false,
|
||||
IsTypeExpansionSensitive = true
|
||||
};
|
||||
|
||||
/// Is the type infinitely defined in terms of itself? (Such types can never
|
||||
/// be concretely instantiated, but may still arise from generic specialization.)
|
||||
enum IsInfiniteType_t : bool {
|
||||
IsNotInfiniteType = false,
|
||||
IsInfiniteType = true,
|
||||
};
|
||||
|
||||
/// Does this type contain any pack-like thing.
|
||||
enum HasPack_t : bool {
|
||||
HasNoPack = false,
|
||||
HasPack = true,
|
||||
};
|
||||
|
||||
/// Is the type addressable-for-dependencies?
|
||||
///
|
||||
/// Values of an addressable-for-dependency type are passed indirectly into
|
||||
/// functions that specify a return value lifetime dependency on the value.
|
||||
/// This allows the dependent value to safely contain pointers to the in-memory
|
||||
/// representation of the source of the dependency.
|
||||
enum IsAddressableForDependencies_t : bool {
|
||||
IsNotAddressableForDependencies = false,
|
||||
IsAddressableForDependencies = true,
|
||||
};
|
||||
|
||||
class SILTypeProperties {
|
||||
// These are chosen so that bitwise-or merges the flags properly.
|
||||
//
|
||||
// clang-format off
|
||||
enum : unsigned {
|
||||
NonTrivialFlag = 1 << 0,
|
||||
NonFixedABIFlag = 1 << 1,
|
||||
AddressOnlyFlag = 1 << 2,
|
||||
ResilientFlag = 1 << 3,
|
||||
TypeExpansionSensitiveFlag = 1 << 4,
|
||||
InfiniteFlag = 1 << 5,
|
||||
HasRawPointerFlag = 1 << 6,
|
||||
LexicalFlag = 1 << 7,
|
||||
HasPackFlag = 1 << 8,
|
||||
AddressableForDependenciesFlag = 1 << 9,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
uint16_t Flags;
|
||||
|
||||
public:
|
||||
/// Construct a default SILTypeProperties, which corresponds to
|
||||
/// a trivial, loadable, fixed-layout type.
|
||||
constexpr SILTypeProperties() : Flags(0) {}
|
||||
|
||||
constexpr SILTypeProperties(
|
||||
IsTrivial_t isTrivial, IsFixedABI_t isFixedABI,
|
||||
IsAddressOnly_t isAddressOnly, IsResilient_t isResilient,
|
||||
IsTypeExpansionSensitive_t isTypeExpansionSensitive =
|
||||
IsNotTypeExpansionSensitive,
|
||||
HasRawPointer_t hasRawPointer = DoesNotHaveRawPointer,
|
||||
IsLexical_t isLexical = IsNotLexical, HasPack_t hasPack = HasNoPack,
|
||||
IsAddressableForDependencies_t isAFD = IsNotAddressableForDependencies)
|
||||
: Flags((isTrivial ? 0U : NonTrivialFlag) |
|
||||
(isFixedABI ? 0U : NonFixedABIFlag) |
|
||||
(isAddressOnly ? AddressOnlyFlag : 0U) |
|
||||
(isResilient ? ResilientFlag : 0U) |
|
||||
(isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0U) |
|
||||
(hasRawPointer ? HasRawPointerFlag : 0U) |
|
||||
(isLexical ? LexicalFlag : 0U) |
|
||||
(hasPack ? HasPackFlag : 0U) |
|
||||
(isAFD ? AddressableForDependenciesFlag : 0U)) {}
|
||||
|
||||
constexpr bool operator==(SILTypeProperties p) const {
|
||||
return Flags == p.Flags;
|
||||
}
|
||||
|
||||
static constexpr SILTypeProperties forTrivial() {
|
||||
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient};
|
||||
}
|
||||
|
||||
static constexpr SILTypeProperties forTrivialOpaque() {
|
||||
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient,
|
||||
IsNotTypeExpansionSensitive, HasRawPointer, IsNotLexical,
|
||||
HasNoPack, IsAddressableForDependencies};
|
||||
}
|
||||
|
||||
static constexpr SILTypeProperties forRawPointer() {
|
||||
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient,
|
||||
IsNotTypeExpansionSensitive, HasRawPointer};
|
||||
}
|
||||
|
||||
static constexpr SILTypeProperties forReference() {
|
||||
return {IsNotTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient,
|
||||
IsNotTypeExpansionSensitive, DoesNotHaveRawPointer, IsLexical};
|
||||
}
|
||||
|
||||
static constexpr SILTypeProperties forOpaque() {
|
||||
return {IsNotTrivial, IsNotFixedABI, IsAddressOnly, IsNotResilient,
|
||||
IsNotTypeExpansionSensitive, HasRawPointer, IsLexical,
|
||||
HasNoPack, IsAddressableForDependencies};
|
||||
}
|
||||
|
||||
static constexpr SILTypeProperties forResilient() {
|
||||
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsResilient,
|
||||
IsNotTypeExpansionSensitive, HasRawPointer, IsNotLexical,
|
||||
HasNoPack, IsNotAddressableForDependencies};
|
||||
}
|
||||
|
||||
void addSubobject(SILTypeProperties other) {
|
||||
Flags |= other.Flags;
|
||||
}
|
||||
|
||||
IsTrivial_t isTrivial() const {
|
||||
return IsTrivial_t((Flags & NonTrivialFlag) == 0);
|
||||
}
|
||||
HasRawPointer_t isOrContainsRawPointer() const {
|
||||
return HasRawPointer_t((Flags & HasRawPointerFlag) != 0);
|
||||
}
|
||||
IsFixedABI_t isFixedABI() const {
|
||||
return IsFixedABI_t((Flags & NonFixedABIFlag) == 0);
|
||||
}
|
||||
IsAddressOnly_t isAddressOnly() const {
|
||||
return IsAddressOnly_t((Flags & AddressOnlyFlag) != 0);
|
||||
}
|
||||
bool isLoadable() const {
|
||||
return !isAddressOnly();
|
||||
}
|
||||
IsResilient_t isResilient() const {
|
||||
return IsResilient_t((Flags & ResilientFlag) != 0);
|
||||
}
|
||||
IsTypeExpansionSensitive_t isTypeExpansionSensitive() const {
|
||||
return IsTypeExpansionSensitive_t(
|
||||
(Flags & TypeExpansionSensitiveFlag) != 0);
|
||||
}
|
||||
IsInfiniteType_t isInfinite() const {
|
||||
return IsInfiniteType_t((Flags & InfiniteFlag) != 0);
|
||||
}
|
||||
IsLexical_t isLexical() const {
|
||||
return IsLexical_t((Flags & LexicalFlag) != 0);
|
||||
}
|
||||
HasPack_t isOrContainsPack() const {
|
||||
return HasPack_t((Flags & HasPackFlag) != 0);
|
||||
}
|
||||
IsAddressableForDependencies_t isAddressableForDependencies() const {
|
||||
return IsAddressableForDependencies_t(
|
||||
(Flags & AddressableForDependenciesFlag) != 0);
|
||||
}
|
||||
|
||||
void setNonTrivial() { Flags |= NonTrivialFlag; }
|
||||
void setIsOrContainsRawPointer() { Flags |= HasRawPointerFlag; }
|
||||
|
||||
void setNonFixedABI() { Flags |= NonFixedABIFlag; }
|
||||
void setAddressOnly() { Flags |= AddressOnlyFlag; }
|
||||
void setTypeExpansionSensitive(
|
||||
IsTypeExpansionSensitive_t isTypeExpansionSensitive) {
|
||||
Flags = (Flags & ~TypeExpansionSensitiveFlag) |
|
||||
(isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0);
|
||||
}
|
||||
void setInfinite() { Flags |= InfiniteFlag; }
|
||||
void setLexical(IsLexical_t isLexical) {
|
||||
Flags = (Flags & ~LexicalFlag) | (isLexical ? LexicalFlag : 0);
|
||||
}
|
||||
void setHasPack() { Flags |= HasPackFlag; }
|
||||
void setAddressableForDependencies() {
|
||||
Flags |= AddressableForDependenciesFlag;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace swift
|
||||
|
||||
#endif
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "swift/SIL/SILDeclRef.h"
|
||||
#include "swift/SIL/SILInstruction.h"
|
||||
#include "swift/SIL/SILLocation.h"
|
||||
#include "swift/SIL/SILTypeProperties.h"
|
||||
#include "swift/SIL/SILValue.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/Hashing.h"
|
||||
@@ -92,240 +93,8 @@ adjustFunctionType(CanSILFunctionType t, SILFunctionType::Representation rep,
|
||||
witnessMethodConformance);
|
||||
}
|
||||
|
||||
/// Is a lowered SIL type trivial? That is, are copies ultimately just
|
||||
/// bit-copies, and it takes no work to destroy a value?
|
||||
enum IsTrivial_t : bool {
|
||||
IsNotTrivial = false,
|
||||
IsTrivial = true
|
||||
};
|
||||
|
||||
/// Is a lowered SIL type the Builtin.RawPointer or a struct/tuple/enum which
|
||||
/// contains a Builtin.RawPointer?
|
||||
/// HasRawPointer is true only for types that are known to contain
|
||||
/// Builtin.RawPointer. It is not assumed true for generic or resilient types.
|
||||
enum HasRawPointer_t : bool {
|
||||
DoesNotHaveRawPointer = false,
|
||||
HasRawPointer = true
|
||||
};
|
||||
|
||||
/// Is a lowered SIL type fixed-ABI? That is, can the current context
|
||||
/// assign it a fixed size and alignment and perform value operations on it
|
||||
/// (such as copies, destroys, constructions, and projections) without
|
||||
/// metadata?
|
||||
///
|
||||
/// Note that a fully concrete type can be non-fixed-ABI without being
|
||||
/// itself resilient if it contains a subobject which is not fixed-ABI.
|
||||
///
|
||||
/// Also note that we're only concerned with the external value ABI here:
|
||||
/// resilient class types are still fixed-ABI, indirect enum cases do not
|
||||
/// affect the fixed-ABI-ness of the enum, and so on.
|
||||
enum IsFixedABI_t : bool {
|
||||
IsNotFixedABI = false,
|
||||
IsFixedABI = true
|
||||
};
|
||||
|
||||
/// Is a lowered SIL type address-only? That is, is the current context
|
||||
/// required to keep the value in memory for some reason?
|
||||
///
|
||||
/// A type might be address-only because:
|
||||
///
|
||||
/// - it is not fixed-size (e.g. because it is a resilient type) and
|
||||
/// therefore cannot be loaded into a statically-boundable set of
|
||||
/// registers; or
|
||||
///
|
||||
/// - it is semantically bound to memory, either because its storage
|
||||
/// address is used by the language runtime to implement its semantics
|
||||
/// (as with a weak reference) or because its representation is somehow
|
||||
/// address-dependent (as with something like a relative pointer).
|
||||
///
|
||||
/// An address-only type can be fixed-layout and/or trivial.
|
||||
/// A non-fixed-layout type is always address-only.
|
||||
enum IsAddressOnly_t : bool {
|
||||
IsNotAddressOnly = false,
|
||||
IsAddressOnly = true
|
||||
};
|
||||
|
||||
/// Is this type somewhat like a reference-counted type?
|
||||
enum IsReferenceCounted_t : bool {
|
||||
IsNotReferenceCounted = false,
|
||||
IsReferenceCounted = true
|
||||
};
|
||||
|
||||
/// Is this type address only because it's resilient?
|
||||
enum IsResilient_t : bool {
|
||||
IsNotResilient = false,
|
||||
IsResilient = true
|
||||
};
|
||||
|
||||
/// Does this type contain an opaque result type that affects type lowering?
|
||||
enum IsTypeExpansionSensitive_t : bool {
|
||||
IsNotTypeExpansionSensitive = false,
|
||||
IsTypeExpansionSensitive = true
|
||||
};
|
||||
|
||||
/// Is the type infinitely defined in terms of itself? (Such types can never
|
||||
/// be concretely instantiated, but may still arise from generic specialization.)
|
||||
enum IsInfiniteType_t : bool {
|
||||
IsNotInfiniteType = false,
|
||||
IsInfiniteType = true,
|
||||
};
|
||||
|
||||
/// Does this type contain any pack-like thing.
|
||||
enum HasPack_t : bool {
|
||||
HasNoPack = false,
|
||||
HasPack = true,
|
||||
};
|
||||
|
||||
/// Is the type addressable-for-dependencies?
|
||||
///
|
||||
/// Values of an addressable-for-dependency type are passed indirectly into
|
||||
/// functions that specify a return value lifetime dependency on the value.
|
||||
/// This allows the dependent value to safely contain pointers to the in-memory
|
||||
/// representation of the source of the dependency.
|
||||
enum IsAddressableForDependencies_t : bool {
|
||||
IsNotAddressableForDependencies = false,
|
||||
IsAddressableForDependencies = true,
|
||||
};
|
||||
|
||||
/// Extended type information used by SIL.
|
||||
class TypeLowering {
|
||||
public:
|
||||
class RecursiveProperties {
|
||||
// These are chosen so that bitwise-or merges the flags properly.
|
||||
//
|
||||
// clang-format off
|
||||
enum : unsigned {
|
||||
NonTrivialFlag = 1 << 0,
|
||||
NonFixedABIFlag = 1 << 1,
|
||||
AddressOnlyFlag = 1 << 2,
|
||||
ResilientFlag = 1 << 3,
|
||||
TypeExpansionSensitiveFlag = 1 << 4,
|
||||
InfiniteFlag = 1 << 5,
|
||||
HasRawPointerFlag = 1 << 6,
|
||||
LexicalFlag = 1 << 7,
|
||||
HasPackFlag = 1 << 8,
|
||||
AddressableForDependenciesFlag = 1 << 9,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
uint16_t Flags;
|
||||
|
||||
public:
|
||||
/// Construct a default RecursiveProperties, which corresponds to
|
||||
/// a trivial, loadable, fixed-layout type.
|
||||
constexpr RecursiveProperties() : Flags(0) {}
|
||||
|
||||
constexpr RecursiveProperties(
|
||||
IsTrivial_t isTrivial, IsFixedABI_t isFixedABI,
|
||||
IsAddressOnly_t isAddressOnly, IsResilient_t isResilient,
|
||||
IsTypeExpansionSensitive_t isTypeExpansionSensitive =
|
||||
IsNotTypeExpansionSensitive,
|
||||
HasRawPointer_t hasRawPointer = DoesNotHaveRawPointer,
|
||||
IsLexical_t isLexical = IsNotLexical, HasPack_t hasPack = HasNoPack,
|
||||
IsAddressableForDependencies_t isAFD = IsNotAddressableForDependencies)
|
||||
: Flags((isTrivial ? 0U : NonTrivialFlag) |
|
||||
(isFixedABI ? 0U : NonFixedABIFlag) |
|
||||
(isAddressOnly ? AddressOnlyFlag : 0U) |
|
||||
(isResilient ? ResilientFlag : 0U) |
|
||||
(isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0U) |
|
||||
(hasRawPointer ? HasRawPointerFlag : 0U) |
|
||||
(isLexical ? LexicalFlag : 0U) |
|
||||
(hasPack ? HasPackFlag : 0U) |
|
||||
(isAFD ? AddressableForDependenciesFlag : 0U)) {}
|
||||
|
||||
constexpr bool operator==(RecursiveProperties p) const {
|
||||
return Flags == p.Flags;
|
||||
}
|
||||
|
||||
static constexpr RecursiveProperties forTrivial() {
|
||||
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient};
|
||||
}
|
||||
|
||||
static constexpr RecursiveProperties forTrivialOpaque() {
|
||||
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient,
|
||||
IsNotTypeExpansionSensitive, HasRawPointer, IsNotLexical,
|
||||
HasNoPack, IsAddressableForDependencies};
|
||||
}
|
||||
|
||||
static constexpr RecursiveProperties forRawPointer() {
|
||||
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient,
|
||||
IsNotTypeExpansionSensitive, HasRawPointer};
|
||||
}
|
||||
|
||||
static constexpr RecursiveProperties forReference() {
|
||||
return {IsNotTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient,
|
||||
IsNotTypeExpansionSensitive, DoesNotHaveRawPointer, IsLexical};
|
||||
}
|
||||
|
||||
static constexpr RecursiveProperties forOpaque() {
|
||||
return {IsNotTrivial, IsNotFixedABI, IsAddressOnly, IsNotResilient,
|
||||
IsNotTypeExpansionSensitive, HasRawPointer, IsLexical,
|
||||
HasNoPack, IsAddressableForDependencies};
|
||||
}
|
||||
|
||||
static constexpr RecursiveProperties forResilient() {
|
||||
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsResilient,
|
||||
IsNotTypeExpansionSensitive, HasRawPointer, IsNotLexical,
|
||||
HasNoPack, IsNotAddressableForDependencies};
|
||||
}
|
||||
|
||||
void addSubobject(RecursiveProperties other) {
|
||||
Flags |= other.Flags;
|
||||
}
|
||||
|
||||
IsTrivial_t isTrivial() const {
|
||||
return IsTrivial_t((Flags & NonTrivialFlag) == 0);
|
||||
}
|
||||
HasRawPointer_t isOrContainsRawPointer() const {
|
||||
return HasRawPointer_t((Flags & HasRawPointerFlag) != 0);
|
||||
}
|
||||
IsFixedABI_t isFixedABI() const {
|
||||
return IsFixedABI_t((Flags & NonFixedABIFlag) == 0);
|
||||
}
|
||||
IsAddressOnly_t isAddressOnly() const {
|
||||
return IsAddressOnly_t((Flags & AddressOnlyFlag) != 0);
|
||||
}
|
||||
IsResilient_t isResilient() const {
|
||||
return IsResilient_t((Flags & ResilientFlag) != 0);
|
||||
}
|
||||
IsTypeExpansionSensitive_t isTypeExpansionSensitive() const {
|
||||
return IsTypeExpansionSensitive_t(
|
||||
(Flags & TypeExpansionSensitiveFlag) != 0);
|
||||
}
|
||||
IsInfiniteType_t isInfinite() const {
|
||||
return IsInfiniteType_t((Flags & InfiniteFlag) != 0);
|
||||
}
|
||||
IsLexical_t isLexical() const {
|
||||
return IsLexical_t((Flags & LexicalFlag) != 0);
|
||||
}
|
||||
HasPack_t isOrContainsPack() const {
|
||||
return HasPack_t((Flags & HasPackFlag) != 0);
|
||||
}
|
||||
IsAddressableForDependencies_t isAddressableForDependencies() const {
|
||||
return IsAddressableForDependencies_t(
|
||||
(Flags & AddressableForDependenciesFlag) != 0);
|
||||
}
|
||||
|
||||
void setNonTrivial() { Flags |= NonTrivialFlag; }
|
||||
void setIsOrContainsRawPointer() { Flags |= HasRawPointerFlag; }
|
||||
|
||||
void setNonFixedABI() { Flags |= NonFixedABIFlag; }
|
||||
void setAddressOnly() { Flags |= AddressOnlyFlag; }
|
||||
void setTypeExpansionSensitive(
|
||||
IsTypeExpansionSensitive_t isTypeExpansionSensitive) {
|
||||
Flags = (Flags & ~TypeExpansionSensitiveFlag) |
|
||||
(isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0);
|
||||
}
|
||||
void setInfinite() { Flags |= InfiniteFlag; }
|
||||
void setLexical(IsLexical_t isLexical) {
|
||||
Flags = (Flags & ~LexicalFlag) | (isLexical ? LexicalFlag : 0);
|
||||
}
|
||||
void setHasPack() { Flags |= HasPackFlag; }
|
||||
void setAddressableForDependencies() {
|
||||
Flags |= AddressableForDependenciesFlag;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
friend class TypeConverter;
|
||||
|
||||
@@ -336,7 +105,7 @@ protected:
|
||||
mutable SILType LoweredType;
|
||||
|
||||
private:
|
||||
RecursiveProperties Properties;
|
||||
SILTypeProperties Properties;
|
||||
|
||||
/// The resilience expansion for this type lowering.
|
||||
/// If the type is not resilient at all, this is always Minimal.
|
||||
@@ -349,7 +118,7 @@ private:
|
||||
mutable const TypeLowering *NextExpansion = nullptr;
|
||||
|
||||
protected:
|
||||
TypeLowering(SILType type, RecursiveProperties properties,
|
||||
TypeLowering(SILType type, SILTypeProperties properties,
|
||||
IsReferenceCounted_t isRefCounted,
|
||||
TypeExpansionContext expansionContext)
|
||||
: LoweredType(type), Properties(properties),
|
||||
@@ -367,7 +136,7 @@ public:
|
||||
/// Dump out the internal state of this type lowering to llvm::dbgs().
|
||||
SWIFT_DEBUG_DUMP;
|
||||
|
||||
RecursiveProperties getRecursiveProperties() const {
|
||||
SILTypeProperties getRecursiveProperties() const {
|
||||
return Properties;
|
||||
}
|
||||
|
||||
@@ -382,7 +151,7 @@ public:
|
||||
/// full layout is available to the compiler. This is the inverse of
|
||||
/// isAddressOnly.
|
||||
bool isLoadable() const {
|
||||
return !isAddressOnly();
|
||||
return Properties.isLoadable();
|
||||
}
|
||||
|
||||
/// isFixedABI - Returns true if the type has a known fixed layout.
|
||||
@@ -1071,6 +840,14 @@ public:
|
||||
return ti.getLoweredType();
|
||||
}
|
||||
|
||||
SILTypeProperties getTypeProperties(AbstractionPattern origType,
|
||||
Type substType,
|
||||
TypeExpansionContext forExpansion);
|
||||
SILTypeProperties getTypeProperties(Type substType,
|
||||
TypeExpansionContext forExpansion);
|
||||
SILTypeProperties getTypeProperties(SILType type,
|
||||
TypeExpansionContext forExpansion);
|
||||
|
||||
CanType getLoweredRValueType(TypeExpansionContext context, Type t) {
|
||||
return getLoweredType(t, context).getRawASTType();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user