diff options
author | Ruchira Sasanka <sasanka@students.uiuc.edu> | 2001-08-31 20:59:58 +0000 |
---|---|---|
committer | Ruchira Sasanka <sasanka@students.uiuc.edu> | 2001-08-31 20:59:58 +0000 |
commit | f2a6477aee0939b18f2d32e6bd2809cb444cfc04 (patch) | |
tree | c49ae6f5aacd4978d5e672d84403934092d15f75 /lib/CodeGen/TargetMachine/Sparc | |
parent | 33b6e9f48b61738f3355e41ffb292d5303a1bf10 (diff) |
*** empty log message ***
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@412 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/TargetMachine/Sparc')
-rw-r--r-- | lib/CodeGen/TargetMachine/Sparc/Sparc.cpp | 304 | ||||
-rw-r--r-- | lib/CodeGen/TargetMachine/Sparc/SparcRegInfo.cpp | 302 |
2 files changed, 606 insertions, 0 deletions
diff --git a/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp b/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp index f66d10e749..372b7e0dca 100644 --- a/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp +++ b/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp @@ -9,11 +9,307 @@ // 7/15/01 - Vikram Adve - Created //**************************************************************************/ +#include "llvm/Method.h" +#include "llvm/Instruction.h" + +#include "llvm/CodeGen/LiveRange.h" +#include "llvm/CodeGen/LiveRangeInfo.h" #include "llvm/CodeGen/Sparc.h" +#include "llvm/CodeGen/SparcRegInfo.h" //************************ Class Implementations **************************/ + + + +//--------------------------------------------------------------------------- +// UltraSparcRegInfo +// Purpose: +// This method will color incoming args to a method. If there are more +// args than that can fit in regs, code will be inserted to pop them from +// stack +//--------------------------------------------------------------------------- + + +void UltraSparcRegInfo::colorArgs(const Method *const Meth, + LiveRangeInfo& LRI) const +{ + + // get the argument list + const Method::ArgumentListType& ArgList = Meth->getArgumentList(); + // get an iterator to arg list + Method::ArgumentListType::const_iterator ArgIt = ArgList.begin(); + unsigned intArgNo=0; + + // to keep track of which float regs are allocated for argument passing + bool FloatArgUsedArr[NumOfFloatArgRegs]; + + // init float arg used array + for(unsigned i=0; i < NumOfFloatArgRegs; ++i) + FloatArgUsedArr[i] = false; + + // for each argument + for( ; ArgIt != ArgList.end() ; ++ArgIt) { + + // get the LR of arg + LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt); + unsigned RegClassID = (LR->getRegClass())->getID(); + + // if the arg is in int class - allocate a reg for an int arg + if( RegClassID == IntRegClassID ) { + + if( intArgNo < NumOfIntArgRegs) { + LR->setColor( SparcIntRegOrder::i0 + intArgNo ); + + if( DEBUG_RA) printReg( LR ); + } + + else { + // TODO: Insert push code here + assert( 0 && "Insert push code here!"); + } + ++intArgNo; + } + + // if the arg is float/double + else if ( RegClassID == FloatRegClassID) { + + if( LR->getTypeID() == Type::DoubleTyID ) { + + // find the first reg # we can pass a double arg + for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) { + if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) { + LR->setColor( SparcFloatRegOrder::f0 + i ); + FloatArgUsedArr[i] = true; + FloatArgUsedArr[i+1] = true; + if( DEBUG_RA) printReg( LR ); + break; + } + } + if( ! LR->hasColor() ) { // if LR was not colored above + + assert(0 && "insert push code here for a double"); + + } + + } + else if( LR->getTypeID() == Type::FloatTyID ) { + + // find the first reg # we can pass a float arg + for(unsigned i=0; i < NumOfFloatArgRegs; ++i) { + if ( !FloatArgUsedArr[i] ) { + LR->setColor( SparcFloatRegOrder::f0 + i ); + FloatArgUsedArr[i] = true; + if( DEBUG_RA) printReg( LR ); + break; + } + } + if( ! LR->hasColor() ) { // if LR was not colored above + assert(0 && "insert push code here for a float"); + } + + } + else + assert(0 && "unknown float type in method arg"); + + } // float register class + + else + assert(0 && "Unknown RegClassID"); + } + +} + + + + + + +void UltraSparcRegInfo::printReg(const LiveRange *const LR) { + + unsigned RegClassID = (LR->getRegClass())->getID(); + + cout << " *Node " << (LR->getUserIGNode())->getIndex(); + + if( ! LR->hasColor() ) { + cout << " - could not find a color" << endl; + return; + } + + // if a color is found + + cout << " colored with color "<< LR->getColor(); + + if( RegClassID == IntRegClassID ) { + + cout<< " [" << SparcIntRegOrder::getRegName(LR->getColor()) ; + cout << "]" << endl; + } + else if ( RegClassID == FloatRegClassID) { + cout << "[" << SparcFloatRegOrder::getRegName(LR->getColor()); + if( LR->getTypeID() == Type::DoubleTyID ) + cout << "+" << SparcFloatRegOrder::getRegName(LR->getColor()+1); + cout << "]" << endl; + } + + +} + + + + + +void UltraSparcRegInfo::colorCallArgs(vector<const Instruction *> & + CallInstrList, LiveRangeInfo& LRI ) const +{ + + vector<const Instruction *>::const_iterator InstIt = CallInstrList.begin(); + + for( ; InstIt != CallInstrList.end(); ++InstIt) { + + // Inst = LLVM call instruction + const Instruction *const CallI = *InstIt; + + MachineCodeForVMInstr & MInstVec = CallI->getMachineInstrVec(); + MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin(); + + // find the CALL/JMMPL machine instruction + for( ; MIIt != MInstVec.end() && + ! getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode()); + ++MIIt ); + + assert( (MIIt != MInstVec.end()) && "CALL/JMPL not found"); + + // CallMI = CALL/JMPL machine isntruction + const MachineInstr *const CallMI = *MIIt; + + Instruction::op_const_iterator OpIt = CallI->op_begin(); + + unsigned intArgNo=0; + //unsigned NumOfCallInterfs = LR->getNumOfCallInterferences(); + + // to keep track of which float regs are allocated for argument passing + bool FloatArgUsedArr[NumOfFloatArgRegs]; + + // init float arg used array + for(unsigned i=0; i < NumOfFloatArgRegs; ++i) + FloatArgUsedArr[i] = false; + + // go thru all the operands of LLVM instruction + for( ; OpIt != CallI->op_end(); ++OpIt ) { + + // get the LR of call operand (parameter) + LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt); + + if ( !LR ) { + cout << " Warning: In call instr, no LR for arg: " ; + printValue(*OpIt); + cout << endl; + continue; + } + + unsigned RegClassID = (LR->getRegClass())->getID(); + + // if the arg is in int class - allocate a reg for an int arg + if( RegClassID == IntRegClassID ) { + + if( intArgNo < NumOfIntArgRegs) { + setCallArgColor( LR, SparcIntRegOrder::o0 + intArgNo ); + } + + else { + // TODO: Insert push code here + assert( 0 && "Insert push code here!"); + } + ++intArgNo; + } + + // if the arg is float/double + else if ( RegClassID == FloatRegClassID) { + + if( LR->getTypeID() == Type::DoubleTyID ) { + + // find the first reg # we can pass a double arg + for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) { + if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) { + setCallArgColor(LR, SparcFloatRegOrder::f0 + i ); + FloatArgUsedArr[i] = true; + FloatArgUsedArr[i+1] = true; + //if( DEBUG_RA) printReg( LR ); + break; + } + } + if( ! LR->hasColor() ) { // if LR was not colored above + + assert(0 && "insert push code here for a double"); + + } + + } + else if( LR->getTypeID() == Type::FloatTyID ) { + + // find the first reg # we can pass a float arg + for(unsigned i=0; i < NumOfFloatArgRegs; ++i) { + if ( !FloatArgUsedArr[i] ) { + setCallArgColor(LR, SparcFloatRegOrder::f0 + i ); + FloatArgUsedArr[i] = true; + // LR->setColor( SparcFloatRegOrder::f0 + i ); + // if( DEBUG_RA) printReg( LR ); + break; + } + } + if( ! LR->hasColor() ) { // if LR was not colored above + assert(0 && "insert push code here for a float"); + } + + } + else + assert(0 && "unknown float type in method arg"); + + } // float register class + + else + assert(0 && "Unknown RegClassID"); + + + } // for each operand in a call instruction + + + + + } // for all call instrctions in CallInstrList + +} + + +void UltraSparcRegInfo::setCallArgColor(LiveRange *const LR, + const unsigned RegNo) const { + + // if no call interference and LR is NOT previously colored (e.g., as an + // incoming arg) + if( ! LR->getNumOfCallInterferences() && ! LR->hasColor() ) { + // we can directly allocate a %o register + LR->setColor( RegNo); + if( DEBUG_RA) printReg( LR ); + } + else { // there are call interferences + + /* + // insert a copy machine instr to copy from LR to %o(reg) + PreMInstrMap[ CallMI ] = + getNewCopyMInstr( LR->, SparcIntRegOrder::o0 + intArgNo ); + */ + cout << " $$$ TODO: Insert a copy for call argument!: " << endl; + + // We don't color LR here. It's colored as any other normal LR + } + +} + + + + //--------------------------------------------------------------------------- // class UltraSparcInstrInfo // @@ -79,6 +375,11 @@ UltraSparcSchedInfo::initializeResources() } + + + + + //--------------------------------------------------------------------------- // class UltraSparcMachine // @@ -91,10 +392,12 @@ UltraSparcSchedInfo::initializeResources() //--------------------------------------------------------------------------- UltraSparc::UltraSparc() + : TargetMachine("UltraSparc-Native") { machineInstrInfo = new UltraSparcInstrInfo; machineSchedInfo = new UltraSparcSchedInfo(machineInstrInfo); + machineRegInfo = new UltraSparcRegInfo(this); optSizeForSubWordData = 4; minMemOpWordSize = 8; @@ -105,6 +408,7 @@ UltraSparc::UltraSparc() UltraSparc::~UltraSparc() { delete (UltraSparcInstrInfo*) machineInstrInfo; + delete (UltraSparcRegInfo*) machineRegInfo; delete (UltraSparcSchedInfo*) machineSchedInfo; } 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 |