s/Method/Function
[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...something magical :)
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/Function.h"
25 #include "llvm/BasicBlock.h"
26 #include "llvm/iPHINode.h"
27 #include "llvm/iTerminators.h"
28
29 using namespace std;
30
31
32 using cfg::DominanceFrontier;
33
34 namespace {
35
36 //instance of the promoter -- to keep all the local function data.
37 // gets re-created for each function processed
38 class PromoteInstance
39 {
40         protected:
41         vector<AllocaInst*>                     Allocas;   // the alloca instruction..
42         map<Instruction *, int>                 AllocaLookup; //reverse mapping of above
43
44         vector<vector<BasicBlock *> >           WriteSets; // index corresponds to Allocas
45         vector<vector<BasicBlock *> >           PhiNodes;  // index corresponds to Allocas
46         vector<vector<Value *> >                CurrentValue; //the current value stack
47
48         //list of instructions to remove at end of pass :)
49         vector<Instruction *> killlist;
50
51         set<BasicBlock *>                       visited;        //the basic blocks we've already visited
52         map<BasicBlock *, vector<PHINode *> >   new_phinodes;   //the phinodes we're adding
53
54
55         void traverse(BasicBlock *f, BasicBlock * predecessor);
56         bool PromoteFunction(Function *F, DominanceFrontier &DF);
57         bool queuePhiNode(BasicBlock *bb, int alloca_index);
58         void findSafeAllocas(Function *M);
59         bool didchange;
60         public:
61         // I do this so that I can force the deconstruction of the local variables
62         PromoteInstance(Function *F, DominanceFrontier &DF)
63         {
64                 didchange=PromoteFunction(F, DF);
65         }
66         //This returns whether the pass changes anything
67         operator bool () { return didchange; }
68 };
69
70 }  // end of anonymous namespace
71
72 // findSafeAllocas - Find allocas that are safe to promote
73 //
74 void PromoteInstance::findSafeAllocas(Function *F)  
75 {
76   BasicBlock *BB = F->getEntryNode();  // Get the entry node for the function
77
78   // Look at all instructions in the entry node
79   for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
80     if (AllocaInst *AI = dyn_cast<AllocaInst>(*I))       // Is it an alloca?
81       if (!AI->isArrayAllocation()) {
82         bool isSafe = true;
83         for (Value::use_iterator UI = AI->use_begin(), UE = AI->use_end();
84              UI != UE; ++UI) {   // Loop over all of the uses of the alloca
85
86           // Only allow nonindexed memory access instructions...
87           if (MemAccessInst *MAI = dyn_cast<MemAccessInst>(*UI)) {
88             if (MAI->hasIndices()) {  // indexed?
89               // Allow the access if there is only one index and the index is zero.
90               if (*MAI->idx_begin() != ConstantUInt::get(Type::UIntTy, 0) ||
91                   MAI->idx_begin()+1 != MAI->idx_end()) {
92                 isSafe = false; break;
93               }
94             }
95           } else {
96             isSafe = false; break;   // Not a load or store?
97           }
98         }
99         if (isSafe)              // If all checks pass, add alloca to safe list
100           {
101             AllocaLookup[AI]=Allocas.size();
102             Allocas.push_back(AI);
103           }
104       }
105 }
106
107
108
109 bool PromoteInstance::PromoteFunction(Function *F, DominanceFrontier & DF) {
110         // Calculate the set of safe allocas
111         findSafeAllocas(F);
112
113         // Add each alloca to the killlist
114         // note: killlist is destroyed MOST recently added to least recently.
115         killlist.assign(Allocas.begin(), Allocas.end());
116
117         // Calculate the set of write-locations for each alloca.
118         // this is analogous to counting the number of 'redefinitions' of each variable.
119         for (unsigned i = 0; i<Allocas.size(); ++i)
120         {
121                 AllocaInst * AI = Allocas[i];
122                 WriteSets.push_back(std::vector<BasicBlock *>()); //add a new set
123                 for (Value::use_iterator U = AI->use_begin();U!=AI->use_end();++U)
124                 {
125                         if (MemAccessInst *MAI = dyn_cast<StoreInst>(*U)) {
126                                 WriteSets[i].push_back(MAI->getParent()); // jot down the basic-block it came from
127                         }
128                 }
129         }
130
131         // Compute the locations where PhiNodes need to be inserted
132         // look at the dominance frontier of EACH basic-block we have a write in
133         PhiNodes.resize(Allocas.size());
134         for (unsigned i = 0; i<Allocas.size(); ++i)
135         {
136                 for (unsigned j = 0; j<WriteSets[i].size(); j++)
137                 {
138                         //look up the DF for this write, add it to PhiNodes
139                         DominanceFrontier::const_iterator it = DF.find(WriteSets[i][j]);
140                         DominanceFrontier::DomSetType     s = (*it).second;
141                         for (DominanceFrontier::DomSetType::iterator p = s.begin();p!=s.end(); ++p)
142                         {
143                                 if (queuePhiNode((BasicBlock *)*p, i))
144                                 PhiNodes[i].push_back((BasicBlock *)*p);
145                         }
146                 }
147                 // perform iterative step
148                 for (unsigned k = 0; k<PhiNodes[i].size(); k++)
149                 {
150                         DominanceFrontier::const_iterator it = DF.find(PhiNodes[i][k]);
151                         DominanceFrontier::DomSetType     s = it->second;
152                         for (DominanceFrontier::DomSetType::iterator p = s.begin(); p!=s.end(); ++p)
153                         {
154                                 if (queuePhiNode((BasicBlock *)*p,i))
155                                 PhiNodes[i].push_back((BasicBlock*)*p);
156                         }
157                 }
158         }
159
160         // Walks all basic blocks in the function
161         // performing the SSA rename algorithm
162         // and inserting the phi nodes we marked as necessary
163         BasicBlock * f = F->front(); //get root basic-block
164
165         CurrentValue.push_back(vector<Value *>(Allocas.size()));
166
167         traverse(f, NULL);  // there is no predecessor of the root node
168
169
170         // ** REMOVE EVERYTHING IN THE KILL-LIST **
171         // we need to kill 'uses' before root values
172         // so we should probably run through in reverse
173         for (vector<Instruction *>::reverse_iterator i = killlist.rbegin(); i!=killlist.rend(); ++i)
174         {
175                 Instruction * r = *i;
176                 BasicBlock * o = r->getParent();
177                 //now go find..
178
179                 BasicBlock::InstListType & l = o->getInstList();
180                 o->getInstList().remove(r);
181                 delete r;
182         }
183
184         return !Allocas.empty();
185 }
186
187
188
189 void PromoteInstance::traverse(BasicBlock *f, BasicBlock * predecessor)
190 {
191         vector<Value *> * tos = &CurrentValue.back(); //look at top-
192
193         //if this is a BB needing a phi node, lookup/create the phinode for
194         // each variable we need phinodes for.
195         map<BasicBlock *, vector<PHINode *> >::iterator nd = new_phinodes.find(f);
196         if (nd!=new_phinodes.end())
197         {
198                 for (unsigned k = 0; k!=nd->second.size(); ++k)
199                 if (nd->second[k])
200                 {
201                         //at this point we can assume that the array has phi nodes.. let's
202                         // add the incoming data
203                         if ((*tos)[k])
204                         nd->second[k]->addIncoming((*tos)[k],predecessor);
205                         //also note that the active variable IS designated by the phi node
206                         (*tos)[k] = nd->second[k];
207                 }
208         }
209
210         //don't revisit nodes
211         if (visited.find(f)!=visited.end())
212         return;
213         //mark as visited
214         visited.insert(f);
215
216         BasicBlock::iterator i = f->begin();
217         //keep track of the value of each variable we're watching.. how?
218         while(i!=f->end())
219         {
220                 Instruction * inst = *i; //get the instruction
221                 //is this a write/read?
222                 if (LoadInst * LI = dyn_cast<LoadInst>(inst))
223                 {
224                         // This is a bit weird...
225                         Value * ptr = LI->getPointerOperand(); //of type value
226                         if (AllocaInst * srcinstr = dyn_cast<AllocaInst>(ptr))
227                         {
228                                 map<Instruction *, int>::iterator ai = AllocaLookup.find(srcinstr);
229                                 if (ai!=AllocaLookup.end())
230                                 {
231                                         if (Value *r = (*tos)[ai->second])
232                                         {
233                                                 //walk the use list of this load and replace
234                                                 // all uses with r
235                                                 LI->replaceAllUsesWith(r);
236                                                 //now delete the instruction.. somehow..
237                                                 killlist.push_back((Instruction *)LI);
238                                         }
239                                 }
240                         }
241                 }
242                 else if (StoreInst * SI = dyn_cast<StoreInst>(inst))
243                 {
244                         // delete this instruction and mark the name as the
245                         // current holder of the value
246                         Value * ptr =  SI->getPointerOperand(); //of type value
247                         if (Instruction * srcinstr = dyn_cast<Instruction>(ptr))
248                         {
249                                 map<Instruction *, int>::iterator ai = AllocaLookup.find(srcinstr);
250                                 if (ai!=AllocaLookup.end())
251                                 {
252                                         //what value were we writing?
253                                         Value * writeval = SI->getOperand(0);
254                                         //write down...
255                                         (*tos)[ai->second] = writeval;
256                                         //now delete it.. somehow?
257                                         killlist.push_back((Instruction *)SI);
258                                 }
259                         }
260
261                 }
262                 else if (TerminatorInst * TI = dyn_cast<TerminatorInst>(inst))
263                 {
264                         // Recurse across our sucessors
265                         for (unsigned i = 0; i!=TI->getNumSuccessors(); i++)
266                         {
267                                 CurrentValue.push_back(CurrentValue.back());
268                                 traverse(TI->getSuccessor(i),f); //this node IS the predecessor
269                                 CurrentValue.pop_back();
270                         }
271                 }
272                 i++;
273         }
274 }
275
276 // queues a phi-node to be added to a basic-block for a specific Alloca
277 // returns true  if there wasn't already a phi-node for that variable
278
279
280 bool PromoteInstance::queuePhiNode(BasicBlock *bb, int i /*the alloca*/)
281 {
282         map<BasicBlock *, vector<PHINode *> >::iterator nd;
283         //look up the basic-block in question
284         nd = new_phinodes.find(bb);
285         //if the basic-block has no phi-nodes added, or at least none
286         //for the i'th alloca. then add.
287         if (nd==new_phinodes.end() || nd->second[i]==NULL)
288         {
289                 //we're not added any phi nodes to this basicblock yet
290                 // create the phi-node array.
291                 if (nd==new_phinodes.end())
292                 {
293                         new_phinodes[bb] = vector<PHINode *>(Allocas.size());
294                         nd = new_phinodes.find(bb);
295                 }
296
297                 //find the type the alloca returns
298                 const PointerType * pt = Allocas[i]->getType();
299                 //create a phi-node using the DEREFERENCED type
300                 PHINode * ph = new PHINode(pt->getElementType(), Allocas[i]->getName()+".mem2reg");
301                 nd->second[i] = ph;
302                 //add the phi-node to the basic-block
303                 bb->getInstList().push_front(ph);
304                 return true;
305         }
306         return false;
307 }
308
309
310 namespace {
311   struct PromotePass : public MethodPass {
312
313     // runOnMethod - To run this pass, first we calculate the alloca
314     // instructions that are safe for promotion, then we promote each one.
315     //
316     virtual bool runOnMethod(Function *F) {
317       return (bool)PromoteInstance(F, getAnalysis<DominanceFrontier>());
318     }
319     
320
321     // getAnalysisUsageInfo - We need dominance frontiers
322     //
323     virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Requires,
324                                       Pass::AnalysisSet &Destroyed,
325                                       Pass::AnalysisSet &Provided) {
326       Requires.push_back(DominanceFrontier::ID);
327     }
328   };
329 }
330   
331
332 // createPromoteMemoryToRegister - Provide an entry point to create this pass.
333 //
334 Pass *createPromoteMemoryToRegister() {
335         return new PromotePass();
336 }
337
338