blob: ec4868b938dce1dcb424d87ec978c49c59ad1818 [file] [log] [blame]
Ruchira Sasanka94d86e92001-09-14 20:31:39 +00001#include "llvm/Target/Sparc.h"
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00002#include "SparcInternals.h"
3#include "llvm/Method.h"
4#include "llvm/iTerminators.h"
5#include "llvm/CodeGen/InstrScheduling.h"
6#include "llvm/CodeGen/InstrSelection.h"
Chris Lattner20b1ea02001-09-14 03:47:57 +00007
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00008#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
9#include "llvm/CodeGen/PhyRegAlloc.h"
Chris Lattner20b1ea02001-09-14 03:47:57 +000010
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000011
12
13
14//---------------------------------------------------------------------------
15// UltraSparcRegInfo
16//---------------------------------------------------------------------------
17
18/*
19Rules for coloring values with sepcial registers:
20=================================================
21
22The following are the cases we color values with special regs:
23
241) Incoming Method Arguements
252) Outgoing Call Arguments
263) Return Value of a call
274) Return Value of a return statement
28
29Both 1 and 3 are defs. Therefore, they can be set directly. For case 1,
30incoming args are colored to %i0-%i5 and %f0 - %fx. For case 3, the return
31value of the call must be colored to %o0 or %f0.
32
33For case 2 we can use %o0-%o6 and %f0- %fx and for case 4 we can use %i0 or
34%f0. However, we cannot pre-color them directly to those regs
35if there are call interferences or they can be already colred by case 1.
36(Note that a return value is call is already colored and it is registered
37as a call interference as well if it is live after the call). Otherwise, they
38can be precolored. In cases where we cannot precolor, we just have to insert
39a copy instruction to copy the LR to the required register.
40
41*/
42
43
44
45//---------------------------------------------------------------------------
46// This method will color incoming args to a method. If there are more
47// args than that can fit in regs, code will be inserted to pop them from
48// stack
49//---------------------------------------------------------------------------
50
51void UltraSparcRegInfo::colorArgs(const Method *const Meth,
52 LiveRangeInfo& LRI) const
Chris Lattner20b1ea02001-09-14 03:47:57 +000053{
54
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000055 // get the argument list
56 const Method::ArgumentListType& ArgList = Meth->getArgumentList();
57 // get an iterator to arg list
58 Method::ArgumentListType::const_iterator ArgIt = ArgList.begin();
59 unsigned intArgNo=0;
Chris Lattner20b1ea02001-09-14 03:47:57 +000060
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000061 // to keep track of which float regs are allocated for argument passing
62 bool FloatArgUsedArr[NumOfFloatArgRegs];
Chris Lattner20b1ea02001-09-14 03:47:57 +000063
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000064 // init float arg used array
65 for(unsigned i=0; i < NumOfFloatArgRegs; ++i)
66 FloatArgUsedArr[i] = false;
Chris Lattner20b1ea02001-09-14 03:47:57 +000067
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000068 // for each argument
69 for( ; ArgIt != ArgList.end() ; ++ArgIt) {
Chris Lattner20b1ea02001-09-14 03:47:57 +000070
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000071 // get the LR of arg
72 LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt);
73 unsigned RegClassID = (LR->getRegClass())->getID();
Chris Lattner20b1ea02001-09-14 03:47:57 +000074
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000075 // if the arg is in int class - allocate a reg for an int arg
76 if( RegClassID == IntRegClassID ) {
Chris Lattner20b1ea02001-09-14 03:47:57 +000077
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000078 if( intArgNo < NumOfIntArgRegs) {
79 LR->setColor( SparcIntRegOrder::i0 + intArgNo );
Chris Lattner20b1ea02001-09-14 03:47:57 +000080
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000081 if( DEBUG_RA) printReg( LR );
82 }
83
84 else {
85 // TODO: Insert push code here
86 assert( 0 && "Insert push code here!");
87 }
88 ++intArgNo;
Chris Lattner20b1ea02001-09-14 03:47:57 +000089 }
90
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000091 // if the arg is float/double
92 else if ( RegClassID == FloatRegClassID) {
Chris Lattner20b1ea02001-09-14 03:47:57 +000093
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000094 if( LR->getTypeID() == Type::DoubleTyID ) {
95
96 // find the first reg # we can pass a double arg
97 for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
98 if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
99 LR->setColor( SparcFloatRegOrder::f0 + i );
100 FloatArgUsedArr[i] = true;
101 FloatArgUsedArr[i+1] = true;
102 if( DEBUG_RA) printReg( LR );
103 break;
104 }
105 }
106 if( ! LR->hasColor() ) { // if LR was not colored above
107
108 assert(0 && "insert push code here for a double");
109
110 }
111
112 }
113 else if( LR->getTypeID() == Type::FloatTyID ) {
114
115 // find the first reg # we can pass a float arg
116 for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
117 if ( !FloatArgUsedArr[i] ) {
118 LR->setColor( SparcFloatRegOrder::f0 + i );
119 FloatArgUsedArr[i] = true;
120 if( DEBUG_RA) printReg( LR );
121 break;
122 }
123 }
124 if( ! LR->hasColor() ) { // if LR was not colored above
125 assert(0 && "insert push code here for a float");
126 }
127
128 }
129 else
130 assert(0 && "unknown float type in method arg");
131
132 } // float register class
133
134 else
135 assert(0 && "Unknown RegClassID");
Chris Lattner20b1ea02001-09-14 03:47:57 +0000136 }
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000137
Chris Lattner20b1ea02001-09-14 03:47:57 +0000138}
139
140
141
142
143
144
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000145void UltraSparcRegInfo::colorCallArgs(vector<const Instruction *> &
146 CallInstrList, LiveRangeInfo& LRI,
147 AddedInstrMapType &AddedInstrMap) const
Chris Lattner20b1ea02001-09-14 03:47:57 +0000148{
149
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000150 vector<const Instruction *>::const_iterator InstIt;
Chris Lattner20b1ea02001-09-14 03:47:57 +0000151
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000152 // First color the return value of all call instructions. The return value
153 // will be in %o0 if the value is an integer type, or in %f0 if the
154 // value is a float type.
155
156 for(InstIt=CallInstrList.begin(); InstIt != CallInstrList.end(); ++InstIt) {
157
158 const Instruction *const CallI = *InstIt;
159
160 // get the live range of return value of this call
161 LiveRange *const LR = LRI.getLiveRangeForValue( CallI );
162
163 if ( LR ) {
164
165 // Since the call is a def, it cannot be colored by some other instr.
166 // Therefore, we can definitely set a color here.
167 // However, this def can be used by some other instr like another call
168 // or return which places that in a special register. In that case
169 // it has to put a copy. Note that, the def will have a call interference
170 // with this call instr itself if it is live after this call.
171
172 assert( ! LR->hasColor() && "Can't have a color since this is a def");
173
174 unsigned RegClassID = (LR->getRegClass())->getID();
Chris Lattner20b1ea02001-09-14 03:47:57 +0000175
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000176 if( RegClassID == IntRegClassID ) {
177 LR->setColor(SparcIntRegOrder::o0);
178 }
179 else if (RegClassID == FloatRegClassID ) {
180 LR->setColor(SparcFloatRegOrder::f0 );
181 }
Chris Lattner20b1ea02001-09-14 03:47:57 +0000182 }
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000183 else {
184 cout << "Warning: No Live Range for return value of CALL" << endl;
Chris Lattner20b1ea02001-09-14 03:47:57 +0000185 }
186 }
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000187
188
189 for( InstIt=CallInstrList.begin(); InstIt != CallInstrList.end(); ++InstIt) {
190
191 // Inst = LLVM call instruction
192 const Instruction *const CallI = *InstIt;
193
194 // find the CALL/JMMPL machine instruction
195 MachineCodeForVMInstr & MInstVec = CallI->getMachineInstrVec();
196 MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
197
198 /*
199 for( ; MIIt != MInstVec.end() &&
200 ! getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode());
201 ++MIIt );
202
203 assert( (MIIt != MInstVec.end()) && "CALL/JMPL not found");
204 */
205
206 assert(getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode()) &&
207 "First machine instruction is not a Call/JMPL Machine Instr");
208
209 // CallMI = CALL/JMPL machine isntruction
210 const MachineInstr *const CallMI = *MIIt;
211
212 Instruction::op_const_iterator OpIt = CallI->op_begin();
213
214 unsigned intArgNo=0;
215
216
217 // to keep track of which float regs are allocated for argument passing
218 bool FloatArgUsedArr[NumOfFloatArgRegs];
219
220 // init float arg used array
221 for(unsigned i=0; i < NumOfFloatArgRegs; ++i)
222 FloatArgUsedArr[i] = false;
223
224 // go thru all the operands of LLVM instruction
225 for( ; OpIt != CallI->op_end(); ++OpIt ) {
226
227 // get the LR of call operand (parameter)
228 LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt);
229
230 if ( !LR ) {
231 cout << " Warning: In call instr, no LR for arg: " ;
232 printValue(*OpIt);
233 cout << endl;
234 continue;
235 }
236
237 unsigned RegClassID = (LR->getRegClass())->getID();
238
239 // if the arg is in int class - allocate a reg for an int arg
240 if( RegClassID == IntRegClassID ) {
241
242 if( intArgNo < NumOfIntArgRegs) {
243 setCallOrRetArgCol( LR, SparcIntRegOrder::o0 + intArgNo,
244 CallMI, AddedInstrMap);
245 }
246
247 else {
248 // TODO: Insert push code here
249 assert( 0 && "Insert push code here!");
250
251 AddedInstrns * AI = AddedInstrMap[ CallMI ];
252 if( ! AI ) AI = new AddedInstrns();
253
254 // AI->InstrnsBefore.push_back( getStackPushInstr(LR) );
255 AddedInstrMap[ CallMI ] = AI;
256
257 }
258 ++intArgNo;
259 }
260
261 // if the arg is float/double
262 else if ( RegClassID == FloatRegClassID) {
263
264 if( LR->getTypeID() == Type::DoubleTyID ) {
265
266 // find the first reg # we can pass a double arg
267 for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
268 if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
269 setCallOrRetArgCol(LR, SparcFloatRegOrder::f0 + i,
270 CallMI, AddedInstrMap);
271 FloatArgUsedArr[i] = true;
272 FloatArgUsedArr[i+1] = true;
273 //if( DEBUG_RA) printReg( LR );
274 break;
275 }
276 }
277 if( ! LR->hasColor() ) { // if LR was not colored above
278
279 assert(0 && "insert push code here for a double");
280
281 }
282
283 }
284 else if( LR->getTypeID() == Type::FloatTyID ) {
285
286 // find the first reg # we can pass a float arg
287 for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
288 if ( !FloatArgUsedArr[i] ) {
289 setCallOrRetArgCol(LR, SparcFloatRegOrder::f0 + i,
290 CallMI, AddedInstrMap);
291 FloatArgUsedArr[i] = true;
292 // LR->setColor( SparcFloatRegOrder::f0 + i );
293 // if( DEBUG_RA) printReg( LR );
294 break;
295 }
296 }
297 if( ! LR->hasColor() ) { // if LR was not colored above
298 assert(0 && "insert push code here for a float");
299 }
300
301 }
302 else
303 assert(0 && "unknown float type in method arg");
304
305 } // float register class
306
307 else
308 assert(0 && "Unknown RegClassID");
309
310
311 } // for each operand in a call instruction
312
313
314
315
316
317 } // for all call instrctions in CallInstrList
318
Chris Lattner20b1ea02001-09-14 03:47:57 +0000319}
320
321
322
323
324
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000325void UltraSparcRegInfo::colorRetArg(vector<const Instruction *> &
326 RetInstrList, LiveRangeInfo& LRI,
327 AddedInstrMapType &AddedInstrMap) const
Chris Lattner20b1ea02001-09-14 03:47:57 +0000328{
329
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000330 vector<const Instruction *>::const_iterator InstIt;
Chris Lattner20b1ea02001-09-14 03:47:57 +0000331
332
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000333 for(InstIt=RetInstrList.begin(); InstIt != RetInstrList.end(); ++InstIt) {
Chris Lattner20b1ea02001-09-14 03:47:57 +0000334
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000335 const ReturnInst *const RetI = (ReturnInst *) *InstIt;
336
337 // get the return value of this return instruction
338 const Value *RetVal = (RetI)->getReturnValue();
339
340 if( RetVal ) {
341
342 // find the CALL/JMMPL machine instruction
343 MachineCodeForVMInstr & MInstVec = RetI->getMachineInstrVec();
344 MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
345
346 assert(getUltraSparcInfo().getInstrInfo().isReturn((*MIIt)->getOpCode())
347 && "First machine instruction is not a RET Machine Instr");
348 // RET machine isntruction
349 const MachineInstr *const RetMI = *MIIt;
350
351 LiveRange *const LR = LRI.getLiveRangeForValue( RetVal );
352 unsigned RegClassID = (LR->getRegClass())->getID();
353
354 if ( LR ) {
355 if( RegClassID == IntRegClassID ) {
356 setCallOrRetArgCol( LR, SparcIntRegOrder::i0, RetMI, AddedInstrMap);
357 }
358 else if (RegClassID==FloatRegClassID ) {
359 setCallOrRetArgCol(LR, SparcFloatRegOrder::f0, RetMI, AddedInstrMap);
360 }
361
362 }
363 else {
364 cout << "Warning: No LR for return value" << endl;
365 }
366
Chris Lattner20b1ea02001-09-14 03:47:57 +0000367 }
Chris Lattner20b1ea02001-09-14 03:47:57 +0000368
369 }
370
Chris Lattner20b1ea02001-09-14 03:47:57 +0000371}
372
373
374
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000375void UltraSparcRegInfo::setCallOrRetArgCol(LiveRange *const LR,
376 const unsigned RegNo,
377 const MachineInstr *MI,
378 AddedInstrMapType &AIMap) const {
379
380 // if no call interference and LR is NOT previously colored (e.g., as an
381 // incoming arg)
382 if( ! LR->getNumOfCallInterferences() && ! LR->hasColor() ) {
383 // we can directly allocate a %o register
384 LR->setColor( RegNo);
385 if( DEBUG_RA) printReg( LR );
386 }
387 else {
388
389 // there are call interferences (e.g., live across a call or produced
390 // by a call instr) or this LR is already colored as an incoming argument
391
392 MachineInstr *MI = getCopy2RegMI((*(LR->begin())), RegNo,
393 (LR->getRegClass())->getID());
394
395 AddedInstrns * AI = AIMap[ MI ]; // get already added instrns for MI
396 if( ! AI ) AI = new AddedInstrns();
397
398 AI->InstrnsBefore.push_back( MI ); // add the new MI yp AMI
399 AIMap[ MI ] = AI;
400
401
402 cout << "Inserted a copy instr for a RET/CALL instr " << endl;
403
404 // We don't color LR here. It's colored as any other normal LR or
405 // as an incoming arg or a return value of a call.
406 }
407
408}
409
410// Generates a copy machine instruction to copy a value to a given
411// register.
412
413MachineInstr * UltraSparcRegInfo::getCopy2RegMI(const Value *SrcVal,
414 const unsigned Reg,
415 unsigned RegClassID) const {
416 MachineInstr * MI;
417
418 if( RegClassID == IntRegClassID ) { // if integer move
419
420 MI = new MachineInstr(ADD, 3);
421
422 MI->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, SrcVal);
423 MI->SetMachineOperand(1, SparcIntRegOrder::g0, false);
424 MI->SetMachineOperand(2, Reg, true);
425 }
426 else { // if FP move
427
428 if(SrcVal->getType()-> getPrimitiveID() == Type::FloatTyID )
429 MI = new MachineInstr(FMOVS, 2);
430 else if(SrcVal->getType()-> getPrimitiveID() == Type::DoubleTyID)
431 MI = new MachineInstr(FMOVD, 2);
432 else assert( 0 && "Unknown Type");
433
434 MI->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, SrcVal);
435 MI->SetMachineOperand(1, Reg, true);
436 }
437
438 return MI;
439
440}
Chris Lattner20b1ea02001-09-14 03:47:57 +0000441
442
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000443//---------------------------------------------------------------------------
444// Print the register assigned to a LR
445//---------------------------------------------------------------------------
446
447void UltraSparcRegInfo::printReg(const LiveRange *const LR) {
448
449 unsigned RegClassID = (LR->getRegClass())->getID();
450
451 cout << " *Node " << (LR->getUserIGNode())->getIndex();
452
453 if( ! LR->hasColor() ) {
454 cout << " - could not find a color" << endl;
455 return;
456 }
457
458 // if a color is found
459
460 cout << " colored with color "<< LR->getColor();
461
462 if( RegClassID == IntRegClassID ) {
463
464 cout<< " [" << SparcIntRegOrder::getRegName(LR->getColor()) ;
465 cout << "]" << endl;
466 }
467 else if ( RegClassID == FloatRegClassID) {
468 cout << "[" << SparcFloatRegOrder::getRegName(LR->getColor());
469 if( LR->getTypeID() == Type::DoubleTyID )
470 cout << "+" << SparcFloatRegOrder::getRegName(LR->getColor()+1);
471 cout << "]" << endl;
472 }
Chris Lattner20b1ea02001-09-14 03:47:57 +0000473
Ruchira Sasanka94d86e92001-09-14 20:31:39 +0000474
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000475}