blob: 027e14f5d5a0ff776626726d5527718c683f812e [file] [log] [blame]
Chris Lattnered5171e2002-02-03 07:52:04 +00001//===-- SparcRegInfo.cpp - Sparc Target Register Information --------------===//
2//
3// This file contains implementation of Sparc specific helper methods
4// used for register allocation.
5//
6//===----------------------------------------------------------------------===//
7
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00008#include "SparcInternals.h"
Chris Lattner699683c2002-02-04 05:59:25 +00009#include "SparcRegClassInfo.h"
10#include "llvm/Target/Sparc.h"
Chris Lattnered5171e2002-02-03 07:52:04 +000011#include "llvm/CodeGen/MachineCodeForMethod.h"
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000012#include "llvm/CodeGen/PhyRegAlloc.h"
Chris Lattner699683c2002-02-04 05:59:25 +000013#include "llvm/CodeGen/MachineInstr.h"
Chris Lattner699683c2002-02-04 05:59:25 +000014#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
15#include "llvm/iTerminators.h"
16#include "llvm/iOther.h"
Chris Lattner0ac54292002-04-09 19:08:28 +000017#include "llvm/Function.h"
Ruchira Sasankad00982a2002-01-07 19:20:28 +000018#include "llvm/DerivedTypes.h"
Chris Lattner697954c2002-01-20 22:54:45 +000019#include <iostream>
20using std::cerr;
Chris Lattner20b1ea02001-09-14 03:47:57 +000021
Chris Lattner699683c2002-02-04 05:59:25 +000022UltraSparcRegInfo::UltraSparcRegInfo(const UltraSparc &tgt)
23 : MachineRegInfo(tgt), UltraSparcInfo(&tgt), NumOfIntArgRegs(6),
24 NumOfFloatArgRegs(32), InvalidRegNum(1000) {
25
26 MachineRegClassArr.push_back(new SparcIntRegClass(IntRegClassID));
27 MachineRegClassArr.push_back(new SparcFloatRegClass(FloatRegClassID));
28 MachineRegClassArr.push_back(new SparcIntCCRegClass(IntCCRegClassID));
29 MachineRegClassArr.push_back(new SparcFloatCCRegClass(FloatCCRegClassID));
30
31 assert(SparcFloatRegOrder::StartOfNonVolatileRegs == 32 &&
32 "32 Float regs are used for float arg passing");
33}
34
35
Vikram S. Advef1c15ee2002-03-18 03:12:16 +000036// getZeroRegNum - returns the register that contains always zero.
37// this is the unified register number
Chris Lattner699683c2002-02-04 05:59:25 +000038//
Vikram S. Advef1c15ee2002-03-18 03:12:16 +000039int UltraSparcRegInfo::getZeroRegNum() const {
40 return this->getUnifiedRegNum(UltraSparcRegInfo::IntRegClassID,
41 SparcIntRegOrder::g0);
42}
Chris Lattner699683c2002-02-04 05:59:25 +000043
44// getCallAddressReg - returns the reg used for pushing the address when a
45// method is called. This can be used for other purposes between calls
46//
47unsigned UltraSparcRegInfo::getCallAddressReg() const {
Vikram S. Advef1c15ee2002-03-18 03:12:16 +000048 return this->getUnifiedRegNum(UltraSparcRegInfo::IntRegClassID,
49 SparcIntRegOrder::o7);
Chris Lattner699683c2002-02-04 05:59:25 +000050}
51
52// Returns the register containing the return address.
53// It should be made sure that this register contains the return
54// value when a return instruction is reached.
55//
56unsigned UltraSparcRegInfo::getReturnAddressReg() const {
Vikram S. Advef1c15ee2002-03-18 03:12:16 +000057 return this->getUnifiedRegNum(UltraSparcRegInfo::IntRegClassID,
58 SparcIntRegOrder::i7);
Chris Lattner699683c2002-02-04 05:59:25 +000059}
60
61// given the unified register number, this gives the name
62// for generating assembly code or debugging.
63//
64const std::string UltraSparcRegInfo::getUnifiedRegName(int reg) const {
65 if( reg < 32 )
66 return SparcIntRegOrder::getRegName(reg);
67 else if ( reg < (64 + 32) )
68 return SparcFloatRegOrder::getRegName( reg - 32);
69 else if( reg < (64+32+4) )
70 return SparcFloatCCRegOrder::getRegName( reg -32 - 64);
71 else if( reg < (64+32+4+2) ) // two names: %xcc and %ccr
72 return SparcIntCCRegOrder::getRegName( reg -32 - 64 - 4);
73 else if (reg== InvalidRegNum) //****** TODO: Remove */
74 return "<*NoReg*>";
75 else
76 assert(0 && "Invalid register number");
77 return "";
78}
79
Vikram S. Advef1c15ee2002-03-18 03:12:16 +000080// Get unified reg number for frame pointer
Chris Lattner699683c2002-02-04 05:59:25 +000081unsigned UltraSparcRegInfo::getFramePointer() const {
Vikram S. Advef1c15ee2002-03-18 03:12:16 +000082 return this->getUnifiedRegNum(UltraSparcRegInfo::IntRegClassID,
83 SparcIntRegOrder::i6);
Chris Lattner699683c2002-02-04 05:59:25 +000084}
85
Vikram S. Advef1c15ee2002-03-18 03:12:16 +000086// Get unified reg number for stack pointer
Chris Lattner699683c2002-02-04 05:59:25 +000087unsigned UltraSparcRegInfo::getStackPointer() const {
Vikram S. Advef1c15ee2002-03-18 03:12:16 +000088 return this->getUnifiedRegNum(UltraSparcRegInfo::IntRegClassID,
89 SparcIntRegOrder::o6);
Chris Lattner699683c2002-02-04 05:59:25 +000090}
91
92
93
Ruchira Sasankad00982a2002-01-07 19:20:28 +000094//---------------------------------------------------------------------------
Ruchira Sasankad00982a2002-01-07 19:20:28 +000095// Finds the return value of a sparc specific call instruction
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000096//---------------------------------------------------------------------------
Vikram S. Advea44c6c02002-03-31 19:04:50 +000097
Ruchira Sasankab3b6f532001-10-21 16:43:41 +000098const Value *
Ruchira Sasankad00982a2002-01-07 19:20:28 +000099UltraSparcRegInfo::getCallInstRetVal(const MachineInstr *CallMI) const {
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000100 unsigned OpCode = CallMI->getOpCode();
Chris Lattner697954c2002-01-20 22:54:45 +0000101 unsigned NumOfImpRefs = CallMI->getNumImplicitRefs();
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000102
Chris Lattner697954c2002-01-20 22:54:45 +0000103 if (OpCode == CALL) {
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000104
105 // The one before the last implicit operand is the return value of
106 // a CALL instr
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000107 //
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000108 if( NumOfImpRefs > 1 )
Chris Lattner699683c2002-02-04 05:59:25 +0000109 if (CallMI->implicitRefIsDefined(NumOfImpRefs-2))
110 return CallMI->getImplicitRef(NumOfImpRefs-2);
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000111
Chris Lattner697954c2002-01-20 22:54:45 +0000112 } else if (OpCode == JMPLCALL) {
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000113
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000114 // The last implicit operand is the return value of a JMPL
115 //
Chris Lattner697954c2002-01-20 22:54:45 +0000116 if(NumOfImpRefs > 0)
117 if (CallMI->implicitRefIsDefined(NumOfImpRefs-1))
118 return CallMI->getImplicitRef(NumOfImpRefs-1);
Chris Lattner699683c2002-02-04 05:59:25 +0000119 } else
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000120 assert(0 && "OpCode must be CALL/JMPL for a call instr");
121
122 return NULL;
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000123}
124
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000125
Vikram S. Advea44c6c02002-03-31 19:04:50 +0000126const Value *
127UltraSparcRegInfo::getCallInstIndirectAddrVal(const MachineInstr *CallMI) const
128{
129 return (CallMI->getOpCode() == JMPLCALL)?
130 CallMI->getOperand(0).getVRegValue() : NULL;
131}
132
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000133
134//---------------------------------------------------------------------------
135// Finds the return address of a call sparc specific call instruction
136//---------------------------------------------------------------------------
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000137const Value *
Chris Lattner699683c2002-02-04 05:59:25 +0000138UltraSparcRegInfo::getCallInstRetAddr(const MachineInstr *CallMI) const {
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000139 unsigned OpCode = CallMI->getOpCode();
140
Chris Lattner699683c2002-02-04 05:59:25 +0000141 if (OpCode == CALL) {
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000142 unsigned NumOfImpRefs = CallMI->getNumImplicitRefs();
143
144 assert( NumOfImpRefs && "CALL instr must have at least on ImpRef");
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000145
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000146 // The last implicit operand is the return address of a CALL instr
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000147 //
Chris Lattner699683c2002-02-04 05:59:25 +0000148 return CallMI->getImplicitRef(NumOfImpRefs-1);
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000149
Chris Lattner699683c2002-02-04 05:59:25 +0000150 } else if(OpCode == JMPLCALL) {
151 MachineOperand &MO = (MachineOperand &)CallMI->getOperand(2);
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000152 return MO.getVRegValue();
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000153 }
Chris Lattner699683c2002-02-04 05:59:25 +0000154
155 assert(0 && "OpCode must be CALL/JMPL for a call instr");
156 return 0;
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000157}
158
Chris Lattner699683c2002-02-04 05:59:25 +0000159// The following 3 methods are used to find the RegType (see enum above)
160// of a LiveRange, Value and using the unified RegClassID
161//
162int UltraSparcRegInfo::getRegType(const LiveRange *LR) const {
Chris Lattner699683c2002-02-04 05:59:25 +0000163 switch (LR->getRegClass()->getID()) {
164 case IntRegClassID: return IntRegType;
Chris Lattner37730942002-02-05 03:52:29 +0000165 case FloatRegClassID: {
166 const Type *Typ = LR->getType();
167 if (Typ == Type::FloatTy)
Chris Lattner699683c2002-02-04 05:59:25 +0000168 return FPSingleRegType;
Chris Lattner37730942002-02-05 03:52:29 +0000169 else if (Typ == Type::DoubleTy)
Chris Lattner699683c2002-02-04 05:59:25 +0000170 return FPDoubleRegType;
171 assert(0 && "Unknown type in FloatRegClass");
Chris Lattner37730942002-02-05 03:52:29 +0000172 }
Chris Lattner699683c2002-02-04 05:59:25 +0000173 case IntCCRegClassID: return IntCCRegType;
174 case FloatCCRegClassID: return FloatCCRegType;
175 default: assert( 0 && "Unknown reg class ID");
176 return 0;
177 }
178}
179
180int UltraSparcRegInfo::getRegType(const Value *Val) const {
181 unsigned Typ;
182
183 switch (getRegClassIDOfValue(Val)) {
184 case IntRegClassID: return IntRegType;
185 case FloatRegClassID:
186 Typ = Val->getType()->getPrimitiveID();
187 if (Typ == Type::FloatTyID)
188 return FPSingleRegType;
189 else if (Typ == Type::DoubleTyID)
190 return FPDoubleRegType;
191 assert(0 && "Unknown type in FloatRegClass");
192
193 case IntCCRegClassID: return IntCCRegType;
194 case FloatCCRegClassID: return FloatCCRegType ;
195 default: assert(0 && "Unknown reg class ID");
196 return 0;
197 }
198}
199
200int UltraSparcRegInfo::getRegType(int reg) const {
201 if (reg < 32)
202 return IntRegType;
203 else if (reg < (32 + 32))
204 return FPSingleRegType;
205 else if (reg < (64 + 32))
206 return FPDoubleRegType;
207 else if (reg < (64+32+4))
208 return FloatCCRegType;
209 else if (reg < (64+32+4+2))
210 return IntCCRegType;
211 else
212 assert(0 && "Invalid register number in getRegType");
Chris Lattner49b8a9c2002-02-24 23:02:40 +0000213 return 0;
Chris Lattner699683c2002-02-04 05:59:25 +0000214}
215
216
217
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000218
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000219
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000220//---------------------------------------------------------------------------
Vikram S. Adve53fec862001-10-22 13:41:12 +0000221// Finds the # of actual arguments of the call instruction
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000222//---------------------------------------------------------------------------
Chris Lattner699683c2002-02-04 05:59:25 +0000223unsigned
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000224UltraSparcRegInfo::getCallInstNumArgs(const MachineInstr *CallMI) const {
225
226 unsigned OpCode = CallMI->getOpCode();
Chris Lattner699683c2002-02-04 05:59:25 +0000227 unsigned NumOfImpRefs = CallMI->getNumImplicitRefs();
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000228
Chris Lattner699683c2002-02-04 05:59:25 +0000229 if (OpCode == CALL) {
230 switch (NumOfImpRefs) {
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000231 case 0: assert(0 && "A CALL inst must have at least one ImpRef (RetAddr)");
Chris Lattner699683c2002-02-04 05:59:25 +0000232 case 1: return 0;
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000233 default: // two or more implicit refs
Chris Lattner699683c2002-02-04 05:59:25 +0000234 if (CallMI->implicitRefIsDefined(NumOfImpRefs-2))
235 return NumOfImpRefs - 2;
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000236 else
Chris Lattner699683c2002-02-04 05:59:25 +0000237 return NumOfImpRefs - 1;
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000238 }
Chris Lattner699683c2002-02-04 05:59:25 +0000239 } else if (OpCode == JMPLCALL) {
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000240
241 // The last implicit operand is the return value of a JMPL instr
242 if( NumOfImpRefs > 0 ) {
Chris Lattner699683c2002-02-04 05:59:25 +0000243 if (CallMI->implicitRefIsDefined(NumOfImpRefs-1))
244 return NumOfImpRefs - 1;
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000245 else
Chris Lattner699683c2002-02-04 05:59:25 +0000246 return NumOfImpRefs;
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000247 }
248 else
Chris Lattner699683c2002-02-04 05:59:25 +0000249 return NumOfImpRefs;
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000250 }
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000251
Chris Lattner699683c2002-02-04 05:59:25 +0000252 assert(0 && "OpCode must be CALL/JMPL for a call instr");
253 return 0;
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000254}
255
256
Vikram S. Adve53fec862001-10-22 13:41:12 +0000257
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000258//---------------------------------------------------------------------------
259// Finds whether a call is an indirect call
260//---------------------------------------------------------------------------
261bool UltraSparcRegInfo::isVarArgCall(const MachineInstr *CallMI) const {
262
263 assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) );
264
265 const MachineOperand & calleeOp = CallMI->getOperand(0);
266 Value *calleeVal = calleeOp.getVRegValue();
267
Chris Lattner2aac6bf2002-04-04 22:19:18 +0000268 PointerType *PT = cast<PointerType>(calleeVal->getType());
269 return cast<FunctionType>(PT->getElementType())->isVarArg();
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000270}
271
272
273
274
275//---------------------------------------------------------------------------
276// Suggests a register for the ret address in the RET machine instruction.
277// We always suggest %i7 by convention.
278//---------------------------------------------------------------------------
Chris Lattner699683c2002-02-04 05:59:25 +0000279void UltraSparcRegInfo::suggestReg4RetAddr(const MachineInstr *RetMI,
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000280 LiveRangeInfo& LRI) const {
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000281
Vikram S. Adve53fec862001-10-22 13:41:12 +0000282 assert( (RetMI->getNumOperands() >= 2)
283 && "JMPL/RETURN must have 3 and 2 operands respectively");
284
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000285 MachineOperand & MO = ( MachineOperand &) RetMI->getOperand(0);
286
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000287 // return address is always mapped to i7
288 //
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000289 MO.setRegForValue( getUnifiedRegNum( IntRegClassID, SparcIntRegOrder::i7) );
Vikram S. Adve53fec862001-10-22 13:41:12 +0000290
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000291 // Possible Optimization:
Ruchira Sasankac4d4b762001-10-16 01:23:19 +0000292 // Instead of setting the color, we can suggest one. In that case,
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000293 // we have to test later whether it received the suggested color.
294 // In that case, a LR has to be created at the start of method.
295 // It has to be done as follows (remove the setRegVal above):
Ruchira Sasanka91442282001-09-30 23:16:47 +0000296
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000297 // const Value *RetAddrVal = MO.getVRegValue();
298 // assert( RetAddrVal && "LR for ret address must be created at start");
299 // LiveRange * RetAddrLR = LRI.getLiveRangeForValue( RetAddrVal);
300 // RetAddrLR->setSuggestedColor(getUnifiedRegNum( IntRegClassID,
301 // SparcIntRegOrdr::i7) );
Ruchira Sasanka91442282001-09-30 23:16:47 +0000302}
303
304
305//---------------------------------------------------------------------------
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000306// Suggests a register for the ret address in the JMPL/CALL machine instr.
307// Sparc ABI dictates that %o7 be used for this purpose.
Ruchira Sasanka91442282001-09-30 23:16:47 +0000308//---------------------------------------------------------------------------
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000309void UltraSparcRegInfo::suggestReg4CallAddr(const MachineInstr * CallMI,
310 LiveRangeInfo& LRI,
Chris Lattner697954c2002-01-20 22:54:45 +0000311 std::vector<RegClass *> RCList) const {
Ruchira Sasanka91442282001-09-30 23:16:47 +0000312
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000313
314 const Value *RetAddrVal = getCallInstRetAddr( CallMI );
315
316 // RetAddrVal cannot be NULL (asserted in getCallInstRetAddr)
317 // create a new LR for the return address and color it
318
319 LiveRange * RetAddrLR = new LiveRange();
Chris Lattnerd1b60fb2002-02-04 16:37:09 +0000320 RetAddrLR->insert( RetAddrVal );
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000321 unsigned RegClassID = getRegClassIDOfValue( RetAddrVal );
322 RetAddrLR->setRegClass( RCList[RegClassID] );
323 RetAddrLR->setColor(getUnifiedRegNum(IntRegClassID,SparcIntRegOrder::o7));
324 LRI.addLRToMap( RetAddrVal, RetAddrLR);
325
Ruchira Sasanka91442282001-09-30 23:16:47 +0000326}
327
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000328
329
Ruchira Sasanka91442282001-09-30 23:16:47 +0000330
331//---------------------------------------------------------------------------
332// This method will suggest colors to incoming args to a method.
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000333// According to the Sparc ABI, the first 6 incoming args are in
334// %i0 - %i5 (if they are integer) OR in %f0 - %f31 (if they are float).
Ruchira Sasanka91442282001-09-30 23:16:47 +0000335// If the arg is passed on stack due to the lack of regs, NOTHING will be
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000336// done - it will be colored (or spilled) as a normal live range.
Ruchira Sasanka91442282001-09-30 23:16:47 +0000337//---------------------------------------------------------------------------
Chris Lattnerb7653df2002-04-08 22:03:57 +0000338void UltraSparcRegInfo::suggestRegs4MethodArgs(const Function *Meth,
Ruchira Sasanka91442282001-09-30 23:16:47 +0000339 LiveRangeInfo& LRI) const
Chris Lattner20b1ea02001-09-14 03:47:57 +0000340{
341
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000342 // get the argument list
Chris Lattnerb7653df2002-04-08 22:03:57 +0000343 const Function::ArgumentListType& ArgList = Meth->getArgumentList();
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000344 // get an iterator to arg list
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000345 // for each argument
Chris Lattnerb62fc4a2002-04-09 19:46:27 +0000346 for( unsigned argNo=0; argNo != ArgList.size(); ++argNo) {
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000347 // get the LR of arg
Chris Lattnerb62fc4a2002-04-09 19:46:27 +0000348 LiveRange *LR = LRI.getLiveRangeForValue((const Value *)ArgList[argNo]);
Ruchira Sasanka91442282001-09-30 23:16:47 +0000349 assert( LR && "No live range found for method arg");
350
351 unsigned RegType = getRegType( LR );
352
Chris Lattner20b1ea02001-09-14 03:47:57 +0000353
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000354 // if the arg is in int class - allocate a reg for an int arg
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000355 //
Ruchira Sasanka91442282001-09-30 23:16:47 +0000356 if( RegType == IntRegType ) {
Chris Lattner20b1ea02001-09-14 03:47:57 +0000357
Ruchira Sasanka91442282001-09-30 23:16:47 +0000358 if( argNo < NumOfIntArgRegs) {
359 LR->setSuggestedColor( SparcIntRegOrder::i0 + argNo );
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000360 }
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000361 else {
Ruchira Sasanka91442282001-09-30 23:16:47 +0000362 // Do NOTHING as this will be colored as a normal value.
Chris Lattner1e23ed72001-10-15 18:15:27 +0000363 if (DEBUG_RA) cerr << " Int Regr not suggested for method arg\n";
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000364 }
Ruchira Sasanka91442282001-09-30 23:16:47 +0000365
Chris Lattner20b1ea02001-09-14 03:47:57 +0000366 }
Ruchira Sasanka91442282001-09-30 23:16:47 +0000367 else if( RegType==FPSingleRegType && (argNo*2+1) < NumOfFloatArgRegs)
368 LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2 + 1) );
369
370
371 else if( RegType == FPDoubleRegType && (argNo*2) < NumOfFloatArgRegs)
372 LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2) );
373
Chris Lattner20b1ea02001-09-14 03:47:57 +0000374 }
Chris Lattner20b1ea02001-09-14 03:47:57 +0000375}
376
Ruchira Sasanka91442282001-09-30 23:16:47 +0000377
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000378
379//---------------------------------------------------------------------------
380// This method is called after graph coloring to move incoming args to
381// the correct hardware registers if they did not receive the correct
382// (suggested) color through graph coloring.
383//---------------------------------------------------------------------------
Chris Lattnerb7653df2002-04-08 22:03:57 +0000384void UltraSparcRegInfo::colorMethodArgs(const Function *Meth,
Chris Lattner699683c2002-02-04 05:59:25 +0000385 LiveRangeInfo &LRI,
386 AddedInstrns *FirstAI) const {
Ruchira Sasanka91442282001-09-30 23:16:47 +0000387
388 // get the argument list
Chris Lattnerb7653df2002-04-08 22:03:57 +0000389 const Function::ArgumentListType& ArgList = Meth->getArgumentList();
Ruchira Sasanka91442282001-09-30 23:16:47 +0000390 // get an iterator to arg list
Ruchira Sasanka91442282001-09-30 23:16:47 +0000391 MachineInstr *AdMI;
392
Ruchira Sasanka91442282001-09-30 23:16:47 +0000393 // for each argument
Chris Lattnerb62fc4a2002-04-09 19:46:27 +0000394 for( unsigned argNo=0; argNo != ArgList.size(); ++argNo) {
Ruchira Sasanka91442282001-09-30 23:16:47 +0000395 // get the LR of arg
Chris Lattnerb62fc4a2002-04-09 19:46:27 +0000396 LiveRange *LR = LRI.getLiveRangeForValue((Value*)ArgList[argNo]);
Ruchira Sasanka91442282001-09-30 23:16:47 +0000397 assert( LR && "No live range found for method arg");
398
399
Ruchira Sasanka91442282001-09-30 23:16:47 +0000400 unsigned RegType = getRegType( LR );
401 unsigned RegClassID = (LR->getRegClass())->getID();
402
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000403 // Find whether this argument is coming in a register (if not, on stack)
404 // Also find the correct register that the argument must go (UniArgReg)
405 //
Ruchira Sasanka91442282001-09-30 23:16:47 +0000406 bool isArgInReg = false;
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000407 unsigned UniArgReg = InvalidRegNum; // reg that LR MUST be colored with
Ruchira Sasanka91442282001-09-30 23:16:47 +0000408
409 if( (RegType== IntRegType && argNo < NumOfIntArgRegs)) {
410 isArgInReg = true;
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000411 UniArgReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::i0 + argNo );
Ruchira Sasanka91442282001-09-30 23:16:47 +0000412 }
413 else if(RegType == FPSingleRegType && argNo < NumOfFloatArgRegs) {
414 isArgInReg = true;
415 UniArgReg = getUnifiedRegNum( RegClassID,
416 SparcFloatRegOrder::f0 + argNo*2 + 1 ) ;
417 }
418 else if(RegType == FPDoubleRegType && argNo < NumOfFloatArgRegs) {
419 isArgInReg = true;
420 UniArgReg = getUnifiedRegNum(RegClassID, SparcFloatRegOrder::f0+argNo*2);
421 }
422
423
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000424 if( LR->hasColor() ) { // if this arg received a register
Ruchira Sasanka91442282001-09-30 23:16:47 +0000425
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000426 unsigned UniLRReg = getUnifiedRegNum( RegClassID, LR->getColor() );
427
428 // if LR received the correct color, nothing to do
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000429 //
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000430 if( UniLRReg == UniArgReg )
431 continue;
432
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000433 // We are here because the LR did not receive the suggested
434 // but LR received another register.
435 // Now we have to copy the %i reg (or stack pos of arg)
436 // to the register the LR was colored with.
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000437
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000438 // if the arg is coming in UniArgReg register, it MUST go into
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000439 // the UniLRReg register
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000440 //
Ruchira Sasanka91442282001-09-30 23:16:47 +0000441 if( isArgInReg )
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000442 AdMI = cpReg2RegMI( UniArgReg, UniLRReg, RegType );
Ruchira Sasanka91442282001-09-30 23:16:47 +0000443
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000444 else {
Ruchira Sasanka91442282001-09-30 23:16:47 +0000445
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000446 // Now the arg is coming on stack. Since the LR recieved a register,
447 // we just have to load the arg on stack into that register
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000448 //
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000449 const MachineFrameInfo& frameInfo = target.getFrameInfo();
450 assert(frameInfo.argsOnStackHaveFixedSize());
451
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000452 bool growUp; // find the offset of arg in stack frame
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000453 int firstArg =
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000454 frameInfo.getFirstIncomingArgOffset(MachineCodeForMethod::get(Meth),
455 growUp);
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000456 int offsetFromFP =
457 growUp? firstArg + argNo * frameInfo.getSizeOfEachArgOnStack()
458 : firstArg - argNo * frameInfo.getSizeOfEachArgOnStack();
459
460 AdMI = cpMem2RegMI(getFramePointer(), offsetFromFP,
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000461 UniLRReg, RegType );
462 }
463
464 FirstAI->InstrnsBefore.push_back( AdMI );
465
466 } // if LR received a color
467
468 else {
469
470 // Now, the LR did not receive a color. But it has a stack offset for
471 // spilling.
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000472 // So, if the arg is coming in UniArgReg register, we can just move
473 // that on to the stack pos of LR
474
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000475 if( isArgInReg ) {
Chris Lattner697954c2002-01-20 22:54:45 +0000476 cpReg2MemMI(UniArgReg, getFramePointer(),
477 LR->getSpillOffFromFP(), RegType );
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000478
479 FirstAI->InstrnsBefore.push_back( AdMI );
480 }
481
482 else {
483
484 // Now the arg is coming on stack. Since the LR did NOT
485 // recieved a register as well, it is allocated a stack position. We
486 // can simply change the stack poistion of the LR. We can do this,
487 // since this method is called before any other method that makes
488 // uses of the stack pos of the LR (e.g., updateMachineInstr)
489
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000490 const MachineFrameInfo& frameInfo = target.getFrameInfo();
491 assert(frameInfo.argsOnStackHaveFixedSize());
492
493 bool growUp;
494 int firstArg = frameInfo.getFirstIncomingArgOffset(MachineCodeForMethod::get(Meth), growUp);
495 int offsetFromFP =
496 growUp? firstArg + argNo * frameInfo.getSizeOfEachArgOnStack()
497 : firstArg - argNo * frameInfo.getSizeOfEachArgOnStack();
498
499 LR->modifySpillOffFromFP( offsetFromFP );
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000500 }
Ruchira Sasanka91442282001-09-30 23:16:47 +0000501
502 }
503
Ruchira Sasanka91442282001-09-30 23:16:47 +0000504 } // for each incoming argument
505
506}
507
Chris Lattner20b1ea02001-09-14 03:47:57 +0000508
509
Ruchira Sasanka91442282001-09-30 23:16:47 +0000510//---------------------------------------------------------------------------
511// This method is called before graph coloring to suggest colors to the
512// outgoing call args and the return value of the call.
513//---------------------------------------------------------------------------
Chris Lattner699683c2002-02-04 05:59:25 +0000514void UltraSparcRegInfo::suggestRegs4CallArgs(const MachineInstr *CallMI,
Ruchira Sasanka91442282001-09-30 23:16:47 +0000515 LiveRangeInfo& LRI,
Chris Lattner697954c2002-01-20 22:54:45 +0000516 std::vector<RegClass *> RCList) const {
Chris Lattner20b1ea02001-09-14 03:47:57 +0000517
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000518 assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) );
Chris Lattner20b1ea02001-09-14 03:47:57 +0000519
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000520 suggestReg4CallAddr(CallMI, LRI, RCList);
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000521
Chris Lattner20b1ea02001-09-14 03:47:57 +0000522
Ruchira Sasanka91442282001-09-30 23:16:47 +0000523 // First color the return value of the call instruction. The return value
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000524 // will be in %o0 if the value is an integer type, or in %f0 if the
525 // value is a float type.
526
Ruchira Sasanka91442282001-09-30 23:16:47 +0000527 // the return value cannot have a LR in machine instruction since it is
528 // only defined by the call instruction
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000529
Ruchira Sasanka91442282001-09-30 23:16:47 +0000530 // if type is not void, create a new live range and set its
531 // register class and add to LRI
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000532
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000533
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000534 const Value *RetVal = getCallInstRetVal( CallMI );
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000535
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000536
Chris Lattner699683c2002-02-04 05:59:25 +0000537 if (RetVal) {
538 assert ((!LRI.getLiveRangeForValue(RetVal)) &&
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000539 "LR for ret Value of call already definded!");
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000540
Chris Lattner699683c2002-02-04 05:59:25 +0000541 // create a new LR for the return value
542 LiveRange *RetValLR = new LiveRange();
Chris Lattnerd1b60fb2002-02-04 16:37:09 +0000543 RetValLR->insert(RetVal);
Chris Lattner699683c2002-02-04 05:59:25 +0000544 unsigned RegClassID = getRegClassIDOfValue(RetVal);
545 RetValLR->setRegClass(RCList[RegClassID]);
546 LRI.addLRToMap(RetVal, RetValLR);
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000547
548 // now suggest a register depending on the register class of ret arg
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000549
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000550 if( RegClassID == IntRegClassID )
551 RetValLR->setSuggestedColor(SparcIntRegOrder::o0);
552 else if (RegClassID == FloatRegClassID )
553 RetValLR->setSuggestedColor(SparcFloatRegOrder::f0 );
554 else assert( 0 && "Unknown reg class for return value of call\n");
Chris Lattner20b1ea02001-09-14 03:47:57 +0000555 }
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000556
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000557
Ruchira Sasanka91442282001-09-30 23:16:47 +0000558 // Now suggest colors for arguments (operands) of the call instruction.
559 // Colors are suggested only if the arg number is smaller than the
560 // the number of registers allocated for argument passing.
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000561 // Now, go thru call args - implicit operands of the call MI
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000562
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000563 unsigned NumOfCallArgs = getCallInstNumArgs( CallMI );
Ruchira Sasanka91442282001-09-30 23:16:47 +0000564
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000565 for(unsigned argNo=0, i=0; i < NumOfCallArgs; ++i, ++argNo ) {
566
567 const Value *CallArg = CallMI->getImplicitRef(i);
Ruchira Sasanka91442282001-09-30 23:16:47 +0000568
569 // get the LR of call operand (parameter)
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000570 LiveRange *const LR = LRI.getLiveRangeForValue(CallArg);
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000571
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000572 // not possible to have a null LR since all args (even consts)
573 // must be defined before
Chris Lattner0665a5f2002-02-05 01:43:49 +0000574 if (!LR) {
575 cerr << " ERROR: In call instr, no LR for arg: " << RAV(CallArg) << "\n";
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000576 assert(0 && "NO LR for call arg");
Ruchira Sasanka91442282001-09-30 23:16:47 +0000577 }
578
579 unsigned RegType = getRegType( LR );
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000580
Ruchira Sasanka91442282001-09-30 23:16:47 +0000581 // if the arg is in int class - allocate a reg for an int arg
582 if( RegType == IntRegType ) {
583
584 if( argNo < NumOfIntArgRegs)
585 LR->setSuggestedColor( SparcIntRegOrder::o0 + argNo );
586
587 else if (DEBUG_RA)
588 // Do NOTHING as this will be colored as a normal value.
Chris Lattner697954c2002-01-20 22:54:45 +0000589 cerr << " Regr not suggested for int call arg\n";
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000590
Ruchira Sasanka91442282001-09-30 23:16:47 +0000591 }
592 else if( RegType == FPSingleRegType && (argNo*2 +1)< NumOfFloatArgRegs)
593 LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2 + 1) );
594
595
596 else if( RegType == FPDoubleRegType && (argNo*2) < NumOfFloatArgRegs)
597 LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2) );
598
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000599
Ruchira Sasanka91442282001-09-30 23:16:47 +0000600 } // for all call arguments
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000601
Chris Lattner20b1ea02001-09-14 03:47:57 +0000602}
603
604
Ruchira Sasanka91442282001-09-30 23:16:47 +0000605//---------------------------------------------------------------------------
606// After graph coloring, we have call this method to see whehter the return
607// value and the call args received the correct colors. If not, we have
608// to instert copy instructions.
609//---------------------------------------------------------------------------
Chris Lattner20b1ea02001-09-14 03:47:57 +0000610
Chris Lattner699683c2002-02-04 05:59:25 +0000611void UltraSparcRegInfo::colorCallArgs(const MachineInstr *CallMI,
612 LiveRangeInfo &LRI,
613 AddedInstrns *CallAI,
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000614 PhyRegAlloc &PRA,
615 const BasicBlock *BB) const {
Chris Lattner20b1ea02001-09-14 03:47:57 +0000616
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000617 assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) );
618
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000619 // Reset the optional args area in the stack frame
620 // since that is reused for each call
621 //
622 PRA.mcInfo.resetOptionalArgs(target);
623
Ruchira Sasanka91442282001-09-30 23:16:47 +0000624 // First color the return value of the call.
625 // If there is a LR for the return value, it means this
626 // method returns a value
627
628 MachineInstr *AdMI;
Chris Lattner20b1ea02001-09-14 03:47:57 +0000629
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000630 const Value *RetVal = getCallInstRetVal( CallMI );
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000631
Chris Lattner0665a5f2002-02-05 01:43:49 +0000632 if (RetVal) {
633 LiveRange *RetValLR = LRI.getLiveRangeForValue( RetVal );
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000634
Chris Lattner0665a5f2002-02-05 01:43:49 +0000635 if (!RetValLR) {
636 cerr << "\nNo LR for:" << RAV(RetVal) << "\n";
637 assert(0 && "ERR:No LR for non-void return value");
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000638 }
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000639
640 unsigned RegClassID = (RetValLR->getRegClass())->getID();
641 bool recvCorrectColor = false;
642
643 unsigned CorrectCol; // correct color for ret value
644 if(RegClassID == IntRegClassID)
645 CorrectCol = SparcIntRegOrder::o0;
646 else if(RegClassID == FloatRegClassID)
647 CorrectCol = SparcFloatRegOrder::f0;
Chris Lattner8e5c0b42001-11-07 14:01:59 +0000648 else {
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000649 assert( 0 && "Unknown RegClass");
Chris Lattner8e5c0b42001-11-07 14:01:59 +0000650 return;
651 }
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000652
653 // if the LR received the correct color, NOTHING to do
654
655 if( RetValLR->hasColor() )
656 if( RetValLR->getColor() == CorrectCol )
657 recvCorrectColor = true;
658
659
660 // if we didn't receive the correct color for some reason,
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000661 // put copy instruction
662
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000663 if( !recvCorrectColor ) {
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000664
665 unsigned RegType = getRegType( RetValLR );
666
667 // the reg that LR must be colored with
668 unsigned UniRetReg = getUnifiedRegNum( RegClassID, CorrectCol);
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000669
670 if( RetValLR->hasColor() ) {
671
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000672 unsigned
673 UniRetLRReg=getUnifiedRegNum(RegClassID,RetValLR->getColor());
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000674
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000675 // the return value is coming in UniRetReg but has to go into
676 // the UniRetLRReg
677
678 AdMI = cpReg2RegMI( UniRetReg, UniRetLRReg, RegType );
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000679
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000680 } // if LR has color
681 else {
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000682
683 // if the LR did NOT receive a color, we have to move the return
684 // value coming in UniRetReg to the stack pos of spilled LR
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000685
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000686 AdMI = cpReg2MemMI(UniRetReg, getFramePointer(),
687 RetValLR->getSpillOffFromFP(), RegType );
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000688 }
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000689
690 CallAI->InstrnsAfter.push_back( AdMI );
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000691
692 } // the LR didn't receive the suggested color
693
694 } // if there a return value
Ruchira Sasanka91442282001-09-30 23:16:47 +0000695
696
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000697 //-------------------------------------------
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000698 // Now color all args of the call instruction
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000699 //-------------------------------------------
Ruchira Sasanka91442282001-09-30 23:16:47 +0000700
Chris Lattner697954c2002-01-20 22:54:45 +0000701 std::vector<MachineInstr *> AddedInstrnsBefore;
Ruchira Sasanka868cf822001-11-09 23:49:14 +0000702
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000703 unsigned NumOfCallArgs = getCallInstNumArgs( CallMI );
Ruchira Sasanka91442282001-09-30 23:16:47 +0000704
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000705 bool VarArgCall = isVarArgCall( CallMI );
706
707 if(VarArgCall) cerr << "\nVar arg call found!!\n";
708
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000709 for(unsigned argNo=0, i=0; i < NumOfCallArgs; ++i, ++argNo ) {
710
711 const Value *CallArg = CallMI->getImplicitRef(i);
712
Ruchira Sasanka91442282001-09-30 23:16:47 +0000713 // get the LR of call operand (parameter)
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000714 LiveRange *const LR = LRI.getLiveRangeForValue(CallArg);
Ruchira Sasanka91442282001-09-30 23:16:47 +0000715
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000716 unsigned RegType = getRegType( CallArg );
717 unsigned RegClassID = getRegClassIDOfValue( CallArg);
Ruchira Sasanka91442282001-09-30 23:16:47 +0000718
719 // find whether this argument is coming in a register (if not, on stack)
720
721 bool isArgInReg = false;
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000722 unsigned UniArgReg = InvalidRegNum; // reg that LR must be colored with
Ruchira Sasanka91442282001-09-30 23:16:47 +0000723
724 if( (RegType== IntRegType && argNo < NumOfIntArgRegs)) {
725 isArgInReg = true;
726 UniArgReg = getUnifiedRegNum(RegClassID, SparcIntRegOrder::o0 + argNo );
727 }
728 else if(RegType == FPSingleRegType && argNo < NumOfFloatArgRegs) {
729 isArgInReg = true;
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000730
731 if( !VarArgCall )
732 UniArgReg = getUnifiedRegNum(RegClassID,
733 SparcFloatRegOrder::f0 + (argNo*2 + 1) );
734 else {
735 // a variable argument call - must pass float arg in %o's
736 if( argNo < NumOfIntArgRegs)
737 UniArgReg=getUnifiedRegNum(IntRegClassID,SparcIntRegOrder::o0+argNo);
738 else
739 isArgInReg = false;
740 }
741
Ruchira Sasanka91442282001-09-30 23:16:47 +0000742 }
743 else if(RegType == FPDoubleRegType && argNo < NumOfFloatArgRegs) {
744 isArgInReg = true;
Chris Lattner20b1ea02001-09-14 03:47:57 +0000745
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000746 if( !VarArgCall )
747 UniArgReg =getUnifiedRegNum(RegClassID,SparcFloatRegOrder::f0+argNo*2);
748 else {
749 // a variable argument call - must pass float arg in %o's
750 if( argNo < NumOfIntArgRegs)
751 UniArgReg=getUnifiedRegNum(IntRegClassID,SparcIntRegOrder::o0+argNo);
752 else
753 isArgInReg = false;
754 }
755 }
Chris Lattner20b1ea02001-09-14 03:47:57 +0000756
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000757 // not possible to have a null LR since all args (even consts)
758 // must be defined before
Chris Lattner0665a5f2002-02-05 01:43:49 +0000759 if (!LR) {
760 cerr << " ERROR: In call instr, no LR for arg: " << RAV(CallArg) << "\n";
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000761 assert(0 && "NO LR for call arg");
Ruchira Sasanka91442282001-09-30 23:16:47 +0000762 }
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000763
Ruchira Sasanka91442282001-09-30 23:16:47 +0000764
Chris Lattner699683c2002-02-04 05:59:25 +0000765 if (LR->hasColor()) {
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000766 unsigned UniLRReg = getUnifiedRegNum( RegClassID, LR->getColor() );
767
768 // if LR received the correct color, nothing to do
769 if( UniLRReg == UniArgReg )
770 continue;
771
Ruchira Sasanka91442282001-09-30 23:16:47 +0000772 // We are here because though the LR is allocated a register, it
773 // was not allocated the suggested register. So, we have to copy %ix reg
774 // (or stack pos of arg) to the register it was colored with
775
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000776 // the LR is colored with UniLRReg but has to go into UniArgReg
777 // to pass it as an argument
Ruchira Sasanka91442282001-09-30 23:16:47 +0000778
Ruchira Sasanka9d478662001-11-12 20:54:19 +0000779 if( isArgInReg ) {
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000780
781 if( VarArgCall && RegClassID == FloatRegClassID ) {
782
783
784 // for a variable argument call, the float reg must go in a %o reg.
785 // We have to move a float reg to an int reg via memory.
786 // The store instruction will be directly added to
787 // CallAI->InstrnsBefore since it does not need reordering
788 //
789 int TmpOff = PRA.mcInfo.pushTempValue(target,
790 getSpilledRegSize(RegType));
791
792 AdMI = cpReg2MemMI(UniLRReg, getFramePointer(), TmpOff, RegType );
793 CallAI->InstrnsBefore.push_back( AdMI );
794
795 AdMI = cpMem2RegMI(getFramePointer(), TmpOff, UniArgReg, IntRegType);
796 AddedInstrnsBefore.push_back( AdMI );
797 }
798
799 else {
800 AdMI = cpReg2RegMI(UniLRReg, UniArgReg, RegType );
801 AddedInstrnsBefore.push_back( AdMI );
802 }
803
Chris Lattner699683c2002-02-04 05:59:25 +0000804 } else {
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000805 // Now, we have to pass the arg on stack. Since LR received a register
806 // we just have to move that register to the stack position where
807 // the argument must be passed
Ruchira Sasanka91442282001-09-30 23:16:47 +0000808
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000809 int argOffset = PRA.mcInfo.allocateOptionalArg(target, LR->getType());
Ruchira Sasanka91442282001-09-30 23:16:47 +0000810
Ruchira Sasankac56e5c12001-11-11 22:37:51 +0000811 AdMI = cpReg2MemMI(UniLRReg, getStackPointer(), argOffset, RegType );
Ruchira Sasanka9d478662001-11-12 20:54:19 +0000812
813 // Now add the instruction. We can directly add to
814 // CallAI->InstrnsBefore since we are just saving a reg on stack
815 //
816 CallAI->InstrnsBefore.push_back( AdMI );
817
818 //cerr << "\nCaution: Passing a reg on stack";
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000819 }
820
Ruchira Sasanka9d478662001-11-12 20:54:19 +0000821
Chris Lattner699683c2002-02-04 05:59:25 +0000822 } else { // LR is not colored (i.e., spilled)
Ruchira Sasanka91442282001-09-30 23:16:47 +0000823
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000824 if( isArgInReg ) {
825
826 // Now the LR did NOT recieve a register but has a stack poistion.
827 // Since, the outgoing arg goes in a register we just have to insert
828 // a load instruction to load the LR to outgoing register
829
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000830 if( VarArgCall && RegClassID == FloatRegClassID )
831 AdMI = cpMem2RegMI(getFramePointer(), LR->getSpillOffFromFP(),
832 UniArgReg, IntRegType );
833 else
834 AdMI = cpMem2RegMI(getFramePointer(), LR->getSpillOffFromFP(),
835 UniArgReg, RegType );
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000836
Ruchira Sasanka91014f62001-11-12 20:31:47 +0000837 cerr << "\nCaution: Loading a spilled val to a reg as a call arg";
Ruchira Sasanka868cf822001-11-09 23:49:14 +0000838 AddedInstrnsBefore.push_back( AdMI ); // Now add the instruction
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000839 }
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000840
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000841 else {
842 // Now, we have to pass the arg on stack. Since LR also did NOT
843 // receive a register we have to move an argument in memory to
844 // outgoing parameter on stack.
845
846 // Optoimize: Optimize when reverse pointers in MahineInstr are
847 // introduced.
848 // call PRA.getUnusedRegAtMI(....) to get an unused reg. Only if this
849 // fails, then use the following code. Currently, we cannot call the
850 // above method since we cannot find LVSetBefore without the BB
851
Ruchira Sasanka295264d2001-11-15 20:25:07 +0000852 int TReg = PRA.getUniRegNotUsedByThisInst( LR->getRegClass(), CallMI );
Ruchira Sasanka868cf822001-11-09 23:49:14 +0000853
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000854 int TmpOff = PRA.mcInfo.pushTempValue(target,
855 getSpilledRegSize(getRegType(LR)) );
856
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000857
858 int argOffset = PRA.mcInfo.allocateOptionalArg(target, LR->getType());
859
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000860 MachineInstr *Ad1, *Ad2, *Ad3, *Ad4;
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000861
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000862 // Sequence:
863 // (1) Save TReg on stack
864 // (2) Load LR value into TReg from stack pos of LR
865 // (3) Store Treg on outgoing Arg pos on stack
866 // (4) Load the old value of TReg from stack to TReg (restore it)
867
868 Ad1 = cpReg2MemMI(TReg, getFramePointer(), TmpOff, RegType );
869 Ad2 = cpMem2RegMI(getFramePointer(), LR->getSpillOffFromFP(),
870 TReg, RegType );
Ruchira Sasankac56e5c12001-11-11 22:37:51 +0000871 Ad3 = cpReg2MemMI(TReg, getStackPointer(), argOffset, RegType );
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000872 Ad4 = cpMem2RegMI(getFramePointer(), TmpOff, TReg, RegType );
Ruchira Sasanka868cf822001-11-09 23:49:14 +0000873
874 // We directly add to CallAI->InstrnsBefore instead of adding to
875 // AddedInstrnsBefore since these instructions must not be
876 // reordered.
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000877
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000878 CallAI->InstrnsBefore.push_back( Ad1 );
879 CallAI->InstrnsBefore.push_back( Ad2 );
880 CallAI->InstrnsBefore.push_back( Ad3 );
881 CallAI->InstrnsBefore.push_back( Ad4 );
Ruchira Sasanka868cf822001-11-09 23:49:14 +0000882
Ruchira Sasanka91014f62001-11-12 20:31:47 +0000883 cerr << "\nCaution: Call arg moved from stack2stack for: " << *CallMI ;
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000884 }
Ruchira Sasanka91442282001-09-30 23:16:47 +0000885 }
Ruchira Sasanka91442282001-09-30 23:16:47 +0000886 } // for each parameter in call instruction
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000887
Ruchira Sasanka868cf822001-11-09 23:49:14 +0000888
889 // if we added any instruction before the call instruction, verify
890 // that they are in the proper order and if not, reorder them
891
Chris Lattner699683c2002-02-04 05:59:25 +0000892 if (!AddedInstrnsBefore.empty()) {
Ruchira Sasanka868cf822001-11-09 23:49:14 +0000893
Chris Lattner699683c2002-02-04 05:59:25 +0000894 if (DEBUG_RA) {
Ruchira Sasanka868cf822001-11-09 23:49:14 +0000895 cerr << "\nCalling reorder with instrns: \n";
896 for(unsigned i=0; i < AddedInstrnsBefore.size(); i++)
897 cerr << *(AddedInstrnsBefore[i]);
898 }
899
Chris Lattner697954c2002-01-20 22:54:45 +0000900 std::vector<MachineInstr *> TmpVec;
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +0000901 OrderAddedInstrns(AddedInstrnsBefore, TmpVec, PRA);
Ruchira Sasanka868cf822001-11-09 23:49:14 +0000902
Chris Lattner699683c2002-02-04 05:59:25 +0000903 if (DEBUG_RA) {
Ruchira Sasanka868cf822001-11-09 23:49:14 +0000904 cerr << "\nAfter reordering instrns: \n";
Chris Lattner699683c2002-02-04 05:59:25 +0000905 for(unsigned i = 0; i < TmpVec.size(); i++)
906 cerr << *TmpVec[i];
Ruchira Sasanka868cf822001-11-09 23:49:14 +0000907 }
908
909 // copy the results back from TmpVec to InstrnsBefore
910 for(unsigned i=0; i < TmpVec.size(); i++)
911 CallAI->InstrnsBefore.push_back( TmpVec[i] );
912 }
913
914
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000915 // now insert caller saving code for this call instruction
916 //
917 insertCallerSavingCode(CallMI, BB, PRA);
918
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000919 // Reset optional args area again to be safe
Vikram S. Adve1c0fba62001-11-08 04:56:41 +0000920 PRA.mcInfo.resetOptionalArgs(target);
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000921}
922
Ruchira Sasanka91442282001-09-30 23:16:47 +0000923//---------------------------------------------------------------------------
924// This method is called for an LLVM return instruction to identify which
925// values will be returned from this method and to suggest colors.
926//---------------------------------------------------------------------------
Chris Lattner699683c2002-02-04 05:59:25 +0000927void UltraSparcRegInfo::suggestReg4RetValue(const MachineInstr *RetMI,
928 LiveRangeInfo &LRI) const {
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000929
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000930 assert( (UltraSparcInfo->getInstrInfo()).isReturn( RetMI->getOpCode() ) );
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000931
Ruchira Sasanka88dedc12001-10-23 21:40:39 +0000932 suggestReg4RetAddr(RetMI, LRI);
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000933
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000934 // if there is an implicit ref, that has to be the ret value
935 if( RetMI->getNumImplicitRefs() > 0 ) {
Ruchira Sasanka91442282001-09-30 23:16:47 +0000936
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000937 // The first implicit operand is the return value of a return instr
938 const Value *RetVal = RetMI->getImplicitRef(0);
Ruchira Sasanka91442282001-09-30 23:16:47 +0000939
Ruchira Sasanka91442282001-09-30 23:16:47 +0000940 LiveRange *const LR = LRI.getLiveRangeForValue( RetVal );
Ruchira Sasanka91442282001-09-30 23:16:47 +0000941
Chris Lattner0665a5f2002-02-05 01:43:49 +0000942 if (!LR) {
943 cerr << "\nNo LR for:" << RAV(RetVal) << "\n";
944 assert(0 && "No LR for return value of non-void method");
945 }
Ruchira Sasanka91442282001-09-30 23:16:47 +0000946
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000947 unsigned RegClassID = (LR->getRegClass())->getID();
Ruchira Sasanka91442282001-09-30 23:16:47 +0000948
Chris Lattner699683c2002-02-04 05:59:25 +0000949 if (RegClassID == IntRegClassID)
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000950 LR->setSuggestedColor(SparcIntRegOrder::i0);
Chris Lattner699683c2002-02-04 05:59:25 +0000951 else if (RegClassID == FloatRegClassID)
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000952 LR->setSuggestedColor(SparcFloatRegOrder::f0);
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000953 }
Ruchira Sasanka91442282001-09-30 23:16:47 +0000954}
955
Ruchira Sasanka91442282001-09-30 23:16:47 +0000956
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000957
958//---------------------------------------------------------------------------
959// Colors the return value of a method to %i0 or %f0, if possible. If it is
960// not possilbe to directly color the LR, insert a copy instruction to move
961// the LR to %i0 or %f0. When the LR is spilled, instead of the copy, we
962// have to put a load instruction.
Ruchira Sasanka91442282001-09-30 23:16:47 +0000963//---------------------------------------------------------------------------
Chris Lattner699683c2002-02-04 05:59:25 +0000964void UltraSparcRegInfo::colorRetValue(const MachineInstr *RetMI,
965 LiveRangeInfo &LRI,
966 AddedInstrns *RetAI) const {
Ruchira Sasanka91442282001-09-30 23:16:47 +0000967
Chris Lattner699683c2002-02-04 05:59:25 +0000968 assert((UltraSparcInfo->getInstrInfo()).isReturn( RetMI->getOpCode()));
Ruchira Sasanka91442282001-09-30 23:16:47 +0000969
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000970 // if there is an implicit ref, that has to be the ret value
Chris Lattner699683c2002-02-04 05:59:25 +0000971 if(RetMI->getNumImplicitRefs() > 0) {
Ruchira Sasanka91442282001-09-30 23:16:47 +0000972
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000973 // The first implicit operand is the return value of a return instr
974 const Value *RetVal = RetMI->getImplicitRef(0);
Ruchira Sasanka91442282001-09-30 23:16:47 +0000975
Chris Lattner699683c2002-02-04 05:59:25 +0000976 LiveRange *LR = LRI.getLiveRangeForValue(RetVal);
Ruchira Sasanka91442282001-09-30 23:16:47 +0000977
Chris Lattner0665a5f2002-02-05 01:43:49 +0000978 if (!LR) {
979 cerr << "\nNo LR for:" << RAV(RetVal) << "\n";
980 // assert( LR && "No LR for return value of non-void method");
981 return;
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000982 }
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000983
Ruchira Sasanka91442282001-09-30 23:16:47 +0000984 unsigned RegClassID = getRegClassIDOfValue(RetVal);
985 unsigned RegType = getRegType( RetVal );
Ruchira Sasanka88dedc12001-10-23 21:40:39 +0000986
Ruchira Sasanka88dedc12001-10-23 21:40:39 +0000987 unsigned CorrectCol;
Ruchira Sasanka91442282001-09-30 23:16:47 +0000988 if(RegClassID == IntRegClassID)
Ruchira Sasanka88dedc12001-10-23 21:40:39 +0000989 CorrectCol = SparcIntRegOrder::i0;
Ruchira Sasanka91442282001-09-30 23:16:47 +0000990 else if(RegClassID == FloatRegClassID)
Ruchira Sasanka88dedc12001-10-23 21:40:39 +0000991 CorrectCol = SparcFloatRegOrder::f0;
Chris Lattner8e5c0b42001-11-07 14:01:59 +0000992 else {
Chris Lattner699683c2002-02-04 05:59:25 +0000993 assert (0 && "Unknown RegClass");
Chris Lattner8e5c0b42001-11-07 14:01:59 +0000994 return;
995 }
Ruchira Sasanka91442282001-09-30 23:16:47 +0000996
Ruchira Sasankac74a7202001-10-24 15:56:58 +0000997 // if the LR received the correct color, NOTHING to do
Ruchira Sasanka91442282001-09-30 23:16:47 +0000998
Chris Lattner699683c2002-02-04 05:59:25 +0000999 if (LR->hasColor() && LR->getColor() == CorrectCol)
1000 return;
Ruchira Sasanka88dedc12001-10-23 21:40:39 +00001001
Chris Lattner699683c2002-02-04 05:59:25 +00001002 unsigned UniRetReg = getUnifiedRegNum(RegClassID, CorrectCol);
Ruchira Sasanka91442282001-09-30 23:16:47 +00001003
Chris Lattner699683c2002-02-04 05:59:25 +00001004 if (LR->hasColor()) {
Ruchira Sasanka91442282001-09-30 23:16:47 +00001005
Ruchira Sasanka88dedc12001-10-23 21:40:39 +00001006 // We are here because the LR was allocted a regiter
1007 // It may be the suggested register or not
Ruchira Sasanka91442282001-09-30 23:16:47 +00001008
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +00001009 // copy the LR of retun value to i0 or f0
Ruchira Sasanka91442282001-09-30 23:16:47 +00001010
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +00001011 unsigned UniLRReg =getUnifiedRegNum( RegClassID, LR->getColor());
Ruchira Sasanka91442282001-09-30 23:16:47 +00001012
Ruchira Sasankac74a7202001-10-24 15:56:58 +00001013 // the LR received UniLRReg but must be colored with UniRetReg
1014 // to pass as the return value
Chris Lattner697954c2002-01-20 22:54:45 +00001015 RetAI->InstrnsBefore.push_back(cpReg2RegMI(UniLRReg, UniRetReg, RegType));
Ruchira Sasanka91442282001-09-30 23:16:47 +00001016 }
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001017 else { // if the LR is spilled
Chris Lattner697954c2002-01-20 22:54:45 +00001018 MachineInstr *AdMI = cpMem2RegMI(getFramePointer(),
1019 LR->getSpillOffFromFP(),
1020 UniRetReg, RegType);
1021 RetAI->InstrnsBefore.push_back(AdMI);
1022 cerr << "\nCopied the return value from stack\n";
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001023 }
1024
Ruchira Sasanka91442282001-09-30 23:16:47 +00001025 } // if there is a return value
1026
1027}
1028
1029
1030//---------------------------------------------------------------------------
1031// Copy from a register to register. Register number must be the unified
1032// register number
1033//---------------------------------------------------------------------------
1034
Chris Lattner699683c2002-02-04 05:59:25 +00001035MachineInstr * UltraSparcRegInfo::cpReg2RegMI(unsigned SrcReg, unsigned DestReg,
1036 int RegType) const {
Ruchira Sasanka91442282001-09-30 23:16:47 +00001037
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001038 assert( ((int)SrcReg != InvalidRegNum) && ((int)DestReg != InvalidRegNum) &&
Ruchira Sasanka91442282001-09-30 23:16:47 +00001039 "Invalid Register");
1040
1041 MachineInstr * MI = NULL;
1042
1043 switch( RegType ) {
1044
1045 case IntRegType:
Ruchira Sasanka735d6e32001-10-18 22:38:52 +00001046 case IntCCRegType:
1047 case FloatCCRegType:
Ruchira Sasanka91442282001-09-30 23:16:47 +00001048 MI = new MachineInstr(ADD, 3);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001049 MI->SetMachineOperandReg(0, SrcReg, false);
1050 MI->SetMachineOperandReg(1, this->getZeroRegNum(), false);
1051 MI->SetMachineOperandReg(2, DestReg, true);
Ruchira Sasanka91442282001-09-30 23:16:47 +00001052 break;
1053
1054 case FPSingleRegType:
1055 MI = new MachineInstr(FMOVS, 2);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001056 MI->SetMachineOperandReg(0, SrcReg, false);
1057 MI->SetMachineOperandReg(1, DestReg, true);
Ruchira Sasanka91442282001-09-30 23:16:47 +00001058 break;
1059
1060 case FPDoubleRegType:
1061 MI = new MachineInstr(FMOVD, 2);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001062 MI->SetMachineOperandReg(0, SrcReg, false);
1063 MI->SetMachineOperandReg(1, DestReg, true);
Ruchira Sasanka91442282001-09-30 23:16:47 +00001064 break;
1065
1066 default:
1067 assert(0 && "Unknow RegType");
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00001068 }
1069
1070 return MI;
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00001071}
Chris Lattner20b1ea02001-09-14 03:47:57 +00001072
1073
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001074//---------------------------------------------------------------------------
Ruchira Sasanka7dcd6122001-10-24 22:05:34 +00001075// Copy from a register to memory (i.e., Store). Register number must
1076// be the unified register number
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001077//---------------------------------------------------------------------------
1078
1079
Chris Lattner699683c2002-02-04 05:59:25 +00001080MachineInstr * UltraSparcRegInfo::cpReg2MemMI(unsigned SrcReg,
1081 unsigned DestPtrReg,
1082 int Offset, int RegType) const {
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001083 MachineInstr * MI = NULL;
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001084 switch( RegType ) {
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001085 case IntRegType:
Ruchira Sasanka735d6e32001-10-18 22:38:52 +00001086 case FloatCCRegType:
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001087 MI = new MachineInstr(STX, 3);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001088 MI->SetMachineOperandReg(0, SrcReg, false);
1089 MI->SetMachineOperandReg(1, DestPtrReg, false);
1090 MI->SetMachineOperandConst(2, MachineOperand:: MO_SignExtendedImmed,
1091 (int64_t) Offset);
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001092 break;
1093
1094 case FPSingleRegType:
1095 MI = new MachineInstr(ST, 3);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001096 MI->SetMachineOperandReg(0, SrcReg, false);
1097 MI->SetMachineOperandReg(1, DestPtrReg, false);
1098 MI->SetMachineOperandConst(2, MachineOperand:: MO_SignExtendedImmed,
1099 (int64_t) Offset);
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001100 break;
1101
1102 case FPDoubleRegType:
1103 MI = new MachineInstr(STD, 3);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001104 MI->SetMachineOperandReg(0, SrcReg, false);
1105 MI->SetMachineOperandReg(1, DestPtrReg, false);
1106 MI->SetMachineOperandConst(2, MachineOperand:: MO_SignExtendedImmed,
1107 (int64_t) Offset);
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001108 break;
1109
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001110 case IntCCRegType:
1111 assert( 0 && "Cannot directly store %ccr to memory");
1112
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001113 default:
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001114 assert(0 && "Unknow RegType in cpReg2MemMI");
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001115 }
1116
1117 return MI;
1118}
1119
1120
1121//---------------------------------------------------------------------------
Ruchira Sasanka7dcd6122001-10-24 22:05:34 +00001122// Copy from memory to a reg (i.e., Load) Register number must be the unified
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001123// register number
1124//---------------------------------------------------------------------------
1125
1126
Chris Lattner699683c2002-02-04 05:59:25 +00001127MachineInstr * UltraSparcRegInfo::cpMem2RegMI(unsigned SrcPtrReg,
1128 int Offset,
1129 unsigned DestReg,
1130 int RegType) const {
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001131 MachineInstr * MI = NULL;
Chris Lattner699683c2002-02-04 05:59:25 +00001132 switch (RegType) {
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001133 case IntRegType:
Ruchira Sasanka735d6e32001-10-18 22:38:52 +00001134 case FloatCCRegType:
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001135 MI = new MachineInstr(LDX, 3);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001136 MI->SetMachineOperandReg(0, SrcPtrReg, false);
1137 MI->SetMachineOperandConst(1, MachineOperand:: MO_SignExtendedImmed,
1138 (int64_t) Offset);
1139 MI->SetMachineOperandReg(2, DestReg, true);
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001140 break;
1141
1142 case FPSingleRegType:
1143 MI = new MachineInstr(LD, 3);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001144 MI->SetMachineOperandReg(0, SrcPtrReg, false);
1145 MI->SetMachineOperandConst(1, MachineOperand:: MO_SignExtendedImmed,
1146 (int64_t) Offset);
1147 MI->SetMachineOperandReg(2, DestReg, true);
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001148
1149 break;
1150
1151 case FPDoubleRegType:
1152 MI = new MachineInstr(LDD, 3);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001153 MI->SetMachineOperandReg(0, SrcPtrReg, false);
1154 MI->SetMachineOperandConst(1, MachineOperand:: MO_SignExtendedImmed,
1155 (int64_t) Offset);
1156 MI->SetMachineOperandReg(2, DestReg, true);
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001157 break;
1158
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001159 case IntCCRegType:
1160 assert( 0 && "Cannot directly load into %ccr from memory");
1161
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001162 default:
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001163 assert(0 && "Unknown RegType in cpMem2RegMI");
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001164 }
1165
1166 return MI;
1167}
1168
1169
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001170
1171
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001172
Ruchira Sasanka67a463a2001-11-12 14:45:33 +00001173//---------------------------------------------------------------------------
1174// Generate a copy instruction to copy a value to another. Temporarily
1175// used by PhiElimination code.
1176//---------------------------------------------------------------------------
1177
1178
Chris Lattner699683c2002-02-04 05:59:25 +00001179MachineInstr *UltraSparcRegInfo::cpValue2Value(Value *Src, Value *Dest) const {
Ruchira Sasanka67a463a2001-11-12 14:45:33 +00001180 int RegType = getRegType( Src );
1181
1182 assert( (RegType==getRegType(Src)) && "Src & Dest are diff types");
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001183
Ruchira Sasankaef1b0cb2001-11-03 17:13:27 +00001184 MachineInstr * MI = NULL;
1185
Ruchira Sasanka67a463a2001-11-12 14:45:33 +00001186 switch( RegType ) {
Ruchira Sasanka67a463a2001-11-12 14:45:33 +00001187 case IntRegType:
Ruchira Sasanka67a463a2001-11-12 14:45:33 +00001188 MI = new MachineInstr(ADD, 3);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001189 MI->SetMachineOperandVal(0, MachineOperand:: MO_VirtualRegister, Src, false);
1190 MI->SetMachineOperandReg(1, this->getZeroRegNum(), false);
1191 MI->SetMachineOperandVal(2, MachineOperand:: MO_VirtualRegister, Dest, true);
Ruchira Sasanka67a463a2001-11-12 14:45:33 +00001192 break;
1193
1194 case FPSingleRegType:
1195 MI = new MachineInstr(FMOVS, 2);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001196 MI->SetMachineOperandVal(0, MachineOperand:: MO_VirtualRegister, Src, false);
1197 MI->SetMachineOperandVal(1, MachineOperand:: MO_VirtualRegister, Dest, true);
Ruchira Sasanka67a463a2001-11-12 14:45:33 +00001198 break;
1199
1200
1201 case FPDoubleRegType:
1202 MI = new MachineInstr(FMOVD, 2);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001203 MI->SetMachineOperandVal(0, MachineOperand:: MO_VirtualRegister, Src, false);
1204 MI->SetMachineOperandVal(1, MachineOperand:: MO_VirtualRegister, Dest, true);
Ruchira Sasanka67a463a2001-11-12 14:45:33 +00001205 break;
1206
1207 default:
1208 assert(0 && "Unknow RegType in CpValu2Value");
1209 }
Ruchira Sasankaef1b0cb2001-11-03 17:13:27 +00001210
1211 return MI;
Ruchira Sasankaef1b0cb2001-11-03 17:13:27 +00001212}
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001213
1214
1215
Ruchira Sasanka67a463a2001-11-12 14:45:33 +00001216
1217
1218
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001219//----------------------------------------------------------------------------
1220// This method inserts caller saving/restoring instructons before/after
Ruchira Sasankabf915522002-01-07 21:03:42 +00001221// a call machine instruction. The caller saving/restoring instructions are
1222// inserted like:
1223//
1224// ** caller saving instructions
1225// other instructions inserted for the call by ColorCallArg
1226// CALL instruction
1227// other instructions inserted for the call ColorCallArg
1228// ** caller restoring instructions
1229//
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001230//----------------------------------------------------------------------------
Ruchira Sasankac4d4b762001-10-16 01:23:19 +00001231
Ruchira Sasanka91442282001-09-30 23:16:47 +00001232
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001233void UltraSparcRegInfo::insertCallerSavingCode(const MachineInstr *MInst,
1234 const BasicBlock *BB,
1235 PhyRegAlloc &PRA) const {
Ruchira Sasanka91442282001-09-30 23:16:47 +00001236
Ruchira Sasankabf915522002-01-07 21:03:42 +00001237 // has set to record which registers were saved/restored
1238 //
Chris Lattner697954c2002-01-20 22:54:45 +00001239 std::hash_set<unsigned> PushedRegSet;
Ruchira Sasankabf915522002-01-07 21:03:42 +00001240
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001241 // Now find the LR of the return value of the call
1242 // The last *implicit operand* is the return value of a call
1243 // Insert it to to he PushedRegSet since we must not save that register
1244 // and restore it after the call.
1245 // We do this because, we look at the LV set *after* the instruction
1246 // to determine, which LRs must be saved across calls. The return value
1247 // of the call is live in this set - but we must not save/restore it.
Ruchira Sasanka91442282001-09-30 23:16:47 +00001248
1249
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001250 const Value *RetVal = getCallInstRetVal( MInst );
Ruchira Sasanka91442282001-09-30 23:16:47 +00001251
Chris Lattner699683c2002-02-04 05:59:25 +00001252 if (RetVal) {
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001253 LiveRange *RetValLR = PRA.LRI.getLiveRangeForValue( RetVal );
Chris Lattner699683c2002-02-04 05:59:25 +00001254 assert(RetValLR && "No LR for RetValue of call");
Ruchira Sasanka91442282001-09-30 23:16:47 +00001255
Chris Lattner699683c2002-02-04 05:59:25 +00001256 if (RetValLR->hasColor())
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001257 PushedRegSet.insert(
1258 getUnifiedRegNum((RetValLR->getRegClass())->getID(),
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001259 RetValLR->getColor() ) );
Ruchira Sasanka91442282001-09-30 23:16:47 +00001260 }
1261
1262
Chris Lattner748697d2002-02-05 04:20:12 +00001263 const ValueSet &LVSetAft = PRA.LVI->getLiveVarSetAfterMInst(MInst, BB);
1264 ValueSet::const_iterator LIt = LVSetAft.begin();
Ruchira Sasanka91442282001-09-30 23:16:47 +00001265
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001266 // for each live var in live variable set after machine inst
Chris Lattner748697d2002-02-05 04:20:12 +00001267 for( ; LIt != LVSetAft.end(); ++LIt) {
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001268
1269 // get the live range corresponding to live var
1270 LiveRange *const LR = PRA.LRI.getLiveRangeForValue(*LIt );
1271
1272 // LR can be null if it is a const since a const
1273 // doesn't have a dominating def - see Assumptions above
1274 if( LR ) {
1275
1276 if( LR->hasColor() ) {
1277
1278 unsigned RCID = (LR->getRegClass())->getID();
1279 unsigned Color = LR->getColor();
1280
1281 if ( isRegVolatile(RCID, Color) ) {
1282
1283 // if the value is in both LV sets (i.e., live before and after
1284 // the call machine instruction)
1285
1286 unsigned Reg = getUnifiedRegNum(RCID, Color);
1287
1288 if( PushedRegSet.find(Reg) == PushedRegSet.end() ) {
1289
1290 // if we haven't already pushed that register
1291
1292 unsigned RegType = getRegType( LR );
1293
1294 // Now get two instructions - to push on stack and pop from stack
1295 // and add them to InstrnsBefore and InstrnsAfter of the
1296 // call instruction
1297
Ruchira Sasankad00982a2002-01-07 19:20:28 +00001298
1299 int StackOff = PRA.mcInfo.pushTempValue(target,
1300 getSpilledRegSize(RegType));
1301
Vikram S. Adve1c0fba62001-11-08 04:56:41 +00001302
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001303 MachineInstr *AdIBefCC=NULL, *AdIAftCC=NULL, *AdICpCC;
1304 MachineInstr *AdIBef=NULL, *AdIAft=NULL;
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001305
1306 //---- Insert code for pushing the reg on stack ----------
1307
1308 if( RegType == IntCCRegType ) {
1309
1310 // Handle IntCCRegType specially since we cannot directly
1311 // push %ccr on to the stack
1312
Chris Lattner748697d2002-02-05 04:20:12 +00001313 const ValueSet &LVSetBef =
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001314 PRA.LVI->getLiveVarSetBeforeMInst(MInst, BB);
1315
1316 // get a free INTEGER register
1317 int FreeIntReg =
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001318 PRA.getUsableUniRegAtMI(PRA.getRegClassByID(IntRegClassID) /*LR->getRegClass()*/,
1319 IntRegType, MInst, &LVSetBef, AdIBefCC, AdIAftCC);
1320
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001321 // insert the instructions in reverse order since we are
1322 // adding them to the front of InstrnsBefore
1323
1324 if(AdIAftCC)
Chris Lattner0b0ffa02002-04-09 05:13:04 +00001325 PRA.AddedInstrMap[MInst].InstrnsBefore.push_front(AdIAftCC);
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001326
1327 AdICpCC = cpCCR2IntMI(FreeIntReg);
Chris Lattner0b0ffa02002-04-09 05:13:04 +00001328 PRA.AddedInstrMap[MInst].InstrnsBefore.push_front(AdICpCC);
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001329
1330 if(AdIBefCC)
Chris Lattner0b0ffa02002-04-09 05:13:04 +00001331 PRA.AddedInstrMap[MInst].InstrnsBefore.push_front(AdIBefCC);
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001332
Ruchira Sasankaaa12a782001-11-10 00:26:55 +00001333 if(DEBUG_RA) {
1334 cerr << "\n!! Inserted caller saving (push) inst for %ccr:";
1335 if(AdIBefCC) cerr << "\t" << *(AdIBefCC);
1336 cerr << "\t" << *AdICpCC;
1337 if(AdIAftCC) cerr << "\t" << *(AdIAftCC);
1338 }
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001339
1340 } else {
1341 // for any other register type, just add the push inst
Ruchira Sasanka6beb0132001-11-11 21:49:37 +00001342 AdIBef = cpReg2MemMI(Reg, getFramePointer(), StackOff, RegType );
Chris Lattner0b0ffa02002-04-09 05:13:04 +00001343 PRA.AddedInstrMap[MInst].InstrnsBefore.push_front(AdIBef);
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001344 }
1345
1346
1347 //---- Insert code for popping the reg from the stack ----------
1348
Chris Lattner748697d2002-02-05 04:20:12 +00001349 if (RegType == IntCCRegType) {
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001350
1351 // Handle IntCCRegType specially since we cannot directly
1352 // pop %ccr on from the stack
1353
1354 // get a free INT register
1355 int FreeIntReg =
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001356 PRA.getUsableUniRegAtMI(PRA.getRegClassByID(IntRegClassID) /* LR->getRegClass()*/,
1357 IntRegType, MInst, &LVSetAft, AdIBefCC, AdIAftCC);
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001358
1359 if(AdIBefCC)
Chris Lattner0b0ffa02002-04-09 05:13:04 +00001360 PRA.AddedInstrMap[MInst].InstrnsAfter.push_back(AdIBefCC);
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001361
1362 AdICpCC = cpInt2CCRMI(FreeIntReg);
Chris Lattner0b0ffa02002-04-09 05:13:04 +00001363 PRA.AddedInstrMap[MInst].InstrnsAfter.push_back(AdICpCC);
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001364
1365 if(AdIAftCC)
Chris Lattner0b0ffa02002-04-09 05:13:04 +00001366 PRA.AddedInstrMap[MInst].InstrnsAfter.push_back(AdIAftCC);
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001367
Ruchira Sasankaaa12a782001-11-10 00:26:55 +00001368 if(DEBUG_RA) {
1369
1370 cerr << "\n!! Inserted caller saving (pop) inst for %ccr:";
1371 if(AdIBefCC) cerr << "\t" << *(AdIBefCC);
1372 cerr << "\t" << *AdICpCC;
1373 if(AdIAftCC) cerr << "\t" << *(AdIAftCC);
1374 }
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001375
1376 } else {
1377 // for any other register type, just add the pop inst
Ruchira Sasanka6beb0132001-11-11 21:49:37 +00001378 AdIAft = cpMem2RegMI(getFramePointer(), StackOff, Reg, RegType );
Chris Lattner0b0ffa02002-04-09 05:13:04 +00001379 PRA.AddedInstrMap[MInst].InstrnsAfter.push_back(AdIAft);
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001380 }
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001381
Chris Lattner748697d2002-02-05 04:20:12 +00001382 PushedRegSet.insert(Reg);
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001383
Ruchira Sasankaaa12a782001-11-10 00:26:55 +00001384 if(DEBUG_RA) {
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001385 cerr << "\nFor call inst:" << *MInst;
Ruchira Sasankaaa12a782001-11-10 00:26:55 +00001386 cerr << " -inserted caller saving instrs:\n\t ";
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001387 if( RegType == IntCCRegType ) {
1388 if(AdIBefCC) cerr << *AdIBefCC << "\t";
1389 if(AdIAftCC) cerr << *AdIAftCC;
1390 }
1391 else {
1392 if(AdIBef) cerr << *AdIBef << "\t";
1393 if(AdIAft) cerr << *AdIAft;
1394 }
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001395 }
1396 } // if not already pushed
1397
1398 } // if LR has a volatile color
1399
1400 } // if LR has color
1401
1402 } // if there is a LR for Var
Ruchira Sasanka91442282001-09-30 23:16:47 +00001403
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001404 } // for each value in the LV set after instruction
1405
Ruchira Sasanka91442282001-09-30 23:16:47 +00001406}
1407
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001408//---------------------------------------------------------------------------
1409// Copies %ccr into an integer register. IntReg is the UNIFIED register
1410// number.
1411//---------------------------------------------------------------------------
Ruchira Sasanka91442282001-09-30 23:16:47 +00001412
Chris Lattner699683c2002-02-04 05:59:25 +00001413MachineInstr * UltraSparcRegInfo::cpCCR2IntMI(unsigned IntReg) const {
1414 MachineInstr * MI = new MachineInstr(RDCCR, 2);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001415 MI->SetMachineOperandReg(0, this->getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
1416 SparcIntCCRegOrder::ccr),
1417 false, true);
1418 MI->SetMachineOperandReg(1, IntReg, true);
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001419 return MI;
1420}
Ruchira Sasanka91442282001-09-30 23:16:47 +00001421
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001422//---------------------------------------------------------------------------
1423// Copies an integer register into %ccr. IntReg is the UNIFIED register
1424// number.
1425//---------------------------------------------------------------------------
1426
Chris Lattner699683c2002-02-04 05:59:25 +00001427MachineInstr *UltraSparcRegInfo::cpInt2CCRMI(unsigned IntReg) const {
1428 MachineInstr *MI = new MachineInstr(WRCCR, 3);
Vikram S. Advef1c15ee2002-03-18 03:12:16 +00001429 MI->SetMachineOperandReg(0, IntReg, false);
1430 MI->SetMachineOperandReg(1, this->getZeroRegNum(), false);
1431 MI->SetMachineOperandReg(2, this->getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID, SparcIntCCRegOrder::ccr),
1432 true, true);
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +00001433 return MI;
1434}
Ruchira Sasanka91442282001-09-30 23:16:47 +00001435
1436
Ruchira Sasanka20c82b12001-10-28 18:15:12 +00001437
1438
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00001439//---------------------------------------------------------------------------
1440// Print the register assigned to a LR
1441//---------------------------------------------------------------------------
1442
Chris Lattner699683c2002-02-04 05:59:25 +00001443void UltraSparcRegInfo::printReg(const LiveRange *LR) {
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00001444 unsigned RegClassID = (LR->getRegClass())->getID();
Chris Lattner1e23ed72001-10-15 18:15:27 +00001445 cerr << " *Node " << (LR->getUserIGNode())->getIndex();
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00001446
Chris Lattner699683c2002-02-04 05:59:25 +00001447 if (!LR->hasColor()) {
Chris Lattner697954c2002-01-20 22:54:45 +00001448 cerr << " - could not find a color\n";
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00001449 return;
1450 }
1451
1452 // if a color is found
1453
Chris Lattner1e23ed72001-10-15 18:15:27 +00001454 cerr << " colored with color "<< LR->getColor();
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00001455
Chris Lattner699683c2002-02-04 05:59:25 +00001456 if (RegClassID == IntRegClassID) {
Chris Lattner697954c2002-01-20 22:54:45 +00001457 cerr<< " [" << SparcIntRegOrder::getRegName(LR->getColor()) << "]\n";
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00001458
Chris Lattner699683c2002-02-04 05:59:25 +00001459 } else if (RegClassID == FloatRegClassID) {
Chris Lattner1e23ed72001-10-15 18:15:27 +00001460 cerr << "[" << SparcFloatRegOrder::getRegName(LR->getColor());
Chris Lattner37730942002-02-05 03:52:29 +00001461 if( LR->getType() == Type::DoubleTy)
Chris Lattner1e23ed72001-10-15 18:15:27 +00001462 cerr << "+" << SparcFloatRegOrder::getRegName(LR->getColor()+1);
Chris Lattner697954c2002-01-20 22:54:45 +00001463 cerr << "]\n";
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00001464 }
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +00001465}
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001466
1467//---------------------------------------------------------------------------
1468// This method examines instructions inserted by RegAlloc code before a
1469// machine instruction to detect invalid orders that destroy values before
1470// they are used. If it detects such conditions, it reorders the instructions.
1471//
1472// The unordered instructions come in the UnordVec. These instructions are
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001473// instructions inserted by RegAlloc. All such instruction MUST have
1474// their USES BEFORE THE DEFS after reordering.
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001475
1476// The UnordVec & OrdVec must be DISTINCT. The OrdVec must be empty when
1477// this method is called.
1478
1479// This method uses two vectors for efficiency in accessing
1480
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001481// Since instructions are inserted in RegAlloc, this assumes that the
1482// first operand is the source reg and the last operand is the dest reg.
1483
1484// All the uses are before THE def to a register
1485
1486
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001487//---------------------------------------------------------------------------
Chris Lattner697954c2002-01-20 22:54:45 +00001488void UltraSparcRegInfo::OrderAddedInstrns(std::vector<MachineInstr *> &UnordVec,
1489 std::vector<MachineInstr *> &OrdVec,
1490 PhyRegAlloc &PRA) const{
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001491
1492 /*
1493 Problem: We can have instructions inserted by RegAlloc like
1494 1. add %ox %g0 %oy
1495 2. add %oy %g0 %oz, where z!=x or z==x
1496
1497 This is wrong since %oy used by 2 is overwritten by 1
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001498
1499 Solution:
1500 We re-order the instructions so that the uses are before the defs
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001501
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001502 Algorithm:
1503
1504 do
1505 for each instruction 'DefInst' in the UnOrdVec
1506 for each instruction 'UseInst' that follows the DefInst
1507 if the reg defined by DefInst is used by UseInst
1508 mark DefInst as not movable in this iteration
1509 If DefInst is not marked as not-movable, move DefInst to OrdVec
1510 while all instructions in DefInst are moved to OrdVec
1511
1512 For moving, we call the move2OrdVec(). It checks whether there is a def
1513 in it for the uses in the instruction to be added to OrdVec. If there
1514 are no preceding defs, it just appends the instruction. If there is a
1515 preceding def, it puts two instructions to save the reg on stack before
1516 the load and puts a restore at use.
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001517
1518 */
1519
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001520 bool CouldMoveAll;
1521 bool DebugPrint = false;
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001522
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001523 do {
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001524 CouldMoveAll = true;
Chris Lattner697954c2002-01-20 22:54:45 +00001525 std::vector<MachineInstr *>::iterator DefIt = UnordVec.begin();
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001526
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001527 for( ; DefIt != UnordVec.end(); ++DefIt ) {
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001528
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001529 // for each instruction in the UnordVec do ...
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001530
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001531 MachineInstr *DefInst = *DefIt;
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001532
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001533 if( DefInst == NULL) continue;
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001534
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001535 //cerr << "\nInst in UnordVec = " << *DefInst;
1536
1537 // last operand is the def (unless for a store which has no def reg)
1538 MachineOperand& DefOp = DefInst->getOperand(DefInst->getNumOperands()-1);
1539
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001540 if( DefOp.opIsDef() &&
1541 DefOp.getOperandType() == MachineOperand::MO_MachineRegister) {
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001542
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001543 // If the operand in DefInst is a def ...
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001544
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001545 bool DefEqUse = false;
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001546
Chris Lattner697954c2002-01-20 22:54:45 +00001547 std::vector<MachineInstr *>::iterator UseIt = DefIt;
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001548 UseIt++;
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001549
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001550 for( ; UseIt != UnordVec.end(); ++UseIt ) {
1551
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001552 MachineInstr *UseInst = *UseIt;
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001553 if( UseInst == NULL) continue;
1554
1555 // for each inst (UseInst) that is below the DefInst do ...
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001556 MachineOperand& UseOp = UseInst->getOperand(0);
1557
1558 if( ! UseOp.opIsDef() &&
1559 UseOp.getOperandType() == MachineOperand::MO_MachineRegister) {
1560
1561 // if use is a register ...
1562
1563 if( DefOp.getMachineRegNum() == UseOp.getMachineRegNum() ) {
1564
1565 // if Def and this use are the same, it means that this use
1566 // is destroyed by a def before it is used
1567
1568 // cerr << "\nCouldn't move " << *DefInst;
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001569
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001570 DefEqUse = true;
1571 CouldMoveAll = false;
1572 DebugPrint = true;
1573 break;
1574 } // if two registers are equal
1575
1576 } // if use is a register
1577
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001578 }// for all use instructions
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001579
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001580 if( ! DefEqUse ) {
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001581
1582 // after examining all the instructions that follow the DefInst
1583 // if there are no dependencies, we can move it to the OrdVec
1584
1585 // cerr << "Moved to Ord: " << *DefInst;
1586
1587 moveInst2OrdVec(OrdVec, DefInst, PRA);
1588
1589 //OrdVec.push_back(DefInst);
1590
1591 // mark the pos of DefInst with NULL to indicate that it is
1592 // empty
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001593 *DefIt = NULL;
1594 }
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001595
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001596 } // if Def is a machine register
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001597
1598 } // for all instructions in the UnordVec
1599
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001600
Chris Lattner699683c2002-02-04 05:59:25 +00001601 } while(!CouldMoveAll);
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001602
Chris Lattner699683c2002-02-04 05:59:25 +00001603 if (DebugPrint) {
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001604 cerr << "\nAdded instructions were reordered to:\n";
1605 for(unsigned int i=0; i < OrdVec.size(); i++)
1606 cerr << *(OrdVec[i]);
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001607 }
Ruchira Sasanka868cf822001-11-09 23:49:14 +00001608}
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001609
1610
1611
1612
1613
Chris Lattner697954c2002-01-20 22:54:45 +00001614void UltraSparcRegInfo::moveInst2OrdVec(std::vector<MachineInstr *> &OrdVec,
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001615 MachineInstr *UnordInst,
Chris Lattner699683c2002-02-04 05:59:25 +00001616 PhyRegAlloc &PRA) const {
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001617 MachineOperand& UseOp = UnordInst->getOperand(0);
1618
1619 if( ! UseOp.opIsDef() &&
1620 UseOp.getOperandType() == MachineOperand::MO_MachineRegister) {
1621
1622 // for the use of UnordInst, see whether there is a defining instr
1623 // before in the OrdVec
1624 bool DefEqUse = false;
1625
Chris Lattner697954c2002-01-20 22:54:45 +00001626 std::vector<MachineInstr *>::iterator OrdIt = OrdVec.begin();
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001627
1628 for( ; OrdIt != OrdVec.end(); ++OrdIt ) {
1629
1630 MachineInstr *OrdInst = *OrdIt ;
1631
1632 MachineOperand& DefOp =
1633 OrdInst->getOperand(OrdInst->getNumOperands()-1);
1634
1635 if( DefOp.opIsDef() &&
1636 DefOp.getOperandType() == MachineOperand::MO_MachineRegister) {
1637
1638 //cerr << "\nDefining Ord Inst: " << *OrdInst;
1639
1640 if( DefOp.getMachineRegNum() == UseOp.getMachineRegNum() ) {
1641
1642 // we are here because there is a preceding def in the OrdVec
1643 // for the use in this intr we are going to insert. This
1644 // happened because the original code was like:
1645 // 1. add %ox %g0 %oy
1646 // 2. add %oy %g0 %ox
1647 // In Round1, we added 2 to OrdVec but 1 remained in UnordVec
1648 // Now we are processing %ox of 1.
1649 // We have to
1650
1651 const int UReg = DefOp.getMachineRegNum();
1652 const int RegType = getRegType(UReg);
1653 MachineInstr *AdIBef, *AdIAft;
1654
Ruchira Sasankad00982a2002-01-07 19:20:28 +00001655 const int StackOff = PRA.mcInfo.pushTempValue(target,
1656 getSpilledRegSize(RegType));
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001657
1658 // Save the UReg (%ox) on stack before it's destroyed
Ruchira Sasanka6beb0132001-11-11 21:49:37 +00001659 AdIBef=cpReg2MemMI(UReg, getFramePointer(), StackOff, RegType);
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001660 OrdIt = OrdVec.insert( OrdIt, AdIBef);
1661 OrdIt++; // points to current instr we processed
1662
1663 // Load directly into DReg (%oy)
1664 MachineOperand& DOp=
1665 (UnordInst->getOperand(UnordInst->getNumOperands()-1));
1666 assert(DOp.opIsDef() && "Last operand is not the def");
1667 const int DReg = DOp.getMachineRegNum();
1668
Ruchira Sasanka6beb0132001-11-11 21:49:37 +00001669 AdIAft=cpMem2RegMI(getFramePointer(), StackOff, DReg, RegType);
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001670 OrdVec.push_back(AdIAft);
1671
1672 cerr << "\nFixed CIRCULAR references by reordering";
1673
1674 if( DEBUG_RA ) {
1675 cerr << "\nBefore CIRCULAR Reordering:\n";
1676 cerr << *UnordInst;
1677 cerr << *OrdInst;
1678
1679 cerr << "\nAfter CIRCULAR Reordering - All Inst so far:\n";
1680 for(unsigned i=0; i < OrdVec.size(); i++)
1681 cerr << *(OrdVec[i]);
1682 }
1683
1684 // Do not copy the UseInst to OrdVec
1685 DefEqUse = true;
1686 break;
1687
1688 }// if two registers are equal
1689
1690 } // if Def is a register
1691
1692 } // for each instr in OrdVec
1693
Chris Lattner699683c2002-02-04 05:59:25 +00001694 if(!DefEqUse) {
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001695
1696 // We didn't find a def in the OrdVec, so just append this inst
1697 OrdVec.push_back( UnordInst );
1698 //cerr << "Reordered Inst (Moved Dn): " << *UnordInst;
1699 }
1700
1701 }// if the operand in UnordInst is a use
Ruchira Sasankaae4bcd72001-11-10 21:20:43 +00001702}