Renamed inst_const_iterator -> const_inst_iterator
[oota-llvm.git] / lib / CodeGen / MachineInstr.cpp
1 // $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
15
16 #include "llvm/CodeGen/MachineInstr.h"
17 #include "llvm/Target/MachineFrameInfo.h"
18 #include "llvm/Target/MachineRegInfo.h"
19 #include "llvm/Target/MachineCacheInfo.h"
20 #include "llvm/Method.h"
21 #include "llvm/iOther.h"
22 #include "llvm/Instruction.h"
23
24 AnnotationID MachineCodeForMethod::AID(
25                  AnnotationManager::getID("MachineCodeForMethodAnnotation"));
26
27
28 //************************ Class Implementations **************************/
29
30 // Constructor for instructions with fixed #operands (nearly all)
31 MachineInstr::MachineInstr(MachineOpCode _opCode,
32                            OpCodeMask    _opCodeMask)
33   : opCode(_opCode),
34     opCodeMask(_opCodeMask),
35     operands(TargetInstrDescriptors[_opCode].numOperands)
36 {
37   assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
38 }
39
40 // Constructor for instructions with variable #operands
41 MachineInstr::MachineInstr(MachineOpCode _opCode,
42                            unsigned      numOperands,
43                            OpCodeMask    _opCodeMask)
44   : opCode(_opCode),
45     opCodeMask(_opCodeMask),
46     operands(numOperands)
47 {
48 }
49
50 void
51 MachineInstr::SetMachineOperand(unsigned int i,
52                                 MachineOperand::MachineOperandType operandType,
53                                 Value* _val, bool isdef=false)
54 {
55   assert(i < operands.size());
56   operands[i].Initialize(operandType, _val);
57   operands[i].isDef = isdef ||
58     TargetInstrDescriptors[opCode].resultPos == (int) i;
59 }
60
61 void
62 MachineInstr::SetMachineOperand(unsigned int i,
63                                 MachineOperand::MachineOperandType operandType,
64                                 int64_t intValue, bool isdef=false)
65 {
66   assert(i < operands.size());
67   operands[i].InitializeConst(operandType, intValue);
68   operands[i].isDef = isdef ||
69     TargetInstrDescriptors[opCode].resultPos == (int) i;
70 }
71
72 void
73 MachineInstr::SetMachineOperand(unsigned int i,
74                                 int regNum, bool isdef=false)
75 {
76   assert(i < operands.size());
77   operands[i].InitializeReg(regNum);
78   operands[i].isDef = isdef ||
79     TargetInstrDescriptors[opCode].resultPos == (int) i;
80 }
81
82 void
83 MachineInstr::dump(unsigned int indent) const 
84 {
85   for (unsigned i=0; i < indent; i++)
86     cout << "    ";
87   
88   cout << *this;
89 }
90
91 ostream&
92 operator<< (ostream& os, const MachineInstr& minstr)
93 {
94   os << TargetInstrDescriptors[minstr.opCode].opCodeString;
95   
96   for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
97     os << "\t" << minstr.getOperand(i);
98     if( minstr.getOperand(i).opIsDef() ) 
99       os << "*";
100   }
101   
102 #undef DEBUG_VAL_OP_ITERATOR
103 #ifdef DEBUG_VAL_OP_ITERATOR
104   os << endl << "\tValue operands are: ";
105   for (MachineInstr::val_const_op_iterator vo(&minstr); ! vo.done(); ++vo)
106     {
107       const Value* val = *vo;
108       os << val << (vo.isDef()? "(def), " : ", ");
109     }
110 #endif
111   
112  
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);
124       if( minstr.implicitRefIsDefined(z)) os << "*";
125       os << "\t";
126     }
127   }
128
129 #endif
130
131
132   os << endl;
133   
134   return os;
135 }
136
137 static inline ostream&
138 OutputOperand(ostream &os, const MachineOperand &mop)
139 {
140   Value* val;
141   switch (mop.getOperandType())
142     {
143     case MachineOperand::MO_CCRegister:
144     case MachineOperand::MO_VirtualRegister:
145       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 << ")";
152     case MachineOperand::MO_MachineRegister:
153       return os << "("     << mop.getMachineRegNum() << ")";
154     default:
155       assert(0 && "Unknown operand type");
156       return os;
157     }
158 }
159
160
161 ostream&
162 operator<<(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:
178       {
179         const Value* opVal = mop.getVRegValue();
180         bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal);
181         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 << ")";
187       }
188     default:
189       assert(0 && "Unrecognized operand type");
190       break;
191     }
192   
193   return os;
194 }
195
196 // 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 // 
202 inline unsigned int
203 SizeToAlignment(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
214 static unsigned int
215 ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method)
216 {
217   const MachineFrameInfo& frameInfo = target.getFrameInfo();
218   
219   unsigned int maxSize = 0;
220   
221   for (Method::const_inst_iterator I=method->inst_begin(),E=method->inst_end();
222        I != E; ++I)
223     if ((*I)->getOpcode() == Instruction::Call)
224       {
225         CallInst* callInst = cast<CallInst>(*I);
226         unsigned int numOperands = callInst->getNumOperands() - 1;
227         int numExtra = (int) numOperands - frameInfo.getNumFixedOutgoingArgs();
228         if (numExtra <= 0)
229           continue;
230         
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;
251 }
252
253
254 /*ctor*/
255 MachineCodeForMethod::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)
262 {
263   maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method);
264   staticStackSize = maxOptionalArgsSize +
265                     target.getFrameInfo().getMinStackFrameSize();
266 }
267
268 int
269 MachineCodeForMethod::allocateLocalVar(const TargetMachine& target,
270                                        const Value* val,
271                                        unsigned int size)
272 {
273   // 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     {
278       bool growUp;
279       int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this,
280                                                                        growUp);
281       unsigned char align;
282       if (size == 0)
283         {
284           size  = target.findOptimalStorageSize(val->getType());
285           // align = target.DataLayout.getTypeAlignment(val->getType());
286         }
287       
288       align = SizeToAlignment(size, target);
289           
290       offset = getAutomaticVarsSize();
291       if (! growUp)
292         offset += size; 
293       
294       if (unsigned int mod = offset % align)
295         {
296           offset += align - mod;
297           size   += align - mod;
298         }
299       
300       offset = growUp? firstOffset + offset
301                      : firstOffset - offset;
302       
303       offsets[val] = offset;
304       
305       incrementAutomaticVarsSize(size);
306     }
307   return offset;
308 }
309
310 int
311 MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target,
312                                            const Type* type)
313 {
314   unsigned int size  = target.findOptimalStorageSize(type);
315   unsigned char align = target.DataLayout.getTypeAlignment(type);
316   
317   bool growUp;
318   int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp);
319   
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   
330   offset = growUp? firstOffset + offset
331                  : firstOffset - offset;
332   
333   incrementRegSpillsSize(size);
334   
335   return offset;
336 }
337
338 int
339 MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target,
340                                           const Type* type)
341 {
342   const MachineFrameInfo& frameInfo = target.getFrameInfo();
343   
344   int size = MAXINT;
345   if (frameInfo.argsOnStackHaveFixedSize())
346     size = frameInfo.getSizeOfEachArgOnStack(); 
347   else
348     {
349       size = target.findOptimalStorageSize(type);
350       assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual argument sizes for computing optional arg offsets");
351     }
352   unsigned char align = target.DataLayout.getTypeAlignment(type);
353   
354   bool growUp;
355   int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp);
356   
357   int offset = getCurrentOptionalArgsSize();
358   if (! growUp)
359     offset += size; 
360   
361   if (unsigned int mod = offset % align)
362     {
363       offset += align - mod;
364       size   += align - mod;
365     }
366   
367   offset = growUp? firstOffset + offset
368                  : firstOffset - offset;
369   
370   incrementCurrentOptionalArgsSize(size);
371   
372   return offset;
373 }
374
375 void
376 MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target)
377 {
378   currentOptionalArgsSize = 0;
379 }
380
381 int
382 MachineCodeForMethod::pushTempValue(const TargetMachine& target,
383                                     unsigned int size)
384 {
385   // 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   
393   bool growUp;
394   int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp);
395   
396   int offset = currentTmpValuesSize;
397   if (! growUp)
398     offset += size; 
399   
400   if (unsigned int mod = offset % align)
401     {
402       offset += align - mod;
403       size   += align - mod;
404     }
405   
406   offset = growUp? firstTmpOffset + offset
407                  : firstTmpOffset - offset;
408   
409   currentTmpValuesSize += size;
410   return offset;
411 }
412
413 void
414 MachineCodeForMethod::popAllTempValues(const TargetMachine& target)
415 {
416   currentTmpValuesSize = 0;
417 }
418
419 int
420 MachineCodeForMethod::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
426 void
427 MachineCodeForMethod::dump() const
428 {
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++)
442         cout << "\t" << *mvec[i];
443     } 
444   cout << endl << "End method \"" << method->getName() << "\""
445        << endl << endl;
446 }