2 //***************************************************************************
9 // 7/15/01 - Vikram Adve - Created
10 //**************************************************************************/
12 #include "llvm/Target/Sparc.h"
13 #include "SparcInternals.h"
14 #include "llvm/Method.h"
15 #include "llvm/CodeGen/InstrScheduling.h"
16 #include "llvm/CodeGen/InstrSelection.h"
18 #include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
19 #include "llvm/CodeGen/PhyRegAlloc.h"
22 //***************************** Internal Functions *************************/
24 //----------------------------------------------------------------------------
25 // allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
26 // that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
27 //----------------------------------------------------------------------------
29 TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
32 //----------------------------------------------------------------------------
33 // Entry point for register allocation for a module
34 //----------------------------------------------------------------------------
37 AllocateRegisters(Method *M, TargetMachine &TM)
40 if ( (M)->isExternal() ) // don't process prototypes
44 cout << endl << "******************** Method "<< (M)->getName();
45 cout << " ********************" <<endl;
48 MethodLiveVarInfo LVI(M ); // Analyze live varaibles
52 PhyRegAlloc PRA(M, TM , &LVI); // allocate registers
53 PRA.allocateRegisters();
56 if( DEBUG_RA ) cout << endl << "Register allocation complete!" << endl;
61 //***************************** External Classes **************************/
64 //---------------------------------------------------------------------------
65 // class UltraSparcInstrInfo
68 // Information about individual instructions.
69 // Most information is stored in the SparcMachineInstrDesc array above.
70 // Other information is computed on demand, and most such functions
71 // default to member functions in base class MachineInstrInfo.
72 //---------------------------------------------------------------------------
75 UltraSparcInstrInfo::UltraSparcInstrInfo()
76 : MachineInstrInfo(SparcMachineInstrDesc,
77 /*descSize = */ NUM_TOTAL_OPCODES,
78 /*numRealOpCodes = */ NUM_REAL_OPCODES)
83 //---------------------------------------------------------------------------
84 // class UltraSparcSchedInfo
87 // Scheduling information for the UltraSPARC.
88 // Primarily just initializes machine-dependent parameters in
89 // class MachineSchedInfo.
90 //---------------------------------------------------------------------------
93 UltraSparcSchedInfo::UltraSparcSchedInfo(const MachineInstrInfo* mii)
94 : MachineSchedInfo((unsigned int) SPARC_NUM_SCHED_CLASSES,
97 SparcInstrUsageDeltas,
98 SparcInstrIssueDeltas,
99 sizeof(SparcInstrUsageDeltas)/sizeof(InstrRUsageDelta),
100 sizeof(SparcInstrIssueDeltas)/sizeof(InstrIssueDelta))
102 maxNumIssueTotal = 4;
103 longestIssueConflict = 0; // computed from issuesGaps[]
105 branchMispredictPenalty = 4; // 4 for SPARC IIi
106 branchTargetUnknownPenalty = 2; // 2 for SPARC IIi
107 l1DCacheMissPenalty = 8; // 7 or 9 for SPARC IIi
108 l1ICacheMissPenalty = 8; // ? for SPARC IIi
110 inOrderLoads = true; // true for SPARC IIi
111 inOrderIssue = true; // true for SPARC IIi
112 inOrderExec = false; // false for most architectures
113 inOrderRetire= true; // true for most architectures
115 // must be called after above parameters are initialized.
116 this->initializeResources();
120 UltraSparcSchedInfo::initializeResources()
122 // Compute MachineSchedInfo::instrRUsages and MachineSchedInfo::issueGaps
123 MachineSchedInfo::initializeResources();
125 // Machine-dependent fixups go here. None for now.
132 //---------------------------------------------------------------------------
135 // This method will color incoming args to a method. If there are more
136 // args than that can fit in regs, code will be inserted to pop them from
138 //---------------------------------------------------------------------------
141 void UltraSparcRegInfo::colorArgs(const Method *const Meth,
142 LiveRangeInfo& LRI) const
145 // get the argument list
146 const Method::ArgumentListType& ArgList = Meth->getArgumentList();
147 // get an iterator to arg list
148 Method::ArgumentListType::const_iterator ArgIt = ArgList.begin();
151 // to keep track of which float regs are allocated for argument passing
152 bool FloatArgUsedArr[NumOfFloatArgRegs];
154 // init float arg used array
155 for(unsigned i=0; i < NumOfFloatArgRegs; ++i)
156 FloatArgUsedArr[i] = false;
159 for( ; ArgIt != ArgList.end() ; ++ArgIt) {
162 LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt);
163 unsigned RegClassID = (LR->getRegClass())->getID();
165 // if the arg is in int class - allocate a reg for an int arg
166 if( RegClassID == IntRegClassID ) {
168 if( intArgNo < NumOfIntArgRegs) {
169 LR->setColor( SparcIntRegOrder::i0 + intArgNo );
171 if( DEBUG_RA) printReg( LR );
175 // TODO: Insert push code here
176 assert( 0 && "Insert push code here!");
181 // if the arg is float/double
182 else if ( RegClassID == FloatRegClassID) {
184 if( LR->getTypeID() == Type::DoubleTyID ) {
186 // find the first reg # we can pass a double arg
187 for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
188 if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
189 LR->setColor( SparcFloatRegOrder::f0 + i );
190 FloatArgUsedArr[i] = true;
191 FloatArgUsedArr[i+1] = true;
192 if( DEBUG_RA) printReg( LR );
196 if( ! LR->hasColor() ) { // if LR was not colored above
198 assert(0 && "insert push code here for a double");
203 else if( LR->getTypeID() == Type::FloatTyID ) {
205 // find the first reg # we can pass a float arg
206 for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
207 if ( !FloatArgUsedArr[i] ) {
208 LR->setColor( SparcFloatRegOrder::f0 + i );
209 FloatArgUsedArr[i] = true;
210 if( DEBUG_RA) printReg( LR );
214 if( ! LR->hasColor() ) { // if LR was not colored above
215 assert(0 && "insert push code here for a float");
220 assert(0 && "unknown float type in method arg");
222 } // float register class
225 assert(0 && "Unknown RegClassID");
235 void UltraSparcRegInfo::printReg(const LiveRange *const LR) {
237 unsigned RegClassID = (LR->getRegClass())->getID();
239 cout << " *Node " << (LR->getUserIGNode())->getIndex();
241 if( ! LR->hasColor() ) {
242 cout << " - could not find a color" << endl;
246 // if a color is found
248 cout << " colored with color "<< LR->getColor();
250 if( RegClassID == IntRegClassID ) {
252 cout<< " [" << SparcIntRegOrder::getRegName(LR->getColor()) ;
255 else if ( RegClassID == FloatRegClassID) {
256 cout << "[" << SparcFloatRegOrder::getRegName(LR->getColor());
257 if( LR->getTypeID() == Type::DoubleTyID )
258 cout << "+" << SparcFloatRegOrder::getRegName(LR->getColor()+1);
266 void UltraSparcRegInfo::colorCallArgs(vector<const Instruction *> &
267 CallInstrList, LiveRangeInfo& LRI,
268 AddedInstrMapType &AddedInstrMap) const
271 vector<const Instruction *>::const_iterator InstIt = CallInstrList.begin();
273 for( ; InstIt != CallInstrList.end(); ++InstIt) {
275 // Inst = LLVM call instruction
276 const Instruction *const CallI = *InstIt;
278 MachineCodeForVMInstr & MInstVec = CallI->getMachineInstrVec();
279 MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
281 // find the CALL/JMMPL machine instruction
282 for( ; MIIt != MInstVec.end() &&
283 ! getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode());
286 assert( (MIIt != MInstVec.end()) && "CALL/JMPL not found");
288 // CallMI = CALL/JMPL machine isntruction
289 const MachineInstr *const CallMI = *MIIt;
291 Instruction::op_const_iterator OpIt = CallI->op_begin();
294 //unsigned NumOfCallInterfs = LR->getNumOfCallInterferences();
296 // to keep track of which float regs are allocated for argument passing
297 bool FloatArgUsedArr[NumOfFloatArgRegs];
299 // init float arg used array
300 for(unsigned i=0; i < NumOfFloatArgRegs; ++i)
301 FloatArgUsedArr[i] = false;
303 // go thru all the operands of LLVM instruction
304 for( ; OpIt != CallI->op_end(); ++OpIt ) {
306 // get the LR of call operand (parameter)
307 LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt);
310 cout << " Warning: In call instr, no LR for arg: " ;
316 unsigned RegClassID = (LR->getRegClass())->getID();
318 // if the arg is in int class - allocate a reg for an int arg
319 if( RegClassID == IntRegClassID ) {
321 if( intArgNo < NumOfIntArgRegs) {
322 setCallArgColor( LR, SparcIntRegOrder::o0 + intArgNo );
326 // TODO: Insert push code here
327 assert( 0 && "Insert push code here!");
329 AddedInstrns * AI = AddedInstrMap[ CallMI ];
330 if( ! AI ) AI = new AddedInstrns();
332 // AI->InstrnsBefore.push_back( getStackPushInstr(LR) );
333 AddedInstrMap[ CallMI ] = AI;
339 // if the arg is float/double
340 else if ( RegClassID == FloatRegClassID) {
342 if( LR->getTypeID() == Type::DoubleTyID ) {
344 // find the first reg # we can pass a double arg
345 for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
346 if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
347 setCallArgColor(LR, SparcFloatRegOrder::f0 + i );
348 FloatArgUsedArr[i] = true;
349 FloatArgUsedArr[i+1] = true;
350 //if( DEBUG_RA) printReg( LR );
354 if( ! LR->hasColor() ) { // if LR was not colored above
356 assert(0 && "insert push code here for a double");
361 else if( LR->getTypeID() == Type::FloatTyID ) {
363 // find the first reg # we can pass a float arg
364 for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
365 if ( !FloatArgUsedArr[i] ) {
366 setCallArgColor(LR, SparcFloatRegOrder::f0 + i );
367 FloatArgUsedArr[i] = true;
368 // LR->setColor( SparcFloatRegOrder::f0 + i );
369 // if( DEBUG_RA) printReg( LR );
373 if( ! LR->hasColor() ) { // if LR was not colored above
374 assert(0 && "insert push code here for a float");
379 assert(0 && "unknown float type in method arg");
381 } // float register class
384 assert(0 && "Unknown RegClassID");
387 } // for each operand in a call instruction
392 } // for all call instrctions in CallInstrList
397 void UltraSparcRegInfo::setCallArgColor(LiveRange *const LR,
398 const unsigned RegNo) const {
400 // if no call interference and LR is NOT previously colored (e.g., as an
402 if( ! LR->getNumOfCallInterferences() && ! LR->hasColor() ) {
403 // we can directly allocate a %o register
404 LR->setColor( RegNo);
405 if( DEBUG_RA) printReg( LR );
407 else { // there are call interferences
410 // insert a copy machine instr to copy from LR to %o(reg)
411 PreMInstrMap[ CallMI ] =
412 getNewCopyMInstr( LR->, SparcIntRegOrder::o0 + intArgNo );
414 cout << " $$$ TODO: Insert a copy for call argument!: " << endl;
416 // We don't color LR here. It's colored as any other normal LR
425 //---------------------------------------------------------------------------
426 // class UltraSparcMachine
429 // Primary interface to machine description for the UltraSPARC.
430 // Primarily just initializes machine-dependent parameters in
431 // class TargetMachine, and creates machine-dependent subclasses
432 // for classes such as MachineInstrInfo.
434 //---------------------------------------------------------------------------
436 UltraSparc::UltraSparc()
437 : TargetMachine("UltraSparc-Native"),
439 schedInfo(&instrInfo),
442 optSizeForSubWordData = 4;
443 minMemOpWordSize = 8;
444 maxAtomicMemOpWordSize = 8;
449 UltraSparc::compileMethod(Method *M)
451 if (SelectInstructionsForMethod(M, *this))
453 cerr << "Instruction selection failed for method " << M->getName()
458 if (ScheduleInstructionsWithSSA(M, *this))
460 cerr << "Instruction scheduling before allocation failed for method "
461 << M->getName() << "\n\n";
465 // if (AllocateRegisters(M, *this)) // allocate registers
467 // cerr << "Register allocation failed for method "
468 // << M->getName() << "\n\n";