xref: /llvm-project/llvm/lib/CodeGen/MachineInstr.cpp (revision 4b9c46da246442b679cff6bd2c84fea56113b850)
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/Method.h"
20 #include "llvm/iOther.h"
21 #include "llvm/Instruction.h"
22 
23 AnnotationID MachineCodeForMethod::AID(
24                  AnnotationManager::getID("MachineCodeForMethodAnnotation"));
25 
26 
27 //************************ Class Implementations **************************/
28 
29 // Constructor for instructions with fixed #operands (nearly all)
30 MachineInstr::MachineInstr(MachineOpCode _opCode,
31 			   OpCodeMask    _opCodeMask)
32   : opCode(_opCode),
33     opCodeMask(_opCodeMask),
34     operands(TargetInstrDescriptors[_opCode].numOperands)
35 {
36   assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
37 }
38 
39 // Constructor for instructions with variable #operands
40 MachineInstr::MachineInstr(MachineOpCode _opCode,
41 			   unsigned	 numOperands,
42 			   OpCodeMask    _opCodeMask)
43   : opCode(_opCode),
44     opCodeMask(_opCodeMask),
45     operands(numOperands)
46 {
47 }
48 
49 void
50 MachineInstr::SetMachineOperand(unsigned int i,
51 				MachineOperand::MachineOperandType operandType,
52 				Value* _val, bool isdef=false)
53 {
54   assert(i < operands.size());
55   operands[i].Initialize(operandType, _val);
56   operands[i].isDef = isdef ||
57     TargetInstrDescriptors[opCode].resultPos == (int) i;
58 }
59 
60 void
61 MachineInstr::SetMachineOperand(unsigned int i,
62 				MachineOperand::MachineOperandType operandType,
63 				int64_t intValue, bool isdef=false)
64 {
65   assert(i < operands.size());
66   operands[i].InitializeConst(operandType, intValue);
67   operands[i].isDef = isdef ||
68     TargetInstrDescriptors[opCode].resultPos == (int) i;
69 }
70 
71 void
72 MachineInstr::SetMachineOperand(unsigned int i,
73 				int regNum, bool isdef=false)
74 {
75   assert(i < operands.size());
76   operands[i].InitializeReg(regNum);
77   operands[i].isDef = isdef ||
78     TargetInstrDescriptors[opCode].resultPos == (int) i;
79 }
80 
81 void
82 MachineInstr::dump(unsigned int indent) const
83 {
84   for (unsigned i=0; i < indent; i++)
85     cout << "    ";
86 
87   cout << *this;
88 }
89 
90 ostream&
91 operator<< (ostream& os, const MachineInstr& minstr)
92 {
93   os << TargetInstrDescriptors[minstr.opCode].opCodeString;
94 
95   for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
96     os << "\t" << minstr.getOperand(i);
97 
98 #undef DEBUG_VAL_OP_ITERATOR
99 #ifdef DEBUG_VAL_OP_ITERATOR
100   os << endl << "\tValue operands are: ";
101   for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
102     {
103       const Value* val = *vo;
104       os << val << (vo.isDef()? "(def), " : ", ");
105     }
106 #endif
107 
108 
109 
110 #if 1
111   // code for printing implict references
112 
113   unsigned NumOfImpRefs =  minstr.getNumImplicitRefs();
114   if(  NumOfImpRefs > 0 ) {
115 
116     os << "\tImplicit:";
117 
118     for(unsigned z=0; z < NumOfImpRefs; z++) {
119       os << minstr.getImplicitRef(z);
120 	  cout << "\t";
121     }
122   }
123 
124 #endif
125 
126 
127   os << endl;
128 
129   return os;
130 }
131 
132 static inline ostream&
133 OutputOperand(ostream &os, const MachineOperand &mop)
134 {
135   Value* val;
136   switch (mop.getOperandType())
137     {
138     case MachineOperand::MO_CCRegister:
139     case MachineOperand::MO_VirtualRegister:
140       val = mop.getVRegValue();
141       os << "(val ";
142       if (val && val->hasName())
143         os << val->getName().c_str();
144       else
145         os << val;
146       return os << ")";
147     case MachineOperand::MO_MachineRegister:
148       return os << "("     << mop.getMachineRegNum() << ")";
149     default:
150       assert(0 && "Unknown operand type");
151       return os;
152     }
153 }
154 
155 
156 ostream&
157 operator<<(ostream &os, const MachineOperand &mop)
158 {
159   switch(mop.opType)
160     {
161     case MachineOperand::MO_VirtualRegister:
162     case MachineOperand::MO_MachineRegister:
163       os << "%reg";
164       return OutputOperand(os, mop);
165     case MachineOperand::MO_CCRegister:
166       os << "%ccreg";
167       return OutputOperand(os, mop);
168     case MachineOperand::MO_SignExtendedImmed:
169       return os << mop.immedVal;
170     case MachineOperand::MO_UnextendedImmed:
171       return os << mop.immedVal;
172     case MachineOperand::MO_PCRelativeDisp:
173       {
174         const Value* opVal = mop.getVRegValue();
175         bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal);
176         os << "%disp(" << (isLabel? "label " : "addr-of-val ");
177         if (opVal->hasName())
178           os << opVal->getName().c_str();
179         else
180           os << opVal;
181         return os << ")";
182       }
183     default:
184       assert(0 && "Unrecognized operand type");
185       break;
186     }
187 
188   return os;
189 }
190 
191 static unsigned int
192 ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method)
193 {
194   const MachineFrameInfo& frameInfo = target.getFrameInfo();
195 
196   unsigned int maxSize = 0;
197 
198   for (Method::inst_const_iterator I=method->inst_begin(),E=method->inst_end();
199        I != E; ++I)
200     if ((*I)->getOpcode() == Instruction::Call)
201       {
202         CallInst* callInst = cast<CallInst>(*I);
203         unsigned int numOperands = callInst->getNumOperands() - 1;
204         int numExtra = (int) numOperands - frameInfo.getNumFixedOutgoingArgs();
205         if (numExtra <= 0)
206           continue;
207 
208         unsigned int sizeForThisCall;
209         if (frameInfo.argsOnStackHaveFixedSize())
210           {
211             int argSize = frameInfo.getSizeOfEachArgOnStack();
212             sizeForThisCall = numExtra * (unsigned) argSize;
213           }
214         else
215           {
216             assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual arg sizes to compute MaxOptionalArgsSize");
217             sizeForThisCall = 0;
218             for (unsigned i=0; i < numOperands; ++i)
219               sizeForThisCall += target.findOptimalStorageSize(callInst->
220                                                     getOperand(i)->getType());
221           }
222 
223         if (maxSize < sizeForThisCall)
224           maxSize = sizeForThisCall;
225       }
226 
227   return maxSize;
228 }
229 
230 
231 /*ctor*/
232 MachineCodeForMethod::MachineCodeForMethod(const Method* _M,
233                                            const TargetMachine& target)
234   : Annotation(AID),
235     method(_M), compiledAsLeaf(false), staticStackSize(0),
236     automaticVarsSize(0), regSpillsSize(0),
237     currentOptionalArgsSize(0), maxOptionalArgsSize(0),
238     currentTmpValuesSize(0)
239 {
240   maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method);
241   staticStackSize = maxOptionalArgsSize +
242                     target.getFrameInfo().getMinStackFrameSize();
243 }
244 
245 int
246 MachineCodeForMethod::allocateLocalVar(const TargetMachine& target,
247                                        const Value* val)
248 {
249   // Check if we've allocated a stack slot for this value already
250   //
251   int offset = getOffset(val);
252   if (offset == INVALID_FRAME_OFFSET)
253     {
254       bool growUp;
255       int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this,
256                                                                        growUp);
257       unsigned int  size  = target.findOptimalStorageSize(val->getType());
258       unsigned char align = target.DataLayout.getTypeAlignment(val->getType());
259 
260       offset = getAutomaticVarsSize();
261       if (! growUp)
262         offset += size;
263 
264       if (unsigned int mod = offset % align)
265         {
266           offset += align - mod;
267           size   += align - mod;
268         }
269 
270       offset = growUp? firstOffset + offset
271                      : firstOffset - offset;
272 
273       offsets[val] = offset;
274 
275       incrementAutomaticVarsSize(size);
276     }
277   return offset;
278 }
279 
280 int
281 MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target,
282                                            const Type* type)
283 {
284   unsigned int size  = target.findOptimalStorageSize(type);
285   unsigned char align = target.DataLayout.getTypeAlignment(type);
286 
287   bool growUp;
288   int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp);
289 
290   int offset = getRegSpillsSize();
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   incrementRegSpillsSize(size);
304 
305   return offset;
306 }
307 
308 int
309 MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target,
310                                           const Type* type)
311 {
312   const MachineFrameInfo& frameInfo = target.getFrameInfo();
313 
314   int size = MAXINT;
315   if (frameInfo.argsOnStackHaveFixedSize())
316     size = frameInfo.getSizeOfEachArgOnStack();
317   else
318     {
319       size = target.findOptimalStorageSize(type);
320       assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual argument sizes for computing optional arg offsets");
321     }
322   unsigned char align = target.DataLayout.getTypeAlignment(type);
323 
324   bool growUp;
325   int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp);
326 
327   int offset = getCurrentOptionalArgsSize();
328   if (! growUp)
329     offset += size;
330 
331   if (unsigned int mod = offset % align)
332     {
333       offset += align - mod;
334       size   += align - mod;
335     }
336 
337   offset = growUp? firstOffset + offset
338                  : firstOffset - offset;
339 
340   incrementCurrentOptionalArgsSize(size);
341 
342   return offset;
343 }
344 
345 void
346 MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target)
347 {
348   currentOptionalArgsSize = 0;
349 }
350 
351 int
352 MachineCodeForMethod::pushTempValue(const TargetMachine& target,
353                                     unsigned int size)
354 {
355   // Compute a power-of-2 alignment according to the possible sizes,
356   // but not greater than the alignment of the largest type we support
357   // (currently a double word -- see class TargetData).
358   unsigned char align = 1;
359   for (; align < size && align < target.DataLayout.getDoubleAlignment();
360          align = 2*align)
361     ;
362 
363   bool growUp;
364   int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp);
365 
366   int offset = currentTmpValuesSize;
367   if (! growUp)
368     offset += size;
369 
370   if (unsigned int mod = offset % align)
371     {
372       offset += align - mod;
373       size   += align - mod;
374     }
375 
376   offset = growUp? firstTmpOffset + offset
377                  : firstTmpOffset - offset;
378 
379   currentTmpValuesSize += size;
380   return offset;
381 }
382 
383 void
384 MachineCodeForMethod::popAllTempValues(const TargetMachine& target)
385 {
386   currentTmpValuesSize = 0;
387 }
388 
389 int
390 MachineCodeForMethod::getOffset(const Value* val) const
391 {
392   hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
393   return (pair == offsets.end())? INVALID_FRAME_OFFSET : (*pair).second;
394 }
395 
396 void
397 MachineCodeForMethod::dump() const
398 {
399   cout << "\n" << method->getReturnType()
400        << " \"" << method->getName() << "\"" << endl;
401 
402   for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
403     {
404       BasicBlock* bb = *BI;
405       cout << "\n"
406 	   << (bb->hasName()? bb->getName() : "Label")
407 	   << " (" << bb << ")" << ":"
408 	   << endl;
409 
410       MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
411       for (unsigned i=0; i < mvec.size(); i++)
412 	cout << "\t" << *mvec[i];
413     }
414   cout << endl << "End method \"" << method->getName() << "\""
415        << endl << endl;
416 }
417