Skip to content

Commit 4646bc7

Browse files
authored
Merge pull request #3739 from swiftwasm/main
[pull] swiftwasm from main
2 parents ad2e90a + fbd3837 commit 4646bc7

24 files changed

+568
-600
lines changed

include/swift/Basic/DAGNodeWorklist.h renamed to include/swift/Basic/GraphNodeWorklist.h

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- DAGNodeWorklist.h --------------------------------------*- C++ -*-===//
1+
//===--- GraphNodeWorklist.h ------------------------------------*- C++ -*-===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
@@ -10,8 +10,8 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#ifndef SWIFT_BASIC_DAGNODEWORKLIST_H
14-
#define SWIFT_BASIC_DAGNODEWORKLIST_H
13+
#ifndef SWIFT_BASIC_GRAPHNODEWORKLIST_H
14+
#define SWIFT_BASIC_GRAPHNODEWORKLIST_H
1515

1616
#include "swift/Basic/LLVM.h"
1717
#include "llvm/ADT/SmallPtrSet.h"
@@ -25,23 +25,22 @@
2525
///
2626
/// The primary API has two methods: intialize() and pop(). Others are provided
2727
/// for flexibility.
28-
///
29-
/// TODO: This also works well for cyclic graph traversal. Particularly CFG
30-
/// traversal. So we should probably just call it GraphNodeWorklist.
31-
template <typename T, unsigned SmallSize> struct DAGNodeWorklist {
28+
template <typename T, unsigned SmallSize>
29+
struct GraphNodeWorklist {
3230
llvm::SmallPtrSet<T, SmallSize> nodeVisited;
3331
llvm::SmallVector<T, SmallSize> nodeVector;
3432

35-
DAGNodeWorklist() = default;
33+
GraphNodeWorklist() = default;
3634

37-
DAGNodeWorklist(const DAGNodeWorklist &) = delete;
35+
GraphNodeWorklist(const GraphNodeWorklist &) = delete;
3836

3937
void initialize(T t) {
4038
clear();
4139
insert(t);
4240
}
4341

44-
template <typename R> void initializeRange(R &&range) {
42+
template <typename R>
43+
void initializeRange(R &&range) {
4544
clear();
4645
nodeVisited.insert(range.begin(), range.end());
4746
nodeVector.append(range.begin(), range.end());
@@ -64,4 +63,4 @@ template <typename T, unsigned SmallSize> struct DAGNodeWorklist {
6463
}
6564
};
6665

67-
#endif // SWIFT_BASIC_DAGNODEWORKLIST_H
66+
#endif // SWIFT_BASIC_GRAPHNODEWORKLIST_H

include/swift/SILOptimizer/Analysis/EscapeAnalysis.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,8 +1059,8 @@ class EscapeAnalysis : public BottomUpIPAnalysis {
10591059
// returns an instantiated array struct and unsafe pointer to the elements.
10601060
struct ArrayUninitCall {
10611061
SILValue arrayStorageRef;
1062-
TupleExtractInst *arrayStruct = nullptr;
1063-
TupleExtractInst *arrayElementPtr = nullptr;
1062+
SILValue arrayStruct = nullptr;
1063+
SILValue arrayElementPtr = nullptr;
10641064

10651065
bool isValid() const {
10661066
return arrayStorageRef && arrayStruct && arrayElementPtr;
@@ -1072,9 +1072,9 @@ class EscapeAnalysis : public BottomUpIPAnalysis {
10721072
ArrayUninitCall
10731073
canOptimizeArrayUninitializedCall(ApplyInst *ai);
10741074

1075-
/// Return true of this tuple_extract is the result of an optimizable
1075+
/// Return true of this tuple_extract/destructure_tuple is the result of an optimizable
10761076
/// @_semantics("array.uninitialized") call.
1077-
bool canOptimizeArrayUninitializedResult(TupleExtractInst *tei);
1077+
bool canOptimizeArrayUninitializedResult(SILInstruction *tei);
10781078

10791079
/// Handle a call to "@_semantics(array.uninitialized") precisely by mapping
10801080
/// each call result to a separate graph node and relating them to the

include/swift/SILOptimizer/Utils/CanonicalOSSALifetime.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
#ifndef SWIFT_SILOPTIMIZER_UTILS_CANONICALOSSALIFETIME_H
9797
#define SWIFT_SILOPTIMIZER_UTILS_CANONICALOSSALIFETIME_H
9898

99-
#include "swift/Basic/DAGNodeWorklist.h"
99+
#include "swift/Basic/GraphNodeWorklist.h"
100100
#include "swift/Basic/SmallPtrSetVector.h"
101101
#include "swift/SIL/PrunedLiveness.h"
102102
#include "swift/SIL/SILInstruction.h"
@@ -271,10 +271,10 @@ class CanonicalizeOSSALifetime {
271271
llvm::SmallPtrSet<DebugValueInst *, 8> debugValues;
272272

273273
/// Visited set for general def-use traversal that prevents revisiting values.
274-
DAGNodeWorklist<SILValue, 8> defUseWorklist;
274+
GraphNodeWorklist<SILValue, 8> defUseWorklist;
275275

276276
/// Visited set general CFG traversal that prevents revisiting blocks.
277-
DAGNodeWorklist<SILBasicBlock *, 8> blockWorklist;
277+
GraphNodeWorklist<SILBasicBlock *, 8> blockWorklist;
278278

279279
/// Pruned liveness for the extended live range including copies. For this
280280
/// purpose, only consuming instructions are considered "lifetime

include/swift/SILOptimizer/Utils/CanonicalizeBorrowScope.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#ifndef SWIFT_SILOPTIMIZER_UTILS_CANONICALIZEBORROWSCOPES_H
2828
#define SWIFT_SILOPTIMIZER_UTILS_CANONICALIZEBORROWSCOPES_H
2929

30-
#include "swift/Basic/DAGNodeWorklist.h"
30+
#include "swift/Basic/GraphNodeWorklist.h"
3131
#include "swift/Basic/SmallPtrSetVector.h"
3232
#include "swift/SIL/OwnershipUtils.h"
3333
#include "swift/SIL/PrunedLiveness.h"
@@ -69,10 +69,10 @@ class CanonicalizeBorrowScope {
6969
InstructionDeleter &deleter;
7070

7171
/// Visited set for general def-use traversal that prevents revisiting values.
72-
DAGNodeWorklist<SILValue, 8> defUseWorklist;
72+
GraphNodeWorklist<SILValue, 8> defUseWorklist;
7373

7474
/// Visited set general CFG traversal that prevents revisiting blocks.
75-
DAGNodeWorklist<SILBasicBlock *, 8> blockWorklist;
75+
GraphNodeWorklist<SILBasicBlock *, 8> blockWorklist;
7676

7777
/// Record any copies outside the borrow scope that were updated. This
7878
/// includes the outer copy that us used by outer uses and copies for any

include/swift/SILOptimizer/Utils/OwnershipOptUtils.h

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,10 @@ struct OwnershipFixupContext {
148148
InstModCallbacks &callbacks;
149149
DeadEndBlocks &deBlocks;
150150

151-
152-
// FIXME: remove these two vectors once BorrowedLifetimeExtender is used
153-
// everywhere.
154-
SmallVector<Operand *, 8> transitiveBorrowedUses;
155-
SmallVector<PhiOperand, 8> recursiveReborrows;
151+
// Cache the use-points for the lifetime of an inner guaranteed value (which
152+
// does not introduce a borrow scope) after checking validity. These will be
153+
// used again to extend the lifetime of the replacement value.
154+
SmallVector<Operand *, 8> guaranteedUsePoints;
156155

157156
/// Extra state initialized by OwnershipRAUWFixupHelper::get() that we use
158157
/// when RAUWing addresses. This ensures we do not need to recompute this
@@ -162,6 +161,8 @@ struct OwnershipFixupContext {
162161
/// compute all transitive address uses of oldValue. If we find that we do
163162
/// need this fixed up, then we will copy our interior pointer base value
164163
/// and use this to seed that new lifetime.
164+
///
165+
/// FIXME: shouldn't these already be covered by guaranteedUsePoints?
165166
SmallVector<Operand *, 8> allAddressUsesFromOldValue;
166167

167168
/// This is the interior pointer (e.g. ref_element_addr)
@@ -184,8 +185,7 @@ struct OwnershipFixupContext {
184185
: callbacks(callbacks), deBlocks(deBlocks) {}
185186

186187
void clear() {
187-
transitiveBorrowedUses.clear();
188-
recursiveReborrows.clear();
188+
guaranteedUsePoints.clear();
189189
extraAddressFixupInfo.allAddressUsesFromOldValue.clear();
190190
extraAddressFixupInfo.base = AccessBase();
191191
}
@@ -212,6 +212,8 @@ class OwnershipRAUWHelper {
212212
private:
213213
OwnershipFixupContext *ctx;
214214
SILValue oldValue;
215+
// newValue is the aspirational replacement. It might not be the actual
216+
// replacement after SILCombine fixups (like type casting) and OSSA fixups.
215217
SILValue newValue;
216218

217219
public:
@@ -253,21 +255,27 @@ class OwnershipRAUWHelper {
253255
/// Perform OSSA fixup on newValue and return a fixed-up value based that can
254256
/// be used to replace all uses of oldValue.
255257
///
256-
/// This is so that we can avoid creating "forwarding" transformation
257-
/// instructions before we know if we can perform the RAUW. Any such
258-
/// "forwarding" transformation must be performed upon \p newValue at \p
259-
/// oldValue's insertion point so that we can then here RAUW the transformed
260-
/// \p newValue.
258+
/// This is only used by clients that must transform \p newValue, such as
259+
/// adding type casts, before it can be used to replace \p oldValue.
260+
///
261+
/// \p rewrittenNewValue is only passed when the client needs to regenerate
262+
/// newValue after checking its RAUW validity, but before performing OSSA
263+
/// fixup on it.
264+
SILValue prepareReplacement(SILValue rewrittenNewValue = SILValue());
265+
266+
/// Perform the actual RAUW--replace all uses if \p oldValue.
267+
///
268+
/// Precondition: \p replacementValue is either invalid or has the same type
269+
/// as \p oldValue and is a valid OSSA replacement.
261270
SILBasicBlock::iterator
262-
perform(SingleValueInstruction *maybeTransformedNewValue = nullptr);
271+
perform(SILValue replacementValue = SILValue());
263272

264273
private:
265-
SILBasicBlock::iterator replaceAddressUses(SingleValueInstruction *oldValue,
266-
SILValue newValue);
267-
268274
void invalidate() {
269275
ctx = nullptr;
270276
}
277+
278+
SILValue getReplacementAddress();
271279
};
272280

273281
/// A utility composed ontop of OwnershipFixupContext that knows how to replace

lib/Driver/DarwinToolChains.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,11 +600,11 @@ toolchains::Darwin::addDeploymentTargetArgs(ArgStringList &Arguments,
600600
micro = 0;
601601
}
602602

603-
// Mac Catalyst was introduced with an iOS deployment target of 13.0;
603+
// Mac Catalyst was introduced with an iOS deployment target of 13.1;
604604
// the linker doesn't want to see a deployment target before that.
605605
if (major < 13) {
606606
major = 13;
607-
minor = 0;
607+
minor = 1;
608608
micro = 0;
609609
}
610610
} else {

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/SIL/OwnershipUtils.h"
14-
#include "swift/Basic/DAGNodeWorklist.h"
1514
#include "swift/Basic/Defer.h"
16-
#include "swift/Basic/DAGNodeWorklist.h"
15+
#include "swift/Basic/GraphNodeWorklist.h"
1716
#include "swift/Basic/SmallPtrSetVector.h"
1817
#include "swift/SIL/InstructionUtils.h"
1918
#include "swift/SIL/LinearLifetimeChecker.h"
@@ -179,7 +178,7 @@ bool swift::findInnerTransitiveGuaranteedUses(
179178
// grow exponentially without the membership check. It's fine to do this
180179
// membership check locally in this function (within a borrow scope) because
181180
// it isn't needed for the immediate uses, only the transitive uses.
182-
DAGNodeWorklist<Operand *, 8> worklist;
181+
GraphNodeWorklist<Operand *, 8> worklist;
183182
for (Operand *use : guaranteedValue->getUses()) {
184183
if (use->getOperandOwnership() != OperandOwnership::NonUse)
185184
worklist.insert(use);
@@ -1438,7 +1437,7 @@ void swift::findTransitiveReborrowBaseValuePairs(
14381437
void swift::visitTransitiveEndBorrows(
14391438
BorrowedValue beginBorrow,
14401439
function_ref<void(EndBorrowInst *)> visitEndBorrow) {
1441-
DAGNodeWorklist<SILValue, 4> worklist;
1440+
GraphNodeWorklist<SILValue, 4> worklist;
14421441
worklist.insert(beginBorrow.value);
14431442

14441443
while (!worklist.empty()) {

lib/SILOptimizer/Analysis/EscapeAnalysis.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,14 @@ SILValue EscapeAnalysis::getPointerBase(SILValue value) {
250250
}
251251
return pointerOperand;
252252
}
253+
case ValueKind::MultipleValueInstructionResult: {
254+
if (auto *dt = dyn_cast<DestructureTupleInst>(value)) {
255+
if (canOptimizeArrayUninitializedResult(dt))
256+
return SILValue();
257+
return dt->getOperand();
258+
}
259+
return SILValue();
260+
}
253261
default:
254262
return SILValue();
255263
}
@@ -1939,6 +1947,11 @@ EscapeAnalysis::canOptimizeArrayUninitializedCall(ApplyInst *ai) {
19391947
continue;
19401948
}
19411949
}
1950+
if (auto *dt = dyn_cast<DestructureTupleInst>(use->getUser())) {
1951+
call.arrayStruct = dt->getResult(0);
1952+
call.arrayElementPtr = dt->getResult(1);
1953+
continue;
1954+
}
19421955
// If there are any other uses, such as a release_value, erase the previous
19431956
// call info and bail out.
19441957
call.arrayStruct = nullptr;
@@ -1957,8 +1970,9 @@ EscapeAnalysis::canOptimizeArrayUninitializedCall(ApplyInst *ai) {
19571970
}
19581971

19591972
bool EscapeAnalysis::canOptimizeArrayUninitializedResult(
1960-
TupleExtractInst *tei) {
1961-
ApplyInst *ai = dyn_cast<ApplyInst>(tei->getOperand());
1973+
SILInstruction *extract) {
1974+
assert(isa<TupleExtractInst>(extract) || isa<DestructureTupleInst>(extract));
1975+
ApplyInst *ai = dyn_cast<ApplyInst>(extract->getOperand(0));
19621976
if (!ai)
19631977
return false;
19641978

@@ -2362,11 +2376,17 @@ void EscapeAnalysis::analyzeInstruction(SILInstruction *I,
23622376
// This is a tuple_extract which extracts the second result of an
23632377
// array.uninitialized call (otherwise getPointerBase should have already
23642378
// looked through it).
2365-
auto *TEI = cast<TupleExtractInst>(I);
2366-
assert(canOptimizeArrayUninitializedResult(TEI)
2379+
assert(canOptimizeArrayUninitializedResult(I)
23672380
&& "tuple_extract should be handled as projection");
23682381
return;
23692382
}
2383+
case SILInstructionKind::DestructureTupleInst: {
2384+
if (canOptimizeArrayUninitializedResult(I)) {
2385+
return;
2386+
}
2387+
setAllEscaping(I, ConGraph);
2388+
return;
2389+
}
23702390
case SILInstructionKind::UncheckedRefCastAddrInst: {
23712391
auto *URCAI = cast<UncheckedRefCastAddrInst>(I);
23722392
CGNode *SrcNode = ConGraph->getNode(URCAI->getSrc());

0 commit comments

Comments
 (0)