Skip to content

Wire up the new epilogue retain matcher with FSO #4546

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions include/swift/SILOptimizer/Analysis/ARCAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,16 @@ class EpilogueARCContext {
/// The exit blocks of the function.
llvm::SmallPtrSet<SILBasicBlock *, 2> ExitBlocks;

/// Return true if this is a function exitting block this epilogue ARC
/// matcher is interested in.
bool isInterestedFunctionExitingBlock(SILBasicBlock *BB) {
if (EpilogueARCKind::Release == Kind)
return BB->getTerminator()->isFunctionExiting();

return BB->getTerminator()->isFunctionExiting() &&
BB->getTerminator()->getTermKind() != TermKind::ThrowInst;
}

/// Return true if this is a function exit block.
bool isExitBlock(SILBasicBlock *BB) {
return ExitBlocks.count(BB);
Expand Down Expand Up @@ -489,7 +499,8 @@ class EpilogueARCContext {
// Initialize the epilogue arc data flow context.
initializeDataflow();
// Converge the data flow.
convergeDataflow();
if (!convergeDataflow())
return false;
// Lastly, find the epilogue ARC instructions.
return computeEpilogueARC();
}
Expand All @@ -504,7 +515,7 @@ class EpilogueARCContext {
void initializeDataflow();

/// Keep iterating until the data flow is converged.
void convergeDataflow();
bool convergeDataflow();

/// Find the epilogue ARC instructions.
bool computeEpilogueARC();
Expand Down
20 changes: 12 additions & 8 deletions lib/SILOptimizer/Analysis/ARCAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,7 @@ SILInstruction *swift::findReleaseToMatchUnsafeGuaranteedValue(
void EpilogueARCContext::initializeDataflow() {
for (auto &B : *F) {
// Find the exit blocks.
if (B.getTerminator()->isFunctionExiting()) {
if (isInterestedFunctionExitingBlock(&B)) {
ExitBlocks.insert(&B);
}
// Allocate the storage.
Expand All @@ -1186,11 +1186,13 @@ void EpilogueARCContext::initializeDataflow() {
llvm::DenseSet<SILValue> Processed;
ToProcess.push_back(Arg);
while (!ToProcess.empty()) {
SILValue Arg = ToProcess.pop_back_val();
if (Processed.find(Arg) != Processed.end())
SILValue CArg = ToProcess.pop_back_val();
if (!CArg)
continue;
if (Processed.find(CArg) != Processed.end())
continue;
Processed.insert(Arg);
SILArgument *A = dyn_cast<SILArgument>(Arg);
Processed.insert(CArg);
SILArgument *A = dyn_cast<SILArgument>(CArg);
if (A && !A->isFunctionArg()) {
// Find predecessor and break the SILArgument to predecessors.
for (auto X : A->getParent()->getPreds()) {
Expand All @@ -1204,7 +1206,7 @@ void EpilogueARCContext::initializeDataflow() {
}
}

void EpilogueARCContext::convergeDataflow() {
bool EpilogueARCContext::convergeDataflow() {
// Keep iterating until Changed is false.
bool Changed = false;
do {
Expand Down Expand Up @@ -1238,9 +1240,10 @@ void EpilogueARCContext::convergeDataflow() {
break;
}
// This is a transition from 1 to 0 due to a blocking instruction.
// at this point, its OK to abort the data flow as we have one path
// which we did not find an epilogue retain before getting blocked.
if (mayBlockEpilogueARC(&*I, RCFI->getRCIdentityRoot(Arg))) {
BBSetOut = false;
break;
return false;
}
}
}
Expand All @@ -1250,6 +1253,7 @@ void EpilogueARCContext::convergeDataflow() {
BS->BBSetIn = BBSetOut;
}
} while(Changed);
return true;
}

bool EpilogueARCContext::computeEpilogueARC() {
Expand Down
26 changes: 22 additions & 4 deletions lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ using ArgumentIndexMap = llvm::SmallDenseMap<int, int>;
// Utilities
//===----------------------------------------------------------------------===//

/// Return the single return value of the function.
static SILValue findReturnValue(SILFunction *F) {
auto RBB = F->findReturnBB();
if (RBB == F->end())
return SILValue();
auto Term = dyn_cast<ReturnInst>(RBB->getTerminator());
return Term->getOperand();
}

/// Return the single apply found in this function.
static SILInstruction *findOnlyApply(SILFunction *F) {
SILInstruction *OnlyApply = nullptr;
Expand Down Expand Up @@ -103,6 +112,9 @@ class FunctionSignatureTransform {
/// The RC identity analysis we are using.
RCIdentityAnalysis *RCIA;

/// Post order analysis we are using.
PostOrderAnalysis *PO;

// The function signature mangler we are using.
FunctionSignatureSpecializationMangler &FM;

Expand Down Expand Up @@ -220,11 +232,12 @@ class FunctionSignatureTransform {
/// Constructor.
FunctionSignatureTransform(SILFunction *F,
AliasAnalysis *AA, RCIdentityAnalysis *RCIA,
PostOrderAnalysis *PO,
FunctionSignatureSpecializationMangler &FM,
ArgumentIndexMap &AIM,
llvm::SmallVector<ArgumentDescriptor, 4> &ADL,
llvm::SmallVector<ResultDescriptor, 4> &RDL)
: F(F), NewF(nullptr), AA(AA), RCIA(RCIA), FM(FM),
: F(F), NewF(nullptr), AA(AA), RCIA(RCIA), PO(PO), FM(FM),
AIM(AIM), shouldModifySelfArgument(false), ArgumentDescList(ADL),
ResultDescList(RDL) {}

Expand Down Expand Up @@ -646,10 +659,14 @@ bool FunctionSignatureTransform::OwnedToGuaranteedAnalyzeResults() {

bool SignatureOptimize = false;
if (ResultDescList[0].hasConvention(ResultConvention::Owned)) {
auto RV = findReturnValue(F);
if (!RV)
return false;
auto &RI = ResultDescList[0];
// We have an @owned return value, find the epilogue retains now.
ConsumedResultToEpilogueRetainMatcher ReturnRetainMap(RCIA->get(F), AA, F);
auto Retains = ReturnRetainMap.getEpilogueRetains();
auto Retains =
computeEpilogueARCInstructions(EpilogueARCContext::EpilogueARCKind::Retain,
RV, F, PO->get(F), AA, RCIA->get(F));
// We do not need to worry about the throw block, as the return value is only
// going to be used in the return block/normal block of the try_apply
// instruction.
Expand Down Expand Up @@ -880,6 +897,7 @@ class FunctionSignatureOpts : public SILFunctionTransform {
auto *AA = PM->getAnalysis<AliasAnalysis>();
auto *RCIA = getAnalysis<RCIdentityAnalysis>();
CallerAnalysis *CA = PM->getAnalysis<CallerAnalysis>();
auto *PO = PM->getAnalysis<PostOrderAnalysis>();

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

Expand Down Expand Up @@ -910,7 +928,7 @@ class FunctionSignatureOpts : public SILFunctionTransform {
}

// Owned to guaranteed optimization.
FunctionSignatureTransform FST(F, AA, RCIA, FM, AIM,
FunctionSignatureTransform FST(F, AA, RCIA, PO, FM, AIM,
ArgumentDescList, ResultDescList);

bool Changed = false;
Expand Down