Skip to content

Commit 3b2e409

Browse files
committed
TypeLowering: add a recursive property to check if a type contains a RawPointer
This is needed for the new escape analysis
1 parent 003fdec commit 3b2e409

File tree

7 files changed

+65
-3
lines changed

7 files changed

+65
-3
lines changed

SwiftCompilerSources/Sources/SIL/Type.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ public struct Type : CustomStringConvertible, CustomReflectable {
2727
return SILType_isReferenceCounted(bridged, function.bridged) != 0
2828
}
2929

30+
public func isNonTrivialOrContainsRawPointer(in function: Function) -> Bool {
31+
return SILType_isNonTrivialOrContainsRawPointer(bridged, function.bridged) != 0
32+
}
33+
3034
public var isNominal: Bool { SILType_isNominal(bridged) != 0 }
3135
public var isClass: Bool { SILType_isClass(bridged) != 0 }
3236
public var isStruct: Bool { SILType_isStruct(bridged) != 0 }

include/swift/SIL/SILBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ BridgedStringRef SILType_debugDescription(BridgedType);
219219
SwiftInt SILType_isAddress(BridgedType);
220220
SwiftInt SILType_isTrivial(BridgedType, BridgedFunction);
221221
SwiftInt SILType_isReferenceCounted(BridgedType type, BridgedFunction);
222+
SwiftInt SILType_isNonTrivialOrContainsRawPointer(BridgedType, BridgedFunction);
222223
SwiftInt SILType_isNominal(BridgedType type);
223224
SwiftInt SILType_isClass(BridgedType type);
224225
SwiftInt SILType_isStruct(BridgedType type);

include/swift/SIL/SILType.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,15 @@ class SILType {
308308
/// even though they are technically trivial.
309309
bool isTrivial(const SILFunction &F) const;
310310

311+
/// True if the type is the Builtin.RawPointer or a struct/tuple/enum which
312+
/// contains a Builtin.RawPointer.
313+
/// Returns false for types for which this property is not known, e.g. generic
314+
/// types.
315+
bool isOrContainsRawPointer(const SILFunction &F) const;
316+
317+
/// An efficient implementation of `!isTrivial() && isOrContainsRawPointer()`.
318+
bool isNonTrivialOrContainsRawPointer(const SILFunction &F) const;
319+
311320
/// True if the type is an empty tuple or an empty struct or a tuple or
312321
/// struct containing only empty types.
313322
bool isEmpty(const SILFunction &F) const;

include/swift/SIL/TypeLowering.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ enum IsTrivial_t : bool {
9898
IsTrivial = true
9999
};
100100

101+
/// Is a lowered SIL type the Builtin.RawPointer or a struct/tuple/enum which
102+
/// contains a Builtin.RawPointer?
103+
/// HasRawPointer is true only for types that are known to contain
104+
/// Builtin.RawPointer. It is not assumed true for generic or resilient types.
105+
enum HasRawPointer_t : bool {
106+
DoesNotHaveRawPointer = false,
107+
HasRawPointer = true
108+
};
109+
101110
/// Is a lowered SIL type fixed-ABI? That is, can the current context
102111
/// assign it a fixed size and alignment and perform value operations on it
103112
/// (such as copies, destroys, constructions, and projections) without
@@ -172,6 +181,7 @@ class TypeLowering {
172181
ResilientFlag = 1 << 3,
173182
TypeExpansionSensitiveFlag = 1 << 4,
174183
InfiniteFlag = 1 << 5,
184+
HasRawPointerFlag = 1 << 6,
175185
};
176186

177187
uint8_t Flags;
@@ -184,12 +194,14 @@ class TypeLowering {
184194
IsTrivial_t isTrivial, IsFixedABI_t isFixedABI,
185195
IsAddressOnly_t isAddressOnly, IsResilient_t isResilient,
186196
IsTypeExpansionSensitive_t isTypeExpansionSensitive =
187-
IsNotTypeExpansionSensitive)
197+
IsNotTypeExpansionSensitive,
198+
HasRawPointer_t hasRawPointer = DoesNotHaveRawPointer)
188199
: Flags((isTrivial ? 0U : NonTrivialFlag) |
189200
(isFixedABI ? 0U : NonFixedABIFlag) |
190201
(isAddressOnly ? AddressOnlyFlag : 0U) |
191202
(isResilient ? ResilientFlag : 0U) |
192-
(isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0U)) {}
203+
(isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0U) |
204+
(hasRawPointer ? HasRawPointerFlag : 0U)) {}
193205

194206
constexpr bool operator==(RecursiveProperties p) const {
195207
return Flags == p.Flags;
@@ -199,6 +211,11 @@ class TypeLowering {
199211
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient};
200212
}
201213

214+
static constexpr RecursiveProperties forRawPointer() {
215+
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient,
216+
IsNotTypeExpansionSensitive, HasRawPointer};
217+
}
218+
202219
static constexpr RecursiveProperties forReference() {
203220
return {IsNotTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient};
204221
}
@@ -219,6 +236,9 @@ class TypeLowering {
219236
IsTrivial_t isTrivial() const {
220237
return IsTrivial_t((Flags & NonTrivialFlag) == 0);
221238
}
239+
IsTrivial_t isOrContainsRawPointer() const {
240+
return IsTrivial_t((Flags & HasRawPointerFlag) != 0);
241+
}
222242
IsFixedABI_t isFixedABI() const {
223243
return IsFixedABI_t((Flags & NonFixedABIFlag) == 0);
224244
}
@@ -315,6 +335,10 @@ class TypeLowering {
315335
return Properties.isTrivial();
316336
}
317337

338+
bool isOrContainsRawPointer() const {
339+
return Properties.isOrContainsRawPointer();
340+
}
341+
318342
/// Returns true if the type is a scalar reference-counted reference, which
319343
/// can be retained and released.
320344
bool isReferenceCounted() const {

lib/SIL/IR/SILType.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,17 @@ bool SILType::isTrivial(const SILFunction &F) const {
108108
return F.getTypeLowering(contextType).isTrivial();
109109
}
110110

111+
bool SILType::isOrContainsRawPointer(const SILFunction &F) const {
112+
auto contextType = hasTypeParameter() ? F.mapTypeIntoContext(*this) : *this;
113+
return F.getTypeLowering(contextType).isOrContainsRawPointer();
114+
}
115+
116+
bool SILType::isNonTrivialOrContainsRawPointer(const SILFunction &F) const {
117+
auto contextType = hasTypeParameter() ? F.mapTypeIntoContext(*this) : *this;
118+
const TypeLowering &tyLowering = F.getTypeLowering(contextType);
119+
return !tyLowering.isTrivial() || tyLowering.isOrContainsRawPointer();
120+
}
121+
111122
bool SILType::isEmpty(const SILFunction &F) const {
112123
// Infinite types are never empty.
113124
if (F.getTypeLowering(*this).getRecursiveProperties().isInfinite()) {

lib/SIL/IR/TypeLowering.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,6 @@ namespace {
244244
IMPL(BuiltinInteger, Trivial)
245245
IMPL(BuiltinIntegerLiteral, Trivial)
246246
IMPL(BuiltinFloat, Trivial)
247-
IMPL(BuiltinRawPointer, Trivial)
248247
IMPL(BuiltinRawUnsafeContinuation, Trivial)
249248
IMPL(BuiltinJob, Trivial)
250249
IMPL(BuiltinExecutor, Trivial)
@@ -259,6 +258,14 @@ namespace {
259258

260259
#undef IMPL
261260

261+
RetTy visitBuiltinRawPointerType(CanBuiltinRawPointerType type,
262+
AbstractionPattern orig,
263+
IsTypeExpansionSensitive_t isSensitive) {
264+
RecursiveProperties props = mergeIsTypeExpansionSensitive(isSensitive,
265+
RecursiveProperties::forRawPointer());
266+
return asImpl().handleTrivial(type, props);
267+
}
268+
262269
RetTy visitBuiltinUnsafeValueBufferType(
263270
CanBuiltinUnsafeValueBufferType type,
264271
AbstractionPattern origType,

lib/SIL/Utils/SILBridging.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,12 @@ SwiftInt SILType_isReferenceCounted(BridgedType type, BridgedFunction function)
371371
return castToSILType(type).isReferenceCounted(f->getModule()) ? 1 : 0;
372372
}
373373

374+
SwiftInt SILType_isNonTrivialOrContainsRawPointer(BridgedType type,
375+
BridgedFunction function) {
376+
SILFunction *f = castToFunction(function);
377+
return castToSILType(type).isNonTrivialOrContainsRawPointer(*f);
378+
}
379+
374380
SwiftInt SILType_isNominal(BridgedType type) {
375381
return castToSILType(type).getNominalOrBoundGenericNominal() ? 1 : 0;
376382
}

0 commit comments

Comments
 (0)