1 #include "llvm/CodeGen/IGNode.h"
2 #include "SparcRegInfo.h"
3 #include "SparcInternals.h"
5 #include "llvm/Target/Sparc.h"
7 //-----------------------------------------------------------------------------
9 //-----------------------------------------------------------------------------
11 void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
15 Record the color of all neighbors.
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.
24 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
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
35 unsigned SearchStart; // start pos of color in pref-order
36 bool ColorFound= false; // have we found a color yet?
38 //if this Node is between calls
39 if( Node->getNumOfCallInterferences() == 0) {
41 // start with volatiles (we can allocate volatiles safely)
42 SearchStart = SparcIntRegOrder::StartOfAllRegs;
45 // start with non volatiles (no non-volatiles)
46 SearchStart = SparcIntRegOrder::StartOfNonVolatileRegs;
49 unsigned c=0; // color
51 // find first unused color
52 for( c=SearchStart; c < SparcIntRegOrder::NumOfAvailRegs; c++) {
53 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
57 Node->setColor(c); // first color found in preffered order
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() )
63 // start from 0 - try to find even a volatile this time
64 SearchStart = SparcIntRegOrder::StartOfAllRegs;
66 // find first unused volatile color
67 for(c=SearchStart; c < SparcIntRegOrder::StartOfNonVolatileRegs; c++) {
68 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
73 // since LR span across calls, must save across calls
74 Node->markForSaveAcrossCalls();
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
82 Node->markForSpill(); // no color found - must spill
86 UltraSparcRegInfo::printReg( Node->getParentLR() );
95 //-----------------------------------------------------------------------------
96 // Float Register Class
97 //-----------------------------------------------------------------------------
99 // find the first available color in the range [Start,End] depending on the
100 // type of the Node (i.e., float/double)
102 int SparcFloatRegClass::findFloatColor(const IGNode *const Node, unsigned Start,
104 bool IsColorUsedArr[] ) const
107 bool ColorFound = false;
110 if( Node->getTypeID() == Type::DoubleTyID ) {
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; }
120 // find first unused color for a single
121 for( c=Start; c < End; c++) {
122 if( ! IsColorUsedArr[ c ] ) { ColorFound=true; break; }
126 if( ColorFound ) return c;
134 void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
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
150 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
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;
161 int ColorFound = -1; // have we found a color yet?
162 unsigned NumOfCallInterf = Node->getNumOfCallInterferences();
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 );
169 if( ColorFound >= 0 ) {
170 Node->setColor(ColorFound);
171 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
175 else { // the above fails or LR is single precision
177 unsigned SearchStart; // start pos of color in pref-order
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;
185 // start with non volatiles (no non-volatiles)
186 SearchStart = SparcFloatRegOrder::StartOfNonVolatileRegs;
189 ColorFound = findFloatColor( Node, SearchStart, 32, IsColorUsedArr );
193 if( ColorFound >= 0 ) {
194 Node->setColor(ColorFound);
195 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
199 else if( NumOfCallInterf ) {
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
205 ColorFound = findFloatColor( Node, SparcFloatRegOrder::StartOfAllRegs,
206 SparcFloatRegOrder::StartOfNonVolatileRegs,
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() );
218 Node->markForSpill(); // no color found - must spill
219 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
246 //-----------------------------------------------------------------------------
247 // Float Register Class
248 //-----------------------------------------------------------------------------
250 void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
254 Record the color of all neighbors.
256 Single precision can use f0 - f31
257 Double precision can use f0 - f63
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
265 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
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;
277 unsigned SearchStart; // start pos of color in pref-order
278 bool ColorFound= false; // have we found a color yet?
282 if( Node->getTypeID() == Type::DoubleTyID ) { // if value is a double
284 // search the double only reigon (f32 - f63)
285 for( c=32; c < 64; c+= 2) {
286 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
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; }
298 else { // value is Single
300 for( c=0; c < 32; c++) {
301 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
307 Node->setColor(c); // first color found in preferred order
309 Node->markForSpill(); // no color found - must spill
313 UltraSparcRegInfo::printReg( Node->getParentLR() );