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 switch (mop.getOperandType()) 136 { 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() << ")"; 142 default: 143 assert(0 && "Unknown operand type"); 144 return os; 145 } 146 } 147 148 149 ostream& 150 operator<<(ostream &os, const MachineOperand &mop) 151 { 152 switch(mop.opType) 153 { 154 case MachineOperand::MO_VirtualRegister: 155 case MachineOperand::MO_MachineRegister: 156 os << "%reg"; 157 return OutputOperand(os, mop); 158 case MachineOperand::MO_CCRegister: 159 os << "%ccreg"; 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: 166 { 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 ") 171 << opVal << ")"; 172 } 173 default: 174 assert(0 && "Unrecognized operand type"); 175 break; 176 } 177 178 return os; 179 } 180 181 static unsigned int 182 ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method) 183 { 184 const MachineFrameInfo& frameInfo = target.getFrameInfo(); 185 186 unsigned int maxSize = 0; 187 188 for (Method::inst_const_iterator I=method->inst_begin(),E=method->inst_end(); 189 I != E; ++I) 190 if ((*I)->getOpcode() == Instruction::Call) 191 { 192 CallInst* callInst = cast<CallInst>(*I); 193 unsigned int numOperands = callInst->getNumOperands() - 1; 194 unsigned int numExtra = numOperands 195 - frameInfo.getNumFixedOutgoingArgs(); 196 197 unsigned int sizeForThisCall; 198 if (frameInfo.argsOnStackHaveFixedSize()) 199 { 200 int argSize = frameInfo.getSizeOfEachArgOnStack(); 201 sizeForThisCall = numExtra * (unsigned) argSize; 202 } 203 else 204 { 205 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual arg sizes to compute MaxOptionalArgsSize"); 206 sizeForThisCall = 0; 207 for (unsigned i=0; i < numOperands; ++i) 208 sizeForThisCall += target.findOptimalStorageSize(callInst-> 209 getOperand(i)->getType()); 210 } 211 212 if (maxSize < sizeForThisCall) 213 maxSize = sizeForThisCall; 214 } 215 216 return maxSize; 217 } 218 219 220 /*ctor*/ 221 MachineCodeForMethod::MachineCodeForMethod(const Method* _M, 222 const TargetMachine& target) 223 : Annotation(AID), 224 method(_M), compiledAsLeaf(false), staticStackSize(0), 225 automaticVarsSize(0), regSpillsSize(0), 226 currentOptionalArgsSize(0), maxOptionalArgsSize(0), 227 currentTmpValuesSize(0) 228 { 229 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method); 230 staticStackSize = maxOptionalArgsSize + 231 target.getFrameInfo().getMinStackFrameSize(); 232 } 233 234 int 235 MachineCodeForMethod::allocateLocalVar(const TargetMachine& target, 236 const Value* val) 237 { 238 // Check if we've allocated a stack slot for this value already 239 // 240 int offset = getOffset(val); 241 if (offset == INVALID_FRAME_OFFSET) 242 { 243 bool growUp; 244 int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this, 245 growUp); 246 offset = growUp? firstOffset + getAutomaticVarsSize() 247 : firstOffset - getAutomaticVarsSize(); 248 offsets[val] = offset; 249 250 unsigned int size = target.findOptimalStorageSize(val->getType()); 251 incrementAutomaticVarsSize(size); 252 } 253 return offset; 254 } 255 256 int 257 MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target, 258 const Type* type) 259 { 260 bool growUp; 261 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp); 262 int offset = growUp? firstOffset + getRegSpillsSize() 263 : firstOffset - getRegSpillsSize(); 264 265 unsigned int size = target.findOptimalStorageSize(type); 266 incrementRegSpillsSize(size); 267 268 return offset; 269 } 270 271 int 272 MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target, 273 const Type* type) 274 { 275 const MachineFrameInfo& frameInfo = target.getFrameInfo(); 276 bool growUp; 277 int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp); 278 int offset = growUp? firstOffset + getCurrentOptionalArgsSize() 279 : firstOffset - getCurrentOptionalArgsSize(); 280 281 int size = MAXINT; 282 if (frameInfo.argsOnStackHaveFixedSize()) 283 size = frameInfo.getSizeOfEachArgOnStack(); 284 else 285 { 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); 288 } 289 290 incrementCurrentOptionalArgsSize(size); 291 292 return offset; 293 } 294 295 void 296 MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target) 297 { 298 currentOptionalArgsSize = 0; 299 } 300 301 int 302 MachineCodeForMethod::pushTempValue(const TargetMachine& target, 303 unsigned int size) 304 { 305 bool growUp; 306 int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp); 307 int offset = growUp? firstTmpOffset + currentTmpValuesSize 308 : firstTmpOffset - currentTmpValuesSize; 309 currentTmpValuesSize += size; 310 return offset; 311 } 312 313 void 314 MachineCodeForMethod::popAllTempValues(const TargetMachine& target) 315 { 316 currentTmpValuesSize = 0; 317 } 318 319 320 // void 321 // MachineCodeForMethod::putLocalVarAtOffsetFromSP(const Value* local, 322 // int offset, 323 // unsigned int size) 324 // { 325 // offsetsFromSP[local] = offset; 326 // incrementAutomaticVarsSize(size); 327 // } 328 // 329 330 int 331 MachineCodeForMethod::getOffset(const Value* val) const 332 { 333 hash_map<const Value*, int>::const_iterator pair = offsets.find(val); 334 return (pair == offsets.end())? INVALID_FRAME_OFFSET : (*pair).second; 335 } 336 337 338 // int 339 // MachineCodeForMethod::getOffsetFromSP(const Value* local) const 340 // { 341 // hash_map<const Value*, int>::const_iterator pair = offsetsFromSP.find(local); 342 // return (pair == offsetsFromSP.end())? INVALID_FRAME_OFFSET : (*pair).second; 343 // } 344 345 346 void 347 MachineCodeForMethod::dump() const 348 { 349 cout << "\n" << method->getReturnType() 350 << " \"" << method->getName() << "\"" << endl; 351 352 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI) 353 { 354 BasicBlock* bb = *BI; 355 cout << "\n" 356 << (bb->hasName()? bb->getName() : "Label") 357 << " (" << bb << ")" << ":" 358 << endl; 359 360 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec(); 361 for (unsigned i=0; i < mvec.size(); i++) 362 cout << "\t" << *mvec[i]; 363 } 364 cout << endl << "End method \"" << method->getName() << "\"" 365 << endl << endl; 366 } 367