diff options
Diffstat (limited to 'lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.cpp')
-rw-r--r-- | lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.cpp | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.cpp b/lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.cpp new file mode 100644 index 0000000000..2cda2d7f39 --- /dev/null +++ b/lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.cpp @@ -0,0 +1,302 @@ +#include "llvm/CodeGen/IGNode.h" +#include "llvm/CodeGen/SparcRegInfo.h" + +#include "llvm/CodeGen/Sparc.h" + +//----------------------------------------------------------------------------- +// Int Register Class +//----------------------------------------------------------------------------- + +void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const +{ + + /* Algorithm: + Record the color of all neighbors. + + If there is no call interf, try to allocate volatile, then non volatile + If there is call interf, try to allocate non-volatile. If that fails + try to allocate a volatile and insert save across calls + If both above fail, spill. + + */ + + unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors + + for(unsigned n=0; n < NumNeighbors; n++) { // for each neigh + IGNode *NeighIGNode = Node->getAdjIGNode(n); + if( NeighIGNode->hasColor() ) { // if neigh has a color + IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color + } + } + + + + unsigned SearchStart; // start pos of color in pref-order + bool ColorFound= false; // have we found a color yet? + + //if this Node is between calls + if( Node->getNumOfCallInterferences() == 0) { + + // start with volatiles (we can allocate volatiles safely) + SearchStart = SparcIntRegOrder::StartOfAllRegs; + } + else { + // start with non volatiles (no non-volatiles) + SearchStart = SparcIntRegOrder::StartOfNonVolatileRegs; + } + + unsigned c=0; // color + + // find first unused color + for( c=SearchStart; c < SparcIntRegOrder::NumOfAvailRegs; c++) { + if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; } + } + + if( ColorFound) + Node->setColor(c); // first color found in preffered order + + // if color is not found because of call interference + // try even finding a volatile color and insert save across calls + else if( Node->getNumOfCallInterferences() ) + { + // start from 0 - try to find even a volatile this time + SearchStart = SparcIntRegOrder::StartOfAllRegs; + + // find first unused volatile color + for(c=SearchStart; c < SparcIntRegOrder::StartOfNonVolatileRegs; c++) { + if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; } + } + + if( ColorFound) { + Node->setColor(c); + // since LR span across calls, must save across calls + Node->markForSaveAcrossCalls(); + } + + } + + // If we couldn't find a color regardless of call interference - i.e., we + // don't have either a volatile or non-volatile color left + if( !ColorFound ) + Node->markForSpill(); // no color found - must spill + + + if( DEBUG_RA) + UltraSparcRegInfo::printReg( Node->getParentLR() ); + +} + + + + + + +//----------------------------------------------------------------------------- +// Float Register Class +//----------------------------------------------------------------------------- + +// find the first available color in the range [Start,End] depending on the +// type of the Node (i.e., float/double) + +int SparcFloatRegClass::findFloatColor(const IGNode *const Node, unsigned Start, + unsigned End, + bool IsColorUsedArr[] ) const +{ + + bool ColorFound = false; + unsigned c; + + if( Node->getTypeID() == Type::DoubleTyID ) { + + // find first unused color for a double + for( c=Start; c < End ;c+= 2){ + if( ! IsColorUsedArr[ c ] && ! IsColorUsedArr[ c+1 ]) + { ColorFound=true; break; } + } + + } else { + + // find first unused color for a single + for( c=Start; c < End; c++) { + if( ! IsColorUsedArr[ c ] ) { ColorFound=true; break; } + } + } + + if( ColorFound ) return c; + else return -1; +} + + + + + +void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const +{ + + /* Algorithm: + + If the LR is a double try to allocate f32 - f63 + If the above fails or LR is single precision + If the LR does not interfere with a call + start allocating from f0 + Else start allocating from f6 + If a color is still not found because LR interferes with a call + Search in f0 - f6. If found mark for spill across calls. + If a color is still not fond, mark for spilling + */ + + + unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors + + for(unsigned n=0; n < NumNeighbors; n++) { // for each neigh + IGNode *NeighIGNode = Node->getAdjIGNode(n); + if( NeighIGNode->hasColor() ) { // if neigh has a color + IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color + if( NeighIGNode->getTypeID() == Type::DoubleTyID ) + IsColorUsedArr[ (NeighIGNode->getColor()) + 1 ] = true; + } + } + + int ColorFound = -1; // have we found a color yet? + unsigned NumOfCallInterf = Node->getNumOfCallInterferences(); + + // if value is a double - search the double only reigon (f32 - f63) + if( Node->getTypeID() == Type::DoubleTyID ) + ColorFound = findFloatColor( Node, 32, 64, IsColorUsedArr ); + + + if( ColorFound >= 0 ) { + Node->setColor(ColorFound); + if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() ); + return; + } + + else { // the above fails or LR is single precision + + unsigned SearchStart; // start pos of color in pref-order + + //if this Node is between calls (i.e., no call interferences ) + if( ! NumOfCallInterf ) { + // start with volatiles (we can allocate volatiles safely) + SearchStart = SparcFloatRegOrder::StartOfAllRegs; + } + else { + // start with non volatiles (no non-volatiles) + SearchStart = SparcFloatRegOrder::StartOfNonVolatileRegs; + } + + ColorFound = findFloatColor( Node, SearchStart, 32, IsColorUsedArr ); + + } + + if( ColorFound >= 0 ) { + Node->setColor(ColorFound); + if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() ); + return; + } + + else if( NumOfCallInterf ) { + + // We are here because there is a call interference and no non-volatile + // color could be found. + // Now try to allocate even a volatile color + + ColorFound = findFloatColor( Node, SparcFloatRegOrder::StartOfAllRegs, + SparcFloatRegOrder::StartOfNonVolatileRegs, + IsColorUsedArr); + } + + if( ColorFound >= 0 ) { + Node->setColor(ColorFound); // first color found in preffered order + Node->markForSaveAcrossCalls(); + if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() ); + return; + } + + else { + Node->markForSpill(); // no color found - must spill + if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() ); + } + + +} + + + + + + +#if 0 + +//----------------------------------------------------------------------------- +// Float Register Class +//----------------------------------------------------------------------------- + +void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const +{ + + /* Algorithm: + Record the color of all neighbors. + + Single precision can use f0 - f31 + Double precision can use f0 - f63 + + if LR is a double, try to allocate f32 - f63. + if the above attempt fails, or Value is single presion, try to allcoate + f0 - f31. + + */ + + unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors + + for(unsigned n=0; n < NumNeighbors; n++) { // for each neigh + IGNode *NeighIGNode = Node->getAdjIGNode(n); + if( NeighIGNode->hasColor() ) { // if neigh has a color + IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color + if( NeighIGNode->getTypeID() == Type::DoubleTyID ) + IsColorUsedArr[ (NeighIGNode->getColor()) + 1 ] = true; + } + } + + + unsigned SearchStart; // start pos of color in pref-order + bool ColorFound= false; // have we found a color yet? + unsigned c; + + + if( Node->getTypeID() == Type::DoubleTyID ) { // if value is a double + + // search the double only reigon (f32 - f63) + for( c=32; c < 64; c+= 2) { + if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; } + } + + // search f0 - f31 region + if( ! ColorFound ) { // if color not found + for( c=0; c < 32; c+= 2) { + if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; } + } + } + + } + + else { // value is Single + + for( c=0; c < 32; c++) { + if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; } + } + } + + + if( ColorFound) + Node->setColor(c); // first color found in preferred order + else + Node->markForSpill(); // no color found - must spill + + + if( DEBUG_RA) + UltraSparcRegInfo::printReg( Node->getParentLR() ); + +} + +#endif |