MachineInstr.cpp revision d9beb975f20cea2d3e9c3f528068cd25b80a1b72
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 23AnnotationID MachineCodeForMethod::AID( 24 AnnotationManager::getID("MachineCodeForMethodAnnotation")); 25 26 27//************************ Class Implementations **************************/ 28 29// Constructor for instructions with fixed #operands (nearly all) 30MachineInstr::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 40MachineInstr::MachineInstr(MachineOpCode _opCode, 41 unsigned numOperands, 42 OpCodeMask _opCodeMask) 43 : opCode(_opCode), 44 opCodeMask(_opCodeMask), 45 operands(numOperands) 46{ 47} 48 49void 50MachineInstr::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 60void 61MachineInstr::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 71void 72MachineInstr::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 81void 82MachineInstr::dump(unsigned int indent) const 83{ 84 for (unsigned i=0; i < indent; i++) 85 cout << " "; 86 87 cout << *this; 88} 89 90ostream& 91operator<< (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 132static inline ostream& 133OutputOperand(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 156ostream& 157operator<<(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 191static unsigned int 192ComputeMaxOptionalArgsSize(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*/ 232MachineCodeForMethod::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 245int 246MachineCodeForMethod::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 unsigned int size = target.findOptimalStorageSize(val->getType()); 255 unsigned char align = target.DataLayout.getTypeAlignment(val->getType()); 256 257 offset = getAutomaticVarsSize(); 258 if (unsigned int mod = offset % align) 259 { 260 offset += align - mod; 261 size += align - mod; 262 } 263 264 bool growUp; 265 int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this, 266 growUp); 267 offset = growUp? firstOffset + offset 268 : firstOffset - offset - size; 269 270 offsets[val] = offset; 271 272 incrementAutomaticVarsSize(size); 273 } 274 return offset; 275} 276 277int 278MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target, 279 const Type* type) 280{ 281 unsigned int size = target.findOptimalStorageSize(type); 282 unsigned char align = target.DataLayout.getTypeAlignment(type); 283 284 int offset = getRegSpillsSize(); 285 if (unsigned int mod = offset % align) 286 { 287 offset += align - mod; 288 size += align - mod; 289 } 290 291 bool growUp; 292 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp); 293 offset = growUp? firstOffset + offset 294 : firstOffset - offset - size; 295 296 incrementRegSpillsSize(size); 297 298 return offset; 299} 300 301int 302MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target, 303 const Type* type) 304{ 305 const MachineFrameInfo& frameInfo = target.getFrameInfo(); 306 307 int size = MAXINT; 308 if (frameInfo.argsOnStackHaveFixedSize()) 309 size = frameInfo.getSizeOfEachArgOnStack(); 310 else 311 { 312 size = target.findOptimalStorageSize(type); 313 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual argument sizes for computing optional arg offsets"); 314 } 315 unsigned char align = target.DataLayout.getTypeAlignment(type); 316 317 int offset = getCurrentOptionalArgsSize(); 318 if (unsigned int mod = offset % align) 319 { 320 offset += align - mod; 321 size += align - mod; 322 } 323 324 bool growUp; 325 int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp); 326 offset = growUp? firstOffset + offset 327 : firstOffset - offset - size; 328 329 incrementCurrentOptionalArgsSize(size); 330 331 return offset; 332} 333 334void 335MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target) 336{ 337 currentOptionalArgsSize = 0; 338} 339 340int 341MachineCodeForMethod::pushTempValue(const TargetMachine& target, 342 unsigned int size) 343{ 344 // Compute a power-of-2 alignment according to the possible sizes, 345 // but not greater than the alignment of the largest type we support 346 // (currently a double word -- see class TargetData). 347 unsigned char align = 1; 348 for (; align < size && align < target.DataLayout.getDoubleAlignment(); 349 align = 2*align) 350 ; 351 352 int offset = currentTmpValuesSize; 353 if (unsigned int mod = offset % align) 354 { 355 offset += align - mod; 356 size += align - mod; 357 } 358 359 bool growUp; 360 int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp); 361 offset = growUp? firstTmpOffset + offset 362 : firstTmpOffset - offset - size; 363 364 currentTmpValuesSize += size; 365 return offset; 366} 367 368void 369MachineCodeForMethod::popAllTempValues(const TargetMachine& target) 370{ 371 currentTmpValuesSize = 0; 372} 373 374 375// void 376// MachineCodeForMethod::putLocalVarAtOffsetFromSP(const Value* local, 377// int offset, 378// unsigned int size) 379// { 380// offsetsFromSP[local] = offset; 381// incrementAutomaticVarsSize(size); 382// } 383// 384 385int 386MachineCodeForMethod::getOffset(const Value* val) const 387{ 388 hash_map<const Value*, int>::const_iterator pair = offsets.find(val); 389 return (pair == offsets.end())? INVALID_FRAME_OFFSET : (*pair).second; 390} 391 392 393// int 394// MachineCodeForMethod::getOffsetFromSP(const Value* local) const 395// { 396// hash_map<const Value*, int>::const_iterator pair = offsetsFromSP.find(local); 397// return (pair == offsetsFromSP.end())? INVALID_FRAME_OFFSET : (*pair).second; 398// } 399 400 401void 402MachineCodeForMethod::dump() const 403{ 404 cout << "\n" << method->getReturnType() 405 << " \"" << method->getName() << "\"" << endl; 406 407 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI) 408 { 409 BasicBlock* bb = *BI; 410 cout << "\n" 411 << (bb->hasName()? bb->getName() : "Label") 412 << " (" << bb << ")" << ":" 413 << endl; 414 415 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec(); 416 for (unsigned i=0; i < mvec.size(); i++) 417 cout << "\t" << *mvec[i]; 418 } 419 cout << endl << "End method \"" << method->getName() << "\"" 420 << endl << endl; 421} 422