From e3c18a5ae8ab0f5c3201b4231445425f2d993f86 Mon Sep 17 00:00:00 2001 From: Sean Silva Date: Tue, 19 Jul 2016 23:54:23 +0000 Subject: [PATCH] [PM] Port LoopUnroll. We just set PreserveLCSSA to always true since we don't have an analogous method `mustPreserveAnalysisID(LCSSA)`. Also port LoopInfo verifier pass to test LoopUnrollPass. llvm-svn: 276063 --- llvm/include/llvm/Analysis/LoopInfo.h | 5 +++ .../llvm/Transforms/Scalar/LoopUnrollPass.h | 28 ++++++++++++++++ llvm/lib/Analysis/LoopInfo.cpp | 7 ++++ llvm/lib/Passes/PassBuilder.cpp | 1 + llvm/lib/Passes/PassRegistry.def | 2 ++ llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp | 33 +++++++++++++++++++ llvm/test/Transforms/LoopUnroll/unloop.ll | 1 + 7 files changed, 77 insertions(+) create mode 100644 llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h diff --git a/llvm/include/llvm/Analysis/LoopInfo.h b/llvm/include/llvm/Analysis/LoopInfo.h index 35dc6bcb6864..a7d9ac5d2a8b 100644 --- a/llvm/include/llvm/Analysis/LoopInfo.h +++ b/llvm/include/llvm/Analysis/LoopInfo.h @@ -791,6 +791,11 @@ public: PreservedAnalyses run(Function &F, AnalysisManager &AM); }; +/// \brief Verifier pass for the \c LoopAnalysis results. +struct LoopVerifierPass : public PassInfoMixin { + PreservedAnalyses run(Function &F, AnalysisManager &AM); +}; + /// \brief The legacy pass manager's analysis pass to compute loop information. class LoopInfoWrapperPass : public FunctionPass { LoopInfo LI; diff --git a/llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h b/llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h new file mode 100644 index 000000000000..6305ce5539ab --- /dev/null +++ b/llvm/include/llvm/Transforms/Scalar/LoopUnrollPass.h @@ -0,0 +1,28 @@ +//===- LoopUnrollPass.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H +#define LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H + +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { + +struct LoopUnrollPass : public PassInfoMixin { + Optional ProvidedCount; + Optional ProvidedThreshold; + Optional ProvidedAllowPartial; + Optional ProvidedRuntime; + + PreservedAnalyses run(Loop &L, AnalysisManager &AM); +}; +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp index 30f7ef392422..16325f6e78a9 100644 --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/lib/Analysis/LoopInfo.cpp @@ -715,6 +715,13 @@ void LoopInfoWrapperPass::print(raw_ostream &OS, const Module *) const { LI.print(OS); } +PreservedAnalyses LoopVerifierPass::run(Function &F, + AnalysisManager &AM) { + LoopInfo &LI = AM.getResult(F); + LI.verify(); + return PreservedAnalyses::all(); +} + //===----------------------------------------------------------------------===// // LoopBlocksDFS implementation // diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 829572942c2b..4191a9df09e3 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -99,6 +99,7 @@ #include "llvm/Transforms/Scalar/LoopRotation.h" #include "llvm/Transforms/Scalar/LoopSimplifyCFG.h" #include "llvm/Transforms/Scalar/LoopStrengthReduce.h" +#include "llvm/Transforms/Scalar/LoopUnrollPass.h" #include "llvm/Transforms/Scalar/LowerAtomic.h" #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" #include "llvm/Transforms/Scalar/MemCpyOptimizer.h" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 7ae6750007c2..b92020567393 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -176,6 +176,7 @@ FUNCTION_PASS("tailcallelim", TailCallElimPass()) FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass()) FUNCTION_PASS("verify", VerifierPass()) FUNCTION_PASS("verify", DominatorTreeVerifierPass()) +FUNCTION_PASS("verify", LoopVerifierPass()) FUNCTION_PASS("verify", MemorySSAVerifierPass()) FUNCTION_PASS("verify", RegionInfoVerifierPass()) #undef FUNCTION_PASS @@ -202,6 +203,7 @@ LOOP_PASS("loop-deletion", LoopDeletionPass()) LOOP_PASS("simplify-cfg", LoopSimplifyCFGPass()) LOOP_PASS("strength-reduce", LoopStrengthReducePass()) LOOP_PASS("indvars", IndVarSimplifyPass()) +LOOP_PASS("unroll", LoopUnrollPass()) LOOP_PASS("print-access-info", LoopAccessInfoPrinterPass(dbgs())) LOOP_PASS("print", IVUsersPrinterPass(dbgs())) #undef LOOP_PASS diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp index 91af4a1922ce..cc4e0615658a 100644 --- a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -12,12 +12,14 @@ // counts of loops easily. //===----------------------------------------------------------------------===// +#include "llvm/Transforms/Scalar/LoopUnrollPass.h" #include "llvm/ADT/SetVector.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/CodeMetrics.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/LoopPassManager.h" #include "llvm/Analysis/LoopUnrollAnalyzer.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" @@ -1054,3 +1056,34 @@ Pass *llvm::createLoopUnrollPass(int Threshold, int Count, int AllowPartial, Pass *llvm::createSimpleLoopUnrollPass() { return llvm::createLoopUnrollPass(-1, -1, 0, 0); } + +PreservedAnalyses LoopUnrollPass::run(Loop &L, AnalysisManager &AM) { + const auto &FAM = + AM.getResult(L).getManager(); + Function *F = L.getHeader()->getParent(); + + + DominatorTree *DT = FAM.getCachedResult(*F); + LoopInfo *LI = FAM.getCachedResult(*F); + ScalarEvolution *SE = FAM.getCachedResult(*F); + auto *TTI = FAM.getCachedResult(*F); + auto *AC = FAM.getCachedResult(*F); + if (!DT) + report_fatal_error("LoopUnrollPass: DominatorTreeAnalysis not cached at a higher level"); + if (!LI) + report_fatal_error("LoopUnrollPass: LoopAnalysis not cached at a higher level"); + if (!SE) + report_fatal_error("LoopUnrollPass: ScalarEvolutionAnalysis not cached at a higher level"); + if (!TTI) + report_fatal_error("LoopUnrollPass: TargetIRAnalysis not cached at a higher level"); + if (!AC) + report_fatal_error("LoopUnrollPass: AssumptionAnalysis not cached at a higher level"); + + bool Changed = tryToUnrollLoop( + &L, *DT, LI, SE, *TTI, *AC, /*PreserveLCSSA*/ true, ProvidedCount, + ProvidedThreshold, ProvidedAllowPartial, ProvidedRuntime); + + if (!Changed) + return PreservedAnalyses::all(); + return getLoopPassPreservedAnalyses(); +} diff --git a/llvm/test/Transforms/LoopUnroll/unloop.ll b/llvm/test/Transforms/LoopUnroll/unloop.ll index 720b2ae1bdbc..38d342dbd634 100644 --- a/llvm/test/Transforms/LoopUnroll/unloop.ll +++ b/llvm/test/Transforms/LoopUnroll/unloop.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -S -loop-unroll -verify-loop-info | FileCheck %s +; RUN: opt < %s -S -passes='function(require,require,loop(unroll),verify)' | FileCheck %s ; ; Unit tests for LoopInfo::markAsRemoved.