blob: 5832b8ed18b3afcaad625b2205d8f6f2036406e6 [file] [log] [blame]
Vikram S. Adve70bc4b52001-07-21 12:41:50 +00001// $Id$
2//***************************************************************************
3// File:
4// MachineInstr.cpp
5//
6// Purpose:
7//
8//
9// Strategy:
10//
11// History:
12// 7/2/01 - Vikram Adve - Created
13//**************************************************************************/
14
Vikram S. Adve5b795912001-08-28 23:02:39 +000015
Chris Lattner822b4fb2001-09-07 17:18:30 +000016#include "llvm/CodeGen/MachineInstr.h"
Vikram S. Advebe495262001-11-08 04:47:06 +000017#include "llvm/Target/MachineFrameInfo.h"
Vikram S. Adve6e447182001-09-18 12:56:28 +000018#include "llvm/Target/MachineRegInfo.h"
Vikram S. Adve7c47c722001-11-15 15:22:26 +000019#include "llvm/Target/MachineCacheInfo.h"
Vikram S. Adve5b795912001-08-28 23:02:39 +000020#include "llvm/Method.h"
Vikram S. Advebe495262001-11-08 04:47:06 +000021#include "llvm/iOther.h"
Chris Lattner68498ce2001-07-21 23:24:48 +000022#include "llvm/Instruction.h"
Vikram S. Adve5b795912001-08-28 23:02:39 +000023
Vikram S. Advebe495262001-11-08 04:47:06 +000024AnnotationID MachineCodeForMethod::AID(
25 AnnotationManager::getID("MachineCodeForMethodAnnotation"));
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000026
Ruchira Sasanka69917e22001-10-18 22:40:02 +000027
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000028//************************ Class Implementations **************************/
29
Vikram S. Adve1885da42001-07-31 21:49:28 +000030// Constructor for instructions with fixed #operands (nearly all)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000031MachineInstr::MachineInstr(MachineOpCode _opCode,
32 OpCodeMask _opCodeMask)
33 : opCode(_opCode),
34 opCodeMask(_opCodeMask),
Vikram S. Adve6a175e02001-07-28 04:06:37 +000035 operands(TargetInstrDescriptors[_opCode].numOperands)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000036{
Vikram S. Adve1885da42001-07-31 21:49:28 +000037 assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
38}
39
40// Constructor for instructions with variable #operands
41MachineInstr::MachineInstr(MachineOpCode _opCode,
42 unsigned numOperands,
43 OpCodeMask _opCodeMask)
44 : opCode(_opCode),
45 opCodeMask(_opCodeMask),
46 operands(numOperands)
47{
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000048}
49
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000050void
51MachineInstr::SetMachineOperand(unsigned int i,
52 MachineOperand::MachineOperandType operandType,
Ruchira Sasanka45c171e2001-08-07 20:16:52 +000053 Value* _val, bool isdef=false)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000054{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000055 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000056 operands[i].Initialize(operandType, _val);
Vikram S. Adve149977b2001-08-13 16:32:45 +000057 operands[i].isDef = isdef ||
Vikram S. Adve6e447182001-09-18 12:56:28 +000058 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000059}
60
61void
62MachineInstr::SetMachineOperand(unsigned int i,
63 MachineOperand::MachineOperandType operandType,
Ruchira Sasanka45c171e2001-08-07 20:16:52 +000064 int64_t intValue, bool isdef=false)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000065{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000066 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000067 operands[i].InitializeConst(operandType, intValue);
Vikram S. Adve149977b2001-08-13 16:32:45 +000068 operands[i].isDef = isdef ||
Vikram S. Adve6e447182001-09-18 12:56:28 +000069 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000070}
71
72void
73MachineInstr::SetMachineOperand(unsigned int i,
Vikram S. Advedf1c3b82001-11-05 03:56:02 +000074 int regNum, bool isdef=false)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000075{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000076 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000077 operands[i].InitializeReg(regNum);
Vikram S. Adve149977b2001-08-13 16:32:45 +000078 operands[i].isDef = isdef ||
Vikram S. Adve6e447182001-09-18 12:56:28 +000079 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000080}
81
82void
Ruchira Sasanka0b03c6a2001-08-07 21:01:23 +000083MachineInstr::dump(unsigned int indent) const
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000084{
85 for (unsigned i=0; i < indent; i++)
86 cout << " ";
87
88 cout << *this;
89}
90
91ostream&
92operator<< (ostream& os, const MachineInstr& minstr)
93{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000094 os << TargetInstrDescriptors[minstr.opCode].opCodeString;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000095
Ruchira Sasanka8d243372001-11-14 20:05:23 +000096 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000097 os << "\t" << minstr.getOperand(i);
Ruchira Sasanka07c70862001-11-15 20:46:40 +000098 if( minstr.getOperand(i).opIsDef() )
99 os << "*";
Ruchira Sasanka8d243372001-11-14 20:05:23 +0000100 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000101
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000102#undef DEBUG_VAL_OP_ITERATOR
103#ifdef DEBUG_VAL_OP_ITERATOR
104 os << endl << "\tValue operands are: ";
Chris Lattner7a176752001-12-04 00:03:30 +0000105 for (MachineInstr::val_const_op_iterator vo(&minstr); ! vo.done(); ++vo)
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000106 {
107 const Value* val = *vo;
108 os << val << (vo.isDef()? "(def), " : ", ");
109 }
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000110#endif
111
Ruchira Sasanka69917e22001-10-18 22:40:02 +0000112
113
114#if 1
115 // code for printing implict references
116
117 unsigned NumOfImpRefs = minstr.getNumImplicitRefs();
118 if( NumOfImpRefs > 0 ) {
119
120 os << "\tImplicit:";
121
122 for(unsigned z=0; z < NumOfImpRefs; z++) {
123 os << minstr.getImplicitRef(z);
Ruchira Sasanka8d243372001-11-14 20:05:23 +0000124 if( minstr.implicitRefIsDefined(z)) os << "*";
Ruchira Sasanka07c70862001-11-15 20:46:40 +0000125 os << "\t";
Ruchira Sasanka69917e22001-10-18 22:40:02 +0000126 }
127 }
128
129#endif
130
131
Vikram S. Adve6d353262001-10-17 23:57:50 +0000132 os << endl;
133
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000134 return os;
135}
136
Vikram S. Adve6e447182001-09-18 12:56:28 +0000137static inline ostream&
138OutputOperand(ostream &os, const MachineOperand &mop)
139{
Vikram S. Adved9beb972001-11-12 14:19:47 +0000140 Value* val;
Vikram S. Adve6e447182001-09-18 12:56:28 +0000141 switch (mop.getOperandType())
142 {
143 case MachineOperand::MO_CCRegister:
144 case MachineOperand::MO_VirtualRegister:
Vikram S. Adved9beb972001-11-12 14:19:47 +0000145 val = mop.getVRegValue();
146 os << "(val ";
147 if (val && val->hasName())
148 os << val->getName().c_str();
149 else
150 os << val;
151 return os << ")";
Vikram S. Adve6e447182001-09-18 12:56:28 +0000152 case MachineOperand::MO_MachineRegister:
153 return os << "(" << mop.getMachineRegNum() << ")";
154 default:
155 assert(0 && "Unknown operand type");
156 return os;
157 }
Chris Lattnere6fdb112001-09-09 22:26:29 +0000158}
159
160
Vikram S. Adve6e447182001-09-18 12:56:28 +0000161ostream&
162operator<<(ostream &os, const MachineOperand &mop)
163{
164 switch(mop.opType)
165 {
166 case MachineOperand::MO_VirtualRegister:
167 case MachineOperand::MO_MachineRegister:
168 os << "%reg";
169 return OutputOperand(os, mop);
170 case MachineOperand::MO_CCRegister:
171 os << "%ccreg";
172 return OutputOperand(os, mop);
173 case MachineOperand::MO_SignExtendedImmed:
174 return os << mop.immedVal;
175 case MachineOperand::MO_UnextendedImmed:
176 return os << mop.immedVal;
177 case MachineOperand::MO_PCRelativeDisp:
Vikram S. Advee949da52001-09-30 23:44:19 +0000178 {
179 const Value* opVal = mop.getVRegValue();
Chris Lattner1d87bcf2001-10-01 20:11:19 +0000180 bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal);
Vikram S. Adved9beb972001-11-12 14:19:47 +0000181 os << "%disp(" << (isLabel? "label " : "addr-of-val ");
182 if (opVal->hasName())
183 os << opVal->getName().c_str();
184 else
185 os << opVal;
186 return os << ")";
Vikram S. Advee949da52001-09-30 23:44:19 +0000187 }
Vikram S. Adve6e447182001-09-18 12:56:28 +0000188 default:
189 assert(0 && "Unrecognized operand type");
190 break;
191 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000192
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000193 return os;
194}
195
Vikram S. Adve7c47c722001-11-15 15:22:26 +0000196// Align data larger than one L1 cache line on L1 cache line boundaries.
197// Align all smaller data on the next higher 2^x boundary (4, 8, ...).
198//
199// THIS FUNCTION HAS BEEN COPIED FROM EMITASSEMBLY.CPP AND
200// SHOULD BE USED DIRECTLY THERE
201//
202inline unsigned int
203SizeToAlignment(unsigned int size, const TargetMachine& target)
204{
205 unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1);
206 if (size > (unsigned) cacheLineSize / 2)
207 return cacheLineSize;
208 else
209 for (unsigned sz=1; /*no condition*/; sz *= 2)
210 if (sz >= size)
211 return sz;
212}
213
Vikram S. Advebe495262001-11-08 04:47:06 +0000214static unsigned int
215ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method)
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000216{
Vikram S. Advebe495262001-11-08 04:47:06 +0000217 const MachineFrameInfo& frameInfo = target.getFrameInfo();
218
219 unsigned int maxSize = 0;
220
Chris Lattner7a176752001-12-04 00:03:30 +0000221 for (Method::const_inst_iterator I=method->inst_begin(),E=method->inst_end();
Vikram S. Advebe495262001-11-08 04:47:06 +0000222 I != E; ++I)
223 if ((*I)->getOpcode() == Instruction::Call)
224 {
225 CallInst* callInst = cast<CallInst>(*I);
226 unsigned int numOperands = callInst->getNumOperands() - 1;
Vikram S. Advef1a0a102001-11-11 21:23:33 +0000227 int numExtra = (int) numOperands - frameInfo.getNumFixedOutgoingArgs();
228 if (numExtra <= 0)
229 continue;
Vikram S. Advebe495262001-11-08 04:47:06 +0000230
231 unsigned int sizeForThisCall;
232 if (frameInfo.argsOnStackHaveFixedSize())
233 {
234 int argSize = frameInfo.getSizeOfEachArgOnStack();
235 sizeForThisCall = numExtra * (unsigned) argSize;
236 }
237 else
238 {
239 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual arg sizes to compute MaxOptionalArgsSize");
240 sizeForThisCall = 0;
241 for (unsigned i=0; i < numOperands; ++i)
242 sizeForThisCall += target.findOptimalStorageSize(callInst->
243 getOperand(i)->getType());
244 }
245
246 if (maxSize < sizeForThisCall)
247 maxSize = sizeForThisCall;
248 }
249
250 return maxSize;
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000251}
252
253
Vikram S. Advebe495262001-11-08 04:47:06 +0000254/*ctor*/
255MachineCodeForMethod::MachineCodeForMethod(const Method* _M,
256 const TargetMachine& target)
257 : Annotation(AID),
258 method(_M), compiledAsLeaf(false), staticStackSize(0),
259 automaticVarsSize(0), regSpillsSize(0),
260 currentOptionalArgsSize(0), maxOptionalArgsSize(0),
261 currentTmpValuesSize(0)
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000262{
Vikram S. Advebe495262001-11-08 04:47:06 +0000263 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method);
264 staticStackSize = maxOptionalArgsSize +
265 target.getFrameInfo().getMinStackFrameSize();
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000266}
267
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000268int
Vikram S. Advebe495262001-11-08 04:47:06 +0000269MachineCodeForMethod::allocateLocalVar(const TargetMachine& target,
Vikram S. Adve7c47c722001-11-15 15:22:26 +0000270 const Value* val,
271 unsigned int size)
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000272{
Vikram S. Advebe495262001-11-08 04:47:06 +0000273 // Check if we've allocated a stack slot for this value already
274 //
275 int offset = getOffset(val);
276 if (offset == INVALID_FRAME_OFFSET)
277 {
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000278 bool growUp;
279 int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this,
280 growUp);
Vikram S. Adve7c47c722001-11-15 15:22:26 +0000281 unsigned char align;
282 if (size == 0)
283 {
284 size = target.findOptimalStorageSize(val->getType());
285 // align = target.DataLayout.getTypeAlignment(val->getType());
286 }
Vikram S. Adve5567e942001-11-12 05:17:23 +0000287
Vikram S. Adve7c47c722001-11-15 15:22:26 +0000288 align = SizeToAlignment(size, target);
289
Vikram S. Adve5567e942001-11-12 05:17:23 +0000290 offset = getAutomaticVarsSize();
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000291 if (! growUp)
292 offset += size;
293
Vikram S. Adve5567e942001-11-12 05:17:23 +0000294 if (unsigned int mod = offset % align)
295 {
296 offset += align - mod;
297 size += align - mod;
298 }
299
Vikram S. Adve5567e942001-11-12 05:17:23 +0000300 offset = growUp? firstOffset + offset
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000301 : firstOffset - offset;
Vikram S. Advef1a0a102001-11-11 21:23:33 +0000302
Vikram S. Advebe495262001-11-08 04:47:06 +0000303 offsets[val] = offset;
304
Vikram S. Advebe495262001-11-08 04:47:06 +0000305 incrementAutomaticVarsSize(size);
306 }
307 return offset;
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000308}
309
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000310int
Vikram S. Advebe495262001-11-08 04:47:06 +0000311MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target,
312 const Type* type)
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000313{
Vikram S. Adve5567e942001-11-12 05:17:23 +0000314 unsigned int size = target.findOptimalStorageSize(type);
315 unsigned char align = target.DataLayout.getTypeAlignment(type);
316
Vikram S. Advebe495262001-11-08 04:47:06 +0000317 bool growUp;
318 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp);
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000319
320 int offset = getRegSpillsSize();
321 if (! growUp)
322 offset += size;
323
324 if (unsigned int mod = offset % align)
325 {
326 offset += align - mod;
327 size += align - mod;
328 }
329
Vikram S. Adve5567e942001-11-12 05:17:23 +0000330 offset = growUp? firstOffset + offset
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000331 : firstOffset - offset;
Vikram S. Advef1a0a102001-11-11 21:23:33 +0000332
Vikram S. Advebe495262001-11-08 04:47:06 +0000333 incrementRegSpillsSize(size);
334
335 return offset;
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000336}
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000337
Vikram S. Advebe495262001-11-08 04:47:06 +0000338int
339MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target,
340 const Type* type)
341{
342 const MachineFrameInfo& frameInfo = target.getFrameInfo();
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000343
Vikram S. Advebe495262001-11-08 04:47:06 +0000344 int size = MAXINT;
345 if (frameInfo.argsOnStackHaveFixedSize())
346 size = frameInfo.getSizeOfEachArgOnStack();
347 else
348 {
Vikram S. Advebe495262001-11-08 04:47:06 +0000349 size = target.findOptimalStorageSize(type);
Vikram S. Advef1a0a102001-11-11 21:23:33 +0000350 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual argument sizes for computing optional arg offsets");
Vikram S. Advebe495262001-11-08 04:47:06 +0000351 }
Vikram S. Adve5567e942001-11-12 05:17:23 +0000352 unsigned char align = target.DataLayout.getTypeAlignment(type);
Vikram S. Advebe495262001-11-08 04:47:06 +0000353
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000354 bool growUp;
355 int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp);
356
Vikram S. Adve5567e942001-11-12 05:17:23 +0000357 int offset = getCurrentOptionalArgsSize();
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000358 if (! growUp)
359 offset += size;
360
Vikram S. Adve5567e942001-11-12 05:17:23 +0000361 if (unsigned int mod = offset % align)
362 {
363 offset += align - mod;
364 size += align - mod;
365 }
366
Vikram S. Adve5567e942001-11-12 05:17:23 +0000367 offset = growUp? firstOffset + offset
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000368 : firstOffset - offset;
Vikram S. Adve5567e942001-11-12 05:17:23 +0000369
Vikram S. Advebe495262001-11-08 04:47:06 +0000370 incrementCurrentOptionalArgsSize(size);
371
372 return offset;
373}
374
375void
376MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target)
377{
378 currentOptionalArgsSize = 0;
379}
380
381int
382MachineCodeForMethod::pushTempValue(const TargetMachine& target,
383 unsigned int size)
384{
Vikram S. Adve5567e942001-11-12 05:17:23 +0000385 // Compute a power-of-2 alignment according to the possible sizes,
386 // but not greater than the alignment of the largest type we support
387 // (currently a double word -- see class TargetData).
388 unsigned char align = 1;
389 for (; align < size && align < target.DataLayout.getDoubleAlignment();
390 align = 2*align)
391 ;
392
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000393 bool growUp;
394 int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp);
395
Vikram S. Adve5567e942001-11-12 05:17:23 +0000396 int offset = currentTmpValuesSize;
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000397 if (! growUp)
398 offset += size;
399
Vikram S. Adve5567e942001-11-12 05:17:23 +0000400 if (unsigned int mod = offset % align)
401 {
402 offset += align - mod;
403 size += align - mod;
404 }
405
Vikram S. Adve5567e942001-11-12 05:17:23 +0000406 offset = growUp? firstTmpOffset + offset
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000407 : firstTmpOffset - offset;
Vikram S. Adve5567e942001-11-12 05:17:23 +0000408
Vikram S. Advebe495262001-11-08 04:47:06 +0000409 currentTmpValuesSize += size;
410 return offset;
411}
412
413void
414MachineCodeForMethod::popAllTempValues(const TargetMachine& target)
415{
416 currentTmpValuesSize = 0;
417}
418
Vikram S. Advebe495262001-11-08 04:47:06 +0000419int
420MachineCodeForMethod::getOffset(const Value* val) const
421{
422 hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
423 return (pair == offsets.end())? INVALID_FRAME_OFFSET : (*pair).second;
424}
425
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000426void
427MachineCodeForMethod::dump() const
Ruchira Sasankaed8f6742001-09-15 19:07:45 +0000428{
429 cout << "\n" << method->getReturnType()
430 << " \"" << method->getName() << "\"" << endl;
431
432 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
433 {
434 BasicBlock* bb = *BI;
435 cout << "\n"
436 << (bb->hasName()? bb->getName() : "Label")
437 << " (" << bb << ")" << ":"
438 << endl;
439
440 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
441 for (unsigned i=0; i < mvec.size(); i++)
Vikram S. Adve6d353262001-10-17 23:57:50 +0000442 cout << "\t" << *mvec[i];
Ruchira Sasankaed8f6742001-09-15 19:07:45 +0000443 }
444 cout << endl << "End method \"" << method->getName() << "\""
445 << endl << endl;
446}