Skip to content

[AccessEnforcementOpts] Add mergeAccesses analysis + optimization #18560

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 3 commits into from
Aug 10, 2018
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
38 changes: 29 additions & 9 deletions lib/SILOptimizer/LoopTransforms/LICM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILBuilder.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h"
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
#include "swift/SILOptimizer/Analysis/Analysis.h"
#include "swift/SILOptimizer/Analysis/ArraySemantic.h"
Expand Down Expand Up @@ -361,6 +362,7 @@ class LoopTreeOptimization {
AliasAnalysis *AA;
SideEffectAnalysis *SEA;
DominanceInfo *DomTree;
AccessedStorageAnalysis *ASA;
bool Changed;

/// True if LICM is done on high-level SIL, i.e. semantic calls are not
Expand All @@ -380,8 +382,9 @@ class LoopTreeOptimization {
public:
LoopTreeOptimization(SILLoop *TopLevelLoop, SILLoopInfo *LI,
AliasAnalysis *AA, SideEffectAnalysis *SEA,
DominanceInfo *DT, bool RunsOnHighLevelSil)
: LoopInfo(LI), AA(AA), SEA(SEA), DomTree(DT), Changed(false),
DominanceInfo *DT, AccessedStorageAnalysis *ASA,
bool RunsOnHighLevelSil)
: LoopInfo(LI), AA(AA), SEA(SEA), DomTree(DT), ASA(ASA), Changed(false),
RunsOnHighLevelSIL(RunsOnHighLevelSil) {
// Collect loops for a recursive bottom-up traversal in the loop tree.
BotUpWorkList.push_back(TopLevelLoop);
Expand Down Expand Up @@ -528,9 +531,10 @@ static bool handledEndAccesses(BeginAccessInst *BI, SILLoop *Loop) {
return true;
}

static bool
analyzeBeginAccess(BeginAccessInst *BI,
SmallVector<BeginAccessInst *, 8> &BeginAccesses) {
static bool analyzeBeginAccess(BeginAccessInst *BI,
SmallVector<BeginAccessInst *, 8> &BeginAccesses,
SmallVector<FullApplySite, 8> &fullApplies,
AccessedStorageAnalysis *ASA) {
if (BI->getEnforcement() != SILAccessEnforcement::Dynamic) {
return false;
}
Expand All @@ -550,8 +554,18 @@ analyzeBeginAccess(BeginAccessInst *BI,
findAccessedStorageNonNested(OtherBI));
};

return (
std::all_of(BeginAccesses.begin(), BeginAccesses.end(), safeBeginPred));
if (!std::all_of(BeginAccesses.begin(), BeginAccesses.end(), safeBeginPred))
return false;

for (auto fullApply : fullApplies) {
FunctionAccessedStorage callSiteAccesses;
ASA->getCallSiteEffects(callSiteAccesses, fullApply);
SILAccessKind accessKind = BI->getAccessKind();
if (callSiteAccesses.mayConflictWith(accessKind, storage))
return false;
}

return true;
}

// Analyzes current loop for hosting/sinking potential:
Expand All @@ -575,6 +589,8 @@ void LoopTreeOptimization::analyzeCurrentLoop(
SmallVector<FixLifetimeInst *, 8> FixLifetimes;
// Contains begin_access, we might be able to hoist them.
SmallVector<BeginAccessInst *, 8> BeginAccesses;
// Contains all applies - used for begin_access
SmallVector<FullApplySite, 8> fullApplies;

for (auto *BB : Loop->getBlocks()) {
for (auto &Inst : *BB) {
Expand Down Expand Up @@ -618,6 +634,9 @@ void LoopTreeOptimization::analyzeCurrentLoop(
LLVM_FALLTHROUGH;
}
default: {
if (auto fullApply = FullApplySite::isa(&Inst)) {
fullApplies.push_back(fullApply);
}
checkSideEffects(Inst, MayWrites);
if (canHoistUpDefault(&Inst, Loop, DomTree, RunsOnHighLevelSIL)) {
HoistUp.insert(&Inst);
Expand Down Expand Up @@ -660,7 +679,7 @@ void LoopTreeOptimization::analyzeCurrentLoop(
LLVM_DEBUG(llvm::dbgs() << "Some end accesses can't be handled\n");
continue;
}
if (analyzeBeginAccess(BI, BeginAccesses)) {
if (analyzeBeginAccess(BI, BeginAccesses, fullApplies, ASA)) {
SpecialHoist.insert(BI);
}
}
Expand Down Expand Up @@ -711,14 +730,15 @@ class LICM : public SILFunctionTransform {
DominanceAnalysis *DA = PM->getAnalysis<DominanceAnalysis>();
AliasAnalysis *AA = PM->getAnalysis<AliasAnalysis>();
SideEffectAnalysis *SEA = PM->getAnalysis<SideEffectAnalysis>();
AccessedStorageAnalysis *ASA = getAnalysis<AccessedStorageAnalysis>();
DominanceInfo *DomTree = nullptr;

LLVM_DEBUG(llvm::dbgs() << "Processing loops in " << F->getName() << "\n");
bool Changed = false;

for (auto *TopLevelLoop : *LoopInfo) {
if (!DomTree) DomTree = DA->get(F);
LoopTreeOptimization Opt(TopLevelLoop, LoopInfo, AA, SEA, DomTree,
LoopTreeOptimization Opt(TopLevelLoop, LoopInfo, AA, SEA, DomTree, ASA,
RunsOnHighLevelSil);
Changed |= Opt.optimize();
}
Expand Down
8 changes: 8 additions & 0 deletions lib/SILOptimizer/PassManager/PassPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ void addHighLevelLoopOptPasses(SILPassPipelinePlan &P) {
P.addHighLevelLICM();
// Simplify CFG after LICM that creates new exit blocks
P.addSimplifyCFG();
// LICM might have added new merging potential by hoisting
// we don't want to restart the pipeline - ignore the
// potential of merging out of two loops
P.addAccessEnforcementOpts();
// Start of loop unrolling passes.
P.addArrayCountPropagation();
// To simplify induction variable.
Expand Down Expand Up @@ -457,6 +461,10 @@ static void addLateLoopOptPassPipeline(SILPassPipelinePlan &P) {
P.addLICM();
// Simplify CFG after LICM that creates new exit blocks
P.addSimplifyCFG();
// LICM might have added new merging potential by hoisting
// we don't want to restart the pipeline - ignore the
// potential of merging out of two loops
P.addAccessEnforcementOpts();

// Optimize overflow checks.
P.addRedundantOverflowCheckRemoval();
Expand Down
Loading