diff --git a/lib/CodeGen/RegAlloc/IGNode.h b/lib/CodeGen/RegAlloc/IGNode.h new file mode 100644 index 00000000000..03bcfc07b1a --- /dev/null +++ b/lib/CodeGen/RegAlloc/IGNode.h @@ -0,0 +1,152 @@ +/* Title: IGNode.h + Author: Ruchira Sasanka + Date: July 25, 01 + Purpose: Represents a node in an interference graph. + Notes: + + For efficiency, the AdjList is updated only once - ie. we can add but not + remove nodes from AdjList. + + The removal of nodes from IG is simulated by decrementing the CurDegree. + If this node is put on stack (that is removed from IG), the CurDegree of all + the neighbors are decremented and this node is marked OnSack. Hence + the effective neighbors in the AdjList are the ones that do not have the + OnStack flag set (therefore, they are in the IG). + + The methods that modify/use the CurDegree Must be called only + fter all modifications to the IG are over (i.e., all neighbors are fixed). + + The vector representation the most efficient one for adj list. + Though nodes are removed when coalsing is done, we access it in sequence + for far many times when coloring (colorNode()). + +*/ + +#ifndef IG_NODE_H +#define IG_NODE_H + + +#include "llvm/CodeGen/RegAllocCommon.h" +#include "llvm/CodeGen/LiveRange.h" + +class IGNode +{ + private: + + const int Index; // index within IGNodeList + + bool OnStack; // this has been pushed on to stack for coloring + + vector AdjList; // adjacency list for this live range + + + // set by InterferenceGraph::setCurDegreeOfIGNodes() after calculating + // all adjacency lists. + // Decremented when a neighbor is pushed on to the stack. + // After that, never incremented/set again nor used. + int CurDegree; + + LiveRange *const ParentLR; // parent LR (cannot be a const) + + + public: + + inline unsigned int getIndex() const + { return Index; } + + // adjLists must be updated only once. However, the CurDegree can be changed + inline void addAdjIGNode( IGNode *const AdjNode) + { AdjList.push_back(AdjNode); } + + inline IGNode * getAdjIGNode(unsigned int ind) const + { assert ( ind < AdjList.size()); return AdjList[ ind ]; } + + // delete a node in AdjList - node must be in the list + // should not be called often + void delAdjIGNode(const IGNode *const Node); + + inline unsigned int getNumOfNeighbors() const + { return AdjList.size() ; } + + + inline bool isOnStack() const + { return OnStack; } + + // remove form IG and pushes on to stack (reduce the degree of neighbors) + void pushOnStack(); + + // CurDegree is the effective number of neighbors when neighbors are + // pushed on to the stack during the coloring phase. Must be called + // after all modifications to the IG are over (i.e., all neighbors are + // fixed). + + inline void setCurDegree() + { assert( CurDegree == -1); CurDegree = AdjList.size(); } + + inline int getCurDegree() const + { return CurDegree; } + + // called when a neigh is pushed on to stack + inline void decCurDegree() + { assert( CurDegree > 0 ); --CurDegree; } + + + // The following methods call the methods in ParentLR + // They are added to this class for convenience + // If many of these are called within a single scope, + // consider calling the methods directly on LR + + + inline void setRegClass(RegClass *const RC) + { ParentLR->setRegClass(RC); } + + inline RegClass *const getRegClass() const + { return ParentLR->getRegClass(); } + + inline bool hasColor() const + { return ParentLR->hasColor(); } + + inline unsigned int getColor() const + { return ParentLR->getColor(); } + + inline void setColor(unsigned int Col) + { ParentLR->setColor(Col); } + + inline void markForSpill() + { ParentLR->markForSpill(); } + + inline void markForSaveAcrossCalls() + { ParentLR->markForSaveAcrossCalls(); } + + // inline void markForLoadFromStack() + // { ParentLR->markForLoadFromStack(); } + + + inline unsigned int getNumOfCallInterferences() const + { return ParentLR->getNumOfCallInterferences(); } + + inline LiveRange *getParentLR() const + { return ParentLR; } + + inline Type::PrimitiveID getTypeID() const + { return ParentLR->getTypeID(); } + + + + //---- constructor and destructor ---- + + + IGNode(LiveRange *const LR, unsigned int index); + + ~IGNode() { } // an empty destructor + + +}; + + + + + + + +#endif diff --git a/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp b/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp index f66d10e7494..372b7e0dca9 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 & + CallInstrList, LiveRangeInfo& LRI ) const +{ + + vector::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 00000000000..2cda2d7f39d --- /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 diff --git a/lib/Target/SparcV9/RegAlloc/IGNode.h b/lib/Target/SparcV9/RegAlloc/IGNode.h new file mode 100644 index 00000000000..03bcfc07b1a --- /dev/null +++ b/lib/Target/SparcV9/RegAlloc/IGNode.h @@ -0,0 +1,152 @@ +/* Title: IGNode.h + Author: Ruchira Sasanka + Date: July 25, 01 + Purpose: Represents a node in an interference graph. + Notes: + + For efficiency, the AdjList is updated only once - ie. we can add but not + remove nodes from AdjList. + + The removal of nodes from IG is simulated by decrementing the CurDegree. + If this node is put on stack (that is removed from IG), the CurDegree of all + the neighbors are decremented and this node is marked OnSack. Hence + the effective neighbors in the AdjList are the ones that do not have the + OnStack flag set (therefore, they are in the IG). + + The methods that modify/use the CurDegree Must be called only + fter all modifications to the IG are over (i.e., all neighbors are fixed). + + The vector representation the most efficient one for adj list. + Though nodes are removed when coalsing is done, we access it in sequence + for far many times when coloring (colorNode()). + +*/ + +#ifndef IG_NODE_H +#define IG_NODE_H + + +#include "llvm/CodeGen/RegAllocCommon.h" +#include "llvm/CodeGen/LiveRange.h" + +class IGNode +{ + private: + + const int Index; // index within IGNodeList + + bool OnStack; // this has been pushed on to stack for coloring + + vector AdjList; // adjacency list for this live range + + + // set by InterferenceGraph::setCurDegreeOfIGNodes() after calculating + // all adjacency lists. + // Decremented when a neighbor is pushed on to the stack. + // After that, never incremented/set again nor used. + int CurDegree; + + LiveRange *const ParentLR; // parent LR (cannot be a const) + + + public: + + inline unsigned int getIndex() const + { return Index; } + + // adjLists must be updated only once. However, the CurDegree can be changed + inline void addAdjIGNode( IGNode *const AdjNode) + { AdjList.push_back(AdjNode); } + + inline IGNode * getAdjIGNode(unsigned int ind) const + { assert ( ind < AdjList.size()); return AdjList[ ind ]; } + + // delete a node in AdjList - node must be in the list + // should not be called often + void delAdjIGNode(const IGNode *const Node); + + inline unsigned int getNumOfNeighbors() const + { return AdjList.size() ; } + + + inline bool isOnStack() const + { return OnStack; } + + // remove form IG and pushes on to stack (reduce the degree of neighbors) + void pushOnStack(); + + // CurDegree is the effective number of neighbors when neighbors are + // pushed on to the stack during the coloring phase. Must be called + // after all modifications to the IG are over (i.e., all neighbors are + // fixed). + + inline void setCurDegree() + { assert( CurDegree == -1); CurDegree = AdjList.size(); } + + inline int getCurDegree() const + { return CurDegree; } + + // called when a neigh is pushed on to stack + inline void decCurDegree() + { assert( CurDegree > 0 ); --CurDegree; } + + + // The following methods call the methods in ParentLR + // They are added to this class for convenience + // If many of these are called within a single scope, + // consider calling the methods directly on LR + + + inline void setRegClass(RegClass *const RC) + { ParentLR->setRegClass(RC); } + + inline RegClass *const getRegClass() const + { return ParentLR->getRegClass(); } + + inline bool hasColor() const + { return ParentLR->hasColor(); } + + inline unsigned int getColor() const + { return ParentLR->getColor(); } + + inline void setColor(unsigned int Col) + { ParentLR->setColor(Col); } + + inline void markForSpill() + { ParentLR->markForSpill(); } + + inline void markForSaveAcrossCalls() + { ParentLR->markForSaveAcrossCalls(); } + + // inline void markForLoadFromStack() + // { ParentLR->markForLoadFromStack(); } + + + inline unsigned int getNumOfCallInterferences() const + { return ParentLR->getNumOfCallInterferences(); } + + inline LiveRange *getParentLR() const + { return ParentLR; } + + inline Type::PrimitiveID getTypeID() const + { return ParentLR->getTypeID(); } + + + + //---- constructor and destructor ---- + + + IGNode(LiveRange *const LR, unsigned int index); + + ~IGNode() { } // an empty destructor + + +}; + + + + + + + +#endif