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