diff --git a/lib/CodeGen/RegAlloc/LiveRange.h b/lib/CodeGen/RegAlloc/LiveRange.h index d8e130a329c..9c4d4508805 100644 --- a/lib/CodeGen/RegAlloc/LiveRange.h +++ b/lib/CodeGen/RegAlloc/LiveRange.h @@ -39,6 +39,9 @@ class LiveRange : public ValueSet // bool mustLoadFromStack; // must load from stack at start of method + + int SuggestedColor; // The suggested color for this LR + public: @@ -92,9 +95,27 @@ class LiveRange : public ValueSet } + inline void setSuggestedColor(int Col) { + //assert( (SuggestedColor == -1) && "Changing an already suggested color"); + + if(SuggestedColor == -1 ) + SuggestedColor = Col; + else if (DEBUG_RA) + cout << "Already has a suggested color " << Col << endl; + } + + inline unsigned getSuggestedColor() const { + assert( SuggestedColor != -1); // only a valid color is obtained + return (unsigned) SuggestedColor; + } + + inline bool hasSuggestedColor() const { + return ( SuggestedColor > -1); + } + inline LiveRange() : ValueSet() , CallInterferenceList() { - Color = -1; // not yet colored + Color = SuggestedColor = -1; // not yet colored mustSpill = mustSaveAcrossCalls = false; MyRegClass = NULL; UserIGNode = NULL; diff --git a/lib/CodeGen/RegAlloc/LiveRangeInfo.h b/lib/CodeGen/RegAlloc/LiveRangeInfo.h index da5601790a0..2a8eb2ffb6f 100644 --- a/lib/CodeGen/RegAlloc/LiveRangeInfo.h +++ b/lib/CodeGen/RegAlloc/LiveRangeInfo.h @@ -42,7 +42,7 @@ typedef hash_map LiveRangeMapType; - +typedef vector CallRetInstrListType; class LiveRangeInfo { @@ -56,7 +56,9 @@ private: const TargetMachine& TM; // target machine description vector & RegClassList;// a vector containing register classess + const MachineRegInfo& MRI; // machine reg info + CallRetInstrListType CallRetInstrList; // a list of all call/ret instrs void unionAndUpdateLRs(LiveRange *L1, LiveRange *L2); @@ -72,12 +74,22 @@ public: void constructLiveRanges(); + inline void addLRToMap(const Value *Val, LiveRange *LR) { + assert( Val && LR && "Val/LR is NULL!\n"); + assert( (! LiveRangeMap[ Val ]) && "LR already set in map"); + LiveRangeMap[ Val ] = LR; + } + + inline const LiveRangeMapType *const getLiveRangeMap() const { return &LiveRangeMap; } inline LiveRange *getLiveRangeForValue( const Value *const Val) { return LiveRangeMap[ Val ]; } + inline CallRetInstrListType &getCallRetInstrList() { + return CallRetInstrList; + } diff --git a/lib/CodeGen/RegAlloc/PhyRegAlloc.h b/lib/CodeGen/RegAlloc/PhyRegAlloc.h index fcf28320cc7..f96f27bdfbb 100644 --- a/lib/CodeGen/RegAlloc/PhyRegAlloc.h +++ b/lib/CodeGen/RegAlloc/PhyRegAlloc.h @@ -43,8 +43,8 @@ class AddedInstrns { public: - vector InstrnsBefore; - vector InstrnsAfter; + vector InstrnsBefore; + vector InstrnsAfter; AddedInstrns() : InstrnsBefore(), InstrnsAfter() { } }; @@ -65,8 +65,8 @@ class PhyRegAlloc const MachineRegInfo &MRI; // Machine Register information const unsigned NumOfRegClasses; // recorded here for efficiency - vector CallInstrList; // a list of all call instrs - vector RetInstrList; // a list of all return instrs + //vector CallInstrList; // a list of all call instrs + //vector RetInstrList; // a list of all return instrs AddedInstrMapType AddedInstrMap; // to store instrns added in this phase @@ -85,7 +85,9 @@ class PhyRegAlloc { LRI.constructLiveRanges(); } void colorIncomingArgs(); + void colorCallRetArgs(); void updateMachineCode(); + void printLabel(const Value *const Val); void printMachineCode(); diff --git a/lib/Target/SparcV9/RegAlloc/LiveRange.h b/lib/Target/SparcV9/RegAlloc/LiveRange.h index d8e130a329c..9c4d4508805 100644 --- a/lib/Target/SparcV9/RegAlloc/LiveRange.h +++ b/lib/Target/SparcV9/RegAlloc/LiveRange.h @@ -39,6 +39,9 @@ class LiveRange : public ValueSet // bool mustLoadFromStack; // must load from stack at start of method + + int SuggestedColor; // The suggested color for this LR + public: @@ -92,9 +95,27 @@ class LiveRange : public ValueSet } + inline void setSuggestedColor(int Col) { + //assert( (SuggestedColor == -1) && "Changing an already suggested color"); + + if(SuggestedColor == -1 ) + SuggestedColor = Col; + else if (DEBUG_RA) + cout << "Already has a suggested color " << Col << endl; + } + + inline unsigned getSuggestedColor() const { + assert( SuggestedColor != -1); // only a valid color is obtained + return (unsigned) SuggestedColor; + } + + inline bool hasSuggestedColor() const { + return ( SuggestedColor > -1); + } + inline LiveRange() : ValueSet() , CallInterferenceList() { - Color = -1; // not yet colored + Color = SuggestedColor = -1; // not yet colored mustSpill = mustSaveAcrossCalls = false; MyRegClass = NULL; UserIGNode = NULL; diff --git a/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.h b/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.h index da5601790a0..2a8eb2ffb6f 100644 --- a/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.h +++ b/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.h @@ -42,7 +42,7 @@ typedef hash_map LiveRangeMapType; - +typedef vector CallRetInstrListType; class LiveRangeInfo { @@ -56,7 +56,9 @@ private: const TargetMachine& TM; // target machine description vector & RegClassList;// a vector containing register classess + const MachineRegInfo& MRI; // machine reg info + CallRetInstrListType CallRetInstrList; // a list of all call/ret instrs void unionAndUpdateLRs(LiveRange *L1, LiveRange *L2); @@ -72,12 +74,22 @@ public: void constructLiveRanges(); + inline void addLRToMap(const Value *Val, LiveRange *LR) { + assert( Val && LR && "Val/LR is NULL!\n"); + assert( (! LiveRangeMap[ Val ]) && "LR already set in map"); + LiveRangeMap[ Val ] = LR; + } + + inline const LiveRangeMapType *const getLiveRangeMap() const { return &LiveRangeMap; } inline LiveRange *getLiveRangeForValue( const Value *const Val) { return LiveRangeMap[ Val ]; } + inline CallRetInstrListType &getCallRetInstrList() { + return CallRetInstrList; + } diff --git a/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h b/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h index fcf28320cc7..f96f27bdfbb 100644 --- a/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h +++ b/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h @@ -43,8 +43,8 @@ class AddedInstrns { public: - vector InstrnsBefore; - vector InstrnsAfter; + vector InstrnsBefore; + vector InstrnsAfter; AddedInstrns() : InstrnsBefore(), InstrnsAfter() { } }; @@ -65,8 +65,8 @@ class PhyRegAlloc const MachineRegInfo &MRI; // Machine Register information const unsigned NumOfRegClasses; // recorded here for efficiency - vector CallInstrList; // a list of all call instrs - vector RetInstrList; // a list of all return instrs + //vector CallInstrList; // a list of all call instrs + //vector RetInstrList; // a list of all return instrs AddedInstrMapType AddedInstrMap; // to store instrns added in this phase @@ -85,7 +85,9 @@ class PhyRegAlloc { LRI.constructLiveRanges(); } void colorIncomingArgs(); + void colorCallRetArgs(); void updateMachineCode(); + void printLabel(const Value *const Val); void printMachineCode(); diff --git a/lib/Target/SparcV9/SparcV9Internals.h b/lib/Target/SparcV9/SparcV9Internals.h index 172ae2d334a..2b51ebfb081 100644 --- a/lib/Target/SparcV9/SparcV9Internals.h +++ b/lib/Target/SparcV9/SparcV9Internals.h @@ -14,6 +14,7 @@ #include "llvm/Target/MachineInstrInfo.h" #include "llvm/Target/MachineSchedInfo.h" +#include "llvm/CodeGen/RegClass.h" #include "llvm/Type.h" #include @@ -95,6 +96,10 @@ public: return (opCode == FCMPS || opCode == FCMPD || opCode == FCMPQ); } + + + + }; @@ -109,6 +114,8 @@ class UltraSparcRegInfo : public MachineRegInfo private: + // The actual register classes in the Sparc + enum RegClassIDs { IntRegClassID, FloatRegClassID, @@ -116,6 +123,19 @@ class UltraSparcRegInfo : public MachineRegInfo FloatCCRegClassID }; + + // Type of registers available in Sparc. There can be several reg types + // in the same class. For instace, the float reg class has Single/Double + // types + enum RegTypes { + IntRegType, + FPSingleRegType, + FPDoubleRegType, + IntCCRegType, + FloatCCRegType + }; + + // WARNING: If the above enum order must be changed, also modify // getRegisterClassOfValue method below since it assumes this particular // order for efficiency. @@ -124,12 +144,11 @@ class UltraSparcRegInfo : public MachineRegInfo // reverse pointer to get info about the ultra sparc machine const UltraSparc *const UltraSparcInfo; - // Int arguments can be passed in 6 int regs - %o0 to %o5 (cannot be changed) + // Both int and float rguments can be passed in 6 int regs - + // %o0 to %o5 (cannot be changed) unsigned const NumOfIntArgRegs; - - // Float arguments can be passed in this many regs - can be canged if needed - // %f0 - %f5 are used (can hold 6 floats or 3 doubles) unsigned const NumOfFloatArgRegs; + unsigned const InvalidRegNum; //void setCallArgColor(LiveRange *const LR, const unsigned RegNo) const; @@ -139,20 +158,85 @@ class UltraSparcRegInfo : public MachineRegInfo MachineInstr * getCopy2RegMI(const Value *SrcVal, const unsigned Reg, unsigned RegClassID) const ; + Value *getValue4ReturnAddr( const MachineInstr * MInst ) const ; + + int getRegType(const LiveRange *const LR) const { + + unsigned Typ; + + switch( (LR->getRegClass())->getID() ) { + + case IntRegClassID: return IntRegType; + + case FloatRegClassID: + Typ = LR->getTypeID(); + if( Typ == Type::FloatTyID ) + return FPSingleRegType; + else if( Typ == Type::DoubleTyID ) + return FPDoubleRegType; + else assert(0 && "Unknown type in FloatRegClass"); + + case IntCCRegClassID: return IntCCRegType; + + case FloatCCRegClassID: return FloatCCRegType ; + + default: assert( 0 && "Unknown reg class ID"); + + } + + } + + int getRegType(const Value *const Val) const { + + unsigned Typ; + + switch( getRegClassIDOfValue(Val) ) { + + case IntRegClassID: return IntRegType; + + case FloatRegClassID: + Typ = (Val->getType())->getPrimitiveID(); + if( Typ == Type::FloatTyID ) + return FPSingleRegType; + else if( Typ == Type::DoubleTyID ) + return FPDoubleRegType; + else assert(0 && "Unknown type in FloatRegClass"); + + case IntCCRegClassID: return IntCCRegType; + + case FloatCCRegClassID: return FloatCCRegType ; + + default: assert( 0 && "Unknown reg class ID"); + + } + + } + + + + + MachineInstr * cpReg2RegMI(const unsigned SrcReg, const unsigned DestReg, + const int RegType) const; + + MachineInstr * cpValue2RegMI(Value * Val, const unsigned DestReg, + const int RegType) const; + + public: UltraSparcRegInfo(const UltraSparc *const USI ) : UltraSparcInfo(USI), NumOfIntArgRegs(6), - NumOfFloatArgRegs(6) + NumOfFloatArgRegs(32), + InvalidRegNum(1000) { MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) ); MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) ); MachineRegClassArr.push_back( new SparcIntCCRegClass(IntCCRegClassID) ); MachineRegClassArr.push_back( new SparcFloatCCRegClass(FloatCCRegClassID)); - assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 6 && - "6 Float regs are used for float arg passing"); + assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 32 && + "32 Float regs are used for float arg passing"); } // ***** TODO Delete @@ -172,7 +256,8 @@ class UltraSparcRegInfo : public MachineRegInfo unsigned res; - if( ty && ty <= Type::LongTyID || (ty == Type::PointerTyID) ) + if( (ty && ty <= Type::LongTyID) || (ty == Type::LabelTyID) || + (ty == Type::MethodTyID) || (ty == Type::PointerTyID) ) res = IntRegClassID; // sparc int reg (ty=0: void) else if( ty <= Type::DoubleTyID) res = FloatRegClassID; // sparc float reg class @@ -191,6 +276,7 @@ class UltraSparcRegInfo : public MachineRegInfo } // returns the register tha contains always zero + // this is the unified register number inline int getZeroRegNum() const { return SparcIntRegOrder::g0; } // returns the reg used for pushing the address when a method is called. @@ -202,18 +288,31 @@ class UltraSparcRegInfo : public MachineRegInfo // register contains the return value when a return instruction is reached. unsigned getReturnAddressReg() const { return SparcIntRegOrder::i7; } - void colorArgs(const Method *const Meth, LiveRangeInfo& LRI) const; + void suggestRegs4MethodArgs(const Method *const Meth, + LiveRangeInfo& LRI) const; - static void printReg(const LiveRange *const LR) ; + void suggestRegs4CallArgs(const CallInst *const CallI, + LiveRangeInfo& LRI, vector RCL) const; - void colorCallArgs(vector & CallInstrList, - LiveRangeInfo& LRI, - AddedInstrMapType& AddedInstrMap ) const; + void suggestReg4RetValue(const ReturnInst *const RetI, + LiveRangeInfo& LRI) const; - void colorRetArg(vector & - RetInstrList, LiveRangeInfo& LRI, - AddedInstrMapType &AddedInstrMap) const; + void colorMethodArgs(const Method *const Meth, LiveRangeInfo& LRI, + AddedInstrns *const FirstAI) const; + + void colorCallArgs(const CallInst *const CallI, LiveRangeInfo& LRI, + AddedInstrns *const CallAI) const; + + void colorRetValue(const ReturnInst *const RetI, LiveRangeInfo& LRI, + AddedInstrns *const RetAI) const; + + + bool handleSpecialMInstr(const MachineInstr * MInst, + LiveRangeInfo& LRI, vector RCL) const; + + + static void printReg(const LiveRange *const LR) ; // this method provides a unique number for each register inline int getUnifiedRegNum(int RegClassID, int reg) const { @@ -226,6 +325,8 @@ class UltraSparcRegInfo : public MachineRegInfo return reg + 32 + 64; // 32 int, 64 float else if( RegClassID == IntCCRegClassID ) return 4+ 32 + 64; // only int cc reg + else if (reg==1000) //****** TODO: Remove + return 1000; else assert(0 && "Invalid register class or reg number"); @@ -241,6 +342,9 @@ class UltraSparcRegInfo : public MachineRegInfo return SparcFloatCCRegOrder::getRegName( reg -32 - 64); else if ( reg == 64+32+4) return "xcc"; // only integer cc reg + + else if (reg==1000) //****** TODO: Remove + return "<*NoReg*>"; else assert(0 && "Invalid register number"); }