Skip to content

Commit 1a88c86

Browse files
authored
Merge pull request #4546 from trentxintong/wireup-FSO
Wire up the new epilogue retain matcher with FSO
2 parents e5a6b22 + f1843d0 commit 1a88c86

File tree

3 files changed

+47
-14
lines changed

3 files changed

+47
-14
lines changed

include/swift/SILOptimizer/Analysis/ARCAnalysis.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,16 @@ class EpilogueARCContext {
455455
/// The exit blocks of the function.
456456
llvm::SmallPtrSet<SILBasicBlock *, 2> ExitBlocks;
457457

458+
/// Return true if this is a function exitting block this epilogue ARC
459+
/// matcher is interested in.
460+
bool isInterestedFunctionExitingBlock(SILBasicBlock *BB) {
461+
if (EpilogueARCKind::Release == Kind)
462+
return BB->getTerminator()->isFunctionExiting();
463+
464+
return BB->getTerminator()->isFunctionExiting() &&
465+
BB->getTerminator()->getTermKind() != TermKind::ThrowInst;
466+
}
467+
458468
/// Return true if this is a function exit block.
459469
bool isExitBlock(SILBasicBlock *BB) {
460470
return ExitBlocks.count(BB);
@@ -489,7 +499,8 @@ class EpilogueARCContext {
489499
// Initialize the epilogue arc data flow context.
490500
initializeDataflow();
491501
// Converge the data flow.
492-
convergeDataflow();
502+
if (!convergeDataflow())
503+
return false;
493504
// Lastly, find the epilogue ARC instructions.
494505
return computeEpilogueARC();
495506
}
@@ -504,7 +515,7 @@ class EpilogueARCContext {
504515
void initializeDataflow();
505516

506517
/// Keep iterating until the data flow is converged.
507-
void convergeDataflow();
518+
bool convergeDataflow();
508519

509520
/// Find the epilogue ARC instructions.
510521
bool computeEpilogueARC();

lib/SILOptimizer/Analysis/ARCAnalysis.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,7 @@ SILInstruction *swift::findReleaseToMatchUnsafeGuaranteedValue(
11731173
void EpilogueARCContext::initializeDataflow() {
11741174
for (auto &B : *F) {
11751175
// Find the exit blocks.
1176-
if (B.getTerminator()->isFunctionExiting()) {
1176+
if (isInterestedFunctionExitingBlock(&B)) {
11771177
ExitBlocks.insert(&B);
11781178
}
11791179
// Allocate the storage.
@@ -1186,11 +1186,13 @@ void EpilogueARCContext::initializeDataflow() {
11861186
llvm::DenseSet<SILValue> Processed;
11871187
ToProcess.push_back(Arg);
11881188
while (!ToProcess.empty()) {
1189-
SILValue Arg = ToProcess.pop_back_val();
1190-
if (Processed.find(Arg) != Processed.end())
1189+
SILValue CArg = ToProcess.pop_back_val();
1190+
if (!CArg)
1191+
continue;
1192+
if (Processed.find(CArg) != Processed.end())
11911193
continue;
1192-
Processed.insert(Arg);
1193-
SILArgument *A = dyn_cast<SILArgument>(Arg);
1194+
Processed.insert(CArg);
1195+
SILArgument *A = dyn_cast<SILArgument>(CArg);
11941196
if (A && !A->isFunctionArg()) {
11951197
// Find predecessor and break the SILArgument to predecessors.
11961198
for (auto X : A->getParent()->getPreds()) {
@@ -1204,7 +1206,7 @@ void EpilogueARCContext::initializeDataflow() {
12041206
}
12051207
}
12061208

1207-
void EpilogueARCContext::convergeDataflow() {
1209+
bool EpilogueARCContext::convergeDataflow() {
12081210
// Keep iterating until Changed is false.
12091211
bool Changed = false;
12101212
do {
@@ -1238,9 +1240,10 @@ void EpilogueARCContext::convergeDataflow() {
12381240
break;
12391241
}
12401242
// This is a transition from 1 to 0 due to a blocking instruction.
1243+
// at this point, its OK to abort the data flow as we have one path
1244+
// which we did not find an epilogue retain before getting blocked.
12411245
if (mayBlockEpilogueARC(&*I, RCFI->getRCIdentityRoot(Arg))) {
1242-
BBSetOut = false;
1243-
break;
1246+
return false;
12441247
}
12451248
}
12461249
}
@@ -1250,6 +1253,7 @@ void EpilogueARCContext::convergeDataflow() {
12501253
BS->BBSetIn = BBSetOut;
12511254
}
12521255
} while(Changed);
1256+
return true;
12531257
}
12541258

12551259
bool EpilogueARCContext::computeEpilogueARC() {

lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ using ArgumentIndexMap = llvm::SmallDenseMap<int, int>;
6262
// Utilities
6363
//===----------------------------------------------------------------------===//
6464

65+
/// Return the single return value of the function.
66+
static SILValue findReturnValue(SILFunction *F) {
67+
auto RBB = F->findReturnBB();
68+
if (RBB == F->end())
69+
return SILValue();
70+
auto Term = dyn_cast<ReturnInst>(RBB->getTerminator());
71+
return Term->getOperand();
72+
}
73+
6574
/// Return the single apply found in this function.
6675
static SILInstruction *findOnlyApply(SILFunction *F) {
6776
SILInstruction *OnlyApply = nullptr;
@@ -103,6 +112,9 @@ class FunctionSignatureTransform {
103112
/// The RC identity analysis we are using.
104113
RCIdentityAnalysis *RCIA;
105114

115+
/// Post order analysis we are using.
116+
PostOrderAnalysis *PO;
117+
106118
// The function signature mangler we are using.
107119
FunctionSignatureSpecializationMangler &FM;
108120

@@ -220,11 +232,12 @@ class FunctionSignatureTransform {
220232
/// Constructor.
221233
FunctionSignatureTransform(SILFunction *F,
222234
AliasAnalysis *AA, RCIdentityAnalysis *RCIA,
235+
PostOrderAnalysis *PO,
223236
FunctionSignatureSpecializationMangler &FM,
224237
ArgumentIndexMap &AIM,
225238
llvm::SmallVector<ArgumentDescriptor, 4> &ADL,
226239
llvm::SmallVector<ResultDescriptor, 4> &RDL)
227-
: F(F), NewF(nullptr), AA(AA), RCIA(RCIA), FM(FM),
240+
: F(F), NewF(nullptr), AA(AA), RCIA(RCIA), PO(PO), FM(FM),
228241
AIM(AIM), shouldModifySelfArgument(false), ArgumentDescList(ADL),
229242
ResultDescList(RDL) {}
230243

@@ -646,10 +659,14 @@ bool FunctionSignatureTransform::OwnedToGuaranteedAnalyzeResults() {
646659

647660
bool SignatureOptimize = false;
648661
if (ResultDescList[0].hasConvention(ResultConvention::Owned)) {
662+
auto RV = findReturnValue(F);
663+
if (!RV)
664+
return false;
649665
auto &RI = ResultDescList[0];
650666
// We have an @owned return value, find the epilogue retains now.
651-
ConsumedResultToEpilogueRetainMatcher ReturnRetainMap(RCIA->get(F), AA, F);
652-
auto Retains = ReturnRetainMap.getEpilogueRetains();
667+
auto Retains =
668+
computeEpilogueARCInstructions(EpilogueARCContext::EpilogueARCKind::Retain,
669+
RV, F, PO->get(F), AA, RCIA->get(F));
653670
// We do not need to worry about the throw block, as the return value is only
654671
// going to be used in the return block/normal block of the try_apply
655672
// instruction.
@@ -880,6 +897,7 @@ class FunctionSignatureOpts : public SILFunctionTransform {
880897
auto *AA = PM->getAnalysis<AliasAnalysis>();
881898
auto *RCIA = getAnalysis<RCIdentityAnalysis>();
882899
CallerAnalysis *CA = PM->getAnalysis<CallerAnalysis>();
900+
auto *PO = PM->getAnalysis<PostOrderAnalysis>();
883901

884902
const CallerAnalysis::FunctionInfo &FuncInfo = CA->getCallerInfo(F);
885903

@@ -910,7 +928,7 @@ class FunctionSignatureOpts : public SILFunctionTransform {
910928
}
911929

912930
// Owned to guaranteed optimization.
913-
FunctionSignatureTransform FST(F, AA, RCIA, FM, AIM,
931+
FunctionSignatureTransform FST(F, AA, RCIA, PO, FM, AIM,
914932
ArgumentDescList, ResultDescList);
915933

916934
bool Changed = false;

0 commit comments

Comments
 (0)