1 #include "llvm/Target/Sparc.h"
2 #include "SparcInternals.h"
3 #include "llvm/Method.h"
4 #include "llvm/iTerminators.h"
5 #include "llvm/iOther.h"
6 #include "llvm/CodeGen/InstrScheduling.h"
7 #include "llvm/CodeGen/InstrSelection.h"
9 #include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
10 #include "llvm/CodeGen/PhyRegAlloc.h"
15 //---------------------------------------------------------------------------
17 //---------------------------------------------------------------------------
21 //---------------------------------------------------------------------------
22 // This method sets the hidden operand for return address in RETURN and
23 // JMPL machine instructions.
24 //---------------------------------------------------------------------------
26 bool UltraSparcRegInfo::handleSpecialMInstr(const MachineInstr * MInst,
28 vector<RegClass *>RCList) const {
30 unsigned OpCode = MInst->getOpCode();
33 // if the instruction is a RETURN instruction, suggest %i7
35 if( (UltraSparcInfo->getInstrInfo()).isReturn( OpCode ) ) {
37 const Value *RetAddrVal = getValue4ReturnAddr(MInst);
39 if( (getRegClassIDOfValue( RetAddrVal) == IntRegClassID) ) {
41 cout << "\n$?$Return Address Value is not of Integer Type. Type =";
42 cout << (RetAddrVal->getType())->getPrimitiveID() << endl;
47 LiveRange * RetAddrLR = new LiveRange();
48 RetAddrLR->add(RetAddrVal);
49 RetAddrLR->setRegClass( RCList[IntRegClassID] );
50 LRI.addLRToMap( RetAddrVal, RetAddrLR);
52 RetAddrLR->setSuggestedColor(SparcIntRegOrder::i7);
57 // else if the instruction is a JMPL instruction, color it with %o7
58 // this can be permenently colored since the LR is very short (one instr)
59 // TODO: Directly change the machine register instead of creating a LR
61 else if( (UltraSparcInfo->getInstrInfo()).isCall(MInst->getOpCode() ) ) {
63 const Value *RetAddrVal = getValue4ReturnAddr(MInst);
65 if( (getRegClassIDOfValue( RetAddrVal) == IntRegClassID) ) {
67 cout << "\n$?$Return Address Value is not of Integer Type. Type =";
68 cout << (RetAddrVal->getType())->getPrimitiveID() << endl;
72 LiveRange * RetAddrLR = new LiveRange();
73 RetAddrLR->add(RetAddrVal);
74 RetAddrLR->setRegClass( RCList[IntRegClassID] );
75 LRI.addLRToMap( RetAddrVal, RetAddrLR);
77 RetAddrLR->setColor(SparcIntRegOrder::o7);
83 else return false; // not a special machine instruction
88 //---------------------------------------------------------------------------
89 // This gets the hidden value in a return register which is used to
90 // pass the return address.
91 //---------------------------------------------------------------------------
94 UltraSparcRegInfo::getValue4ReturnAddr( const MachineInstr * MInst ) const {
96 if( (UltraSparcInfo->getInstrInfo()).isReturn(MInst->getOpCode()) ) {
98 assert( (MInst->getNumOperands() == 2) && "RETURN must have 2 operands");
99 const MachineOperand & MO = MInst->getOperand(0);
100 return MO.getVRegValue();
103 else if( (UltraSparcInfo->getInstrInfo()).isCall(MInst->getOpCode()) ) {
105 assert( (MInst->getNumOperands() == 3) && "JMPL must have 3 operands");
106 const MachineOperand & MO = MInst->getOperand(2);
107 return MO.getVRegValue();
111 assert(0 && "Machine Instr is not a CALL/RET");
116 //---------------------------------------------------------------------------
117 // This method will suggest colors to incoming args to a method.
118 // If the arg is passed on stack due to the lack of regs, NOTHING will be
119 // done - it will be colored (or spilled) as a normal value.
120 //---------------------------------------------------------------------------
122 void UltraSparcRegInfo::suggestRegs4MethodArgs(const Method *const Meth,
123 LiveRangeInfo& LRI) const
126 // get the argument list
127 const Method::ArgumentListType& ArgList = Meth->getArgumentList();
128 // get an iterator to arg list
129 Method::ArgumentListType::const_iterator ArgIt = ArgList.begin();
132 for( unsigned argNo=0; ArgIt != ArgList.end() ; ++ArgIt, ++argNo) {
135 LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt);
136 assert( LR && "No live range found for method arg");
138 unsigned RegType = getRegType( LR );
141 // if the arg is in int class - allocate a reg for an int arg
142 if( RegType == IntRegType ) {
144 if( argNo < NumOfIntArgRegs) {
145 LR->setSuggestedColor( SparcIntRegOrder::i0 + argNo );
150 // Do NOTHING as this will be colored as a normal value.
151 if (DEBUG_RA) cout << " Int Regr not suggested for method arg\n";
155 else if( RegType==FPSingleRegType && (argNo*2+1) < NumOfFloatArgRegs)
156 LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2 + 1) );
159 else if( RegType == FPDoubleRegType && (argNo*2) < NumOfFloatArgRegs)
160 LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2) );
167 //---------------------------------------------------------------------------
169 //---------------------------------------------------------------------------
171 void UltraSparcRegInfo::colorMethodArgs(const Method *const Meth,
173 AddedInstrns *const FirstAI) const {
175 // get the argument list
176 const Method::ArgumentListType& ArgList = Meth->getArgumentList();
177 // get an iterator to arg list
178 Method::ArgumentListType::const_iterator ArgIt = ArgList.begin();
184 for( unsigned argNo=0; ArgIt != ArgList.end() ; ++ArgIt, ++argNo) {
187 LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt);
188 assert( LR && "No live range found for method arg");
191 // if the LR received the suggested color, NOTHING to be done
192 if( LR->hasSuggestedColor() && LR->hasColor() )
193 if( LR->getSuggestedColor() == LR->getColor() )
196 // We are here because the LR did not have a suggested
197 // color or did not receive the suggested color. Now handle
201 unsigned RegType = getRegType( LR );
202 unsigned RegClassID = (LR->getRegClass())->getID();
205 // find whether this argument is coming in a register (if not, on stack)
207 bool isArgInReg = false;
208 unsigned UniArgReg = InvalidRegNum;
210 if( (RegType== IntRegType && argNo < NumOfIntArgRegs)) {
212 UniArgReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::o0 + argNo );
214 else if(RegType == FPSingleRegType && argNo < NumOfFloatArgRegs) {
216 UniArgReg = getUnifiedRegNum( RegClassID,
217 SparcFloatRegOrder::f0 + argNo*2 + 1 ) ;
219 else if(RegType == FPDoubleRegType && argNo < NumOfFloatArgRegs) {
221 UniArgReg = getUnifiedRegNum(RegClassID, SparcFloatRegOrder::f0+argNo*2);
225 if( LR->hasColor() ) {
227 // We are here because the LR did not have a suggested
228 // color or did not receive the suggested color but LR got a register.
229 // Now we have to copy %ix reg (or stack pos of arg)
230 // to the register it was colored with.
232 unsigned UniLRReg = getUnifiedRegNum( RegClassID, LR->getColor() );
234 // if the arg is coming in a register and goes into a register
236 AdMI = cpReg2RegMI(UniArgReg, UniLRReg, RegType );
239 assert(0 && "TODO: Color an Incoming arg on stack");
241 // Now add the instruction
242 FirstAI->InstrnsBefore.push_back( AdMI );
246 else { // LR is not colored (i.e., spilled)
248 assert(0 && "TODO: Color a spilled arg ");
253 } // for each incoming argument
260 //---------------------------------------------------------------------------
261 // This method is called before graph coloring to suggest colors to the
262 // outgoing call args and the return value of the call.
263 //---------------------------------------------------------------------------
264 void UltraSparcRegInfo::suggestRegs4CallArgs(const CallInst *const CallI,
266 vector<RegClass *> RCList) const {
269 assert( (CallI->getOpcode() == Instruction::Call) && "Not a call instr");
271 // First color the return value of the call instruction. The return value
272 // will be in %o0 if the value is an integer type, or in %f0 if the
273 // value is a float type.
275 // the return value cannot have a LR in machine instruction since it is
276 // only defined by the call instruction
278 assert( (! LRI.getLiveRangeForValue( CallI ) ) &&
279 "LR for ret Value of call already definded!");
281 // if type is not void, create a new live range and set its
282 // register class and add to LRI
284 if( ! ((CallI->getType())->getPrimitiveID() == Type::VoidTyID) ) {
286 // create a new LR for the return value
288 LiveRange * RetValLR = new LiveRange();
289 RetValLR->add( CallI );
290 unsigned RegClassID = getRegClassIDOfValue( CallI );
291 RetValLR->setRegClass( RCList[RegClassID] );
292 LRI.addLRToMap( CallI, RetValLR);
294 // now suggest a register depending on the register class of ret arg
296 if( RegClassID == IntRegClassID )
297 RetValLR->setSuggestedColor(SparcIntRegOrder::o0);
298 else if (RegClassID == FloatRegClassID )
299 RetValLR->setSuggestedColor(SparcFloatRegOrder::f0 );
300 else assert( 0 && "Unknown reg class for return value of call\n");
305 // Now suggest colors for arguments (operands) of the call instruction.
306 // Colors are suggested only if the arg number is smaller than the
307 // the number of registers allocated for argument passing.
309 Instruction::op_const_iterator OpIt = CallI->op_begin();
310 ++OpIt; // first operand is the called method - skip it
312 // go thru all the operands of LLVM instruction
313 for(unsigned argNo=0; OpIt != CallI->op_end(); ++OpIt, ++argNo ) {
315 // get the LR of call operand (parameter)
316 LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt);
318 if( !LR ) { // possible because arg can be a const
320 cout << " Warning: In call instr, no LR for arg: " ;
321 printValue(*OpIt); cout << endl;
326 unsigned RegType = getRegType( LR );
328 // if the arg is in int class - allocate a reg for an int arg
329 if( RegType == IntRegType ) {
331 if( argNo < NumOfIntArgRegs)
332 LR->setSuggestedColor( SparcIntRegOrder::o0 + argNo );
335 // Do NOTHING as this will be colored as a normal value.
336 cout << " Regr not suggested for int call arg" << endl;
339 else if( RegType == FPSingleRegType && (argNo*2 +1)< NumOfFloatArgRegs)
340 LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2 + 1) );
343 else if( RegType == FPDoubleRegType && (argNo*2) < NumOfFloatArgRegs)
344 LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2) );
347 } // for all call arguments
352 //---------------------------------------------------------------------------
353 // After graph coloring, we have call this method to see whehter the return
354 // value and the call args received the correct colors. If not, we have
355 // to instert copy instructions.
356 //---------------------------------------------------------------------------
359 void UltraSparcRegInfo::colorCallArgs(const CallInst *const CallI,
361 AddedInstrns *const CallAI) const {
364 // First color the return value of the call.
365 // If there is a LR for the return value, it means this
366 // method returns a value
369 LiveRange * RetValLR = LRI.getLiveRangeForValue( CallI );
373 bool recvSugColor = false;
375 if( RetValLR->hasSuggestedColor() && RetValLR->hasColor() )
376 if( RetValLR->getSuggestedColor() == RetValLR->getColor())
379 // if we didn't receive the suggested color for some reason,
380 // put copy instruction
382 if( !recvSugColor ) {
384 if( RetValLR->hasColor() ) {
386 unsigned RegType = getRegType( RetValLR );
387 unsigned RegClassID = (RetValLR->getRegClass())->getID();
389 unsigned UniRetLRReg=getUnifiedRegNum(RegClassID,RetValLR->getColor());
390 unsigned UniRetReg = InvalidRegNum;
392 // find where we receive the return value depending on
395 if(RegClassID == IntRegClassID)
396 UniRetReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::o0);
397 else if(RegClassID == FloatRegClassID)
398 UniRetReg = getUnifiedRegNum( RegClassID, SparcFloatRegOrder::f0);
401 AdMI = cpReg2RegMI(UniRetLRReg, UniRetReg, RegType );
402 CallAI->InstrnsAfter.push_back( AdMI );
408 assert(0 && "LR of return value is splilled");
412 } // the LR didn't receive the suggested color
414 } // if there is a LR - i.e., return value is not void
418 // Now color all the operands of the call instruction
420 Instruction::op_const_iterator OpIt = CallI->op_begin();
421 ++OpIt; // first operand is the called method - skip it
423 // go thru all the operands of LLVM instruction
424 for(unsigned argNo=0; OpIt != CallI->op_end(); ++OpIt, ++argNo ) {
426 // get the LR of call operand (parameter)
427 LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt);
429 Value *ArgVal = (Value *) *OpIt;
431 unsigned RegType = getRegType( ArgVal );
432 unsigned RegClassID = getRegClassIDOfValue( ArgVal );
434 // find whether this argument is coming in a register (if not, on stack)
436 bool isArgInReg = false;
437 unsigned UniArgReg = InvalidRegNum;
439 if( (RegType== IntRegType && argNo < NumOfIntArgRegs)) {
441 UniArgReg = getUnifiedRegNum(RegClassID, SparcIntRegOrder::o0 + argNo );
443 else if(RegType == FPSingleRegType && argNo < NumOfFloatArgRegs) {
445 UniArgReg = getUnifiedRegNum(RegClassID,
446 SparcFloatRegOrder::f0 + (argNo*2 + 1) );
448 else if(RegType == FPDoubleRegType && argNo < NumOfFloatArgRegs) {
450 UniArgReg = getUnifiedRegNum(RegClassID, SparcFloatRegOrder::f0+argNo*2);
455 if( !LR ) { // possible because arg can be a const
458 cout << " Warning: In call instr, no LR for arg: " ;
459 printValue(*OpIt); cout << endl;
462 //AdMI = cpValue2RegMI( ArgVal, UniArgReg, RegType);
463 //(CallAI->InstrnsBefore).push_back( AdMI );
464 //cout << " *Constant moved to an output register\n";
470 // if the LR received the suggested color, NOTHING to do
472 if( LR->hasSuggestedColor() && LR->hasColor() )
473 if( LR->getSuggestedColor() == LR->getColor() )
480 if( LR->hasColor() ) {
482 // We are here because though the LR is allocated a register, it
483 // was not allocated the suggested register. So, we have to copy %ix reg
484 // (or stack pos of arg) to the register it was colored with
487 unsigned UniLRReg = getUnifiedRegNum( RegClassID, LR->getColor() );
490 AdMI = cpReg2RegMI(UniLRReg, UniArgReg, RegType );
493 assert(0 && "TODO: Push an outgoing arg on stack");
495 // Now add the instruction
496 CallAI->InstrnsBefore.push_back( AdMI );
500 else { // LR is not colored (i.e., spilled)
502 assert(0 && "TODO: Copy a spilled call arg to an output reg ");
506 } // for each parameter in call instruction
510 //---------------------------------------------------------------------------
511 // This method is called for an LLVM return instruction to identify which
512 // values will be returned from this method and to suggest colors.
513 //---------------------------------------------------------------------------
514 void UltraSparcRegInfo::suggestReg4RetValue(const ReturnInst *const RetI,
515 LiveRangeInfo& LRI) const {
519 assert( (RetI->getOpcode() == Instruction::Ret) && "Not a ret instr");
521 // get the return value of this return instruction
523 const Value *RetVal = (RetI)->getReturnValue();
525 // if the method returns a value
529 LiveRange *const LR = LRI.getLiveRangeForValue( RetVal );
534 unsigned RegClassID = (LR->getRegClass())->getID();
536 if( RegClassID == IntRegClassID )
537 LR->setSuggestedColor(SparcIntRegOrder::i0);
539 else if ( RegClassID == FloatRegClassID )
540 LR->setSuggestedColor(SparcFloatRegOrder::f0);
545 cout << "Warning: No LR for return value" << endl;
546 // possible since this can be returning a constant
557 //---------------------------------------------------------------------------
559 //---------------------------------------------------------------------------
560 void UltraSparcRegInfo::colorRetValue(const ReturnInst *const RetI,
562 AddedInstrns *const RetAI) const {
565 // get the return value of this return instruction
566 Value *RetVal = (Value *) (RetI)->getReturnValue();
568 // if the method returns a value
572 LiveRange *const LR = LRI.getLiveRangeForValue( RetVal );
574 unsigned RegClassID = getRegClassIDOfValue(RetVal);
575 unsigned RegType = getRegType( RetVal );
576 unsigned UniRetReg = InvalidRegNum;
578 if(RegClassID == IntRegClassID)
579 UniRetReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::i0 );
580 else if(RegClassID == FloatRegClassID)
581 UniRetReg = getUnifiedRegNum( RegClassID, SparcFloatRegOrder::f0);
585 // if the LR received the suggested color, NOTHING to do
587 if( LR->hasSuggestedColor() && LR->hasColor() )
588 if( LR->getSuggestedColor() == LR->getColor() )
591 if( LR->hasColor() ) {
593 // We are here because the LR was allocted a regiter, but NOT
594 // the correct register.
596 // copy the LR of retun value to i0 or f0
598 unsigned UniLRReg =getUnifiedRegNum( RegClassID, LR->getColor());
600 if(RegClassID == IntRegClassID)
601 UniRetReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::i0);
602 else if(RegClassID == FloatRegClassID)
603 UniRetReg = getUnifiedRegNum( RegClassID, SparcFloatRegOrder::f0);
605 AdMI = cpReg2RegMI( UniLRReg, UniRetReg, RegType);
609 assert(0 && "TODO: Copy the return value from stack\n");
613 // if NO LR we have to add an explicit copy to move the value to
614 // the return register.
616 //AdMI = cpValue2RegMI( RetVal, UniRetReg, RegType);
617 //(RetAI->InstrnsBefore).push_back( AdMI );
619 // assert( 0 && "Returned constant must be moved to the ret reg\n");
623 } // if there is a return value
628 //---------------------------------------------------------------------------
629 // Copy from a register to register. Register number must be the unified
631 //---------------------------------------------------------------------------
634 MachineInstr * UltraSparcRegInfo::cpReg2RegMI(const unsigned SrcReg,
635 const unsigned DestReg,
636 const int RegType) const {
638 assert( (SrcReg != InvalidRegNum) && (DestReg != InvalidRegNum) &&
641 MachineInstr * MI = NULL;
646 MI = new MachineInstr(ADD, 3);
647 MI->SetMachineOperand(0, SrcReg, false);
648 MI->SetMachineOperand(1, SparcIntRegOrder::g0, false);
649 MI->SetMachineOperand(2, DestReg, true);
652 case FPSingleRegType:
653 MI = new MachineInstr(FMOVS, 2);
654 MI->SetMachineOperand(0, SrcReg, false);
655 MI->SetMachineOperand(1, DestReg, true);
658 case FPDoubleRegType:
659 MI = new MachineInstr(FMOVD, 2);
660 MI->SetMachineOperand(0, SrcReg, false);
661 MI->SetMachineOperand(1, DestReg, true);
665 assert(0 && "Unknow RegType");
674 //---------------------------------------------------------------------------
675 // Only constant/label values are accepted.
676 // ***This code is temporary ***
677 //---------------------------------------------------------------------------
680 MachineInstr * UltraSparcRegInfo::cpValue2RegMI(Value * Val,
681 const unsigned DestReg,
682 const int RegType) const {
684 assert( (DestReg != InvalidRegNum) && "Invalid Register");
690 MachineOperand::MachineOperandType MOTypeInt =
691 ChooseRegOrImmed(Val, ADD, *UltraSparcInfo, true, MReg, Imm);
694 MachineOperand::MachineOperandType MOType;
696 switch( Val->getValueType() ) {
698 case Value::ConstantVal:
699 case Value::GlobalVal:
700 MOType = MachineOperand:: MO_UnextendedImmed; // TODO**** correct???
703 case Value::BasicBlockVal:
704 case Value::MethodVal:
705 MOType = MachineOperand::MO_PCRelativeDisp;
709 cout << "Value Type: " << Val->getValueType() << endl;
710 assert(0 && "Unknown val type - Only constants/globals/labels are valid");
715 MachineInstr * MI = NULL;
720 MI = new MachineInstr(ADD);
721 MI->SetMachineOperand(0, MOType, Val, false);
722 MI->SetMachineOperand(1, SparcIntRegOrder::g0, false);
723 MI->SetMachineOperand(2, DestReg, true);
726 case FPSingleRegType:
727 assert(0 && "FP const move not yet implemented");
728 MI = new MachineInstr(FMOVS);
729 MI->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, Val, false);
730 MI->SetMachineOperand(1, DestReg, true);
733 case FPDoubleRegType:
734 assert(0 && "FP const move not yet implemented");
735 MI = new MachineInstr(FMOVD);
736 MI->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, Val, false);
737 MI->SetMachineOperand(1, DestReg, true);
741 assert(0 && "Unknow RegType");
753 //---------------------------------------------------------------------------
754 // Print the register assigned to a LR
755 //---------------------------------------------------------------------------
757 void UltraSparcRegInfo::printReg(const LiveRange *const LR) {
759 unsigned RegClassID = (LR->getRegClass())->getID();
761 cout << " *Node " << (LR->getUserIGNode())->getIndex();
763 if( ! LR->hasColor() ) {
764 cout << " - could not find a color" << endl;
768 // if a color is found
770 cout << " colored with color "<< LR->getColor();
772 if( RegClassID == IntRegClassID ) {
774 cout<< " [" << SparcIntRegOrder::getRegName(LR->getColor()) ;
777 else if ( RegClassID == FloatRegClassID) {
778 cout << "[" << SparcFloatRegOrder::getRegName(LR->getColor());
779 if( LR->getTypeID() == Type::DoubleTyID )
780 cout << "+" << SparcFloatRegOrder::getRegName(LR->getColor()+1);