blob: 8cf36f83ed81ba062c1098eb0a0e909cfaa011ad [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"
Chris Lattnerfb3b1ec2002-02-03 07:39:06 +000016#include "llvm/CodeGen/MachineCodeForInstruction.h"
17#include "llvm/CodeGen/MachineCodeForMethod.h"
18#include "llvm/CodeGen/InstrForest.h"
Vikram S. Advea1d14f32001-10-10 20:50:43 +000019#include "llvm/Target/TargetMachine.h"
20#include "llvm/Target/MachineRegInfo.h"
Chris Lattner31bcdb82002-04-28 19:55:58 +000021#include "llvm/Constants.h"
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000022#include "llvm/Function.h"
Vikram S. Adve94e40ef2001-10-28 21:46:23 +000023#include "llvm/BasicBlock.h"
Vikram S. Advea1d14f32001-10-10 20:50:43 +000024#include "llvm/Type.h"
25#include "llvm/iMemory.h"
Chris Lattner697954c2002-01-20 22:54:45 +000026using std::vector;
Vikram S. Advea1d14f32001-10-10 20:50:43 +000027
28//*************************** Local Functions ******************************/
29
Vikram S. Advea1d14f32001-10-10 20:50:43 +000030
Vikram S. Adve6d353262001-10-17 23:57:50 +000031static TmpInstruction*
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000032InsertCodeToLoadConstant(Function *F,
Vikram S. Adve42f63202002-03-18 03:33:43 +000033 Value* opValue,
Vikram S. Adve6d353262001-10-17 23:57:50 +000034 Instruction* vmInstr,
35 vector<MachineInstr*>& loadConstVec,
36 TargetMachine& target)
Vikram S. Advea1d14f32001-10-10 20:50:43 +000037{
Vikram S. Adve6d353262001-10-17 23:57:50 +000038 vector<TmpInstruction*> tempVec;
Vikram S. Advea1d14f32001-10-10 20:50:43 +000039
Vikram S. Adve6d353262001-10-17 23:57:50 +000040 // Create a tmp virtual register to hold the constant.
Chris Lattnerfb3b1ec2002-02-03 07:39:06 +000041 TmpInstruction* tmpReg = new TmpInstruction(opValue);
42 MachineCodeForInstruction &MCFI = MachineCodeForInstruction::get(vmInstr);
43 MCFI.addTemp(tmpReg);
Vikram S. Advea1d14f32001-10-10 20:50:43 +000044
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000045 target.getInstrInfo().CreateCodeToLoadConst(F, opValue, tmpReg,
Vikram S. Adve6d353262001-10-17 23:57:50 +000046 loadConstVec, tempVec);
47
48 // Register the new tmp values created for this m/c instruction sequence
49 for (unsigned i=0; i < tempVec.size(); i++)
Chris Lattnerfb3b1ec2002-02-03 07:39:06 +000050 MCFI.addTemp(tempVec[i]);
Vikram S. Adve6d353262001-10-17 23:57:50 +000051
52 // Record the mapping from the tmp VM instruction to machine instruction.
53 // Do this for all machine instructions that were not mapped to any
54 // other temp values created by
55 // tmpReg->addMachineInstruction(loadConstVec.back());
56
57 return tmpReg;
Vikram S. Advea1d14f32001-10-10 20:50:43 +000058}
59
60
Vikram S. Adve6d353262001-10-17 23:57:50 +000061//---------------------------------------------------------------------------
62// Function GetConstantValueAsSignedInt
63//
64// Convenience function to get the value of an integer constant, for an
65// appropriate integer or non-integer type that can be held in an integer.
66// The type of the argument must be the following:
67// Signed or unsigned integer
68// Boolean
69// Pointer
70//
71// isValidConstant is set to true if a valid constant was found.
72//---------------------------------------------------------------------------
73
74int64_t
75GetConstantValueAsSignedInt(const Value *V,
76 bool &isValidConstant)
Vikram S. Advea1d14f32001-10-10 20:50:43 +000077{
Chris Lattnere9bb2df2001-12-03 22:26:30 +000078 if (!isa<Constant>(V))
Vikram S. Advea1d14f32001-10-10 20:50:43 +000079 {
Vikram S. Adve6d353262001-10-17 23:57:50 +000080 isValidConstant = false;
81 return 0;
Vikram S. Advea1d14f32001-10-10 20:50:43 +000082 }
83
Vikram S. Adve6d353262001-10-17 23:57:50 +000084 isValidConstant = true;
85
86 if (V->getType() == Type::BoolTy)
Chris Lattnere9bb2df2001-12-03 22:26:30 +000087 return (int64_t) cast<ConstantBool>(V)->getValue();
Vikram S. Adve6d353262001-10-17 23:57:50 +000088
89 if (V->getType()->isIntegral())
90 {
91 if (V->getType()->isSigned())
Chris Lattnere9bb2df2001-12-03 22:26:30 +000092 return cast<ConstantSInt>(V)->getValue();
Vikram S. Adve6d353262001-10-17 23:57:50 +000093
94 assert(V->getType()->isUnsigned());
Chris Lattnere9bb2df2001-12-03 22:26:30 +000095 uint64_t Val = cast<ConstantUInt>(V)->getValue();
Vikram S. Adve6d353262001-10-17 23:57:50 +000096 if (Val < INT64_MAX) // then safe to cast to signed
97 return (int64_t)Val;
98 }
Vikram S. Adve17927792002-03-31 18:56:51 +000099
Vikram S. Adve6d353262001-10-17 23:57:50 +0000100 isValidConstant = false;
101 return 0;
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000102}
103
104
105//---------------------------------------------------------------------------
106// Function: FoldGetElemChain
107//
108// Purpose:
Vikram S. Advec941b872002-03-24 03:37:53 +0000109// Fold a chain of GetElementPtr instructions containing only
110// structure offsets into an equivalent (Pointer, IndexVector) pair.
111// Returns the pointer Value, and stores the resulting IndexVector
112// in argument chainIdxVec.
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000113//---------------------------------------------------------------------------
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
Vikram S. Adve17927792002-03-31 18:56:51 +0000122 // Return NULL if we don't fold any instructions in.
Vikram S. Advec941b872002-03-24 03:37:53 +0000123 Value* ptrVal = NULL;
Vikram S. Adve17927792002-03-31 18:56:51 +0000124
125 // The incoming index vector must be for the user of the chain.
126 // Its leading index must be [0] and we insert indices after that.
127 assert(chainIdxVec.size() > 0 &&
128 isa<ConstantUInt>(chainIdxVec.front()) &&
129 cast<ConstantUInt>(chainIdxVec.front())->getValue() == 0);
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000130
Vikram S. Advec941b872002-03-24 03:37:53 +0000131 // Now chase the chain of getElementInstr instructions, if any.
132 // Check for any array indices and stop there.
133 //
134 const InstrTreeNode* ptrChild = getElemInstrNode;
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000135 while (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
136 ptrChild->getOpLabel() == GetElemPtrIdx)
137 {
138 // Child is a GetElemPtr instruction
139 getElemInst = (MemAccessInst*)
140 ((InstructionNode*) ptrChild)->getInstruction();
Vikram S. Advefa248972001-12-15 00:36:32 +0000141 const vector<Value*>& idxVec = getElemInst->copyIndices();
Vikram S. Advec941b872002-03-24 03:37:53 +0000142 bool allStructureOffsets = true;
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000143
Vikram S. Advec941b872002-03-24 03:37:53 +0000144 // If it is a struct* access, the first offset must be array index [0],
145 // and all other offsets must be structure (not array) offsets
146 if (!isa<ConstantUInt>(idxVec.front()) ||
147 cast<ConstantUInt>(idxVec.front())->getValue() != 0)
148 allStructureOffsets = false;
149
150 if (allStructureOffsets)
151 for (unsigned int i=1; i < idxVec.size(); i++)
152 if (idxVec[i]->getType() == Type::UIntTy)
153 {
154 allStructureOffsets = false;
155 break;
156 }
157
158 if (allStructureOffsets)
Vikram S. Adve17927792002-03-31 18:56:51 +0000159 { // Get pointer value out of ptrChild.
Vikram S. Advec941b872002-03-24 03:37:53 +0000160 ptrVal = getElemInst->getPointerOperand();
Vikram S. Adve17927792002-03-31 18:56:51 +0000161
162 // Insert its index vector at the start, but after the leading [0]
163 chainIdxVec.insert(chainIdxVec.begin()+1,
Vikram S. Advec941b872002-03-24 03:37:53 +0000164 idxVec.begin()+1, idxVec.end());
Vikram S. Adve17927792002-03-31 18:56:51 +0000165
166 // Mark the folded node so no code is generated for it.
Vikram S. Advec941b872002-03-24 03:37:53 +0000167 ((InstructionNode*) ptrChild)->markFoldedIntoParent();
Vikram S. Advec941b872002-03-24 03:37:53 +0000168 }
169 else // cannot fold this getElementPtr instr. or any further ones
170 break;
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000171
172 ptrChild = ptrChild->leftChild();
173 }
174
175 return ptrVal;
176}
177
178
179//------------------------------------------------------------------------
180// Function Set2OperandsFromInstr
181// Function Set3OperandsFromInstr
182//
183// For the common case of 2- and 3-operand arithmetic/logical instructions,
184// set the m/c instr. operands directly from the VM instruction's operands.
185// Check whether the first or second operand is 0 and can use a dedicated "0"
186// register.
187// Check whether the second operand should use an immediate field or register.
188// (First and third operands are never immediates for such instructions.)
189//
190// Arguments:
191// canDiscardResult: Specifies that the result operand can be discarded
192// by using the dedicated "0"
193//
194// op1position, op2position and resultPosition: Specify in which position
195// in the machine instruction the 3 operands (arg1, arg2
196// and result) should go.
197//
198// RETURN VALUE: unsigned int flags, where
199// flags & 0x01 => operand 1 is constant and needs a register
200// flags & 0x02 => operand 2 is constant and needs a register
201//------------------------------------------------------------------------
202
203void
204Set2OperandsFromInstr(MachineInstr* minstr,
205 InstructionNode* vmInstrNode,
206 const TargetMachine& target,
207 bool canDiscardResult,
208 int op1Position,
209 int resultPosition)
210{
211 Set3OperandsFromInstr(minstr, vmInstrNode, target,
212 canDiscardResult, op1Position,
213 /*op2Position*/ -1, resultPosition);
214}
215
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000216
217void
218Set3OperandsFromInstr(MachineInstr* minstr,
219 InstructionNode* vmInstrNode,
220 const TargetMachine& target,
221 bool canDiscardResult,
222 int op1Position,
223 int op2Position,
224 int resultPosition)
225{
226 assert(op1Position >= 0);
227 assert(resultPosition >= 0);
228
229 // operand 1
Vikram S. Adve42f63202002-03-18 03:33:43 +0000230 minstr->SetMachineOperandVal(op1Position, MachineOperand::MO_VirtualRegister,
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000231 vmInstrNode->leftChild()->getValue());
232
233 // operand 2 (if any)
234 if (op2Position >= 0)
Vikram S. Adve42f63202002-03-18 03:33:43 +0000235 minstr->SetMachineOperandVal(op2Position, MachineOperand::MO_VirtualRegister,
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000236 vmInstrNode->rightChild()->getValue());
237
238 // result operand: if it can be discarded, use a dead register if one exists
239 if (canDiscardResult && target.getRegInfo().getZeroRegNum() >= 0)
Vikram S. Adve42f63202002-03-18 03:33:43 +0000240 minstr->SetMachineOperandReg(resultPosition,
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000241 target.getRegInfo().getZeroRegNum());
242 else
Vikram S. Adve42f63202002-03-18 03:33:43 +0000243 minstr->SetMachineOperandVal(resultPosition,
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000244 MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
245}
246
247
248MachineOperand::MachineOperandType
249ChooseRegOrImmed(Value* val,
250 MachineOpCode opCode,
251 const TargetMachine& target,
252 bool canUseImmed,
253 unsigned int& getMachineRegNum,
254 int64_t& getImmedValue)
255{
256 MachineOperand::MachineOperandType opType =
257 MachineOperand::MO_VirtualRegister;
258 getMachineRegNum = 0;
259 getImmedValue = 0;
260
261 // Check for the common case first: argument is not constant
262 //
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000263 Constant *CPV = dyn_cast<Constant>(val);
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000264 if (!CPV) return opType;
265
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000266 if (ConstantBool *CPB = dyn_cast<ConstantBool>(CPV))
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000267 {
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000268 if (!CPB->getValue() && target.getRegInfo().getZeroRegNum() >= 0)
269 {
270 getMachineRegNum = target.getRegInfo().getZeroRegNum();
271 return MachineOperand::MO_MachineRegister;
272 }
273
274 getImmedValue = 1;
275 return MachineOperand::MO_SignExtendedImmed;
276 }
277
Vikram S. Advec8117452001-11-14 17:24:49 +0000278 // Otherwise it needs to be an integer or a NULL pointer
279 if (! CPV->getType()->isIntegral() &&
Chris Lattner9b625032002-05-06 16:15:30 +0000280 ! (isa<PointerType>(CPV->getType()) &&
Vikram S. Advec8117452001-11-14 17:24:49 +0000281 CPV->isNullValue()))
282 return opType;
283
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000284 // Now get the constant value and check if it fits in the IMMED field.
285 // Take advantage of the fact that the max unsigned value will rarely
286 // fit into any IMMED field and ignore that case (i.e., cast smaller
287 // unsigned constants to signed).
288 //
289 int64_t intValue;
Chris Lattner9b625032002-05-06 16:15:30 +0000290 if (isa<PointerType>(CPV->getType()))
Vikram S. Advec8117452001-11-14 17:24:49 +0000291 {
292 intValue = 0;
293 }
Vikram S. Adve9e29f782001-11-14 17:55:02 +0000294 else if (CPV->getType()->isSigned())
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000295 {
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000296 intValue = cast<ConstantSInt>(CPV)->getValue();
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000297 }
298 else
299 {
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000300 uint64_t V = cast<ConstantUInt>(CPV)->getValue();
Vikram S. Advea1d14f32001-10-10 20:50:43 +0000301 if (V >= INT64_MAX) return opType;
302 intValue = (int64_t)V;
303 }
304
305 if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0)
306 {
307 opType = MachineOperand::MO_MachineRegister;
308 getMachineRegNum = target.getRegInfo().getZeroRegNum();
309 }
310 else if (canUseImmed &&
311 target.getInstrInfo().constantFitsInImmedField(opCode, intValue))
312 {
313 opType = MachineOperand::MO_SignExtendedImmed;
314 getImmedValue = intValue;
315 }
316
317 return opType;
318}
319
Vikram S. Adve6d353262001-10-17 23:57:50 +0000320
321//---------------------------------------------------------------------------
322// Function: FixConstantOperandsForInstr
323//
324// Purpose:
325// Special handling for constant operands of a machine instruction
326// -- if the constant is 0, use the hardwired 0 register, if any;
327// -- if the constant fits in the IMMEDIATE field, use that field;
328// -- else create instructions to put the constant into a register, either
329// directly or by loading explicitly from the constant pool.
330//
331// In the first 2 cases, the operand of `minstr' is modified in place.
332// Returns a vector of machine instructions generated for operands that
333// fall under case 3; these must be inserted before `minstr'.
334//---------------------------------------------------------------------------
335
336vector<MachineInstr*>
337FixConstantOperandsForInstr(Instruction* vmInstr,
338 MachineInstr* minstr,
339 TargetMachine& target)
340{
341 vector<MachineInstr*> loadConstVec;
342
343 const MachineInstrDescriptor& instrDesc =
344 target.getInstrInfo().getDescriptor(minstr->getOpCode());
345
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000346 Function *F = vmInstr->getParent()->getParent();
Vikram S. Adve94e40ef2001-10-28 21:46:23 +0000347
Vikram S. Adve6d353262001-10-17 23:57:50 +0000348 for (unsigned op=0; op < minstr->getNumOperands(); op++)
349 {
350 const MachineOperand& mop = minstr->getOperand(op);
351
352 // skip the result position (for efficiency below) and any other
353 // positions already marked as not a virtual register
354 if (instrDesc.resultPos == (int) op ||
355 mop.getOperandType() != MachineOperand::MO_VirtualRegister ||
356 mop.getVRegValue() == NULL)
357 {
358 continue;
359 }
360
361 Value* opValue = mop.getVRegValue();
362 bool constantThatMustBeLoaded = false;
363
Vikram S. Adve42f63202002-03-18 03:33:43 +0000364 if (Constant *opConst = dyn_cast<Constant>(opValue))
365 {
Vikram S. Adve6d353262001-10-17 23:57:50 +0000366 unsigned int machineRegNum;
367 int64_t immedValue;
368 MachineOperand::MachineOperandType opType =
369 ChooseRegOrImmed(opValue, minstr->getOpCode(), target,
Vikram S. Adve42f63202002-03-18 03:33:43 +0000370 (target.getInstrInfo().getImmedConstantPos(minstr->getOpCode()) == (int) op),
Vikram S. Adve6d353262001-10-17 23:57:50 +0000371 machineRegNum, immedValue);
Vikram S. Adveecd58132001-11-14 18:49:45 +0000372
Vikram S. Adve6d353262001-10-17 23:57:50 +0000373 if (opType == MachineOperand::MO_MachineRegister)
Vikram S. Adve42f63202002-03-18 03:33:43 +0000374 minstr->SetMachineOperandReg(op, machineRegNum);
Vikram S. Adve6d353262001-10-17 23:57:50 +0000375 else if (opType == MachineOperand::MO_VirtualRegister)
376 constantThatMustBeLoaded = true; // load is generated below
377 else
Vikram S. Adve42f63202002-03-18 03:33:43 +0000378 minstr->SetMachineOperandConst(op, opType, immedValue);
Vikram S. Adve94e40ef2001-10-28 21:46:23 +0000379 }
380
Vikram S. Adve6d353262001-10-17 23:57:50 +0000381 if (constantThatMustBeLoaded || isa<GlobalValue>(opValue))
382 { // opValue is a constant that must be explicitly loaded into a reg.
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000383 TmpInstruction* tmpReg = InsertCodeToLoadConstant(F, opValue, vmInstr,
384 loadConstVec,
385 target);
Vikram S. Adve42f63202002-03-18 03:33:43 +0000386 minstr->SetMachineOperandVal(op, MachineOperand::MO_VirtualRegister,
387 tmpReg);
Vikram S. Adve6d353262001-10-17 23:57:50 +0000388 }
389 }
390
391 //
392 // Also, check for implicit operands used (not those defined) by the
393 // machine instruction. These include:
394 // -- arguments to a Call
395 // -- return value of a Return
396 // Any such operand that is a constant value needs to be fixed also.
397 // The current instructions with implicit refs (viz., Call and Return)
398 // have no immediate fields, so the constant always needs to be loaded
399 // into a register.
400 //
401 for (unsigned i=0, N=minstr->getNumImplicitRefs(); i < N; ++i)
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000402 if (isa<Constant>(minstr->getImplicitRef(i)) ||
Vikram S. Adve6d353262001-10-17 23:57:50 +0000403 isa<GlobalValue>(minstr->getImplicitRef(i)))
404 {
Vikram S. Adve94e40ef2001-10-28 21:46:23 +0000405 Value* oldVal = minstr->getImplicitRef(i);
Vikram S. Adve6d353262001-10-17 23:57:50 +0000406 TmpInstruction* tmpReg =
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000407 InsertCodeToLoadConstant(F, oldVal, vmInstr, loadConstVec, target);
Vikram S. Adve6d353262001-10-17 23:57:50 +0000408 minstr->setImplicitRef(i, tmpReg);
409 }
410
411 return loadConstVec;
412}
413
414