* Frame indices are signed
[oota-llvm.git] / include / llvm / CodeGen / MachineInstr.h
1 //===-- llvm/CodeGen/MachineInstr.h - MachineInstr class ---------*- C++ -*--=//
2 //
3 // This file contains the declaration of the MachineInstr class, which is the
4 // basic representation for all target dependant machine instructions used by
5 // the back end.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_CODEGEN_MACHINEINSTR_H
10 #define LLVM_CODEGEN_MACHINEINSTR_H
11
12 #include "llvm/Annotation.h"
13 #include "llvm/Target/MRegisterInfo.h"
14 #include "Support/iterator"
15 #include "Support/NonCopyable.h"
16 #include <vector>
17 class Value;
18 class Function;
19 class MachineBasicBlock;
20 class TargetMachine;
21
22 typedef int MachineOpCode;
23
24 /// MOTy - MachineOperandType - This namespace contains an enum that describes
25 /// how the machine operand is used by the instruction: is it read, defined, or
26 /// both?  Note that the MachineInstr/Operator class currently uses bool
27 /// arguments to represent this information instead of an enum.  Eventually this
28 /// should change over to use this _easier to read_ representation instead.
29 ///
30 namespace MOTy {
31   enum UseType {
32     Use,             /// This machine operand is only read by the instruction
33     Def,             /// This machine operand is only written by the instruction
34     UseAndDef        /// This machine operand is read AND written
35   };
36 }
37
38 //---------------------------------------------------------------------------
39 // class MachineOperand 
40 // 
41 // Purpose:
42 //   Representation of each machine instruction operand.
43 //   This class is designed so that you can allocate a vector of operands
44 //   first and initialize each one later.
45 //
46 //   E.g, for this VM instruction:
47 //              ptr = alloca type, numElements
48 //   we generate 2 machine instructions on the SPARC:
49 // 
50 //              mul Constant, Numelements -> Reg
51 //              add %sp, Reg -> Ptr
52 // 
53 //   Each instruction has 3 operands, listed above.  Of those:
54 //   -  Reg, NumElements, and Ptr are of operand type MO_Register.
55 //   -  Constant is of operand type MO_SignExtendedImmed on the SPARC.
56 //      
57 //   For the register operands, the virtual register type is as follows:
58 //      
59 //   -  Reg will be of virtual register type MO_MInstrVirtualReg.  The field
60 //      MachineInstr* minstr will point to the instruction that computes reg.
61 // 
62 //   -  %sp will be of virtual register type MO_MachineReg.
63 //      The field regNum identifies the machine register.
64 // 
65 //   -  NumElements will be of virtual register type MO_VirtualReg.
66 //      The field Value* value identifies the value.
67 // 
68 //   -  Ptr will also be of virtual register type MO_VirtualReg.
69 //      Again, the field Value* value identifies the value.
70 // 
71 //---------------------------------------------------------------------------
72
73 class MachineOperand {
74 public:
75   enum MachineOperandType {
76     MO_VirtualRegister,         // virtual register for *value
77     MO_MachineRegister,         // pre-assigned machine register `regNum'
78     MO_CCRegister,
79     MO_SignExtendedImmed,
80     MO_UnextendedImmed,
81     MO_PCRelativeDisp,
82     MO_MachineBasicBlock,       // MachineBasicBlock reference
83     MO_FrameIndex,              // Abstract Stack Frame Index
84   };
85   
86 private:
87   // Bit fields of the flags variable used for different operand properties
88   static const char DEFFLAG    = 0x01; // this is a def of the operand
89   static const char DEFUSEFLAG = 0x02; // this is both a def and a use
90   static const char HIFLAG32   = 0x04; // operand is %hi32(value_or_immedVal)
91   static const char LOFLAG32   = 0x08; // operand is %lo32(value_or_immedVal)
92   static const char HIFLAG64   = 0x10; // operand is %hi64(value_or_immedVal)
93   static const char LOFLAG64   = 0x20; // operand is %lo64(value_or_immedVal)
94
95   static const char USEDEFMASK = 0x03;
96   
97 private:
98   union {
99     Value*      value;          // BasicBlockVal for a label operand.
100                                 // ConstantVal for a non-address immediate.
101                                 // Virtual register for an SSA operand,
102                                 // including hidden operands required for
103                                 // the generated machine code.     
104     int64_t immedVal;           // constant value for an explicit constant
105
106     MachineBasicBlock *MBB;     // For MO_MachineBasicBlock type
107   };
108
109   char flags;                   // see bit field definitions above
110   MachineOperandType opType:8;  // Pack into 8 bits efficiently after flags.
111   int regNum;                   // register number for an explicit register
112                                 // will be set for a value after reg allocation
113 private:
114   MachineOperand()
115     : immedVal(0),
116       flags(0),
117       opType(MO_VirtualRegister),
118       regNum(-1) {}
119
120   MachineOperand(int64_t ImmVal, MachineOperandType OpTy)
121     : immedVal(ImmVal),
122       flags(0),
123       opType(OpTy),
124       regNum(-1) {}
125
126   MachineOperand(int Reg, MachineOperandType OpTy, MOTy::UseType UseTy)
127     : immedVal(0),
128       opType(OpTy),
129       regNum(Reg) {
130     switch (UseTy) {
131     case MOTy::Use:       flags = 0; break;
132     case MOTy::Def:       flags = DEFFLAG; break;
133     case MOTy::UseAndDef: flags = DEFUSEFLAG; break;
134     default: assert(0 && "Invalid value for UseTy!");
135     }
136   }
137
138   MachineOperand(Value *V, MachineOperandType OpTy, MOTy::UseType UseTy) 
139     : value(V), opType(OpTy), regNum(-1) {
140     switch (UseTy) {
141     case MOTy::Use:       flags = 0; break;
142     case MOTy::Def:       flags = DEFFLAG; break;
143     case MOTy::UseAndDef: flags = DEFUSEFLAG; break;
144     default: assert(0 && "Invalid value for UseTy!");
145     }
146   }
147
148   MachineOperand(MachineBasicBlock *mbb)
149     : MBB(mbb), flags(0), opType(MO_MachineBasicBlock), regNum(-1) {}
150
151 public:
152   MachineOperand(const MachineOperand &M)
153     : immedVal(M.immedVal),
154       flags(M.flags),
155       opType(M.opType),
156       regNum(M.regNum) {}
157
158   ~MachineOperand() {}
159   
160   // Accessor methods.  Caller is responsible for checking the
161   // operand type before invoking the corresponding accessor.
162   // 
163   MachineOperandType getType() const { return opType; }
164
165
166   // This is to finally stop caring whether we have a virtual or machine
167   // register -- an easier interface is to simply call both virtual and machine
168   // registers essentially the same, yet be able to distinguish when
169   // necessary. Thus the instruction selector can just add registers without
170   // abandon, and the register allocator won't be confused.
171   bool isVirtualRegister() const {
172     return (opType == MO_VirtualRegister || opType == MO_MachineRegister) 
173       && regNum >= MRegisterInfo::FirstVirtualRegister;
174   }
175   bool isPhysicalRegister() const {
176     return (opType == MO_VirtualRegister || opType == MO_MachineRegister) 
177       && regNum < MRegisterInfo::FirstVirtualRegister;
178   }
179   bool isRegister() const { return isVirtualRegister() || isPhysicalRegister();}
180   bool isMachineRegister() const { return !isVirtualRegister(); }
181   bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
182   bool isPCRelativeDisp() const { return opType == MO_PCRelativeDisp; }
183   bool isImmediate() const {
184     return opType == MO_SignExtendedImmed || opType == MO_UnextendedImmed;
185   }
186   bool isFrameIndex() const { return opType == MO_FrameIndex; }
187
188   Value* getVRegValue() const {
189     assert(opType == MO_VirtualRegister || opType == MO_CCRegister || 
190            isPCRelativeDisp());
191     return value;
192   }
193   Value* getVRegValueOrNull() const {
194     return (opType == MO_VirtualRegister || opType == MO_CCRegister || 
195             isPCRelativeDisp()) ? value : NULL;
196   }
197   int getMachineRegNum() const {
198     assert(opType == MO_MachineRegister);
199     return regNum;
200   }
201   int64_t getImmedValue() const { assert(isImmediate()); return immedVal; }
202   MachineBasicBlock *getMachineBasicBlock() const {
203     assert(isMachineBasicBlock() && "Can't get MBB in non-MBB operand!");
204     return MBB;
205   }
206   int getFrameIndex() const { assert(isFrameIndex()); return immedVal; }
207
208   bool          opIsUse         () const { return (flags & USEDEFMASK) == 0; }
209   bool          opIsDef         () const { return flags & DEFFLAG; }
210   bool          opIsDefAndUse   () const { return flags & DEFUSEFLAG; }
211   bool          opHiBits32      () const { return flags & HIFLAG32; }
212   bool          opLoBits32      () const { return flags & LOFLAG32; }
213   bool          opHiBits64      () const { return flags & HIFLAG64; }
214   bool          opLoBits64      () const { return flags & LOFLAG64; }
215
216   // used to check if a machine register has been allocated to this operand
217   bool hasAllocatedReg() const {
218     return (regNum >= 0 &&
219             (opType == MO_VirtualRegister || opType == MO_CCRegister || 
220              opType == MO_MachineRegister));
221   }
222
223   // used to get the reg number if when one is allocated
224   int getAllocatedRegNum() const {
225     assert(opType == MO_VirtualRegister || opType == MO_CCRegister || 
226            opType == MO_MachineRegister);
227     return regNum;
228   }
229
230   unsigned getReg() const {
231     assert(hasAllocatedReg() && "Cannot call MachineOperand::getReg()!");
232     return regNum;
233   }    
234   
235   friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
236
237 private:
238
239   // Construction methods needed for fine-grain control.
240   // These must be accessed via coresponding methods in MachineInstr.
241   void markHi32()      { flags |= HIFLAG32; }
242   void markLo32()      { flags |= LOFLAG32; }
243   void markHi64()      { flags |= HIFLAG64; }
244   void markLo64()      { flags |= LOFLAG64; }
245   
246   // Replaces the Value with its corresponding physical register after
247   // register allocation is complete
248   void setRegForValue(int reg) {
249     assert(opType == MO_VirtualRegister || opType == MO_CCRegister || 
250            opType == MO_MachineRegister);
251     regNum = reg;
252   }
253   
254   friend class MachineInstr;
255 };
256
257
258 //---------------------------------------------------------------------------
259 // class MachineInstr 
260 // 
261 // Purpose:
262 //   Representation of each machine instruction.
263 // 
264 //   MachineOpCode must be an enum, defined separately for each target.
265 //   E.g., It is defined in SparcInstructionSelection.h for the SPARC.
266 // 
267 //  There are 2 kinds of operands:
268 // 
269 //  (1) Explicit operands of the machine instruction in vector operands[] 
270 // 
271 //  (2) "Implicit operands" are values implicitly used or defined by the
272 //      machine instruction, such as arguments to a CALL, return value of
273 //      a CALL (if any), and return value of a RETURN.
274 //---------------------------------------------------------------------------
275
276 class MachineInstr: public NonCopyable {      // Disable copy operations
277
278   MachineOpCode    opCode;              // the opcode
279   std::vector<MachineOperand> operands; // the operands
280   unsigned numImplicitRefs;             // number of implicit operands
281
282   MachineOperand& getImplicitOp(unsigned i) {
283     assert(i < numImplicitRefs && "implicit ref# out of range!");
284     return operands[i + operands.size() - numImplicitRefs];
285   }
286   const MachineOperand& getImplicitOp(unsigned i) const {
287     assert(i < numImplicitRefs && "implicit ref# out of range!");
288     return operands[i + operands.size() - numImplicitRefs];
289   }
290
291   // regsUsed - all machine registers used for this instruction, including regs
292   // used to save values across the instruction.  This is a bitset of registers.
293   std::vector<bool> regsUsed;
294
295   // OperandComplete - Return true if it's illegal to add a new operand
296   bool OperandsComplete() const;
297
298 public:
299   MachineInstr(MachineOpCode Opcode);
300   MachineInstr(MachineOpCode Opcode, unsigned numOperands);
301
302   /// MachineInstr ctor - This constructor only does a _reserve_ of the
303   /// operands, not a resize for them.  It is expected that if you use this that
304   /// you call add* methods below to fill up the operands, instead of the Set
305   /// methods.  Eventually, the "resizing" ctors will be phased out.
306   ///
307   MachineInstr(MachineOpCode Opcode, unsigned numOperands, bool XX, bool YY);
308
309   /// MachineInstr ctor - Work exactly the same as the ctor above, except that
310   /// the MachineInstr is created and added to the end of the specified basic
311   /// block.
312   ///
313   MachineInstr(MachineBasicBlock *MBB, MachineOpCode Opcode, unsigned numOps);
314   
315
316   // The opcode.
317   // 
318   const MachineOpCode getOpcode() const { return opCode; }
319   const MachineOpCode getOpCode() const { return opCode; }
320
321   //
322   // Information about explicit operands of the instruction
323   // 
324   unsigned getNumOperands() const { return operands.size() - numImplicitRefs; }
325   
326   const MachineOperand& getOperand(unsigned i) const {
327     assert(i < getNumOperands() && "getOperand() out of range!");
328     return operands[i];
329   }
330   MachineOperand& getOperand(unsigned i) {
331     assert(i < getNumOperands() && "getOperand() out of range!");
332     return operands[i];
333   }
334
335   // FIXME: ELIMINATE
336   MachineOperand::MachineOperandType getOperandType(unsigned i) const {
337     return getOperand(i).getType();
338   }
339
340   // FIXME: ELIMINATE: Misleading name: Definition not defined.
341   bool operandIsDefined(unsigned i) const {
342     return getOperand(i).opIsDef();
343   }
344
345   bool operandIsDefinedAndUsed(unsigned i) const {
346     return getOperand(i).opIsDefAndUse();
347   }
348
349   //
350   // Information about implicit operands of the instruction
351   // 
352   unsigned getNumImplicitRefs() const{ return numImplicitRefs; }
353   
354   const Value* getImplicitRef(unsigned i) const {
355     return getImplicitOp(i).getVRegValue();
356   }
357   Value* getImplicitRef(unsigned i) {
358     return getImplicitOp(i).getVRegValue();
359   }
360
361   bool implicitRefIsDefined(unsigned i) const {
362     return getImplicitOp(i).opIsDef();
363   }
364   bool implicitRefIsDefinedAndUsed(unsigned i) const {
365     return getImplicitOp(i).opIsDefAndUse();
366   }
367   inline void addImplicitRef    (Value* V,
368                                  bool isDef=false,bool isDefAndUse=false);
369   inline void setImplicitRef    (unsigned i, Value* V,
370                                  bool isDef=false, bool isDefAndUse=false);
371
372   //
373   // Information about registers used in this instruction
374   // 
375   const std::vector<bool> &getRegsUsed() const { return regsUsed; }
376   
377   // insertUsedReg - Add a register to the Used registers set...
378   void insertUsedReg(unsigned Reg) {
379     if (Reg >= regsUsed.size())
380       regsUsed.resize(Reg+1);
381     regsUsed[Reg] = true;
382   }
383
384   //
385   // Debugging support
386   //
387   void print(std::ostream &OS, const TargetMachine &TM) const;
388   void dump() const;
389   friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr);
390
391   //
392   // Define iterators to access the Value operands of the Machine Instruction.
393   // Note that these iterators only enumerate the explicit operands.
394   // begin() and end() are defined to produce these iterators...
395   //
396   template<class _MI, class _V> class ValOpIterator;
397   typedef ValOpIterator<const MachineInstr*,const Value*> const_val_op_iterator;
398   typedef ValOpIterator<      MachineInstr*,      Value*> val_op_iterator;
399
400
401   //===--------------------------------------------------------------------===//
402   // Accessors to add operands when building up machine instructions
403   //
404
405   /// addRegOperand - Add a MO_VirtualRegister operand to the end of the
406   /// operands list...
407   ///
408   void addRegOperand(Value *V, bool isDef, bool isDefAndUse=false) {
409     assert(!OperandsComplete() &&
410            "Trying to add an operand to a machine instr that is already done!");
411     operands.push_back(MachineOperand(V, MachineOperand::MO_VirtualRegister,
412              !isDef ? MOTy::Use : (isDefAndUse ? MOTy::UseAndDef : MOTy::Def)));
413   }
414
415   void addRegOperand(Value *V, MOTy::UseType UTy = MOTy::Use) {
416     assert(!OperandsComplete() &&
417            "Trying to add an operand to a machine instr that is already done!");
418     operands.push_back(MachineOperand(V, MachineOperand::MO_VirtualRegister,
419                                       UTy));
420   }
421
422   /// addRegOperand - Add a symbolic virtual register reference...
423   ///
424   void addRegOperand(int reg, bool isDef) {
425     assert(!OperandsComplete() &&
426            "Trying to add an operand to a machine instr that is already done!");
427     operands.push_back(MachineOperand(reg, MachineOperand::MO_VirtualRegister,
428                                       isDef ? MOTy::Def : MOTy::Use));
429   }
430
431   /// addRegOperand - Add a symbolic virtual register reference...
432   ///
433   void addRegOperand(int reg, MOTy::UseType UTy = MOTy::Use) {
434     assert(!OperandsComplete() &&
435            "Trying to add an operand to a machine instr that is already done!");
436     operands.push_back(MachineOperand(reg, MachineOperand::MO_VirtualRegister,
437                                       UTy));
438   }
439
440   /// addPCDispOperand - Add a PC relative displacement operand to the MI
441   ///
442   void addPCDispOperand(Value *V) {
443     assert(!OperandsComplete() &&
444            "Trying to add an operand to a machine instr that is already done!");
445     operands.push_back(MachineOperand(V, MachineOperand::MO_PCRelativeDisp,
446                                       MOTy::Use));
447   }
448
449   /// addMachineRegOperand - Add a virtual register operand to this MachineInstr
450   ///
451   void addMachineRegOperand(int reg, bool isDef) {
452     assert(!OperandsComplete() &&
453            "Trying to add an operand to a machine instr that is already done!");
454     operands.push_back(MachineOperand(reg, MachineOperand::MO_MachineRegister,
455                                       isDef ? MOTy::Def : MOTy::Use));
456     insertUsedReg(reg);
457   }
458
459   /// addMachineRegOperand - Add a virtual register operand to this MachineInstr
460   ///
461   void addMachineRegOperand(int reg, MOTy::UseType UTy = MOTy::Use) {
462     assert(!OperandsComplete() &&
463            "Trying to add an operand to a machine instr that is already done!");
464     operands.push_back(MachineOperand(reg, MachineOperand::MO_MachineRegister,
465                                       UTy));
466     insertUsedReg(reg);
467   }
468
469   /// addZeroExtImmOperand - Add a zero extended constant argument to the
470   /// machine instruction.
471   ///
472   void addZeroExtImmOperand(int64_t intValue) {
473     assert(!OperandsComplete() &&
474            "Trying to add an operand to a machine instr that is already done!");
475     operands.push_back(MachineOperand(intValue,
476                                       MachineOperand::MO_UnextendedImmed));
477   }
478
479   /// addSignExtImmOperand - Add a zero extended constant argument to the
480   /// machine instruction.
481   ///
482   void addSignExtImmOperand(int64_t intValue) {
483     assert(!OperandsComplete() &&
484            "Trying to add an operand to a machine instr that is already done!");
485     operands.push_back(MachineOperand(intValue,
486                                       MachineOperand::MO_SignExtendedImmed));
487   }
488
489   void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
490     assert(!OperandsComplete() &&
491            "Trying to add an operand to a machine instr that is already done!");
492     operands.push_back(MachineOperand(MBB));
493   }
494
495   /// addFrameIndexOperand - Add an abstract frame index to the instruction
496   ///
497   void addFrameIndexOperand(unsigned Idx) {
498     assert(!OperandsComplete() &&
499            "Trying to add an operand to a machine instr that is already done!");
500     operands.push_back(MachineOperand(Idx, MachineOperand::MO_FrameIndex));
501   }
502
503
504   //===--------------------------------------------------------------------===//
505   // Accessors used to modify instructions in place.
506   //
507   // FIXME: Move this stuff to MachineOperand itself!
508
509   /// replace - Support to rewrite a machine instruction in place: for now,
510   /// simply replace() and then set new operands with Set.*Operand methods
511   /// below.
512   /// 
513   void replace(MachineOpCode Opcode, unsigned numOperands);
514
515   // Access to set the operands when building the machine instruction
516   // 
517   void SetMachineOperandVal     (unsigned i,
518                                  MachineOperand::MachineOperandType operandType,
519                                  Value* V,
520                                  bool isDef=false,
521                                  bool isDefAndUse=false);
522
523   void SetMachineOperandConst   (unsigned i,
524                                  MachineOperand::MachineOperandType operandType,
525                                  int64_t intValue);
526
527   void SetMachineOperandReg     (unsigned i,
528                                  int regNum,
529                                  bool isDef=false);
530
531
532   unsigned substituteValue(const Value* oldVal, Value* newVal,
533                            bool defsOnly = true);
534
535   void setOperandHi32(unsigned i) { operands[i].markHi32(); }
536   void setOperandLo32(unsigned i) { operands[i].markLo32(); }
537   void setOperandHi64(unsigned i) { operands[i].markHi64(); }
538   void setOperandLo64(unsigned i) { operands[i].markLo64(); }
539   
540   
541   // SetRegForOperand - Replaces the Value for the operand with its allocated
542   // physical register after register allocation is complete.
543   // 
544   void SetRegForOperand(unsigned i, int regNum);
545
546   //
547   // Iterator to enumerate machine operands.
548   // 
549   template<class MITy, class VTy>
550   class ValOpIterator : public forward_iterator<VTy, ptrdiff_t> {
551     unsigned i;
552     MITy MI;
553     
554     void skipToNextVal() {
555       while (i < MI->getNumOperands() &&
556              !( (MI->getOperandType(i) == MachineOperand::MO_VirtualRegister ||
557                  MI->getOperandType(i) == MachineOperand::MO_CCRegister)
558                 && MI->getOperand(i).getVRegValue() != 0))
559         ++i;
560     }
561   
562     inline ValOpIterator(MITy mi, unsigned I) : i(I), MI(mi) {
563       skipToNextVal();
564     }
565   
566   public:
567     typedef ValOpIterator<MITy, VTy> _Self;
568     
569     inline VTy operator*() const {
570       return MI->getOperand(i).getVRegValue();
571     }
572
573     const MachineOperand &getMachineOperand() const { return MI->getOperand(i);}
574           MachineOperand &getMachineOperand()       { return MI->getOperand(i);}
575
576     inline VTy operator->() const { return operator*(); }
577
578     inline bool isDef()       const { return MI->getOperand(i).opIsDef(); } 
579     inline bool isDefAndUse() const { return MI->getOperand(i).opIsDefAndUse();}
580
581     inline _Self& operator++() { i++; skipToNextVal(); return *this; }
582     inline _Self  operator++(int) { _Self tmp = *this; ++*this; return tmp; }
583
584     inline bool operator==(const _Self &y) const { 
585       return i == y.i;
586     }
587     inline bool operator!=(const _Self &y) const { 
588       return !operator==(y);
589     }
590
591     static _Self begin(MITy MI) {
592       return _Self(MI, 0);
593     }
594     static _Self end(MITy MI) {
595       return _Self(MI, MI->getNumOperands());
596     }
597   };
598
599   // define begin() and end()
600   val_op_iterator begin() { return val_op_iterator::begin(this); }
601   val_op_iterator end()   { return val_op_iterator::end(this); }
602
603   const_val_op_iterator begin() const {
604     return const_val_op_iterator::begin(this);
605   }
606   const_val_op_iterator end() const {
607     return const_val_op_iterator::end(this);
608   }
609 };
610
611
612 // Define here to enable inlining of the functions used.
613 // 
614 void MachineInstr::addImplicitRef(Value* V,
615                                   bool isDef,
616                                   bool isDefAndUse)
617 {
618   ++numImplicitRefs;
619   addRegOperand(V, isDef, isDefAndUse);
620 }
621
622 void MachineInstr::setImplicitRef(unsigned i,
623                                   Value* V,
624                                   bool isDef,
625                                   bool isDefAndUse)
626 {
627   assert(i < getNumImplicitRefs() && "setImplicitRef() out of range!");
628   SetMachineOperandVal(i + getNumOperands(),
629                        MachineOperand::MO_VirtualRegister,
630                        V, isDef, isDefAndUse);
631 }
632
633
634 //---------------------------------------------------------------------------
635 // Debugging Support
636 //---------------------------------------------------------------------------
637
638 std::ostream& operator<<        (std::ostream& os,
639                                  const MachineInstr& minstr);
640
641 std::ostream& operator<<        (std::ostream& os,
642                                  const MachineOperand& mop);
643                                          
644 void PrintMachineInstructions   (const Function *F);
645
646 #endif