Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/IPO/LoopExtractor.cpp
35266 views
//===- LoopExtractor.cpp - Extract each loop into a new function ----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// A pass wrapper around the ExtractLoop() scalar transformation to extract each9// top-level loop into its own new function. If the loop is the ONLY loop in a10// given function, it is not touched. This is a pass most useful for debugging11// via bugpoint.12//13//===----------------------------------------------------------------------===//1415#include "llvm/Transforms/IPO/LoopExtractor.h"16#include "llvm/ADT/Statistic.h"17#include "llvm/Analysis/AssumptionCache.h"18#include "llvm/Analysis/LoopInfo.h"19#include "llvm/IR/Dominators.h"20#include "llvm/IR/Instructions.h"21#include "llvm/IR/Module.h"22#include "llvm/IR/PassManager.h"23#include "llvm/InitializePasses.h"24#include "llvm/Pass.h"25#include "llvm/Transforms/IPO.h"26#include "llvm/Transforms/Utils.h"27#include "llvm/Transforms/Utils/CodeExtractor.h"28using namespace llvm;2930#define DEBUG_TYPE "loop-extract"3132STATISTIC(NumExtracted, "Number of loops extracted");3334namespace {35struct LoopExtractorLegacyPass : public ModulePass {36static char ID; // Pass identification, replacement for typeid3738unsigned NumLoops;3940explicit LoopExtractorLegacyPass(unsigned NumLoops = ~0)41: ModulePass(ID), NumLoops(NumLoops) {42initializeLoopExtractorLegacyPassPass(*PassRegistry::getPassRegistry());43}4445bool runOnModule(Module &M) override;4647void getAnalysisUsage(AnalysisUsage &AU) const override {48AU.addRequiredID(BreakCriticalEdgesID);49AU.addRequired<DominatorTreeWrapperPass>();50AU.addRequired<LoopInfoWrapperPass>();51AU.addPreserved<LoopInfoWrapperPass>();52AU.addRequiredID(LoopSimplifyID);53AU.addUsedIfAvailable<AssumptionCacheTracker>();54}55};5657struct LoopExtractor {58explicit LoopExtractor(59unsigned NumLoops,60function_ref<DominatorTree &(Function &)> LookupDomTree,61function_ref<LoopInfo &(Function &)> LookupLoopInfo,62function_ref<AssumptionCache *(Function &)> LookupAssumptionCache)63: NumLoops(NumLoops), LookupDomTree(LookupDomTree),64LookupLoopInfo(LookupLoopInfo),65LookupAssumptionCache(LookupAssumptionCache) {}66bool runOnModule(Module &M);6768private:69// The number of natural loops to extract from the program into functions.70unsigned NumLoops;7172function_ref<DominatorTree &(Function &)> LookupDomTree;73function_ref<LoopInfo &(Function &)> LookupLoopInfo;74function_ref<AssumptionCache *(Function &)> LookupAssumptionCache;7576bool runOnFunction(Function &F);7778bool extractLoops(Loop::iterator From, Loop::iterator To, LoopInfo &LI,79DominatorTree &DT);80bool extractLoop(Loop *L, LoopInfo &LI, DominatorTree &DT);81};82} // namespace8384char LoopExtractorLegacyPass::ID = 0;85INITIALIZE_PASS_BEGIN(LoopExtractorLegacyPass, "loop-extract",86"Extract loops into new functions", false, false)87INITIALIZE_PASS_DEPENDENCY(BreakCriticalEdges)88INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)89INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)90INITIALIZE_PASS_DEPENDENCY(LoopSimplify)91INITIALIZE_PASS_END(LoopExtractorLegacyPass, "loop-extract",92"Extract loops into new functions", false, false)9394namespace {95/// SingleLoopExtractor - For bugpoint.96struct SingleLoopExtractor : public LoopExtractorLegacyPass {97static char ID; // Pass identification, replacement for typeid98SingleLoopExtractor() : LoopExtractorLegacyPass(1) {}99};100} // End anonymous namespace101102char SingleLoopExtractor::ID = 0;103INITIALIZE_PASS(SingleLoopExtractor, "loop-extract-single",104"Extract at most one loop into a new function", false, false)105106// createLoopExtractorPass - This pass extracts all natural loops from the107// program into a function if it can.108//109Pass *llvm::createLoopExtractorPass() { return new LoopExtractorLegacyPass(); }110111bool LoopExtractorLegacyPass::runOnModule(Module &M) {112if (skipModule(M))113return false;114115bool Changed = false;116auto LookupDomTree = [this](Function &F) -> DominatorTree & {117return this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();118};119auto LookupLoopInfo = [this, &Changed](Function &F) -> LoopInfo & {120return this->getAnalysis<LoopInfoWrapperPass>(F, &Changed).getLoopInfo();121};122auto LookupACT = [this](Function &F) -> AssumptionCache * {123if (auto *ACT = this->getAnalysisIfAvailable<AssumptionCacheTracker>())124return ACT->lookupAssumptionCache(F);125return nullptr;126};127return LoopExtractor(NumLoops, LookupDomTree, LookupLoopInfo, LookupACT)128.runOnModule(M) ||129Changed;130}131132bool LoopExtractor::runOnModule(Module &M) {133if (M.empty())134return false;135136if (!NumLoops)137return false;138139bool Changed = false;140141// The end of the function list may change (new functions will be added at the142// end), so we run from the first to the current last.143auto I = M.begin(), E = --M.end();144while (true) {145Function &F = *I;146147Changed |= runOnFunction(F);148if (!NumLoops)149break;150151// If this is the last function.152if (I == E)153break;154155++I;156}157return Changed;158}159160bool LoopExtractor::runOnFunction(Function &F) {161// Do not modify `optnone` functions.162if (F.hasOptNone())163return false;164165if (F.empty())166return false;167168bool Changed = false;169LoopInfo &LI = LookupLoopInfo(F);170171// If there are no loops in the function.172if (LI.empty())173return Changed;174175DominatorTree &DT = LookupDomTree(F);176177// If there is more than one top-level loop in this function, extract all of178// the loops.179if (std::next(LI.begin()) != LI.end())180return Changed | extractLoops(LI.begin(), LI.end(), LI, DT);181182// Otherwise there is exactly one top-level loop.183Loop *TLL = *LI.begin();184185// If the loop is in LoopSimplify form, then extract it only if this function186// is more than a minimal wrapper around the loop.187if (TLL->isLoopSimplifyForm()) {188bool ShouldExtractLoop = false;189190// Extract the loop if the entry block doesn't branch to the loop header.191Instruction *EntryTI = F.getEntryBlock().getTerminator();192if (!isa<BranchInst>(EntryTI) ||193!cast<BranchInst>(EntryTI)->isUnconditional() ||194EntryTI->getSuccessor(0) != TLL->getHeader()) {195ShouldExtractLoop = true;196} else {197// Check to see if any exits from the loop are more than just return198// blocks.199SmallVector<BasicBlock *, 8> ExitBlocks;200TLL->getExitBlocks(ExitBlocks);201for (auto *ExitBlock : ExitBlocks)202if (!isa<ReturnInst>(ExitBlock->getTerminator())) {203ShouldExtractLoop = true;204break;205}206}207208if (ShouldExtractLoop)209return Changed | extractLoop(TLL, LI, DT);210}211212// Okay, this function is a minimal container around the specified loop.213// If we extract the loop, we will continue to just keep extracting it214// infinitely... so don't extract it. However, if the loop contains any215// sub-loops, extract them.216return Changed | extractLoops(TLL->begin(), TLL->end(), LI, DT);217}218219bool LoopExtractor::extractLoops(Loop::iterator From, Loop::iterator To,220LoopInfo &LI, DominatorTree &DT) {221bool Changed = false;222SmallVector<Loop *, 8> Loops;223224// Save the list of loops, as it may change.225Loops.assign(From, To);226for (Loop *L : Loops) {227// If LoopSimplify form is not available, stay out of trouble.228if (!L->isLoopSimplifyForm())229continue;230231Changed |= extractLoop(L, LI, DT);232if (!NumLoops)233break;234}235return Changed;236}237238bool LoopExtractor::extractLoop(Loop *L, LoopInfo &LI, DominatorTree &DT) {239assert(NumLoops != 0);240Function &Func = *L->getHeader()->getParent();241AssumptionCache *AC = LookupAssumptionCache(Func);242CodeExtractorAnalysisCache CEAC(Func);243CodeExtractor Extractor(DT, *L, false, nullptr, nullptr, AC);244if (Extractor.extractCodeRegion(CEAC)) {245LI.erase(L);246--NumLoops;247++NumExtracted;248return true;249}250return false;251}252253// createSingleLoopExtractorPass - This pass extracts one natural loop from the254// program into a function if it can. This is used by bugpoint.255//256Pass *llvm::createSingleLoopExtractorPass() {257return new SingleLoopExtractor();258}259260PreservedAnalyses LoopExtractorPass::run(Module &M, ModuleAnalysisManager &AM) {261auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();262auto LookupDomTree = [&FAM](Function &F) -> DominatorTree & {263return FAM.getResult<DominatorTreeAnalysis>(F);264};265auto LookupLoopInfo = [&FAM](Function &F) -> LoopInfo & {266return FAM.getResult<LoopAnalysis>(F);267};268auto LookupAssumptionCache = [&FAM](Function &F) -> AssumptionCache * {269return FAM.getCachedResult<AssumptionAnalysis>(F);270};271if (!LoopExtractor(NumLoops, LookupDomTree, LookupLoopInfo,272LookupAssumptionCache)273.runOnModule(M))274return PreservedAnalyses::all();275276PreservedAnalyses PA;277PA.preserve<LoopAnalysis>();278return PA;279}280281void LoopExtractorPass::printPipeline(282raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {283static_cast<PassInfoMixin<LoopExtractorPass> *>(this)->printPipeline(284OS, MapClassName2PassName);285OS << '<';286if (NumLoops == 1)287OS << "single";288OS << '>';289}290291292