summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Transforms/Scalar/LoopDistribute.cpp')
-rw-r--r--contrib/llvm/lib/Transforms/Scalar/LoopDistribute.cpp109
1 files changed, 53 insertions, 56 deletions
diff --git a/contrib/llvm/lib/Transforms/Scalar/LoopDistribute.cpp b/contrib/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
index 7eca28e..19716b2 100644
--- a/contrib/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
+++ b/contrib/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
@@ -28,15 +28,16 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
@@ -72,11 +73,10 @@ static cl::opt<unsigned> PragmaDistributeSCEVCheckThreshold(
"The maximum number of SCEV checks allowed for Loop "
"Distribution for loop marked with #pragma loop distribute(enable)"));
-// Note that the initial value for this depends on whether the pass is invoked
-// directly or from the optimization pipeline.
static cl::opt<bool> EnableLoopDistribute(
"enable-loop-distribute", cl::Hidden,
- cl::desc("Enable the new, experimental LoopDistribution Pass"));
+ cl::desc("Enable the new, experimental LoopDistribution Pass"),
+ cl::init(false));
STATISTIC(NumLoopsDistributed, "Number of loops distributed");
@@ -605,11 +605,13 @@ public:
DEBUG(dbgs() << "\nLDist: In \"" << L->getHeader()->getParent()->getName()
<< "\" checking " << *L << "\n");
- BasicBlock *PH = L->getLoopPreheader();
- if (!PH)
- return fail("no preheader");
if (!L->getExitBlock())
- return fail("multiple exit blocks");
+ return fail("MultipleExitBlocks", "multiple exit blocks");
+ if (!L->isLoopSimplifyForm())
+ return fail("NotLoopSimplifyForm",
+ "loop is not in loop-simplify form");
+
+ BasicBlock *PH = L->getLoopPreheader();
// LAA will check that we only have a single exiting block.
LAI = &GetLAA(*L);
@@ -617,11 +619,12 @@ public:
// Currently, we only distribute to isolate the part of the loop with
// dependence cycles to enable partial vectorization.
if (LAI->canVectorizeMemory())
- return fail("memory operations are safe for vectorization");
+ return fail("MemOpsCanBeVectorized",
+ "memory operations are safe for vectorization");
auto *Dependences = LAI->getDepChecker().getDependences();
if (!Dependences || Dependences->empty())
- return fail("no unsafe dependences to isolate");
+ return fail("NoUnsafeDeps", "no unsafe dependences to isolate");
InstPartitionContainer Partitions(L, LI, DT);
@@ -674,14 +677,16 @@ public:
DEBUG(dbgs() << "Seeded partitions:\n" << Partitions);
if (Partitions.getSize() < 2)
- return fail("cannot isolate unsafe dependencies");
+ return fail("CantIsolateUnsafeDeps",
+ "cannot isolate unsafe dependencies");
// Run the merge heuristics: Merge non-cyclic adjacent partitions since we
// should be able to vectorize these together.
Partitions.mergeBeforePopulating();
DEBUG(dbgs() << "\nMerged partitions:\n" << Partitions);
if (Partitions.getSize() < 2)
- return fail("cannot isolate unsafe dependencies");
+ return fail("CantIsolateUnsafeDeps",
+ "cannot isolate unsafe dependencies");
// Now, populate the partitions with non-memory operations.
Partitions.populateUsedSet();
@@ -693,7 +698,8 @@ public:
DEBUG(dbgs() << "\nPartitions merged to ensure unique loads:\n"
<< Partitions);
if (Partitions.getSize() < 2)
- return fail("cannot isolate unsafe dependencies");
+ return fail("CantIsolateUnsafeDeps",
+ "cannot isolate unsafe dependencies");
}
// Don't distribute the loop if we need too many SCEV run-time checks.
@@ -701,7 +707,8 @@ public:
if (Pred.getComplexity() > (IsForced.getValueOr(false)
? PragmaDistributeSCEVCheckThreshold
: DistributeSCEVCheckThreshold))
- return fail("too many SCEV run-time checks needed.\n");
+ return fail("TooManySCEVRuntimeChecks",
+ "too many SCEV run-time checks needed.\n");
DEBUG(dbgs() << "\nDistributing loop: " << *L << "\n");
// We're done forming the partitions set up the reverse mapping from
@@ -742,36 +749,38 @@ public:
DEBUG(Partitions.printBlocks());
if (LDistVerify) {
- LI->verify();
+ LI->verify(*DT);
DT->verifyDomTree();
}
++NumLoopsDistributed;
// Report the success.
- emitOptimizationRemark(F->getContext(), LDIST_NAME, *F, L->getStartLoc(),
- "distributed loop");
+ ORE->emit(OptimizationRemark(LDIST_NAME, "Distribute", L->getStartLoc(),
+ L->getHeader())
+ << "distributed loop");
return true;
}
/// \brief Provide diagnostics then \return with false.
- bool fail(llvm::StringRef Message) {
+ bool fail(StringRef RemarkName, StringRef Message) {
LLVMContext &Ctx = F->getContext();
bool Forced = isForced().getValueOr(false);
DEBUG(dbgs() << "Skipping; " << Message << "\n");
// With Rpass-missed report that distribution failed.
- ORE->emitOptimizationRemarkMissed(
- LDIST_NAME, L,
- "loop not distributed: use -Rpass-analysis=loop-distribute for more "
- "info");
+ ORE->emit(
+ OptimizationRemarkMissed(LDIST_NAME, "NotDistributed", L->getStartLoc(),
+ L->getHeader())
+ << "loop not distributed: use -Rpass-analysis=loop-distribute for more "
+ "info");
// With Rpass-analysis report why. This is on by default if distribution
// was requested explicitly.
- emitOptimizationRemarkAnalysis(
- Ctx, Forced ? DiagnosticInfoOptimizationRemarkAnalysis::AlwaysPrint
- : LDIST_NAME,
- *F, L->getStartLoc(), Twine("loop not distributed: ") + Message);
+ ORE->emit(OptimizationRemarkAnalysis(
+ Forced ? OptimizationRemarkAnalysis::AlwaysPrint : LDIST_NAME,
+ RemarkName, L->getStartLoc(), L->getHeader())
+ << "loop not distributed: " << Message);
// Also issue a warning if distribution was requested explicitly but it
// failed.
@@ -865,8 +874,7 @@ private:
/// Shared implementation between new and old PMs.
static bool runImpl(Function &F, LoopInfo *LI, DominatorTree *DT,
ScalarEvolution *SE, OptimizationRemarkEmitter *ORE,
- std::function<const LoopAccessInfo &(Loop &)> &GetLAA,
- bool ProcessAllLoops) {
+ std::function<const LoopAccessInfo &(Loop &)> &GetLAA) {
// Build up a worklist of inner-loops to vectorize. This is necessary as the
// act of distributing a loop creates new loops and can invalidate iterators
// across the loops.
@@ -885,7 +893,7 @@ static bool runImpl(Function &F, LoopInfo *LI, DominatorTree *DT,
// If distribution was forced for the specific loop to be
// enabled/disabled, follow that. Otherwise use the global flag.
- if (LDL.isForced().getValueOr(ProcessAllLoops))
+ if (LDL.isForced().getValueOr(EnableLoopDistribute))
Changed |= LDL.processLoop(GetLAA);
}
@@ -896,15 +904,8 @@ static bool runImpl(Function &F, LoopInfo *LI, DominatorTree *DT,
/// \brief The pass class.
class LoopDistributeLegacy : public FunctionPass {
public:
- /// \p ProcessAllLoopsByDefault specifies whether loop distribution should be
- /// performed by default. Pass -enable-loop-distribute={0,1} overrides this
- /// default. We use this to keep LoopDistribution off by default when invoked
- /// from the optimization pipeline but on when invoked explicitly from opt.
- LoopDistributeLegacy(bool ProcessAllLoopsByDefault = true)
- : FunctionPass(ID), ProcessAllLoops(ProcessAllLoopsByDefault) {
+ LoopDistributeLegacy() : FunctionPass(ID) {
// The default is set by the caller.
- if (EnableLoopDistribute.getNumOccurrences() > 0)
- ProcessAllLoops = EnableLoopDistribute;
initializeLoopDistributeLegacyPass(*PassRegistry::getPassRegistry());
}
@@ -920,7 +921,7 @@ public:
std::function<const LoopAccessInfo &(Loop &)> GetLAA =
[&](Loop &L) -> const LoopAccessInfo & { return LAA->getInfo(&L); };
- return runImpl(F, LI, DT, SE, ORE, GetLAA, ProcessAllLoops);
+ return runImpl(F, LI, DT, SE, ORE, GetLAA);
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -931,48 +932,46 @@ public:
AU.addRequired<DominatorTreeWrapperPass>();
AU.addPreserved<DominatorTreeWrapperPass>();
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
+ AU.addPreserved<GlobalsAAWrapperPass>();
}
static char ID;
-
-private:
- /// \brief Whether distribution should be on in this function. The per-loop
- /// pragma can override this.
- bool ProcessAllLoops;
};
} // anonymous namespace
PreservedAnalyses LoopDistributePass::run(Function &F,
FunctionAnalysisManager &AM) {
- // FIXME: This does not currently match the behavior from the old PM.
- // ProcessAllLoops with the old PM defaults to true when invoked from opt and
- // false when invoked from the optimization pipeline.
- bool ProcessAllLoops = false;
- if (EnableLoopDistribute.getNumOccurrences() > 0)
- ProcessAllLoops = EnableLoopDistribute;
-
auto &LI = AM.getResult<LoopAnalysis>(F);
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
+ // We don't directly need these analyses but they're required for loop
+ // analyses so provide them below.
+ auto &AA = AM.getResult<AAManager>(F);
+ auto &AC = AM.getResult<AssumptionAnalysis>(F);
+ auto &TTI = AM.getResult<TargetIRAnalysis>(F);
+ auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
+
auto &LAM = AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
std::function<const LoopAccessInfo &(Loop &)> GetLAA =
[&](Loop &L) -> const LoopAccessInfo & {
- return LAM.getResult<LoopAccessAnalysis>(L);
+ LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE, TLI, TTI};
+ return LAM.getResult<LoopAccessAnalysis>(L, AR);
};
- bool Changed = runImpl(F, &LI, &DT, &SE, &ORE, GetLAA, ProcessAllLoops);
+ bool Changed = runImpl(F, &LI, &DT, &SE, &ORE, GetLAA);
if (!Changed)
return PreservedAnalyses::all();
PreservedAnalyses PA;
PA.preserve<LoopAnalysis>();
PA.preserve<DominatorTreeAnalysis>();
+ PA.preserve<GlobalsAA>();
return PA;
}
char LoopDistributeLegacy::ID;
-static const char ldist_name[] = "Loop Distribition";
+static const char ldist_name[] = "Loop Distribution";
INITIALIZE_PASS_BEGIN(LoopDistributeLegacy, LDIST_NAME, ldist_name, false,
false)
@@ -984,7 +983,5 @@ INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
INITIALIZE_PASS_END(LoopDistributeLegacy, LDIST_NAME, ldist_name, false, false)
namespace llvm {
-FunctionPass *createLoopDistributePass(bool ProcessAllLoopsByDefault) {
- return new LoopDistributeLegacy(ProcessAllLoopsByDefault);
-}
+FunctionPass *createLoopDistributePass() { return new LoopDistributeLegacy(); }
}
OpenPOWER on IntegriCloud