2 //***************************************************************************
12 // 7/2/01 - Vikram Adve - Created
13 //**************************************************************************/
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"
24 AnnotationID MachineCodeForMethod::AID(
25 AnnotationManager::getID("MachineCodeForMethodAnnotation"));
28 //************************ Class Implementations **************************/
30 // Constructor for instructions with fixed #operands (nearly all)
31 MachineInstr::MachineInstr(MachineOpCode _opCode,
32 OpCodeMask _opCodeMask)
34 opCodeMask(_opCodeMask),
35 operands(TargetInstrDescriptors[_opCode].numOperands)
37 assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
40 // Constructor for instructions with variable #operands
41 MachineInstr::MachineInstr(MachineOpCode _opCode,
43 OpCodeMask _opCodeMask)
45 opCodeMask(_opCodeMask),
51 MachineInstr::SetMachineOperand(unsigned int i,
52 MachineOperand::MachineOperandType operandType,
53 Value* _val, bool isdef=false)
55 assert(i < operands.size());
56 operands[i].Initialize(operandType, _val);
57 operands[i].isDef = isdef ||
58 TargetInstrDescriptors[opCode].resultPos == (int) i;
62 MachineInstr::SetMachineOperand(unsigned int i,
63 MachineOperand::MachineOperandType operandType,
64 int64_t intValue, bool isdef=false)
66 assert(i < operands.size());
67 operands[i].InitializeConst(operandType, intValue);
68 operands[i].isDef = isdef ||
69 TargetInstrDescriptors[opCode].resultPos == (int) i;
73 MachineInstr::SetMachineOperand(unsigned int i,
74 int regNum, bool isdef=false)
76 assert(i < operands.size());
77 operands[i].InitializeReg(regNum);
78 operands[i].isDef = isdef ||
79 TargetInstrDescriptors[opCode].resultPos == (int) i;
83 MachineInstr::dump(unsigned int indent) const
85 for (unsigned i=0; i < indent; i++)
92 operator<< (ostream& os, const MachineInstr& minstr)
94 os << TargetInstrDescriptors[minstr.opCode].opCodeString;
96 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
97 os << "\t" << minstr.getOperand(i);
98 if( minstr.getOperand(i).opIsDef() ) os << "*";
102 #undef DEBUG_VAL_OP_ITERATOR
103 #ifdef DEBUG_VAL_OP_ITERATOR
104 os << endl << "\tValue operands are: ";
105 for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
107 const Value* val = *vo;
108 os << val << (vo.isDef()? "(def), " : ", ");
115 // code for printing implict references
117 unsigned NumOfImpRefs = minstr.getNumImplicitRefs();
118 if( NumOfImpRefs > 0 ) {
122 for(unsigned z=0; z < NumOfImpRefs; z++) {
123 os << minstr.getImplicitRef(z);
124 if( minstr.implicitRefIsDefined(z)) os << "*";
137 static inline ostream&
138 OutputOperand(ostream &os, const MachineOperand &mop)
141 switch (mop.getOperandType())
143 case MachineOperand::MO_CCRegister:
144 case MachineOperand::MO_VirtualRegister:
145 val = mop.getVRegValue();
147 if (val && val->hasName())
148 os << val->getName().c_str();
152 case MachineOperand::MO_MachineRegister:
153 return os << "(" << mop.getMachineRegNum() << ")";
155 assert(0 && "Unknown operand type");
162 operator<<(ostream &os, const MachineOperand &mop)
166 case MachineOperand::MO_VirtualRegister:
167 case MachineOperand::MO_MachineRegister:
169 return OutputOperand(os, mop);
170 case MachineOperand::MO_CCRegister:
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:
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();
189 assert(0 && "Unrecognized operand type");
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, ...).
199 // THIS FUNCTION HAS BEEN COPIED FROM EMITASSEMBLY.CPP AND
200 // SHOULD BE USED DIRECTLY THERE
203 SizeToAlignment(unsigned int size, const TargetMachine& target)
205 unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1);
206 if (size > (unsigned) cacheLineSize / 2)
207 return cacheLineSize;
209 for (unsigned sz=1; /*no condition*/; sz *= 2)
215 ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method)
217 const MachineFrameInfo& frameInfo = target.getFrameInfo();
219 unsigned int maxSize = 0;
221 for (Method::inst_const_iterator I=method->inst_begin(),E=method->inst_end();
223 if ((*I)->getOpcode() == Instruction::Call)
225 CallInst* callInst = cast<CallInst>(*I);
226 unsigned int numOperands = callInst->getNumOperands() - 1;
227 int numExtra = (int) numOperands - frameInfo.getNumFixedOutgoingArgs();
231 unsigned int sizeForThisCall;
232 if (frameInfo.argsOnStackHaveFixedSize())
234 int argSize = frameInfo.getSizeOfEachArgOnStack();
235 sizeForThisCall = numExtra * (unsigned) argSize;
239 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual arg sizes to compute MaxOptionalArgsSize");
241 for (unsigned i=0; i < numOperands; ++i)
242 sizeForThisCall += target.findOptimalStorageSize(callInst->
243 getOperand(i)->getType());
246 if (maxSize < sizeForThisCall)
247 maxSize = sizeForThisCall;
255 MachineCodeForMethod::MachineCodeForMethod(const Method* _M,
256 const TargetMachine& target)
258 method(_M), compiledAsLeaf(false), staticStackSize(0),
259 automaticVarsSize(0), regSpillsSize(0),
260 currentOptionalArgsSize(0), maxOptionalArgsSize(0),
261 currentTmpValuesSize(0)
263 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method);
264 staticStackSize = maxOptionalArgsSize +
265 target.getFrameInfo().getMinStackFrameSize();
269 MachineCodeForMethod::allocateLocalVar(const TargetMachine& target,
273 // Check if we've allocated a stack slot for this value already
275 int offset = getOffset(val);
276 if (offset == INVALID_FRAME_OFFSET)
279 int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this,
284 size = target.findOptimalStorageSize(val->getType());
285 // align = target.DataLayout.getTypeAlignment(val->getType());
288 align = SizeToAlignment(size, target);
290 offset = getAutomaticVarsSize();
294 if (unsigned int mod = offset % align)
296 offset += align - mod;
300 offset = growUp? firstOffset + offset
301 : firstOffset - offset;
303 offsets[val] = offset;
305 incrementAutomaticVarsSize(size);
311 MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target,
314 unsigned int size = target.findOptimalStorageSize(type);
315 unsigned char align = target.DataLayout.getTypeAlignment(type);
318 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp);
320 int offset = getRegSpillsSize();
324 if (unsigned int mod = offset % align)
326 offset += align - mod;
330 offset = growUp? firstOffset + offset
331 : firstOffset - offset;
333 incrementRegSpillsSize(size);
339 MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target,
342 const MachineFrameInfo& frameInfo = target.getFrameInfo();
345 if (frameInfo.argsOnStackHaveFixedSize())
346 size = frameInfo.getSizeOfEachArgOnStack();
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");
352 unsigned char align = target.DataLayout.getTypeAlignment(type);
355 int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp);
357 int offset = getCurrentOptionalArgsSize();
361 if (unsigned int mod = offset % align)
363 offset += align - mod;
367 offset = growUp? firstOffset + offset
368 : firstOffset - offset;
370 incrementCurrentOptionalArgsSize(size);
376 MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target)
378 currentOptionalArgsSize = 0;
382 MachineCodeForMethod::pushTempValue(const TargetMachine& target,
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();
394 int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp);
396 int offset = currentTmpValuesSize;
400 if (unsigned int mod = offset % align)
402 offset += align - mod;
406 offset = growUp? firstTmpOffset + offset
407 : firstTmpOffset - offset;
409 currentTmpValuesSize += size;
414 MachineCodeForMethod::popAllTempValues(const TargetMachine& target)
416 currentTmpValuesSize = 0;
420 MachineCodeForMethod::getOffset(const Value* val) const
422 hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
423 return (pair == offsets.end())? INVALID_FRAME_OFFSET : (*pair).second;
427 MachineCodeForMethod::dump() const
429 cout << "\n" << method->getReturnType()
430 << " \"" << method->getName() << "\"" << endl;
432 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
434 BasicBlock* bb = *BI;
436 << (bb->hasName()? bb->getName() : "Label")
437 << " (" << bb << ")" << ":"
440 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
441 for (unsigned i=0; i < mvec.size(); i++)
442 cout << "\t" << *mvec[i];
444 cout << endl << "End method \"" << method->getName() << "\""