blob: 0ecf96cf13cad9ff7648f552ef2b2379b137d91f [file] [log] [blame]
Ruchira Sasanka9f181192001-07-24 17:14:13 +00001#include "llvm/Analysis/LiveVar/BBLiveVar.h"
Ruchira Sasanka11e97b02001-08-20 21:12:49 +00002#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
3#include "llvm/CodeGen/MachineInstr.h"
Chris Lattner7f74a562002-01-20 22:54:45 +00004
5/// BROKEN: Should not include sparc stuff directly into here
Ruchira Sasanka4552ee42001-12-08 21:05:27 +00006#include "../../Target/Sparc/SparcInternals.h" // Only for PHI defn
Ruchira Sasanka9f181192001-07-24 17:14:13 +00007
Chris Lattner7f74a562002-01-20 22:54:45 +00008using std::cerr;
9using std::endl;
10using std::pair;
Ruchira Sasanka9f181192001-07-24 17:14:13 +000011
Ruchira Sasanka4552ee42001-12-08 21:05:27 +000012//-----------------------------------------------------------------------------
13// Constructor
14//-----------------------------------------------------------------------------
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000015BBLiveVar::BBLiveVar( const BasicBlock *const baseBB, unsigned int RdfoId)
16 : BaseBB(baseBB), DefSet(), InSet(),
17 OutSet(), PhiArgMap() {
Ruchira Sasanka9f181192001-07-24 17:14:13 +000018 BaseBB = baseBB;
19 InSetChanged = OutSetChanged = false;
20 POId = RdfoId;
21}
22
Ruchira Sasanka4552ee42001-12-08 21:05:27 +000023
24//-----------------------------------------------------------------------------
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000025// caluculates def and use sets for each BB
26// There are two passes over operands of a machine instruction. This is
27// because, we can have instructions like V = V + 1, since we no longer
28// assume single definition.
Ruchira Sasanka4552ee42001-12-08 21:05:27 +000029//-----------------------------------------------------------------------------
Ruchira Sasanka9f181192001-07-24 17:14:13 +000030
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000031void BBLiveVar::calcDefUseSets()
Ruchira Sasanka9f181192001-07-24 17:14:13 +000032{
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000033 // get the iterator for machine instructions
34 const MachineCodeForBasicBlock& MIVec = BaseBB->getMachineInstrVec();
35 MachineCodeForBasicBlock::const_reverse_iterator
36 MInstIterator = MIVec.rbegin();
Ruchira Sasanka9f181192001-07-24 17:14:13 +000037
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000038 // iterate over all the machine instructions in BB
39 for( ; MInstIterator != MIVec.rend(); ++MInstIterator) {
Ruchira Sasanka9f181192001-07-24 17:14:13 +000040
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000041 const MachineInstr * MInst = *MInstIterator; // MInst is the machine inst
42 assert(MInst);
Ruchira Sasanka9f181192001-07-24 17:14:13 +000043
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000044 if( DEBUG_LV > 1) { // debug msg
Chris Lattner24872c82001-10-15 18:30:06 +000045 cerr << " *Iterating over machine instr ";
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000046 MInst->dump();
Chris Lattner7f74a562002-01-20 22:54:45 +000047 cerr << "\n";
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000048 }
49
50 // iterate over MI operands to find defs
Chris Lattner2413b162001-12-04 00:03:30 +000051 for( MachineInstr::val_const_op_iterator OpI(MInst); !OpI.done() ; ++OpI) {
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000052
Ruchira Sasanka04009ef2001-10-12 17:47:23 +000053 if( OpI.isDef() ) // add to Defs only if this operand is a def
54 addDef( *OpI );
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000055 }
56
Ruchira Sasanka04009ef2001-10-12 17:47:23 +000057 // do for implicit operands as well
58 for( unsigned i=0; i < MInst->getNumImplicitRefs(); ++i) {
59 if( MInst->implicitRefIsDefined(i) )
60 addDef( MInst->getImplicitRef(i) );
61 }
62
63
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000064 bool IsPhi = ( MInst->getOpCode() == PHI );
65
66
67 // iterate over MI operands to find uses
Ruchira Sasanka4552ee42001-12-08 21:05:27 +000068 for (MachineInstr::val_const_op_iterator OpI(MInst); !OpI.done() ; ++OpI) {
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000069 const Value *Op = *OpI;
70
71 if ( ((Op)->getType())->isLabelType() )
72 continue; // don't process labels
73
Ruchira Sasanka04009ef2001-10-12 17:47:23 +000074 if(! OpI.isDef() ) { // add to Defs only if this operand is a use
75 addUse( Op );
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000076
77 if( IsPhi ) { // for a phi node
Ruchira Sasanka04009ef2001-10-12 17:47:23 +000078 // put args into the PhiArgMap (Val -> BB)
79
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000080 const Value * ArgVal = Op;
81 ++OpI; // increment to point to BB of value
82 const Value * BBVal = *OpI;
Ruchira Sasanka04009ef2001-10-12 17:47:23 +000083
84
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000085 assert( (BBVal)->getValueType() == Value::BasicBlockVal );
86
87 PhiArgMap[ ArgVal ] = (const BasicBlock *) (BBVal);
88 assert( PhiArgMap[ ArgVal ] );
Ruchira Sasanka04009ef2001-10-12 17:47:23 +000089
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000090 if( DEBUG_LV > 1) { // debug msg of level 2
Chris Lattner24872c82001-10-15 18:30:06 +000091 cerr << " - phi operand ";
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000092 printValue( ArgVal );
Chris Lattner7f74a562002-01-20 22:54:45 +000093 cerr << " came from BB ";
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000094 printValue( PhiArgMap[ ArgVal ]);
Chris Lattner7f74a562002-01-20 22:54:45 +000095 cerr << "\n";
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000096 }
97
Ruchira Sasanka04009ef2001-10-12 17:47:23 +000098 } // if( IsPhi )
Ruchira Sasanka11e97b02001-08-20 21:12:49 +000099
Ruchira Sasanka04009ef2001-10-12 17:47:23 +0000100 } // if a use
101
102 } // for all operands
103
104 // do for implicit operands as well
105 for( unsigned i=0; i < MInst->getNumImplicitRefs(); ++i) {
106
107 assert( !IsPhi && "Phi cannot have implicit opeands");
108 const Value *Op = MInst->getImplicitRef(i);
109
110 if ( ((Op)->getType())->isLabelType() )
111 continue; // don't process labels
112 if( ! MInst->implicitRefIsDefined(i) )
113 addUse( Op );
114 }
Ruchira Sasanka11e97b02001-08-20 21:12:49 +0000115
116 } // for all machine instructions
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000117}
Ruchira Sasanka4552ee42001-12-08 21:05:27 +0000118
119
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000120
Ruchira Sasanka4552ee42001-12-08 21:05:27 +0000121//-----------------------------------------------------------------------------
122// To add an operand which is a def
123//-----------------------------------------------------------------------------
Ruchira Sasanka04009ef2001-10-12 17:47:23 +0000124void BBLiveVar::addDef(const Value *Op)
125{
126 DefSet.add( Op ); // operand is a def - so add to def set
127 InSet.remove( Op); // this definition kills any uses
128 InSetChanged = true;
129
130 if( DEBUG_LV > 1) {
Chris Lattner7f74a562002-01-20 22:54:45 +0000131 cerr << " +Def: "; printValue( Op ); cerr << "\n";
Ruchira Sasanka04009ef2001-10-12 17:47:23 +0000132 }
133}
134
Ruchira Sasanka04009ef2001-10-12 17:47:23 +0000135
Ruchira Sasanka4552ee42001-12-08 21:05:27 +0000136//-----------------------------------------------------------------------------
137// To add an operand which is a use
138//-----------------------------------------------------------------------------
Ruchira Sasanka04009ef2001-10-12 17:47:23 +0000139void BBLiveVar::addUse(const Value *Op)
140{
141 InSet.add( Op ); // An operand is a use - so add to use set
142 OutSet.remove( Op ); // remove if there is a def below this use
143 InSetChanged = true;
144
145 if( DEBUG_LV > 1) { // debug msg of level 2
Chris Lattner24872c82001-10-15 18:30:06 +0000146 cerr << " Use: "; printValue( Op ); cerr << endl;
Ruchira Sasanka04009ef2001-10-12 17:47:23 +0000147 }
148
149}
150
151
Ruchira Sasanka4552ee42001-12-08 21:05:27 +0000152//-----------------------------------------------------------------------------
153// Applies the transfer function to a basic block to produce the InSet using
154// the outset.
155//-----------------------------------------------------------------------------
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000156
157bool BBLiveVar::applyTransferFunc() // calculates the InSet in terms of OutSet
158{
159
160 // IMPORTANT: caller should check whether the OutSet changed
161 // (else no point in calling)
162
Ruchira Sasanka11e97b02001-08-20 21:12:49 +0000163 LiveVarSet OutMinusDef; // set to hold (Out[B] - Def[B])
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000164 OutMinusDef.setDifference( &OutSet, &DefSet);
165 InSetChanged = InSet.setUnion( &OutMinusDef );
166
Ruchira Sasanka11e97b02001-08-20 21:12:49 +0000167 OutSetChanged = false; // no change to OutSet since transf func applied
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000168
169 return InSetChanged;
170}
171
172
Ruchira Sasanka4552ee42001-12-08 21:05:27 +0000173//-----------------------------------------------------------------------------
Ruchira Sasanka11e97b02001-08-20 21:12:49 +0000174// calculates Out set using In sets of the predecessors
Ruchira Sasanka4552ee42001-12-08 21:05:27 +0000175//-----------------------------------------------------------------------------
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000176bool BBLiveVar::setPropagate( LiveVarSet *const OutSet,
177 const LiveVarSet *const InSet,
178 const BasicBlock *const PredBB) {
179
180 LiveVarSet::const_iterator InIt;
181 pair<LiveVarSet::iterator, bool> result;
182 bool changed = false;
183 const BasicBlock *PredBBOfPhiArg;
184
Ruchira Sasanka11e97b02001-08-20 21:12:49 +0000185 // for all all elements in InSet
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000186 for( InIt = InSet->begin() ; InIt != InSet->end(); InIt++) {
187 PredBBOfPhiArg = PhiArgMap[ *InIt ];
188
Ruchira Sasanka11e97b02001-08-20 21:12:49 +0000189 // if this var is not a phi arg OR
190 // it's a phi arg and the var went down from this BB
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000191 if( !PredBBOfPhiArg || PredBBOfPhiArg == PredBB) {
192 result = OutSet->insert( *InIt ); // insert to this set
193 if( result.second == true) changed = true;
194 }
195 }
196
197 return changed;
198}
199
200
Ruchira Sasanka4552ee42001-12-08 21:05:27 +0000201//-----------------------------------------------------------------------------
Ruchira Sasanka11e97b02001-08-20 21:12:49 +0000202// propogates in set to OutSets of PREDECESSORs
Ruchira Sasanka4552ee42001-12-08 21:05:27 +0000203//-----------------------------------------------------------------------------
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000204bool BBLiveVar::applyFlowFunc(BBToBBLiveVarMapType LVMap)
205{
206
207 // IMPORTANT: caller should check whether inset changed
208 // (else no point in calling)
209
210 bool needAnotherIt= false; // did this BB change any OutSets of pred.s
211 // whose POId is lower
212
213
Chris Lattnerba1c1f22001-10-01 13:19:53 +0000214 BasicBlock::pred_const_iterator PredBBI = BaseBB->pred_begin();
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000215
Chris Lattnerba1c1f22001-10-01 13:19:53 +0000216 for( ; PredBBI != BaseBB->pred_end() ; PredBBI++) {
Ruchira Sasanka11e97b02001-08-20 21:12:49 +0000217 assert( *PredBBI ); // assert that the predecessor is valid
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000218 BBLiveVar *PredLVBB = LVMap[*PredBBI];
219
Ruchira Sasanka11e97b02001-08-20 21:12:49 +0000220 // do set union
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000221 if( setPropagate( &(PredLVBB->OutSet), &InSet, *PredBBI ) == true) {
222 PredLVBB->OutSetChanged = true;
223
Ruchira Sasanka11e97b02001-08-20 21:12:49 +0000224 // if the predec POId is lower than mine
225 if( PredLVBB->getPOId() <= POId)
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000226 needAnotherIt = true;
227 }
Ruchira Sasanka11e97b02001-08-20 21:12:49 +0000228
229 } // for
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000230
231 return needAnotherIt;
232
233}
234
235
236
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000237/* ----------------- Methods For Debugging (Printing) ----------------- */
238
239void BBLiveVar::printAllSets() const
240{
Chris Lattner24872c82001-10-15 18:30:06 +0000241 cerr << " Defs: "; DefSet.printSet(); cerr << endl;
242 cerr << " In: "; InSet.printSet(); cerr << endl;
243 cerr << " Out: "; OutSet.printSet(); cerr << endl;
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000244}
245
246void BBLiveVar::printInOutSets() const
247{
Chris Lattner24872c82001-10-15 18:30:06 +0000248 cerr << " In: "; InSet.printSet(); cerr << endl;
249 cerr << " Out: "; OutSet.printSet(); cerr << endl;
Ruchira Sasanka9f181192001-07-24 17:14:13 +0000250}
Ruchira Sasanka11e97b02001-08-20 21:12:49 +0000251
252
253
254