diff options
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r-- | include/llvm/ADT/APInt.h | 20 | ||||
-rw-r--r-- | include/llvm/ADT/ArrayRef.h | 48 | ||||
-rw-r--r-- | include/llvm/ADT/TinyPtrVector.h | 133 |
3 files changed, 196 insertions, 5 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index e68e579..58c9837 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -15,6 +15,7 @@ #ifndef LLVM_APINT_H #define LLVM_APINT_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/MathExtras.h" #include <cassert> #include <climits> @@ -176,6 +177,9 @@ class APInt { /// out-of-line slow case for inline constructor void initSlowCase(unsigned numBits, uint64_t val, bool isSigned); + /// shared code between two array constructors + void initFromArray(ArrayRef<uint64_t> array); + /// out-of-line slow case for inline copy constructor void initSlowCase(const APInt& that); @@ -230,12 +234,19 @@ public: clearUnusedBits(); } - /// Note that numWords can be smaller or larger than the corresponding bit - /// width but any extraneous bits will be dropped. + /// Note that bigVal.size() can be smaller or larger than the corresponding + /// bit width but any extraneous bits will be dropped. /// @param numBits the bit width of the constructed APInt - /// @param numWords the number of words in bigVal /// @param bigVal a sequence of words to form the initial value of the APInt /// @brief Construct an APInt of numBits width, initialized as bigVal[]. + APInt(unsigned numBits, ArrayRef<uint64_t> bigVal); + /// Equivalent to APInt(numBits, ArrayRef<uint64_t>(bigVal, numWords)), but + /// deprecated because this constructor is prone to ambiguity with the + /// APInt(unsigned, uint64_t, bool) constructor. + /// + /// If this overload is ever deleted, care should be taken to prevent calls + /// from being incorrectly captured by the APInt(unsigned, uint64_t, bool) + /// constructor. APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]); /// This constructor interprets the string \arg str in the given radix. The @@ -342,7 +353,8 @@ public: if (isSingleWord()) return isUIntN(N, VAL); - return APInt(N, getNumWords(), pVal).zext(getBitWidth()) == (*this); + return APInt(N, makeArrayRef(pVal, getNumWords())).zext(getBitWidth()) + == (*this); } /// @brief Check if this APInt has an N-bits signed integer value. diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index 6db866e..a073f06 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -147,7 +147,53 @@ namespace llvm { /// @} }; - + + /// @name ArrayRef Convenience constructors + /// @{ + + /// Construct an ArrayRef from a single element. + template<typename T> + ArrayRef<T> makeArrayRef(const T &OneElt) { + return OneElt; + } + + /// Construct an ArrayRef from a pointer and length. + template<typename T> + ArrayRef<T> makeArrayRef(const T *data, size_t length) { + return ArrayRef<T>(data, length); + } + + /// Construct an ArrayRef from a range. + template<typename T> + ArrayRef<T> makeArrayRef(const T *begin, const T *end) { + return ArrayRef<T>(begin, end); + } + + /// Construct an ArrayRef from a SmallVector. + template <typename T> + ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) { + return Vec; + } + + /// Construct an ArrayRef from a SmallVector. + template <typename T, unsigned N> + ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) { + return Vec; + } + + /// Construct an ArrayRef from a std::vector. + template<typename T> + ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) { + return Vec; + } + + /// Construct an ArrayRef from a C array. + template<typename T, size_t N> + ArrayRef<T> makeArrayRef(const T (&Arr)[N]) { + return ArrayRef<T>(Arr, N); + } + + /// @} /// @name ArrayRef Comparison Operators /// @{ diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h new file mode 100644 index 0000000..ee86d8b --- /dev/null +++ b/include/llvm/ADT/TinyPtrVector.h @@ -0,0 +1,133 @@ +//===- llvm/ADT/TinyPtrVector.h - 'Normally tiny' vectors -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_TINYPTRVECTOR_H +#define LLVM_ADT_TINYPTRVECTOR_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/PointerUnion.h" + +namespace llvm { + +/// TinyPtrVector - This class is specialized for cases where there are +/// normally 0 or 1 element in a vector, but is general enough to go beyond that +/// when required. +/// +/// NOTE: This container doesn't allow you to store a null pointer into it. +/// +template <typename EltTy> +class TinyPtrVector { +public: + typedef llvm::SmallVector<EltTy, 4> VecTy; + llvm::PointerUnion<EltTy, VecTy*> Val; + + TinyPtrVector() {} + TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) { + if (VecTy *V = Val.template dyn_cast<VecTy*>()) + Val = new VecTy(*V); + } + ~TinyPtrVector() { + if (VecTy *V = Val.template dyn_cast<VecTy*>()) + delete V; + } + + bool empty() const { + // This vector can be empty if it contains no element, or if it + // contains a pointer to an empty vector. + if (Val.isNull()) return true; + if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) + return Vec->empty(); + return false; + } + + unsigned size() const { + if (empty()) + return 0; + if (Val.template is<EltTy>()) + return 1; + return Val.template get<VecTy*>()->size(); + } + + typedef const EltTy *iterator; + iterator begin() const { + if (empty()) + return 0; + + if (Val.template is<EltTy>()) + return Val.template getAddrOf<EltTy>(); + + return Val.template get<VecTy *>()->begin(); + + } + iterator end() const { + if (empty()) + return 0; + + if (Val.template is<EltTy>()) + return begin() + 1; + + return Val.template get<VecTy *>()->end(); + } + + + EltTy operator[](unsigned i) const { + assert(!Val.isNull() && "can't index into an empty vector"); + if (EltTy V = Val.template dyn_cast<EltTy>()) { + assert(i == 0 && "tinyvector index out of range"); + return V; + } + + assert(i < Val.template get<VecTy*>()->size() && + "tinyvector index out of range"); + return (*Val.template get<VecTy*>())[i]; + } + + EltTy front() const { + assert(!empty() && "vector empty"); + if (EltTy V = Val.template dyn_cast<EltTy>()) + return V; + return Val.template get<VecTy*>()->front(); + } + + void push_back(EltTy NewVal) { + assert(NewVal != 0 && "Can't add a null value"); + + // If we have nothing, add something. + if (Val.isNull()) { + Val = NewVal; + return; + } + + // If we have a single value, convert to a vector. + if (EltTy V = Val.template dyn_cast<EltTy>()) { + Val = new VecTy(); + Val.template get<VecTy*>()->push_back(V); + } + + // Add the new value, we know we have a vector. + Val.template get<VecTy*>()->push_back(NewVal); + } + + void clear() { + // If we have a single value, convert to empty. + if (Val.template is<EltTy>()) { + Val = (EltTy)0; + } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) { + // If we have a vector form, just clear it. + Vec->clear(); + } + // Otherwise, we're already empty. + } + +private: + void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET. +}; +} // end namespace llvm + +#endif |