2004-02-28 11:33:01 +08:00
|
|
|
//===- LoopExtractor.cpp - Extract each loop into a new function ----------===//
|
2005-04-22 07:48:37 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2005-04-22 07:48:37 +08:00
|
|
|
//
|
2004-03-14 10:34:07 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2004-02-28 11:33:01 +08:00
|
|
|
//
|
|
|
|
// A pass wrapper around the ExtractLoop() scalar transformation to extract each
|
|
|
|
// top-level loop into its own new function. If the loop is the ONLY loop in a
|
2004-03-02 08:19:09 +08:00
|
|
|
// given function, it is not touched. This is a pass most useful for debugging
|
|
|
|
// via bugpoint.
|
2004-02-28 11:33:01 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/ADT/Statistic.h"
|
2019-02-08 14:55:18 +08:00
|
|
|
#include "llvm/Analysis/AssumptionCache.h"
|
2020-02-09 18:25:21 +08:00
|
|
|
#include "llvm/Analysis/LoopInfo.h"
|
2014-01-13 17:26:24 +08:00
|
|
|
#include "llvm/IR/Dominators.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/Instructions.h"
|
|
|
|
#include "llvm/IR/Module.h"
|
Sink all InitializePasses.h includes
This file lists every pass in LLVM, and is included by Pass.h, which is
very popular. Every time we add, remove, or rename a pass in LLVM, it
caused lots of recompilation.
I found this fact by looking at this table, which is sorted by the
number of times a file was changed over the last 100,000 git commits
multiplied by the number of object files that depend on it in the
current checkout:
recompiles touches affected_files header
342380 95 3604 llvm/include/llvm/ADT/STLExtras.h
314730 234 1345 llvm/include/llvm/InitializePasses.h
307036 118 2602 llvm/include/llvm/ADT/APInt.h
213049 59 3611 llvm/include/llvm/Support/MathExtras.h
170422 47 3626 llvm/include/llvm/Support/Compiler.h
162225 45 3605 llvm/include/llvm/ADT/Optional.h
158319 63 2513 llvm/include/llvm/ADT/Triple.h
140322 39 3598 llvm/include/llvm/ADT/StringRef.h
137647 59 2333 llvm/include/llvm/Support/Error.h
131619 73 1803 llvm/include/llvm/Support/FileSystem.h
Before this change, touching InitializePasses.h would cause 1345 files
to recompile. After this change, touching it only causes 550 compiles in
an incremental rebuild.
Reviewers: bkramer, asbirlea, bollu, jdoerfert
Differential Revision: https://reviews.llvm.org/D70211
2019-11-14 05:15:01 +08:00
|
|
|
#include "llvm/InitializePasses.h"
|
2004-02-28 11:33:01 +08:00
|
|
|
#include "llvm/Pass.h"
|
2007-11-14 14:47:06 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2017-06-06 19:49:48 +08:00
|
|
|
#include "llvm/Transforms/IPO.h"
|
2004-03-14 12:01:06 +08:00
|
|
|
#include "llvm/Transforms/Scalar.h"
|
2018-03-29 01:44:36 +08:00
|
|
|
#include "llvm/Transforms/Utils.h"
|
2011-09-21 03:10:24 +08:00
|
|
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
2012-05-04 18:18:49 +08:00
|
|
|
#include "llvm/Transforms/Utils/CodeExtractor.h"
|
2007-11-14 14:47:06 +08:00
|
|
|
#include <fstream>
|
|
|
|
#include <set>
|
2004-02-28 11:33:01 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2014-04-22 10:55:47 +08:00
|
|
|
#define DEBUG_TYPE "loop-extract"
|
|
|
|
|
2006-12-20 06:09:18 +08:00
|
|
|
STATISTIC(NumExtracted, "Number of loops extracted");
|
2005-04-22 07:48:37 +08:00
|
|
|
|
2006-12-20 06:09:18 +08:00
|
|
|
namespace {
|
2020-02-09 18:25:21 +08:00
|
|
|
struct LoopExtractor : public ModulePass {
|
2007-05-06 21:37:16 +08:00
|
|
|
static char ID; // Pass identification, replacement for typeid
|
2020-02-09 18:25:21 +08:00
|
|
|
|
|
|
|
// The number of natural loops to extract from the program into functions.
|
2004-03-15 04:01:36 +08:00
|
|
|
unsigned NumLoops;
|
|
|
|
|
2016-01-09 03:08:53 +08:00
|
|
|
explicit LoopExtractor(unsigned numLoops = ~0)
|
2020-02-09 18:25:21 +08:00
|
|
|
: ModulePass(ID), NumLoops(numLoops) {
|
|
|
|
initializeLoopExtractorPass(*PassRegistry::getPassRegistry());
|
|
|
|
}
|
2004-03-15 04:01:36 +08:00
|
|
|
|
2020-02-09 18:25:21 +08:00
|
|
|
bool runOnModule(Module &M) override;
|
|
|
|
bool runOnFunction(Function &F);
|
|
|
|
|
|
|
|
bool extractLoops(Loop::iterator From, Loop::iterator To, LoopInfo &LI,
|
|
|
|
DominatorTree &DT);
|
|
|
|
bool extractLoop(Loop *L, LoopInfo &LI, DominatorTree &DT);
|
2005-04-22 07:48:37 +08:00
|
|
|
|
2014-03-05 17:10:37 +08:00
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
2004-03-18 13:43:18 +08:00
|
|
|
AU.addRequiredID(BreakCriticalEdgesID);
|
2014-01-13 21:07:17 +08:00
|
|
|
AU.addRequired<DominatorTreeWrapperPass>();
|
2015-12-17 02:40:20 +08:00
|
|
|
AU.addRequired<LoopInfoWrapperPass>();
|
2020-02-09 18:25:21 +08:00
|
|
|
AU.addPreserved<LoopInfoWrapperPass>();
|
2020-02-13 04:39:21 +08:00
|
|
|
AU.addRequiredID(LoopSimplifyID);
|
2019-02-08 14:55:18 +08:00
|
|
|
AU.addUsedIfAvailable<AssumptionCacheTracker>();
|
2004-03-14 10:34:07 +08:00
|
|
|
}
|
|
|
|
};
|
2015-06-23 17:49:53 +08:00
|
|
|
}
|
2004-03-14 10:34:07 +08:00
|
|
|
|
2008-05-13 08:00:25 +08:00
|
|
|
char LoopExtractor::ID = 0;
|
2010-10-13 03:48:12 +08:00
|
|
|
INITIALIZE_PASS_BEGIN(LoopExtractor, "loop-extract",
|
2011-09-21 03:10:24 +08:00
|
|
|
"Extract loops into new functions", false, false)
|
2010-10-13 03:48:12 +08:00
|
|
|
INITIALIZE_PASS_DEPENDENCY(BreakCriticalEdges)
|
2014-01-13 21:07:17 +08:00
|
|
|
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
2020-02-09 18:25:21 +08:00
|
|
|
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
2020-02-13 04:39:21 +08:00
|
|
|
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
|
2010-10-13 03:48:12 +08:00
|
|
|
INITIALIZE_PASS_END(LoopExtractor, "loop-extract",
|
2011-09-21 03:10:24 +08:00
|
|
|
"Extract loops into new functions", false, false)
|
2004-03-15 04:01:36 +08:00
|
|
|
|
2008-05-13 08:00:25 +08:00
|
|
|
namespace {
|
2004-03-15 04:01:36 +08:00
|
|
|
/// SingleLoopExtractor - For bugpoint.
|
|
|
|
struct SingleLoopExtractor : public LoopExtractor {
|
2007-05-06 21:37:16 +08:00
|
|
|
static char ID; // Pass identification, replacement for typeid
|
2004-03-15 04:01:36 +08:00
|
|
|
SingleLoopExtractor() : LoopExtractor(1) {}
|
|
|
|
};
|
2005-04-22 07:48:37 +08:00
|
|
|
} // End anonymous namespace
|
2004-02-28 11:33:01 +08:00
|
|
|
|
2008-05-13 08:00:25 +08:00
|
|
|
char SingleLoopExtractor::ID = 0;
|
2010-07-22 06:09:45 +08:00
|
|
|
INITIALIZE_PASS(SingleLoopExtractor, "loop-extract-single",
|
2010-10-08 06:25:06 +08:00
|
|
|
"Extract at most one loop into a new function", false, false)
|
2008-05-13 08:00:25 +08:00
|
|
|
|
2005-01-09 01:21:40 +08:00
|
|
|
// createLoopExtractorPass - This pass extracts all natural loops from the
|
|
|
|
// program into a function if it can.
|
|
|
|
//
|
2009-09-28 22:37:51 +08:00
|
|
|
Pass *llvm::createLoopExtractorPass() { return new LoopExtractor(); }
|
2005-01-09 01:21:40 +08:00
|
|
|
|
2020-02-09 18:25:21 +08:00
|
|
|
bool LoopExtractor::runOnModule(Module &M) {
|
|
|
|
if (skipModule(M))
|
2014-02-06 08:07:05 +08:00
|
|
|
return false;
|
|
|
|
|
2020-02-09 18:25:21 +08:00
|
|
|
if (M.empty())
|
2004-02-28 11:33:01 +08:00
|
|
|
return false;
|
|
|
|
|
2020-02-09 18:25:21 +08:00
|
|
|
if (!NumLoops)
|
2009-11-06 05:11:53 +08:00
|
|
|
return false;
|
|
|
|
|
2004-02-28 11:33:01 +08:00
|
|
|
bool Changed = false;
|
2005-04-22 07:48:37 +08:00
|
|
|
|
2020-02-09 18:25:21 +08:00
|
|
|
// The end of the function list may change (new functions will be added at the
|
|
|
|
// end), so we run from the first to the current last.
|
|
|
|
auto I = M.begin(), E = --M.end();
|
|
|
|
while (true) {
|
|
|
|
Function &F = *I;
|
|
|
|
|
|
|
|
Changed |= runOnFunction(F);
|
|
|
|
if (!NumLoops)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// If this is the last function.
|
|
|
|
if (I == E)
|
|
|
|
break;
|
|
|
|
|
|
|
|
++I;
|
|
|
|
}
|
|
|
|
return Changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LoopExtractor::runOnFunction(Function &F) {
|
|
|
|
// Do not modify `optnone` functions.
|
|
|
|
if (F.hasOptNone())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (F.empty())
|
|
|
|
return false;
|
|
|
|
|
2020-06-26 21:23:05 +08:00
|
|
|
bool Changed = false;
|
|
|
|
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>(F, &Changed).getLoopInfo();
|
2020-02-09 18:25:21 +08:00
|
|
|
|
|
|
|
// If there are no loops in the function.
|
|
|
|
if (LI.empty())
|
2020-06-26 21:23:05 +08:00
|
|
|
return Changed;
|
2020-02-09 18:25:21 +08:00
|
|
|
|
|
|
|
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
|
|
|
|
|
2009-09-28 22:37:51 +08:00
|
|
|
// If there is more than one top-level loop in this function, extract all of
|
2020-02-09 18:25:21 +08:00
|
|
|
// the loops.
|
|
|
|
if (std::next(LI.begin()) != LI.end())
|
2020-06-26 21:23:05 +08:00
|
|
|
return Changed | extractLoops(LI.begin(), LI.end(), LI, DT);
|
2020-02-09 18:25:21 +08:00
|
|
|
|
|
|
|
// Otherwise there is exactly one top-level loop.
|
|
|
|
Loop *TLL = *LI.begin();
|
|
|
|
|
|
|
|
// If the loop is in LoopSimplify form, then extract it only if this function
|
|
|
|
// is more than a minimal wrapper around the loop.
|
|
|
|
if (TLL->isLoopSimplifyForm()) {
|
|
|
|
bool ShouldExtractLoop = false;
|
|
|
|
|
|
|
|
// Extract the loop if the entry block doesn't branch to the loop header.
|
|
|
|
Instruction *EntryTI = F.getEntryBlock().getTerminator();
|
|
|
|
if (!isa<BranchInst>(EntryTI) ||
|
|
|
|
!cast<BranchInst>(EntryTI)->isUnconditional() ||
|
|
|
|
EntryTI->getSuccessor(0) != TLL->getHeader()) {
|
|
|
|
ShouldExtractLoop = true;
|
|
|
|
} else {
|
|
|
|
// Check to see if any exits from the loop are more than just return
|
|
|
|
// blocks.
|
|
|
|
SmallVector<BasicBlock *, 8> ExitBlocks;
|
|
|
|
TLL->getExitBlocks(ExitBlocks);
|
|
|
|
for (auto *ExitBlock : ExitBlocks)
|
|
|
|
if (!isa<ReturnInst>(ExitBlock->getTerminator())) {
|
|
|
|
ShouldExtractLoop = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ShouldExtractLoop)
|
2020-06-26 21:23:05 +08:00
|
|
|
return Changed | extractLoop(TLL, LI, DT);
|
2011-09-21 06:27:16 +08:00
|
|
|
}
|
|
|
|
|
2020-02-09 18:25:21 +08:00
|
|
|
// Okay, this function is a minimal container around the specified loop.
|
|
|
|
// If we extract the loop, we will continue to just keep extracting it
|
|
|
|
// infinitely... so don't extract it. However, if the loop contains any
|
|
|
|
// sub-loops, extract them.
|
2020-06-26 21:23:05 +08:00
|
|
|
return Changed | extractLoops(TLL->begin(), TLL->end(), LI, DT);
|
2020-02-09 18:25:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool LoopExtractor::extractLoops(Loop::iterator From, Loop::iterator To,
|
|
|
|
LoopInfo &LI, DominatorTree &DT) {
|
|
|
|
bool Changed = false;
|
|
|
|
SmallVector<Loop *, 8> Loops;
|
|
|
|
|
|
|
|
// Save the list of loops, as it may change.
|
|
|
|
Loops.assign(From, To);
|
|
|
|
for (Loop *L : Loops) {
|
|
|
|
// If LoopSimplify form is not available, stay out of trouble.
|
|
|
|
if (!L->isLoopSimplifyForm())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Changed |= extractLoop(L, LI, DT);
|
|
|
|
if (!NumLoops)
|
|
|
|
break;
|
2009-09-28 22:37:51 +08:00
|
|
|
}
|
2020-02-09 18:25:21 +08:00
|
|
|
return Changed;
|
|
|
|
}
|
2011-09-21 06:27:16 +08:00
|
|
|
|
2020-02-09 18:25:21 +08:00
|
|
|
bool LoopExtractor::extractLoop(Loop *L, LoopInfo &LI, DominatorTree &DT) {
|
|
|
|
assert(NumLoops != 0);
|
|
|
|
AssumptionCache *AC = nullptr;
|
|
|
|
Function &Func = *L->getHeader()->getParent();
|
|
|
|
if (auto *ACT = getAnalysisIfAvailable<AssumptionCacheTracker>())
|
|
|
|
AC = ACT->lookupAssumptionCache(Func);
|
|
|
|
CodeExtractorAnalysisCache CEAC(Func);
|
|
|
|
CodeExtractor Extractor(DT, *L, false, nullptr, nullptr, AC);
|
|
|
|
if (Extractor.extractCodeRegion(CEAC)) {
|
|
|
|
LI.erase(L);
|
2009-09-28 22:37:51 +08:00
|
|
|
--NumLoops;
|
|
|
|
++NumExtracted;
|
2020-02-09 18:25:21 +08:00
|
|
|
return true;
|
2004-03-15 04:01:36 +08:00
|
|
|
}
|
2020-02-09 18:25:21 +08:00
|
|
|
return false;
|
2004-02-28 11:33:01 +08:00
|
|
|
}
|
|
|
|
|
2004-03-15 04:01:36 +08:00
|
|
|
// createSingleLoopExtractorPass - This pass extracts one natural loop from the
|
|
|
|
// program into a function if it can. This is used by bugpoint.
|
|
|
|
//
|
2009-09-28 22:37:51 +08:00
|
|
|
Pass *llvm::createSingleLoopExtractorPass() {
|
2004-03-15 04:01:36 +08:00
|
|
|
return new SingleLoopExtractor();
|
2004-02-28 11:33:01 +08:00
|
|
|
}
|