3d43fa3d2a164e92d561fe608c13f965690349c1
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9RegInfo.cpp
1 #include "llvm/CodeGen/IGNode.h"
2 #include "SparcRegInfo.h"
3
4 #include "llvm/Target/Sparc.h"
5
6 //-----------------------------------------------------------------------------
7 // Int Register Class
8 //-----------------------------------------------------------------------------
9
10 void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const 
11 {
12
13   /* Algorithm:
14   Record the color of all neighbors.
15
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
21   */
22
23   unsigned NumNeighbors =  Node->getNumOfNeighbors();   // total # of neighbors
24
25   for(unsigned n=0; n < NumNeighbors; n++) {            // for each neigh 
26     IGNode *NeighIGNode = Node->getAdjIGNode(n);
27     if( NeighIGNode->hasColor() ) {                     // if neigh has a color
28       IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color
29     }
30   }
31
32
33
34   unsigned SearchStart;                 // start pos of color in pref-order
35   bool ColorFound= false;               // have we found a color yet?
36
37   //if this Node is between calls
38   if( Node->getNumOfCallInterferences() == 0) { 
39
40     // start with volatiles (we can  allocate volatiles safely)
41     SearchStart = SparcIntRegOrder::StartOfAllRegs;  
42   }
43   else {           
44     // start with non volatiles (no non-volatiles)
45     SearchStart =  SparcIntRegOrder::StartOfNonVolatileRegs;  
46   }
47
48   unsigned c=0;                         // color
49  
50   // find first unused color
51   for( c=SearchStart; c < SparcIntRegOrder::NumOfAvailRegs; c++) { 
52     if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
53   }
54
55   if( ColorFound) 
56     Node->setColor(c);                  // first color found in preffered order
57
58   // if color is not found because of call interference
59   // try even finding a volatile color and insert save across calls
60   else if( Node->getNumOfCallInterferences() ) 
61   { 
62     // start from 0 - try to find even a volatile this time
63     SearchStart = SparcIntRegOrder::StartOfAllRegs;  
64
65     // find first unused volatile color
66     for(c=SearchStart; c < SparcIntRegOrder::StartOfNonVolatileRegs; c++) { 
67       if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
68     }
69
70     if( ColorFound) { 
71       Node->setColor(c);  
72       // since LR span across calls, must save across calls 
73       Node->markForSaveAcrossCalls();       
74     }
75
76   }
77
78   // If we couldn't find a color regardless of call interference - i.e., we
79   // don't have either a volatile or non-volatile color left
80   if( !ColorFound )  
81     Node->markForSpill();               // no color found - must spill
82
83
84   if( DEBUG_RA)                  
85     UltraSparcRegInfo::printReg( Node->getParentLR() );
86
87 }
88
89
90
91
92
93
94 //-----------------------------------------------------------------------------
95 // Float Register Class
96 //-----------------------------------------------------------------------------
97
98 // find the first available color in the range [Start,End] depending on the
99 // type of the Node (i.e., float/double)
100
101 int SparcFloatRegClass::findFloatColor(const IGNode *const Node, unsigned Start,
102                                        unsigned End, 
103                                        bool IsColorUsedArr[] ) const
104 {
105
106   bool ColorFound = false;
107   unsigned c;
108
109   if( Node->getTypeID() == Type::DoubleTyID ) { 
110       
111     // find first unused color for a double 
112     for( c=Start; c < End ;c+= 2){
113       if( ! IsColorUsedArr[ c ] &&  ! IsColorUsedArr[ c+1 ]) 
114         { ColorFound=true;  break; }
115     }
116     
117   } else {
118     
119     // find first unused color for a single
120     for( c=Start; c < End; c++) { 
121       if( ! IsColorUsedArr[ c ] ) { ColorFound=true;  break; }
122     }
123   }
124   
125   if( ColorFound ) return c;
126   else return -1;
127 }
128
129
130
131
132
133 void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
134 {
135
136   /* Algorithm:
137
138      If the LR is a double try to allocate f32 - f63
139      If the above fails or LR is single precision
140         If the LR does not interfere with a call
141            start allocating from f0
142         Else start allocating from f6
143      If a color is still not found because LR interferes with a call
144         Search in f0 - f6. If found mark for spill across calls.
145      If a color is still not fond, mark for spilling
146   */
147
148
149   unsigned NumNeighbors =  Node->getNumOfNeighbors();   // total # of neighbors
150
151   for(unsigned n=0; n < NumNeighbors; n++) {            // for each neigh 
152     IGNode *NeighIGNode = Node->getAdjIGNode(n);
153     if( NeighIGNode->hasColor() ) {                     // if neigh has a color
154       IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color
155       if( NeighIGNode->getTypeID() == Type::DoubleTyID )
156         IsColorUsedArr[ (NeighIGNode->getColor()) + 1 ] = true;  
157     }
158   }
159
160   int ColorFound = -1;               // have we found a color yet?
161   unsigned NumOfCallInterf = Node->getNumOfCallInterferences();
162
163   // if value is a double - search the double only reigon (f32 - f63)
164   if( Node->getTypeID() == Type::DoubleTyID )       
165     ColorFound = findFloatColor( Node, 32, 64, IsColorUsedArr );
166     
167
168   if( ColorFound >= 0 ) {
169     Node->setColor(ColorFound);                
170     if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
171     return;
172   }
173
174   else { // the above fails or LR is single precision
175
176     unsigned SearchStart;                 // start pos of color in pref-order
177
178     //if this Node is between calls (i.e., no call interferences )
179     if( ! NumOfCallInterf ) {
180       // start with volatiles (we can  allocate volatiles safely)
181       SearchStart = SparcFloatRegOrder::StartOfAllRegs;  
182     }
183     else {           
184       // start with non volatiles (no non-volatiles)
185       SearchStart =  SparcFloatRegOrder::StartOfNonVolatileRegs;  
186     }
187     
188     ColorFound = findFloatColor( Node, SearchStart, 32, IsColorUsedArr );
189
190   }
191
192   if( ColorFound >= 0 ) {
193     Node->setColor(ColorFound);                  
194     if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
195     return;
196   }
197
198   else if( NumOfCallInterf ) { 
199
200     // We are here because there is a call interference and no non-volatile
201     // color could be found.
202     // Now try to allocate even a volatile color
203
204     ColorFound = findFloatColor( Node, SparcFloatRegOrder::StartOfAllRegs, 
205                                 SparcFloatRegOrder::StartOfNonVolatileRegs,
206                                 IsColorUsedArr);
207   }
208
209   if( ColorFound >= 0 ) {
210     Node->setColor(ColorFound);         // first color found in preffered order
211     Node->markForSaveAcrossCalls();  
212     if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
213     return;
214   }
215
216   else {
217     Node->markForSpill();               // no color found - must spill
218     if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
219   }
220   
221
222 }
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243 #if 0
244
245 //-----------------------------------------------------------------------------
246 // Float Register Class
247 //-----------------------------------------------------------------------------
248
249 void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
250 {
251
252   /* Algorithm:
253   Record the color of all neighbors.
254
255   Single precision can use f0 - f31
256   Double precision can use f0 - f63
257
258   if LR is a double, try to allocate f32 - f63.
259   if the above attempt fails, or Value is single presion, try to allcoate 
260     f0 - f31.
261
262       */
263
264   unsigned NumNeighbors =  Node->getNumOfNeighbors();   // total # of neighbors
265
266   for(unsigned n=0; n < NumNeighbors; n++) {            // for each neigh 
267     IGNode *NeighIGNode = Node->getAdjIGNode(n);
268     if( NeighIGNode->hasColor() ) {                     // if neigh has a color
269       IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color
270       if( NeighIGNode->getTypeID() == Type::DoubleTyID )
271         IsColorUsedArr[ (NeighIGNode->getColor()) + 1 ] = true;  
272     }
273   }
274
275
276   unsigned SearchStart;                 // start pos of color in pref-order
277   bool ColorFound= false;               // have we found a color yet?
278   unsigned c;    
279
280
281   if( Node->getTypeID() == Type::DoubleTyID ) {        // if value is a double
282
283     // search the double only reigon (f32 - f63)
284      for( c=32; c < 64; c+= 2) { 
285       if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
286     }
287
288      // search f0 - f31 region
289     if( ! ColorFound )  {                // if color not found
290      for( c=0; c < 32; c+= 2) { 
291       if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
292      }
293     }
294
295   }
296
297   else {  // value is Single
298
299     for( c=0; c < 32; c++) { 
300       if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
301     }
302   }
303   
304
305   if( ColorFound) 
306     Node->setColor(c);                  // first color found in preferred order
307   else
308     Node->markForSpill();               // no color found - must spill
309
310
311   if( DEBUG_RA)                  
312     UltraSparcRegInfo::printReg( Node->getParentLR() );
313
314 }
315
316 #endif