I forgot to provide dominance frontier information. Now it's available.
[oota-llvm.git] / lib / Transforms / Utils / PromoteMemoryToRegister.cpp
1 //===- PromoteMemoryToRegister.cpp - Convert memory refs to regs ----------===//
2 //
3 // This pass is used to promote memory references to be register references.  A
4 // simple example of the transformation performed by this pass is:
5 //
6 //        FROM CODE                           TO CODE
7 //   %X = alloca int, uint 1                 ret int 42
8 //   store int 42, int *%X
9 //   %Y = load int* %X
10 //   ret int %Y
11 //
12 // To do this transformation, a simple analysis is done to ensure it is safe.
13 // Currently this just loops over all alloca instructions, looking for
14 // instructions that are only used in simple load and stores.
15 //
16 // After this, the code is transformed by...
17 //
18 //===----------------------------------------------------------------------===//
19
20 #include "llvm/Transforms/Scalar/PromoteMemoryToRegister.h"
21 #include "llvm/Analysis/Dominators.h"
22 #include "llvm/iMemory.h"
23 #include "llvm/Pass.h"
24 #include "llvm/Method.h"
25 #include "llvm/Assembly/Writer.h"  // For debugging
26 using cfg::DominanceFrontier;
27
28 // PromotePass - This class is implements the PromoteMemoryToRegister pass
29 //
30 class PromotePass : public MethodPass {
31 public:
32   // runOnMethod - To run this pass, first we calculate the alloca instructions
33   // that are safe for promotion, then we promote each one.
34   //
35   virtual bool runOnMethod(Method *M) {
36     std::vector<AllocaInst*> Allocas;
37     findSafeAllocas(M, Allocas);      // Calculate safe allocas
38
39     // Get dominance frontier information...
40     DominanceFrontier &DF = getAnalysis<DominanceFrontier>();
41
42     // Transform each alloca in turn...
43     for (std::vector<AllocaInst*>::iterator I = Allocas.begin(),
44            E = Allocas.end(); I != E; ++I)
45       promoteAlloca(*I, DF);
46
47     return !Allocas.empty();
48   }
49
50
51   // getAnalysisUsageInfo - We need dominance frontiers
52   //
53   virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Requires,
54                                     Pass::AnalysisSet &Destroyed,
55                                     Pass::AnalysisSet &Provided) {
56     Requires.push_back(DominanceFrontier::ID);
57   }
58
59 private:
60   // findSafeAllocas - Find allocas that are safe to promote
61   //
62   void findSafeAllocas(Method *M, std::vector<AllocaInst*> &Allocas) const;
63
64   // promoteAlloca - Convert the use chain of an alloca instruction into
65   // register references.
66   //
67   void promoteAlloca(AllocaInst *AI, DominanceFrontier &DF);
68 };
69
70
71 // findSafeAllocas - Find allocas that are safe to promote
72 //
73 void PromotePass::findSafeAllocas(Method *M,
74                                   std::vector<AllocaInst*> &Allocas) const {
75   BasicBlock *BB = M->front();  // Get the entry node for the method
76
77   // Look at all instructions in the entry node
78   for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
79     if (AllocaInst *AI = dyn_cast<AllocaInst>(*I))       // Is it an alloca?
80       if (!AI->isArrayAllocation()) {
81         bool isSafe = true;
82         for (Value::use_iterator UI = AI->use_begin(), UE = AI->use_end();
83              UI != UE; ++UI) {   // Loop over all of the uses of the alloca
84           // Only allow nonindexed memory access instructions...
85           if (MemAccessInst *MAI = dyn_cast<MemAccessInst>(*UI)) {
86             if (MAI->hasIndices()) { isSafe = false; break; } // indexed?
87           } else {
88             isSafe = false; break;   // Not a load or store?
89           }
90         }
91
92         if (isSafe)              // If all checks pass, add alloca to safe list
93           Allocas.push_back(AI);
94       }
95
96 }
97
98
99
100 // promoteAlloca - Convert the use chain of an alloca instruction into
101 // register references.
102 //
103 void PromotePass::promoteAlloca(AllocaInst *AI, DominanceFrontier &DFInfo) {
104   cerr << "TODO: Should process: " << AI;
105 }
106
107
108 // newPromoteMemoryToRegister - Provide an entry point to create this pass.
109 //
110 Pass *newPromoteMemoryToRegister() {
111   return new PromotePass();
112 }