MachineInstr.cpp revision e492c9d4d1a161cd0972bfb8bab33f073fb018b4
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 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 280int 281MachineCodeForMethod::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 308int 309MachineCodeForMethod::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 345void 346MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target) 347{ 348 currentOptionalArgsSize = 0; 349} 350 351int 352MachineCodeForMethod::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 383void 384MachineCodeForMethod::popAllTempValues(const TargetMachine& target) 385{ 386 currentTmpValuesSize = 0; 387} 388 389int 390MachineCodeForMethod::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 396void 397MachineCodeForMethod::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