aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/IPO/PartialInlining.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/IPO/PartialInlining.cpp')
-rw-r--r--lib/Transforms/IPO/PartialInlining.cpp74
1 files changed, 40 insertions, 34 deletions
diff --git a/lib/Transforms/IPO/PartialInlining.cpp b/lib/Transforms/IPO/PartialInlining.cpp
index 0c5c84bbccab..49c44173491e 100644
--- a/lib/Transforms/IPO/PartialInlining.cpp
+++ b/lib/Transforms/IPO/PartialInlining.cpp
@@ -12,13 +12,14 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/PartialInlining.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
+#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/CodeExtractor.h"
using namespace llvm;
@@ -28,27 +29,34 @@ using namespace llvm;
STATISTIC(NumPartialInlined, "Number of functions partially inlined");
namespace {
- struct PartialInliner : public ModulePass {
- void getAnalysisUsage(AnalysisUsage &AU) const override { }
- static char ID; // Pass identification, replacement for typeid
- PartialInliner() : ModulePass(ID) {
- initializePartialInlinerPass(*PassRegistry::getPassRegistry());
- }
+struct PartialInlinerLegacyPass : public ModulePass {
+ static char ID; // Pass identification, replacement for typeid
+ PartialInlinerLegacyPass() : ModulePass(ID) {
+ initializePartialInlinerLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
- bool runOnModule(Module& M) override;
+ bool runOnModule(Module &M) override {
+ if (skipModule(M))
+ return false;
+ ModuleAnalysisManager DummyMAM;
+ auto PA = Impl.run(M, DummyMAM);
+ return !PA.areAllPreserved();
+ }
- private:
- Function* unswitchFunction(Function* F);
+private:
+ PartialInlinerPass Impl;
};
}
-char PartialInliner::ID = 0;
-INITIALIZE_PASS(PartialInliner, "partial-inliner",
- "Partial Inliner", false, false)
+char PartialInlinerLegacyPass::ID = 0;
+INITIALIZE_PASS(PartialInlinerLegacyPass, "partial-inliner", "Partial Inliner",
+ false, false)
-ModulePass* llvm::createPartialInliningPass() { return new PartialInliner(); }
+ModulePass *llvm::createPartialInliningPass() {
+ return new PartialInlinerLegacyPass();
+}
-Function* PartialInliner::unswitchFunction(Function* F) {
+Function *PartialInlinerPass::unswitchFunction(Function *F) {
// First, verify that this function is an unswitching candidate...
BasicBlock *entryBlock = &F->front();
BranchInst *BR = dyn_cast<BranchInst>(entryBlock->getTerminator());
@@ -71,10 +79,8 @@ Function* PartialInliner::unswitchFunction(Function* F) {
// Clone the function, so that we can hack away on it.
ValueToValueMapTy VMap;
- Function* duplicateFunction = CloneFunction(F, VMap,
- /*ModuleLevelChanges=*/false);
+ Function* duplicateFunction = CloneFunction(F, VMap);
duplicateFunction->setLinkage(GlobalValue::InternalLinkage);
- F->getParent()->getFunctionList().push_back(duplicateFunction);
BasicBlock* newEntryBlock = cast<BasicBlock>(VMap[entryBlock]);
BasicBlock* newReturnBlock = cast<BasicBlock>(VMap[returnBlock]);
BasicBlock* newNonReturnBlock = cast<BasicBlock>(VMap[nonReturnBlock]);
@@ -112,11 +118,10 @@ Function* PartialInliner::unswitchFunction(Function* F) {
// Gather up the blocks that we're going to extract.
std::vector<BasicBlock*> toExtract;
toExtract.push_back(newNonReturnBlock);
- for (Function::iterator FI = duplicateFunction->begin(),
- FE = duplicateFunction->end(); FI != FE; ++FI)
- if (&*FI != newEntryBlock && &*FI != newReturnBlock &&
- &*FI != newNonReturnBlock)
- toExtract.push_back(&*FI);
+ for (BasicBlock &BB : *duplicateFunction)
+ if (&BB != newEntryBlock && &BB != newReturnBlock &&
+ &BB != newNonReturnBlock)
+ toExtract.push_back(&BB);
// The CodeExtractor needs a dominator tree.
DominatorTree DT;
@@ -131,11 +136,10 @@ Function* PartialInliner::unswitchFunction(Function* F) {
// Inline the top-level if test into all callers.
std::vector<User *> Users(duplicateFunction->user_begin(),
duplicateFunction->user_end());
- for (std::vector<User*>::iterator UI = Users.begin(), UE = Users.end();
- UI != UE; ++UI)
- if (CallInst *CI = dyn_cast<CallInst>(*UI))
+ for (User *User : Users)
+ if (CallInst *CI = dyn_cast<CallInst>(User))
InlineFunction(CI, IFI);
- else if (InvokeInst *II = dyn_cast<InvokeInst>(*UI))
+ else if (InvokeInst *II = dyn_cast<InvokeInst>(User))
InlineFunction(II, IFI);
// Ditch the duplicate, since we're done with it, and rewrite all remaining
@@ -148,13 +152,13 @@ Function* PartialInliner::unswitchFunction(Function* F) {
return extractedFunction;
}
-bool PartialInliner::runOnModule(Module& M) {
+PreservedAnalyses PartialInlinerPass::run(Module &M, ModuleAnalysisManager &) {
std::vector<Function*> worklist;
worklist.reserve(M.size());
- for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI)
- if (!FI->use_empty() && !FI->isDeclaration())
- worklist.push_back(&*FI);
-
+ for (Function &F : M)
+ if (!F.use_empty() && !F.isDeclaration())
+ worklist.push_back(&F);
+
bool changed = false;
while (!worklist.empty()) {
Function* currFunc = worklist.back();
@@ -178,6 +182,8 @@ bool PartialInliner::runOnModule(Module& M) {
}
}
-
- return changed;
+
+ if (changed)
+ return PreservedAnalyses::none();
+ return PreservedAnalyses::all();
}