Casting.h: Automatically handle isa<Base>(Derived).
[oota-llvm.git] / include / llvm / Operator.h
index 48ac09d54fc401a2a5e1aa36411c1305aea00ec6..61ac163d4a153fd79318375cf06fd3d98e98d166 100644 (file)
 #ifndef LLVM_OPERATOR_H
 #define LLVM_OPERATOR_H
 
-#include "llvm/Instruction.h"
 #include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instruction.h"
+#include "llvm/Type.h"
 
 namespace llvm {
 
 class GetElementPtrInst;
+class BinaryOperator;
+class ConstantExpr;
 
 /// Operator - This is a utility class that provides an abstraction for the
 /// common functionality between Instructions and ConstantExprs.
@@ -29,9 +33,11 @@ class Operator : public User {
 private:
   // Do not implement any of these. The Operator class is intended to be used
   // as a utility, and is never itself instantiated.
-  void *operator new(size_t, unsigned);
-  void *operator new(size_t s);
-  Operator();
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  void *operator new(size_t s) LLVM_DELETED_FUNCTION;
+  Operator() LLVM_DELETED_FUNCTION;
+  // NOTE: cannot use LLVM_DELETED_FUNCTION because gcc errors when deleting
+  // an override of a non-deleted function.
   ~Operator();
 
 public:
@@ -55,8 +61,8 @@ public:
   }
 
   static inline bool classof(const Operator *) { return true; }
-  static inline bool classof(const Instruction *I) { return true; }
-  static inline bool classof(const ConstantExpr *I) { return true; }
+  static inline bool classof(const Instruction *) { return true; }
+  static inline bool classof(const ConstantExpr *) { return true; }
   static inline bool classof(const Value *V) {
     return isa<Instruction>(V) || isa<ConstantExpr>(V);
   }
@@ -67,36 +73,51 @@ public:
 /// despite that operator having the potential for overflow.
 ///
 class OverflowingBinaryOperator : public Operator {
-  ~OverflowingBinaryOperator(); // do not implement
+public:
+  enum {
+    NoUnsignedWrap = (1 << 0),
+    NoSignedWrap   = (1 << 1)
+  };
+
+private:
+  ~OverflowingBinaryOperator(); // DO NOT IMPLEMENT
+
+  friend class BinaryOperator;
+  friend class ConstantExpr;
+  void setHasNoUnsignedWrap(bool B) {
+    SubclassOptionalData =
+      (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
+  }
+  void setHasNoSignedWrap(bool B) {
+    SubclassOptionalData =
+      (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
+  }
+
 public:
   /// hasNoUnsignedWrap - Test whether this operation is known to never
   /// undergo unsigned overflow, aka the nuw property.
   bool hasNoUnsignedWrap() const {
-    return SubclassOptionalData & (1 << 0);
-  }
-  void setHasNoUnsignedWrap(bool B) {
-    SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
+    return SubclassOptionalData & NoUnsignedWrap;
   }
 
   /// hasNoSignedWrap - Test whether this operation is known to never
   /// undergo signed overflow, aka the nsw property.
   bool hasNoSignedWrap() const {
-    return SubclassOptionalData & (1 << 1);
-  }
-  void setHasNoSignedWrap(bool B) {
-    SubclassOptionalData = (SubclassOptionalData & ~(1 << 1)) | (B << 1);
+    return (SubclassOptionalData & NoSignedWrap) != 0;
   }
 
   static inline bool classof(const OverflowingBinaryOperator *) { return true; }
   static inline bool classof(const Instruction *I) {
     return I->getOpcode() == Instruction::Add ||
            I->getOpcode() == Instruction::Sub ||
-           I->getOpcode() == Instruction::Mul;
+           I->getOpcode() == Instruction::Mul ||
+           I->getOpcode() == Instruction::Shl;
   }
   static inline bool classof(const ConstantExpr *CE) {
     return CE->getOpcode() == Instruction::Add ||
            CE->getOpcode() == Instruction::Sub ||
-           CE->getOpcode() == Instruction::Mul;
+           CE->getOpcode() == Instruction::Mul ||
+           CE->getOpcode() == Instruction::Shl;
   }
   static inline bool classof(const Value *V) {
     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
@@ -104,17 +125,41 @@ public:
   }
 };
 
-/// AddOperator - Utility class for integer addition operators.
-///
-class AddOperator : public OverflowingBinaryOperator {
-  ~AddOperator(); // do not implement
+/// PossiblyExactOperator - A udiv or sdiv instruction, which can be marked as
+/// "exact", indicating that no bits are destroyed.
+class PossiblyExactOperator : public Operator {
 public:
-  static inline bool classof(const AddOperator *) { return true; }
-  static inline bool classof(const Instruction *I) {
-    return I->getOpcode() == Instruction::Add;
+  enum {
+    IsExact = (1 << 0)
+  };
+  
+private:
+  ~PossiblyExactOperator(); // DO NOT IMPLEMENT
+
+  friend class BinaryOperator;
+  friend class ConstantExpr;
+  void setIsExact(bool B) {
+    SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
+  }
+  
+public:
+  /// isExact - Test whether this division is known to be exact, with
+  /// zero remainder.
+  bool isExact() const {
+    return SubclassOptionalData & IsExact;
+  }
+  
+  static bool isPossiblyExactOpcode(unsigned OpC) {
+    return OpC == Instruction::SDiv ||
+           OpC == Instruction::UDiv ||
+           OpC == Instruction::AShr ||
+           OpC == Instruction::LShr;
   }
   static inline bool classof(const ConstantExpr *CE) {
-    return CE->getOpcode() == Instruction::Add;
+    return isPossiblyExactOpcode(CE->getOpcode());
+  }
+  static inline bool classof(const Instruction *I) {
+    return isPossiblyExactOpcode(I->getOpcode());
   }
   static inline bool classof(const Value *V) {
     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
@@ -122,35 +167,43 @@ public:
   }
 };
 
-/// SubOperator - Utility class for integer subtraction operators.
-///
-class SubOperator : public OverflowingBinaryOperator {
-  ~SubOperator(); // do not implement
+/// FPMathOperator - Utility class for floating point operations which can have
+/// information about relaxed accuracy requirements attached to them.
+class FPMathOperator : public Operator {
+private:
+  ~FPMathOperator(); // DO NOT IMPLEMENT
+
 public:
-  static inline bool classof(const SubOperator *) { return true; }
+
+  /// \brief Get the maximum error permitted by this operation in ULPs.  An
+  /// accuracy of 0.0 means that the operation should be performed with the
+  /// default precision.
+  float getFPAccuracy() const;
+
+  static inline bool classof(const FPMathOperator *) { return true; }
   static inline bool classof(const Instruction *I) {
-    return I->getOpcode() == Instruction::Sub;
-  }
-  static inline bool classof(const ConstantExpr *CE) {
-    return CE->getOpcode() == Instruction::Sub;
+    return I->getType()->isFPOrFPVectorTy();
   }
   static inline bool classof(const Value *V) {
-    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
-           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
   }
 };
 
-/// MulOperator - Utility class for integer multiplication operators.
-///
-class MulOperator : public OverflowingBinaryOperator {
-  ~MulOperator(); // do not implement
+  
+/// ConcreteOperator - A helper template for defining operators for individual
+/// opcodes.
+template<typename SuperClass, unsigned Opc>
+class ConcreteOperator : public SuperClass {
+  ~ConcreteOperator() LLVM_DELETED_FUNCTION;
 public:
-  static inline bool classof(const MulOperator *) { return true; }
+  static inline bool classof(const ConcreteOperator<SuperClass, Opc> *) {
+    return true;
+  }
   static inline bool classof(const Instruction *I) {
-    return I->getOpcode() == Instruction::Mul;
+    return I->getOpcode() == Opc;
   }
   static inline bool classof(const ConstantExpr *CE) {
-    return CE->getOpcode() == Instruction::Mul;
+    return CE->getOpcode() == Opc;
   }
   static inline bool classof(const Value *V) {
     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
@@ -158,44 +211,63 @@ public:
   }
 };
 
-/// SDivOperator - An Operator with opcode Instruction::SDiv.
-///
-class SDivOperator : public Operator {
-  ~SDivOperator(); // do not implement
-public:
-  /// isExact - Test whether this division is known to be exact, with
-  /// zero remainder.
-  bool isExact() const {
-    return SubclassOptionalData & (1 << 0);
-  }
-  void setIsExact(bool B) {
-    SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
-  }
+class AddOperator
+  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
+  ~AddOperator() LLVM_DELETED_FUNCTION;
+};
+class SubOperator
+  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
+  ~SubOperator() LLVM_DELETED_FUNCTION;
+};
+class MulOperator
+  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
+  ~MulOperator() LLVM_DELETED_FUNCTION;
+};
+class ShlOperator
+  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
+  ~ShlOperator() LLVM_DELETED_FUNCTION;
+};
 
-  // Methods for support type inquiry through isa, cast, and dyn_cast:
-  static inline bool classof(const SDivOperator *) { return true; }
-  static inline bool classof(const ConstantExpr *CE) {
-    return CE->getOpcode() == Instruction::SDiv;
-  }
-  static inline bool classof(const Instruction *I) {
-    return I->getOpcode() == Instruction::SDiv;
-  }
-  static inline bool classof(const Value *V) {
-    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
-           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
-  }
+  
+class SDivOperator
+  : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
+  ~SDivOperator() LLVM_DELETED_FUNCTION;
+};
+class UDivOperator
+  : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
+  ~UDivOperator() LLVM_DELETED_FUNCTION;
 };
+class AShrOperator
+  : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
+  ~AShrOperator() LLVM_DELETED_FUNCTION;
+};
+class LShrOperator
+  : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
+  ~LShrOperator() LLVM_DELETED_FUNCTION;
+};
+  
+  
+  
+class GEPOperator
+  : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
+  ~GEPOperator() LLVM_DELETED_FUNCTION;
+
+  enum {
+    IsInBounds = (1 << 0)
+  };
+
+  friend class GetElementPtrInst;
+  friend class ConstantExpr;
+  void setIsInBounds(bool B) {
+    SubclassOptionalData =
+      (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
+  }
 
-class GEPOperator : public Operator {
-  ~GEPOperator(); // do not implement
 public:
   /// isInBounds - Test whether this is an inbounds GEP, as defined
   /// by LangRef.html.
   bool isInBounds() const {
-    return SubclassOptionalData & (1 << 0);
-  }
-  void setIsInBounds(bool B) {
-    SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
+    return SubclassOptionalData & IsInBounds;
   }
 
   inline op_iterator       idx_begin()       { return op_begin()+1; }
@@ -215,8 +287,14 @@ public:
 
   /// getPointerOperandType - Method to return the pointer operand as a
   /// PointerType.
-  const PointerType *getPointerOperandType() const {
-    return reinterpret_cast<const PointerType*>(getPointerOperand()->getType());
+  Type *getPointerOperandType() const {
+    return getPointerOperand()->getType();
+  }
+
+  /// getPointerAddressSpace - Method to return the address space of the
+  /// pointer operand.
+  unsigned getPointerAddressSpace() const {
+    return cast<PointerType>(getPointerOperandType())->getAddressSpace();
   }
 
   unsigned getNumIndices() const {  // Note: always non-negative
@@ -232,26 +310,23 @@ public:
   /// value, just potentially different types.
   bool hasAllZeroIndices() const {
     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
-      if (Constant *C = dyn_cast<Constant>(I))
-        if (C->isNullValue())
+      if (ConstantInt *C = dyn_cast<ConstantInt>(I))
+        if (C->isZero())
           continue;
       return false;
     }
     return true;
   }
 
-  // Methods for support type inquiry through isa, cast, and dyn_cast:
-  static inline bool classof(const GEPOperator *) { return true; }
-  static inline bool classof(const GetElementPtrInst *) { return true; }
-  static inline bool classof(const ConstantExpr *CE) {
-    return CE->getOpcode() == Instruction::GetElementPtr;
-  }
-  static inline bool classof(const Instruction *I) {
-    return I->getOpcode() == Instruction::GetElementPtr;
-  }
-  static inline bool classof(const Value *V) {
-    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
-           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
+  /// hasAllConstantIndices - Return true if all of the indices of this GEP are
+  /// constant integers.  If so, the result pointer and the first operand have
+  /// a constant offset between them.
+  bool hasAllConstantIndices() const {
+    for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
+      if (!isa<ConstantInt>(I))
+        return false;
+    }
+    return true;
   }
 };