1919#include " swift/Demangling/Demangler.h"
2020#include " swift/Demangling/ManglingMacros.h"
2121#include " swift/SIL/ApplySite.h"
22+ #include " swift/SIL/BasicBlockDatastructures.h"
23+ #include " swift/SIL/BasicBlockUtils.h"
2224#include " swift/SIL/DebugUtils.h"
2325#include " swift/SIL/DynamicCasts.h"
2426#include " swift/SIL/SILArgument.h"
2527#include " swift/SIL/SILBuilder.h"
2628#include " swift/SIL/SILFunction.h"
2729#include " swift/SIL/SILInstruction.h"
2830#include " swift/SIL/SILModule.h"
29- #include " swift/SIL/BasicBlockDatastructures .h"
31+ #include " swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis .h"
3032#include " swift/SILOptimizer/PassManager/Passes.h"
3133#include " swift/SILOptimizer/PassManager/Transforms.h"
34+ #include " swift/SILOptimizer/Utils/OwnershipOptUtils.h"
3235#include " swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
3336#include " llvm/ADT/BitVector.h"
3437#include " llvm/Support/CommandLine.h"
@@ -118,9 +121,14 @@ namespace {
118121class OutlinePattern {
119122protected:
120123 SILOptFunctionBuilder &FuncBuilder;
124+ InstModCallbacks callbacks;
125+ DeadEndBlocks *deBlocks;
121126
122127public:
123- OutlinePattern (SILOptFunctionBuilder &FuncBuilder) : FuncBuilder(FuncBuilder) {}
128+ OutlinePattern (SILOptFunctionBuilder &FuncBuilder,
129+ InstModCallbacks callbacks,
130+ DeadEndBlocks *deBlocks)
131+ : FuncBuilder(FuncBuilder), callbacks(callbacks), deBlocks(deBlocks) {}
124132
125133 // / Match the instruction sequence.
126134 virtual bool matchInstSequence (SILBasicBlock::iterator I) = 0;
@@ -233,7 +241,10 @@ class BridgedProperty : public OutlinePattern {
233241 std::pair<SILFunction *, SILBasicBlock::iterator>
234242 outline (SILModule &M) override ;
235243
236- BridgedProperty (SILOptFunctionBuilder &FuncBuilder) : OutlinePattern(FuncBuilder) {
244+ BridgedProperty (SILOptFunctionBuilder &FuncBuilder,
245+ InstModCallbacks callbacks,
246+ DeadEndBlocks *deBlocks)
247+ : OutlinePattern(FuncBuilder, callbacks, deBlocks) {
237248 clearState ();
238249 }
239250
@@ -352,7 +363,9 @@ BridgedProperty::outline(SILModule &M) {
352363 auto *OutlinedEntryBB = StartBB->split (SILBasicBlock::iterator (FirstInst));
353364 auto *OldMergeBB = switchInfo.Br ->getDestBB ();
354365 auto *NewTailBB = OldMergeBB->split (OldMergeBB->begin ());
355-
366+ if (deBlocks) {
367+ deBlocks->updateForNewBlock (NewTailBB);
368+ }
356369 // Call the outlined function.
357370 {
358371 SILBuilder Builder (StartBB);
@@ -900,8 +913,11 @@ namespace {
900913//
901914// bb3(%32 : $Optional<String>):
902915class BridgedReturn {
916+ DeadEndBlocks *deBlocks;
903917 SwitchInfo switchInfo;
904918public:
919+ BridgedReturn (DeadEndBlocks *deBlocks) : deBlocks(deBlocks) {}
920+
905921 bool match (ApplyInst *BridgedCall) {
906922 switchInfo = SwitchInfo ();
907923 auto *SwitchBB = BridgedCall->getParent ();
@@ -941,7 +957,10 @@ void BridgedReturn::outline(SILFunction *Fun, ApplyInst *NewOutlinedCall) {
941957 auto *OutlinedEntryBB = StartBB->split (SILBasicBlock::iterator (switchInfo.SwitchEnum ));
942958 auto *OldMergeBB = switchInfo.Br ->getDestBB ();
943959 auto *NewTailBB = OldMergeBB->split (OldMergeBB->begin ());
944- auto Loc = switchInfo.SwitchEnum ->getLoc ();
960+ if (deBlocks) {
961+ deBlocks->updateForNewBlock (NewTailBB);
962+ }
963+ auto Loc = switchInfo.SwitchEnum ->getLoc ();
945964
946965 {
947966 SILBuilder Builder (StartBB);
@@ -992,8 +1011,10 @@ class ObjCMethodCall : public OutlinePattern {
9921011 std::pair<SILFunction *, SILBasicBlock::iterator>
9931012 outline (SILModule &M) override ;
9941013
995- ObjCMethodCall (SILOptFunctionBuilder &FuncBuilder)
996- : OutlinePattern(FuncBuilder) {}
1014+ ObjCMethodCall (SILOptFunctionBuilder &FuncBuilder,
1015+ InstModCallbacks callbacks,
1016+ DeadEndBlocks *deBlocks)
1017+ : OutlinePattern(FuncBuilder, callbacks, deBlocks), BridgedReturn(deBlocks) {}
9971018 ~ObjCMethodCall ();
9981019
9991020private:
@@ -1043,7 +1064,12 @@ ObjCMethodCall::outline(SILModule &M) {
10431064 for (auto Arg : BridgedCall->getArguments ()) {
10441065 if (BridgedArgIdx < BridgedArguments.size () &&
10451066 BridgedArguments[BridgedArgIdx].Idx == OrigSigIdx) {
1046- Args.push_back (BridgedArguments[BridgedArgIdx].bridgedValue ());
1067+ auto bridgedArgValue = BridgedArguments[BridgedArgIdx].bridgedValue ();
1068+ if (bridgedArgValue.getOwnershipKind () == OwnershipKind::Guaranteed) {
1069+ bridgedArgValue = makeGuaranteedValueAvailable (
1070+ bridgedArgValue, BridgedCall, *deBlocks);
1071+ }
1072+ Args.push_back (bridgedArgValue);
10471073 ++BridgedArgIdx;
10481074 } else {
10491075 // Otherwise, use the original type convention.
@@ -1263,9 +1289,11 @@ class OutlinePatterns {
12631289 return nullptr ;
12641290 }
12651291
1266- OutlinePatterns (SILOptFunctionBuilder &FuncBuilder)
1267- : BridgedPropertyPattern(FuncBuilder),
1268- ObjCMethodCallPattern (FuncBuilder) {}
1292+ OutlinePatterns (SILOptFunctionBuilder &FuncBuilder,
1293+ InstModCallbacks callbacks,
1294+ DeadEndBlocks *deBlocks)
1295+ : BridgedPropertyPattern(FuncBuilder, callbacks, deBlocks),
1296+ ObjCMethodCallPattern (FuncBuilder, callbacks, deBlocks) {}
12691297 ~OutlinePatterns () {}
12701298
12711299 OutlinePatterns (const OutlinePatterns&) = delete ;
@@ -1277,9 +1305,11 @@ class OutlinePatterns {
12771305// / Perform outlining on the function and return any newly created outlined
12781306// / functions.
12791307bool tryOutline (SILOptFunctionBuilder &FuncBuilder, SILFunction *Fun,
1280- SmallVectorImpl<SILFunction *> &FunctionsAdded) {
1308+ SmallVectorImpl<SILFunction *> &FunctionsAdded,
1309+ InstModCallbacks callbacks = InstModCallbacks(),
1310+ DeadEndBlocks *deBlocks = nullptr) {
12811311 BasicBlockWorklist Worklist (Fun->getEntryBlock ());
1282- OutlinePatterns patterns (FuncBuilder);
1312+ OutlinePatterns patterns (FuncBuilder, callbacks, deBlocks );
12831313 bool changed = false ;
12841314
12851315 // Traverse the function.
@@ -1329,9 +1359,21 @@ class Outliner : public SILFunctionTransform {
13291359 Fun->dump ();
13301360 }
13311361
1362+ DeadEndBlocksAnalysis *deBlocksAnalysis =
1363+ PM->getAnalysis <DeadEndBlocksAnalysis>();
1364+ DeadEndBlocks *deBlocks = deBlocksAnalysis->get (Fun);
1365+ InstModCallbacks callbacks;
1366+
13321367 SILOptFunctionBuilder FuncBuilder (*this );
13331368 SmallVector<SILFunction *, 16 > FunctionsAdded;
1334- bool Changed = tryOutline (FuncBuilder, Fun, FunctionsAdded);
1369+ bool Changed = false ;
1370+
1371+ if (Fun->hasOwnership ()) {
1372+ Changed =
1373+ tryOutline (FuncBuilder, Fun, FunctionsAdded, callbacks, deBlocks);
1374+ } else {
1375+ Changed = tryOutline (FuncBuilder, Fun, FunctionsAdded);
1376+ }
13351377
13361378 if (!FunctionsAdded.empty ()) {
13371379 // Notify the pass manager of any new functions we outlined.
0 commit comments