blob: b1949945bae3725faa16aa12c3968dbf77ba3b68 [file] [log] [blame]
Ruchira Sasanka683847f2001-07-24 17:14:13 +00001#include "llvm/Analysis/LiveVar/BBLiveVar.h"
Ruchira Sasankae27c3442001-08-20 21:12:49 +00002#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
3#include "llvm/CodeGen/MachineInstr.h"
Chris Lattner11646322002-02-04 16:35:12 +00004#include "llvm/BasicBlock.h"
Chris Lattner697954c2002-01-20 22:54:45 +00005
6/// BROKEN: Should not include sparc stuff directly into here
Ruchira Sasanka789cebb2001-12-08 21:05:27 +00007#include "../../Target/Sparc/SparcInternals.h" // Only for PHI defn
Ruchira Sasanka683847f2001-07-24 17:14:13 +00008
Chris Lattner697954c2002-01-20 22:54:45 +00009using std::cerr;
10using std::endl;
11using std::pair;
Ruchira Sasanka683847f2001-07-24 17:14:13 +000012
Ruchira Sasanka789cebb2001-12-08 21:05:27 +000013//-----------------------------------------------------------------------------
14// Constructor
15//-----------------------------------------------------------------------------
Ruchira Sasankae27c3442001-08-20 21:12:49 +000016BBLiveVar::BBLiveVar( const BasicBlock *const baseBB, unsigned int RdfoId)
17 : BaseBB(baseBB), DefSet(), InSet(),
18 OutSet(), PhiArgMap() {
Ruchira Sasanka683847f2001-07-24 17:14:13 +000019 BaseBB = baseBB;
20 InSetChanged = OutSetChanged = false;
21 POId = RdfoId;
22}
23
Ruchira Sasanka789cebb2001-12-08 21:05:27 +000024
25//-----------------------------------------------------------------------------
Ruchira Sasankae27c3442001-08-20 21:12:49 +000026// caluculates def and use sets for each BB
27// There are two passes over operands of a machine instruction. This is
28// because, we can have instructions like V = V + 1, since we no longer
29// assume single definition.
Ruchira Sasanka789cebb2001-12-08 21:05:27 +000030//-----------------------------------------------------------------------------
Ruchira Sasanka683847f2001-07-24 17:14:13 +000031
Ruchira Sasankae27c3442001-08-20 21:12:49 +000032void BBLiveVar::calcDefUseSets()
Ruchira Sasanka683847f2001-07-24 17:14:13 +000033{
Ruchira Sasankae27c3442001-08-20 21:12:49 +000034 // get the iterator for machine instructions
35 const MachineCodeForBasicBlock& MIVec = BaseBB->getMachineInstrVec();
36 MachineCodeForBasicBlock::const_reverse_iterator
37 MInstIterator = MIVec.rbegin();
Ruchira Sasanka683847f2001-07-24 17:14:13 +000038
Ruchira Sasankae27c3442001-08-20 21:12:49 +000039 // iterate over all the machine instructions in BB
40 for( ; MInstIterator != MIVec.rend(); ++MInstIterator) {
Ruchira Sasanka683847f2001-07-24 17:14:13 +000041
Ruchira Sasankae27c3442001-08-20 21:12:49 +000042 const MachineInstr * MInst = *MInstIterator; // MInst is the machine inst
43 assert(MInst);
Ruchira Sasanka683847f2001-07-24 17:14:13 +000044
Ruchira Sasankae27c3442001-08-20 21:12:49 +000045 if( DEBUG_LV > 1) { // debug msg
Chris Lattner634b3522001-10-15 18:30:06 +000046 cerr << " *Iterating over machine instr ";
Ruchira Sasankae27c3442001-08-20 21:12:49 +000047 MInst->dump();
Chris Lattner697954c2002-01-20 22:54:45 +000048 cerr << "\n";
Ruchira Sasankae27c3442001-08-20 21:12:49 +000049 }
50
51 // iterate over MI operands to find defs
Chris Lattner7a176752001-12-04 00:03:30 +000052 for( MachineInstr::val_const_op_iterator OpI(MInst); !OpI.done() ; ++OpI) {
Ruchira Sasankae27c3442001-08-20 21:12:49 +000053
Ruchira Sasankac1daae82001-10-12 17:47:23 +000054 if( OpI.isDef() ) // add to Defs only if this operand is a def
55 addDef( *OpI );
Ruchira Sasankae27c3442001-08-20 21:12:49 +000056 }
57
Ruchira Sasankac1daae82001-10-12 17:47:23 +000058 // do for implicit operands as well
59 for( unsigned i=0; i < MInst->getNumImplicitRefs(); ++i) {
60 if( MInst->implicitRefIsDefined(i) )
61 addDef( MInst->getImplicitRef(i) );
62 }
63
64
Ruchira Sasankae27c3442001-08-20 21:12:49 +000065 bool IsPhi = ( MInst->getOpCode() == PHI );
66
67
68 // iterate over MI operands to find uses
Ruchira Sasanka789cebb2001-12-08 21:05:27 +000069 for (MachineInstr::val_const_op_iterator OpI(MInst); !OpI.done() ; ++OpI) {
Ruchira Sasankae27c3442001-08-20 21:12:49 +000070 const Value *Op = *OpI;
71
72 if ( ((Op)->getType())->isLabelType() )
73 continue; // don't process labels
74
Ruchira Sasankac1daae82001-10-12 17:47:23 +000075 if(! OpI.isDef() ) { // add to Defs only if this operand is a use
76 addUse( Op );
Ruchira Sasankae27c3442001-08-20 21:12:49 +000077
78 if( IsPhi ) { // for a phi node
Ruchira Sasankac1daae82001-10-12 17:47:23 +000079 // put args into the PhiArgMap (Val -> BB)
80
Ruchira Sasankae27c3442001-08-20 21:12:49 +000081 const Value * ArgVal = Op;
82 ++OpI; // increment to point to BB of value
83 const Value * BBVal = *OpI;
Ruchira Sasankac1daae82001-10-12 17:47:23 +000084
85
Ruchira Sasankae27c3442001-08-20 21:12:49 +000086 assert( (BBVal)->getValueType() == Value::BasicBlockVal );
87
88 PhiArgMap[ ArgVal ] = (const BasicBlock *) (BBVal);
89 assert( PhiArgMap[ ArgVal ] );
Ruchira Sasankac1daae82001-10-12 17:47:23 +000090
Ruchira Sasankae27c3442001-08-20 21:12:49 +000091 if( DEBUG_LV > 1) { // debug msg of level 2
Chris Lattner634b3522001-10-15 18:30:06 +000092 cerr << " - phi operand ";
Ruchira Sasankae27c3442001-08-20 21:12:49 +000093 printValue( ArgVal );
Chris Lattner697954c2002-01-20 22:54:45 +000094 cerr << " came from BB ";
Ruchira Sasankae27c3442001-08-20 21:12:49 +000095 printValue( PhiArgMap[ ArgVal ]);
Chris Lattner697954c2002-01-20 22:54:45 +000096 cerr << "\n";
Ruchira Sasankae27c3442001-08-20 21:12:49 +000097 }
98
Ruchira Sasankac1daae82001-10-12 17:47:23 +000099 } // if( IsPhi )
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000100
Ruchira Sasankac1daae82001-10-12 17:47:23 +0000101 } // if a use
102
103 } // for all operands
104
105 // do for implicit operands as well
106 for( unsigned i=0; i < MInst->getNumImplicitRefs(); ++i) {
107
108 assert( !IsPhi && "Phi cannot have implicit opeands");
109 const Value *Op = MInst->getImplicitRef(i);
110
111 if ( ((Op)->getType())->isLabelType() )
112 continue; // don't process labels
113 if( ! MInst->implicitRefIsDefined(i) )
114 addUse( Op );
115 }
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000116
117 } // for all machine instructions
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000118}
Ruchira Sasanka789cebb2001-12-08 21:05:27 +0000119
120
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000121
Ruchira Sasanka789cebb2001-12-08 21:05:27 +0000122//-----------------------------------------------------------------------------
123// To add an operand which is a def
124//-----------------------------------------------------------------------------
Ruchira Sasankac1daae82001-10-12 17:47:23 +0000125void BBLiveVar::addDef(const Value *Op)
126{
Chris Lattner11646322002-02-04 16:35:12 +0000127 DefSet.insert(Op); // operand is a def - so add to def set
128 InSet.erase(Op); // this definition kills any uses
Ruchira Sasankac1daae82001-10-12 17:47:23 +0000129 InSetChanged = true;
130
131 if( DEBUG_LV > 1) {
Chris Lattner697954c2002-01-20 22:54:45 +0000132 cerr << " +Def: "; printValue( Op ); cerr << "\n";
Ruchira Sasankac1daae82001-10-12 17:47:23 +0000133 }
134}
135
Ruchira Sasankac1daae82001-10-12 17:47:23 +0000136
Ruchira Sasanka789cebb2001-12-08 21:05:27 +0000137//-----------------------------------------------------------------------------
138// To add an operand which is a use
139//-----------------------------------------------------------------------------
Ruchira Sasankac1daae82001-10-12 17:47:23 +0000140void BBLiveVar::addUse(const Value *Op)
141{
Chris Lattner11646322002-02-04 16:35:12 +0000142 InSet.insert(Op); // An operand is a use - so add to use set
143 OutSet.erase(Op); // remove if there is a def below this use
Ruchira Sasankac1daae82001-10-12 17:47:23 +0000144 InSetChanged = true;
145
146 if( DEBUG_LV > 1) { // debug msg of level 2
Chris Lattner634b3522001-10-15 18:30:06 +0000147 cerr << " Use: "; printValue( Op ); cerr << endl;
Ruchira Sasankac1daae82001-10-12 17:47:23 +0000148 }
149
150}
151
152
Ruchira Sasanka789cebb2001-12-08 21:05:27 +0000153//-----------------------------------------------------------------------------
154// Applies the transfer function to a basic block to produce the InSet using
155// the outset.
156//-----------------------------------------------------------------------------
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000157
158bool BBLiveVar::applyTransferFunc() // calculates the InSet in terms of OutSet
159{
160
161 // IMPORTANT: caller should check whether the OutSet changed
162 // (else no point in calling)
163
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000164 LiveVarSet OutMinusDef; // set to hold (Out[B] - Def[B])
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000165 OutMinusDef.setDifference( &OutSet, &DefSet);
166 InSetChanged = InSet.setUnion( &OutMinusDef );
167
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000168 OutSetChanged = false; // no change to OutSet since transf func applied
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000169
170 return InSetChanged;
171}
172
173
Ruchira Sasanka789cebb2001-12-08 21:05:27 +0000174//-----------------------------------------------------------------------------
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000175// calculates Out set using In sets of the predecessors
Ruchira Sasanka789cebb2001-12-08 21:05:27 +0000176//-----------------------------------------------------------------------------
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000177bool BBLiveVar::setPropagate( LiveVarSet *const OutSet,
178 const LiveVarSet *const InSet,
179 const BasicBlock *const PredBB) {
180
181 LiveVarSet::const_iterator InIt;
182 pair<LiveVarSet::iterator, bool> result;
183 bool changed = false;
184 const BasicBlock *PredBBOfPhiArg;
185
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000186 // for all all elements in InSet
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000187 for( InIt = InSet->begin() ; InIt != InSet->end(); InIt++) {
188 PredBBOfPhiArg = PhiArgMap[ *InIt ];
189
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000190 // if this var is not a phi arg OR
191 // it's a phi arg and the var went down from this BB
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000192 if( !PredBBOfPhiArg || PredBBOfPhiArg == PredBB) {
193 result = OutSet->insert( *InIt ); // insert to this set
194 if( result.second == true) changed = true;
195 }
196 }
197
198 return changed;
199}
200
201
Ruchira Sasanka789cebb2001-12-08 21:05:27 +0000202//-----------------------------------------------------------------------------
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000203// propogates in set to OutSets of PREDECESSORs
Ruchira Sasanka789cebb2001-12-08 21:05:27 +0000204//-----------------------------------------------------------------------------
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000205bool BBLiveVar::applyFlowFunc(BBToBBLiveVarMapType LVMap)
206{
207
208 // IMPORTANT: caller should check whether inset changed
209 // (else no point in calling)
210
211 bool needAnotherIt= false; // did this BB change any OutSets of pred.s
212 // whose POId is lower
213
214
Chris Lattnerf0604b82001-10-01 13:19:53 +0000215 BasicBlock::pred_const_iterator PredBBI = BaseBB->pred_begin();
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000216
Chris Lattnerf0604b82001-10-01 13:19:53 +0000217 for( ; PredBBI != BaseBB->pred_end() ; PredBBI++) {
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000218 assert( *PredBBI ); // assert that the predecessor is valid
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000219 BBLiveVar *PredLVBB = LVMap[*PredBBI];
220
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000221 // do set union
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000222 if( setPropagate( &(PredLVBB->OutSet), &InSet, *PredBBI ) == true) {
223 PredLVBB->OutSetChanged = true;
224
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000225 // if the predec POId is lower than mine
226 if( PredLVBB->getPOId() <= POId)
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000227 needAnotherIt = true;
228 }
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000229
230 } // for
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000231
232 return needAnotherIt;
233
234}
235
236
237
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000238/* ----------------- Methods For Debugging (Printing) ----------------- */
239
240void BBLiveVar::printAllSets() const
241{
Chris Lattner634b3522001-10-15 18:30:06 +0000242 cerr << " Defs: "; DefSet.printSet(); cerr << endl;
243 cerr << " In: "; InSet.printSet(); cerr << endl;
244 cerr << " Out: "; OutSet.printSet(); cerr << endl;
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000245}
246
247void BBLiveVar::printInOutSets() const
248{
Chris Lattner634b3522001-10-15 18:30:06 +0000249 cerr << " In: "; InSet.printSet(); cerr << endl;
250 cerr << " Out: "; OutSet.printSet(); cerr << endl;
Ruchira Sasanka683847f2001-07-24 17:14:13 +0000251}
Ruchira Sasankae27c3442001-08-20 21:12:49 +0000252
253
254
255