MachineInstr.cpp revision 6b2c05f3d3c7b44183c629485ade10c18b86828d
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// Methods common to all machine instructions. 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/CodeGen/MachineInstr.h" 15#include "llvm/CodeGen/MachineFunction.h" 16#include "llvm/Target/TargetMachine.h" 17#include "llvm/Target/TargetInstrInfo.h" 18#include "llvm/Target/MRegisterInfo.h" 19#include "llvm/Support/LeakDetector.h" 20#include <iostream> 21 22using namespace llvm; 23 24// Global variable holding an array of descriptors for machine instructions. 25// The actual object needs to be created separately for each target machine. 26// This variable is initialized and reset by class TargetInstrInfo. 27// 28// FIXME: This should be a property of the target so that more than one target 29// at a time can be active... 30// 31namespace llvm { 32 extern const TargetInstrDescriptor *TargetInstrDescriptors; 33} 34 35/// MachineInstr ctor - This constructor only does a _reserve_ of the operands, 36/// not a resize for them. It is expected that if you use this that you call 37/// add* methods below to fill up the operands, instead of the Set methods. 38/// Eventually, the "resizing" ctors will be phased out. 39/// 40MachineInstr::MachineInstr(short opcode, unsigned numOperands) 41 : Opcode(opcode), NumImplicitOps(0), parent(0) { 42 Operands.reserve(numOperands); 43 // Make sure that we get added to a machine basicblock 44 LeakDetector::addGarbageObject(this); 45} 46 47void MachineInstr::addImplicitDefUseOperands(const TargetInstrDescriptor &TID) { 48 if (TID.ImplicitDefs) 49 for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs) { 50 MachineOperand Op; 51 Op.opType = MachineOperand::MO_Register; 52 Op.IsDef = true; 53 Op.IsImp = true; 54 Op.IsKill = false; 55 Op.IsDead = false; 56 Op.contents.RegNo = *ImpDefs; 57 Op.offset = 0; 58 Operands.push_back(Op); 59 } 60 if (TID.ImplicitUses) 61 for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses) { 62 MachineOperand Op; 63 Op.opType = MachineOperand::MO_Register; 64 Op.IsDef = false; 65 Op.IsImp = true; 66 Op.IsKill = false; 67 Op.IsDead = false; 68 Op.contents.RegNo = *ImpUses; 69 Op.offset = 0; 70 Operands.push_back(Op); 71 } 72} 73 74/// MachineInstr ctor - This constructor create a MachineInstr and add the 75/// implicit operands. It reserves space for numOperand operands. 76MachineInstr::MachineInstr(const TargetInstrInfo &TII, short opcode, 77 unsigned numOperands) 78 : Opcode(opcode), NumImplicitOps(0), parent(0) { 79 const TargetInstrDescriptor &TID = TII.get(opcode); 80 if (TID.ImplicitDefs) 81 for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs) 82 NumImplicitOps++; 83 if (TID.ImplicitUses) 84 for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses) 85 NumImplicitOps++; 86 Operands.reserve(NumImplicitOps + numOperands); 87 addImplicitDefUseOperands(TID); 88 // Make sure that we get added to a machine basicblock 89 LeakDetector::addGarbageObject(this); 90} 91 92/// MachineInstr ctor - Work exactly the same as the ctor above, except that the 93/// MachineInstr is created and added to the end of the specified basic block. 94/// 95MachineInstr::MachineInstr(MachineBasicBlock *MBB, short opcode, 96 unsigned numOperands) 97 : Opcode(opcode), NumImplicitOps(0), parent(0) { 98 assert(MBB && "Cannot use inserting ctor with null basic block!"); 99 const TargetInstrDescriptor &TID = MBB->getParent()->getTarget(). 100 getInstrInfo()->get(opcode); 101 if (TID.ImplicitDefs) 102 for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs) 103 NumImplicitOps++; 104 if (TID.ImplicitUses) 105 for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses) 106 NumImplicitOps++; 107 Operands.reserve(NumImplicitOps + numOperands); 108 addImplicitDefUseOperands(TID); 109 // Make sure that we get added to a machine basicblock 110 LeakDetector::addGarbageObject(this); 111 MBB->push_back(this); // Add instruction to end of basic block! 112} 113 114/// MachineInstr ctor - Copies MachineInstr arg exactly 115/// 116MachineInstr::MachineInstr(const MachineInstr &MI) { 117 Opcode = MI.getOpcode(); 118 NumImplicitOps = MI.NumImplicitOps; 119 Operands.reserve(MI.getNumOperands()); 120 121 // Add operands 122 for (unsigned i = 0; i != MI.getNumOperands(); ++i) 123 Operands.push_back(MI.getOperand(i)); 124 125 // Set parent, next, and prev to null 126 parent = 0; 127 prev = 0; 128 next = 0; 129} 130 131 132MachineInstr::~MachineInstr() { 133 LeakDetector::removeGarbageObject(this); 134} 135 136/// removeFromParent - This method unlinks 'this' from the containing basic 137/// block, and returns it, but does not delete it. 138MachineInstr *MachineInstr::removeFromParent() { 139 assert(getParent() && "Not embedded in a basic block!"); 140 getParent()->remove(this); 141 return this; 142} 143 144 145/// OperandComplete - Return true if it's illegal to add a new operand 146/// 147bool MachineInstr::OperandsComplete() const { 148 int NumOperands = TargetInstrDescriptors[Opcode].numOperands; 149 if ((TargetInstrDescriptors[Opcode].Flags & M_VARIABLE_OPS) == 0 && 150 getNumOperands()-NumImplicitOps >= (unsigned)NumOperands) 151 return true; // Broken: we have all the operands of this instruction! 152 return false; 153} 154 155/// isIdenticalTo - Return true if this operand is identical to the specified 156/// operand. 157bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 158 if (getType() != Other.getType()) return false; 159 160 switch (getType()) { 161 default: assert(0 && "Unrecognized operand type"); 162 case MachineOperand::MO_Register: 163 return getReg() == Other.getReg() && isDef() == Other.isDef(); 164 case MachineOperand::MO_Immediate: 165 return getImm() == Other.getImm(); 166 case MachineOperand::MO_MachineBasicBlock: 167 return getMBB() == Other.getMBB(); 168 case MachineOperand::MO_FrameIndex: 169 return getFrameIndex() == Other.getFrameIndex(); 170 case MachineOperand::MO_ConstantPoolIndex: 171 return getConstantPoolIndex() == Other.getConstantPoolIndex() && 172 getOffset() == Other.getOffset(); 173 case MachineOperand::MO_JumpTableIndex: 174 return getJumpTableIndex() == Other.getJumpTableIndex(); 175 case MachineOperand::MO_GlobalAddress: 176 return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 177 case MachineOperand::MO_ExternalSymbol: 178 return !strcmp(getSymbolName(), Other.getSymbolName()) && 179 getOffset() == Other.getOffset(); 180 } 181} 182 183/// setOpcode - Replace the opcode of the current instruction with a new one. 184/// 185void MachineInstr::setOpcode(unsigned Op) { 186 Operands.erase(Operands.begin(), Operands.begin()+NumImplicitOps); 187 NumImplicitOps = 0; 188 Opcode = Op; 189 if (!getParent()) 190 return; 191 const TargetInstrDescriptor &TID = getParent()->getParent()-> 192 getTarget().getInstrInfo()->get(Op); 193 if (TID.ImplicitDefs) 194 for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs) { 195 MachineOperand Op; 196 Op.opType = MachineOperand::MO_Register; 197 Op.IsDef = true; 198 Op.IsImp = true; 199 Op.IsKill = false; 200 Op.IsDead = false; 201 Op.contents.RegNo = *ImpDefs; 202 Op.offset = 0; 203 Operands.insert(Operands.begin()+NumImplicitOps, Op); 204 NumImplicitOps++; 205 } 206 if (TID.ImplicitUses) 207 for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses) { 208 MachineOperand Op; 209 Op.opType = MachineOperand::MO_Register; 210 Op.IsDef = false; 211 Op.IsImp = true; 212 Op.IsKill = false; 213 Op.IsDead = false; 214 Op.contents.RegNo = *ImpUses; 215 Op.offset = 0; 216 Operands.insert(Operands.begin()+NumImplicitOps, Op); 217 NumImplicitOps++; 218 } 219} 220 221 222void MachineInstr::dump() const { 223 std::cerr << " " << *this; 224} 225 226static inline void OutputReg(std::ostream &os, unsigned RegNo, 227 const MRegisterInfo *MRI = 0) { 228 if (!RegNo || MRegisterInfo::isPhysicalRegister(RegNo)) { 229 if (MRI) 230 os << "%" << MRI->get(RegNo).Name; 231 else 232 os << "%mreg(" << RegNo << ")"; 233 } else 234 os << "%reg" << RegNo; 235} 236 237static void print(const MachineOperand &MO, std::ostream &OS, 238 const TargetMachine *TM) { 239 const MRegisterInfo *MRI = 0; 240 241 if (TM) MRI = TM->getRegisterInfo(); 242 243 switch (MO.getType()) { 244 case MachineOperand::MO_Register: 245 OutputReg(OS, MO.getReg(), MRI); 246 break; 247 case MachineOperand::MO_Immediate: 248 OS << MO.getImmedValue(); 249 break; 250 case MachineOperand::MO_MachineBasicBlock: 251 OS << "mbb<" 252 << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName() 253 << "," << (void*)MO.getMachineBasicBlock() << ">"; 254 break; 255 case MachineOperand::MO_FrameIndex: 256 OS << "<fi#" << MO.getFrameIndex() << ">"; 257 break; 258 case MachineOperand::MO_ConstantPoolIndex: 259 OS << "<cp#" << MO.getConstantPoolIndex() << ">"; 260 break; 261 case MachineOperand::MO_JumpTableIndex: 262 OS << "<jt#" << MO.getJumpTableIndex() << ">"; 263 break; 264 case MachineOperand::MO_GlobalAddress: 265 OS << "<ga:" << ((Value*)MO.getGlobal())->getName(); 266 if (MO.getOffset()) OS << "+" << MO.getOffset(); 267 OS << ">"; 268 break; 269 case MachineOperand::MO_ExternalSymbol: 270 OS << "<es:" << MO.getSymbolName(); 271 if (MO.getOffset()) OS << "+" << MO.getOffset(); 272 OS << ">"; 273 break; 274 default: 275 assert(0 && "Unrecognized operand type"); 276 } 277} 278 279void MachineInstr::print(std::ostream &OS, const TargetMachine *TM) const { 280 unsigned StartOp = 0; 281 282 // Specialize printing if op#0 is definition 283 if (getNumOperands() && getOperand(0).isReg() && getOperand(0).isDef()) { 284 ::print(getOperand(0), OS, TM); 285 OS << " = "; 286 ++StartOp; // Don't print this operand again! 287 } 288 289 // Must check if Target machine is not null because machine BB could not 290 // be attached to a Machine function yet 291 if (TM) 292 OS << TM->getInstrInfo()->getName(getOpcode()); 293 294 for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 295 const MachineOperand& mop = getOperand(i); 296 if (i != StartOp) 297 OS << ","; 298 OS << " "; 299 ::print(mop, OS, TM); 300 301 if (mop.isReg()) { 302 if (mop.isDef() || mop.isKill() || mop.isDead() || mop.isImplicit()) { 303 OS << "<"; 304 bool NeedComma = false; 305 if (mop.isImplicit()) { 306 OS << (mop.isDef() ? "imp-def" : "imp-use"); 307 NeedComma = true; 308 } else if (mop.isDef()) { 309 OS << "def"; 310 NeedComma = true; 311 } 312 if (mop.isKill() || mop.isDead()) { 313 if (NeedComma) 314 OS << ","; 315 if (mop.isKill()) 316 OS << "kill"; 317 if (mop.isDead()) 318 OS << "dead"; 319 } 320 OS << ">"; 321 } 322 } 323 } 324 325 OS << "\n"; 326} 327 328std::ostream &llvm::operator<<(std::ostream &os, const MachineInstr &MI) { 329 // If the instruction is embedded into a basic block, we can find the target 330 // info for the instruction. 331 if (const MachineBasicBlock *MBB = MI.getParent()) { 332 const MachineFunction *MF = MBB->getParent(); 333 if (MF) 334 MI.print(os, &MF->getTarget()); 335 else 336 MI.print(os, 0); 337 return os; 338 } 339 340 // Otherwise, print it out in the "raw" format without symbolic register names 341 // and such. 342 os << TargetInstrDescriptors[MI.getOpcode()].Name; 343 344 for (unsigned i = 0, N = MI.getNumOperands(); i < N; i++) { 345 os << "\t" << MI.getOperand(i); 346 if (MI.getOperand(i).isReg() && MI.getOperand(i).isDef()) 347 os << "<d>"; 348 } 349 350 return os << "\n"; 351} 352 353std::ostream &llvm::operator<<(std::ostream &OS, const MachineOperand &MO) { 354 switch (MO.getType()) { 355 case MachineOperand::MO_Register: 356 OutputReg(OS, MO.getReg()); 357 break; 358 case MachineOperand::MO_Immediate: 359 OS << (long)MO.getImmedValue(); 360 break; 361 case MachineOperand::MO_MachineBasicBlock: 362 OS << "<mbb:" 363 << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName() 364 << "@" << (void*)MO.getMachineBasicBlock() << ">"; 365 break; 366 case MachineOperand::MO_FrameIndex: 367 OS << "<fi#" << MO.getFrameIndex() << ">"; 368 break; 369 case MachineOperand::MO_ConstantPoolIndex: 370 OS << "<cp#" << MO.getConstantPoolIndex() << ">"; 371 break; 372 case MachineOperand::MO_JumpTableIndex: 373 OS << "<jt#" << MO.getJumpTableIndex() << ">"; 374 break; 375 case MachineOperand::MO_GlobalAddress: 376 OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">"; 377 break; 378 case MachineOperand::MO_ExternalSymbol: 379 OS << "<es:" << MO.getSymbolName() << ">"; 380 break; 381 default: 382 assert(0 && "Unrecognized operand type"); 383 break; 384 } 385 386 return OS; 387} 388