blob: 08e33245ba3ac04481b56ff9536b5283d0365f9e [file] [log] [blame]
Chris Lattner5216cc52002-02-04 05:59:25 +00001#include "SparcRegClassInfo.h"
Chris Lattnerd5a84702002-04-29 17:42:12 +00002#include "llvm/CodeGen/RegAllocCommon.h"
Ruchira Sasankadfc6c882001-09-18 22:52:44 +00003#include "llvm/Target/Sparc.h"
Chris Lattnerd30f9892002-02-05 03:52:29 +00004#include "llvm/Type.h"
Chris Lattner7f74a562002-01-20 22:54:45 +00005#include <iostream>
6using std::cerr;
Anand Shukla458496c2002-06-25 20:55:50 +00007using std::vector;
Ruchira Sasankadfc6c882001-09-18 22:52:44 +00008
9//-----------------------------------------------------------------------------
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +000010// Int Register Class - method for coloring a node in the interference graph.
11//
12// Algorithm:
13// Record the colors/suggested colors of all neighbors.
14//
15// If there is a suggested color, try to allocate it
16// If there is no call interf, try to allocate volatile, then non volatile
17// If there is call interf, try to allocate non-volatile. If that fails
18// try to allocate a volatile and insert save across calls
19// If both above fail, spill.
20//
Ruchira Sasankadfc6c882001-09-18 22:52:44 +000021//-----------------------------------------------------------------------------
Chris Lattnerabe98192002-05-23 15:50:03 +000022void SparcIntRegClass::colorIGNode(IGNode * Node, vector<bool> &IsColorUsedArr) const {
Chris Lattner5216cc52002-02-04 05:59:25 +000023 LiveRange *LR = Node->getParentLR();
Ruchira Sasankadfc6c882001-09-18 22:52:44 +000024
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000025 if( DEBUG_RA ) {
Chris Lattner7f74a562002-01-20 22:54:45 +000026 cerr << "\nColoring LR [CallInt=" << LR->isCallInterference() <<"]:";
Chris Lattnerb0af9cd2002-02-05 02:52:05 +000027 printSet(*LR);
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000028 }
Ruchira Sasankadfc6c882001-09-18 22:52:44 +000029
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +000030 if( LR->hasSuggestedColor() ) {
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000031
32 unsigned SugCol = LR->getSuggestedColor();
33
Chris Lattnerabe98192002-05-23 15:50:03 +000034 if (!IsColorUsedArr[SugCol]) {
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000035
Ruchira Sasanka6a073492001-10-19 21:41:16 +000036 if( LR->isSuggestedColorUsable() ) {
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000037
38 // if the suggested color is volatile, we should use it only if
39 // there are no call interferences. Otherwise, it will get spilled.
40
41 if (DEBUG_RA)
Chris Lattner7f74a562002-01-20 22:54:45 +000042 cerr << "\n -Coloring with sug color: " << SugCol;
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000043
44 LR->setColor( LR->getSuggestedColor() );
45 return;
46 }
47 else if(DEBUG_RA)
Chris Lattner7f74a562002-01-20 22:54:45 +000048 cerr << "\n Couldn't alloc Sug col - LR voloatile & calls interf";
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000049
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +000050 }
Ruchira Sasanka5f629312001-10-18 22:38:52 +000051 else if ( DEBUG_RA ) { // can't allocate the suggested col
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000052 cerr << " \n Could NOT allocate the suggested color (already used) ";
Chris Lattnerb0af9cd2002-02-05 02:52:05 +000053 printSet(*LR); cerr << "\n";
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +000054 }
55 }
Ruchira Sasankadfc6c882001-09-18 22:52:44 +000056
57 unsigned SearchStart; // start pos of color in pref-order
58 bool ColorFound= false; // have we found a color yet?
59
60 //if this Node is between calls
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000061 if( ! LR->isCallInterference() ) {
Ruchira Sasankadfc6c882001-09-18 22:52:44 +000062
63 // start with volatiles (we can allocate volatiles safely)
64 SearchStart = SparcIntRegOrder::StartOfAllRegs;
65 }
66 else {
67 // start with non volatiles (no non-volatiles)
68 SearchStart = SparcIntRegOrder::StartOfNonVolatileRegs;
69 }
70
71 unsigned c=0; // color
72
73 // find first unused color
74 for( c=SearchStart; c < SparcIntRegOrder::NumOfAvailRegs; c++) {
Chris Lattnerabe98192002-05-23 15:50:03 +000075 if(!IsColorUsedArr[c] ) { ColorFound = true; break; }
Ruchira Sasankadfc6c882001-09-18 22:52:44 +000076 }
77
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000078 if( ColorFound) {
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +000079 LR->setColor(c); // first color found in preffered order
Chris Lattner7f74a562002-01-20 22:54:45 +000080 if (DEBUG_RA) cerr << "\n Colored after first search with col " << c ;
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000081 }
Ruchira Sasankadfc6c882001-09-18 22:52:44 +000082
83 // if color is not found because of call interference
84 // try even finding a volatile color and insert save across calls
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +000085 //
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000086 else if( LR->isCallInterference() )
Ruchira Sasankadfc6c882001-09-18 22:52:44 +000087 {
88 // start from 0 - try to find even a volatile this time
89 SearchStart = SparcIntRegOrder::StartOfAllRegs;
90
91 // find first unused volatile color
92 for(c=SearchStart; c < SparcIntRegOrder::StartOfNonVolatileRegs; c++) {
93 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
94 }
95
Chris Lattner5216cc52002-02-04 05:59:25 +000096 if (ColorFound) {
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +000097 LR->setColor(c);
98 // get the live range corresponding to live var
99 // since LR span across calls, must save across calls
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000100 //
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +0000101 LR->markForSaveAcrossCalls();
Chris Lattner7f74a562002-01-20 22:54:45 +0000102 if(DEBUG_RA) cerr << "\n Colored after SECOND search with col " << c ;
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000103 }
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000104 }
105
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000106
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000107 // If we couldn't find a color regardless of call interference - i.e., we
108 // don't have either a volatile or non-volatile color left
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000109 //
Chris Lattner5216cc52002-02-04 05:59:25 +0000110 if (!ColorFound)
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000111 LR->markForSpill(); // no color found - must spill
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000112}
113
114
115
116
117
118
119//-----------------------------------------------------------------------------
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000120// Float Register Class - method for coloring a node in the interference graph.
121//
122// Algorithm:
123//
124// If the LR is a double try to allocate f32 - f63
125// If the above fails or LR is single precision
126// If the LR does not interfere with a call
127// start allocating from f0
128// Else start allocating from f6
129// If a color is still not found because LR interferes with a call
130// Search in f0 - f6. If found mark for spill across calls.
131// If a color is still not fond, mark for spilling
132//
133//----------------------------------------------------------------------------
Chris Lattnerabe98192002-05-23 15:50:03 +0000134void SparcFloatRegClass::colorIGNode(IGNode * Node,
135 vector<bool> &IsColorUsedArr) const{
Chris Lattnerd30f9892002-02-05 03:52:29 +0000136 LiveRange *LR = Node->getParentLR();
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000137
Vikram S. Advee9327f02002-05-19 15:25:51 +0000138 // Mark the second color for double-precision registers:
139 // This is UGLY and should be merged into nearly identical code
140 // in RegClass::colorIGNode that handles the first color.
141 //
142 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000143 for(unsigned n=0; n < NumNeighbors; n++) { // for each neigh
144 IGNode *NeighIGNode = Node->getAdjIGNode(n);
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000145 LiveRange *NeighLR = NeighIGNode->getParentLR();
Vikram S. Advee9327f02002-05-19 15:25:51 +0000146
147 if( NeighLR->hasColor() &&
148 NeighLR->getType() == Type::DoubleTy) {
149 IsColorUsedArr[ (NeighLR->getColor()) + 1 ] = true;
150
151 } else if (NeighLR->hasSuggestedColor() &&
152 NeighLR-> isSuggestedColorUsable() ) {
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000153
Vikram S. Advee9327f02002-05-19 15:25:51 +0000154 // if the neighbour can use the suggested color
Ruchira Sasanka6a073492001-10-19 21:41:16 +0000155 IsColorUsedArr[ NeighLR->getSuggestedColor() ] = true;
Chris Lattnerd30f9892002-02-05 03:52:29 +0000156 if (NeighLR->getType() == Type::DoubleTy)
Ruchira Sasanka6a073492001-10-19 21:41:16 +0000157 IsColorUsedArr[ (NeighLR->getSuggestedColor()) + 1 ] = true;
Vikram S. Advee9327f02002-05-19 15:25:51 +0000158 }
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000159 }
160
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +0000161 // **NOTE: We don't check for call interferences in allocating suggested
162 // color in this class since ALL registers are volatile. If this fact
163 // changes, we should change the following part
164 //- see SparcIntRegClass::colorIGNode()
Vikram S. Advee9327f02002-05-19 15:25:51 +0000165 //
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000166 if( LR->hasSuggestedColor() ) {
167 if( ! IsColorUsedArr[ LR->getSuggestedColor() ] ) {
168 LR->setColor( LR->getSuggestedColor() );
169 return;
Chris Lattnerb0af9cd2002-02-05 02:52:05 +0000170 } else if (DEBUG_RA) { // can't allocate the suggested col
Chris Lattnerf3f1e452001-10-15 18:15:27 +0000171 cerr << " Could NOT allocate the suggested color for LR ";
Chris Lattnerb0af9cd2002-02-05 02:52:05 +0000172 printSet(*LR); cerr << "\n";
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000173 }
174 }
175
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000176
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000177 int ColorFound = -1; // have we found a color yet?
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +0000178 bool isCallInterf = LR->isCallInterference();
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000179
Chris Lattnerabe98192002-05-23 15:50:03 +0000180 // if value is a double - search the double only region (f32 - f63)
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000181 // i.e. we try to allocate f32 - f63 first for doubles since singles
182 // cannot go there. By doing that, we provide more space for singles
183 // in f0 - f31
184 //
Chris Lattnerd30f9892002-02-05 03:52:29 +0000185 if (LR->getType() == Type::DoubleTy)
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000186 ColorFound = findFloatColor( LR, 32, 64, IsColorUsedArr );
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000187
188
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000189 if( ColorFound >= 0 ) { // if we could find a color
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000190 LR->setColor(ColorFound);
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000191 return;
Chris Lattner5216cc52002-02-04 05:59:25 +0000192 } else {
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000193
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000194 // if we didn't find a color becuase the LR was single precision or
195 // all f32-f63 range is filled, we try to allocate a register from
196 // the f0 - f31 region
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000197
198 unsigned SearchStart; // start pos of color in pref-order
199
200 //if this Node is between calls (i.e., no call interferences )
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +0000201 if( ! isCallInterf ) {
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000202 // start with volatiles (we can allocate volatiles safely)
203 SearchStart = SparcFloatRegOrder::StartOfAllRegs;
204 }
205 else {
206 // start with non volatiles (no non-volatiles)
207 SearchStart = SparcFloatRegOrder::StartOfNonVolatileRegs;
208 }
209
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000210 ColorFound = findFloatColor( LR, SearchStart, 32, IsColorUsedArr );
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000211 }
212
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000213
214
215 if( ColorFound >= 0 ) { // if we could find a color
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000216 LR->setColor(ColorFound);
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000217 return;
218 }
Ruchira Sasankad77a1bb2001-10-19 17:23:43 +0000219 else if( isCallInterf ) {
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000220
221 // We are here because there is a call interference and no non-volatile
222 // color could be found.
223 // Now try to allocate even a volatile color
224
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000225 ColorFound = findFloatColor( LR, SparcFloatRegOrder::StartOfAllRegs,
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000226 SparcFloatRegOrder::StartOfNonVolatileRegs,
227 IsColorUsedArr);
228 }
229
230 if( ColorFound >= 0 ) {
Vikram S. Advee9327f02002-05-19 15:25:51 +0000231 LR->setColor(ColorFound); // first color found in prefered order
Ruchira Sasanka5867c7a2001-09-30 23:16:47 +0000232 LR->markForSaveAcrossCalls();
Chris Lattner5216cc52002-02-04 05:59:25 +0000233 } else {
234 // we are here because no color could be found
235 LR->markForSpill(); // no color found - must spill
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000236 }
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000237}
238
239
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000240//-----------------------------------------------------------------------------
241// Helper method for coloring a node of Float Reg class.
242// Finds the first available color in the range [Start,End] depending on the
243// type of the Node (i.e., float/double)
244//-----------------------------------------------------------------------------
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000245
Chris Lattner5216cc52002-02-04 05:59:25 +0000246int SparcFloatRegClass::findFloatColor(const LiveRange *LR,
247 unsigned Start, unsigned End,
Chris Lattnerabe98192002-05-23 15:50:03 +0000248 vector<bool> &IsColorUsedArr) const {
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000249 bool ColorFound = false;
250 unsigned c;
251
Chris Lattnerd30f9892002-02-05 03:52:29 +0000252 if (LR->getType() == Type::DoubleTy) {
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000253 // find first unused color for a double
Chris Lattner5216cc52002-02-04 05:59:25 +0000254 for (c=Start; c < End ; c+= 2)
255 if (!IsColorUsedArr[c] && !IsColorUsedArr[c+1])
256 return c;
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000257 } else {
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000258 // find first unused color for a single
Chris Lattner5216cc52002-02-04 05:59:25 +0000259 for (c = Start; c < End; c++)
260 if (!IsColorUsedArr[c])
261 return c;
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000262 }
263
Chris Lattner5216cc52002-02-04 05:59:25 +0000264 return -1;
Ruchira Sasanka4cfbfd52002-01-07 19:20:28 +0000265}