2727#include " swift/SIL/SILInstruction.h"
2828#include " swift/SIL/SILModule.h"
2929#include " swift/SIL/BasicBlockDatastructures.h"
30+ #include " swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis.h"
3031#include " swift/SILOptimizer/PassManager/Passes.h"
3132#include " swift/SILOptimizer/PassManager/Transforms.h"
3233#include " swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
@@ -118,9 +119,14 @@ namespace {
118119class OutlinePattern {
119120protected:
120121 SILOptFunctionBuilder &FuncBuilder;
122+ InstModCallbacks callbacks;
123+ DeadEndBlocks *deBlocks;
121124
122125public:
123- OutlinePattern (SILOptFunctionBuilder &FuncBuilder) : FuncBuilder(FuncBuilder) {}
126+ OutlinePattern (SILOptFunctionBuilder &FuncBuilder,
127+ InstModCallbacks callbacks,
128+ DeadEndBlocks *deBlocks)
129+ : FuncBuilder(FuncBuilder), callbacks(callbacks), deBlocks(deBlocks) {}
124130
125131 // / Match the instruction sequence.
126132 virtual bool matchInstSequence (SILBasicBlock::iterator I) = 0;
@@ -233,7 +239,10 @@ class BridgedProperty : public OutlinePattern {
233239 std::pair<SILFunction *, SILBasicBlock::iterator>
234240 outline (SILModule &M) override ;
235241
236- BridgedProperty (SILOptFunctionBuilder &FuncBuilder) : OutlinePattern(FuncBuilder) {
242+ BridgedProperty (SILOptFunctionBuilder &FuncBuilder,
243+ InstModCallbacks callbacks,
244+ DeadEndBlocks *deBlocks)
245+ : OutlinePattern(FuncBuilder, callbacks, deBlocks) {
237246 clearState ();
238247 }
239248
@@ -352,7 +361,9 @@ BridgedProperty::outline(SILModule &M) {
352361 auto *OutlinedEntryBB = StartBB->split (SILBasicBlock::iterator (FirstInst));
353362 auto *OldMergeBB = switchInfo.Br ->getDestBB ();
354363 auto *NewTailBB = OldMergeBB->split (OldMergeBB->begin ());
355-
364+ if (deBlocks) {
365+ deBlocks->updateForNewBlock (NewTailBB);
366+ }
356367 // Call the outlined function.
357368 {
358369 SILBuilder Builder (StartBB);
@@ -900,8 +911,11 @@ namespace {
900911//
901912// bb3(%32 : $Optional<String>):
902913class BridgedReturn {
914+ DeadEndBlocks *deBlocks;
903915 SwitchInfo switchInfo;
904916public:
917+ BridgedReturn (DeadEndBlocks *deBlocks) : deBlocks(deBlocks) {}
918+
905919 bool match (ApplyInst *BridgedCall) {
906920 switchInfo = SwitchInfo ();
907921 auto *SwitchBB = BridgedCall->getParent ();
@@ -941,6 +955,9 @@ void BridgedReturn::outline(SILFunction *Fun, ApplyInst *NewOutlinedCall) {
941955 auto *OutlinedEntryBB = StartBB->split (SILBasicBlock::iterator (switchInfo.SwitchEnum ));
942956 auto *OldMergeBB = switchInfo.Br ->getDestBB ();
943957 auto *NewTailBB = OldMergeBB->split (OldMergeBB->begin ());
958+ if (deBlocks) {
959+ deBlocks->updateForNewBlock (NewTailBB);
960+ }
944961 auto Loc = switchInfo.SwitchEnum ->getLoc ();
945962
946963 {
@@ -992,8 +1009,10 @@ class ObjCMethodCall : public OutlinePattern {
9921009 std::pair<SILFunction *, SILBasicBlock::iterator>
9931010 outline (SILModule &M) override ;
9941011
995- ObjCMethodCall (SILOptFunctionBuilder &FuncBuilder)
996- : OutlinePattern(FuncBuilder) {}
1012+ ObjCMethodCall (SILOptFunctionBuilder &FuncBuilder,
1013+ InstModCallbacks callbacks,
1014+ DeadEndBlocks *deBlocks)
1015+ : OutlinePattern(FuncBuilder, callbacks, deBlocks), BridgedReturn(deBlocks) {}
9971016 ~ObjCMethodCall ();
9981017
9991018private:
@@ -1263,9 +1282,11 @@ class OutlinePatterns {
12631282 return nullptr ;
12641283 }
12651284
1266- OutlinePatterns (SILOptFunctionBuilder &FuncBuilder)
1267- : BridgedPropertyPattern(FuncBuilder),
1268- ObjCMethodCallPattern (FuncBuilder) {}
1285+ OutlinePatterns (SILOptFunctionBuilder &FuncBuilder,
1286+ InstModCallbacks callbacks,
1287+ DeadEndBlocks *deBlocks)
1288+ : BridgedPropertyPattern(FuncBuilder, callbacks, deBlocks),
1289+ ObjCMethodCallPattern (FuncBuilder, callbacks, deBlocks) {}
12691290 ~OutlinePatterns () {}
12701291
12711292 OutlinePatterns (const OutlinePatterns&) = delete ;
@@ -1277,9 +1298,11 @@ class OutlinePatterns {
12771298// / Perform outlining on the function and return any newly created outlined
12781299// / functions.
12791300bool tryOutline (SILOptFunctionBuilder &FuncBuilder, SILFunction *Fun,
1280- SmallVectorImpl<SILFunction *> &FunctionsAdded) {
1301+ SmallVectorImpl<SILFunction *> &FunctionsAdded,
1302+ InstModCallbacks callbacks,
1303+ DeadEndBlocks *deBlocks) {
12811304 BasicBlockWorklist Worklist (Fun->getEntryBlock ());
1282- OutlinePatterns patterns (FuncBuilder);
1305+ OutlinePatterns patterns (FuncBuilder, callbacks, deBlocks );
12831306 bool changed = false ;
12841307
12851308 // Traverse the function.
@@ -1323,15 +1346,27 @@ class Outliner : public SILFunctionTransform {
13231346 if (!Fun->optimizeForSize ())
13241347 return ;
13251348
1349+
13261350 // Dump function if requested.
13271351 if (DumpFuncsBeforeOutliner.size () &&
13281352 Fun->getName ().contains (DumpFuncsBeforeOutliner)) {
13291353 Fun->dump ();
13301354 }
13311355
1356+ DeadEndBlocksAnalysis *deBlocksAnalysis =
1357+ PM->getAnalysis <DeadEndBlocksAnalysis>();
1358+ DeadEndBlocks *deBlocks = deBlocksAnalysis->get (Fun);
1359+ InstModCallbacks callbacks;
1360+
13321361 SILOptFunctionBuilder FuncBuilder (*this );
13331362 SmallVector<SILFunction *, 16 > FunctionsAdded;
1334- bool Changed = tryOutline (FuncBuilder, Fun, FunctionsAdded);
1363+ bool Changed = false ;
1364+
1365+ if (Fun->hasOwnership ()) {
1366+ Changed = tryOutline (FuncBuilder, Fun, FunctionsAdded, callbacks, deBlocks);
1367+ } else {
1368+ Changed = tryOutline (FuncBuilder, Fun, FunctionsAdded);
1369+ }
13351370
13361371 if (!FunctionsAdded.empty ()) {
13371372 // Notify the pass manager of any new functions we outlined.
0 commit comments