blob: 37052568cd13ae9cf927a2135a0ae2094f179646 [file] [log] [blame]
Vikram S. Adve0fb49802001-09-18 13:01:29 +00001// $Id$
Chris Lattner20b1ea02001-09-14 03:47:57 +00002//***************************************************************************
3// File:
4// Sparc.cpp
5//
6// Purpose:
7//
8// History:
9// 7/15/01 - Vikram Adve - Created
10//**************************************************************************/
11
Chris Lattner46cbff62001-09-14 16:56:32 +000012#include "llvm/Target/Sparc.h"
Chris Lattner20b1ea02001-09-14 03:47:57 +000013#include "SparcInternals.h"
14#include "llvm/Method.h"
15#include "llvm/CodeGen/InstrScheduling.h"
16#include "llvm/CodeGen/InstrSelection.h"
17
Ruchira Sasankae38bd5332001-09-15 00:30:44 +000018#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
19#include "llvm/CodeGen/PhyRegAlloc.h"
20
21
Vikram S. Adve0fb49802001-09-18 13:01:29 +000022//***************************** Internal Functions *************************/
23
24//----------------------------------------------------------------------------
Chris Lattner46cbff62001-09-14 16:56:32 +000025// allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
26// that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
Vikram S. Adve0fb49802001-09-18 13:01:29 +000027//----------------------------------------------------------------------------
Chris Lattner46cbff62001-09-14 16:56:32 +000028//
29TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
Chris Lattner20b1ea02001-09-14 03:47:57 +000030
31
Vikram S. Adve0fb49802001-09-18 13:01:29 +000032//----------------------------------------------------------------------------
33// Entry point for register allocation for a module
34//----------------------------------------------------------------------------
35
36bool
37AllocateRegisters(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
Chris Lattner20b1ea02001-09-14 03:47:57 +000064//---------------------------------------------------------------------------
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*/
75UltraSparcInstrInfo::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*/
93UltraSparcSchedInfo::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
119void
120UltraSparcSchedInfo::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
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000129
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000130
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000131
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
141void 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
235void 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
266void 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
397void 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
Chris Lattner20b1ea02001-09-14 03:47:57 +0000425//---------------------------------------------------------------------------
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
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000436UltraSparc::UltraSparc()
437 : TargetMachine("UltraSparc-Native"),
438 instrInfo(),
439 schedInfo(&instrInfo),
440 regInfo( this )
441{
Chris Lattner20b1ea02001-09-14 03:47:57 +0000442 optSizeForSubWordData = 4;
443 minMemOpWordSize = 8;
444 maxAtomicMemOpWordSize = 8;
Chris Lattner20b1ea02001-09-14 03:47:57 +0000445}
446
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000447
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000448bool
449UltraSparc::compileMethod(Method *M)
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000450{
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000451 if (SelectInstructionsForMethod(M, *this))
452 {
453 cerr << "Instruction selection failed for method " << M->getName()
454 << "\n\n";
455 return true;
456 }
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000457
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000458 if (ScheduleInstructionsWithSSA(M, *this))
459 {
460 cerr << "Instruction scheduling before allocation failed for method "
461 << M->getName() << "\n\n";
462 return true;
463 }
Chris Lattner20b1ea02001-09-14 03:47:57 +0000464
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000465 // if (AllocateRegisters(M, *this)) // allocate registers
466 // {
467 // cerr << "Register allocation failed for method "
468 // << M->getName() << "\n\n";
469 // return true;
470 // }
471
Chris Lattner20b1ea02001-09-14 03:47:57 +0000472 return false;
473}
Chris Lattnerf6e0e282001-09-14 04:32:55 +0000474