Sparc.o \
Sparc.burm.o \
SparcInstrSelection.o \
+ SparcRegClassInfo.o \
SparcRegInfo.o
include $(LEVEL)/Makefile.common
#ifndef SPARC_INTERNALS_H
#define SPARC_INTERNALS_H
-#include "SparcRegInfo.h"
+
+#include "SparcRegClassInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/MachineInstrInfo.h"
+
#include "llvm/Target/MachineSchedInfo.h"
#include "llvm/Type.h"
};
-//---------------------------------------------------------------------------
-// class UltraSparcRegInfo
-//
-// Purpose:
-// This class provides info about sparc register classes.
-//---------------------------------------------------------------------------
class LiveRange;
class UltraSparc;
+
class UltraSparcRegInfo : public MachineRegInfo
{
// %f0 - %f5 are used (can hold 6 floats or 3 doubles)
unsigned const NumOfFloatArgRegs;
- void setCallArgColor(LiveRange *const LR, const unsigned RegNo) const;
+ //void setCallArgColor(LiveRange *const LR, const unsigned RegNo) const;
+
+ void setCallOrRetArgCol(LiveRange *const LR, const unsigned RegNo,
+ const MachineInstr *MI,AddedInstrMapType &AIMap)const;
+
+ MachineInstr * getCopy2RegMI(const Value *SrcVal, const unsigned Reg,
+ unsigned RegClassID) const ;
+
public:
- UltraSparcRegInfo(const UltraSparc *const USI )
- : MachineRegInfo(),
- UltraSparcInfo(USI),
- NumOfIntArgRegs(6),
- NumOfFloatArgRegs(6)
+ UltraSparcRegInfo(const UltraSparc *const USI ) : UltraSparcInfo(USI),
+ NumOfIntArgRegs(6),
+ NumOfFloatArgRegs(6)
{
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");
}
-
+
// ***** TODO Delete
~UltraSparcRegInfo(void) { } // empty destructor
return *UltraSparcInfo;
}
- // returns the register that is hardwired to zero
- virtual inline int getZeroRegNum() const {
- return (int) SparcIntRegOrder::g0;
- }
-
+
inline unsigned getRegClassIDOfValue (const Value *const Val,
bool isCCReg = false) const {
}
+ // returns the register tha contains always zero
+ inline int getZeroRegNum() const { return SparcIntRegOrder::g0; }
+
+ // returns the reg used for pushing the address when a method is called.
+ // This can be used for other purposes between calls
+ unsigned getCallAddressReg() const { return SparcIntRegOrder::o7; }
+
+
+ // and when we return from a method. It should be made sure that this
+ // 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;
static void printReg(const LiveRange *const LR) ;
LiveRangeInfo& LRI,
AddedInstrMapType& AddedInstrMap ) const;
+ void colorRetArg(vector<const Instruction *> &
+ RetInstrList, LiveRangeInfo& LRI,
+ AddedInstrMapType &AddedInstrMap) const;
+
+
// this method provides a unique number for each register
inline int getUnifiedRegNum(int RegClassID, int reg) const {
-
/*---------------------------------------------------------------------------
Scheduling guidelines for SPARC IIi:
--- /dev/null
+#include "llvm/CodeGen/IGNode.h"
+#include "SparcInternals.h"
+
+#include "llvm/Target/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() );
+ }
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/* Title: SparcRegClassInfo.h -*- C++ -*-
+ Author: Ruchira Sasanka
+ Date: Aug 20, 01
+ Purpose: Contains the description of integer register class of Sparc
+*/
+
+
+#ifndef SPARC_REG_INFO_CLASS_H
+#define SPARC_REG_INFO_CLASS_H
+
+#include "llvm/Target/MachineRegInfo.h"
+#include "llvm/CodeGen/IGNode.h"
+
+//-----------------------------------------------------------------------------
+// Integer Register Class
+//-----------------------------------------------------------------------------
+
+
+// Int register names in same order as enum in class SparcIntRegOrder
+
+static string const IntRegNames[] =
+ { "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5",
+ "g0", "i6", "i7", "o6" };
+
+
+
+class SparcIntRegOrder{
+
+ public:
+
+ enum RegsInPrefOrder // colors possible for a LR (in preferred order)
+ {
+ // --- following colors are volatile across function calls
+ // %g0 can't be used for coloring - always 0
+
+ g1, g2, g3, g4, g5, g6, g7, //%g1-%g7
+ o0, o1, o2, o3, o4, o5, o7, // %o0-%o5,
+
+ // %o6 is sp,
+ // all %0's can get modified by a call
+
+ // --- following colors are NON-volatile across function calls
+
+ l0, l1, l2, l3, l4, l5, l6, l7, // %l0-%l7
+ i0, i1, i2, i3, i4, i5, // %i0-%i5: i's need not be preserved
+
+ // %i6 is the fp - so not allocated
+ // %i7 is the ret address - can be used if saved
+
+ // max # of colors reg coloring can allocate (NumOfAvailRegs)
+
+ // --- following colors are not available for allocation within this phase
+ // --- but can appear for pre-colored ranges
+
+ g0, i6, i7, o6
+
+
+
+ };
+
+ // max # of colors reg coloring can allocate
+ static unsigned int const NumOfAvailRegs = g0;
+
+ static unsigned int const StartOfNonVolatileRegs = l0;
+ static unsigned int const StartOfAllRegs = g1;
+ static unsigned int const NumOfAllRegs = o6 + 1;
+
+
+ static const string getRegName(const unsigned reg) {
+ assert( reg < NumOfAllRegs );
+ return IntRegNames[reg];
+ }
+
+};
+
+
+
+class SparcIntRegClass : public MachineRegClassInfo
+{
+ public:
+
+ SparcIntRegClass(unsigned ID)
+ : MachineRegClassInfo(ID,
+ SparcIntRegOrder::NumOfAvailRegs,
+ SparcIntRegOrder::NumOfAllRegs)
+ { }
+
+ void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const;
+
+};
+
+//-----------------------------------------------------------------------------
+// Float Register Class
+//-----------------------------------------------------------------------------
+
+static string const FloatRegNames[] =
+ {
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9",
+ "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19",
+ "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29",
+ "f30", "f31", "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
+ "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", "f48", "f49",
+ "f50", "f51", "f52", "f53", "f54", "f55", "f56", "f57", "f58", "f59",
+ "f60", "f61", "f62", "f63"
+ };
+
+
+class SparcFloatRegOrder{
+
+ public:
+
+ enum RegsInPrefOrder {
+
+ f0, f1, f2, f3, f4, f5, f6, f7, f8, f9,
+ f10, f11, f12, f13, f14, f15, f16, f17, f18, f19,
+ f20, f21, f22, f23, f24, f25, f26, f27, f28, f29,
+ f30, f31, f32, f33, f34, f35, f36, f37, f38, f39,
+ f40, f41, f42, f43, f44, f45, f46, f47, f48, f49,
+ f50, f51, f52, f53, f54, f55, f56, f57, f58, f59,
+ f60, f61, f62, f63
+
+ };
+
+ // there are 64 regs alltogether but only 32 regs can be allocated at
+ // a time.
+
+ static unsigned int const NumOfAvailRegs = 32;
+ static unsigned int const NumOfAllRegs = 64;
+
+ static unsigned int const StartOfNonVolatileRegs = f6;
+ static unsigned int const StartOfAllRegs = f0;
+
+
+ static const string getRegName(const unsigned reg) {
+ assert( reg < NumOfAllRegs );
+ return FloatRegNames[reg];
+ }
+
+
+
+};
+
+
+
+class SparcFloatRegClass : public MachineRegClassInfo
+{
+ private:
+
+ int findFloatColor(const IGNode *const Node, unsigned Start,
+ unsigned End, bool IsColorUsedArr[] ) const;
+
+ public:
+
+ SparcFloatRegClass(unsigned ID)
+ : MachineRegClassInfo(ID,
+ SparcFloatRegOrder::NumOfAvailRegs,
+ SparcFloatRegOrder::NumOfAllRegs)
+ { }
+
+ void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const;
+
+};
+
+
+
+
+//-----------------------------------------------------------------------------
+// Int CC Register Class
+// Only one integer cc register is available
+//-----------------------------------------------------------------------------
+
+
+class SparcIntCCRegClass : public MachineRegClassInfo
+{
+public:
+
+ SparcIntCCRegClass(unsigned ID)
+ : MachineRegClassInfo(ID,1, 1) { }
+
+ inline void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const {
+ Node->setColor(0); // only one int cc reg is available
+ }
+
+};
+
+
+
+//-----------------------------------------------------------------------------
+// Float CC Register Class
+// Only 4 Float CC registers are available
+//-----------------------------------------------------------------------------
+
+
+static string const FloatCCRegNames[] =
+ {
+ "fcc0", "fcc1", "fcc2", "fcc3"
+ };
+
+
+class SparcFloatCCRegOrder{
+
+ public:
+
+ enum RegsInPrefOrder {
+
+ fcc0, fcc1, fcc2, fcc3
+ };
+
+ static const string getRegName(const unsigned reg) {
+ assert( reg < 4 );
+ return FloatCCRegNames[reg];
+ }
+
+};
+
+
+
+class SparcFloatCCRegClass : public MachineRegClassInfo
+{
+public:
+
+ SparcFloatCCRegClass(unsigned ID)
+ : MachineRegClassInfo(ID, 4, 4) { }
+
+ void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const {
+ int c;
+ for(c=0; c < 4 && IsColorUsedArr[c] ; ++c) ; // find color
+ assert( (c < 4) && "Can allocate only 4 float cc registers");
+ Node->setColor(c);
+ }
+
+};
+
+
+
+
+#endif
-#include "llvm/CodeGen/IGNode.h"
-#include "SparcRegInfo.h"
+#include "llvm/Target/Sparc.h"
#include "SparcInternals.h"
+#include "llvm/Method.h"
+#include "llvm/iTerminators.h"
+#include "llvm/CodeGen/InstrScheduling.h"
+#include "llvm/CodeGen/InstrSelection.h"
-#include "llvm/Target/Sparc.h"
+#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
+#include "llvm/CodeGen/PhyRegAlloc.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.
+//---------------------------------------------------------------------------
+// UltraSparcRegInfo
+//---------------------------------------------------------------------------
- */
+/*
+Rules for coloring values with sepcial registers:
+=================================================
- unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
+The following are the cases we color values with special regs:
- 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
- }
- }
+1) Incoming Method Arguements
+2) Outgoing Call Arguments
+3) Return Value of a call
+4) Return Value of a return statement
+Both 1 and 3 are defs. Therefore, they can be set directly. For case 1,
+incoming args are colored to %i0-%i5 and %f0 - %fx. For case 3, the return
+value of the call must be colored to %o0 or %f0.
+For case 2 we can use %o0-%o6 and %f0- %fx and for case 4 we can use %i0 or
+%f0. However, we cannot pre-color them directly to those regs
+if there are call interferences or they can be already colred by case 1.
+(Note that a return value is call is already colored and it is registered
+as a call interference as well if it is live after the call). Otherwise, they
+can be precolored. In cases where we cannot precolor, we just have to insert
+a copy instruction to copy the LR to the required register.
- 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; }
- }
+//---------------------------------------------------------------------------
+// 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
+//---------------------------------------------------------------------------
- if( ColorFound)
- Node->setColor(c); // first color found in preffered order
+void UltraSparcRegInfo::colorArgs(const Method *const Meth,
+ LiveRangeInfo& LRI) const
+{
- // 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;
+ // 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;
- // find first unused volatile color
- for(c=SearchStart; c < SparcIntRegOrder::StartOfNonVolatileRegs; c++) {
- if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
- }
+ // to keep track of which float regs are allocated for argument passing
+ bool FloatArgUsedArr[NumOfFloatArgRegs];
- if( ColorFound) {
- Node->setColor(c);
- // since LR span across calls, must save across calls
- Node->markForSaveAcrossCalls();
+ // 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");
}
+
+}
- // 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() );
-}
+void UltraSparcRegInfo::colorCallArgs(vector<const Instruction *> &
+ CallInstrList, LiveRangeInfo& LRI,
+ AddedInstrMapType &AddedInstrMap) const
+{
+ vector<const Instruction *>::const_iterator InstIt;
+ // First color the return value of all call instructions. The return value
+ // will be in %o0 if the value is an integer type, or in %f0 if the
+ // value is a float type.
+ for(InstIt=CallInstrList.begin(); InstIt != CallInstrList.end(); ++InstIt) {
-//-----------------------------------------------------------------------------
-// Float Register Class
-//-----------------------------------------------------------------------------
+ const Instruction *const CallI = *InstIt;
-// find the first available color in the range [Start,End] depending on the
-// type of the Node (i.e., float/double)
+ // get the live range of return value of this call
+ LiveRange *const LR = LRI.getLiveRangeForValue( CallI );
-int SparcFloatRegClass::findFloatColor(const IGNode *const Node, unsigned Start,
- unsigned End,
- bool IsColorUsedArr[] ) const
-{
+ if ( LR ) {
- bool ColorFound = false;
- unsigned c;
+ // Since the call is a def, it cannot be colored by some other instr.
+ // Therefore, we can definitely set a color here.
+ // However, this def can be used by some other instr like another call
+ // or return which places that in a special register. In that case
+ // it has to put a copy. Note that, the def will have a call interference
+ // with this call instr itself if it is live after this call.
- if( Node->getTypeID() == Type::DoubleTyID ) {
+ assert( ! LR->hasColor() && "Can't have a color since this is a def");
+
+ unsigned RegClassID = (LR->getRegClass())->getID();
- // find first unused color for a double
- for( c=Start; c < End ;c+= 2){
- if( ! IsColorUsedArr[ c ] && ! IsColorUsedArr[ c+1 ])
- { ColorFound=true; break; }
+ if( RegClassID == IntRegClassID ) {
+ LR->setColor(SparcIntRegOrder::o0);
+ }
+ else if (RegClassID == FloatRegClassID ) {
+ LR->setColor(SparcFloatRegOrder::f0 );
+ }
}
-
- } else {
-
- // find first unused color for a single
- for( c=Start; c < End; c++) {
- if( ! IsColorUsedArr[ c ] ) { ColorFound=true; break; }
+ else {
+ cout << "Warning: No Live Range for return value of CALL" << endl;
}
}
-
- if( ColorFound ) return c;
- else return -1;
+
+
+ for( InstIt=CallInstrList.begin(); InstIt != CallInstrList.end(); ++InstIt) {
+
+ // Inst = LLVM call instruction
+ const Instruction *const CallI = *InstIt;
+
+ // find the CALL/JMMPL machine instruction
+ MachineCodeForVMInstr & MInstVec = CallI->getMachineInstrVec();
+ MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
+
+ /*
+ for( ; MIIt != MInstVec.end() &&
+ ! getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode());
+ ++MIIt );
+
+ assert( (MIIt != MInstVec.end()) && "CALL/JMPL not found");
+ */
+
+ assert(getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode()) &&
+ "First machine instruction is not a Call/JMPL Machine Instr");
+
+ // CallMI = CALL/JMPL machine isntruction
+ const MachineInstr *const CallMI = *MIIt;
+
+ Instruction::op_const_iterator OpIt = CallI->op_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;
+
+ // 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) {
+ setCallOrRetArgCol( LR, SparcIntRegOrder::o0 + intArgNo,
+ CallMI, AddedInstrMap);
+ }
+
+ else {
+ // TODO: Insert push code here
+ assert( 0 && "Insert push code here!");
+
+ AddedInstrns * AI = AddedInstrMap[ CallMI ];
+ if( ! AI ) AI = new AddedInstrns();
+
+ // AI->InstrnsBefore.push_back( getStackPushInstr(LR) );
+ AddedInstrMap[ CallMI ] = AI;
+
+ }
+ ++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] ) {
+ setCallOrRetArgCol(LR, SparcFloatRegOrder::f0 + i,
+ CallMI, AddedInstrMap);
+ 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] ) {
+ setCallOrRetArgCol(LR, SparcFloatRegOrder::f0 + i,
+ CallMI, AddedInstrMap);
+ 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 SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
+void UltraSparcRegInfo::colorRetArg(vector<const Instruction *> &
+ RetInstrList, LiveRangeInfo& LRI,
+ AddedInstrMapType &AddedInstrMap) const
{
- /* Algorithm:
+ vector<const Instruction *>::const_iterator InstIt;
- 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
- */
+ for(InstIt=RetInstrList.begin(); InstIt != RetInstrList.end(); ++InstIt) {
- unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
+ const ReturnInst *const RetI = (ReturnInst *) *InstIt;
- 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;
- }
- }
+ // get the return value of this return instruction
+ const Value *RetVal = (RetI)->getReturnValue();
- int ColorFound = -1; // have we found a color yet?
- unsigned NumOfCallInterf = Node->getNumOfCallInterferences();
+ if( RetVal ) {
- // if value is a double - search the double only reigon (f32 - f63)
- if( Node->getTypeID() == Type::DoubleTyID )
- ColorFound = findFloatColor( Node, 32, 64, IsColorUsedArr );
-
+ // find the CALL/JMMPL machine instruction
+ MachineCodeForVMInstr & MInstVec = RetI->getMachineInstrVec();
+ MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
- if( ColorFound >= 0 ) {
- Node->setColor(ColorFound);
- if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
- return;
- }
+ assert(getUltraSparcInfo().getInstrInfo().isReturn((*MIIt)->getOpCode())
+ && "First machine instruction is not a RET Machine Instr");
+ // RET machine isntruction
+ const MachineInstr *const RetMI = *MIIt;
- else { // the above fails or LR is single precision
+ LiveRange *const LR = LRI.getLiveRangeForValue( RetVal );
+ unsigned RegClassID = (LR->getRegClass())->getID();
- unsigned SearchStart; // start pos of color in pref-order
+ if ( LR ) {
+ if( RegClassID == IntRegClassID ) {
+ setCallOrRetArgCol( LR, SparcIntRegOrder::i0, RetMI, AddedInstrMap);
+ }
+ else if (RegClassID==FloatRegClassID ) {
+ setCallOrRetArgCol(LR, SparcFloatRegOrder::f0, RetMI, AddedInstrMap);
+ }
+
+ }
+ else {
+ cout << "Warning: No LR for return value" << endl;
+ }
- //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);
- }
+void UltraSparcRegInfo::setCallOrRetArgCol(LiveRange *const LR,
+ const unsigned RegNo,
+ const MachineInstr *MI,
+ AddedInstrMapType &AIMap) const {
- if( ColorFound >= 0 ) {
- Node->setColor(ColorFound); // first color found in preffered order
- Node->markForSaveAcrossCalls();
- if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
- return;
+ // 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 (e.g., live across a call or produced
+ // by a call instr) or this LR is already colored as an incoming argument
+
+ MachineInstr *MI = getCopy2RegMI((*(LR->begin())), RegNo,
+ (LR->getRegClass())->getID());
- else {
- Node->markForSpill(); // no color found - must spill
- if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
+ AddedInstrns * AI = AIMap[ MI ]; // get already added instrns for MI
+ if( ! AI ) AI = new AddedInstrns();
+
+ AI->InstrnsBefore.push_back( MI ); // add the new MI yp AMI
+ AIMap[ MI ] = AI;
+
+
+ cout << "Inserted a copy instr for a RET/CALL instr " << endl;
+
+ // We don't color LR here. It's colored as any other normal LR or
+ // as an incoming arg or a return value of a call.
}
-
}
+// Generates a copy machine instruction to copy a value to a given
+// register.
+MachineInstr * UltraSparcRegInfo::getCopy2RegMI(const Value *SrcVal,
+ const unsigned Reg,
+ unsigned RegClassID) const {
+ MachineInstr * MI;
+ if( RegClassID == IntRegClassID ) { // if integer move
+ MI = new MachineInstr(ADD, 3);
+
+ MI->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, SrcVal);
+ MI->SetMachineOperand(1, SparcIntRegOrder::g0, false);
+ MI->SetMachineOperand(2, Reg, true);
+ }
+ else { // if FP move
+ if(SrcVal->getType()-> getPrimitiveID() == Type::FloatTyID )
+ MI = new MachineInstr(FMOVS, 2);
+ else if(SrcVal->getType()-> getPrimitiveID() == Type::DoubleTyID)
+ MI = new MachineInstr(FMOVD, 2);
+ else assert( 0 && "Unknown Type");
+ MI->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, SrcVal);
+ MI->SetMachineOperand(1, Reg, true);
+ }
+ return MI;
+}
+
+
+//---------------------------------------------------------------------------
+// Print the register assigned to a LR
+//---------------------------------------------------------------------------
+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;
+ }
+}
TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
+
//----------------------------------------------------------------------------
// Entry point for register allocation for a module
//----------------------------------------------------------------------------
-bool
-AllocateRegisters(Method *M, TargetMachine &TM)
+void AllocateRegisters(Method *M, TargetMachine &TM)
{
if ( (M)->isExternal() ) // don't process prototypes
- return false;
+ return;
if( DEBUG_RA ) {
cout << endl << "******************** Method "<< (M)->getName();
if( DEBUG_RA ) cout << endl << "Register allocation complete!" << endl;
- return false;
}
+
+
+
//***************************** External Classes **************************/
-
-//---------------------------------------------------------------------------
-// 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,
- AddedInstrMapType &AddedInstrMap) 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!");
-
- AddedInstrns * AI = AddedInstrMap[ CallMI ];
- if( ! AI ) AI = new AddedInstrns();
-
- // AI->InstrnsBefore.push_back( getStackPushInstr(LR) );
- AddedInstrMap[ CallMI ] = AI;
-
- }
- ++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 UltraSparcMachine
//
}
-bool
-UltraSparc::compileMethod(Method *M)
-{
+
+
+
+bool UltraSparc::compileMethod(Method *M) {
+
if (SelectInstructionsForMethod(M, *this))
{
cerr << "Instruction selection failed for method " << M->getName()
return true;
}
- // if (AllocateRegisters(M, *this)) // allocate registers
- // {
- // cerr << "Register allocation failed for method "
- // << M->getName() << "\n\n";
- // return true;
- // }
-
+ AllocateRegisters(M, *this); // allocate registers
+
+
return false;
}
+
+