1d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner//===- Mem2Reg.cpp - The -mem2reg pass, a wrapper around the Utils lib ----===//
2fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman//
3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//                     The LLVM Compiler Infrastructure
4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman//
8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===//
9d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner//
10d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner// This pass is a simple pass wrapper around the PromoteMemToReg function call
11d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner// exposed by the Utils library.
12d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner//
13d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner//===----------------------------------------------------------------------===//
14d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner
15d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner#include "llvm/Transforms/Scalar.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h"
17ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Analysis/AssumptionCache.h"
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Dominators.h"
190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h"
21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Transforms/Utils/PromoteMemToReg.h"
22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
23d7456026629fc1760a45e6e955e9834246493147Chris Lattnerusing namespace llvm;
24d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "mem2reg"
26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
27d216e8ba60494caacf919cbf5fef110d48f0d162Chris LattnerSTATISTIC(NumPromoted, "Number of alloca's promoted");
28d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner
29d216e8ba60494caacf919cbf5fef110d48f0d162Chris Lattnernamespace {
306726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky  struct PromotePass : public FunctionPass {
31ecd94c804a563f2a86572dcf1d2e81f397e19daaNick Lewycky    static char ID; // Pass identification, replacement for typeid
32081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    PromotePass() : FunctionPass(ID) {
33081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson      initializePromotePassPass(*PassRegistry::getPassRegistry());
34081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    }
35794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel
36d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner    // runOnFunction - To run this pass, first we calculate the alloca
37d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner    // instructions that are safe for promotion, then we promote each one.
38d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner    //
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool runOnFunction(Function &F) override;
40d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void getAnalysisUsage(AnalysisUsage &AU) const override {
42ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      AU.addRequired<AssumptionCacheTracker>();
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      AU.addRequired<DominatorTreeWrapperPass>();
44d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner      AU.setPreservesCFG();
45bed2946a96ecb15b0b636fa74cb26ce61b1c648eAnton Korobeynikov      // This is a cluster of orthogonal Transforms
468d89e7bdbcea38fe2ab3c85d91359712cd45714bChris Lattner      AU.addPreserved<UnifyFunctionExitNodes>();
478d89e7bdbcea38fe2ab3c85d91359712cd45714bChris Lattner      AU.addPreservedID(LowerSwitchID);
48ed96fe8c79b36a38bd9280438656ee539276fb41Chris Lattner      AU.addPreservedID(LowerInvokePassID);
49d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner    }
50d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner  };
51d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner}  // end of anonymous namespace
52d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner
53844731a7f1909f55935e3514c9e713a62d67662eDan Gohmanchar PromotePass::ID = 0;
542ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_BEGIN(PromotePass, "mem2reg", "Promote Memory to Register",
552ab36d350293c77fc8941ce1023e4899df7e3a82Owen Anderson                false, false)
56ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
582ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_END(PromotePass, "mem2reg", "Promote Memory to Register",
59ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson                false, false)
60844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
61d99bf49a53d170112c0241a4393ab374666b04bdChris Lattnerbool PromotePass::runOnFunction(Function &F) {
62d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner  std::vector<AllocaInst*> Allocas;
63d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner
6402a3be020a6b4eedb4b489959997d23a22cdf22eChris Lattner  BasicBlock &BB = F.getEntryBlock();  // Get the entry node for the function
65d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner
66cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (F.hasFnAttribute(Attribute::OptimizeNone))
67cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return false;
68cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
6983c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner  bool Changed  = false;
7043f820d1f7638656be2158efac7dd8f5b08b8b77Chris Lattner
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
72ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  AssumptionCache &AC =
73ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
74fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman
7583c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner  while (1) {
7683c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner    Allocas.clear();
7783c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner
7883c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner    // Find allocas that are safe to promote, by looking at all instructions in
7983c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner    // the entry node
8083c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner    for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
8183c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner      if (AllocaInst *AI = dyn_cast<AllocaInst>(I))       // Is it an alloca?
826c1fa7caaefc88a5a867add402d90115823bd0ebNick Lewycky        if (isAllocaPromotable(AI))
8383c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner          Allocas.push_back(AI);
8483c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner
8583c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner    if (Allocas.empty()) break;
8683c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner
87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    PromoteMemToReg(Allocas, DT, nullptr, &AC);
88d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner    NumPromoted += Allocas.size();
8983c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner    Changed = true;
90d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner  }
9183c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner
9283c39d2edb478e54818b9acc6685c001b76255c6Chris Lattner  return Changed;
93d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner}
94d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner
95d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner// createPromoteMemoryToRegister - Provide an entry point to create this pass.
96d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner//
97ab7ada3ed6a3dbefa05714a5de437997f7f6042cAlkis EvlogimenosFunctionPass *llvm::createPromoteMemoryToRegisterPass() {
98d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner  return new PromotePass();
99d99bf49a53d170112c0241a4393ab374666b04bdChris Lattner}
100