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