MachineInstr::getOpCode() --> getOpcode() in SPARC back-end.
[oota-llvm.git] / lib / Target / SparcV9 / LiveVar / BBLiveVar.cpp
1 //===-- BBLiveVar.cpp - Live Variable Analysis for a BasicBlock -----------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This is a wrapper class for BasicBlock which is used by live var analysis.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "BBLiveVar.h"
15 #include "llvm/CodeGen/FunctionLiveVarInfo.h"
16 #include "llvm/CodeGen/MachineInstr.h"
17 #include "llvm/CodeGen/MachineBasicBlock.h"
18 #include "llvm/Support/CFG.h"
19 #include "Support/SetOperations.h"
20 #include "../SparcInternals.h"
21
22 namespace llvm {
23
24 BBLiveVar::BBLiveVar(const BasicBlock &bb,
25                      const MachineBasicBlock &mbb,
26                      unsigned id)
27   : BB(bb), MBB(mbb), POID(id) {
28   InSetChanged = OutSetChanged = false;
29
30   calcDefUseSets();
31 }
32
33 //-----------------------------------------------------------------------------
34 // calculates def and use sets for each BB
35 // There are two passes over operands of a machine instruction. This is
36 // because, we can have instructions like V = V + 1, since we no longer
37 // assume single definition.
38 //-----------------------------------------------------------------------------
39
40 void BBLiveVar::calcDefUseSets() {
41   // iterate over all the machine instructions in BB
42   for (MachineBasicBlock::const_reverse_iterator MII = MBB.rbegin(),
43          MIE = MBB.rend(); MII != MIE; ++MII) {
44     const MachineInstr *MI = *MII;
45     
46     if (DEBUG_LV >= LV_DEBUG_Verbose) {
47       std::cerr << " *Iterating over machine instr ";
48       MI->dump();
49       std::cerr << "\n";
50     }
51
52     // iterate over  MI operands to find defs
53     for (MachineInstr::const_val_op_iterator OpI = MI->begin(), OpE = MI->end();
54          OpI != OpE; ++OpI)
55       if (OpI.isDef()) // add to Defs if this operand is a def
56         addDef(*OpI);
57
58     // do for implicit operands as well
59     for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i)
60       if (MI->getImplicitOp(i).isDef())
61         addDef(MI->getImplicitRef(i));
62     
63     // iterate over MI operands to find uses
64     for (MachineInstr::const_val_op_iterator OpI = MI->begin(), OpE = MI->end();
65          OpI != OpE; ++OpI) {
66       const Value *Op = *OpI;
67
68       if (isa<BasicBlock>(Op))
69         continue;             // don't process labels
70
71       if (OpI.isUse()) { // add to Uses only if this operand is a use
72         //
73         // *** WARNING: The following code for handling dummy PHI machine
74         //     instructions is untested.  The previous code was broken and I
75         //     fixed it, but it turned out to be unused as long as Phi
76         //     elimination is performed during instruction selection.
77         // 
78         // Put Phi operands in UseSet for the incoming edge, not node.
79         // They must not "hide" later defs, and must be handled specially
80         // during set propagation over the CFG.
81         if (MI->getOpcode() == V9::PHI) {         // for a phi node
82           const Value *ArgVal = Op;
83           const BasicBlock *PredBB = cast<BasicBlock>(*++OpI); // next ptr is BB
84           
85           PredToEdgeInSetMap[PredBB].insert(ArgVal); 
86           
87           if (DEBUG_LV >= LV_DEBUG_Verbose)
88             std::cerr << "   - phi operand " << RAV(ArgVal) << " came from BB "
89                       << RAV(PredBB) << "\n";
90         } // if( IsPhi )
91         else {
92           // It is not a Phi use: add to regular use set and remove later defs.
93           addUse(Op);
94         }
95       } // if a use
96     } // for all operands
97
98     // do for implicit operands as well
99     for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i) {
100       assert(MI->getOpcode() != V9::PHI && "Phi cannot have implicit operands");
101       const Value *Op = MI->getImplicitRef(i);
102
103       if (Op->getType() == Type::LabelTy)             // don't process labels
104         continue;
105
106       if (MI->getImplicitOp(i).isUse())
107         addUse(Op);
108     }
109   } // for all machine instructions
110
111
112
113         
114 //-----------------------------------------------------------------------------
115 // To add an operand which is a def
116 //-----------------------------------------------------------------------------
117 void BBLiveVar::addDef(const Value *Op) {
118   DefSet.insert(Op);     // operand is a def - so add to def set
119   InSet.erase(Op);       // this definition kills any later uses
120   InSetChanged = true; 
121
122   if (DEBUG_LV >= LV_DEBUG_Verbose) std::cerr << "  +Def: " << RAV(Op) << "\n";
123 }
124
125
126 //-----------------------------------------------------------------------------
127 // To add an operand which is a use
128 //-----------------------------------------------------------------------------
129 void  BBLiveVar::addUse(const Value *Op) {
130   InSet.insert(Op);   // An operand is a use - so add to use set
131   DefSet.erase(Op);   // remove if there is a def below this use
132   InSetChanged = true; 
133
134   if (DEBUG_LV >= LV_DEBUG_Verbose) std::cerr << "   Use: " << RAV(Op) << "\n";
135 }
136
137
138 //-----------------------------------------------------------------------------
139 // Applies the transfer function to a basic block to produce the InSet using
140 // the OutSet. 
141 //-----------------------------------------------------------------------------
142
143 bool BBLiveVar::applyTransferFunc() {
144   // IMPORTANT: caller should check whether the OutSet changed 
145   //           (else no point in calling)
146
147   ValueSet OutMinusDef = set_difference(OutSet, DefSet);
148   InSetChanged = set_union(InSet, OutMinusDef);
149  
150   OutSetChanged = false;      // no change to OutSet since transf func applied
151   return InSetChanged;
152 }
153
154
155 //-----------------------------------------------------------------------------
156 // calculates Out set using In sets of the successors
157 //-----------------------------------------------------------------------------
158
159 bool BBLiveVar::setPropagate(ValueSet *OutSet, const ValueSet *InSet, 
160                              const BasicBlock *PredBB) {
161   bool Changed = false;
162   
163   // merge all members of InSet into OutSet of the predecessor
164   for (ValueSet::const_iterator InIt = InSet->begin(), InE = InSet->end();
165        InIt != InE; ++InIt)
166     if ((OutSet->insert(*InIt)).second)
167       Changed = true;
168   
169   // 
170   //**** WARNING: The following code for handling dummy PHI machine
171   //     instructions is untested.  See explanation above.
172   // 
173   // then merge all members of the EdgeInSet for the predecessor into the OutSet
174   const ValueSet& EdgeInSet = PredToEdgeInSetMap[PredBB];
175   for (ValueSet::const_iterator InIt = EdgeInSet.begin(), InE = EdgeInSet.end();
176        InIt != InE; ++InIt)
177     if ((OutSet->insert(*InIt)).second)
178       Changed = true;
179   // 
180   //****
181   
182   return Changed;
183
184
185
186 //-----------------------------------------------------------------------------
187 // propagates in set to OutSets of PREDECESSORs
188 //-----------------------------------------------------------------------------
189
190 bool BBLiveVar::applyFlowFunc(hash_map<const BasicBlock*,
191                                        BBLiveVar*> &BBLiveVarInfo) {
192   // IMPORTANT: caller should check whether inset changed 
193   //            (else no point in calling)
194   
195   // If this BB changed any OutSets of preds whose POID is lower, than we need
196   // another iteration...
197   //
198   bool needAnotherIt = false;  
199
200   for (pred_const_iterator PI = pred_begin(&BB), PE = pred_end(&BB);
201        PI != PE ; ++PI) {
202     BBLiveVar *PredLVBB = BBLiveVarInfo[*PI];
203
204     // do set union
205     if (setPropagate(&PredLVBB->OutSet, &InSet, *PI)) {  
206       PredLVBB->OutSetChanged = true;
207
208       // if the predec POID is lower than mine
209       if (PredLVBB->getPOId() <= POID)
210         needAnotherIt = true;   
211     }
212   }  // for
213
214   return needAnotherIt;
215 }
216
217
218
219 // ----------------- Methods For Debugging (Printing) -----------------
220
221 void BBLiveVar::printAllSets() const {
222   std::cerr << "  Defs: "; printSet(DefSet);  std::cerr << "\n";
223   std::cerr << "  In: ";  printSet(InSet);  std::cerr << "\n";
224   std::cerr << "  Out: "; printSet(OutSet);  std::cerr << "\n";
225 }
226
227 void BBLiveVar::printInOutSets() const {
228   std::cerr << "  In: ";   printSet(InSet);  std::cerr << "\n";
229   std::cerr << "  Out: ";  printSet(OutSet);  std::cerr << "\n";
230 }
231
232 } // End llvm namespace