1 #include "llvm/CodeGen/IGNode.h"
2 #include "SparcRegInfo.h"
4 #include "llvm/Target/Sparc.h"
6 //-----------------------------------------------------------------------------
8 //-----------------------------------------------------------------------------
10 void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
14 Record the color of all neighbors.
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.
23 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
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
34 unsigned SearchStart; // start pos of color in pref-order
35 bool ColorFound= false; // have we found a color yet?
37 //if this Node is between calls
38 if( Node->getNumOfCallInterferences() == 0) {
40 // start with volatiles (we can allocate volatiles safely)
41 SearchStart = SparcIntRegOrder::StartOfAllRegs;
44 // start with non volatiles (no non-volatiles)
45 SearchStart = SparcIntRegOrder::StartOfNonVolatileRegs;
48 unsigned c=0; // color
50 // find first unused color
51 for( c=SearchStart; c < SparcIntRegOrder::NumOfAvailRegs; c++) {
52 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
56 Node->setColor(c); // first color found in preffered order
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() )
62 // start from 0 - try to find even a volatile this time
63 SearchStart = SparcIntRegOrder::StartOfAllRegs;
65 // find first unused volatile color
66 for(c=SearchStart; c < SparcIntRegOrder::StartOfNonVolatileRegs; c++) {
67 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
72 // since LR span across calls, must save across calls
73 Node->markForSaveAcrossCalls();
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
81 Node->markForSpill(); // no color found - must spill
85 UltraSparcRegInfo::printReg( Node->getParentLR() );
94 //-----------------------------------------------------------------------------
95 // Float Register Class
96 //-----------------------------------------------------------------------------
98 // find the first available color in the range [Start,End] depending on the
99 // type of the Node (i.e., float/double)
101 int SparcFloatRegClass::findFloatColor(const IGNode *const Node, unsigned Start,
103 bool IsColorUsedArr[] ) const
106 bool ColorFound = false;
109 if( Node->getTypeID() == Type::DoubleTyID ) {
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; }
119 // find first unused color for a single
120 for( c=Start; c < End; c++) {
121 if( ! IsColorUsedArr[ c ] ) { ColorFound=true; break; }
125 if( ColorFound ) return c;
133 void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
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
149 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
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;
160 int ColorFound = -1; // have we found a color yet?
161 unsigned NumOfCallInterf = Node->getNumOfCallInterferences();
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 );
168 if( ColorFound >= 0 ) {
169 Node->setColor(ColorFound);
170 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
174 else { // the above fails or LR is single precision
176 unsigned SearchStart; // start pos of color in pref-order
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;
184 // start with non volatiles (no non-volatiles)
185 SearchStart = SparcFloatRegOrder::StartOfNonVolatileRegs;
188 ColorFound = findFloatColor( Node, SearchStart, 32, IsColorUsedArr );
192 if( ColorFound >= 0 ) {
193 Node->setColor(ColorFound);
194 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
198 else if( NumOfCallInterf ) {
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
204 ColorFound = findFloatColor( Node, SparcFloatRegOrder::StartOfAllRegs,
205 SparcFloatRegOrder::StartOfNonVolatileRegs,
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() );
217 Node->markForSpill(); // no color found - must spill
218 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
245 //-----------------------------------------------------------------------------
246 // Float Register Class
247 //-----------------------------------------------------------------------------
249 void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
253 Record the color of all neighbors.
255 Single precision can use f0 - f31
256 Double precision can use f0 - f63
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
264 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
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;
276 unsigned SearchStart; // start pos of color in pref-order
277 bool ColorFound= false; // have we found a color yet?
281 if( Node->getTypeID() == Type::DoubleTyID ) { // if value is a double
283 // search the double only reigon (f32 - f63)
284 for( c=32; c < 64; c+= 2) {
285 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
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; }
297 else { // value is Single
299 for( c=0; c < 32; c++) {
300 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
306 Node->setColor(c); // first color found in preferred order
308 Node->markForSpill(); // no color found - must spill
312 UltraSparcRegInfo::printReg( Node->getParentLR() );