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