Skip to content

Commit

Permalink
[LoopUnrollAndJam] Change LoopUnrollAndJamPass to LoopNest pass
Browse files Browse the repository at this point in the history
This patch changes LoopUnrollAndJamPass from FunctionPass to LoopNest pass.
The next patch will utilize LoopNest to effectively handle loop nests.

Reviewed By: Whitney

Differential Revision: https://reviews.llvm.org/D99149
  • Loading branch information
maekawatoshiki committed May 27, 2021
1 parent 5c18d11 commit 2165360
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 46 deletions.
2 changes: 1 addition & 1 deletion llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ class LPMUpdater {
/// state, this routine will mark that the current loop should be skipped by
/// the rest of the pass management infrastructure.
void markLoopAsDeleted(Loop &L, llvm::StringRef Name) {
assert((!LoopNestMode || L.isOutermost()) &&
assert((!LoopNestMode || CurrentL == &L) &&
"L should be a top-level loop in loop-nest mode.");
LAM.clear(L, Name);
assert((&L == CurrentL || CurrentL->contains(&L)) &&
Expand Down
4 changes: 3 additions & 1 deletion llvm/include/llvm/Transforms/Scalar/LoopUnrollAndJamPass.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define LLVM_TRANSFORMS_SCALAR_LOOPUNROLLANDJAMPASS_H

#include "llvm/IR/PassManager.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"

namespace llvm {
class Function;
Expand All @@ -20,7 +21,8 @@ class LoopUnrollAndJamPass : public PassInfoMixin<LoopUnrollAndJamPass> {

public:
explicit LoopUnrollAndJamPass(int OptLevel = 2) : OptLevel(OptLevel) {}
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR, LPMUpdater &U);
};

} // end namespace llvm
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1207,7 +1207,8 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
// across the loop nests.
// We do UnrollAndJam in a separate LPM to ensure it happens before unroll
if (EnableUnrollAndJam && PTO.LoopUnrolling)
FPM.addPass(LoopUnrollAndJamPass(Level.getSpeedupLevel()));
FPM.addPass(createFunctionToLoopPassAdaptor(
LoopUnrollAndJamPass(Level.getSpeedupLevel())));
FPM.addPass(LoopUnrollPass(LoopUnrollOptions(
Level.getSpeedupLevel(), /*OnlyWhenForced=*/!PTO.LoopUnrolling,
PTO.ForgetAllSCEVInLoopUnroll)));
Expand Down Expand Up @@ -1290,7 +1291,8 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
// across the loop nests.
// We do UnrollAndJam in a separate LPM to ensure it happens before unroll
if (EnableUnrollAndJam && PTO.LoopUnrolling) {
FPM.addPass(LoopUnrollAndJamPass(Level.getSpeedupLevel()));
FPM.addPass(createFunctionToLoopPassAdaptor(
LoopUnrollAndJamPass(Level.getSpeedupLevel())));
}
FPM.addPass(LoopUnrollPass(LoopUnrollOptions(
Level.getSpeedupLevel(), /*OnlyWhenForced=*/!PTO.LoopUnrolling,
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,6 @@ FUNCTION_PASS("guard-widening", GuardWideningPass())
FUNCTION_PASS("load-store-vectorizer", LoadStoreVectorizerPass())
FUNCTION_PASS("loop-simplify", LoopSimplifyPass())
FUNCTION_PASS("loop-sink", LoopSinkPass())
FUNCTION_PASS("loop-unroll-and-jam", LoopUnrollAndJamPass())
FUNCTION_PASS("loop-flatten", LoopFlattenPass())
FUNCTION_PASS("lowerinvoke", LowerInvokePass())
FUNCTION_PASS("lowerswitch", LowerSwitchPass())
Expand Down Expand Up @@ -399,6 +398,7 @@ LOOP_PASS("loop-deletion", LoopDeletionPass())
LOOP_PASS("loop-simplifycfg", LoopSimplifyCFGPass())
LOOP_PASS("loop-reduce", LoopStrengthReducePass())
LOOP_PASS("indvars", IndVarSimplifyPass())
LOOP_PASS("loop-unroll-and-jam", LoopUnrollAndJamPass())
LOOP_PASS("loop-unroll-full", LoopFullUnrollPass())
LOOP_PASS("print-access-info", LoopAccessInfoPrinterPass(dbgs()))
LOOP_PASS("print<ddg>", DDGAnalysisPrinterPass(dbgs()))
Expand Down
85 changes: 45 additions & 40 deletions llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "llvm/Analysis/DependenceAnalysis.h"
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/TargetTransformInfo.h"
Expand Down Expand Up @@ -424,65 +425,65 @@ tryToUnrollAndJamLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,
return UnrollResult;
}

static bool tryToUnrollAndJamLoop(Function &F, DominatorTree &DT, LoopInfo &LI,
static bool tryToUnrollAndJamLoop(LoopNest &LN, DominatorTree &DT, LoopInfo &LI,
ScalarEvolution &SE,
const TargetTransformInfo &TTI,
AssumptionCache &AC, DependenceInfo &DI,
OptimizationRemarkEmitter &ORE,
int OptLevel) {
OptimizationRemarkEmitter &ORE, int OptLevel,
LPMUpdater &U) {
bool DidSomething = false;
ArrayRef<Loop *> Loops = LN.getLoops();
Loop *OutmostLoop = &LN.getOutermostLoop();

// The loop unroll and jam pass requires loops to be in simplified form, and
// also needs LCSSA. Since simplification may add new inner loops, it has to
// run before the legality and profitability checks. This means running the
// loop unroll and jam pass will simplify all loops, regardless of whether
// anything end up being unroll and jammed.
for (auto &L : LI) {
DidSomething |=
simplifyLoop(L, &DT, &LI, &SE, &AC, nullptr, false /* PreserveLCSSA */);
DidSomething |= formLCSSARecursively(*L, DT, &LI, &SE);
}

// Add the loop nests in the reverse order of LoopInfo. See method
// Add the loop nests in the reverse order of LN. See method
// declaration.
SmallPriorityWorklist<Loop *, 4> Worklist;
appendLoopsToWorklist(LI, Worklist);
appendLoopsToWorklist(Loops, Worklist);
while (!Worklist.empty()) {
Loop *L = Worklist.pop_back_val();
std::string LoopName = std::string(L->getName());
LoopUnrollResult Result =
tryToUnrollAndJamLoop(L, DT, &LI, SE, TTI, AC, DI, ORE, OptLevel);
if (Result != LoopUnrollResult::Unmodified)
DidSomething = true;
if (L == OutmostLoop && Result == LoopUnrollResult::FullyUnrolled)
U.markLoopAsDeleted(*L, LoopName);
}

return DidSomething;
}

namespace {

class LoopUnrollAndJam : public FunctionPass {
class LoopUnrollAndJam : public LoopPass {
public:
static char ID; // Pass ID, replacement for typeid
unsigned OptLevel;

LoopUnrollAndJam(int OptLevel = 2) : FunctionPass(ID), OptLevel(OptLevel) {
LoopUnrollAndJam(int OptLevel = 2) : LoopPass(ID), OptLevel(OptLevel) {
initializeLoopUnrollAndJamPass(*PassRegistry::getPassRegistry());
}

bool runOnFunction(Function &F) override {
if (skipFunction(F))
bool runOnLoop(Loop *L, LPPassManager &LPM) override {
if (skipLoop(L))
return false;

auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
const TargetTransformInfo &TTI =
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
auto *F = L->getHeader()->getParent();
auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
auto &DI = getAnalysis<DependenceAnalysisWrapperPass>().getDI();
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(*F);
auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(*F);

return tryToUnrollAndJamLoop(F, DT, LI, SE, TTI, AC, DI, ORE, OptLevel);
LoopUnrollResult Result =
tryToUnrollAndJamLoop(L, DT, LI, SE, TTI, AC, DI, ORE, OptLevel);

if (Result == LoopUnrollResult::FullyUnrolled)
LPM.markLoopAsDeleted(*L);

return Result != LoopUnrollResult::Unmodified;
}

/// This transformation requires natural loop information & requires that
Expand All @@ -505,7 +506,10 @@ char LoopUnrollAndJam::ID = 0;
INITIALIZE_PASS_BEGIN(LoopUnrollAndJam, "loop-unroll-and-jam",
"Unroll and Jam loops", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopPass)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
INITIALIZE_PASS_DEPENDENCY(LCSSAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
Expand All @@ -518,19 +522,20 @@ Pass *llvm::createLoopUnrollAndJamPass(int OptLevel) {
return new LoopUnrollAndJam(OptLevel);
}

PreservedAnalyses LoopUnrollAndJamPass::run(Function &F,
FunctionAnalysisManager &AM) {
ScalarEvolution &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
TargetTransformInfo &TTI = AM.getResult<TargetIRAnalysis>(F);
AssumptionCache &AC = AM.getResult<AssumptionAnalysis>(F);
DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F);
DependenceInfo &DI = AM.getResult<DependenceAnalysis>(F);
OptimizationRemarkEmitter &ORE =
AM.getResult<OptimizationRemarkEmitterAnalysis>(F);

if (!tryToUnrollAndJamLoop(F, DT, LI, SE, TTI, AC, DI, ORE, OptLevel))
PreservedAnalyses LoopUnrollAndJamPass::run(LoopNest &LN,
LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR,
LPMUpdater &U) {
Function &F = *LN.getParent();

DependenceInfo DI(&F, &AR.AA, &AR.SE, &AR.LI);
OptimizationRemarkEmitter ORE(&F);

if (!tryToUnrollAndJamLoop(LN, AR.DT, AR.LI, AR.SE, AR.TTI, AR.AC, DI, ORE,
OptLevel, U))
return PreservedAnalyses::all();

return getLoopPassPreservedAnalyses();
auto PA = getLoopPassPreservedAnalyses();
PA.preserve<LoopNestAnalysis>();
return PA;
}
2 changes: 1 addition & 1 deletion llvm/test/Transforms/LoopUnrollAndJam/innerloop.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; RUN: opt -loop-unroll-and-jam -allow-unroll-and-jam -verify-loop-info < %s -S | FileCheck %s
; RUN: opt -passes='loop-unroll-and-jam,verify<loops>' -allow-unroll-and-jam < %s -S | FileCheck %s
; RUN: opt -passes='loop(loop-unroll-and-jam),verify<loops>' -allow-unroll-and-jam < %s -S | FileCheck %s

; Check that the newly created loops to not fail to be added to LI
; This test deliberately disables UnJ on the middle loop, performing it instead on the
Expand Down

0 comments on commit 2165360

Please sign in to comment.