More templatization.
[oota-llvm.git] / lib / CodeGen / StrongPHIElimination.cpp
1 //===- StrongPhiElimination.cpp - Eliminate PHI nodes by inserting copies -===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Owen Anderson and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This pass eliminates machine instruction PHI nodes by inserting copy
11 // instructions, using an intelligent copy-folding technique based on
12 // dominator information.  This is technique is derived from:
13 // 
14 //    Budimlic, et al. Fast copy coalescing and live-range identification.
15 //    In Proceedings of the ACM SIGPLAN 2002 Conference on Programming Language
16 //    Design and Implementation (Berlin, Germany, June 17 - 19, 2002).
17 //    PLDI '02. ACM, New York, NY, 25-32.
18 //    DOI= http://doi.acm.org/10.1145/512529.512534
19 //
20 //===----------------------------------------------------------------------===//
21
22 #define DEBUG_TYPE "strongphielim"
23 #include "llvm/CodeGen/Passes.h"
24 #include "llvm/CodeGen/BreakCriticalMachineEdge.h"
25 #include "llvm/CodeGen/LiveVariables.h"
26 #include "llvm/CodeGen/MachineDominators.h"
27 #include "llvm/CodeGen/MachineFunctionPass.h"
28 #include "llvm/CodeGen/MachineInstr.h"
29 #include "llvm/CodeGen/SSARegMap.h"
30 #include "llvm/Target/TargetInstrInfo.h"
31 #include "llvm/Target/TargetMachine.h"
32 #include "llvm/ADT/Statistic.h"
33 #include "llvm/Support/Compiler.h"
34 using namespace llvm;
35
36
37 namespace {
38   struct VISIBILITY_HIDDEN StrongPHIElimination : public MachineFunctionPass {
39     static char ID; // Pass identification, replacement for typeid
40     StrongPHIElimination() : MachineFunctionPass((intptr_t)&ID) {}
41
42     bool runOnMachineFunction(MachineFunction &Fn);
43     
44     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
45       AU.addPreserved<LiveVariables>();
46       AU.addPreservedID(PHIEliminationID);
47       AU.addRequired<MachineDominatorTree>();
48       AU.addRequired<LiveVariables>();
49       AU.setPreservesAll();
50       MachineFunctionPass::getAnalysisUsage(AU);
51     }
52     
53     virtual void releaseMemory() {
54       preorder.clear();
55       maxpreorder.clear();
56       
57       waiting.clear();
58     }
59
60   private:
61     struct DomForestNode {
62     private:
63       std::vector<DomForestNode*> children;
64       unsigned reg;
65       
66       void addChild(DomForestNode* DFN) { children.push_back(DFN); }
67       
68     public:
69       typedef std::vector<DomForestNode*>::iterator iterator;
70       
71       DomForestNode(unsigned r, DomForestNode* parent) : reg(r) {
72         if (parent)
73           parent->addChild(this);
74       }
75       
76       ~DomForestNode() {
77         for (iterator I = begin(), E = end(); I != E; ++I)
78           delete *I;
79       }
80       
81       inline unsigned getReg() { return reg; }
82       
83       inline DomForestNode::iterator begin() { return children.begin(); }
84       inline DomForestNode::iterator end() { return children.end(); }
85     };
86     
87     DenseMap<MachineBasicBlock*, unsigned> preorder;
88     DenseMap<MachineBasicBlock*, unsigned> maxpreorder;
89     
90     DenseMap<MachineBasicBlock*, std::vector<MachineInstr*> > waiting;
91     
92     
93     void computeDFS(MachineFunction& MF);
94     void processBlock(MachineBasicBlock* MBB);
95     
96     std::vector<DomForestNode*> computeDomForest(std::set<unsigned>& instrs);
97     void breakCriticalEdges(MachineFunction &Fn);
98     
99   };
100
101   char StrongPHIElimination::ID = 0;
102   RegisterPass<StrongPHIElimination> X("strong-phi-node-elimination",
103                   "Eliminate PHI nodes for register allocation, intelligently");
104 }
105
106 const PassInfo *llvm::StrongPHIEliminationID = X.getPassInfo();
107
108 /// computeDFS - Computes the DFS-in and DFS-out numbers of the dominator tree
109 /// of the given MachineFunction.  These numbers are then used in other parts
110 /// of the PHI elimination process.
111 void StrongPHIElimination::computeDFS(MachineFunction& MF) {
112   SmallPtrSet<MachineDomTreeNode*, 8> frontier;
113   SmallPtrSet<MachineDomTreeNode*, 8> visited;
114   
115   unsigned time = 0;
116   
117   MachineDominatorTree& DT = getAnalysis<MachineDominatorTree>();
118   
119   MachineDomTreeNode* node = DT.getRootNode();
120   
121   std::vector<MachineDomTreeNode*> worklist;
122   worklist.push_back(node);
123   
124   while (!worklist.empty()) {
125     MachineDomTreeNode* currNode = worklist.back();
126     
127     if (!frontier.count(currNode)) {
128       frontier.insert(currNode);
129       ++time;
130       preorder.insert(std::make_pair(currNode->getBlock(), time));
131     }
132     
133     bool inserted = false;
134     for (MachineDomTreeNode::iterator I = node->begin(), E = node->end();
135          I != E; ++I)
136       if (!frontier.count(*I) && !visited.count(*I)) {
137         worklist.push_back(*I);
138         inserted = true;
139         break;
140       }
141     
142     if (!inserted) {
143       frontier.erase(currNode);
144       visited.insert(currNode);
145       maxpreorder.insert(std::make_pair(currNode->getBlock(), time));
146       
147       worklist.pop_back();
148     }
149   }
150 }
151
152 /// PreorderSorter - a helper class that is used to sort registers
153 /// according to the preorder number of their defining blocks
154 class PreorderSorter {
155 private:
156   DenseMap<MachineBasicBlock*, unsigned>& preorder;
157   LiveVariables& LV;
158   
159 public:
160   PreorderSorter(DenseMap<MachineBasicBlock*, unsigned>& p,
161                 LiveVariables& L) : preorder(p), LV(L) { }
162   
163   bool operator()(unsigned A, unsigned B) {
164     if (A == B)
165       return false;
166     
167     MachineBasicBlock* ABlock = LV.getVarInfo(A).DefInst->getParent();
168     MachineBasicBlock* BBlock = LV.getVarInfo(A).DefInst->getParent();
169     
170     if (preorder[ABlock] < preorder[BBlock])
171       return true;
172     else if (preorder[ABlock] > preorder[BBlock])
173       return false;
174     
175     assert(0 && "Error sorting by dominance!");
176     return false;
177   }
178 };
179
180 /// computeDomForest - compute the subforest of the DomTree corresponding
181 /// to the defining blocks of the registers in question
182 std::vector<StrongPHIElimination::DomForestNode*>
183 StrongPHIElimination::computeDomForest(std::set<unsigned>& regs) {
184   LiveVariables& LV = getAnalysis<LiveVariables>();
185   
186   DomForestNode* VirtualRoot = new DomForestNode(0, 0);
187   maxpreorder.insert(std::make_pair((MachineBasicBlock*)0, ~0UL));
188   
189   std::vector<unsigned> worklist;
190   worklist.reserve(regs.size());
191   for (std::set<unsigned>::iterator I = regs.begin(), E = regs.end();
192        I != E; ++I)
193     worklist.push_back(*I);
194   
195   PreorderSorter PS(preorder, LV);
196   std::sort(worklist.begin(), worklist.end(), PS);
197   
198   DomForestNode* CurrentParent = VirtualRoot;
199   std::vector<DomForestNode*> stack;
200   stack.push_back(VirtualRoot);
201   
202   for (std::vector<unsigned>::iterator I = worklist.begin(), E = worklist.end();
203        I != E; ++I) {
204     unsigned pre = preorder[LV.getVarInfo(*I).DefInst->getParent()];
205     MachineBasicBlock* parentBlock =
206       LV.getVarInfo(CurrentParent->getReg()).DefInst->getParent();
207     
208     while (pre > maxpreorder[parentBlock]) {
209       stack.pop_back();
210       CurrentParent = stack.back();
211       
212       parentBlock = LV.getVarInfo(CurrentParent->getReg()).DefInst->getParent();
213     }
214     
215     DomForestNode* child = new DomForestNode(*I, CurrentParent);
216     stack.push_back(child);
217     CurrentParent = child;
218   }
219   
220   std::vector<DomForestNode*> ret;
221   ret.insert(ret.end(), VirtualRoot->begin(), VirtualRoot->end());
222   return ret;
223 }
224
225 /// isLiveIn - helper method that determines, from a VarInfo, if a register
226 /// is live into a block
227 bool isLiveIn(LiveVariables::VarInfo& V, MachineBasicBlock* MBB) {
228   if (V.AliveBlocks.test(MBB->getNumber()))
229     return true;
230   
231   if (V.DefInst->getParent() != MBB &&
232       V.UsedBlocks.test(MBB->getNumber()))
233     return true;
234   
235   return false;
236 }
237
238 /// isLiveOut - help method that determines, from a VarInfo, if a register is
239 /// live out of a block.
240 bool isLiveOut(LiveVariables::VarInfo& V, MachineBasicBlock* MBB) {
241   if (MBB == V.DefInst->getParent() ||
242       V.UsedBlocks.test(MBB->getNumber())) {
243     for (std::vector<MachineInstr*>::iterator I = V.Kills.begin(), 
244          E = V.Kills.end(); I != E; ++I)
245       if ((*I)->getParent() == MBB)
246         return false;
247     
248     return true;
249   }
250   
251   return false;
252 }
253
254 /// processBlock - Eliminate PHIs in the given block
255 void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) {
256   LiveVariables& LV = getAnalysis<LiveVariables>();
257   
258   // Holds names that have been added to a set in any PHI within this block
259   // before the current one.
260   std::set<unsigned> ProcessedNames;
261   
262   MachineBasicBlock::iterator P = MBB->begin();
263   while (P->getOpcode() == TargetInstrInfo::PHI) {
264     LiveVariables::VarInfo& PHIInfo = LV.getVarInfo(P->getOperand(0).getReg());
265
266     // Hold the names that are currently in the candidate set.
267     std::set<unsigned> PHIUnion;
268     std::set<MachineBasicBlock*> UnionedBlocks;
269   
270     for (int i = P->getNumOperands() - 1; i >= 2; i-=2) {
271       unsigned SrcReg = P->getOperand(i-1).getReg();
272       LiveVariables::VarInfo& SrcInfo = LV.getVarInfo(SrcReg);
273     
274       if (isLiveIn(SrcInfo, P->getParent())) {
275         // add a copy from a_i to p in Waiting[From[a_i]]
276       } else if (isLiveOut(PHIInfo, SrcInfo.DefInst->getParent())) {
277         // add a copy to Waiting[From[a_i]]
278       } else if (PHIInfo.DefInst->getOpcode() == TargetInstrInfo::PHI &&
279                  isLiveIn(PHIInfo, SrcInfo.DefInst->getParent())) {
280         // add a copy to Waiting[From[a_i]]
281       } else if (ProcessedNames.count(SrcReg)) {
282         // add a copy to Waiting[From[a_i]]
283       } else if (UnionedBlocks.count(SrcInfo.DefInst->getParent())) {
284         // add a copy to Waiting[From[a_i]]
285       } else {
286         PHIUnion.insert(SrcReg);
287         UnionedBlocks.insert(SrcInfo.DefInst->getParent());
288       }
289     }
290     
291     std::vector<StrongPHIElimination::DomForestNode*> DF = 
292                                                      computeDomForest(PHIUnion);
293     
294     // DO STUFF HERE
295     
296     ProcessedNames.insert(PHIUnion.begin(), PHIUnion.end());
297     ++P;
298   }
299 }
300
301 /// breakCriticalEdges - Break critical edges coming into blocks with PHI
302 /// nodes, preserving dominator and livevariable info.
303 void StrongPHIElimination::breakCriticalEdges(MachineFunction &Fn) {
304   typedef std::pair<MachineBasicBlock*, MachineBasicBlock*> MBB_pair;
305   
306   MachineDominatorTree& MDT = getAnalysis<MachineDominatorTree>();
307   LiveVariables& LV = getAnalysis<LiveVariables>();
308   
309   // Find critical edges
310   std::vector<MBB_pair> criticals;
311   for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
312     if (!I->empty() &&
313         I->begin()->getOpcode() == TargetInstrInfo::PHI &&
314         I->pred_size() > 1)
315       for (MachineBasicBlock::pred_iterator PI = I->pred_begin(),
316            PE = I->pred_end(); PI != PE; ++PI)
317         if ((*PI)->succ_size() > 1)
318           criticals.push_back(std::make_pair(*PI, I));
319   
320   for (std::vector<MBB_pair>::iterator I = criticals.begin(),
321        E = criticals.end(); I != E; ++I) {
322     // Split the edge
323     MachineBasicBlock* new_bb = SplitCriticalMachineEdge(I->first, I->second);
324     
325     // Update dominators
326     MDT.splitBlock(I->first);
327     
328     // Update livevariables
329     for (unsigned var = 1024; var < Fn.getSSARegMap()->getLastVirtReg(); ++var)
330       if (isLiveOut(LV.getVarInfo(var), I->first))
331         LV.getVarInfo(var).AliveBlocks.set(new_bb->getNumber());
332   }
333 }
334
335 bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) {
336   breakCriticalEdges(Fn);
337   computeDFS(Fn);
338   
339   for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
340     if (!I->empty() &&
341         I->begin()->getOpcode() == TargetInstrInfo::PHI)
342       processBlock(I);
343   
344   return false;
345 }