xref: /minix3/external/bsd/llvm/dist/llvm/lib/Transforms/Utils/Mem2Reg.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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