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/Method.h"
20 #include "llvm/iOther.h"
21 #include "llvm/Instruction.h"
23 AnnotationID MachineCodeForMethod::AID(
24 AnnotationManager::getID("MachineCodeForMethodAnnotation"));
27 //************************ Class Implementations **************************/
29 // Constructor for instructions with fixed #operands (nearly all)
30 MachineInstr::MachineInstr(MachineOpCode _opCode,
31 OpCodeMask _opCodeMask)
33 opCodeMask(_opCodeMask),
34 operands(TargetInstrDescriptors[_opCode].numOperands)
36 assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
39 // Constructor for instructions with variable #operands
40 MachineInstr::MachineInstr(MachineOpCode _opCode,
42 OpCodeMask _opCodeMask)
44 opCodeMask(_opCodeMask),
50 MachineInstr::SetMachineOperand(unsigned int i,
51 MachineOperand::MachineOperandType operandType,
52 Value* _val, bool isdef=false)
54 assert(i < operands.size());
55 operands[i].Initialize(operandType, _val);
56 operands[i].isDef = isdef ||
57 TargetInstrDescriptors[opCode].resultPos == (int) i;
61 MachineInstr::SetMachineOperand(unsigned int i,
62 MachineOperand::MachineOperandType operandType,
63 int64_t intValue, bool isdef=false)
65 assert(i < operands.size());
66 operands[i].InitializeConst(operandType, intValue);
67 operands[i].isDef = isdef ||
68 TargetInstrDescriptors[opCode].resultPos == (int) i;
72 MachineInstr::SetMachineOperand(unsigned int i,
73 int regNum, bool isdef=false)
75 assert(i < operands.size());
76 operands[i].InitializeReg(regNum);
77 operands[i].isDef = isdef ||
78 TargetInstrDescriptors[opCode].resultPos == (int) i;
82 MachineInstr::dump(unsigned int indent) const
84 for (unsigned i=0; i < indent; i++)
91 operator<< (ostream& os, const MachineInstr& minstr)
93 os << TargetInstrDescriptors[minstr.opCode].opCodeString;
95 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
96 os << "\t" << minstr.getOperand(i);
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)
103 const Value* val = *vo;
104 os << val << (vo.isDef()? "(def), " : ", ");
111 // code for printing implict references
113 unsigned NumOfImpRefs = minstr.getNumImplicitRefs();
114 if( NumOfImpRefs > 0 ) {
118 for(unsigned z=0; z < NumOfImpRefs; z++) {
119 os << minstr.getImplicitRef(z);
132 static inline ostream&
133 OutputOperand(ostream &os, const MachineOperand &mop)
135 switch (mop.getOperandType())
137 case MachineOperand::MO_CCRegister:
138 case MachineOperand::MO_VirtualRegister:
139 return os << "(val " << mop.getVRegValue() << ")";
140 case MachineOperand::MO_MachineRegister:
141 return os << "(" << mop.getMachineRegNum() << ")";
143 assert(0 && "Unknown operand type");
150 operator<<(ostream &os, const MachineOperand &mop)
154 case MachineOperand::MO_VirtualRegister:
155 case MachineOperand::MO_MachineRegister:
157 return OutputOperand(os, mop);
158 case MachineOperand::MO_CCRegister:
160 return OutputOperand(os, mop);
161 case MachineOperand::MO_SignExtendedImmed:
162 return os << mop.immedVal;
163 case MachineOperand::MO_UnextendedImmed:
164 return os << mop.immedVal;
165 case MachineOperand::MO_PCRelativeDisp:
167 const Value* opVal = mop.getVRegValue();
168 bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal);
169 return os << "%disp("
170 << (isLabel? "label " : "addr-of-val ")
174 assert(0 && "Unrecognized operand type");
182 ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method)
184 const MachineFrameInfo& frameInfo = target.getFrameInfo();
186 unsigned int maxSize = 0;
188 for (Method::inst_const_iterator I=method->inst_begin(),E=method->inst_end();
190 if ((*I)->getOpcode() == Instruction::Call)
192 CallInst* callInst = cast<CallInst>(*I);
193 unsigned int numOperands = callInst->getNumOperands() - 1;
194 unsigned int numExtra = numOperands
195 - frameInfo.getNumFixedOutgoingArgs();
197 unsigned int sizeForThisCall;
198 if (frameInfo.argsOnStackHaveFixedSize())
200 int argSize = frameInfo.getSizeOfEachArgOnStack();
201 sizeForThisCall = numExtra * (unsigned) argSize;
205 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual arg sizes to compute MaxOptionalArgsSize");
207 for (unsigned i=0; i < numOperands; ++i)
208 sizeForThisCall += target.findOptimalStorageSize(callInst->
209 getOperand(i)->getType());
212 if (maxSize < sizeForThisCall)
213 maxSize = sizeForThisCall;
221 MachineCodeForMethod::MachineCodeForMethod(const Method* _M,
222 const TargetMachine& target)
224 method(_M), compiledAsLeaf(false), staticStackSize(0),
225 automaticVarsSize(0), regSpillsSize(0),
226 currentOptionalArgsSize(0), maxOptionalArgsSize(0),
227 currentTmpValuesSize(0)
229 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method);
230 staticStackSize = maxOptionalArgsSize +
231 target.getFrameInfo().getMinStackFrameSize();
235 MachineCodeForMethod::allocateLocalVar(const TargetMachine& target,
238 // Check if we've allocated a stack slot for this value already
240 int offset = getOffset(val);
241 if (offset == INVALID_FRAME_OFFSET)
244 int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this,
246 offset = growUp? firstOffset + getAutomaticVarsSize()
247 : firstOffset - getAutomaticVarsSize();
248 offsets[val] = offset;
250 unsigned int size = target.findOptimalStorageSize(val->getType());
251 incrementAutomaticVarsSize(size);
257 MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target,
261 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp);
262 int offset = growUp? firstOffset + getRegSpillsSize()
263 : firstOffset - getRegSpillsSize();
265 unsigned int size = target.findOptimalStorageSize(type);
266 incrementRegSpillsSize(size);
272 MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target,
275 const MachineFrameInfo& frameInfo = target.getFrameInfo();
277 int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp);
278 int offset = growUp? firstOffset + getCurrentOptionalArgsSize()
279 : firstOffset - getCurrentOptionalArgsSize();
282 if (frameInfo.argsOnStackHaveFixedSize())
283 size = frameInfo.getSizeOfEachArgOnStack();
286 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual argument sizes for computing optional arg offsets");
287 size = target.findOptimalStorageSize(type);
290 incrementCurrentOptionalArgsSize(size);
296 MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target)
298 currentOptionalArgsSize = 0;
302 MachineCodeForMethod::pushTempValue(const TargetMachine& target,
306 int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp);
307 int offset = growUp? firstTmpOffset + currentTmpValuesSize
308 : firstTmpOffset - currentTmpValuesSize;
309 currentTmpValuesSize += size;
314 MachineCodeForMethod::popAllTempValues(const TargetMachine& target)
316 currentTmpValuesSize = 0;
321 // MachineCodeForMethod::putLocalVarAtOffsetFromSP(const Value* local,
323 // unsigned int size)
325 // offsetsFromSP[local] = offset;
326 // incrementAutomaticVarsSize(size);
331 MachineCodeForMethod::getOffset(const Value* val) const
333 hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
334 return (pair == offsets.end())? INVALID_FRAME_OFFSET : (*pair).second;
339 // MachineCodeForMethod::getOffsetFromSP(const Value* local) const
341 // hash_map<const Value*, int>::const_iterator pair = offsetsFromSP.find(local);
342 // return (pair == offsetsFromSP.end())? INVALID_FRAME_OFFSET : (*pair).second;
347 MachineCodeForMethod::dump() const
349 cout << "\n" << method->getReturnType()
350 << " \"" << method->getName() << "\"" << endl;
352 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
354 BasicBlock* bb = *BI;
356 << (bb->hasName()? bb->getName() : "Label")
357 << " (" << bb << ")" << ":"
360 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
361 for (unsigned i=0; i < mvec.size(); i++)
362 cout << "\t" << *mvec[i];
364 cout << endl << "End method \"" << method->getName() << "\""