Moved getBinaryOperator to the BinaryOperator class and the getUnaryOperator
[oota-llvm.git] / include / llvm / Instruction.h
1 //===-- llvm/Instruction.h - Instruction class definition --------*- C++ -*--=//
2 //
3 // This file contains the declaration of the Instruction class, which is the
4 // base class for all of the VM instructions.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #ifndef LLVM_INSTRUCTION_H
9 #define LLVM_INSTRUCTION_H
10
11 #include "llvm/User.h"
12
13 class Type;
14 class BasicBlock;
15 class Method;
16
17 class Instruction : public User {
18   BasicBlock *Parent;
19   unsigned iType;      // InstructionType
20
21   friend class ValueHolder<Instruction,BasicBlock>;
22   inline void setParent(BasicBlock *P) { Parent = P; }
23
24 public:
25   Instruction(const Type *Ty, unsigned iType, const string &Name = "");
26   virtual ~Instruction();  // Virtual dtor == good.
27
28   // Specialize setName to handle symbol table majik...
29   virtual void setName(const string &name);
30
31   // clone() - Create a copy of 'this' instruction that is identical in all ways
32   // except the following:
33   //   * The instruction has no parent
34   //   * The instruction has no name
35   //
36   virtual Instruction *clone() const = 0;
37
38   // Accessor methods...
39   //
40   inline const BasicBlock *getParent() const { return Parent; }
41   inline       BasicBlock *getParent()       { return Parent; }
42   bool hasSideEffects() const { return false; }  // Memory & Call insts = true
43
44   // ---------------------------------------------------------------------------
45   // Implement the User interface 
46   // if i > the number of operands, then getOperand() returns 0, and setOperand
47   // returns false.  setOperand() may also return false if the operand is of
48   // the wrong type.
49   //
50   inline Value *getOperand(unsigned i) {
51     return (Value*)((const Instruction *)this)->getOperand(i);
52   }
53   virtual const Value *getOperand(unsigned i) const = 0;
54   virtual bool setOperand(unsigned i, Value *Val) = 0;
55   virtual unsigned getNumOperands() const = 0;
56
57   // ---------------------------------------------------------------------------
58   // Operand Iterator interface...
59   //
60   template <class _Inst, class _Val> class OperandIterator;
61   typedef OperandIterator<Instruction *, Value *> op_iterator;
62   typedef OperandIterator<const Instruction *, const Value *> op_const_iterator;
63
64   inline op_iterator       op_begin()      ;
65   inline op_const_iterator op_begin() const;
66   inline op_iterator       op_end()        ;
67   inline op_const_iterator op_end()   const;
68
69
70   // ---------------------------------------------------------------------------
71   // Subclass classification... getInstType() returns a member of 
72   // one of the enums that is coming soon (down below)...
73   //
74   virtual string getOpcode() const = 0;
75
76   unsigned getInstType() const { return iType; }
77   inline bool isTerminator() const {   // Instance of TerminatorInst?
78     return iType >= FirstTermOp && iType < NumTermOps; 
79   }
80   inline bool isDefinition() const { return !isTerminator(); }
81   inline bool isUnaryOp() const {
82     return iType >= FirstUnaryOp && iType < NumUnaryOps;
83   }
84   inline bool isBinaryOp() const {
85     return iType >= FirstBinaryOp && iType < NumBinaryOps;
86   }
87
88
89   //----------------------------------------------------------------------
90   // Exported enumerations...
91   //
92   enum TermOps {       // These terminate basic blocks
93     FirstTermOp = 1,
94     Ret = 1, Br, Switch, 
95     NumTermOps         // Must remain at end of enum
96   };
97
98   enum UnaryOps {
99     FirstUnaryOp = NumTermOps,
100     Neg          = NumTermOps, Not, 
101     
102     // Type conversions...
103     ToBoolTy  , 
104     ToUByteTy , ToSByteTy,  ToUShortTy, ToShortTy,
105     ToUInt    , ToInt,      ToULongTy , ToLongTy,
106
107     ToFloatTy , ToDoubleTy, ToArrayTy , ToPointerTy,
108
109     NumUnaryOps        // Must remain at end of enum
110   };
111
112   enum BinaryOps {
113     // Standard binary operators...
114     FirstBinaryOp = NumUnaryOps,
115     Add = NumUnaryOps, Sub, Mul, Div, Rem,
116
117     // Logical operators...
118     And, Or, Xor,
119
120     // Binary comparison operators...
121     SetEQ, SetNE, SetLE, SetGE, SetLT, SetGT,
122
123     NumBinaryOps
124   };
125
126   enum MemoryOps {
127     FirstMemoryOp = NumBinaryOps,
128     Malloc = NumBinaryOps, Free,     // Heap management instructions
129     Alloca,                          // Stack management instruction
130
131     Load, Store,                     // Memory manipulation instructions.
132
133     GetField, PutField,              // Structure manipulation instructions
134
135     NumMemoryOps
136   };
137
138   enum OtherOps {
139     FirstOtherOp = NumMemoryOps,
140     PHINode      = NumMemoryOps,     // PHI node instruction
141     Call,                            // Call a function
142
143     Shl, Shr,                        // Shift operations...
144
145     NumOps,                          // Must be the last 'op' defined.
146     UserOp1, UserOp2                 // May be used internally to a pass...
147   };
148
149 public:
150   template <class _Inst, class _Val>         // Operand Iterator Implementation
151   class OperandIterator {
152     const _Inst Inst;
153     unsigned idx;
154   public:
155     typedef OperandIterator<_Inst, _Val> _Self;
156     typedef bidirectional_iterator_tag iterator_category;
157     typedef _Val pointer;
158     
159     inline OperandIterator(_Inst T) : Inst(T), idx(0) {}    // begin iterator
160     inline OperandIterator(_Inst T, bool) 
161       : Inst(T), idx(Inst->getNumOperands()) {}             // end iterator
162     
163     inline bool operator==(const _Self& x) const { return idx == x.idx; }
164     inline bool operator!=(const _Self& x) const { return !operator==(x); }
165
166     inline pointer operator*() const { return Inst->getOperand(idx); }
167     inline pointer *operator->() const { return &(operator*()); }
168     
169     inline _Self& operator++() { ++idx; return *this; } // Preincrement
170     inline _Self operator++(int) { // Postincrement
171       _Self tmp = *this; ++*this; return tmp; 
172     }
173
174     inline _Self& operator--() { --idx; return *this; }  // Predecrement
175     inline _Self operator--(int) { // Postdecrement
176       _Self tmp = *this; --*this; return tmp;
177     }
178   };
179
180 };
181
182 inline Instruction::op_iterator       Instruction::op_begin()       {
183   return op_iterator(this);
184 }
185 inline Instruction::op_const_iterator Instruction::op_begin() const {
186   return op_const_iterator(this);
187 }
188 inline Instruction::op_iterator       Instruction::op_end()         {
189   return op_iterator(this,true);
190 }
191 inline Instruction::op_const_iterator Instruction::op_end()   const {
192   return op_const_iterator(this,true);
193 }
194
195
196 #endif