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