Reverting dtor devirtualization patch.
[oota-llvm.git] / include / llvm / Instructions.h
index 2913341cb8988b8037786dd7131e01e09579670a..2d721bb4147ac56bf2a775dce3c3e4a895e9666b 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "llvm/InstrTypes.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/ParameterAttributes.h"
 
 namespace llvm {
 
@@ -256,7 +257,7 @@ public:
   /// setVolatile - Specify whether this is a volatile load or not.
   ///
   void setVolatile(bool V) { 
-    SubclassData = (SubclassData & ~1) | V
+    SubclassData = (SubclassData & ~1) | (V ? 1 : 0)
   }
 
   virtual LoadInst *clone() const;
@@ -324,7 +325,7 @@ public:
   /// setVolatile - Specify whether this is a volatile load or not.
   ///
   void setVolatile(bool V) { 
-    SubclassData = (SubclassData & ~1) | V
+    SubclassData = (SubclassData & ~1) | (V ? 1 : 0)
   }
 
   /// Transparently provide more efficient getOperand methods.
@@ -367,6 +368,14 @@ public:
 //                             GetElementPtrInst Class
 //===----------------------------------------------------------------------===//
 
+// checkType - Simple wrapper function to give a better assertion failure
+// message on bad indexes for a gep instruction.
+//
+static inline const Type *checkType(const Type *Ty) {
+  assert(Ty && "Invalid GetElementPtrInst indices for type!");
+  return Ty;
+}
+
 /// GetElementPtrInst - an instruction for type-safe pointer arithmetic to
 /// access elements of arrays and structs
 ///
@@ -380,28 +389,94 @@ class GetElementPtrInst : public Instruction {
       OL[i].init(GEPIOL[i], this);
   }
   void init(Value *Ptr, Value* const *Idx, unsigned NumIdx);
-  void init(Value *Ptr, Value *Idx0, Value *Idx1);
   void init(Value *Ptr, Value *Idx);
+
+  template<typename InputIterator>
+  void init(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd,
+            const std::string &Name,
+            // This argument ensures that we have an iterator we can
+            // do arithmetic on in constant time
+            std::random_access_iterator_tag) {
+    typename std::iterator_traits<InputIterator>::difference_type NumIdx = 
+      std::distance(IdxBegin, IdxEnd);
+    
+    if (NumIdx > 0) {
+      // This requires that the itoerator points to contiguous memory.
+      init(Ptr, &*IdxBegin, NumIdx);
+    }
+    else {
+      init(Ptr, 0, NumIdx);
+    }
+
+    setName(Name);
+  }
+
+  /// getIndexedType - Returns the type of the element that would be loaded with
+  /// a load instruction with the specified parameters.
+  ///
+  /// A null type is returned if the indices are invalid for the specified
+  /// pointer type.
+  ///
+  static const Type *getIndexedType(const Type *Ptr,
+                                    Value* const *Idx, unsigned NumIdx,
+                                    bool AllowStructLeaf = false);
+
+  template<typename InputIterator>
+  static const Type *getIndexedType(const Type *Ptr,
+                                    InputIterator IdxBegin, 
+                                    InputIterator IdxEnd,
+                                    bool AllowStructLeaf,
+                                    // This argument ensures that we
+                                    // have an iterator we can do
+                                    // arithmetic on in constant time
+                                    std::random_access_iterator_tag) {
+    typename std::iterator_traits<InputIterator>::difference_type NumIdx = 
+      std::distance(IdxBegin, IdxEnd);
+
+    if (NumIdx > 0) {
+      // This requires that the iterator points to contiguous memory.
+      return(getIndexedType(Ptr, (Value *const *)&*IdxBegin, NumIdx,
+                            AllowStructLeaf));
+    }
+    else {
+      return(getIndexedType(Ptr, (Value *const*)0, NumIdx, AllowStructLeaf));
+    }
+  }
+
 public:
   /// Constructors - Create a getelementptr instruction with a base pointer an
   /// list of indices.  The first ctor can optionally insert before an existing
   /// instruction, the second appends the new instruction to the specified
   /// BasicBlock.
-  GetElementPtrInst(Value *Ptr, Value* const *Idx, unsigned NumIdx,
-                    const std::string &Name = "", Instruction *InsertBefore =0);
-  GetElementPtrInst(Value *Ptr, Value* const *Idx, unsigned NumIdx,
-                    const std::string &Name, BasicBlock *InsertAtEnd);
-  
+  template<typename InputIterator>
+  GetElementPtrInst(Value *Ptr, InputIterator IdxBegin, 
+                    InputIterator IdxEnd,
+                    const std::string &Name = "",
+                    Instruction *InsertBefore =0)
+      : Instruction(PointerType::get(
+                      checkType(getIndexedType(Ptr->getType(),
+                                               IdxBegin, IdxEnd, true))),
+                    GetElementPtr, 0, 0, InsertBefore) {
+    init(Ptr, IdxBegin, IdxEnd, Name,
+         typename std::iterator_traits<InputIterator>::iterator_category());
+  }
+  template<typename InputIterator>
+  GetElementPtrInst(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd,
+                    const std::string &Name, BasicBlock *InsertAtEnd)
+      : Instruction(PointerType::get(
+                      checkType(getIndexedType(Ptr->getType(),
+                                               IdxBegin, IdxEnd, true))),
+                    GetElementPtr, 0, 0, InsertAtEnd) {
+    init(Ptr, IdxBegin, IdxEnd, Name,
+         typename std::iterator_traits<InputIterator>::iterator_category());
+  }
+
   /// Constructors - These two constructors are convenience methods because one
   /// and two index getelementptr instructions are so common.
   GetElementPtrInst(Value *Ptr, Value *Idx,
                     const std::string &Name = "", Instruction *InsertBefore =0);
   GetElementPtrInst(Value *Ptr, Value *Idx,
                     const std::string &Name, BasicBlock *InsertAtEnd);
-  GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1,
-                    const std::string &Name = "", Instruction *InsertBefore =0);
-  GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1,
-                    const std::string &Name, BasicBlock *InsertAtEnd);
   ~GetElementPtrInst();
 
   virtual GetElementPtrInst *clone() const;
@@ -417,12 +492,15 @@ public:
   /// A null type is returned if the indices are invalid for the specified
   /// pointer type.
   ///
+  template<typename InputIterator>
   static const Type *getIndexedType(const Type *Ptr,
-                                    Value* const *Idx, unsigned NumIdx,
-                                    bool AllowStructLeaf = false);
-  
-  static const Type *getIndexedType(const Type *Ptr, Value *Idx0, Value *Idx1,
-                                    bool AllowStructLeaf = false);
+                                    InputIterator IdxBegin,
+                                    InputIterator IdxEnd,
+                                    bool AllowStructLeaf = false) {
+    return(getIndexedType(Ptr, IdxBegin, IdxEnd, AllowStructLeaf, 
+                          typename std::iterator_traits<InputIterator>::
+                          iterator_category()));
+  }  
   static const Type *getIndexedType(const Type *Ptr, Value *Idx);
 
   inline op_iterator       idx_begin()       { return op_begin()+1; }
@@ -563,27 +641,37 @@ public:
   /// @brief Return the signed version of the predicate.
   static Predicate getSignedPredicate(Predicate pred);
 
-  /// This also tests for commutativity. If isEquality() returns true then
-  /// the predicate is also commutative. 
-  /// @returns true if the predicate of this instruction is EQ or NE.
-  /// @brief Determine if this is an equality predicate.
+  /// isEquality - Return true if this predicate is either EQ or NE.  This also
+  /// tests for commutativity.
+  static bool isEquality(Predicate P) {
+    return P == ICMP_EQ || P == ICMP_NE;
+  }
+  
+  /// isEquality - Return true if this predicate is either EQ or NE.  This also
+  /// tests for commutativity.
   bool isEquality() const {
-    return SubclassData == ICMP_EQ || SubclassData == ICMP_NE;
+    return isEquality(getPredicate());
   }
 
   /// @returns true if the predicate of this ICmpInst is commutative
   /// @brief Determine if this relation is commutative.
   bool isCommutative() const { return isEquality(); }
 
-  /// @returns true if the predicate is relational (not EQ or NE). 
-  /// @brief Determine if this a relational predicate.
+  /// isRelational - Return true if the predicate is relational (not EQ or NE). 
+  ///
   bool isRelational() const {
     return !isEquality();
   }
 
+  /// isRelational - Return true if the predicate is relational (not EQ or NE). 
+  ///
+  static bool isRelational(Predicate P) {
+    return !isEquality(P);
+  }
+  
   /// @returns true if the predicate of this ICmpInst is signed, false otherwise
   /// @brief Determine if this instruction's predicate is signed.
-  bool isSignedPredicate() { return isSignedPredicate(getPredicate()); }
+  bool isSignedPredicate() const { return isSignedPredicate(getPredicate()); }
 
   /// @returns true if the predicate provided is signed, false otherwise
   /// @brief Determine if the predicate is signed.
@@ -749,7 +837,7 @@ public:
 ///
 
 class CallInst : public Instruction {
-  ParamAttrsList *ParamAttrs; ///< parameter attributes for call
+  const ParamAttrsList *ParamAttrs; ///< parameter attributes for call
   CallInst(const CallInst &CI);
   void init(Value *Func, Value* const *Params, unsigned NumParams);
   void init(Value *Func, Value *Actual1, Value *Actual2);
@@ -762,17 +850,10 @@ class CallInst : public Instruction {
             // This argument ensures that we have an iterator we can
             // do arithmetic on in constant time
             std::random_access_iterator_tag) {
-    typename std::iterator_traits<InputIterator>::difference_type NumArgs = 
-      std::distance(ArgBegin, ArgEnd);
-    
-    if (NumArgs > 0) {
-      // This requires that the iterator points to contiguous memory.
-      init(Func, &*ArgBegin, NumArgs);
-    }
-    else {
-      init(Func, 0, NumArgs);
-    }
+    unsigned NumArgs = (unsigned)std::distance(ArgBegin, ArgEnd);
     
+    // This requires that the iterator points to contiguous memory.
+    init(Func, NumArgs ? &*ArgBegin : 0, NumArgs);
     setName(Name);
   }
 
@@ -836,18 +917,42 @@ public:
   /// parameter attributes information, if any.
   /// @returns 0 if no attributes have been set.
   /// @brief Get the parameter attributes.
-  ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
+  const ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
 
   /// Sets the parameter attributes for this CallInst. To construct a 
   /// ParamAttrsList, see ParameterAttributes.h
   /// @brief Set the parameter attributes.
-  void setParamAttrs(ParamAttrsList *attrs);
+  void setParamAttrs(const ParamAttrsList *attrs);
+
+  /// @brief Determine whether the call or the callee has the given attribute.
+  bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
+
+  /// @brief Determine if the call does not access memory.
+  bool doesNotAccessMemory() const {
+    return paramHasAttr(0, ParamAttr::ReadNone);
+  }
+
+  /// @brief Determine if the call does not access or only reads memory.
+  bool onlyReadsMemory() const {
+    return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
+  }
+
+  /// @brief Determine if the call cannot unwind.
+  bool isNoUnwind() const {
+    return paramHasAttr(0, ParamAttr::NoUnwind);
+  }
+
+  /// @brief Determine if the call returns a structure.
+  bool isStructReturn() const {
+    // Be friendly and also check the callee.
+    return paramHasAttr(1, ParamAttr::StructRet);
+  }
 
   /// getCalledFunction - Return the function being called by this instruction
   /// if it is a direct call.  If it is a call through a function pointer,
   /// return null.
   Function *getCalledFunction() const {
-    return static_cast<Function*>(dyn_cast<Function>(getOperand(0)));
+    return dyn_cast<Function>(getOperand(0));
   }
 
   /// getCalledValue - Get a pointer to the function that is invoked by this 
@@ -1540,7 +1645,7 @@ private:
 /// calling convention of the call.
 ///
 class InvokeInst : public TerminatorInst {
-  ParamAttrsList *ParamAttrs;
+  const ParamAttrsList *ParamAttrs;
   InvokeInst(const InvokeInst &BI);
   void init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
             Value* const *Args, unsigned NumArgs);
@@ -1552,17 +1657,10 @@ class InvokeInst : public TerminatorInst {
             // This argument ensures that we have an iterator we can
             // do arithmetic on in constant time
             std::random_access_iterator_tag) {
-    typename std::iterator_traits<InputIterator>::difference_type NumArgs = 
-      std::distance(ArgBegin, ArgEnd);
-    
-    if (NumArgs > 0) {
-      // This requires that the iterator points to contiguous memory.
-      init(Func, IfNormal, IfException, &*ArgBegin, NumArgs);
-    }
-    else {
-      init(Func, IfNormal, IfException, 0, NumArgs);
-    }
+    unsigned NumArgs = (unsigned)std::distance(ArgBegin, ArgEnd);
     
+    // This requires that the iterator points to contiguous memory.
+    init(Func, IfNormal, IfException, NumArgs ? &*ArgBegin : 0, NumArgs);
     setName(Name);
   }
 
@@ -1618,12 +1716,36 @@ public:
   /// parameter attributes information, if any.
   /// @returns 0 if no attributes have been set.
   /// @brief Get the parameter attributes.
-  ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
+  const ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
 
   /// Sets the parameter attributes for this InvokeInst. To construct a 
   /// ParamAttrsList, see ParameterAttributes.h
   /// @brief Set the parameter attributes.
-  void setParamAttrs(ParamAttrsList *attrs);
+  void setParamAttrs(const ParamAttrsList *attrs);
+
+  /// @brief Determine whether the call or the callee has the given attribute.
+  bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
+
+  /// @brief Determine if the call does not access memory.
+  bool doesNotAccessMemory() const {
+    return paramHasAttr(0, ParamAttr::ReadNone);
+  }
+
+  /// @brief Determine if the call does not access or only reads memory.
+  bool onlyReadsMemory() const {
+    return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
+  }
+
+  /// @brief Determine if the call cannot unwind.
+  bool isNoUnwind() const {
+    return paramHasAttr(0, ParamAttr::NoUnwind);
+  }
+
+  /// @brief Determine if the call returns a structure.
+  bool isStructReturn() const {
+    // Be friendly and also check the callee.
+    return paramHasAttr(1, ParamAttr::StructRet);
+  }
 
   /// getCalledFunction - Return the function called, or null if this is an
   /// indirect function invocation.