2070af7a7aaf9f37ef174162daea772ec4f42bea
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9TargetMachine.cpp
1 //***************************************************************************
2 // File:
3 //      Sparc.cpp
4 // 
5 // Purpose:
6 //      
7 // History:
8 //      7/15/01  -  Vikram Adve  -  Created
9 //**************************************************************************/
10
11 #include "llvm/Target/Sparc.h"
12 #include "SparcInternals.h"
13 #include "llvm/Method.h"
14 #include "llvm/CodeGen/InstrScheduling.h"
15 #include "llvm/CodeGen/InstrSelection.h"
16
17 #include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
18 #include "llvm/CodeGen/PhyRegAlloc.h"
19
20
21 // allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
22 // that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
23 //
24 TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
25
26
27 //---------------------------------------------------------------------------
28 // class UltraSparcInstrInfo 
29 // 
30 // Purpose:
31 //   Information about individual instructions.
32 //   Most information is stored in the SparcMachineInstrDesc array above.
33 //   Other information is computed on demand, and most such functions
34 //   default to member functions in base class MachineInstrInfo. 
35 //---------------------------------------------------------------------------
36
37 /*ctor*/
38 UltraSparcInstrInfo::UltraSparcInstrInfo()
39   : MachineInstrInfo(SparcMachineInstrDesc,
40                      /*descSize = */ NUM_TOTAL_OPCODES,
41                      /*numRealOpCodes = */ NUM_REAL_OPCODES)
42 {
43 }
44
45
46 //---------------------------------------------------------------------------
47 // class UltraSparcSchedInfo 
48 // 
49 // Purpose:
50 //   Scheduling information for the UltraSPARC.
51 //   Primarily just initializes machine-dependent parameters in
52 //   class MachineSchedInfo.
53 //---------------------------------------------------------------------------
54
55 /*ctor*/
56 UltraSparcSchedInfo::UltraSparcSchedInfo(const MachineInstrInfo* mii)
57   : MachineSchedInfo((unsigned int) SPARC_NUM_SCHED_CLASSES,
58                      mii,
59                      SparcRUsageDesc,
60                      SparcInstrUsageDeltas,
61                      SparcInstrIssueDeltas,
62                      sizeof(SparcInstrUsageDeltas)/sizeof(InstrRUsageDelta),
63                      sizeof(SparcInstrIssueDeltas)/sizeof(InstrIssueDelta))
64 {
65   maxNumIssueTotal = 4;
66   longestIssueConflict = 0;             // computed from issuesGaps[]
67   
68   branchMispredictPenalty = 4;          // 4 for SPARC IIi
69   branchTargetUnknownPenalty = 2;       // 2 for SPARC IIi
70   l1DCacheMissPenalty = 8;              // 7 or 9 for SPARC IIi
71   l1ICacheMissPenalty = 8;              // ? for SPARC IIi
72   
73   inOrderLoads = true;                  // true for SPARC IIi
74   inOrderIssue = true;                  // true for SPARC IIi
75   inOrderExec  = false;                 // false for most architectures
76   inOrderRetire= true;                  // true for most architectures
77   
78   // must be called after above parameters are initialized.
79   this->initializeResources();
80 }
81
82 void
83 UltraSparcSchedInfo::initializeResources()
84 {
85   // Compute MachineSchedInfo::instrRUsages and MachineSchedInfo::issueGaps
86   MachineSchedInfo::initializeResources();
87   
88   // Machine-dependent fixups go here.  None for now.
89 }
90
91
92
93 //---------------------------------------------------------------------------
94 // class UltraSparcRegInfo 
95 //
96 // Purpose:
97 //   This class provides info about sparc register classes.
98 //--------------------------------------------------------------------------
99
100 #if 0
101 UltraSparcRegInfo::UltraSparcRegInfo(const UltraSparc *const USI ) : 
102                                                       UltraSparcInfo(USI), 
103                                                       NumOfIntArgRegs(6), 
104                                                       NumOfFloatArgRegs(6) 
105   {    
106     MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
107     MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
108     MachineRegClassArr.push_back( new SparcIntCCRegClass(IntCCRegClassID) );
109     MachineRegClassArr.push_back( new SparcFloatCCRegClass(FloatCCRegClassID));
110
111     assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 6 && 
112             "6 Float regs are used for float arg passing");
113   }
114
115   // ***** TODO  insert deletes for reg classes 
116 UltraSparcRegInfo::~UltraSparcRegInfo(void) { }    // empty destructor 
117
118 #endif
119
120 //---------------------------------------------------------------------------
121 // UltraSparcRegInfo
122 // Purpose:
123 //   This method will color incoming args to a method. If there are more
124 //   args than that can fit in regs, code will be inserted to pop them from
125 //   stack
126 //---------------------------------------------------------------------------
127
128
129 void UltraSparcRegInfo::colorArgs(const Method *const Meth, 
130                                   LiveRangeInfo& LRI) const 
131 {
132
133                                                  // get the argument list
134   const Method::ArgumentListType& ArgList = Meth->getArgumentList();           
135                                                  // get an iterator to arg list
136   Method::ArgumentListType::const_iterator ArgIt = ArgList.begin(); 
137   unsigned intArgNo=0;
138
139   // to keep track of which float regs are allocated for argument passing
140   bool FloatArgUsedArr[NumOfFloatArgRegs];
141
142   // init float arg used array
143   for(unsigned i=0; i < NumOfFloatArgRegs; ++i) 
144     FloatArgUsedArr[i] = false;
145
146   // for each argument
147   for( ; ArgIt != ArgList.end() ; ++ArgIt) {    
148
149     // get the LR of arg
150     LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt); 
151     unsigned RegClassID = (LR->getRegClass())->getID();
152
153     // if the arg is in int class - allocate a reg for an int arg
154     if( RegClassID == IntRegClassID ) {
155
156       if( intArgNo < NumOfIntArgRegs) {
157         LR->setColor( SparcIntRegOrder::i0 + intArgNo );
158
159         if( DEBUG_RA) printReg( LR );
160       }
161   
162       else {
163         // TODO: Insert push code here
164         assert( 0 && "Insert push code here!");
165       }
166       ++intArgNo;
167     }
168
169     // if the arg is float/double 
170     else if ( RegClassID == FloatRegClassID) {
171
172       if( LR->getTypeID() == Type::DoubleTyID ) {
173
174         // find the first reg # we can pass a double arg
175         for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
176           if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
177             LR->setColor( SparcFloatRegOrder::f0 + i );
178             FloatArgUsedArr[i] = true;
179             FloatArgUsedArr[i+1] = true;
180             if( DEBUG_RA) printReg( LR );
181             break;
182           }
183         }
184         if( ! LR->hasColor() ) { // if LR was not colored above
185
186           assert(0 && "insert push code here for a double");
187
188         }
189
190       }
191       else if( LR->getTypeID() == Type::FloatTyID ) { 
192
193         // find the first reg # we can pass a float arg
194         for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
195           if ( !FloatArgUsedArr[i] ) {
196             LR->setColor( SparcFloatRegOrder::f0 + i );
197             FloatArgUsedArr[i] = true;
198             if( DEBUG_RA) printReg( LR );
199             break;
200           }
201         }
202         if( ! LR->hasColor() ) { // if LR was not colored above
203           assert(0 && "insert push code here for a float");
204         }
205
206       }
207       else 
208         assert(0 && "unknown float type in method arg");
209
210     } // float register class
211
212     else 
213       assert(0 && "Unknown RegClassID");
214   }
215   
216 }
217
218
219
220
221
222
223 void UltraSparcRegInfo::printReg(const LiveRange *const LR) {
224
225   unsigned RegClassID = (LR->getRegClass())->getID();
226
227   cout << " *Node " << (LR->getUserIGNode())->getIndex();
228
229   if( ! LR->hasColor() ) {
230     cout << " - could not find a color" << endl;
231     return;
232   }
233   
234   // if a color is found
235
236   cout << " colored with color "<< LR->getColor();
237
238   if( RegClassID == IntRegClassID ) {
239
240     cout<< " [" << SparcIntRegOrder::getRegName(LR->getColor()) ;
241     cout << "]" << endl;
242   }
243   else if ( RegClassID == FloatRegClassID) {
244     cout << "[" << SparcFloatRegOrder::getRegName(LR->getColor());
245     if( LR->getTypeID() == Type::DoubleTyID )
246       cout << "+" << SparcFloatRegOrder::getRegName(LR->getColor()+1);
247     cout << "]" << endl;
248   }
249
250
251 }
252
253
254 void UltraSparcRegInfo::colorCallArgs(vector<const Instruction *> & 
255                                       CallInstrList, LiveRangeInfo& LRI,
256                                       AddedInstrMapType &AddedInstrMap) const
257 {
258
259   vector<const Instruction *>::const_iterator InstIt = CallInstrList.begin();
260
261   for( ; InstIt != CallInstrList.end(); ++InstIt) {
262
263     // Inst = LLVM call instruction
264     const Instruction *const CallI = *InstIt;
265
266     MachineCodeForVMInstr &  MInstVec = CallI->getMachineInstrVec();
267     MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
268
269     // find the CALL/JMMPL machine instruction
270     for( ; MIIt != MInstVec.end() && 
271            ! getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode()); 
272          ++MIIt );
273
274     assert( (MIIt != MInstVec.end())  && "CALL/JMPL not found");
275
276     // CallMI = CALL/JMPL machine isntruction
277     const MachineInstr *const CallMI = *MIIt;
278
279     Instruction::op_const_iterator OpIt = CallI->op_begin();
280
281     unsigned intArgNo=0;
282     //unsigned NumOfCallInterfs = LR->getNumOfCallInterferences();
283
284     // to keep track of which float regs are allocated for argument passing
285     bool FloatArgUsedArr[NumOfFloatArgRegs];
286
287     // init float arg used array
288     for(unsigned i=0; i < NumOfFloatArgRegs; ++i) 
289       FloatArgUsedArr[i] = false;
290
291     // go thru all the operands of LLVM instruction
292     for( ; OpIt != CallI->op_end(); ++OpIt ) {
293
294       // get the LR of call operand (parameter)
295       LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt); 
296
297       if ( !LR ) {
298         cout << " Warning: In call instr, no LR for arg: " ;
299         printValue(*OpIt);
300         cout << endl;
301         continue;
302       }
303
304       unsigned RegClassID = (LR->getRegClass())->getID();
305       
306       // if the arg is in int class - allocate a reg for an int arg
307       if( RegClassID == IntRegClassID ) {
308         
309         if( intArgNo < NumOfIntArgRegs) {
310           setCallArgColor( LR, SparcIntRegOrder::o0 + intArgNo );
311         }
312         
313         else {
314           // TODO: Insert push code here
315           assert( 0 && "Insert push code here!");
316
317           AddedInstrns * AI = AddedInstrMap[ CallMI ];
318           if( ! AI ) AI = new AddedInstrns();
319
320           // AI->InstrnsBefore.push_back( getStackPushInstr(LR) );
321           AddedInstrMap[ CallMI ] = AI;
322           
323         }
324         ++intArgNo;
325       }
326       
327       // if the arg is float/double 
328       else if ( RegClassID == FloatRegClassID) {
329         
330         if( LR->getTypeID() == Type::DoubleTyID ) {
331           
332           // find the first reg # we can pass a double arg
333           for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
334             if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
335               setCallArgColor(LR, SparcFloatRegOrder::f0 + i );             
336               FloatArgUsedArr[i] = true;
337               FloatArgUsedArr[i+1] = true;
338               //if( DEBUG_RA) printReg( LR );
339               break;
340             }
341           }
342           if( ! LR->hasColor() ) { // if LR was not colored above
343             
344             assert(0 && "insert push code here for a double");
345             
346           }
347           
348         }
349         else if( LR->getTypeID() == Type::FloatTyID ) { 
350           
351           // find the first reg # we can pass a float arg
352           for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
353             if ( !FloatArgUsedArr[i] ) {
354               setCallArgColor(LR, SparcFloatRegOrder::f0 + i );
355               FloatArgUsedArr[i] = true;
356               // LR->setColor( SparcFloatRegOrder::f0 + i );
357               // if( DEBUG_RA) printReg( LR );
358               break;
359             }
360           }
361           if( ! LR->hasColor() ) { // if LR was not colored above
362             assert(0 && "insert push code here for a float");
363           }
364           
365         }
366         else 
367           assert(0 && "unknown float type in method arg");
368         
369       } // float register class
370       
371       else 
372         assert(0 && "Unknown RegClassID");
373
374
375     } // for each operand in a call instruction
376
377     
378
379
380   } // for all call instrctions in CallInstrList
381
382 }
383
384
385 void UltraSparcRegInfo::setCallArgColor(LiveRange *const LR, 
386                                         const unsigned RegNo) const {
387
388   // if no call interference and LR is NOT previously colored (e.g., as an 
389   // incoming arg)
390   if( ! LR->getNumOfCallInterferences() && ! LR->hasColor() ) { 
391     // we can directly allocate a %o register
392     LR->setColor( RegNo);
393     if( DEBUG_RA) printReg( LR );
394   }
395   else {                        // there are call interferences
396     
397     /* 
398     // insert a copy machine instr to copy from LR to %o(reg)
399     PreMInstrMap[ CallMI ] = 
400     getNewCopyMInstr( LR->,  SparcIntRegOrder::o0 + intArgNo );
401     */
402     cout << " $$$ TODO: Insert a copy for call argument!: " << endl;
403
404     // We don't color LR here. It's colored as any other normal LR
405   }
406
407 }
408
409
410
411
412
413 //---------------------------------------------------------------------------
414 // class UltraSparcMachine 
415 // 
416 // Purpose:
417 //   Primary interface to machine description for the UltraSPARC.
418 //   Primarily just initializes machine-dependent parameters in
419 //   class TargetMachine, and creates machine-dependent subclasses
420 //   for classes such as MachineInstrInfo. 
421 // 
422 //---------------------------------------------------------------------------
423
424 UltraSparc::UltraSparc() : TargetMachine("UltraSparc-Native"),
425                            InstSchedulingInfo(&InstInfo),
426                            RegInfo( this )  {
427   optSizeForSubWordData = 4;
428   minMemOpWordSize = 8; 
429   maxAtomicMemOpWordSize = 8;
430   zeroRegNum = 0;                       // %g0 always gives 0 on Sparc
431 }
432
433
434
435 //----------------------------------------------------------------------------
436 // Entry point for register allocation for a module
437 //----------------------------------------------------------------------------
438
439 void AllocateRegisters(Method *M, TargetMachine &TM)
440 {
441  
442   if ( (M)->isExternal() )     // don't process prototypes
443     return;
444     
445   if( DEBUG_RA ) {
446     cout << endl << "******************** Method "<< (M)->getName();
447     cout <<        " ********************" <<endl;
448   }
449     
450   MethodLiveVarInfo LVI(M );   // Analyze live varaibles
451   LVI.analyze();
452   
453     
454   PhyRegAlloc PRA(M, TM , &LVI); // allocate registers
455   PRA.allocateRegisters();
456     
457
458   if( DEBUG_RA )  cout << endl << "Register allocation complete!" << endl;
459
460 }
461
462
463
464
465
466 bool UltraSparc::compileMethod(Method *M) {
467   if (SelectInstructionsForMethod(M, *this)) {
468     cerr << "Instruction selection failed for method " << M->getName()
469        << "\n\n";
470     return true;
471   }
472   
473   if (ScheduleInstructionsWithSSA(M, *this, InstSchedulingInfo)) {
474     cerr << "Instruction scheduling before allocation failed for method "
475        << M->getName() << "\n\n";
476     return true;
477   }
478
479   AllocateRegisters(M, *this);    // allocate registers
480
481
482   return false;
483 }
484