1//===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines various classes for working with Instructions and
11// ConstantExprs.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_OPERATOR_H
16#define LLVM_OPERATOR_H
17
18#include "llvm/Instruction.h"
19#include "llvm/Constants.h"
20
21namespace llvm {
22
23class GetElementPtrInst;
24class BinaryOperator;
25class ConstantExpr;
26
27/// Operator - This is a utility class that provides an abstraction for the
28/// common functionality between Instructions and ConstantExprs.
29///
30class Operator : public User {
31private:
32  // Do not implement any of these. The Operator class is intended to be used
33  // as a utility, and is never itself instantiated.
34  void *operator new(size_t, unsigned);
35  void *operator new(size_t s);
36  Operator();
37  ~Operator();
38
39public:
40  /// getOpcode - Return the opcode for this Instruction or ConstantExpr.
41  ///
42  unsigned getOpcode() const {
43    if (const Instruction *I = dyn_cast<Instruction>(this))
44      return I->getOpcode();
45    return cast<ConstantExpr>(this)->getOpcode();
46  }
47
48  /// getOpcode - If V is an Instruction or ConstantExpr, return its
49  /// opcode. Otherwise return UserOp1.
50  ///
51  static unsigned getOpcode(const Value *V) {
52    if (const Instruction *I = dyn_cast<Instruction>(V))
53      return I->getOpcode();
54    if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
55      return CE->getOpcode();
56    return Instruction::UserOp1;
57  }
58
59  static inline bool classof(const Operator *) { return true; }
60  static inline bool classof(const Instruction *) { return true; }
61  static inline bool classof(const ConstantExpr *) { return true; }
62  static inline bool classof(const Value *V) {
63    return isa<Instruction>(V) || isa<ConstantExpr>(V);
64  }
65};
66
67/// OverflowingBinaryOperator - Utility class for integer arithmetic operators
68/// which may exhibit overflow - Add, Sub, and Mul. It does not include SDiv,
69/// despite that operator having the potential for overflow.
70///
71class OverflowingBinaryOperator : public Operator {
72public:
73  enum {
74    NoUnsignedWrap = (1 << 0),
75    NoSignedWrap   = (1 << 1)
76  };
77
78private:
79  ~OverflowingBinaryOperator(); // do not implement
80
81  friend class BinaryOperator;
82  friend class ConstantExpr;
83  void setHasNoUnsignedWrap(bool B) {
84    SubclassOptionalData =
85      (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
86  }
87  void setHasNoSignedWrap(bool B) {
88    SubclassOptionalData =
89      (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
90  }
91
92public:
93  /// hasNoUnsignedWrap - Test whether this operation is known to never
94  /// undergo unsigned overflow, aka the nuw property.
95  bool hasNoUnsignedWrap() const {
96    return SubclassOptionalData & NoUnsignedWrap;
97  }
98
99  /// hasNoSignedWrap - Test whether this operation is known to never
100  /// undergo signed overflow, aka the nsw property.
101  bool hasNoSignedWrap() const {
102    return (SubclassOptionalData & NoSignedWrap) != 0;
103  }
104
105  static inline bool classof(const OverflowingBinaryOperator *) { return true; }
106  static inline bool classof(const Instruction *I) {
107    return I->getOpcode() == Instruction::Add ||
108           I->getOpcode() == Instruction::Sub ||
109           I->getOpcode() == Instruction::Mul ||
110           I->getOpcode() == Instruction::Shl;
111  }
112  static inline bool classof(const ConstantExpr *CE) {
113    return CE->getOpcode() == Instruction::Add ||
114           CE->getOpcode() == Instruction::Sub ||
115           CE->getOpcode() == Instruction::Mul ||
116           CE->getOpcode() == Instruction::Shl;
117  }
118  static inline bool classof(const Value *V) {
119    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
120           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
121  }
122};
123
124/// PossiblyExactOperator - A udiv or sdiv instruction, which can be marked as
125/// "exact", indicating that no bits are destroyed.
126class PossiblyExactOperator : public Operator {
127public:
128  enum {
129    IsExact = (1 << 0)
130  };
131
132  friend class BinaryOperator;
133  friend class ConstantExpr;
134  void setIsExact(bool B) {
135    SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
136  }
137
138private:
139  ~PossiblyExactOperator(); // do not implement
140public:
141  /// isExact - Test whether this division is known to be exact, with
142  /// zero remainder.
143  bool isExact() const {
144    return SubclassOptionalData & IsExact;
145  }
146
147  static bool isPossiblyExactOpcode(unsigned OpC) {
148    return OpC == Instruction::SDiv ||
149           OpC == Instruction::UDiv ||
150           OpC == Instruction::AShr ||
151           OpC == Instruction::LShr;
152  }
153  static inline bool classof(const ConstantExpr *CE) {
154    return isPossiblyExactOpcode(CE->getOpcode());
155  }
156  static inline bool classof(const Instruction *I) {
157    return isPossiblyExactOpcode(I->getOpcode());
158  }
159  static inline bool classof(const Value *V) {
160    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
161           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
162  }
163};
164
165
166
167/// ConcreteOperator - A helper template for defining operators for individual
168/// opcodes.
169template<typename SuperClass, unsigned Opc>
170class ConcreteOperator : public SuperClass {
171  ~ConcreteOperator(); // DO NOT IMPLEMENT
172public:
173  static inline bool classof(const ConcreteOperator<SuperClass, Opc> *) {
174    return true;
175  }
176  static inline bool classof(const Instruction *I) {
177    return I->getOpcode() == Opc;
178  }
179  static inline bool classof(const ConstantExpr *CE) {
180    return CE->getOpcode() == Opc;
181  }
182  static inline bool classof(const Value *V) {
183    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
184           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
185  }
186};
187
188class AddOperator
189  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
190  ~AddOperator(); // DO NOT IMPLEMENT
191};
192class SubOperator
193  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
194  ~SubOperator(); // DO NOT IMPLEMENT
195};
196class MulOperator
197  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
198  ~MulOperator(); // DO NOT IMPLEMENT
199};
200class ShlOperator
201  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
202  ~ShlOperator(); // DO NOT IMPLEMENT
203};
204
205
206class SDivOperator
207  : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
208  ~SDivOperator(); // DO NOT IMPLEMENT
209};
210class UDivOperator
211  : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
212  ~UDivOperator(); // DO NOT IMPLEMENT
213};
214class AShrOperator
215  : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
216  ~AShrOperator(); // DO NOT IMPLEMENT
217};
218class LShrOperator
219  : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
220  ~LShrOperator(); // DO NOT IMPLEMENT
221};
222
223
224
225class GEPOperator
226  : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
227  ~GEPOperator(); // DO NOT IMPLEMENT
228
229  enum {
230    IsInBounds = (1 << 0)
231  };
232
233  friend class GetElementPtrInst;
234  friend class ConstantExpr;
235  void setIsInBounds(bool B) {
236    SubclassOptionalData =
237      (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
238  }
239
240public:
241  /// isInBounds - Test whether this is an inbounds GEP, as defined
242  /// by LangRef.html.
243  bool isInBounds() const {
244    return SubclassOptionalData & IsInBounds;
245  }
246
247  inline op_iterator       idx_begin()       { return op_begin()+1; }
248  inline const_op_iterator idx_begin() const { return op_begin()+1; }
249  inline op_iterator       idx_end()         { return op_end(); }
250  inline const_op_iterator idx_end()   const { return op_end(); }
251
252  Value *getPointerOperand() {
253    return getOperand(0);
254  }
255  const Value *getPointerOperand() const {
256    return getOperand(0);
257  }
258  static unsigned getPointerOperandIndex() {
259    return 0U;                      // get index for modifying correct operand
260  }
261
262  /// getPointerOperandType - Method to return the pointer operand as a
263  /// PointerType.
264  PointerType *getPointerOperandType() const {
265    return reinterpret_cast<PointerType*>(getPointerOperand()->getType());
266  }
267
268  unsigned getNumIndices() const {  // Note: always non-negative
269    return getNumOperands() - 1;
270  }
271
272  bool hasIndices() const {
273    return getNumOperands() > 1;
274  }
275
276  /// hasAllZeroIndices - Return true if all of the indices of this GEP are
277  /// zeros.  If so, the result pointer and the first operand have the same
278  /// value, just potentially different types.
279  bool hasAllZeroIndices() const {
280    for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
281      if (ConstantInt *C = dyn_cast<ConstantInt>(I))
282        if (C->isZero())
283          continue;
284      return false;
285    }
286    return true;
287  }
288
289  /// hasAllConstantIndices - Return true if all of the indices of this GEP are
290  /// constant integers.  If so, the result pointer and the first operand have
291  /// a constant offset between them.
292  bool hasAllConstantIndices() const {
293    for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
294      if (!isa<ConstantInt>(I))
295        return false;
296    }
297    return true;
298  }
299};
300
301} // End llvm namespace
302
303#endif
304