- Let MachineInstr ctors add implicit def and use operands. Other operands
[oota-llvm.git] / include / llvm / CodeGen / MachineInstr.h
1 //===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===//
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 // This file contains the declaration of the MachineInstr class, which is the
11 // basic representation for all target dependent machine instructions used by
12 // the back end.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_CODEGEN_MACHINEINSTR_H
17 #define LLVM_CODEGEN_MACHINEINSTR_H
18
19 #include "llvm/ADT/iterator"
20 #include "llvm/Support/DataTypes.h"
21 #include <vector>
22 #include <cassert>
23
24 namespace llvm {
25
26 class Value;
27 class Function;
28 class MachineBasicBlock;
29 class TargetInstrInfo;
30 class TargetInstrDescriptor;
31 class TargetMachine;
32 class GlobalValue;
33
34 template <typename T> struct ilist_traits;
35 template <typename T> struct ilist;
36
37 //===----------------------------------------------------------------------===//
38 // class MachineOperand
39 //
40 //   Representation of each machine instruction operand.
41 //
42 struct MachineOperand {
43   enum MachineOperandType {
44     MO_Register,                // Register operand.
45     MO_Immediate,               // Immediate Operand
46     MO_MachineBasicBlock,       // MachineBasicBlock reference
47     MO_FrameIndex,              // Abstract Stack Frame Index
48     MO_ConstantPoolIndex,       // Address of indexed Constant in Constant Pool
49     MO_JumpTableIndex,          // Address of indexed Jump Table for switch
50     MO_ExternalSymbol,          // Name of external global symbol
51     MO_GlobalAddress            // Address of a global value
52   };
53
54 private:
55   union {
56     GlobalValue *GV;          // For MO_GlobalAddress.
57     MachineBasicBlock *MBB;   // For MO_MachineBasicBlock.
58     const char *SymbolName;   // For MO_ExternalSymbol.
59     unsigned RegNo;           // For MO_Register.
60     int64_t immedVal;         // For MO_Immediate and MO_*Index.
61   } contents;
62
63   MachineOperandType opType:8; // Discriminate the union.
64   bool IsDef : 1;              // True if this is a def, false if this is a use.
65   bool IsImp : 1;              // True if this is an implicit def or use.
66
67   bool IsKill : 1;             // True if this is a reg use and the reg is dead
68                                // immediately after the read.
69   bool IsDead : 1;             // True if this is a reg def and the reg is dead
70                                // immediately after the write. i.e. A register
71                                // that is defined but never used.
72   
73   /// offset - Offset to address of global or external, only valid for
74   /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
75   int offset;
76
77   MachineOperand() {}
78 public:
79   MachineOperand(const MachineOperand &M) {
80     *this = M;
81   }
82   
83   ~MachineOperand() {}
84   
85   static MachineOperand CreateImm(int64_t Val) {
86     MachineOperand Op;
87     Op.opType = MachineOperand::MO_Immediate;
88     Op.contents.immedVal = Val;
89     Op.IsDef = false;
90     Op.IsImp = false;
91     Op.IsKill = false;
92     Op.IsDead = false;
93     Op.offset = 0;
94     return Op;
95   }
96   
97   const MachineOperand &operator=(const MachineOperand &MO) {
98     contents = MO.contents;
99     IsDef    = MO.IsDef;
100     IsImp    = MO.IsImp;
101     IsKill   = MO.IsKill;
102     IsDead   = MO.IsDead;
103     opType   = MO.opType;
104     offset   = MO.offset;
105     return *this;
106   }
107
108   /// getType - Returns the MachineOperandType for this operand.
109   ///
110   MachineOperandType getType() const { return opType; }
111
112   /// Accessors that tell you what kind of MachineOperand you're looking at.
113   ///
114   bool isReg() const { return opType == MO_Register; }
115   bool isImm() const { return opType == MO_Immediate; }
116   bool isMBB() const { return opType == MO_MachineBasicBlock; }
117   
118   bool isRegister() const { return opType == MO_Register; }
119   bool isImmediate() const { return opType == MO_Immediate; }
120   bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
121   bool isFrameIndex() const { return opType == MO_FrameIndex; }
122   bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; }
123   bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; }
124   bool isGlobalAddress() const { return opType == MO_GlobalAddress; }
125   bool isExternalSymbol() const { return opType == MO_ExternalSymbol; }
126
127   int64_t getImm() const {
128     assert(isImm() && "Wrong MachineOperand accessor");
129     return contents.immedVal;
130   }
131   
132   int64_t getImmedValue() const {
133     assert(isImm() && "Wrong MachineOperand accessor");
134     return contents.immedVal;
135   }
136   MachineBasicBlock *getMBB() const {
137     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
138     return contents.MBB;
139   }
140   MachineBasicBlock *getMachineBasicBlock() const {
141     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
142     return contents.MBB;
143   }
144   void setMachineBasicBlock(MachineBasicBlock *MBB) {
145     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
146     contents.MBB = MBB;
147   }
148   int getFrameIndex() const {
149     assert(isFrameIndex() && "Wrong MachineOperand accessor");
150     return (int)contents.immedVal;
151   }
152   unsigned getConstantPoolIndex() const {
153     assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
154     return (unsigned)contents.immedVal;
155   }
156   unsigned getJumpTableIndex() const {
157     assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
158     return (unsigned)contents.immedVal;
159   }
160   GlobalValue *getGlobal() const {
161     assert(isGlobalAddress() && "Wrong MachineOperand accessor");
162     return contents.GV;
163   }
164   int getOffset() const {
165     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
166         "Wrong MachineOperand accessor");
167     return offset;
168   }
169   const char *getSymbolName() const {
170     assert(isExternalSymbol() && "Wrong MachineOperand accessor");
171     return contents.SymbolName;
172   }
173
174   bool isUse() const { 
175     assert(isRegister() && "Wrong MachineOperand accessor");
176     return !IsDef;
177   }
178   bool isDef() const {
179     assert(isRegister() && "Wrong MachineOperand accessor");
180     return IsDef;
181   }
182   void setIsUse() {
183     assert(isRegister() && "Wrong MachineOperand accessor");
184     IsDef = false;
185   }
186   void setIsDef() {
187     assert(isRegister() && "Wrong MachineOperand accessor");
188     IsDef = true;
189   }
190
191   bool isImplicit() const { 
192     assert(isRegister() && "Wrong MachineOperand accessor");
193     return IsImp;
194   }
195   void setImplicit() { 
196     assert(isRegister() && "Wrong MachineOperand accessor");
197     IsImp = true;
198   }
199
200   bool isKill() const {
201     assert(isRegister() && "Wrong MachineOperand accessor");
202     return IsKill;
203   }
204   bool isDead() const {
205     assert(isRegister() && "Wrong MachineOperand accessor");
206     return IsDead;
207   }
208   void setIsKill() {
209     assert(isRegister() && "Wrong MachineOperand accessor");
210     IsKill = true;
211   }
212   void setIsDead() {
213     assert(isRegister() && "Wrong MachineOperand accessor");
214     IsDead = true;
215   }
216   void unsetIsKill() {
217     assert(isRegister() && "Wrong MachineOperand accessor");
218     IsKill = false;
219   }
220   void unsetIsDead() {
221     assert(isRegister() && "Wrong MachineOperand accessor");
222     IsDead = false;
223   }
224
225   /// getReg - Returns the register number.
226   ///
227   unsigned getReg() const {
228     assert(isRegister() && "This is not a register operand!");
229     return contents.RegNo;
230   }
231
232   /// MachineOperand mutators.
233   ///
234   void setReg(unsigned Reg) {
235     assert(isRegister() && "This is not a register operand!");
236     contents.RegNo = Reg;
237   }
238
239   void setImmedValue(int64_t immVal) {
240     assert(isImm() && "Wrong MachineOperand mutator");
241     contents.immedVal = immVal;
242   }
243   void setImm(int64_t immVal) {
244     assert(isImm() && "Wrong MachineOperand mutator");
245     contents.immedVal = immVal;
246   }
247
248   void setOffset(int Offset) {
249     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
250             isJumpTableIndex()) &&
251         "Wrong MachineOperand accessor");
252     offset = Offset;
253   }
254   void setConstantPoolIndex(unsigned Idx) {
255     assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
256     contents.immedVal = Idx;
257   }
258   void setJumpTableIndex(unsigned Idx) {
259     assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
260     contents.immedVal = Idx;
261   }
262   
263   /// isIdenticalTo - Return true if this operand is identical to the specified
264   /// operand.
265   bool isIdenticalTo(const MachineOperand &Other) const;
266   
267   /// ChangeToImmediate - Replace this operand with a new immediate operand of
268   /// the specified value.  If an operand is known to be an immediate already,
269   /// the setImmedValue method should be used.
270   void ChangeToImmediate(int64_t ImmVal) {
271     opType = MO_Immediate;
272     contents.immedVal = ImmVal;
273   }
274
275   /// ChangeToRegister - Replace this operand with a new register operand of
276   /// the specified value.  If an operand is known to be an register already,
277   /// the setReg method should be used.
278   void ChangeToRegister(unsigned Reg, bool isDef,
279                         bool isKill = false, bool isDead = false) {
280     opType = MO_Register;
281     contents.RegNo = Reg;
282     IsDef = isDef;
283     IsKill = isKill;
284     IsDead = isDead;
285   }
286
287   friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
288
289   friend class MachineInstr;
290 };
291
292
293 //===----------------------------------------------------------------------===//
294 /// MachineInstr - Representation of each machine instruction.
295 ///
296 class MachineInstr {
297   short Opcode;                         // the opcode
298   std::vector<MachineOperand> Operands; // the operands
299   MachineInstr* prev, *next;            // links for our intrusive list
300   MachineBasicBlock* parent;            // pointer to the owning basic block
301
302   unsigned NumImplicitOps;              // Number of implicit operands (which
303                                         // are determined at construction time).
304
305   // OperandComplete - Return true if it's illegal to add a new operand
306   bool OperandsComplete() const;
307
308   MachineInstr(const MachineInstr&);
309   void operator=(const MachineInstr&); // DO NOT IMPLEMENT
310
311   // Intrusive list support
312   //
313   friend struct ilist_traits<MachineInstr>;
314
315 public:
316   /// MachineInstr ctor - This constructor reserves space for numOperand
317   /// operands.
318   MachineInstr(short Opcode, unsigned numOperands);
319
320   /// MachineInstr ctor - This constructor create a MachineInstr and add the
321   /// implicit operands. It reserves space for numOperand operands.
322   MachineInstr(const TargetInstrInfo &TII, short Opcode, unsigned numOperands);
323
324   /// MachineInstr ctor - Work exactly the same as the ctor above, except that
325   /// the MachineInstr is created and added to the end of the specified basic
326   /// block.
327   ///
328   MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps);
329
330   ~MachineInstr();
331
332   const MachineBasicBlock* getParent() const { return parent; }
333   MachineBasicBlock* getParent() { return parent; }
334
335   /// getOpcode - Returns the opcode of this MachineInstr.
336   ///
337   const int getOpcode() const { return Opcode; }
338
339   /// Access to explicit operands of the instruction.
340   ///
341   unsigned getNumOperands() const { return Operands.size(); }
342
343   const MachineOperand& getOperand(unsigned i) const {
344     assert(i < getNumOperands() && "getOperand() out of range!");
345     return Operands[i];
346   }
347   MachineOperand& getOperand(unsigned i) {
348     assert(i < getNumOperands() && "getOperand() out of range!");
349     return Operands[i];
350   }
351
352   
353   /// isIdenticalTo - Return true if this instruction is identical to (same
354   /// opcode and same operands as) the specified instruction.
355   bool isIdenticalTo(const MachineInstr *Other) const {
356     if (Other->getOpcode() != getOpcode() ||
357         Other->getNumOperands() != getNumOperands())
358       return false;
359     for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
360       if (!getOperand(i).isIdenticalTo(Other->getOperand(i)))
361         return false;
362     return true;
363   }
364
365   /// clone - Create a copy of 'this' instruction that is identical in
366   /// all ways except the the instruction has no parent, prev, or next.
367   MachineInstr* clone() const { return new MachineInstr(*this); }
368   
369   /// removeFromParent - This method unlinks 'this' from the containing basic
370   /// block, and returns it, but does not delete it.
371   MachineInstr *removeFromParent();
372   
373   /// eraseFromParent - This method unlinks 'this' from the containing basic
374   /// block and deletes it.
375   void eraseFromParent() {
376     delete removeFromParent();
377   }
378
379   //
380   // Debugging support
381   //
382   void print(std::ostream &OS, const TargetMachine *TM) const;
383   void dump() const;
384   friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr);
385
386   //===--------------------------------------------------------------------===//
387   // Accessors to add operands when building up machine instructions.
388   //
389
390   /// addRegOperand - Add a register operand.
391   ///
392   void addRegOperand(unsigned Reg, bool IsDef, bool IsImp = false,
393                      bool IsKill = false, bool IsDead = false) {
394     MachineOperand &Op = AddNewOperand(IsImp);
395     Op.opType = MachineOperand::MO_Register;
396     Op.IsDef = IsDef;
397     Op.IsImp = IsImp;
398     Op.IsKill = IsKill;
399     Op.IsDead = IsDead;
400     Op.contents.RegNo = Reg;
401     Op.offset = 0;
402   }
403
404   /// addImmOperand - Add a zero extended constant argument to the
405   /// machine instruction.
406   ///
407   void addImmOperand(int64_t Val) {
408     MachineOperand &Op = AddNewOperand();
409     Op.opType = MachineOperand::MO_Immediate;
410     Op.contents.immedVal = Val;
411     Op.offset = 0;
412   }
413
414   void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
415     MachineOperand &Op = AddNewOperand();
416     Op.opType = MachineOperand::MO_MachineBasicBlock;
417     Op.contents.MBB = MBB;
418     Op.offset = 0;
419   }
420
421   /// addFrameIndexOperand - Add an abstract frame index to the instruction
422   ///
423   void addFrameIndexOperand(unsigned Idx) {
424     MachineOperand &Op = AddNewOperand();
425     Op.opType = MachineOperand::MO_FrameIndex;
426     Op.contents.immedVal = Idx;
427     Op.offset = 0;
428   }
429
430   /// addConstantPoolndexOperand - Add a constant pool object index to the
431   /// instruction.
432   ///
433   void addConstantPoolIndexOperand(unsigned Idx, int Offset) {
434     MachineOperand &Op = AddNewOperand();
435     Op.opType = MachineOperand::MO_ConstantPoolIndex;
436     Op.contents.immedVal = Idx;
437     Op.offset = Offset;
438   }
439
440   /// addJumpTableIndexOperand - Add a jump table object index to the
441   /// instruction.
442   ///
443   void addJumpTableIndexOperand(unsigned Idx) {
444     MachineOperand &Op = AddNewOperand();
445     Op.opType = MachineOperand::MO_JumpTableIndex;
446     Op.contents.immedVal = Idx;
447     Op.offset = 0;
448   }
449   
450   void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
451     MachineOperand &Op = AddNewOperand();
452     Op.opType = MachineOperand::MO_GlobalAddress;
453     Op.contents.GV = GV;
454     Op.offset = Offset;
455   }
456
457   /// addExternalSymbolOperand - Add an external symbol operand to this instr
458   ///
459   void addExternalSymbolOperand(const char *SymName) {
460     MachineOperand &Op = AddNewOperand();
461     Op.opType = MachineOperand::MO_ExternalSymbol;
462     Op.contents.SymbolName = SymName;
463     Op.offset = 0;
464   }
465
466   //===--------------------------------------------------------------------===//
467   // Accessors used to modify instructions in place.
468   //
469
470   /// setOpcode - Replace the opcode of the current instruction with a new one.
471   ///
472   void setOpcode(unsigned Op);
473
474   /// RemoveOperand - Erase an operand  from an instruction, leaving it with one
475   /// fewer operand than it started with.
476   ///
477   void RemoveOperand(unsigned i) {
478     Operands.erase(Operands.begin()+i);
479   }
480 private:
481   MachineOperand &AddNewOperand(bool IsImp = false) {
482     assert((IsImp || !OperandsComplete()) &&
483            "Trying to add an operand to a machine instr that is already done!");
484     if (NumImplicitOps == 0) { // This is true most of the time.
485       Operands.push_back(MachineOperand());
486       return Operands.back();
487     } else {
488       return *Operands.insert(Operands.begin()+Operands.size()-NumImplicitOps,
489                               MachineOperand());
490     }
491   }
492
493   /// addImplicitDefUseOperands - Add all implicit def and use operands to
494   /// this instruction.
495   void addImplicitDefUseOperands(const TargetInstrDescriptor &TID);
496 };
497
498 //===----------------------------------------------------------------------===//
499 // Debugging Support
500
501 std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI);
502 std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO);
503
504 } // End llvm namespace
505
506 #endif