MachineInstr.cpp revision ab8672c8bb83e722b856eac67863542ea7e0cbb2
1//===-- MachineInstr.cpp --------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10//===----------------------------------------------------------------------===// 11 12#include "llvm/CodeGen/MachineInstr.h" 13#include "llvm/CodeGen/MachineBasicBlock.h" 14#include "llvm/Value.h" 15#include "llvm/Target/TargetMachine.h" 16#include "llvm/Target/TargetInstrInfo.h" 17#include "llvm/Target/MRegisterInfo.h" 18 19namespace llvm { 20 21// Global variable holding an array of descriptors for machine instructions. 22// The actual object needs to be created separately for each target machine. 23// This variable is initialized and reset by class TargetInstrInfo. 24// 25// FIXME: This should be a property of the target so that more than one target 26// at a time can be active... 27// 28extern const TargetInstrDescriptor *TargetInstrDescriptors; 29 30// Constructor for instructions with variable #operands 31MachineInstr::MachineInstr(short opcode, unsigned numOperands) 32 : Opcode(opcode), 33 numImplicitRefs(0), 34 operands(numOperands, MachineOperand()), 35 parent(0) { 36} 37 38/// MachineInstr ctor - This constructor only does a _reserve_ of the operands, 39/// not a resize for them. It is expected that if you use this that you call 40/// add* methods below to fill up the operands, instead of the Set methods. 41/// Eventually, the "resizing" ctors will be phased out. 42/// 43MachineInstr::MachineInstr(short opcode, unsigned numOperands, 44 bool XX, bool YY) 45 : Opcode(opcode), 46 numImplicitRefs(0), 47 parent(0) { 48 operands.reserve(numOperands); 49} 50 51/// MachineInstr ctor - Work exactly the same as the ctor above, except that the 52/// MachineInstr is created and added to the end of the specified basic block. 53/// 54MachineInstr::MachineInstr(MachineBasicBlock *MBB, short opcode, 55 unsigned numOperands) 56 : Opcode(opcode), 57 numImplicitRefs(0), 58 parent(0) { 59 assert(MBB && "Cannot use inserting ctor with null basic block!"); 60 operands.reserve(numOperands); 61 MBB->push_back(this); // Add instruction to end of basic block! 62} 63 64 65// OperandComplete - Return true if it's illegal to add a new operand 66bool MachineInstr::OperandsComplete() const { 67 int NumOperands = TargetInstrDescriptors[Opcode].numOperands; 68 if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands) 69 return true; // Broken: we have all the operands of this instruction! 70 return false; 71} 72 73 74// 75// Support for replacing opcode and operands of a MachineInstr in place. 76// This only resets the size of the operand vector and initializes it. 77// The new operands must be set explicitly later. 78// 79void MachineInstr::replace(short opcode, unsigned numOperands) { 80 assert(getNumImplicitRefs() == 0 && 81 "This is probably broken because implicit refs are going to be lost."); 82 Opcode = opcode; 83 operands.clear(); 84 operands.resize(numOperands, MachineOperand()); 85} 86 87void MachineInstr::SetMachineOperandVal(unsigned i, 88 MachineOperand::MachineOperandType opTy, 89 Value* V) { 90 assert(i < operands.size()); // may be explicit or implicit op 91 operands[i].opType = opTy; 92 operands[i].value = V; 93 operands[i].regNum = -1; 94} 95 96void 97MachineInstr::SetMachineOperandConst(unsigned i, 98 MachineOperand::MachineOperandType operandType, 99 int64_t intValue) { 100 assert(i < getNumOperands()); // must be explicit op 101 assert(TargetInstrDescriptors[Opcode].resultPos != (int) i && 102 "immed. constant cannot be defined"); 103 104 operands[i].opType = operandType; 105 operands[i].value = NULL; 106 operands[i].immedVal = intValue; 107 operands[i].regNum = -1; 108 operands[i].flags = 0; 109} 110 111void MachineInstr::SetMachineOperandReg(unsigned i, int regNum) { 112 assert(i < getNumOperands()); // must be explicit op 113 114 operands[i].opType = MachineOperand::MO_MachineRegister; 115 operands[i].value = NULL; 116 operands[i].regNum = regNum; 117} 118 119void MachineInstr::SetRegForOperand(unsigned i, int regNum) { 120 assert(i < getNumOperands()); // must be explicit op 121 operands[i].setRegForValue(regNum); 122} 123 124void MachineInstr::SetRegForImplicitRef(unsigned i, int regNum) { 125 getImplicitOp(i).setRegForValue(regNum); 126} 127 128 129// Substitute all occurrences of Value* oldVal with newVal in all operands 130// and all implicit refs. 131// If defsOnly == true, substitute defs only. 132unsigned 133MachineInstr::substituteValue(const Value* oldVal, Value* newVal, 134 bool defsOnly, bool notDefsAndUses, 135 bool& someArgsWereIgnored) 136{ 137 assert((!defsOnly || !notDefsAndUses) && 138 "notDefsAndUses is irrelevant if defsOnly == true."); 139 140 unsigned numSubst = 0; 141 142 // Substitute operands 143 for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O) 144 if (*O == oldVal) 145 if (!defsOnly || 146 notDefsAndUses && (O.isDef() && !O.isUse()) || 147 !notDefsAndUses && O.isDef()) 148 { 149 O.getMachineOperand().value = newVal; 150 ++numSubst; 151 } 152 else 153 someArgsWereIgnored = true; 154 155 // Substitute implicit refs 156 for (unsigned i=0, N=getNumImplicitRefs(); i < N; ++i) 157 if (getImplicitRef(i) == oldVal) 158 if (!defsOnly || 159 notDefsAndUses && (getImplicitOp(i).isDef() && !getImplicitOp(i).isUse()) || 160 !notDefsAndUses && getImplicitOp(i).isDef()) 161 { 162 getImplicitOp(i).value = newVal; 163 ++numSubst; 164 } 165 else 166 someArgsWereIgnored = true; 167 168 return numSubst; 169} 170 171 172void 173MachineInstr::dump() const 174{ 175 std::cerr << " " << *this; 176} 177 178static inline std::ostream& 179OutputValue(std::ostream &os, const Value* val) 180{ 181 os << "(val "; 182 os << (void*) val; // print address always 183 if (val && val->hasName()) 184 os << " " << val->getName() << ")"; // print name also, if available 185 return os; 186} 187 188static inline void OutputReg(std::ostream &os, unsigned RegNo, 189 const MRegisterInfo *MRI = 0) { 190 if (MRI) { 191 if (RegNo < MRegisterInfo::FirstVirtualRegister) 192 os << "%" << MRI->get(RegNo).Name; 193 else 194 os << "%reg" << RegNo; 195 } else 196 os << "%mreg(" << RegNo << ")"; 197} 198 199static void print(const MachineOperand &MO, std::ostream &OS, 200 const TargetMachine &TM) { 201 const MRegisterInfo *MRI = TM.getRegisterInfo(); 202 bool CloseParen = true; 203 if (MO.isHiBits32()) 204 OS << "%lm("; 205 else if (MO.isLoBits32()) 206 OS << "%lo("; 207 else if (MO.isHiBits64()) 208 OS << "%hh("; 209 else if (MO.isLoBits64()) 210 OS << "%hm("; 211 else 212 CloseParen = false; 213 214 switch (MO.getType()) { 215 case MachineOperand::MO_VirtualRegister: 216 if (MO.getVRegValue()) { 217 OS << "%reg"; 218 OutputValue(OS, MO.getVRegValue()); 219 if (MO.hasAllocatedReg()) 220 OS << "=="; 221 } 222 if (MO.hasAllocatedReg()) 223 OutputReg(OS, MO.getAllocatedRegNum(), MRI); 224 break; 225 case MachineOperand::MO_CCRegister: 226 OS << "%ccreg"; 227 OutputValue(OS, MO.getVRegValue()); 228 if (MO.hasAllocatedReg()) { 229 OS << "=="; 230 OutputReg(OS, MO.getAllocatedRegNum(), MRI); 231 } 232 break; 233 case MachineOperand::MO_MachineRegister: 234 OutputReg(OS, MO.getMachineRegNum(), MRI); 235 break; 236 case MachineOperand::MO_SignExtendedImmed: 237 OS << (long)MO.getImmedValue(); 238 break; 239 case MachineOperand::MO_UnextendedImmed: 240 OS << (long)MO.getImmedValue(); 241 break; 242 case MachineOperand::MO_PCRelativeDisp: { 243 const Value* opVal = MO.getVRegValue(); 244 bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal); 245 OS << "%disp(" << (isLabel? "label " : "addr-of-val "); 246 if (opVal->hasName()) 247 OS << opVal->getName(); 248 else 249 OS << (const void*) opVal; 250 OS << ")"; 251 break; 252 } 253 case MachineOperand::MO_MachineBasicBlock: 254 OS << "bb<" 255 << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName() 256 << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">"; 257 break; 258 case MachineOperand::MO_FrameIndex: 259 OS << "<fi#" << MO.getFrameIndex() << ">"; 260 break; 261 case MachineOperand::MO_ConstantPoolIndex: 262 OS << "<cp#" << MO.getConstantPoolIndex() << ">"; 263 break; 264 case MachineOperand::MO_GlobalAddress: 265 OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">"; 266 break; 267 case MachineOperand::MO_ExternalSymbol: 268 OS << "<es:" << MO.getSymbolName() << ">"; 269 break; 270 default: 271 assert(0 && "Unrecognized operand type"); 272 } 273 274 if (CloseParen) 275 OS << ")"; 276} 277 278void MachineInstr::print(std::ostream &OS, const TargetMachine &TM) const { 279 unsigned StartOp = 0; 280 281 // Specialize printing if op#0 is definition 282 if (getNumOperands() && getOperand(0).isDef() && !getOperand(0).isUse()) { 283 llvm::print(getOperand(0), OS, TM); 284 OS << " = "; 285 ++StartOp; // Don't print this operand again! 286 } 287 OS << TM.getInstrInfo().getName(getOpcode()); 288 289 for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 290 const MachineOperand& mop = getOperand(i); 291 if (i != StartOp) 292 OS << ","; 293 OS << " "; 294 llvm::print(mop, OS, TM); 295 296 if (mop.isDef()) 297 if (mop.isUse()) 298 OS << "<def&use>"; 299 else 300 OS << "<def>"; 301 } 302 303 // code for printing implicit references 304 if (getNumImplicitRefs()) { 305 OS << "\tImplicitRefs: "; 306 for(unsigned i = 0, e = getNumImplicitRefs(); i != e; ++i) { 307 OS << "\t"; 308 OutputValue(OS, getImplicitRef(i)); 309 if (getImplicitOp(i).isDef()) 310 if (getImplicitOp(i).isUse()) 311 OS << "<def&use>"; 312 else 313 OS << "<def>"; 314 } 315 } 316 317 OS << "\n"; 318} 319 320 321std::ostream &operator<<(std::ostream& os, const MachineInstr& MI) 322{ 323 os << TargetInstrDescriptors[MI.getOpcode()].Name; 324 325 for (unsigned i=0, N=MI.getNumOperands(); i < N; i++) { 326 os << "\t" << MI.getOperand(i); 327 if (MI.getOperand(i).isDef()) 328 if (MI.getOperand(i).isUse()) 329 os << "<d&u>"; 330 else 331 os << "<d>"; 332 } 333 334 // code for printing implicit references 335 unsigned NumOfImpRefs = MI.getNumImplicitRefs(); 336 if (NumOfImpRefs > 0) { 337 os << "\tImplicit: "; 338 for (unsigned z=0; z < NumOfImpRefs; z++) { 339 OutputValue(os, MI.getImplicitRef(z)); 340 if (MI.getImplicitOp(z).isDef()) 341 if (MI.getImplicitOp(z).isUse()) 342 os << "<d&u>"; 343 else 344 os << "<d>"; 345 os << "\t"; 346 } 347 } 348 349 return os << "\n"; 350} 351 352std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO) 353{ 354 if (MO.isHiBits32()) 355 OS << "%lm("; 356 else if (MO.isLoBits32()) 357 OS << "%lo("; 358 else if (MO.isHiBits64()) 359 OS << "%hh("; 360 else if (MO.isLoBits64()) 361 OS << "%hm("; 362 363 switch (MO.getType()) 364 { 365 case MachineOperand::MO_VirtualRegister: 366 if (MO.hasAllocatedReg()) 367 OutputReg(OS, MO.getAllocatedRegNum()); 368 369 if (MO.getVRegValue()) { 370 if (MO.hasAllocatedReg()) OS << "=="; 371 OS << "%vreg"; 372 OutputValue(OS, MO.getVRegValue()); 373 } 374 break; 375 case MachineOperand::MO_CCRegister: 376 OS << "%ccreg"; 377 OutputValue(OS, MO.getVRegValue()); 378 if (MO.hasAllocatedReg()) { 379 OS << "=="; 380 OutputReg(OS, MO.getAllocatedRegNum()); 381 } 382 break; 383 case MachineOperand::MO_MachineRegister: 384 OutputReg(OS, MO.getMachineRegNum()); 385 break; 386 case MachineOperand::MO_SignExtendedImmed: 387 OS << (long)MO.getImmedValue(); 388 break; 389 case MachineOperand::MO_UnextendedImmed: 390 OS << (long)MO.getImmedValue(); 391 break; 392 case MachineOperand::MO_PCRelativeDisp: 393 { 394 const Value* opVal = MO.getVRegValue(); 395 bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal); 396 OS << "%disp(" << (isLabel? "label " : "addr-of-val "); 397 if (opVal->hasName()) 398 OS << opVal->getName(); 399 else 400 OS << (const void*) opVal; 401 OS << ")"; 402 break; 403 } 404 case MachineOperand::MO_MachineBasicBlock: 405 OS << "bb<" 406 << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName() 407 << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">"; 408 break; 409 case MachineOperand::MO_FrameIndex: 410 OS << "<fi#" << MO.getFrameIndex() << ">"; 411 break; 412 case MachineOperand::MO_ConstantPoolIndex: 413 OS << "<cp#" << MO.getConstantPoolIndex() << ">"; 414 break; 415 case MachineOperand::MO_GlobalAddress: 416 OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">"; 417 break; 418 case MachineOperand::MO_ExternalSymbol: 419 OS << "<es:" << MO.getSymbolName() << ">"; 420 break; 421 default: 422 assert(0 && "Unrecognized operand type"); 423 break; 424 } 425 426 if (MO.flags & 427 (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 | 428 MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64)) 429 OS << ")"; 430 431 return OS; 432} 433 434} // End llvm namespace 435