Index: include/llvm/InitializePasses.h =================================================================== --- include/llvm/InitializePasses.h +++ include/llvm/InitializePasses.h @@ -179,7 +179,7 @@ void initializeLoopExtractorPass(PassRegistry&); void initializeLoopIdiomRecognizeLegacyPassPass(PassRegistry&); void initializeLoopInfoWrapperPassPass(PassRegistry&); -void initializeLoopInstSimplifyPass(PassRegistry&); +void initializeLoopInstSimplifyLegacyPassPass(PassRegistry&); void initializeLoopInterchangePass(PassRegistry &); void initializeLoopLoadEliminationPass(PassRegistry&); void initializeLoopPassPass(PassRegistry&); Index: include/llvm/Transforms/Scalar/LoopInstSimplify.h =================================================================== --- /dev/null +++ include/llvm/Transforms/Scalar/LoopInstSimplify.h @@ -0,0 +1,29 @@ +//===- LoopInstSimplify.h - Loop Inst Simplify Pass -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass performs lightweight instruction simplification on loop bodies. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_LOOPINSTSIMPLIFY_H +#define LLVM_TRANSFORMS_SCALAR_LOOPINSTSIMPLIFY_H + +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { + +/// Performs Loop Inst Simplify Pass. +class LoopInstSimplifyPass : public PassInfoMixin { +public: + PreservedAnalyses run(Loop &L, AnalysisManager &AM); +}; +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_SCALAR_LOOPINSTSIMPLIFY_H Index: lib/Passes/PassBuilder.cpp =================================================================== --- lib/Passes/PassBuilder.cpp +++ lib/Passes/PassBuilder.cpp @@ -89,6 +89,7 @@ #include "llvm/Transforms/Scalar/IndVarSimplify.h" #include "llvm/Transforms/Scalar/JumpThreading.h" #include "llvm/Transforms/Scalar/LoopIdiomRecognize.h" +#include "llvm/Transforms/Scalar/LoopInstSimplify.h" #include "llvm/Transforms/Scalar/LoopRotation.h" #include "llvm/Transforms/Scalar/LoopSimplifyCFG.h" #include "llvm/Transforms/Scalar/LowerAtomic.h" Index: lib/Passes/PassRegistry.def =================================================================== --- lib/Passes/PassRegistry.def +++ lib/Passes/PassRegistry.def @@ -188,6 +188,7 @@ #endif LOOP_PASS("invalidate", InvalidateAllAnalysesPass()) LOOP_PASS("loop-idiom", LoopIdiomRecognizePass()) +LOOP_PASS("loop-instsimplify", LoopInstSimplifyPass()) LOOP_PASS("rotate", LoopRotatePass()) LOOP_PASS("no-op-loop", NoOpLoopPass()) LOOP_PASS("print", PrintLoopPass(dbgs())) Index: lib/Transforms/Scalar/LoopInstSimplify.cpp =================================================================== --- lib/Transforms/Scalar/LoopInstSimplify.cpp +++ lib/Transforms/Scalar/LoopInstSimplify.cpp @@ -11,19 +11,21 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Scalar/LoopInstSimplify.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/LoopPassManager.h" #include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Instructions.h" #include "llvm/Support/Debug.h" -#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopUtils.h" using namespace llvm; @@ -32,62 +34,20 @@ STATISTIC(NumSimplified, "Number of redundant instructions simplified"); -namespace { - class LoopInstSimplify : public LoopPass { - public: - static char ID; // Pass ID, replacement for typeid - LoopInstSimplify() : LoopPass(ID) { - initializeLoopInstSimplifyPass(*PassRegistry::getPassRegistry()); - } - - bool runOnLoop(Loop*, LPPassManager&) override; - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); - AU.addRequired(); - AU.setPreservesCFG(); - getLoopAnalysisUsage(AU); - } - }; -} - -char LoopInstSimplify::ID = 0; -INITIALIZE_PASS_BEGIN(LoopInstSimplify, "loop-instsimplify", - "Simplify instructions in loops", false, false) -INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) -INITIALIZE_PASS_DEPENDENCY(LoopPass) -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_PASS_END(LoopInstSimplify, "loop-instsimplify", - "Simplify instructions in loops", false, false) - -Pass *llvm::createLoopInstSimplifyPass() { - return new LoopInstSimplify(); -} - -bool LoopInstSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { - if (skipLoop(L)) - return false; - - DominatorTreeWrapperPass *DTWP = - getAnalysisIfAvailable(); - DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr; - LoopInfo *LI = &getAnalysis().getLoopInfo(); - const TargetLibraryInfo *TLI = - &getAnalysis().getTLI(); - auto &AC = getAnalysis().getAssumptionCache( - *L->getHeader()->getParent()); - - SmallVector ExitBlocks; +static bool SimplifyLoopInst(Loop *L, DominatorTree *DT, LoopInfo *LI, + AssumptionCache *AC, + const TargetLibraryInfo *TLI) { + SmallVector ExitBlocks; L->getUniqueExitBlocks(ExitBlocks); array_pod_sort(ExitBlocks.begin(), ExitBlocks.end()); - SmallPtrSet S1, S2, *ToSimplify = &S1, *Next = &S2; + SmallPtrSet S1, S2, *ToSimplify = &S1, *Next = &S2; // The bit we are stealing from the pointer represents whether this basic // block is the header of a subloop, in which case we only process its phis. - typedef PointerIntPair WorklistItem; + typedef PointerIntPair WorklistItem; SmallVector VisitStack; - SmallPtrSet Visited; + SmallPtrSet Visited; bool Changed = false; bool LocalChanged; @@ -117,7 +77,7 @@ // Don't bother simplifying unused instructions. if (!I->use_empty()) { - Value *V = SimplifyInstruction(I, DL, TLI, DT, &AC); + Value *V = SimplifyInstruction(I, DL, TLI, DT, AC); if (V && LI->replacementPreservesLCSSAForm(I, V)) { // Mark all uses for resimplification next time round the loop. for (User *U : I->users()) @@ -132,7 +92,8 @@ // RecursivelyDeleteTriviallyDeadInstruction can remove more than one // instruction, so simply incrementing the iterator does not work. // When instructions get deleted re-iterate instead. - BI = BB->begin(); BE = BB->end(); + BI = BB->begin(); + BE = BB->end(); LocalChanged = true; } @@ -141,8 +102,10 @@ } // Add all successors to the worklist, except for loop exit blocks and the - // bodies of subloops. We visit the headers of loops so that we can process - // their phis, but we contract the rest of the subloop body and only follow + // bodies of subloops. We visit the headers of loops so that we can + // process + // their phis, but we contract the rest of the subloop body and only + // follow // edges leading back to the original loop. for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI) { @@ -151,11 +114,11 @@ continue; const Loop *SuccLoop = LI->getLoopFor(SuccBB); - if (SuccLoop && SuccLoop->getHeader() == SuccBB - && L->contains(SuccLoop)) { + if (SuccLoop && SuccLoop->getHeader() == SuccBB && + L->contains(SuccLoop)) { VisitStack.push_back(WorklistItem(SuccBB, true)); - SmallVector SubLoopExitBlocks; + SmallVector SubLoopExitBlocks; SuccLoop->getExitBlocks(SubLoopExitBlocks); for (unsigned i = 0; i < SubLoopExitBlocks.size(); ++i) { @@ -167,8 +130,8 @@ continue; } - bool IsExitBlock = std::binary_search(ExitBlocks.begin(), - ExitBlocks.end(), SuccBB); + bool IsExitBlock = + std::binary_search(ExitBlocks.begin(), ExitBlocks.end(), SuccBB); if (IsExitBlock) continue; @@ -186,3 +149,68 @@ return Changed; } + +namespace { +class LoopInstSimplifyLegacyPass : public LoopPass { +public: + static char ID; // Pass ID, replacement for typeid + LoopInstSimplifyLegacyPass() : LoopPass(ID) { + initializeLoopInstSimplifyLegacyPassPass(*PassRegistry::getPassRegistry()); + } + + bool runOnLoop(Loop *L, LPPassManager &LPM) override { + if (skipLoop(L)) + return false; + DominatorTreeWrapperPass *DTWP = + getAnalysisIfAvailable(); + DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr; + LoopInfo *LI = &getAnalysis().getLoopInfo(); + AssumptionCache *AC = + &getAnalysis().getAssumptionCache( + *L->getHeader()->getParent()); + const TargetLibraryInfo *TLI = + &getAnalysis().getTLI(); + + return SimplifyLoopInst(L, DT, LI, AC, TLI); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired(); + AU.addRequired(); + AU.setPreservesCFG(); + getLoopAnalysisUsage(AU); + } +}; +} + +PreservedAnalyses LoopInstSimplifyPass::run(Loop &L, + AnalysisManager &AM) { + const auto &FAM = + AM.getResult(L).getManager(); + Function *F = L.getHeader()->getParent(); + + // Use getCachedResult because Loop pass cannot trigger a function analysis. + auto *DT = FAM.getCachedResult(*F); + auto *LI = FAM.getCachedResult(*F); + auto *AC = FAM.getCachedResult(*F); + const auto *TLI = FAM.getCachedResult(*F); + assert((LI && AC && TLI) && "Analyses for Loop Inst Simplify not available"); + + if (!SimplifyLoopInst(&L, DT, LI, AC, TLI)) + return PreservedAnalyses::all(); + + return getLoopPassPreservedAnalyses(); +} + +char LoopInstSimplifyLegacyPass::ID = 0; +INITIALIZE_PASS_BEGIN(LoopInstSimplifyLegacyPass, "loop-instsimplify", + "Simplify instructions in loops", false, false) +INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) +INITIALIZE_PASS_DEPENDENCY(LoopPass) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) +INITIALIZE_PASS_END(LoopInstSimplifyLegacyPass, "loop-instsimplify", + "Simplify instructions in loops", false, false) + +Pass *llvm::createLoopInstSimplifyPass() { + return new LoopInstSimplifyLegacyPass(); +} Index: lib/Transforms/Scalar/Scalar.cpp =================================================================== --- lib/Transforms/Scalar/Scalar.cpp +++ lib/Transforms/Scalar/Scalar.cpp @@ -52,7 +52,7 @@ initializeLoopDataPrefetchPass(Registry); initializeLoopDeletionPass(Registry); initializeLoopAccessLegacyAnalysisPass(Registry); - initializeLoopInstSimplifyPass(Registry); + initializeLoopInstSimplifyLegacyPassPass(Registry); initializeLoopInterchangePass(Registry); initializeLoopRotateLegacyPassPass(Registry); initializeLoopStrengthReducePass(Registry);