1 //===- Mem2Reg.cpp - The -mem2reg pass, a wrapper around the Utils lib ----===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This pass is a simple pass wrapper around the PromoteMemToReg function call
11 // exposed by the Utils library.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Transforms/Utils/Mem2Reg.h"
16 #include "llvm/ADT/Statistic.h"
17 #include "llvm/Analysis/AssumptionCache.h"
18 #include "llvm/IR/Dominators.h"
19 #include "llvm/IR/Function.h"
20 #include "llvm/IR/Instructions.h"
21 #include "llvm/Transforms/Scalar.h"
22 #include "llvm/Transforms/Utils/PromoteMemToReg.h"
23 #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
24 using namespace llvm;
25
26 #define DEBUG_TYPE "mem2reg"
27
28 STATISTIC(NumPromoted, "Number of alloca's promoted");
29
promoteMemoryToRegister(Function & F,DominatorTree & DT,AssumptionCache & AC)30 static bool promoteMemoryToRegister(Function &F, DominatorTree &DT,
31 AssumptionCache &AC) {
32 std::vector<AllocaInst *> Allocas;
33 BasicBlock &BB = F.getEntryBlock(); // Get the entry node for the function
34 bool Changed = false;
35
36 while (1) {
37 Allocas.clear();
38
39 // Find allocas that are safe to promote, by looking at all instructions in
40 // the entry node
41 for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
42 if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) // Is it an alloca?
43 if (isAllocaPromotable(AI))
44 Allocas.push_back(AI);
45
46 if (Allocas.empty())
47 break;
48
49 PromoteMemToReg(Allocas, DT, nullptr, &AC);
50 NumPromoted += Allocas.size();
51 Changed = true;
52 }
53 return Changed;
54 }
55
run(Function & F,AnalysisManager<Function> & AM)56 PreservedAnalyses PromotePass::run(Function &F, AnalysisManager<Function> &AM) {
57 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
58 auto &AC = AM.getResult<AssumptionAnalysis>(F);
59 if (!promoteMemoryToRegister(F, DT, AC))
60 return PreservedAnalyses::all();
61
62 // FIXME: This should also 'preserve the CFG'.
63 return PreservedAnalyses::none();
64 }
65
66 namespace {
67 struct PromoteLegacyPass : public FunctionPass {
68 static char ID; // Pass identification, replacement for typeid
PromoteLegacyPass__anon471c8ac60111::PromoteLegacyPass69 PromoteLegacyPass() : FunctionPass(ID) {
70 initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());
71 }
72
73 // runOnFunction - To run this pass, first we calculate the alloca
74 // instructions that are safe for promotion, then we promote each one.
75 //
runOnFunction__anon471c8ac60111::PromoteLegacyPass76 bool runOnFunction(Function &F) override {
77 if (skipFunction(F))
78 return false;
79
80 DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
81 AssumptionCache &AC =
82 getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
83 return promoteMemoryToRegister(F, DT, AC);
84 }
85
getAnalysisUsage__anon471c8ac60111::PromoteLegacyPass86 void getAnalysisUsage(AnalysisUsage &AU) const override {
87 AU.addRequired<AssumptionCacheTracker>();
88 AU.addRequired<DominatorTreeWrapperPass>();
89 AU.setPreservesCFG();
90 }
91 };
92 } // end of anonymous namespace
93
94 char PromoteLegacyPass::ID = 0;
95 INITIALIZE_PASS_BEGIN(PromoteLegacyPass, "mem2reg", "Promote Memory to "
96 "Register",
97 false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)98 INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
99 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
100 INITIALIZE_PASS_END(PromoteLegacyPass, "mem2reg", "Promote Memory to Register",
101 false, false)
102
103 // createPromoteMemoryToRegister - Provide an entry point to create this pass.
104 //
105 FunctionPass *llvm::createPromoteMemoryToRegisterPass() {
106 return new PromoteLegacyPass();
107 }
108