forked from OSchip/llvm-project
[LoopPredication] Preserve MemorySSA
Since LICM has now unconditionally moved to MemorySSA based form, all passes that run in same LPM as LICM need to preserve MemorySSA (i.e. our downstream pipeline). Added loop-mssa to all tests and perform -verify-memoryssa within LoopPredication itself. Differential Revision: https://reviews.llvm.org/D108724
This commit is contained in:
parent
15acca5ccd
commit
55bdb14026
|
@ -183,6 +183,8 @@
|
|||
#include "llvm/Analysis/GuardUtils.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Analysis/MemorySSA.h"
|
||||
#include "llvm/Analysis/MemorySSAUpdater.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
|
@ -255,6 +257,7 @@ class LoopPredication {
|
|||
ScalarEvolution *SE;
|
||||
LoopInfo *LI;
|
||||
BranchProbabilityInfo *BPI;
|
||||
MemorySSAUpdater *MSSAU;
|
||||
|
||||
Loop *L;
|
||||
const DataLayout *DL;
|
||||
|
@ -308,10 +311,10 @@ class LoopPredication {
|
|||
bool predicateLoopExits(Loop *L, SCEVExpander &Rewriter);
|
||||
|
||||
public:
|
||||
LoopPredication(AliasAnalysis *AA, DominatorTree *DT,
|
||||
ScalarEvolution *SE, LoopInfo *LI,
|
||||
BranchProbabilityInfo *BPI)
|
||||
: AA(AA), DT(DT), SE(SE), LI(LI), BPI(BPI) {};
|
||||
LoopPredication(AliasAnalysis *AA, DominatorTree *DT, ScalarEvolution *SE,
|
||||
LoopInfo *LI, BranchProbabilityInfo *BPI,
|
||||
MemorySSAUpdater *MSSAU)
|
||||
: AA(AA), DT(DT), SE(SE), LI(LI), BPI(BPI), MSSAU(MSSAU){};
|
||||
bool runOnLoop(Loop *L);
|
||||
};
|
||||
|
||||
|
@ -325,6 +328,7 @@ public:
|
|||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<BranchProbabilityInfoWrapperPass>();
|
||||
getLoopAnalysisUsage(AU);
|
||||
AU.addPreserved<MemorySSAWrapperPass>();
|
||||
}
|
||||
|
||||
bool runOnLoop(Loop *L, LPPassManager &LPM) override {
|
||||
|
@ -333,10 +337,14 @@ public:
|
|||
auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||
auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>();
|
||||
std::unique_ptr<MemorySSAUpdater> MSSAU;
|
||||
if (MSSAWP)
|
||||
MSSAU = std::make_unique<MemorySSAUpdater>(&MSSAWP->getMSSA());
|
||||
BranchProbabilityInfo &BPI =
|
||||
getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
|
||||
auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
LoopPredication LP(AA, DT, SE, LI, &BPI);
|
||||
LoopPredication LP(AA, DT, SE, LI, &BPI, MSSAU ? MSSAU.get() : nullptr);
|
||||
return LP.runOnLoop(L);
|
||||
}
|
||||
};
|
||||
|
@ -363,11 +371,18 @@ PreservedAnalyses LoopPredicationPass::run(Loop &L, LoopAnalysisManager &AM,
|
|||
// pass. Function analyses need to be preserved across loop transformations
|
||||
// but BPI is not preserved, hence a newly built one is needed.
|
||||
BranchProbabilityInfo BPI(*F, AR.LI, &AR.TLI, &AR.DT, nullptr);
|
||||
LoopPredication LP(&AR.AA, &AR.DT, &AR.SE, &AR.LI, &BPI);
|
||||
std::unique_ptr<MemorySSAUpdater> MSSAU;
|
||||
if (AR.MSSA)
|
||||
MSSAU = std::make_unique<MemorySSAUpdater>(AR.MSSA);
|
||||
LoopPredication LP(&AR.AA, &AR.DT, &AR.SE, &AR.LI, &BPI,
|
||||
MSSAU ? MSSAU.get() : nullptr);
|
||||
if (!LP.runOnLoop(&L))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
return getLoopPassPreservedAnalyses();
|
||||
auto PA = getLoopPassPreservedAnalyses();
|
||||
if (AR.MSSA)
|
||||
PA.preserve<MemorySSAAnalysis>();
|
||||
return PA;
|
||||
}
|
||||
|
||||
Optional<LoopICmp>
|
||||
|
@ -809,7 +824,7 @@ bool LoopPredication::widenGuardConditions(IntrinsicInst *Guard,
|
|||
Value *AllChecks = Builder.CreateAnd(Checks);
|
||||
auto *OldCond = Guard->getOperand(0);
|
||||
Guard->setOperand(0, AllChecks);
|
||||
RecursivelyDeleteTriviallyDeadInstructions(OldCond);
|
||||
RecursivelyDeleteTriviallyDeadInstructions(OldCond, nullptr /* TLI */, MSSAU);
|
||||
|
||||
LLVM_DEBUG(dbgs() << "Widened checks = " << NumWidened << "\n");
|
||||
return true;
|
||||
|
@ -835,7 +850,7 @@ bool LoopPredication::widenWidenableBranchGuardConditions(
|
|||
Value *AllChecks = Builder.CreateAnd(Checks);
|
||||
auto *OldCond = BI->getCondition();
|
||||
BI->setCondition(AllChecks);
|
||||
RecursivelyDeleteTriviallyDeadInstructions(OldCond);
|
||||
RecursivelyDeleteTriviallyDeadInstructions(OldCond, nullptr /* TLI */, MSSAU);
|
||||
assert(isGuardAsWidenableBranch(BI) &&
|
||||
"Stopped being a guard after transform?");
|
||||
|
||||
|
@ -1242,5 +1257,8 @@ bool LoopPredication::runOnLoop(Loop *Loop) {
|
|||
for (auto *Guard : GuardsAsWidenableBranches)
|
||||
Changed |= widenWidenableBranchGuardConditions(Guard, Expander);
|
||||
Changed |= predicateLoopExits(L, Expander);
|
||||
|
||||
if (MSSAU && VerifyMemorySSA)
|
||||
MSSAU->getMemorySSA()->verifyMemorySSA();
|
||||
return Changed;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -loop-predication -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,require<branch-prob>,loop(loop-predication)' -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,require<branch-prob>,loop-mssa(loop-predication)' -verify-memoryssa -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -basic-aa -loop-predication < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -aa-pipeline=basic-aa -passes='require<aa>,require<scalar-evolution>,loop(loop-predication)' < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -aa-pipeline=basic-aa -passes='require<aa>,require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -loop-predication -S | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s
|
||||
|
||||
declare void @prevent_merging()
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -loop-predication -loop-predication-skip-profitability-checks=false < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -loop-predication-skip-profitability-checks=false -passes='require<scalar-evolution>,require<branch-prob>,loop(loop-predication)' < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -loop-predication-skip-profitability-checks=false -passes='require<scalar-evolution>,require<branch-prob>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s
|
||||
|
||||
; latch block exits to a speculation block. BPI already knows (without prof
|
||||
; data) that deopt is very rarely
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -loop-predication -loop-predication-enable-count-down-loop=true < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' -loop-predication-enable-count-down-loop=true < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -loop-predication-enable-count-down-loop=true < %s 2>&1 | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt < %s -loop-predication -S | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s
|
||||
|
||||
;; This is a simplified copy of @unswitch_exit_form test that should trigger loop-predication
|
||||
;; activity and properly bail out when discovering that widenable check does not lead to deopt.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -loop-predication -loop-predication-enable-iv-truncation=true < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
|
||||
declare i32 @length(i8*)
|
||||
|
|
Loading…
Reference in New Issue