blob: e079c749e37bb55fa9fc75980e804e95ca5d96c6 [file] [log] [blame]
Vikram S. Advea1d14f32001-10-10 20:50:43 +00001// $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"
Chris Lattnerfb3b1ec2002-02-03 07:39:06 +000017#include "llvm/CodeGen/MachineCodeForInstruction.h"
18#include "llvm/CodeGen/MachineCodeForMethod.h"
19#include "llvm/CodeGen/InstrForest.h"
Vikram S. Advea1d14f32001-10-10 20:50:43 +000020#include "llvm/Target/TargetMachine.h"
21#include "llvm/Target/MachineRegInfo.h"
Chris Lattnere9bb2df2001-12-03 22:26:30 +000022#include "llvm/ConstantVals.h"
Vikram S. Adve94e40ef2001-10-28 21:46:23 +000023#include "llvm/Method.h"
24#include "llvm/BasicBlock.h"
Vikram S. Advea1d14f32001-10-10 20:50:43 +000025#include "llvm/Type.h"
26#include "llvm/iMemory.h"
Chris Lattner697954c2002-01-20 22:54:45 +000027using std::vector;
Vikram S. Advea1d14f32001-10-10 20:50:43 +000028
29//*************************** Local Functions ******************************/
30
Vikram S. Advea1d14f32001-10-10 20:50:43 +000031
Vikram S. Adve6d353262001-10-17 23:57:50 +000032static TmpInstruction*
Vikram S. Adve42f63202002-03-18 03:33:43 +000033InsertCodeToLoadConstant(Method* method,
34 Value* opValue,
Vikram S. Adve6d353262001-10-17 23:57:50 +000035 Instruction* vmInstr,
36 vector<MachineInstr*>& loadConstVec,
37 TargetMachine& target)
Vikram S. Advea1d14f32001-10-10 20:50:43 +000038{
Vikram S. Adve6d353262001-10-17 23:57:50 +000039 vector<TmpInstruction*> tempVec;
Vikram S. Advea1d14f32001-10-10 20:50:43 +000040
Vikram S. Adve6d353262001-10-17 23:57:50 +000041 // Create a tmp virtual register to hold the constant.
Chris Lattnerfb3b1ec2002-02-03 07:39:06 +000042 TmpInstruction* tmpReg = new TmpInstruction(opValue);
43 MachineCodeForInstruction &MCFI = MachineCodeForInstruction::get(vmInstr);
44 MCFI.addTemp(tmpReg);
Vikram S. Advea1d14f32001-10-10 20:50:43 +000045
Vikram S. Adve42f63202002-03-18 03:33:43 +000046 target.getInstrInfo().CreateCodeToLoadConst(method, opValue, tmpReg,
Vikram S. Adve6d353262001-10-17 23:57:50 +000047 loadConstVec, tempVec);
48
49 // Register the new tmp values created for this m/c instruction sequence
50 for (unsigned i=0; i < tempVec.size(); i++)
Chris Lattnerfb3b1ec2002-02-03 07:39:06 +000051 MCFI.addTemp(tempVec[i]);
Vikram S. Adve6d353262001-10-17 23:57:50 +000052
53 // Record the mapping from the tmp VM instruction to machine instruction.
54 // Do this for all machine instructions that were not mapped to any
55 // other temp values created by
56 // tmpReg->addMachineInstruction(loadConstVec.back());
57
58 return tmpReg;
Vikram S. Advea1d14f32001-10-10 20:50:43 +000059}
60
61
Vikram S. Adve6d353262001-10-17 23:57:50 +000062//---------------------------------------------------------------------------
63// Function GetConstantValueAsSignedInt
64//
65// Convenience function to get the value of an integer constant, for an
66// appropriate integer or non-integer type that can be held in an integer.
67// The type of the argument must be the following:
68// Signed or unsigned integer
69// Boolean
70// Pointer
71//
72// isValidConstant is set to true if a valid constant was found.
73//---------------------------------------------------------------------------
74
75int64_t
76GetConstantValueAsSignedInt(const Value *V,
77 bool &isValidConstant)
Vikram S. Advea1d14f32001-10-10 20:50:43 +000078{
Chris Lattnere9bb2df2001-12-03 22:26:30 +000079 if (!isa<Constant>(V))
Vikram S. Advea1d14f32001-10-10 20:50:43 +000080 {
Vikram S. Adve6d353262001-10-17 23:57:50 +000081 isValidConstant = false;
82 return 0;
Vikram S. Advea1d14f32001-10-10 20:50:43 +000083 }
84
Vikram S. Adve6d353262001-10-17 23:57:50 +000085 isValidConstant = true;
86
87 if (V->getType() == Type::BoolTy)
Chris Lattnere9bb2df2001-12-03 22:26:30 +000088 return (int64_t) cast<ConstantBool>(V)->getValue();
Vikram S. Adve6d353262001-10-17 23:57:50 +000089
90 if (V->getType()->isIntegral())
91 {
92 if (V->getType()->isSigned())
Chris Lattnere9bb2df2001-12-03 22:26:30 +000093 return cast<ConstantSInt>(V)->getValue();
Vikram S. Adve6d353262001-10-17 23:57:50 +000094
95 assert(V->getType()->isUnsigned());
Chris Lattnere9bb2df2001-12-03 22:26:30 +000096 uint64_t Val = cast<ConstantUInt>(V)->getValue();
Vikram S. Adve6d353262001-10-17 23:57:50 +000097 if (Val < INT64_MAX) // then safe to cast to signed
98 return (int64_t)Val;
99 }
100
101 isValidConstant = false;
102 return 0;
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000103}
104
105
106//---------------------------------------------------------------------------
107// Function: FoldGetElemChain
108//
109// Purpose:
110// Fold a chain of GetElementPtr instructions into an equivalent
111// (Pointer, IndexVector) pair. Returns the pointer Value, and
112// stores the resulting IndexVector in argument chainIdxVec.
113//---------------------------------------------------------------------------
114
115Value*
116FoldGetElemChain(const InstructionNode* getElemInstrNode,
Vikram S. Advefa248972001-12-15 00:36:32 +0000117 vector<Value*>& chainIdxVec)
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000118{
119 MemAccessInst* getElemInst = (MemAccessInst*)
120 getElemInstrNode->getInstruction();
121
122 // Initialize return values from the incoming instruction
Chris Lattner65ea1712001-11-14 11:27:58 +0000123 Value* ptrVal = getElemInst->getPointerOperand();
Vikram S. Advefa248972001-12-15 00:36:32 +0000124 chainIdxVec = getElemInst->copyIndices();
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000125
126 // Now chase the chain of getElementInstr instructions, if any
127 InstrTreeNode* ptrChild = getElemInstrNode->leftChild();
128 while (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
129 ptrChild->getOpLabel() == GetElemPtrIdx)
130 {
131 // Child is a GetElemPtr instruction
132 getElemInst = (MemAccessInst*)
133 ((InstructionNode*) ptrChild)->getInstruction();
Vikram S. Advefa248972001-12-15 00:36:32 +0000134 const vector<Value*>& idxVec = getElemInst->copyIndices();
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000135
136 // Get the pointer value out of ptrChild and *prepend* its index vector
Chris Lattner65ea1712001-11-14 11:27:58 +0000137 ptrVal = getElemInst->getPointerOperand();
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000138 chainIdxVec.insert(chainIdxVec.begin(), idxVec.begin(), idxVec.end());
139
140 ptrChild = ptrChild->leftChild();
141 }
142
143 return ptrVal;
144}
145
146
147//------------------------------------------------------------------------
148// Function Set2OperandsFromInstr
149// Function Set3OperandsFromInstr
150//
151// For the common case of 2- and 3-operand arithmetic/logical instructions,
152// set the m/c instr. operands directly from the VM instruction's operands.
153// Check whether the first or second operand is 0 and can use a dedicated "0"
154// register.
155// Check whether the second operand should use an immediate field or register.
156// (First and third operands are never immediates for such instructions.)
157//
158// Arguments:
159// canDiscardResult: Specifies that the result operand can be discarded
160// by using the dedicated "0"
161//
162// op1position, op2position and resultPosition: Specify in which position
163// in the machine instruction the 3 operands (arg1, arg2
164// and result) should go.
165//
166// RETURN VALUE: unsigned int flags, where
167// flags & 0x01 => operand 1 is constant and needs a register
168// flags & 0x02 => operand 2 is constant and needs a register
169//------------------------------------------------------------------------
170
171void
172Set2OperandsFromInstr(MachineInstr* minstr,
173 InstructionNode* vmInstrNode,
174 const TargetMachine& target,
175 bool canDiscardResult,
176 int op1Position,
177 int resultPosition)
178{
179 Set3OperandsFromInstr(minstr, vmInstrNode, target,
180 canDiscardResult, op1Position,
181 /*op2Position*/ -1, resultPosition);
182}
183
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000184
185void
186Set3OperandsFromInstr(MachineInstr* minstr,
187 InstructionNode* vmInstrNode,
188 const TargetMachine& target,
189 bool canDiscardResult,
190 int op1Position,
191 int op2Position,
192 int resultPosition)
193{
194 assert(op1Position >= 0);
195 assert(resultPosition >= 0);
196
197 // operand 1
Vikram S. Adve42f63202002-03-18 03:33:43 +0000198 minstr->SetMachineOperandVal(op1Position, MachineOperand::MO_VirtualRegister,
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000199 vmInstrNode->leftChild()->getValue());
200
201 // operand 2 (if any)
202 if (op2Position >= 0)
Vikram S. Adve42f63202002-03-18 03:33:43 +0000203 minstr->SetMachineOperandVal(op2Position, MachineOperand::MO_VirtualRegister,
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000204 vmInstrNode->rightChild()->getValue());
205
206 // result operand: if it can be discarded, use a dead register if one exists
207 if (canDiscardResult && target.getRegInfo().getZeroRegNum() >= 0)
Vikram S. Adve42f63202002-03-18 03:33:43 +0000208 minstr->SetMachineOperandReg(resultPosition,
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000209 target.getRegInfo().getZeroRegNum());
210 else
Vikram S. Adve42f63202002-03-18 03:33:43 +0000211 minstr->SetMachineOperandVal(resultPosition,
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000212 MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
213}
214
215
216MachineOperand::MachineOperandType
217ChooseRegOrImmed(Value* val,
218 MachineOpCode opCode,
219 const TargetMachine& target,
220 bool canUseImmed,
221 unsigned int& getMachineRegNum,
222 int64_t& getImmedValue)
223{
224 MachineOperand::MachineOperandType opType =
225 MachineOperand::MO_VirtualRegister;
226 getMachineRegNum = 0;
227 getImmedValue = 0;
228
229 // Check for the common case first: argument is not constant
230 //
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000231 Constant *CPV = dyn_cast<Constant>(val);
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000232 if (!CPV) return opType;
233
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000234 if (ConstantBool *CPB = dyn_cast<ConstantBool>(CPV))
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000235 {
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000236 if (!CPB->getValue() && target.getRegInfo().getZeroRegNum() >= 0)
237 {
238 getMachineRegNum = target.getRegInfo().getZeroRegNum();
239 return MachineOperand::MO_MachineRegister;
240 }
241
242 getImmedValue = 1;
243 return MachineOperand::MO_SignExtendedImmed;
244 }
245
Vikram S. Advec8117452001-11-14 17:24:49 +0000246 // Otherwise it needs to be an integer or a NULL pointer
247 if (! CPV->getType()->isIntegral() &&
248 ! (CPV->getType()->isPointerType() &&
249 CPV->isNullValue()))
250 return opType;
251
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000252 // Now get the constant value and check if it fits in the IMMED field.
253 // Take advantage of the fact that the max unsigned value will rarely
254 // fit into any IMMED field and ignore that case (i.e., cast smaller
255 // unsigned constants to signed).
256 //
257 int64_t intValue;
Vikram S. Advec8117452001-11-14 17:24:49 +0000258 if (CPV->getType()->isPointerType())
259 {
260 intValue = 0;
261 }
Vikram S. Adve9e29f782001-11-14 17:55:02 +0000262 else if (CPV->getType()->isSigned())
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000263 {
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000264 intValue = cast<ConstantSInt>(CPV)->getValue();
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000265 }
266 else
267 {
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000268 uint64_t V = cast<ConstantUInt>(CPV)->getValue();
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000269 if (V >= INT64_MAX) return opType;
270 intValue = (int64_t)V;
271 }
272
273 if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0)
274 {
275 opType = MachineOperand::MO_MachineRegister;
276 getMachineRegNum = target.getRegInfo().getZeroRegNum();
277 }
278 else if (canUseImmed &&
279 target.getInstrInfo().constantFitsInImmedField(opCode, intValue))
280 {
281 opType = MachineOperand::MO_SignExtendedImmed;
282 getImmedValue = intValue;
283 }
284
285 return opType;
286}
287
Vikram S. Adve6d353262001-10-17 23:57:50 +0000288
289//---------------------------------------------------------------------------
290// Function: FixConstantOperandsForInstr
291//
292// Purpose:
293// Special handling for constant operands of a machine instruction
294// -- if the constant is 0, use the hardwired 0 register, if any;
295// -- if the constant fits in the IMMEDIATE field, use that field;
296// -- else create instructions to put the constant into a register, either
297// directly or by loading explicitly from the constant pool.
298//
299// In the first 2 cases, the operand of `minstr' is modified in place.
300// Returns a vector of machine instructions generated for operands that
301// fall under case 3; these must be inserted before `minstr'.
302//---------------------------------------------------------------------------
303
304vector<MachineInstr*>
305FixConstantOperandsForInstr(Instruction* vmInstr,
306 MachineInstr* minstr,
307 TargetMachine& target)
308{
309 vector<MachineInstr*> loadConstVec;
310
311 const MachineInstrDescriptor& instrDesc =
312 target.getInstrInfo().getDescriptor(minstr->getOpCode());
313
Vikram S. Adve94e40ef2001-10-28 21:46:23 +0000314 Method* method = vmInstr->getParent()->getParent();
315
Vikram S. Adve6d353262001-10-17 23:57:50 +0000316 for (unsigned op=0; op < minstr->getNumOperands(); op++)
317 {
318 const MachineOperand& mop = minstr->getOperand(op);
319
320 // skip the result position (for efficiency below) and any other
321 // positions already marked as not a virtual register
322 if (instrDesc.resultPos == (int) op ||
323 mop.getOperandType() != MachineOperand::MO_VirtualRegister ||
324 mop.getVRegValue() == NULL)
325 {
326 continue;
327 }
328
329 Value* opValue = mop.getVRegValue();
330 bool constantThatMustBeLoaded = false;
331
Vikram S. Adve42f63202002-03-18 03:33:43 +0000332 if (Constant *opConst = dyn_cast<Constant>(opValue))
333 {
Vikram S. Adve6d353262001-10-17 23:57:50 +0000334 unsigned int machineRegNum;
335 int64_t immedValue;
336 MachineOperand::MachineOperandType opType =
337 ChooseRegOrImmed(opValue, minstr->getOpCode(), target,
Vikram S. Adve42f63202002-03-18 03:33:43 +0000338 (target.getInstrInfo().getImmedConstantPos(minstr->getOpCode()) == (int) op),
Vikram S. Adve6d353262001-10-17 23:57:50 +0000339 machineRegNum, immedValue);
Vikram S. Adveecd58132001-11-14 18:49:45 +0000340
Vikram S. Adve6d353262001-10-17 23:57:50 +0000341 if (opType == MachineOperand::MO_MachineRegister)
Vikram S. Adve42f63202002-03-18 03:33:43 +0000342 minstr->SetMachineOperandReg(op, machineRegNum);
Vikram S. Adve6d353262001-10-17 23:57:50 +0000343 else if (opType == MachineOperand::MO_VirtualRegister)
344 constantThatMustBeLoaded = true; // load is generated below
345 else
Vikram S. Adve42f63202002-03-18 03:33:43 +0000346 minstr->SetMachineOperandConst(op, opType, immedValue);
Vikram S. Adve94e40ef2001-10-28 21:46:23 +0000347 }
348
Vikram S. Adve6d353262001-10-17 23:57:50 +0000349 if (constantThatMustBeLoaded || isa<GlobalValue>(opValue))
350 { // opValue is a constant that must be explicitly loaded into a reg.
Vikram S. Adve42f63202002-03-18 03:33:43 +0000351 TmpInstruction* tmpReg = InsertCodeToLoadConstant(method, opValue, vmInstr,
352 loadConstVec, target);
353 minstr->SetMachineOperandVal(op, MachineOperand::MO_VirtualRegister,
354 tmpReg);
Vikram S. Adve6d353262001-10-17 23:57:50 +0000355 }
356 }
357
358 //
359 // Also, check for implicit operands used (not those defined) by the
360 // machine instruction. These include:
361 // -- arguments to a Call
362 // -- return value of a Return
363 // Any such operand that is a constant value needs to be fixed also.
364 // The current instructions with implicit refs (viz., Call and Return)
365 // have no immediate fields, so the constant always needs to be loaded
366 // into a register.
367 //
368 for (unsigned i=0, N=minstr->getNumImplicitRefs(); i < N; ++i)
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000369 if (isa<Constant>(minstr->getImplicitRef(i)) ||
Vikram S. Adve6d353262001-10-17 23:57:50 +0000370 isa<GlobalValue>(minstr->getImplicitRef(i)))
371 {
Vikram S. Adve94e40ef2001-10-28 21:46:23 +0000372 Value* oldVal = minstr->getImplicitRef(i);
Vikram S. Adve6d353262001-10-17 23:57:50 +0000373 TmpInstruction* tmpReg =
Vikram S. Adve42f63202002-03-18 03:33:43 +0000374 InsertCodeToLoadConstant(method, oldVal, vmInstr, loadConstVec, target);
Vikram S. Adve6d353262001-10-17 23:57:50 +0000375 minstr->setImplicitRef(i, tmpReg);
376 }
377
378 return loadConstVec;
379}
380
381