1 #include "SparcInternals.h"
2 #include "llvm/CodeGen/IGNode.h"
5 //-----------------------------------------------------------------------------
7 //-----------------------------------------------------------------------------
9 void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
13 Record the color of all neighbors.
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.
22 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
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
33 unsigned SearchStart; // start pos of color in pref-order
34 bool ColorFound= false; // have we found a color yet?
36 //if this Node is between calls
37 if( Node->getNumOfCallInterferences() == 0) {
39 // start with volatiles (we can allocate volatiles safely)
40 SearchStart = SparcIntRegOrder::StartOfAllRegs;
43 // start with non volatiles (no non-volatiles)
44 SearchStart = SparcIntRegOrder::StartOfNonVolatileRegs;
47 unsigned c=0; // color
49 // find first unused color
50 for( c=SearchStart; c < SparcIntRegOrder::NumOfAvailRegs; c++) {
51 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
55 Node->setColor(c); // first color found in preffered order
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() )
61 // start from 0 - try to find even a volatile this time
62 SearchStart = SparcIntRegOrder::StartOfAllRegs;
64 // find first unused volatile color
65 for(c=SearchStart; c < SparcIntRegOrder::StartOfNonVolatileRegs; c++) {
66 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
71 // since LR span across calls, must save across calls
72 Node->markForSaveAcrossCalls();
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
80 Node->markForSpill(); // no color found - must spill
84 UltraSparcRegInfo::printReg( Node->getParentLR() );
93 //-----------------------------------------------------------------------------
94 // Float Register Class
95 //-----------------------------------------------------------------------------
97 // find the first available color in the range [Start,End] depending on the
98 // type of the Node (i.e., float/double)
100 int SparcFloatRegClass::findFloatColor(const IGNode *const Node, unsigned Start,
102 bool IsColorUsedArr[] ) const
105 bool ColorFound = false;
108 if( Node->getTypeID() == Type::DoubleTyID ) {
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; }
118 // find first unused color for a single
119 for( c=Start; c < End; c++) {
120 if( ! IsColorUsedArr[ c ] ) { ColorFound=true; break; }
124 if( ColorFound ) return c;
132 void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
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
148 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
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;
159 int ColorFound = -1; // have we found a color yet?
160 unsigned NumOfCallInterf = Node->getNumOfCallInterferences();
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 );
167 if( ColorFound >= 0 ) {
168 Node->setColor(ColorFound);
169 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
173 else { // the above fails or LR is single precision
175 unsigned SearchStart; // start pos of color in pref-order
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;
183 // start with non volatiles (no non-volatiles)
184 SearchStart = SparcFloatRegOrder::StartOfNonVolatileRegs;
187 ColorFound = findFloatColor( Node, SearchStart, 32, IsColorUsedArr );
191 if( ColorFound >= 0 ) {
192 Node->setColor(ColorFound);
193 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
197 else if( NumOfCallInterf ) {
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
203 ColorFound = findFloatColor( Node, SparcFloatRegOrder::StartOfAllRegs,
204 SparcFloatRegOrder::StartOfNonVolatileRegs,
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() );
216 Node->markForSpill(); // no color found - must spill
217 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
230 //-----------------------------------------------------------------------------
231 // Float Register Class
232 //-----------------------------------------------------------------------------
234 void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
238 Record the color of all neighbors.
240 Single precision can use f0 - f31
241 Double precision can use f0 - f63
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
249 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
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;
261 unsigned SearchStart; // start pos of color in pref-order
262 bool ColorFound= false; // have we found a color yet?
266 if( Node->getTypeID() == Type::DoubleTyID ) { // if value is a double
268 // search the double only reigon (f32 - f63)
269 for( c=32; c < 64; c+= 2) {
270 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
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; }
282 else { // value is Single
284 for( c=0; c < 32; c++) {
285 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
291 Node->setColor(c); // first color found in preferred order
293 Node->markForSpill(); // no color found - must spill
297 UltraSparcRegInfo::printReg( Node->getParentLR() );