summaryrefslogtreecommitdiffstats
path: root/include/llvm/ADT
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r--include/llvm/ADT/APInt.h30
-rw-r--r--include/llvm/ADT/ArrayRef.h48
-rw-r--r--include/llvm/ADT/DenseMap.h6
-rw-r--r--include/llvm/ADT/DenseMapInfo.h14
-rw-r--r--include/llvm/ADT/DenseSet.h2
-rw-r--r--include/llvm/ADT/ImmutableMap.h157
-rw-r--r--include/llvm/ADT/ImmutableSet.h134
-rw-r--r--include/llvm/ADT/IntervalMap.h3
-rw-r--r--include/llvm/ADT/PointerUnion.h6
-rw-r--r--include/llvm/ADT/PostOrderIterator.h10
-rw-r--r--include/llvm/ADT/SCCIterator.h10
-rw-r--r--include/llvm/ADT/STLExtras.h34
-rw-r--r--include/llvm/ADT/SmallVector.h17
-rw-r--r--include/llvm/ADT/Statistic.h18
-rw-r--r--include/llvm/ADT/StringExtras.h1
-rw-r--r--include/llvm/ADT/TinyPtrVector.h133
-rw-r--r--include/llvm/ADT/Triple.h37
-rw-r--r--include/llvm/ADT/Twine.h108
18 files changed, 665 insertions, 103 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index e68e579..707e0db 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>
@@ -160,7 +161,7 @@ class APInt {
/// not assume that the string is well-formed and (2) grows the
/// result to hold the input.
///
- /// @param radix 2, 8, 10, or 16
+ /// @param radix 2, 8, 10, 16, or 36
/// @brief Convert a char array into an APInt
void fromString(unsigned numBits, StringRef str, uint8_t radix);
@@ -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,19 +234,26 @@ 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
/// interpretation stops when the first character that is not suitable for the
/// radix is encountered, or the end of the string. Acceptable radix values
- /// are 2, 8, 10 and 16. It is an error for the value implied by the string to
- /// require more bits than numBits.
+ /// are 2, 8, 10, 16, and 36. It is an error for the value implied by the
+ /// string to require more bits than numBits.
///
/// @param numBits the bit width of the constructed APInt
/// @param str the string to be interpreted
@@ -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.
@@ -1245,13 +1257,13 @@ public:
bool formatAsCLiteral = false) const;
/// Considers the APInt to be unsigned and converts it into a string in the
- /// radix given. The radix can be 2, 8, 10 or 16.
+ /// radix given. The radix can be 2, 8, 10 16, or 36.
void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
toString(Str, Radix, false, false);
}
/// Considers the APInt to be signed and converts it into a string in the
- /// radix given. The radix can be 2, 8, 10 or 16.
+ /// radix given. The radix can be 2, 8, 10, 16, or 36.
void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
toString(Str, Radix, true, false);
}
diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h
index 6db866e..33a8c65 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);
+ }
+
+ /// @}
/// @name ArrayRef Comparison Operators
/// @{
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index 0f1cfeb..e70cacf 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -540,6 +540,12 @@ private:
++Ptr;
}
};
+
+template<typename KeyT, typename ValueT, typename KeyInfoT, typename ValueInfoT>
+static inline size_t
+capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT, ValueInfoT> &X) {
+ return X.getMemorySize();
+}
} // end namespace llvm
diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h
index 744b6f4..df4084e 100644
--- a/include/llvm/ADT/DenseMapInfo.h
+++ b/include/llvm/ADT/DenseMapInfo.h
@@ -51,7 +51,7 @@ struct DenseMapInfo<T*> {
template<> struct DenseMapInfo<char> {
static inline char getEmptyKey() { return ~0; }
static inline char getTombstoneKey() { return ~0 - 1; }
- static unsigned getHashValue(const char& Val) { return Val * 37; }
+ static unsigned getHashValue(const char& Val) { return Val * 37U; }
static bool isEqual(const char &LHS, const char &RHS) {
return LHS == RHS;
}
@@ -61,7 +61,7 @@ template<> struct DenseMapInfo<char> {
template<> struct DenseMapInfo<unsigned> {
static inline unsigned getEmptyKey() { return ~0; }
static inline unsigned getTombstoneKey() { return ~0U - 1; }
- static unsigned getHashValue(const unsigned& Val) { return Val * 37; }
+ static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
return LHS == RHS;
}
@@ -96,7 +96,7 @@ template<> struct DenseMapInfo<unsigned long long> {
template<> struct DenseMapInfo<int> {
static inline int getEmptyKey() { return 0x7fffffff; }
static inline int getTombstoneKey() { return -0x7fffffff - 1; }
- static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37); }
+ static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); }
static bool isEqual(const int& LHS, const int& RHS) {
return LHS == RHS;
}
@@ -109,7 +109,7 @@ template<> struct DenseMapInfo<long> {
}
static inline long getTombstoneKey() { return getEmptyKey() - 1L; }
static unsigned getHashValue(const long& Val) {
- return (unsigned)(Val * 37L);
+ return (unsigned)(Val * 37UL);
}
static bool isEqual(const long& LHS, const long& RHS) {
return LHS == RHS;
@@ -121,7 +121,7 @@ template<> struct DenseMapInfo<long long> {
static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; }
static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; }
static unsigned getHashValue(const long long& Val) {
- return (unsigned)(Val * 37LL);
+ return (unsigned)(Val * 37ULL);
}
static bool isEqual(const long long& LHS,
const long long& RHS) {
@@ -142,7 +142,7 @@ struct DenseMapInfo<std::pair<T, U> > {
}
static inline Pair getTombstoneKey() {
return std::make_pair(FirstInfo::getTombstoneKey(),
- SecondInfo::getEmptyKey());
+ SecondInfo::getTombstoneKey());
}
static unsigned getHashValue(const Pair& PairVal) {
uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32
@@ -158,7 +158,7 @@ struct DenseMapInfo<std::pair<T, U> > {
return (unsigned)key;
}
static bool isEqual(const Pair &LHS, const Pair &RHS) {
- return FirstInfo::isEqual(LHS.first, RHS.first) &&
+ return FirstInfo::isEqual(LHS.first, RHS.first) &&
SecondInfo::isEqual(LHS.second, RHS.second);
}
};
diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h
index 67321f5..8ab9a33 100644
--- a/include/llvm/ADT/DenseSet.h
+++ b/include/llvm/ADT/DenseSet.h
@@ -28,7 +28,7 @@ class DenseSet {
MapTy TheMap;
public:
DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {}
- explicit DenseSet(unsigned NumInitBuckets = 64) : TheMap(NumInitBuckets) {}
+ explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) {}
bool empty() const { return TheMap.empty(); }
unsigned size() const { return TheMap.size(); }
diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h
index d6cce7c..8346ffa 100644
--- a/include/llvm/ADT/ImmutableMap.h
+++ b/include/llvm/ADT/ImmutableMap.h
@@ -117,6 +117,10 @@ public:
return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
}
+ typename TreeTy::Factory *getTreeFactory() const {
+ return const_cast<typename TreeTy::Factory *>(&F);
+ }
+
private:
Factory(const Factory& RHS); // DO NOT IMPLEMENT
void operator=(const Factory& RHS); // DO NOT IMPLEMENT
@@ -256,6 +260,159 @@ public:
}
};
+// NOTE: This will possibly become the new implementation of ImmutableMap some day.
+template <typename KeyT, typename ValT,
+typename ValInfo = ImutKeyValueInfo<KeyT,ValT> >
+class ImmutableMapRef {
+public:
+ typedef typename ValInfo::value_type value_type;
+ typedef typename ValInfo::value_type_ref value_type_ref;
+ typedef typename ValInfo::key_type key_type;
+ typedef typename ValInfo::key_type_ref key_type_ref;
+ typedef typename ValInfo::data_type data_type;
+ typedef typename ValInfo::data_type_ref data_type_ref;
+ typedef ImutAVLTree<ValInfo> TreeTy;
+ typedef typename TreeTy::Factory FactoryTy;
+
+protected:
+ TreeTy *Root;
+ FactoryTy *Factory;
+
+public:
+ /// Constructs a map from a pointer to a tree root. In general one
+ /// should use a Factory object to create maps instead of directly
+ /// invoking the constructor, but there are cases where make this
+ /// constructor public is useful.
+ explicit ImmutableMapRef(const TreeTy* R, FactoryTy *F)
+ : Root(const_cast<TreeTy*>(R)),
+ Factory(F) {
+ if (Root) { Root->retain(); }
+ }
+
+ ImmutableMapRef(const ImmutableMapRef &X)
+ : Root(X.Root),
+ Factory(X.Factory) {
+ if (Root) { Root->retain(); }
+ }
+
+ ImmutableMapRef &operator=(const ImmutableMapRef &X) {
+ if (Root != X.Root) {
+ if (X.Root)
+ X.Root->retain();
+
+ if (Root)
+ Root->release();
+
+ Root = X.Root;
+ Factory = X.Factory;
+ }
+ return *this;
+ }
+
+ ~ImmutableMapRef() {
+ if (Root)
+ Root->release();
+ }
+
+ static inline ImmutableMapRef getEmptyMap(FactoryTy *F) {
+ return ImmutableMapRef(0, F);
+ }
+
+ ImmutableMapRef add(key_type_ref K, data_type_ref D) {
+ TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D));
+ return ImmutableMapRef(NewT, Factory);
+ }
+
+ ImmutableMapRef remove(key_type_ref K) {
+ TreeTy *NewT = Factory->remove(Root, K);
+ return ImmutableMapRef(NewT, Factory);
+ }
+
+ bool contains(key_type_ref K) const {
+ return Root ? Root->contains(K) : false;
+ }
+
+ ImmutableMap<KeyT, ValT> asImmutableMap() const {
+ return ImmutableMap<KeyT, ValT>(Factory->getCanonicalTree(Root));
+ }
+
+ bool operator==(const ImmutableMapRef &RHS) const {
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ }
+
+ bool operator!=(const ImmutableMapRef &RHS) const {
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ }
+
+ bool isEmpty() const { return !Root; }
+
+ //===--------------------------------------------------===//
+ // For testing.
+ //===--------------------------------------------------===//
+
+ void verify() const { if (Root) Root->verify(); }
+
+ //===--------------------------------------------------===//
+ // Iterators.
+ //===--------------------------------------------------===//
+
+ class iterator {
+ typename TreeTy::iterator itr;
+
+ iterator() {}
+ iterator(TreeTy* t) : itr(t) {}
+ friend class ImmutableMapRef;
+
+ public:
+ value_type_ref operator*() const { return itr->getValue(); }
+ value_type* operator->() const { return &itr->getValue(); }
+
+ key_type_ref getKey() const { return itr->getValue().first; }
+ data_type_ref getData() const { return itr->getValue().second; }
+
+
+ iterator& operator++() { ++itr; return *this; }
+ iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+ iterator& operator--() { --itr; return *this; }
+ iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
+ bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+ bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
+ };
+
+ iterator begin() const { return iterator(Root); }
+ iterator end() const { return iterator(); }
+
+ data_type* lookup(key_type_ref K) const {
+ if (Root) {
+ TreeTy* T = Root->find(K);
+ if (T) return &T->getValue().second;
+ }
+
+ return 0;
+ }
+
+ /// getMaxElement - Returns the <key,value> pair in the ImmutableMap for
+ /// which key is the highest in the ordering of keys in the map. This
+ /// method returns NULL if the map is empty.
+ value_type* getMaxElement() const {
+ return Root ? &(Root->getMaxElement()->getValue()) : 0;
+ }
+
+ //===--------------------------------------------------===//
+ // Utility methods.
+ //===--------------------------------------------------===//
+
+ unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+
+ static inline void Profile(FoldingSetNodeID& ID, const ImmutableMapRef &M) {
+ ID.AddPointer(M.Root);
+ }
+
+ inline void Profile(FoldingSetNodeID& ID) const {
+ return Profile(ID, *this);
+ }
+};
+
} // end namespace llvm
#endif
diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h
index 3ca910c..d597a7c 100644
--- a/include/llvm/ADT/ImmutableSet.h
+++ b/include/llvm/ADT/ImmutableSet.h
@@ -997,6 +997,10 @@ public:
BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
+ typename TreeTy::Factory *getTreeFactory() const {
+ return const_cast<typename TreeTy::Factory *>(&F);
+ }
+
private:
Factory(const Factory& RHS); // DO NOT IMPLEMENT
void operator=(const Factory& RHS); // DO NOT IMPLEMENT
@@ -1021,6 +1025,10 @@ public:
if (Root) { Root->retain(); }
return Root;
}
+
+ TreeTy *getRootWithoutRetain() const {
+ return Root;
+ }
/// isEmpty - Return true if the set contains no elements.
bool isEmpty() const { return !Root; }
@@ -1078,6 +1086,132 @@ public:
void validateTree() const { if (Root) Root->validateTree(); }
};
+
+// NOTE: This may some day replace the current ImmutableSet.
+template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
+class ImmutableSetRef {
+public:
+ typedef typename ValInfo::value_type value_type;
+ typedef typename ValInfo::value_type_ref value_type_ref;
+ typedef ImutAVLTree<ValInfo> TreeTy;
+ typedef typename TreeTy::Factory FactoryTy;
+
+private:
+ TreeTy *Root;
+ FactoryTy *Factory;
+
+public:
+ /// Constructs a set from a pointer to a tree root. In general one
+ /// should use a Factory object to create sets instead of directly
+ /// invoking the constructor, but there are cases where make this
+ /// constructor public is useful.
+ explicit ImmutableSetRef(TreeTy* R, FactoryTy *F)
+ : Root(R),
+ Factory(F) {
+ if (Root) { Root->retain(); }
+ }
+ ImmutableSetRef(const ImmutableSetRef &X)
+ : Root(X.Root),
+ Factory(X.Factory) {
+ if (Root) { Root->retain(); }
+ }
+ ImmutableSetRef &operator=(const ImmutableSetRef &X) {
+ if (Root != X.Root) {
+ if (X.Root) { X.Root->retain(); }
+ if (Root) { Root->release(); }
+ Root = X.Root;
+ Factory = X.Factory;
+ }
+ return *this;
+ }
+ ~ImmutableSetRef() {
+ if (Root) { Root->release(); }
+ }
+
+ static inline ImmutableSetRef getEmptySet(FactoryTy *F) {
+ return ImmutableSetRef(0, F);
+ }
+
+ ImmutableSetRef add(value_type_ref V) {
+ return ImmutableSetRef(Factory->add(Root, V), Factory);
+ }
+
+ ImmutableSetRef remove(value_type_ref V) {
+ return ImmutableSetRef(Factory->remove(Root, V), Factory);
+ }
+
+ /// Returns true if the set contains the specified value.
+ bool contains(value_type_ref V) const {
+ return Root ? Root->contains(V) : false;
+ }
+
+ ImmutableSet<ValT> asImmutableSet(bool canonicalize = true) const {
+ return ImmutableSet<ValT>(canonicalize ?
+ Factory->getCanonicalTree(Root) : Root);
+ }
+
+ TreeTy *getRootWithoutRetain() const {
+ return Root;
+ }
+
+ bool operator==(const ImmutableSetRef &RHS) const {
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ }
+
+ bool operator!=(const ImmutableSetRef &RHS) const {
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ }
+
+ /// isEmpty - Return true if the set contains no elements.
+ bool isEmpty() const { return !Root; }
+
+ /// isSingleton - Return true if the set contains exactly one element.
+ /// This method runs in constant time.
+ bool isSingleton() const { return getHeight() == 1; }
+
+ //===--------------------------------------------------===//
+ // Iterators.
+ //===--------------------------------------------------===//
+
+ class iterator {
+ typename TreeTy::iterator itr;
+ iterator(TreeTy* t) : itr(t) {}
+ friend class ImmutableSetRef<ValT,ValInfo>;
+ public:
+ iterator() {}
+ inline value_type_ref operator*() const { return itr->getValue(); }
+ inline iterator& operator++() { ++itr; return *this; }
+ inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+ inline iterator& operator--() { --itr; return *this; }
+ inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
+ inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+ inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
+ inline value_type *operator->() const { return &(operator*()); }
+ };
+
+ iterator begin() const { return iterator(Root); }
+ iterator end() const { return iterator(); }
+
+ //===--------------------------------------------------===//
+ // Utility methods.
+ //===--------------------------------------------------===//
+
+ unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+
+ static inline void Profile(FoldingSetNodeID& ID, const ImmutableSetRef& S) {
+ ID.AddPointer(S.Root);
+ }
+
+ inline void Profile(FoldingSetNodeID& ID) const {
+ return Profile(ID,*this);
+ }
+
+ //===--------------------------------------------------===//
+ // For testing.
+ //===--------------------------------------------------===//
+
+ void validateTree() const { if (Root) Root->validateTree(); }
+};
} // end namespace llvm
diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h
index f28ebf3..1230e8f 100644
--- a/include/llvm/ADT/IntervalMap.h
+++ b/include/llvm/ADT/IntervalMap.h
@@ -1335,6 +1335,9 @@ public:
/// valid - Return true if the current position is valid, false for end().
bool valid() const { return path.valid(); }
+ /// atBegin - Return true if the current position is the first map entry.
+ bool atBegin() const { return path.atBegin(); }
+
/// start - Return the beginning of the current interval.
const KeyT &start() const { return unsafeStart(); }
diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h
index 13b98ce..487096a 100644
--- a/include/llvm/ADT/PointerUnion.h
+++ b/include/llvm/ADT/PointerUnion.h
@@ -108,7 +108,11 @@ namespace llvm {
/// isNull - Return true if the pointer held in the union is null,
/// regardless of which type it is.
- bool isNull() const { return Val.getPointer() == 0; }
+ bool isNull() const {
+ // Convert from the void* to one of the pointer types, to make sure that
+ // we recursively strip off low bits if we have a nested PointerUnion.
+ return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer());
+ }
operator bool() const { return !isNull(); }
/// is<T>() return true if the Union currently holds the type matching T.
diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h
index e3b4994..63a2b52 100644
--- a/include/llvm/ADT/PostOrderIterator.h
+++ b/include/llvm/ADT/PostOrderIterator.h
@@ -29,6 +29,14 @@ public:
SetType Visited;
};
+/// DFSetTraits - Allow the SetType used to record depth-first search results to
+/// optionally record node postorder.
+template<class SetType>
+struct DFSetTraits {
+ static void finishPostorder(
+ typename SetType::iterator::value_type, SetType &) {}
+};
+
template<class SetType>
class po_iterator_storage<SetType, true> {
public:
@@ -109,6 +117,8 @@ public:
inline NodeType *operator->() const { return operator*(); }
inline _Self& operator++() { // Preincrement
+ DFSetTraits<SetType>::finishPostorder(VisitStack.back().first,
+ this->Visited);
VisitStack.pop_back();
if (!VisitStack.empty())
traverseChild();
diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h
index 3e93cfe..48436c6 100644
--- a/include/llvm/ADT/SCCIterator.h
+++ b/include/llvm/ADT/SCCIterator.h
@@ -1,4 +1,4 @@
-//===-- Support/SCCIterator.h - Strongly Connected Comp. Iter. --*- C++ -*-===//
+//===---- ADT/SCCIterator.h - Strongly Connected Comp. Iter. ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -87,7 +87,7 @@ class scc_iterator
DFSVisitOne(childN);
continue;
}
-
+
unsigned childNum = nodeVisitNumbers[childN];
if (MinVisitNumStack.back() > childNum)
MinVisitNumStack.back() = childNum;
@@ -114,7 +114,7 @@ class scc_iterator
if (minVisitNum != nodeVisitNumbers[visitingN])
continue;
-
+
// A full SCC is on the SCCNodeStack! It includes all nodes below
// visitingN on the stack. Copy those nodes to CurrentSCC,
// reset their minVisit values, and return (this suspends
@@ -139,7 +139,7 @@ public:
// Provide static "constructors"...
static inline _Self begin(const GraphT &G){return _Self(GT::getEntryNode(G));}
- static inline _Self end (const GraphT &G) { return _Self(); }
+ static inline _Self end (const GraphT &) { return _Self(); }
// Direct loop termination test: I.isAtEnd() is more efficient than I == end()
inline bool isAtEnd() const {
@@ -183,7 +183,7 @@ public:
return true;
return false;
}
-
+
/// ReplaceNode - This informs the scc_iterator that the specified Old node
/// has been deleted, and New is to be used in its place.
void ReplaceNode(NodeType *Old, NodeType *New) {
diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h
index 0b0346b..5da906d 100644
--- a/include/llvm/ADT/STLExtras.h
+++ b/include/llvm/ADT/STLExtras.h
@@ -186,25 +186,21 @@ inline ItTy prior(ItTy it)
// // do stuff
// else
// // do other stuff
-
-namespace
-{
- template <typename T1, typename T2>
- struct tier {
- typedef T1 &first_type;
- typedef T2 &second_type;
-
- first_type first;
- second_type second;
-
- tier(first_type f, second_type s) : first(f), second(s) { }
- tier& operator=(const std::pair<T1, T2>& p) {
- first = p.first;
- second = p.second;
- return *this;
- }
- };
-}
+template <typename T1, typename T2>
+struct tier {
+ typedef T1 &first_type;
+ typedef T2 &second_type;
+
+ first_type first;
+ second_type second;
+
+ tier(first_type f, second_type s) : first(f), second(s) { }
+ tier& operator=(const std::pair<T1, T2>& p) {
+ first = p.first;
+ second = p.second;
+ return *this;
+ }
+};
template <typename T1, typename T2>
inline tier<T1, T2> tie(T1& f, T2& s) {
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index 5f0a55b..1c42f29 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -78,21 +78,21 @@ protected:
return BeginX == static_cast<const void*>(&FirstEl);
}
+ /// grow_pod - This is an implementation of the grow() method which only works
+ /// on POD-like data types and is out of line to reduce code duplication.
+ void grow_pod(size_t MinSizeInBytes, size_t TSize);
+
+public:
/// size_in_bytes - This returns size()*sizeof(T).
size_t size_in_bytes() const {
return size_t((char*)EndX - (char*)BeginX);
}
-
+
/// capacity_in_bytes - This returns capacity()*sizeof(T).
size_t capacity_in_bytes() const {
return size_t((char*)CapacityX - (char*)BeginX);
}
- /// grow_pod - This is an implementation of the grow() method which only works
- /// on POD-like data types and is out of line to reduce code duplication.
- void grow_pod(size_t MinSizeInBytes, size_t TSize);
-
-public:
bool empty() const { return BeginX == EndX; }
};
@@ -738,6 +738,11 @@ public:
};
+template<typename T, unsigned N>
+static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
+ return X.capacity_in_bytes();
+}
+
} // End llvm namespace
namespace std {
diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h
index fda99c6..b8a1a2f 100644
--- a/include/llvm/ADT/Statistic.h
+++ b/include/llvm/ADT/Statistic.h
@@ -54,7 +54,7 @@ public:
Value = Val;
return init();
}
-
+
const Statistic &operator++() {
// FIXME: This function and all those that follow carefully use an
// atomic operation to update the value safely in the presence of
@@ -63,41 +63,43 @@ public:
sys::AtomicIncrement(&Value);
return init();
}
-
+
unsigned operator++(int) {
init();
unsigned OldValue = Value;
sys::AtomicIncrement(&Value);
return OldValue;
}
-
+
const Statistic &operator--() {
sys::AtomicDecrement(&Value);
return init();
}
-
+
unsigned operator--(int) {
init();
unsigned OldValue = Value;
sys::AtomicDecrement(&Value);
return OldValue;
}
-
+
const Statistic &operator+=(const unsigned &V) {
+ if (!V) return *this;
sys::AtomicAdd(&Value, V);
return init();
}
-
+
const Statistic &operator-=(const unsigned &V) {
+ if (!V) return *this;
sys::AtomicAdd(&Value, -V);
return init();
}
-
+
const Statistic &operator*=(const unsigned &V) {
sys::AtomicMul(&Value, V);
return init();
}
-
+
const Statistic &operator/=(const unsigned &V) {
sys::AtomicDiv(&Value, V);
return init();
diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h
index 5f5c041..d01d3e1 100644
--- a/include/llvm/ADT/StringExtras.h
+++ b/include/llvm/ADT/StringExtras.h
@@ -16,6 +16,7 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/StringRef.h"
#include <cctype>
#include <cstdio>
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
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index fd23608..3503c0f 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -10,8 +10,7 @@
#ifndef LLVM_ADT_TRIPLE_H
#define LLVM_ADT_TRIPLE_H
-#include "llvm/ADT/StringRef.h"
-#include <string>
+#include "llvm/ADT/Twine.h"
// Some system headers or GCC predefined macros conflict with identifiers in
// this file. Undefine them here.
@@ -19,8 +18,6 @@
#undef sparc
namespace llvm {
-class StringRef;
-class Twine;
/// Triple - Helper class for working with target triples.
///
@@ -52,6 +49,8 @@ public:
cellspu, // CellSPU: spu, cellspu
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel, psp
+ mips64, // MIPS64: mips64
+ mips64el,// MIPS64EL: mips64el
msp430, // MSP430: msp430
ppc, // PPC: powerpc
ppc64, // PPC64: powerpc64, ppu
@@ -66,6 +65,8 @@ public:
mblaze, // MBlaze: mblaze
ptx32, // PTX: ptx (32-bit)
ptx64, // PTX: ptx (64-bit)
+ le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
+ amdil, // amdil: amd IL
InvalidArch
};
@@ -85,6 +86,7 @@ public:
DragonFly,
FreeBSD,
IOS,
+ KFreeBSD,
Linux,
Lv2, // PS3
MacOSX,
@@ -96,7 +98,8 @@ public:
Win32,
Haiku,
Minix,
- RTEMS
+ RTEMS,
+ NativeClient
};
enum EnvironmentType {
UnknownEnvironment,
@@ -134,24 +137,16 @@ public:
/// @{
Triple() : Data(), Arch(InvalidArch) {}
- explicit Triple(StringRef Str) : Data(Str), Arch(InvalidArch) {}
- explicit Triple(StringRef ArchStr, StringRef VendorStr, StringRef OSStr)
- : Data(ArchStr), Arch(InvalidArch) {
- Data += '-';
- Data += VendorStr;
- Data += '-';
- Data += OSStr;
+ explicit Triple(const Twine &Str) : Data(Str.str()), Arch(InvalidArch) {}
+ Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
+ : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
+ Arch(InvalidArch) {
}
- explicit Triple(StringRef ArchStr, StringRef VendorStr, StringRef OSStr,
- StringRef EnvironmentStr)
- : Data(ArchStr), Arch(InvalidArch) {
- Data += '-';
- Data += VendorStr;
- Data += '-';
- Data += OSStr;
- Data += '-';
- Data += EnvironmentStr;
+ Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
+ const Twine &EnvironmentStr)
+ : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
+ EnvironmentStr).str()), Arch(InvalidArch) {
}
/// @}
diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h
index ab8d365..3a60cab 100644
--- a/include/llvm/ADT/Twine.h
+++ b/include/llvm/ADT/Twine.h
@@ -99,6 +99,9 @@ namespace llvm {
/// A pointer to a StringRef instance.
StringRefKind,
+ /// A char value reinterpreted as a pointer, to render as a character.
+ CharKind,
+
/// An unsigned int value reinterpreted as a pointer, to render as an
/// unsigned decimal integer.
DecUIKind,
@@ -126,13 +129,31 @@ namespace llvm {
UHexKind
};
+ union Child
+ {
+ const Twine *twine;
+ const char *cString;
+ const std::string *stdString;
+ const StringRef *stringRef;
+ char character;
+ unsigned int decUI;
+ int decI;
+ const unsigned long *decUL;
+ const long *decL;
+ const unsigned long long *decULL;
+ const long long *decLL;
+ const uint64_t *uHex;
+ };
+
private:
/// LHS - The prefix in the concatenation, which may be uninitialized for
/// Null or Empty kinds.
- const void *LHS;
+ Child LHS;
/// RHS - The suffix in the concatenation, which may be uninitialized for
/// Null or Empty kinds.
- const void *RHS;
+ Child RHS;
+ // enums stored as unsigned chars to save on space while some compilers
+ // don't support specifying the backing type for an enum
/// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
unsigned char LHSKind;
/// RHSKind - The NodeKind of the left hand side, \see getLHSKind().
@@ -147,13 +168,15 @@ namespace llvm {
/// Construct a binary twine.
explicit Twine(const Twine &_LHS, const Twine &_RHS)
- : LHS(&_LHS), RHS(&_RHS), LHSKind(TwineKind), RHSKind(TwineKind) {
+ : LHSKind(TwineKind), RHSKind(TwineKind) {
+ LHS.twine = &_LHS;
+ RHS.twine = &_RHS;
assert(isValid() && "Invalid twine!");
}
/// Construct a twine from explicit values.
- explicit Twine(const void *_LHS, NodeKind _LHSKind,
- const void *_RHS, NodeKind _RHSKind)
+ explicit Twine(Child _LHS, NodeKind _LHSKind,
+ Child _RHS, NodeKind _RHSKind)
: LHS(_LHS), RHS(_RHS), LHSKind(_LHSKind), RHSKind(_RHSKind) {
assert(isValid() && "Invalid twine!");
}
@@ -200,10 +223,10 @@ namespace llvm {
// A twine child should always be binary.
if (getLHSKind() == TwineKind &&
- !static_cast<const Twine*>(LHS)->isBinary())
+ !LHS.twine->isBinary())
return false;
if (getRHSKind() == TwineKind &&
- !static_cast<const Twine*>(RHS)->isBinary())
+ !RHS.twine->isBinary())
return false;
return true;
@@ -216,10 +239,10 @@ namespace llvm {
NodeKind getRHSKind() const { return (NodeKind) RHSKind; }
/// printOneChild - Print one child from a twine.
- void printOneChild(raw_ostream &OS, const void *Ptr, NodeKind Kind) const;
+ void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
/// printOneChildRepr - Print the representation of one child from a twine.
- void printOneChildRepr(raw_ostream &OS, const void *Ptr,
+ void printOneChildRepr(raw_ostream &OS, Child Ptr,
NodeKind Kind) const;
public:
@@ -239,7 +262,7 @@ namespace llvm {
/*implicit*/ Twine(const char *Str)
: RHSKind(EmptyKind) {
if (Str[0] != '\0') {
- LHS = Str;
+ LHS.cString = Str;
LHSKind = CStringKind;
} else
LHSKind = EmptyKind;
@@ -249,44 +272,70 @@ namespace llvm {
/// Construct from an std::string.
/*implicit*/ Twine(const std::string &Str)
- : LHS(&Str), LHSKind(StdStringKind), RHSKind(EmptyKind) {
+ : LHSKind(StdStringKind), RHSKind(EmptyKind) {
+ LHS.stdString = &Str;
assert(isValid() && "Invalid twine!");
}
/// Construct from a StringRef.
/*implicit*/ Twine(const StringRef &Str)
- : LHS(&Str), LHSKind(StringRefKind), RHSKind(EmptyKind) {
+ : LHSKind(StringRefKind), RHSKind(EmptyKind) {
+ LHS.stringRef = &Str;
assert(isValid() && "Invalid twine!");
}
+ /// Construct from a char.
+ explicit Twine(char Val)
+ : LHSKind(CharKind), RHSKind(EmptyKind) {
+ LHS.character = Val;
+ }
+
+ /// Construct from a signed char.
+ explicit Twine(signed char Val)
+ : LHSKind(CharKind), RHSKind(EmptyKind) {
+ LHS.character = static_cast<char>(Val);
+ }
+
+ /// Construct from an unsigned char.
+ explicit Twine(unsigned char Val)
+ : LHSKind(CharKind), RHSKind(EmptyKind) {
+ LHS.character = static_cast<char>(Val);
+ }
+
/// Construct a twine to print \arg Val as an unsigned decimal integer.
explicit Twine(unsigned Val)
- : LHS((void*)(intptr_t)Val), LHSKind(DecUIKind), RHSKind(EmptyKind) {
+ : LHSKind(DecUIKind), RHSKind(EmptyKind) {
+ LHS.decUI = Val;
}
/// Construct a twine to print \arg Val as a signed decimal integer.
explicit Twine(int Val)
- : LHS((void*)(intptr_t)Val), LHSKind(DecIKind), RHSKind(EmptyKind) {
+ : LHSKind(DecIKind), RHSKind(EmptyKind) {
+ LHS.decI = Val;
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
explicit Twine(const unsigned long &Val)
- : LHS(&Val), LHSKind(DecULKind), RHSKind(EmptyKind) {
+ : LHSKind(DecULKind), RHSKind(EmptyKind) {
+ LHS.decUL = &Val;
}
/// Construct a twine to print \arg Val as a signed decimal integer.
explicit Twine(const long &Val)
- : LHS(&Val), LHSKind(DecLKind), RHSKind(EmptyKind) {
+ : LHSKind(DecLKind), RHSKind(EmptyKind) {
+ LHS.decL = &Val;
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
explicit Twine(const unsigned long long &Val)
- : LHS(&Val), LHSKind(DecULLKind), RHSKind(EmptyKind) {
+ : LHSKind(DecULLKind), RHSKind(EmptyKind) {
+ LHS.decULL = &Val;
}
/// Construct a twine to print \arg Val as a signed decimal integer.
explicit Twine(const long long &Val)
- : LHS(&Val), LHSKind(DecLLKind), RHSKind(EmptyKind) {
+ : LHSKind(DecLLKind), RHSKind(EmptyKind) {
+ LHS.decLL = &Val;
}
// FIXME: Unfortunately, to make sure this is as efficient as possible we
@@ -296,13 +345,17 @@ namespace llvm {
/// Construct as the concatenation of a C string and a StringRef.
/*implicit*/ Twine(const char *_LHS, const StringRef &_RHS)
- : LHS(_LHS), RHS(&_RHS), LHSKind(CStringKind), RHSKind(StringRefKind) {
+ : LHSKind(CStringKind), RHSKind(StringRefKind) {
+ LHS.cString = _LHS;
+ RHS.stringRef = &_RHS;
assert(isValid() && "Invalid twine!");
}
/// Construct as the concatenation of a StringRef and a C string.
/*implicit*/ Twine(const StringRef &_LHS, const char *_RHS)
- : LHS(&_LHS), RHS(_RHS), LHSKind(StringRefKind), RHSKind(CStringKind) {
+ : LHSKind(StringRefKind), RHSKind(CStringKind) {
+ LHS.stringRef = &_LHS;
+ RHS.cString = _RHS;
assert(isValid() && "Invalid twine!");
}
@@ -318,7 +371,10 @@ namespace llvm {
// Construct a twine to print \arg Val as an unsigned hexadecimal integer.
static Twine utohexstr(const uint64_t &Val) {
- return Twine(&Val, UHexKind, 0, EmptyKind);
+ Child LHS, RHS;
+ LHS.uHex = &Val;
+ RHS.twine = 0;
+ return Twine(LHS, UHexKind, RHS, EmptyKind);
}
/// @}
@@ -371,9 +427,9 @@ namespace llvm {
switch (getLHSKind()) {
default: assert(0 && "Out of sync with isSingleStringRef");
case EmptyKind: return StringRef();
- case CStringKind: return StringRef((const char*)LHS);
- case StdStringKind: return StringRef(*(const std::string*)LHS);
- case StringRefKind: return *(const StringRef*)LHS;
+ case CStringKind: return StringRef(LHS.cString);
+ case StdStringKind: return StringRef(*LHS.stdString);
+ case StringRefKind: return *LHS.stringRef;
}
}
@@ -422,7 +478,9 @@ namespace llvm {
// Otherwise we need to create a new node, taking care to fold in unary
// twines.
- const void *NewLHS = this, *NewRHS = &Suffix;
+ Child NewLHS, NewRHS;
+ NewLHS.twine = this;
+ NewRHS.twine = &Suffix;
NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
if (isUnary()) {
NewLHS = LHS;
OpenPOWER on IntegriCloud