3e9998004df5dddd17a1069afc5739bbe5f180ec
[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
95 //---------------------------------------------------------------------------
96 // UltraSparcRegInfo
97 // Purpose:
98 //   This method will color incoming args to a method. If there are more
99 //   args than that can fit in regs, code will be inserted to pop them from
100 //   stack
101 //---------------------------------------------------------------------------
102
103
104 void UltraSparcRegInfo::colorArgs(const Method *const Meth, 
105                                   LiveRangeInfo& LRI) const 
106 {
107
108                                                  // get the argument list
109   const Method::ArgumentListType& ArgList = Meth->getArgumentList();           
110                                                  // get an iterator to arg list
111   Method::ArgumentListType::const_iterator ArgIt = ArgList.begin(); 
112   unsigned intArgNo=0;
113
114   // to keep track of which float regs are allocated for argument passing
115   bool FloatArgUsedArr[NumOfFloatArgRegs];
116
117   // init float arg used array
118   for(unsigned i=0; i < NumOfFloatArgRegs; ++i) 
119     FloatArgUsedArr[i] = false;
120
121   // for each argument
122   for( ; ArgIt != ArgList.end() ; ++ArgIt) {    
123
124     // get the LR of arg
125     LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt); 
126     unsigned RegClassID = (LR->getRegClass())->getID();
127
128     // if the arg is in int class - allocate a reg for an int arg
129     if( RegClassID == IntRegClassID ) {
130
131       if( intArgNo < NumOfIntArgRegs) {
132         LR->setColor( SparcIntRegOrder::i0 + intArgNo );
133
134         if( DEBUG_RA) printReg( LR );
135       }
136   
137       else {
138         // TODO: Insert push code here
139         assert( 0 && "Insert push code here!");
140       }
141       ++intArgNo;
142     }
143
144     // if the arg is float/double 
145     else if ( RegClassID == FloatRegClassID) {
146
147       if( LR->getTypeID() == Type::DoubleTyID ) {
148
149         // find the first reg # we can pass a double arg
150         for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
151           if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
152             LR->setColor( SparcFloatRegOrder::f0 + i );
153             FloatArgUsedArr[i] = true;
154             FloatArgUsedArr[i+1] = true;
155             if( DEBUG_RA) printReg( LR );
156             break;
157           }
158         }
159         if( ! LR->hasColor() ) { // if LR was not colored above
160
161           assert(0 && "insert push code here for a double");
162
163         }
164
165       }
166       else if( LR->getTypeID() == Type::FloatTyID ) { 
167
168         // find the first reg # we can pass a float arg
169         for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
170           if ( !FloatArgUsedArr[i] ) {
171             LR->setColor( SparcFloatRegOrder::f0 + i );
172             FloatArgUsedArr[i] = true;
173             if( DEBUG_RA) printReg( LR );
174             break;
175           }
176         }
177         if( ! LR->hasColor() ) { // if LR was not colored above
178           assert(0 && "insert push code here for a float");
179         }
180
181       }
182       else 
183         assert(0 && "unknown float type in method arg");
184
185     } // float register class
186
187     else 
188       assert(0 && "Unknown RegClassID");
189   }
190   
191 }
192
193
194
195
196
197
198 void UltraSparcRegInfo::printReg(const LiveRange *const LR) {
199
200   unsigned RegClassID = (LR->getRegClass())->getID();
201
202   cout << " *Node " << (LR->getUserIGNode())->getIndex();
203
204   if( ! LR->hasColor() ) {
205     cout << " - could not find a color" << endl;
206     return;
207   }
208   
209   // if a color is found
210
211   cout << " colored with color "<< LR->getColor();
212
213   if( RegClassID == IntRegClassID ) {
214
215     cout<< " [" << SparcIntRegOrder::getRegName(LR->getColor()) ;
216     cout << "]" << endl;
217   }
218   else if ( RegClassID == FloatRegClassID) {
219     cout << "[" << SparcFloatRegOrder::getRegName(LR->getColor());
220     if( LR->getTypeID() == Type::DoubleTyID )
221       cout << "+" << SparcFloatRegOrder::getRegName(LR->getColor()+1);
222     cout << "]" << endl;
223   }
224
225
226 }
227
228
229 void UltraSparcRegInfo::colorCallArgs(vector<const Instruction *> & 
230                                       CallInstrList, LiveRangeInfo& LRI,
231                                       AddedInstrMapType &AddedInstrMap) const
232 {
233
234   vector<const Instruction *>::const_iterator InstIt = CallInstrList.begin();
235
236   for( ; InstIt != CallInstrList.end(); ++InstIt) {
237
238     // Inst = LLVM call instruction
239     const Instruction *const CallI = *InstIt;
240
241     MachineCodeForVMInstr &  MInstVec = CallI->getMachineInstrVec();
242     MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
243
244     // find the CALL/JMMPL machine instruction
245     for( ; MIIt != MInstVec.end() && 
246            ! getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode()); 
247          ++MIIt );
248
249     assert( (MIIt != MInstVec.end())  && "CALL/JMPL not found");
250
251     // CallMI = CALL/JMPL machine isntruction
252     const MachineInstr *const CallMI = *MIIt;
253
254     Instruction::op_const_iterator OpIt = CallI->op_begin();
255
256     unsigned intArgNo=0;
257     //unsigned NumOfCallInterfs = LR->getNumOfCallInterferences();
258
259     // to keep track of which float regs are allocated for argument passing
260     bool FloatArgUsedArr[NumOfFloatArgRegs];
261
262     // init float arg used array
263     for(unsigned i=0; i < NumOfFloatArgRegs; ++i) 
264       FloatArgUsedArr[i] = false;
265
266     // go thru all the operands of LLVM instruction
267     for( ; OpIt != CallI->op_end(); ++OpIt ) {
268
269       // get the LR of call operand (parameter)
270       LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt); 
271
272       if ( !LR ) {
273         cout << " Warning: In call instr, no LR for arg: " ;
274         printValue(*OpIt);
275         cout << endl;
276         continue;
277       }
278
279       unsigned RegClassID = (LR->getRegClass())->getID();
280       
281       // if the arg is in int class - allocate a reg for an int arg
282       if( RegClassID == IntRegClassID ) {
283         
284         if( intArgNo < NumOfIntArgRegs) {
285           setCallArgColor( LR, SparcIntRegOrder::o0 + intArgNo );
286         }
287         
288         else {
289           // TODO: Insert push code here
290           assert( 0 && "Insert push code here!");
291
292           AddedInstrns * AI = AddedInstrMap[ CallMI ];
293           if( ! AI ) AI = new AddedInstrns();
294
295           // AI->InstrnsBefore.push_back( getStackPushInstr(LR) );
296           AddedInstrMap[ CallMI ] = AI;
297           
298         }
299         ++intArgNo;
300       }
301       
302       // if the arg is float/double 
303       else if ( RegClassID == FloatRegClassID) {
304         
305         if( LR->getTypeID() == Type::DoubleTyID ) {
306           
307           // find the first reg # we can pass a double arg
308           for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
309             if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
310               setCallArgColor(LR, SparcFloatRegOrder::f0 + i );             
311               FloatArgUsedArr[i] = true;
312               FloatArgUsedArr[i+1] = true;
313               //if( DEBUG_RA) printReg( LR );
314               break;
315             }
316           }
317           if( ! LR->hasColor() ) { // if LR was not colored above
318             
319             assert(0 && "insert push code here for a double");
320             
321           }
322           
323         }
324         else if( LR->getTypeID() == Type::FloatTyID ) { 
325           
326           // find the first reg # we can pass a float arg
327           for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
328             if ( !FloatArgUsedArr[i] ) {
329               setCallArgColor(LR, SparcFloatRegOrder::f0 + i );
330               FloatArgUsedArr[i] = true;
331               // LR->setColor( SparcFloatRegOrder::f0 + i );
332               // if( DEBUG_RA) printReg( LR );
333               break;
334             }
335           }
336           if( ! LR->hasColor() ) { // if LR was not colored above
337             assert(0 && "insert push code here for a float");
338           }
339           
340         }
341         else 
342           assert(0 && "unknown float type in method arg");
343         
344       } // float register class
345       
346       else 
347         assert(0 && "Unknown RegClassID");
348
349
350     } // for each operand in a call instruction
351
352     
353
354
355   } // for all call instrctions in CallInstrList
356
357 }
358
359
360 void UltraSparcRegInfo::setCallArgColor(LiveRange *const LR, 
361                                         const unsigned RegNo) const {
362
363   // if no call interference and LR is NOT previously colored (e.g., as an 
364   // incoming arg)
365   if( ! LR->getNumOfCallInterferences() && ! LR->hasColor() ) { 
366     // we can directly allocate a %o register
367     LR->setColor( RegNo);
368     if( DEBUG_RA) printReg( LR );
369   }
370   else {                        // there are call interferences
371     
372     /* 
373     // insert a copy machine instr to copy from LR to %o(reg)
374     PreMInstrMap[ CallMI ] = 
375     getNewCopyMInstr( LR->,  SparcIntRegOrder::o0 + intArgNo );
376     */
377     cout << " $$$ TODO: Insert a copy for call argument!: " << endl;
378
379     // We don't color LR here. It's colored as any other normal LR
380   }
381
382 }
383
384
385
386
387
388 //---------------------------------------------------------------------------
389 // class UltraSparcMachine 
390 // 
391 // Purpose:
392 //   Primary interface to machine description for the UltraSPARC.
393 //   Primarily just initializes machine-dependent parameters in
394 //   class TargetMachine, and creates machine-dependent subclasses
395 //   for classes such as MachineInstrInfo. 
396 // 
397 //---------------------------------------------------------------------------
398
399 UltraSparc::UltraSparc() : TargetMachine("UltraSparc-Native"),
400                            InstSchedulingInfo(&InstInfo),
401                            RegInfo( this )  {
402   optSizeForSubWordData = 4;
403   minMemOpWordSize = 8; 
404   maxAtomicMemOpWordSize = 8;
405   zeroRegNum = RegInfo.getZeroReg();       // %g0 always gives 0 on Sparc
406 }
407
408
409
410 //----------------------------------------------------------------------------
411 // Entry point for register allocation for a module
412 //----------------------------------------------------------------------------
413
414 void AllocateRegisters(Method *M, TargetMachine &TM)
415 {
416  
417   if ( (M)->isExternal() )     // don't process prototypes
418     return;
419     
420   if( DEBUG_RA ) {
421     cout << endl << "******************** Method "<< (M)->getName();
422     cout <<        " ********************" <<endl;
423   }
424     
425   MethodLiveVarInfo LVI(M );   // Analyze live varaibles
426   LVI.analyze();
427   
428     
429   PhyRegAlloc PRA(M, TM , &LVI); // allocate registers
430   PRA.allocateRegisters();
431     
432
433   if( DEBUG_RA )  cout << endl << "Register allocation complete!" << endl;
434
435 }
436
437
438
439
440
441 bool UltraSparc::compileMethod(Method *M) {
442   if (SelectInstructionsForMethod(M, *this)) {
443     cerr << "Instruction selection failed for method " << M->getName()
444        << "\n\n";
445     return true;
446   }
447   
448   if (ScheduleInstructionsWithSSA(M, *this, InstSchedulingInfo)) {
449     cerr << "Instruction scheduling before allocation failed for method "
450        << M->getName() << "\n\n";
451     return true;
452   }
453
454   AllocateRegisters(M, *this);    // allocate registers
455
456
457   return false;
458 }
459