-
Notifications
You must be signed in to change notification settings - Fork 12.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Restore the LoopInstSimplify pass, reverting r327329 that removed it.
The plan had always been to move towards using this rather than so much in-pass simplification within the loop pipeline, but we never got around to it.... until only a couple months after it was removed due to disuse. =/ This commit is just a pure revert of the removal. I will add tests and do some basic cleanup in follow-up commits. Then I'll wire it into the loop pass pipeline. Differential Revision: https://reviews.llvm.org/D47353 llvm-svn: 333250
- Loading branch information
Showing
9 changed files
with
273 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| //===- 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/LoopAnalysisManager.h" | ||
| #include "llvm/IR/PassManager.h" | ||
|
|
||
| namespace llvm { | ||
|
|
||
| class Loop; | ||
| class LPMUpdater; | ||
|
|
||
| /// Performs Loop Inst Simplify Pass. | ||
| class LoopInstSimplifyPass : public PassInfoMixin<LoopInstSimplifyPass> { | ||
| public: | ||
| PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, | ||
| LoopStandardAnalysisResults &AR, LPMUpdater &U); | ||
| }; | ||
|
|
||
| } // end namespace llvm | ||
|
|
||
| #endif // LLVM_TRANSFORMS_SCALAR_LOOPINSTSIMPLIFY_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,223 @@ | ||
| //===- LoopInstSimplify.cpp - Loop Instruction Simplification Pass --------===// | ||
| // | ||
| // 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. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "llvm/Transforms/Scalar/LoopInstSimplify.h" | ||
| #include "llvm/ADT/PointerIntPair.h" | ||
| #include "llvm/ADT/STLExtras.h" | ||
| #include "llvm/ADT/SmallPtrSet.h" | ||
| #include "llvm/ADT/SmallVector.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/TargetLibraryInfo.h" | ||
| #include "llvm/Analysis/Utils/Local.h" | ||
| #include "llvm/IR/BasicBlock.h" | ||
| #include "llvm/IR/CFG.h" | ||
| #include "llvm/IR/DataLayout.h" | ||
| #include "llvm/IR/Dominators.h" | ||
| #include "llvm/IR/Instruction.h" | ||
| #include "llvm/IR/Instructions.h" | ||
| #include "llvm/IR/Module.h" | ||
| #include "llvm/IR/PassManager.h" | ||
| #include "llvm/IR/User.h" | ||
| #include "llvm/Pass.h" | ||
| #include "llvm/Support/Casting.h" | ||
| #include "llvm/Transforms/Scalar.h" | ||
| #include "llvm/Transforms/Utils/LoopUtils.h" | ||
| #include <algorithm> | ||
| #include <utility> | ||
|
|
||
| using namespace llvm; | ||
|
|
||
| #define DEBUG_TYPE "loop-instsimplify" | ||
|
|
||
| STATISTIC(NumSimplified, "Number of redundant instructions simplified"); | ||
|
|
||
| static bool SimplifyLoopInst(Loop *L, DominatorTree *DT, LoopInfo *LI, | ||
| AssumptionCache *AC, | ||
| const TargetLibraryInfo *TLI) { | ||
| SmallVector<BasicBlock *, 8> ExitBlocks; | ||
| L->getUniqueExitBlocks(ExitBlocks); | ||
| array_pod_sort(ExitBlocks.begin(), ExitBlocks.end()); | ||
|
|
||
| SmallPtrSet<const Instruction *, 8> 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. | ||
| using WorklistItem = PointerIntPair<BasicBlock *, 1>; | ||
| SmallVector<WorklistItem, 16> VisitStack; | ||
| SmallPtrSet<BasicBlock *, 32> Visited; | ||
|
|
||
| bool Changed = false; | ||
| bool LocalChanged; | ||
| do { | ||
| LocalChanged = false; | ||
|
|
||
| VisitStack.clear(); | ||
| Visited.clear(); | ||
|
|
||
| VisitStack.push_back(WorklistItem(L->getHeader(), false)); | ||
|
|
||
| while (!VisitStack.empty()) { | ||
| WorklistItem Item = VisitStack.pop_back_val(); | ||
| BasicBlock *BB = Item.getPointer(); | ||
| bool IsSubloopHeader = Item.getInt(); | ||
| const DataLayout &DL = L->getHeader()->getModule()->getDataLayout(); | ||
|
|
||
| // Simplify instructions in the current basic block. | ||
| for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { | ||
| Instruction *I = &*BI++; | ||
|
|
||
| // The first time through the loop ToSimplify is empty and we try to | ||
| // simplify all instructions. On later iterations ToSimplify is not | ||
| // empty and we only bother simplifying instructions that are in it. | ||
| if (!ToSimplify->empty() && !ToSimplify->count(I)) | ||
| continue; | ||
|
|
||
| // Don't bother simplifying unused instructions. | ||
| if (!I->use_empty()) { | ||
| 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()) | ||
| Next->insert(cast<Instruction>(U)); | ||
|
|
||
| I->replaceAllUsesWith(V); | ||
| LocalChanged = true; | ||
| ++NumSimplified; | ||
| } | ||
| } | ||
| if (RecursivelyDeleteTriviallyDeadInstructions(I, TLI)) { | ||
| // 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(); | ||
| LocalChanged = true; | ||
| } | ||
|
|
||
| if (IsSubloopHeader && !isa<PHINode>(I)) | ||
| break; | ||
| } | ||
|
|
||
| // 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 | ||
| // edges leading back to the original loop. | ||
| for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; | ||
| ++SI) { | ||
| BasicBlock *SuccBB = *SI; | ||
| if (!Visited.insert(SuccBB).second) | ||
| continue; | ||
|
|
||
| const Loop *SuccLoop = LI->getLoopFor(SuccBB); | ||
| if (SuccLoop && SuccLoop->getHeader() == SuccBB && | ||
| L->contains(SuccLoop)) { | ||
| VisitStack.push_back(WorklistItem(SuccBB, true)); | ||
|
|
||
| SmallVector<BasicBlock *, 8> SubLoopExitBlocks; | ||
| SuccLoop->getExitBlocks(SubLoopExitBlocks); | ||
|
|
||
| for (unsigned i = 0; i < SubLoopExitBlocks.size(); ++i) { | ||
| BasicBlock *ExitBB = SubLoopExitBlocks[i]; | ||
| if (LI->getLoopFor(ExitBB) == L && Visited.insert(ExitBB).second) | ||
| VisitStack.push_back(WorklistItem(ExitBB, false)); | ||
| } | ||
|
|
||
| continue; | ||
| } | ||
|
|
||
| bool IsExitBlock = | ||
| std::binary_search(ExitBlocks.begin(), ExitBlocks.end(), SuccBB); | ||
| if (IsExitBlock) | ||
| continue; | ||
|
|
||
| VisitStack.push_back(WorklistItem(SuccBB, false)); | ||
| } | ||
| } | ||
|
|
||
| // Place the list of instructions to simplify on the next loop iteration | ||
| // into ToSimplify. | ||
| std::swap(ToSimplify, Next); | ||
| Next->clear(); | ||
|
|
||
| Changed |= LocalChanged; | ||
| } while (LocalChanged); | ||
|
|
||
| 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<DominatorTreeWrapperPass>(); | ||
| DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr; | ||
| LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); | ||
| AssumptionCache *AC = | ||
| &getAnalysis<AssumptionCacheTracker>().getAssumptionCache( | ||
| *L->getHeader()->getParent()); | ||
| const TargetLibraryInfo *TLI = | ||
| &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); | ||
|
|
||
| return SimplifyLoopInst(L, DT, LI, AC, TLI); | ||
| } | ||
|
|
||
| void getAnalysisUsage(AnalysisUsage &AU) const override { | ||
| AU.addRequired<AssumptionCacheTracker>(); | ||
| AU.addRequired<TargetLibraryInfoWrapperPass>(); | ||
| AU.setPreservesCFG(); | ||
| getLoopAnalysisUsage(AU); | ||
| } | ||
| }; | ||
|
|
||
| } // end anonymous namespace | ||
|
|
||
| PreservedAnalyses LoopInstSimplifyPass::run(Loop &L, LoopAnalysisManager &AM, | ||
| LoopStandardAnalysisResults &AR, | ||
| LPMUpdater &) { | ||
| if (!SimplifyLoopInst(&L, &AR.DT, &AR.LI, &AR.AC, &AR.TLI)) | ||
| return PreservedAnalyses::all(); | ||
|
|
||
| auto PA = getLoopPassPreservedAnalyses(); | ||
| PA.preserveSet<CFGAnalyses>(); | ||
| return PA; | ||
| } | ||
|
|
||
| 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(); | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters