Minor method rename
[oota-llvm.git] / lib / Target / SparcV9 / InstrSelection / InstrSelectionSupport.cpp
1 // $Id$ -*-c++-*-
2 //***************************************************************************
3 // File:
4 //      InstrSelectionSupport.h
5 // 
6 // Purpose:
7 //      Target-independent instruction selection code.
8 //      See SparcInstrSelection.cpp for usage.
9 //      
10 // History:
11 //      10/10/01         -  Vikram Adve  -  Created
12 //**************************************************************************/
13
14 #include "llvm/CodeGen/InstrSelectionSupport.h"
15 #include "llvm/CodeGen/InstrSelection.h"
16 #include "llvm/CodeGen/MachineInstr.h"
17 #include "llvm/Target/TargetMachine.h"
18 #include "llvm/Target/MachineRegInfo.h"
19 #include "llvm/ConstPoolVals.h"
20 #include "llvm/Method.h"
21 #include "llvm/BasicBlock.h"
22 #include "llvm/Instruction.h"
23 #include "llvm/Type.h"
24 #include "llvm/iMemory.h"
25
26
27 //*************************** Local Functions ******************************/
28
29
30 static TmpInstruction*
31 InsertCodeToLoadConstant(Value* opValue,
32                          Instruction* vmInstr,
33                          vector<MachineInstr*>& loadConstVec,
34                          TargetMachine& target)
35 {
36   vector<TmpInstruction*> tempVec;
37   
38   // Create a tmp virtual register to hold the constant.
39   TmpInstruction* tmpReg =
40     new TmpInstruction(TMP_INSTRUCTION_OPCODE, opValue, NULL);
41   vmInstr->getMachineInstrVec().addTempValue(tmpReg);
42   
43   target.getInstrInfo().CreateCodeToLoadConst(opValue, tmpReg,
44                                               loadConstVec, tempVec);
45   
46   // Register the new tmp values created for this m/c instruction sequence
47   for (unsigned i=0; i < tempVec.size(); i++)
48     vmInstr->getMachineInstrVec().addTempValue(tempVec[i]);
49   
50   // Record the mapping from the tmp VM instruction to machine instruction.
51   // Do this for all machine instructions that were not mapped to any
52   // other temp values created by 
53   // tmpReg->addMachineInstruction(loadConstVec.back());
54   
55   return tmpReg;
56 }
57
58
59 //---------------------------------------------------------------------------
60 // Function GetConstantValueAsSignedInt
61 // 
62 // Convenience function to get the value of an integer constant, for an
63 // appropriate integer or non-integer type that can be held in an integer.
64 // The type of the argument must be the following:
65 //      Signed or unsigned integer
66 //      Boolean
67 //      Pointer
68 // 
69 // isValidConstant is set to true if a valid constant was found.
70 //---------------------------------------------------------------------------
71
72 int64_t
73 GetConstantValueAsSignedInt(const Value *V,
74                             bool &isValidConstant)
75 {
76   if (!isa<ConstPoolVal>(V))
77     {
78       isValidConstant = false;
79       return 0;
80     }
81   
82   isValidConstant = true;
83   
84   if (V->getType() == Type::BoolTy)
85     return (int64_t) ((ConstPoolBool*)V)->getValue();
86   
87   if (V->getType()->isIntegral())
88     {
89       if (V->getType()->isSigned())
90         return ((ConstPoolSInt*)V)->getValue();
91       
92       assert(V->getType()->isUnsigned());
93       uint64_t Val = ((ConstPoolUInt*)V)->getValue();
94       if (Val < INT64_MAX)     // then safe to cast to signed
95         return (int64_t)Val;
96     }
97
98   isValidConstant = false;
99   return 0;
100 }
101
102
103 //---------------------------------------------------------------------------
104 // Function: FoldGetElemChain
105 // 
106 // Purpose:
107 //   Fold a chain of GetElementPtr instructions into an equivalent
108 //   (Pointer, IndexVector) pair.  Returns the pointer Value, and
109 //   stores the resulting IndexVector in argument chainIdxVec.
110 //---------------------------------------------------------------------------
111
112 Value*
113 FoldGetElemChain(const InstructionNode* getElemInstrNode,
114                  vector<ConstPoolVal*>& chainIdxVec)
115 {
116   MemAccessInst* getElemInst = (MemAccessInst*)
117     getElemInstrNode->getInstruction();
118   
119   // Initialize return values from the incoming instruction
120   Value* ptrVal = getElemInst->getPtrOperand();
121   chainIdxVec = getElemInst->getIndices(); // copies index vector values
122   
123   // Now chase the chain of getElementInstr instructions, if any
124   InstrTreeNode* ptrChild = getElemInstrNode->leftChild();
125   while (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
126          ptrChild->getOpLabel() == GetElemPtrIdx)
127     {
128       // Child is a GetElemPtr instruction
129       getElemInst = (MemAccessInst*)
130         ((InstructionNode*) ptrChild)->getInstruction();
131       const vector<ConstPoolVal*>& idxVec = getElemInst->getIndices();
132       
133       // Get the pointer value out of ptrChild and *prepend* its index vector
134       ptrVal = getElemInst->getPtrOperand();
135       chainIdxVec.insert(chainIdxVec.begin(), idxVec.begin(), idxVec.end());
136       
137       ptrChild = ptrChild->leftChild();
138     }
139   
140   return ptrVal;
141 }
142
143
144 //------------------------------------------------------------------------ 
145 // Function Set2OperandsFromInstr
146 // Function Set3OperandsFromInstr
147 // 
148 // For the common case of 2- and 3-operand arithmetic/logical instructions,
149 // set the m/c instr. operands directly from the VM instruction's operands.
150 // Check whether the first or second operand is 0 and can use a dedicated "0"
151 // register.
152 // Check whether the second operand should use an immediate field or register.
153 // (First and third operands are never immediates for such instructions.)
154 // 
155 // Arguments:
156 // canDiscardResult: Specifies that the result operand can be discarded
157 //                   by using the dedicated "0"
158 // 
159 // op1position, op2position and resultPosition: Specify in which position
160 //                   in the machine instruction the 3 operands (arg1, arg2
161 //                   and result) should go.
162 // 
163 // RETURN VALUE: unsigned int flags, where
164 //      flags & 0x01    => operand 1 is constant and needs a register
165 //      flags & 0x02    => operand 2 is constant and needs a register
166 //------------------------------------------------------------------------ 
167
168 void
169 Set2OperandsFromInstr(MachineInstr* minstr,
170                       InstructionNode* vmInstrNode,
171                       const TargetMachine& target,
172                       bool canDiscardResult,
173                       int op1Position,
174                       int resultPosition)
175 {
176   Set3OperandsFromInstr(minstr, vmInstrNode, target,
177                         canDiscardResult, op1Position,
178                         /*op2Position*/ -1, resultPosition);
179 }
180
181
182 void
183 Set3OperandsFromInstr(MachineInstr* minstr,
184                       InstructionNode* vmInstrNode,
185                       const TargetMachine& target,
186                       bool canDiscardResult,
187                       int op1Position,
188                       int op2Position,
189                       int resultPosition)
190 {
191   assert(op1Position >= 0);
192   assert(resultPosition >= 0);
193   
194   // operand 1
195   minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
196                             vmInstrNode->leftChild()->getValue());   
197   
198   // operand 2 (if any)
199   if (op2Position >= 0)
200     minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
201                               vmInstrNode->rightChild()->getValue());   
202   
203   // result operand: if it can be discarded, use a dead register if one exists
204   if (canDiscardResult && target.getRegInfo().getZeroRegNum() >= 0)
205     minstr->SetMachineOperand(resultPosition,
206                               target.getRegInfo().getZeroRegNum());
207   else
208     minstr->SetMachineOperand(resultPosition,
209                               MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
210 }
211
212
213 MachineOperand::MachineOperandType
214 ChooseRegOrImmed(Value* val,
215                  MachineOpCode opCode,
216                  const TargetMachine& target,
217                  bool canUseImmed,
218                  unsigned int& getMachineRegNum,
219                  int64_t& getImmedValue)
220 {
221   MachineOperand::MachineOperandType opType =
222     MachineOperand::MO_VirtualRegister;
223   getMachineRegNum = 0;
224   getImmedValue = 0;
225   
226   // Check for the common case first: argument is not constant
227   // 
228   ConstPoolVal *CPV = dyn_cast<ConstPoolVal>(val);
229   if (!CPV) return opType;
230
231   if (CPV->getType() == Type::BoolTy)
232     {
233       ConstPoolBool *CPB = (ConstPoolBool*)CPV;
234       if (!CPB->getValue() && target.getRegInfo().getZeroRegNum() >= 0)
235         {
236           getMachineRegNum = target.getRegInfo().getZeroRegNum();
237           return MachineOperand::MO_MachineRegister;
238         }
239
240       getImmedValue = 1;
241       return MachineOperand::MO_SignExtendedImmed;
242     }
243   
244   if (!CPV->getType()->isIntegral()) return opType;
245
246   // Now get the constant value and check if it fits in the IMMED field.
247   // Take advantage of the fact that the max unsigned value will rarely
248   // fit into any IMMED field and ignore that case (i.e., cast smaller
249   // unsigned constants to signed).
250   // 
251   int64_t intValue;
252   if (CPV->getType()->isSigned())
253     {
254       intValue = ((ConstPoolSInt*)CPV)->getValue();
255     }
256   else
257     {
258       uint64_t V = ((ConstPoolUInt*)CPV)->getValue();
259       if (V >= INT64_MAX) return opType;
260       intValue = (int64_t)V;
261     }
262
263   if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0)
264     {
265       opType = MachineOperand::MO_MachineRegister;
266       getMachineRegNum = target.getRegInfo().getZeroRegNum();
267     }
268   else if (canUseImmed &&
269            target.getInstrInfo().constantFitsInImmedField(opCode, intValue))
270     {
271       opType = MachineOperand::MO_SignExtendedImmed;
272       getImmedValue = intValue;
273     }
274   
275   return opType;
276 }
277
278
279 //---------------------------------------------------------------------------
280 // Function: FixConstantOperandsForInstr
281 // 
282 // Purpose:
283 // Special handling for constant operands of a machine instruction
284 // -- if the constant is 0, use the hardwired 0 register, if any;
285 // -- if the constant fits in the IMMEDIATE field, use that field;
286 // -- else create instructions to put the constant into a register, either
287 //    directly or by loading explicitly from the constant pool.
288 // 
289 // In the first 2 cases, the operand of `minstr' is modified in place.
290 // Returns a vector of machine instructions generated for operands that
291 // fall under case 3; these must be inserted before `minstr'.
292 //---------------------------------------------------------------------------
293
294 vector<MachineInstr*>
295 FixConstantOperandsForInstr(Instruction* vmInstr,
296                             MachineInstr* minstr,
297                             TargetMachine& target)
298 {
299   vector<MachineInstr*> loadConstVec;
300   
301   const MachineInstrDescriptor& instrDesc =
302     target.getInstrInfo().getDescriptor(minstr->getOpCode());
303   
304   Method* method = vmInstr->getParent()->getParent();
305   
306   for (unsigned op=0; op < minstr->getNumOperands(); op++)
307     {
308       const MachineOperand& mop = minstr->getOperand(op);
309           
310       // skip the result position (for efficiency below) and any other
311       // positions already marked as not a virtual register
312       if (instrDesc.resultPos == (int) op || 
313           mop.getOperandType() != MachineOperand::MO_VirtualRegister ||
314           mop.getVRegValue() == NULL)
315         {
316           continue;
317         }
318           
319       Value* opValue = mop.getVRegValue();
320       bool constantThatMustBeLoaded = false;
321       
322       if (isa<ConstPoolVal>(opValue))
323         {
324           unsigned int machineRegNum;
325           int64_t immedValue;
326           MachineOperand::MachineOperandType opType =
327             ChooseRegOrImmed(opValue, minstr->getOpCode(), target,
328                              /*canUseImmed*/ (op == 1),
329                              machineRegNum, immedValue);
330               
331           if (opType == MachineOperand::MO_MachineRegister)
332             minstr->SetMachineOperand(op, machineRegNum);
333           else if (opType == MachineOperand::MO_VirtualRegister)
334             constantThatMustBeLoaded = true; // load is generated below
335           else
336             minstr->SetMachineOperand(op, opType, immedValue);
337
338           if (constantThatMustBeLoaded)
339             { // register the value so it is emitted in the assembly
340               method->getMachineCode().addToConstantPool(
341                                                  cast<ConstPoolVal>(opValue));
342             }
343         }
344       
345       if (constantThatMustBeLoaded || isa<GlobalValue>(opValue))
346         { // opValue is a constant that must be explicitly loaded into a reg.
347           TmpInstruction* tmpReg = InsertCodeToLoadConstant(opValue, vmInstr,
348                                                         loadConstVec, target);
349           minstr->SetMachineOperand(op, MachineOperand::MO_VirtualRegister,
350                                         tmpReg);
351         }
352     }
353   
354   // 
355   // Also, check for implicit operands used (not those defined) by the
356   // machine instruction.  These include:
357   // -- arguments to a Call
358   // -- return value of a Return
359   // Any such operand that is a constant value needs to be fixed also.
360   // The current instructions with implicit refs (viz., Call and Return)
361   // have no immediate fields, so the constant always needs to be loaded
362   // into a register.
363   // 
364   for (unsigned i=0, N=minstr->getNumImplicitRefs(); i < N; ++i)
365     if (isa<ConstPoolVal>(minstr->getImplicitRef(i)) ||
366         isa<GlobalValue>(minstr->getImplicitRef(i)))
367       {
368         Value* oldVal = minstr->getImplicitRef(i);
369         TmpInstruction* tmpReg =
370           InsertCodeToLoadConstant(oldVal, vmInstr, loadConstVec, target);
371         minstr->setImplicitRef(i, tmpReg);
372         
373         if (isa<ConstPoolVal>(oldVal))
374           { // register the value so it is emitted in the assembly
375             method->getMachineCode().addToConstantPool(
376                                                cast<ConstPoolVal>(oldVal));
377           }
378       }
379   
380   return loadConstVec;
381 }
382
383