Skip to content

Commit 29741f7

Browse files
Merge pull request #63935 from aschwaighofer/resolve_rebranch
Merge remote-tracking branch 'origin/main' into rebranch
2 parents a8be454 + 1dfc30e commit 29741f7

File tree

307 files changed

+6349
-3556
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

307 files changed

+6349
-3556
lines changed

SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,14 @@ struct AliasAnalysis {
9898
},
9999

100100
// isAddrVisibleFromObj
101-
{ (bridgedCtxt: BridgedPassContext, bridgedAddr: BridgedValue, bridgedObj: BridgedValue) -> Bool in
101+
{ (bridgedCtxt: BridgedPassContext, bridgedAddr: BridgedValue, bridgedObj: BridgedValue, complexityBudget: Int) -> Bool in
102102
let context = FunctionPassContext(_bridged: bridgedCtxt)
103103
let addr = bridgedAddr.value.at(AliasAnalysis.getPtrOrAddressPath(for: bridgedAddr.value))
104104

105105
// This is similar to `canReferenceSameFieldFn`, except that all addresses of all objects are
106106
// considered which are transitively visible from `bridgedObj`.
107107
let anythingReachableFromObj = bridgedObj.value.at(SmallProjectionPath(.anything))
108-
return addr.canAddressAlias(with: anythingReachableFromObj, context)
108+
return addr.canAddressAlias(with: anythingReachableFromObj, complexityBudget: complexityBudget, context)
109109
},
110110

111111
// canReferenceSameFieldFn

SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeUtils.swift

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ extension ProjectedValue {
7575
/// the walk. See `EscapeVisitor` for details.
7676
///
7777
func isEscaping(using visitor: some EscapeVisitor = DefaultVisitor(),
78+
complexityBudget: Int = Int.max,
7879
_ context: some Context) -> Bool {
79-
var walker = EscapeWalker(visitor: visitor, context)
80+
var walker = EscapeWalker(visitor: visitor, complexityBudget: complexityBudget, context)
8081
return walker.walkUp(addressOrValue: value, path: path.escapePath) == .abortWalk
8182
}
8283

@@ -287,9 +288,10 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
287288
AddressUseDefWalker {
288289
typealias Path = EscapeUtilityTypes.EscapePath
289290

290-
init(visitor: V, _ context: some Context) {
291+
init(visitor: V, complexityBudget: Int = Int.max, _ context: some Context) {
291292
self.calleeAnalysis = context.calleeAnalysis
292293
self.visitor = visitor
294+
self.complexityBudget = complexityBudget
293295
}
294296

295297
//===--------------------------------------------------------------------===//
@@ -313,6 +315,9 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
313315
}
314316

315317
mutating func walkDown(value: Operand, path: Path) -> WalkResult {
318+
if complexityBudgetExceeded(value.value) {
319+
return .abortWalk
320+
}
316321
if hasRelevantType(value.value, at: path.projectionPath) {
317322
switch visitor.visitUse(operand: value, path: path) {
318323
case .continueWalk:
@@ -409,6 +414,9 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
409414
}
410415

411416
mutating func walkDown(address: Operand, path: Path) -> WalkResult {
417+
if complexityBudgetExceeded(address.value) {
418+
return .abortWalk
419+
}
412420
if hasRelevantType(address.value, at: path.projectionPath) {
413421
switch visitor.visitUse(operand: address, path: path) {
414422
case .continueWalk:
@@ -508,7 +516,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
508516
return .continueWalk
509517
}
510518
if !visitor.followLoads && p.matches(pattern: SmallProjectionPath(.anyValueFields).push(.anyClassField)) {
511-
// Any address of a class property of the object to destroy cannot esacpe the destructor.
519+
// Any address of a class property of the object to destroy cannot escape the destructor.
512520
// (Whereas a value stored in such a property could escape.)
513521
return .continueWalk
514522
}
@@ -644,6 +652,9 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
644652
}
645653

646654
mutating func walkUp(value: Value, path: Path) -> WalkResult {
655+
if complexityBudgetExceeded(value) {
656+
return .abortWalk
657+
}
647658
if hasRelevantType(value, at: path.projectionPath) {
648659
switch visitor.visitDef(def: value, path: path) {
649660
case .continueWalkUp:
@@ -697,6 +708,9 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
697708
}
698709

699710
mutating func walkUp(address: Value, path: Path) -> WalkResult {
711+
if complexityBudgetExceeded(address) {
712+
return .abortWalk
713+
}
700714
if hasRelevantType(address, at: path.projectionPath) {
701715
switch visitor.visitDef(def: address, path: path) {
702716
case .continueWalkUp:
@@ -785,6 +799,10 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
785799
var walkDownCache = WalkerCache<Path>()
786800
var walkUpCache = WalkerCache<Path>()
787801

802+
// Only this number of up/and down walks are done until the walk aborts.
803+
// Used to avoid quadratic complexity in some scenarios.
804+
var complexityBudget: Int
805+
788806
private let calleeAnalysis: CalleeAnalysis
789807

790808
//===--------------------------------------------------------------------===//
@@ -825,6 +843,14 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
825843
return path.popLastClassAndValuesFromTail()
826844
}
827845

846+
private mutating func complexityBudgetExceeded(_ v: Value) -> Bool {
847+
if complexityBudget <= 0 {
848+
return true
849+
}
850+
complexityBudget = complexityBudget &- 1
851+
return false
852+
}
853+
828854
// Set a breakpoint here to debug when a value is escaping.
829855
private var isEscaping: WalkResult { .abortWalk }
830856
}

SwiftCompilerSources/Sources/Optimizer/Utilities/OptUtils.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,15 +221,15 @@ extension ProjectedValue {
221221
/// `%s`.canAddressAlias(with: `%2`) -> true
222222
/// `%1`.canAddressAlias(with: `%2`) -> false
223223
///
224-
func canAddressAlias(with rhs: ProjectedValue, _ context: some Context) -> Bool {
224+
func canAddressAlias(with rhs: ProjectedValue, complexityBudget: Int = Int.max, _ context: some Context) -> Bool {
225225
// self -> rhs will succeed (= return false) if self is a non-escaping "local" object,
226226
// but not necessarily rhs.
227-
if !isEscaping(using: EscapesToValueVisitor(target: rhs), context) {
227+
if !isEscaping(using: EscapesToValueVisitor(target: rhs), complexityBudget: complexityBudget, context) {
228228
return false
229229
}
230230
// The other way round: rhs -> self will succeed if rhs is a non-escaping "local" object,
231231
// but not necessarily self.
232-
if !rhs.isEscaping(using: EscapesToValueVisitor(target: self), context) {
232+
if !rhs.isEscaping(using: EscapesToValueVisitor(target: self), complexityBudget: complexityBudget, context) {
233233
return false
234234
}
235235
return true

docs/ABI/Mangling.rst

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -887,8 +887,10 @@ now codified into the ABI; the index 0 is therefore reserved.
887887

888888
::
889889

890-
generic-signature ::= requirement* 'l' // one generic parameter
891-
generic-signature ::= requirement* 'r' GENERIC-PARAM-COUNT* 'l'
890+
generic-signature ::= requirement* generic-param-pack-marker* 'l' // one generic parameter
891+
generic-signature ::= requirement* generic-param-pack-marker* 'r' GENERIC-PARAM-COUNT* 'l'
892+
893+
generic-param-pack-marker ::= 'Rv' GENERIC_PARAM-INDEX // generic parameter pack marker
892894

893895
GENERIC-PARAM-COUNT ::= 'z' // zero parameters
894896
GENERIC-PARAM-COUNT ::= INDEX // N+1 parameters
@@ -931,9 +933,11 @@ now codified into the ABI; the index 0 is therefore reserved.
931933
LAYOUT-SIZE ::= INDEX // Size only
932934
LAYOUT-SIZE-AND-ALIGNMENT ::= INDEX INDEX // Size followed by alignment
933935

936+
A generic signature begins with an optional list of requirements.
934937

938+
This is followed by an optional list of generic-param-pack-markers to record
939+
which generic parameters are packs (variadic).
935940

936-
A generic signature begins with an optional list of requirements.
937941
The ``<GENERIC-PARAM-COUNT>`` describes the number of generic parameters at
938942
each depth of the signature. As a special case, no ``<GENERIC-PARAM-COUNT>``
939943
values indicates a single generic parameter at the outermost depth::

docs/proposals/RuntimeValueWitness.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ copied, but do not need to be released or retained.
5858
I16 = 's',
5959
I32 = 'l',
6060
I64 = 'L',
61+
I128 = 'Q',
6162

6263
We also have reference types. While they are all 64bit sized, we need to
6364
differentiate between them because they have different ways of being

include/swift/ABI/Metadata.h

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,15 @@ struct MetadataDependency {
116116
}
117117
};
118118

119+
/// Prefix of a metadata header, containing a pointer to the
120+
/// type layout string.
121+
template <typename Runtime>
122+
struct TargetTypeMetadataLayoutPrefix {
123+
TargetSignedPointer<Runtime, const uint8_t *
124+
__ptrauth_swift_type_layout_string>
125+
layoutString;
126+
};
127+
119128
/// The header before a metadata object which appears on all type
120129
/// metadata. Note that heap metadata are not necessarily type
121130
/// metadata, even for objects of a heap type: for example, objects of
@@ -124,11 +133,25 @@ struct MetadataDependency {
124133
/// This case can be distinguished using the isTypeMetadata() flag
125134
/// on ClassMetadata.
126135
template <typename Runtime>
127-
struct TargetTypeMetadataHeader {
136+
struct TargetTypeMetadataHeaderBase {
128137
/// A pointer to the value-witnesses for this type. This is only
129138
/// present for type metadata.
130139
TargetPointer<Runtime, const ValueWitnessTable> ValueWitnesses;
131140
};
141+
142+
template <typename Runtime>
143+
struct TargetTypeMetadataHeader
144+
: TargetTypeMetadataLayoutPrefix<Runtime>,
145+
TargetTypeMetadataHeaderBase<Runtime> {
146+
147+
TargetTypeMetadataHeader() = default;
148+
constexpr TargetTypeMetadataHeader(
149+
const TargetTypeMetadataLayoutPrefix<Runtime> &layout,
150+
const TargetTypeMetadataHeaderBase<Runtime> &header)
151+
: TargetTypeMetadataLayoutPrefix<Runtime>(layout),
152+
TargetTypeMetadataHeaderBase<Runtime>(header) {}
153+
};
154+
132155
using TypeMetadataHeader = TargetTypeMetadataHeader<InProcess>;
133156

134157
/// A "full" metadata pointer is simply an adjusted address point on a
@@ -284,6 +307,17 @@ struct TargetMetadata {
284307
return isAnyKindOfClass(getKind());
285308
}
286309

310+
const uint8_t *getLayoutString() const {
311+
assert(hasLayoutString());
312+
if (isAnyClass()) {
313+
return asFullMetadata(
314+
reinterpret_cast<const TargetAnyClassMetadata<Runtime> *>(
315+
this))
316+
->layoutString;
317+
}
318+
return asFullMetadata(this)->layoutString;
319+
}
320+
287321
const ValueWitnessTable *getValueWitnesses() const {
288322
return asFullMetadata(this)->ValueWitnesses;
289323
}
@@ -295,6 +329,19 @@ struct TargetMetadata {
295329
void setValueWitnesses(const ValueWitnessTable *table) {
296330
asFullMetadata(this)->ValueWitnesses = table;
297331
}
332+
333+
void setLayoutString(const uint8_t *layoutString) {
334+
if (isAnyClass()) {
335+
asFullMetadata(reinterpret_cast<TargetAnyClassMetadata<Runtime> *>(this))
336+
->layoutString = layoutString;
337+
} else {
338+
asFullMetadata(this)->layoutString = layoutString;
339+
}
340+
}
341+
342+
bool hasLayoutString() const {
343+
return getTypeContextDescriptor()->hasLayoutString();
344+
}
298345

299346
// Define forwarders for value witnesses. These invoke this metadata's value
300347
// witness table with itself as the 'self' parameter.
@@ -445,7 +492,7 @@ struct TargetMetadata {
445492
/// The common structure of opaque metadata. Adds nothing.
446493
template <typename Runtime>
447494
struct TargetOpaqueMetadata {
448-
typedef TargetTypeMetadataHeader<Runtime> HeaderType;
495+
typedef TargetTypeMetadataHeaderBase<Runtime> HeaderType;
449496

450497
// We have to represent this as a member so we can list-initialize it.
451498
TargetMetadata<Runtime> base;
@@ -469,13 +516,16 @@ using HeapMetadataHeaderPrefix =
469516
/// The header present on all heap metadata.
470517
template <typename Runtime>
471518
struct TargetHeapMetadataHeader
472-
: TargetHeapMetadataHeaderPrefix<Runtime>,
473-
TargetTypeMetadataHeader<Runtime> {
519+
: TargetTypeMetadataLayoutPrefix<Runtime>,
520+
TargetHeapMetadataHeaderPrefix<Runtime>,
521+
TargetTypeMetadataHeaderBase<Runtime> {
474522
constexpr TargetHeapMetadataHeader(
523+
const TargetTypeMetadataLayoutPrefix<Runtime> &typeLayoutPrefix,
475524
const TargetHeapMetadataHeaderPrefix<Runtime> &heapPrefix,
476-
const TargetTypeMetadataHeader<Runtime> &typePrefix)
477-
: TargetHeapMetadataHeaderPrefix<Runtime>(heapPrefix),
478-
TargetTypeMetadataHeader<Runtime>(typePrefix) {}
525+
const TargetTypeMetadataHeaderBase<Runtime> &typePrefix)
526+
: TargetTypeMetadataLayoutPrefix<Runtime>(typeLayoutPrefix),
527+
TargetHeapMetadataHeaderPrefix<Runtime>(heapPrefix),
528+
TargetTypeMetadataHeaderBase<Runtime>(typePrefix) {}
479529
};
480530
using HeapMetadataHeader =
481531
TargetHeapMetadataHeader<InProcess>;
@@ -1511,6 +1561,7 @@ using MetatypeMetadata = TargetMetatypeMetadata<InProcess>;
15111561
template <typename Runtime>
15121562
struct TargetTupleTypeMetadata : public TargetMetadata<Runtime> {
15131563
using StoredSize = typename Runtime::StoredSize;
1564+
using HeaderType = TargetTypeMetadataHeaderBase<Runtime>;
15141565
TargetTupleTypeMetadata() = default;
15151566
constexpr TargetTupleTypeMetadata(const TargetMetadata<Runtime> &base,
15161567
uint32_t numElements,
@@ -1696,6 +1747,7 @@ struct TargetExistentialTypeMetadata
16961747
TargetExistentialTypeMetadata<Runtime>,
16971748
ConstTargetMetadataPointer<Runtime, TargetMetadata>,
16981749
TargetProtocolDescriptorRef<Runtime>> {
1750+
using HeaderType = TargetTypeMetadataHeaderBase<Runtime>;
16991751

17001752
private:
17011753
using ProtocolDescriptorRef = TargetProtocolDescriptorRef<Runtime>;
@@ -3642,6 +3694,10 @@ class TargetTypeContextDescriptor
36423694
return getTypeContextDescriptorFlags().hasCanonicalMetadataPrespecializations();
36433695
}
36443696

3697+
bool hasLayoutString() const {
3698+
return getTypeContextDescriptorFlags().hasLayoutString();
3699+
}
3700+
36453701
/// Given that this type has foreign metadata initialization, return the
36463702
/// control structure for it.
36473703
const TargetForeignMetadataInitialization<Runtime> &

include/swift/ABI/MetadataValues.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,8 @@ namespace SpecialPointerAuthDiscriminators {
14451445

14461446
// Relative protocol witness table descriminator
14471447
const uint16_t RelativeProtocolWitnessTable = 0xb830; // = 47152
1448+
1449+
const uint16_t TypeLayoutString = 0x8b65; // = 35685
14481450
}
14491451

14501452
/// The number of arguments that will be passed directly to a generic
@@ -1598,6 +1600,9 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
15981600
/// prespecializations.
15991601
HasCanonicalMetadataPrespecializations = 3,
16001602

1603+
/// Set if the metadata contains a pointer to a layout string
1604+
HasLayoutString = 4,
1605+
16011606
// Type-specific flags:
16021607

16031608
/// Set if the class is an actor.
@@ -1680,6 +1685,10 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
16801685

16811686
FLAGSET_DEFINE_FLAG_ACCESSORS(HasCanonicalMetadataPrespecializations, hasCanonicalMetadataPrespecializations, setHasCanonicalMetadataPrespecializations)
16821687

1688+
FLAGSET_DEFINE_FLAG_ACCESSORS(HasLayoutString,
1689+
hasLayoutString,
1690+
setHasLayoutString)
1691+
16831692
FLAGSET_DEFINE_FLAG_ACCESSORS(Class_HasVTable,
16841693
class_hasVTable,
16851694
class_setHasVTable)

include/swift/AST/GenericEnvironment.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ class OpaqueTypeDecl;
3838
class ElementArchetypeType;
3939
class OpenedArchetypeType;
4040
class PackArchetypeType;
41+
class PackExpansionType;
4142
class SILModule;
4243
class SILType;
44+
template <class> class CanTypeWrapper;
4345

4446
/// Query function suitable for use as a \c TypeSubstitutionFn that queries
4547
/// the mapping of interface types to archetypes.
@@ -310,6 +312,23 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
310312

311313
SWIFT_DEBUG_DUMP;
312314
};
315+
316+
/// A pair of an opened-element generic signature and an opened-element
317+
/// generic environment.
318+
struct OpenedElementContext {
319+
/// The opened-element environment for this expansion.
320+
GenericEnvironment *environment;
321+
322+
/// The opened-element signature for this expansion.
323+
CanGenericSignature signature;
324+
325+
/// Create a fresh opened element context from a contextual pack
326+
/// expansion type. This is useful when writing code that needs to
327+
/// break down the components of a pack expansion.
328+
static OpenedElementContext
329+
createForContextualExpansion(ASTContext &ctx,
330+
CanTypeWrapper<PackExpansionType> expansionType);
331+
};
313332

314333
} // end namespace swift
315334

include/swift/AST/IRGenOptions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ struct PointerAuthOptions : clang::PointerAuthOptions {
207207

208208
/// Relative protocol witness table descriminator.
209209
PointerAuthSchema RelativeProtocolWitnessTable;
210+
211+
/// Type layout string descriminator.
212+
PointerAuthSchema TypeLayoutString;
210213
};
211214

212215
enum class JITDebugArtifact : unsigned {
@@ -422,6 +425,9 @@ class IRGenOptions {
422425
/// Collocate metadata functions in their own section.
423426
unsigned CollocatedMetadataFunctions : 1;
424427

428+
/// Colocate type descriptors in their own section.
429+
unsigned ColocateTypeDescriptors : 1;
430+
425431
/// Use relative (and constant) protocol witness tables.
426432
unsigned UseRelativeProtocolWitnessTables : 1;
427433

@@ -497,6 +503,7 @@ class IRGenOptions {
497503
EmitGenericRODatas(false), NoPreallocatedInstantiationCaches(false),
498504
DisableReadonlyStaticObjects(false),
499505
CollocatedMetadataFunctions(false),
506+
ColocateTypeDescriptors(true),
500507
UseRelativeProtocolWitnessTables(false), CmdArgs(),
501508
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
502509
TypeInfoFilter(TypeInfoDumpFilter::All) {

0 commit comments

Comments
 (0)