* Give BBLiveVar.cpp a proper file header
[oota-llvm.git] / lib / Target / SparcV9 / LiveVar / BBLiveVar.cpp
1 //===-- BBLiveVar.cpp - Live Variable Analysis for a BasicBlock -----------===//
2 //
3 // This is a wrapper class for BasicBlock which is used by live var analysis.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "llvm/Analysis/LiveVar/BBLiveVar.h"
8 #include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
9 #include "llvm/CodeGen/MachineInstr.h"
10 #include "llvm/BasicBlock.h"
11
12 /// BROKEN: Should not include sparc stuff directly into here
13 #include "../../Target/Sparc/SparcInternals.h"  //  Only for PHI defn
14
15 using std::cerr;
16
17 BBLiveVar::BBLiveVar(const BasicBlock *bb, unsigned id)
18   : BB(bb), POID(id) {
19   InSetChanged = OutSetChanged = false;
20 }
21
22 //-----------------------------------------------------------------------------
23 // calculates def and use sets for each BB
24 // There are two passes over operands of a machine instruction. This is
25 // because, we can have instructions like V = V + 1, since we no longer
26 // assume single definition.
27 //-----------------------------------------------------------------------------
28
29 void BBLiveVar::calcDefUseSets() {
30   // get the iterator for machine instructions
31   const MachineCodeForBasicBlock &MIVec = BB->getMachineInstrVec();
32
33   // iterate over all the machine instructions in BB
34   for (MachineCodeForBasicBlock::const_reverse_iterator MII = MIVec.rbegin(),
35          MIE = MIVec.rend(); MII != MIE; ++MII) {
36     const MachineInstr *MI = *MII;
37     
38     if (DEBUG_LV > 1) {                            // debug msg
39       cerr << " *Iterating over machine instr ";
40       MI->dump();
41       cerr << "\n";
42     }
43
44     // iterate over  MI operands to find defs
45     for (MachineInstr::val_const_op_iterator OpI(MI); !OpI.done(); ++OpI)
46       if (OpI.isDef())      // add to Defs only if this operand is a def
47         addDef(*OpI);
48
49     // do for implicit operands as well
50     for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i)
51       if (MI->implicitRefIsDefined(i))
52         addDef(MI->getImplicitRef(i));
53     
54     bool IsPhi = MI->getOpCode() == PHI;
55  
56     // iterate over MI operands to find uses
57     for (MachineInstr::val_const_op_iterator OpI(MI); !OpI.done(); ++OpI) {
58       const Value *Op = *OpI;
59
60       if (Op->getType()->isLabelType())    
61         continue;             // don't process labels
62
63       if (!OpI.isDef()) {   // add to Defs only if this operand is a use
64         addUse(Op);
65
66         if (IsPhi) {         // for a phi node
67           // put args into the PhiArgMap (Val -> BB)
68           const Value *ArgVal = Op;
69           const Value *BBVal = *++OpI; // increment to point to BB of value
70           
71           PhiArgMap[ArgVal] = cast<BasicBlock>(BBVal); 
72           
73           if (DEBUG_LV > 1) {
74             cerr << "   - phi operand "; 
75             printValue(ArgVal); 
76             cerr << " came from BB "; 
77             printValue(PhiArgMap[ArgVal]); 
78             cerr << "\n";
79           }
80         } // if( IsPhi )
81       } // if a use
82     } // for all operands
83
84     // do for implicit operands as well
85     for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i) {
86       assert(!IsPhi && "Phi cannot have implicit opeands");
87       const Value *Op = MI->getImplicitRef(i);
88
89       if (Op->getType()->isLabelType())             // don't process labels
90         continue;
91
92       if (!MI->implicitRefIsDefined(i))
93         addUse(Op);
94     }
95   } // for all machine instructions
96
97
98
99         
100 //-----------------------------------------------------------------------------
101 // To add an operand which is a def
102 //-----------------------------------------------------------------------------
103 void  BBLiveVar::addDef(const Value *Op) {
104   DefSet.insert(Op);     // operand is a def - so add to def set
105   InSet.erase(Op);       // this definition kills any uses
106   InSetChanged = true; 
107
108   if (DEBUG_LV > 1) {
109     cerr << "  +Def: "; printValue( Op ); cerr << "\n";
110   }
111 }
112
113
114 //-----------------------------------------------------------------------------
115 // To add an operand which is a use
116 //-----------------------------------------------------------------------------
117 void  BBLiveVar::addUse(const Value *Op) {
118   InSet.insert(Op);   // An operand is a use - so add to use set
119   OutSet.erase(Op);   // remove if there is a def below this use
120   InSetChanged = true; 
121
122   if (DEBUG_LV > 1) {
123     cerr << "   Use: "; printValue( Op ); cerr << "\n";
124   }
125 }
126
127
128 //-----------------------------------------------------------------------------
129 // Applies the transfer function to a basic block to produce the InSet using
130 // the outset. 
131 //-----------------------------------------------------------------------------
132
133 bool BBLiveVar::applyTransferFunc() {
134   // IMPORTANT: caller should check whether the OutSet changed 
135   //           (else no point in calling)
136
137   LiveVarSet OutMinusDef;     // set to hold (Out[B] - Def[B])
138   OutMinusDef.setDifference(&OutSet, &DefSet);
139   InSetChanged = InSet.setUnion(&OutMinusDef);
140  
141   OutSetChanged = false;      // no change to OutSet since transf func applied
142   return InSetChanged;
143 }
144
145
146 //-----------------------------------------------------------------------------
147 // calculates Out set using In sets of the predecessors
148 //-----------------------------------------------------------------------------
149
150 bool BBLiveVar::setPropagate(LiveVarSet *OutSet, const LiveVarSet *InSet, 
151                              const BasicBlock *PredBB) {
152   bool Changed = false;
153
154   // for all all elements in InSet
155   for (LiveVarSet::const_iterator InIt = InSet->begin(), InE = InSet->end();
156        InIt != InE; ++InIt) {  
157     const BasicBlock *PredBBOfPhiArg = PhiArgMap[*InIt];
158
159     // if this var is not a phi arg OR 
160     // it's a phi arg and the var went down from this BB
161     if (!PredBBOfPhiArg || PredBBOfPhiArg == PredBB)
162       if (OutSet->insert(*InIt).second)
163         Changed = true;
164   }
165
166   return Changed;
167
168
169
170 //-----------------------------------------------------------------------------
171 // propogates in set to OutSets of PREDECESSORs
172 //-----------------------------------------------------------------------------
173
174 bool BBLiveVar::applyFlowFunc(std::map<const BasicBlock *, BBLiveVar *> &LVMap){
175   // IMPORTANT: caller should check whether inset changed 
176   //            (else no point in calling)
177
178   // If this BB changed any OutSets of preds whose POID is lower, than we need
179   // another iteration...
180   //
181   bool needAnotherIt = false;  
182
183   for (BasicBlock::pred_const_iterator PI = BB->pred_begin(),
184          PE = BB->pred_begin(); PI != PE ; ++PI) {
185     BBLiveVar *PredLVBB = LVMap[*PI];
186
187     // do set union
188     if (setPropagate(&PredLVBB->OutSet, &InSet, *PI)) {  
189       PredLVBB->OutSetChanged = true;
190
191       // if the predec POID is lower than mine
192       if (PredLVBB->getPOId() <= POID)
193         needAnotherIt = true;   
194     }
195   }  // for
196
197   return needAnotherIt;
198 }
199
200
201
202 // ----------------- Methods For Debugging (Printing) -----------------
203
204 void BBLiveVar::printAllSets() const {
205   cerr << "  Defs: ";   DefSet.printSet();  cerr << "\n";
206   cerr << "  In: ";   InSet.printSet();  cerr << "\n";
207   cerr << "  Out: ";   OutSet.printSet();  cerr << "\n";
208 }
209
210 void BBLiveVar::printInOutSets() const {
211   cerr << "  In: ";   InSet.printSet();  cerr << "\n";
212   cerr << "  Out: ";  OutSet.printSet();  cerr << "\n";
213 }
214
215
216
217