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