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