diff options
Diffstat (limited to 'include')
246 files changed, 4982 insertions, 3598 deletions
diff --git a/include/llvm-c/Linker.h b/include/llvm-c/Linker.h index cedde5e..9f98a33 100644 --- a/include/llvm-c/Linker.h +++ b/include/llvm-c/Linker.h @@ -20,13 +20,23 @@ extern "C" { #endif +/* This enum is provided for backwards-compatibility only. It has no effect. */ +typedef enum { + LLVMLinkerDestroySource = 0, /* This is the default behavior. */ + LLVMLinkerPreserveSource_Removed = 1 /* This option has been deprecated and + should not be used. */ +} LLVMLinkerMode; + /* Links the source module into the destination module, taking ownership * of the source module away from the caller. Optionally returns a * human-readable description of any errors that occurred in linking. * OutMessage must be disposed with LLVMDisposeMessage. The return value - * is true if an error occurred, false otherwise. */ + * is true if an error occurred, false otherwise. + * + * Note that the linker mode parameter \p Unused is no longer used, and has + * no effect. */ LLVMBool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src, - unsigned Unused, char **OutMessage); + LLVMLinkerMode Unused, char **OutMessage); #ifdef __cplusplus } diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index bf814e0..53b53c5 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -282,12 +282,6 @@ public: /// into FoldingSets. void Profile(FoldingSetNodeID &NID) const; - /// \brief Used by the Bitcode serializer to emit APInts to Bitcode. - void Emit(Serializer &S) const; - - /// \brief Used by the Bitcode deserializer to deserialize APInts. - static APFloat ReadVal(Deserializer &D); - /// \name Arithmetic /// @{ diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index c2fe094..36d8159 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -25,9 +25,7 @@ #include <string> namespace llvm { -class Deserializer; class FoldingSetNodeID; -class Serializer; class StringRef; class hash_code; class raw_ostream; @@ -409,6 +407,13 @@ public: : getZExtValue(); } + /// \brief Check if the APInt consists of a repeated bit pattern. + /// + /// e.g. 0x01010101 satisfies isSplat(8). + /// \param SplatSizeInBits The size of the pattern in bits. Must divide bit + /// width without remainder. + bool isSplat(unsigned SplatSizeInBits) const; + /// @} /// \name Value Generators /// @{ diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index 5b7ed9c..f7b055e 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -11,7 +11,6 @@ #define LLVM_ADT_ARRAYREF_H #include "llvm/ADT/None.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include <vector> @@ -44,19 +43,6 @@ namespace llvm { /// The number of elements. size_type Length; - /// \brief A dummy "optional" type that is only created by implicit - /// conversion from a reference to T. - /// - /// This type must *only* be used in a function argument or as a copy of - /// a function argument, as otherwise it will hold a pointer to a temporary - /// past that temporaries' lifetime. - struct TRefOrNothing { - const T *TPtr; - - TRefOrNothing() : TPtr(nullptr) {} - TRefOrNothing(const T &TRef) : TPtr(&TRef) {} - }; - public: /// @name Constructors /// @{ @@ -151,13 +137,9 @@ namespace llvm { bool equals(ArrayRef RHS) const { if (Length != RHS.Length) return false; - // Don't use std::equal(), since it asserts in MSVC on nullptr iterators. - for (auto L = begin(), LE = end(), R = RHS.begin(); L != LE; ++L, ++R) - // Match std::equal() in using == (instead of !=) to minimize API - // requirements of ArrayRef'ed types. - if (!(*L == *R)) - return false; - return true; + if (Length == 0) + return true; + return std::equal(begin(), end(), RHS.begin()); } /// slice(n) - Chop off the first N elements of the array. @@ -202,47 +184,6 @@ namespace llvm { } /// @} - /// @{ - /// @name Convenience methods - - /// @brief Predicate for testing that the array equals the exact sequence of - /// arguments. - /// - /// Will return false if the size is not equal to the exact number of - /// arguments given or if the array elements don't equal the argument - /// elements in order. Currently supports up to 16 arguments, but can - /// easily be extended. - bool equals(TRefOrNothing Arg0 = TRefOrNothing(), - TRefOrNothing Arg1 = TRefOrNothing(), - TRefOrNothing Arg2 = TRefOrNothing(), - TRefOrNothing Arg3 = TRefOrNothing(), - TRefOrNothing Arg4 = TRefOrNothing(), - TRefOrNothing Arg5 = TRefOrNothing(), - TRefOrNothing Arg6 = TRefOrNothing(), - TRefOrNothing Arg7 = TRefOrNothing(), - TRefOrNothing Arg8 = TRefOrNothing(), - TRefOrNothing Arg9 = TRefOrNothing(), - TRefOrNothing Arg10 = TRefOrNothing(), - TRefOrNothing Arg11 = TRefOrNothing(), - TRefOrNothing Arg12 = TRefOrNothing(), - TRefOrNothing Arg13 = TRefOrNothing(), - TRefOrNothing Arg14 = TRefOrNothing(), - TRefOrNothing Arg15 = TRefOrNothing()) { - TRefOrNothing Args[] = {Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, - Arg6, Arg7, Arg8, Arg9, Arg10, Arg11, - Arg12, Arg13, Arg14, Arg15}; - if (size() > array_lengthof(Args)) - return false; - - for (unsigned i = 0, e = size(); i != e; ++i) - if (Args[i].TPtr == nullptr || (*this)[i] != *Args[i].TPtr) - return false; - - // Either the size is exactly as many args, or the next arg must be null. - return size() == array_lengthof(Args) || Args[size()].TPtr == nullptr; - } - - /// @} }; /// MutableArrayRef - Represent a mutable reference to an array (0 or more diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 0dbe810..f58dd73 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -53,7 +53,7 @@ public: BitPos = Idx % BITWORD_SIZE; } - ~reference() {} + reference(const reference&) = default; reference &operator=(reference t) { *this = bool(t); diff --git a/include/llvm/ADT/DeltaAlgorithm.h b/include/llvm/ADT/DeltaAlgorithm.h index 4d07e04..21bc1e8 100644 --- a/include/llvm/ADT/DeltaAlgorithm.h +++ b/include/llvm/ADT/DeltaAlgorithm.h @@ -77,6 +77,8 @@ protected: /// ExecuteOneTest - Execute a single test predicate on the change set \p S. virtual bool ExecuteOneTest(const changeset_ty &S) = 0; + DeltaAlgorithm& operator=(const DeltaAlgorithm&) = default; + public: virtual ~DeltaAlgorithm(); diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index 1699ea3..8c65f70 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -15,6 +15,7 @@ #define LLVM_ADT_DENSEMAP_H #include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/EpochTracker.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MathExtras.h" @@ -50,7 +51,7 @@ class DenseMapIterator; template <typename DerivedT, typename KeyT, typename ValueT, typename KeyInfoT, typename BucketT> -class DenseMapBase { +class DenseMapBase : public DebugEpochBase { public: typedef unsigned size_type; typedef KeyT key_type; @@ -62,16 +63,17 @@ public: const_iterator; inline iterator begin() { // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets(). - return empty() ? end() : iterator(getBuckets(), getBucketsEnd()); + return empty() ? end() : iterator(getBuckets(), getBucketsEnd(), *this); } inline iterator end() { - return iterator(getBucketsEnd(), getBucketsEnd(), true); + return iterator(getBucketsEnd(), getBucketsEnd(), *this, true); } inline const_iterator begin() const { - return empty() ? end() : const_iterator(getBuckets(), getBucketsEnd()); + return empty() ? end() + : const_iterator(getBuckets(), getBucketsEnd(), *this); } inline const_iterator end() const { - return const_iterator(getBucketsEnd(), getBucketsEnd(), true); + return const_iterator(getBucketsEnd(), getBucketsEnd(), *this, true); } bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { @@ -81,11 +83,13 @@ public: /// Grow the densemap so that it has at least Size buckets. Does not shrink void resize(size_type Size) { + incrementEpoch(); if (Size > getNumBuckets()) grow(Size); } void clear() { + incrementEpoch(); if (getNumEntries() == 0 && getNumTombstones() == 0) return; // If the capacity of the array is huge, and the # elements used is small, @@ -118,13 +122,13 @@ public: iterator find(const KeyT &Val) { BucketT *TheBucket; if (LookupBucketFor(Val, TheBucket)) - return iterator(TheBucket, getBucketsEnd(), true); + return iterator(TheBucket, getBucketsEnd(), *this, true); return end(); } const_iterator find(const KeyT &Val) const { const BucketT *TheBucket; if (LookupBucketFor(Val, TheBucket)) - return const_iterator(TheBucket, getBucketsEnd(), true); + return const_iterator(TheBucket, getBucketsEnd(), *this, true); return end(); } @@ -137,14 +141,14 @@ public: iterator find_as(const LookupKeyT &Val) { BucketT *TheBucket; if (LookupBucketFor(Val, TheBucket)) - return iterator(TheBucket, getBucketsEnd(), true); + return iterator(TheBucket, getBucketsEnd(), *this, true); return end(); } template<class LookupKeyT> const_iterator find_as(const LookupKeyT &Val) const { const BucketT *TheBucket; if (LookupBucketFor(Val, TheBucket)) - return const_iterator(TheBucket, getBucketsEnd(), true); + return const_iterator(TheBucket, getBucketsEnd(), *this, true); return end(); } @@ -163,12 +167,13 @@ public: std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) { BucketT *TheBucket; if (LookupBucketFor(KV.first, TheBucket)) - return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), + return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), false); // Already in map. // Otherwise, insert the new element. TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket); - return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true); + return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), + true); } // Inserts key,value pair into the map if the key isn't already in the map. @@ -177,14 +182,15 @@ public: std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) { BucketT *TheBucket; if (LookupBucketFor(KV.first, TheBucket)) - return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), + return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), false); // Already in map. - + // Otherwise, insert the new element. TheBucket = InsertIntoBucket(std::move(KV.first), std::move(KV.second), TheBucket); - return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true); + return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), + true); } /// insert - Range insertion of pairs. @@ -431,6 +437,8 @@ private: } BucketT *InsertIntoBucketImpl(const KeyT &Key, BucketT *TheBucket) { + incrementEpoch(); + // If the load of the hash table is more than 3/4, or if fewer than 1/8 of // the buckets are empty (meaning that many are filled with tombstones), // grow the table. @@ -987,9 +995,10 @@ private: template <typename KeyT, typename ValueT, typename KeyInfoT, typename Bucket, bool IsConst> -class DenseMapIterator { +class DenseMapIterator : DebugEpochBase::HandleBase { typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true> ConstIterator; friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>; + friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false>; public: typedef ptrdiff_t difference_type; @@ -1003,38 +1012,54 @@ private: public: DenseMapIterator() : Ptr(nullptr), End(nullptr) {} - DenseMapIterator(pointer Pos, pointer E, bool NoAdvance = false) - : Ptr(Pos), End(E) { + DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase &Epoch, + bool NoAdvance = false) + : DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) { + assert(isHandleInSync() && "invalid construction!"); if (!NoAdvance) AdvancePastEmptyBuckets(); } - // If IsConst is true this is a converting constructor from iterator to - // const_iterator and the default copy constructor is used. - // Otherwise this is a copy constructor for iterator. + // Converting ctor from non-const iterators to const iterators. SFINAE'd out + // for const iterator destinations so it doesn't end up as a user defined copy + // constructor. + template <bool IsConstSrc, + typename = typename std::enable_if<!IsConstSrc && IsConst>::type> DenseMapIterator( - const DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false> &I) - : Ptr(I.Ptr), End(I.End) {} + const DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, IsConstSrc> &I) + : DebugEpochBase::HandleBase(I), Ptr(I.Ptr), End(I.End) {} reference operator*() const { + assert(isHandleInSync() && "invalid iterator access!"); return *Ptr; } pointer operator->() const { + assert(isHandleInSync() && "invalid iterator access!"); return Ptr; } bool operator==(const ConstIterator &RHS) const { - return Ptr == RHS.operator->(); + assert((!Ptr || isHandleInSync()) && "handle not in sync!"); + assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!"); + assert(getEpochAddress() == RHS.getEpochAddress() && + "comparing incomparable iterators!"); + return Ptr == RHS.Ptr; } bool operator!=(const ConstIterator &RHS) const { - return Ptr != RHS.operator->(); + assert((!Ptr || isHandleInSync()) && "handle not in sync!"); + assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!"); + assert(getEpochAddress() == RHS.getEpochAddress() && + "comparing incomparable iterators!"); + return Ptr != RHS.Ptr; } inline DenseMapIterator& operator++() { // Preincrement + assert(isHandleInSync() && "invalid iterator access!"); ++Ptr; AdvancePastEmptyBuckets(); return *this; } DenseMapIterator operator++(int) { // Postincrement + assert(isHandleInSync() && "invalid iterator access!"); DenseMapIterator tmp = *this; ++*this; return tmp; } diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h index 6cd9e68..5186333 100644 --- a/include/llvm/ADT/DepthFirstIterator.h +++ b/include/llvm/ADT/DepthFirstIterator.h @@ -113,9 +113,8 @@ private: while (It != GT::child_end(Node)) { NodeType *Next = *It++; // Has our next sibling been visited? - if (Next && !this->Visited.count(Next)) { + if (Next && this->Visited.insert(Next).second) { // No, do it now. - this->Visited.insert(Next); VisitStack.push_back(std::make_pair(PointerIntTy(Next, 0), GT::child_begin(Next))); return; @@ -129,58 +128,57 @@ private: public: typedef typename super::pointer pointer; - typedef df_iterator<GraphT, SetType, ExtStorage, GT> _Self; // Provide static begin and end methods as our public "constructors" - static inline _Self begin(const GraphT& G) { - return _Self(GT::getEntryNode(G)); + static df_iterator begin(const GraphT &G) { + return df_iterator(GT::getEntryNode(G)); } - static inline _Self end(const GraphT& G) { return _Self(); } + static df_iterator end(const GraphT &G) { return df_iterator(); } // Static begin and end methods as our public ctors for external iterators - static inline _Self begin(const GraphT& G, SetType &S) { - return _Self(GT::getEntryNode(G), S); + static df_iterator begin(const GraphT &G, SetType &S) { + return df_iterator(GT::getEntryNode(G), S); } - static inline _Self end(const GraphT& G, SetType &S) { return _Self(S); } + static df_iterator end(const GraphT &G, SetType &S) { return df_iterator(S); } - inline bool operator==(const _Self& x) const { + bool operator==(const df_iterator &x) const { return VisitStack == x.VisitStack; } - inline bool operator!=(const _Self& x) const { return !operator==(x); } + bool operator!=(const df_iterator &x) const { return !(*this == x); } - inline pointer operator*() const { - return VisitStack.back().first.getPointer(); - } + pointer operator*() const { return VisitStack.back().first.getPointer(); } // This is a nonstandard operator-> that dereferences the pointer an extra // time... so that you can actually call methods ON the Node, because // the contained type is a pointer. This allows BBIt->getTerminator() f.e. // - inline NodeType *operator->() const { return operator*(); } + NodeType *operator->() const { return **this; } - inline _Self& operator++() { // Preincrement + df_iterator &operator++() { // Preincrement toNext(); return *this; } // skips all children of the current node and traverses to next node // - inline _Self& skipChildren() { + df_iterator &skipChildren() { VisitStack.pop_back(); if (!VisitStack.empty()) toNext(); return *this; } - inline _Self operator++(int) { // Postincrement - _Self tmp = *this; ++*this; return tmp; + df_iterator operator++(int) { // Postincrement + df_iterator tmp = *this; + ++*this; + return tmp; } // nodeVisited - return true if this iterator has already visited the // specified node. This is public, and will probably be used to iterate over // nodes that a depth first iteration did not find: ie unreachable nodes. // - inline bool nodeVisited(NodeType *Node) const { + bool nodeVisited(NodeType *Node) const { return this->Visited.count(Node) != 0; } diff --git a/include/llvm/ADT/EpochTracker.h b/include/llvm/ADT/EpochTracker.h new file mode 100644 index 0000000..d593073 --- /dev/null +++ b/include/llvm/ADT/EpochTracker.h @@ -0,0 +1,99 @@ +//===- llvm/ADT/EpochTracker.h - ADT epoch tracking --------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the DebugEpochBase and DebugEpochBase::HandleBase classes. +// These can be used to write iterators that are fail-fast when LLVM is built +// with asserts enabled. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_EPOCH_TRACKER_H +#define LLVM_ADT_EPOCH_TRACKER_H + +#include "llvm/Config/llvm-config.h" + +#include <cstdint> + +namespace llvm { + +#ifndef LLVM_ENABLE_ABI_BREAKING_CHECKS + +class DebugEpochBase { +public: + void incrementEpoch() {} + + class HandleBase { + public: + HandleBase() {} + explicit HandleBase(const DebugEpochBase *) {} + bool isHandleInSync() const { return true; } + const void *getEpochAddress() const { return nullptr; } + }; +}; + +#else + +/// \brief A base class for data structure classes wishing to make iterators +/// ("handles") pointing into themselves fail-fast. When building without +/// asserts, this class is empty and does nothing. +/// +/// DebugEpochBase does not by itself track handles pointing into itself. The +/// expectation is that routines touching the handles will poll on +/// isHandleInSync at appropriate points to assert that the handle they're using +/// is still valid. +/// +class DebugEpochBase { + uint64_t Epoch; + +public: + DebugEpochBase() : Epoch(0) {} + + /// \brief Calling incrementEpoch invalidates all handles pointing into the + /// calling instance. + void incrementEpoch() { ++Epoch; } + + /// \brief The destructor calls incrementEpoch to make use-after-free bugs + /// more likely to crash deterministically. + ~DebugEpochBase() { incrementEpoch(); } + + /// \brief A base class for iterator classes ("handles") that wish to poll for + /// iterator invalidating modifications in the underlying data structure. + /// When LLVM is built without asserts, this class is empty and does nothing. + /// + /// HandleBase does not track the parent data structure by itself. It expects + /// the routines modifying the data structure to call incrementEpoch when they + /// make an iterator-invalidating modification. + /// + class HandleBase { + const uint64_t *EpochAddress; + uint64_t EpochAtCreation; + + public: + HandleBase() : EpochAddress(nullptr), EpochAtCreation(UINT64_MAX) {} + + explicit HandleBase(const DebugEpochBase *Parent) + : EpochAddress(&Parent->Epoch), EpochAtCreation(Parent->Epoch) {} + + /// \brief Returns true if the DebugEpochBase this Handle is linked to has + /// not called incrementEpoch on itself since the creation of this + /// HandleBase instance. + bool isHandleInSync() const { return *EpochAddress == EpochAtCreation; } + + /// \brief Returns a pointer to the epoch word stored in the data structure + /// this handle points into. Can be used to check if two iterators point + /// into the same data structure. + const void *getEpochAddress() const { return EpochAddress; } + }; +}; + +#endif // LLVM_ENABLE_ABI_BREAKING_CHECKS + +} // namespace llvm + +#endif diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index 7ade167..52d10c1 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -23,9 +23,6 @@ #include "llvm/Support/DataTypes.h" namespace llvm { - class APFloat; - class APInt; - /// This folding set used for two purposes: /// 1. Given information about a node we want to create, look up the unique /// instance of the node in the set. If the node already exists, return @@ -110,6 +107,8 @@ class FoldingSetNodeID; /// back to the bucket to facilitate node removal. /// class FoldingSetImpl { + virtual void anchor(); // Out of line virtual method. + protected: /// Buckets - Array of bucket chains. /// @@ -123,10 +122,11 @@ protected: /// is greater than twice the number of buckets. unsigned NumNodes; -public: + ~FoldingSetImpl(); + explicit FoldingSetImpl(unsigned Log2InitSize = 6); - virtual ~FoldingSetImpl(); +public: //===--------------------------------------------------------------------===// /// Node - This class is used to maintain the singly linked bucket list in /// a folding set. @@ -393,7 +393,7 @@ DefaultContextualFoldingSetTrait<T, Ctx>::ComputeHash(T &X, /// implementation of the folding set to the node class T. T must be a /// subclass of FoldingSetNode and implement a Profile function. /// -template<class T> class FoldingSet : public FoldingSetImpl { +template <class T> class FoldingSet final : public FoldingSetImpl { private: /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a /// way to convert nodes into a unique specifier. @@ -463,7 +463,7 @@ public: /// function with signature /// void Profile(llvm::FoldingSetNodeID &, Ctx); template <class T, class Ctx> -class ContextualFoldingSet : public FoldingSetImpl { +class ContextualFoldingSet final : public FoldingSetImpl { // Unfortunately, this can't derive from FoldingSet<T> because the // construction vtable for FoldingSet<T> requires // FoldingSet<T>::GetNodeProfile to be instantiated, which in turn diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h index 75fee90..438dec2 100644 --- a/include/llvm/ADT/ImmutableMap.h +++ b/include/llvm/ADT/ImmutableMap.h @@ -203,33 +203,14 @@ public: // Iterators. //===--------------------------------------------------===// - class iterator { - typename TreeTy::iterator itr; - - iterator() {} - iterator(TreeTy* t) : itr(t) {} + class iterator : public ImutAVLValueIterator<ImmutableMap> { + iterator() = default; + explicit iterator(TreeTy *Tree) : iterator::ImutAVLValueIterator(Tree) {} friend class ImmutableMap; public: - typedef ptrdiff_t difference_type; - typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type value_type; - typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type_ref reference; - typedef typename iterator::value_type *pointer; - typedef std::bidirectional_iterator_tag iterator_category; - - typename iterator::reference operator*() const { return itr->getValue(); } - typename iterator::pointer 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; } + key_type_ref getKey() const { return (*this)->first; } + data_type_ref getData() const { return (*this)->second; } }; iterator begin() const { return iterator(Root); } @@ -376,30 +357,17 @@ public: //===--------------------------------------------------===// // Iterators. //===--------------------------------------------------===// - - class iterator { - typename TreeTy::iterator itr; - - iterator() {} - iterator(TreeTy* t) : itr(t) {} + + class iterator : public ImutAVLValueIterator<ImmutableMapRef> { + iterator() = default; + explicit iterator(TreeTy *Tree) : iterator::ImutAVLValueIterator(Tree) {} 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; } + key_type_ref getKey() const { return (*this)->first; } + data_type_ref getData() const { return (*this)->second; } }; - + iterator begin() const { return iterator(Root); } iterator end() const { return iterator(); } diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index 3c6f58c..87026f0 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -142,13 +142,13 @@ public: iterator RItr = RHS.begin(), REnd = RHS.end(); while (LItr != LEnd && RItr != REnd) { - if (*LItr == *RItr) { + if (&*LItr == &*RItr) { LItr.skipSubTree(); RItr.skipSubTree(); continue; } - if (!LItr->isElementEqual(*RItr)) + if (!LItr->isElementEqual(&*RItr)) return false; ++LItr; @@ -293,8 +293,8 @@ private: height = h; } - static inline - uint32_t computeDigest(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) { + static uint32_t computeDigest(ImutAVLTree *L, ImutAVLTree *R, + value_type_ref V) { uint32_t digest = 0; if (L) @@ -311,7 +311,7 @@ private: return digest; } - inline uint32_t computeDigest() { + uint32_t computeDigest() { // Check the lowest bit to determine if digest has actually been // pre-computed. if (hasCachedDigest()) @@ -429,9 +429,7 @@ protected: value_type_ref getValue(TreeTy* T) const { return T->value; } // Make sure the index is not the Tombstone or Entry key of the DenseMap. - static inline unsigned maskCacheIndex(unsigned I) { - return (I & ~0x02); - } + static unsigned maskCacheIndex(unsigned I) { return (I & ~0x02); } unsigned incrementHeight(TreeTy* L, TreeTy* R) const { unsigned hl = getHeight(L); @@ -444,7 +442,7 @@ protected: typename TreeTy::iterator& TE) { typename TreeTy::iterator I = T->begin(), E = T->end(); for ( ; I!=E ; ++I, ++TI) { - if (TI == TE || !I->isElementEqual(*TI)) + if (TI == TE || !I->isElementEqual(&*TI)) return false; } return true; @@ -647,24 +645,26 @@ public: //===----------------------------------------------------------------------===// template <typename ImutInfo> -class ImutAVLTreeGenericIterator { +class ImutAVLTreeGenericIterator + : public std::iterator<std::bidirectional_iterator_tag, + ImutAVLTree<ImutInfo>> { SmallVector<uintptr_t,20> stack; public: enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3, Flags=0x3 }; typedef ImutAVLTree<ImutInfo> TreeTy; - typedef ImutAVLTreeGenericIterator<ImutInfo> _Self; - inline ImutAVLTreeGenericIterator() {} - inline ImutAVLTreeGenericIterator(const TreeTy* Root) { + ImutAVLTreeGenericIterator() {} + ImutAVLTreeGenericIterator(const TreeTy *Root) { if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root)); } - TreeTy* operator*() const { + TreeTy &operator*() const { assert(!stack.empty()); - return reinterpret_cast<TreeTy*>(stack.back() & ~Flags); + return *reinterpret_cast<TreeTy *>(stack.back() & ~Flags); } + TreeTy *operator->() const { return &*this; } uintptr_t getVisitState() const { assert(!stack.empty()); @@ -695,13 +695,15 @@ public: } } - inline bool operator==(const _Self& x) const { + bool operator==(const ImutAVLTreeGenericIterator &x) const { return stack == x.stack; } - inline bool operator!=(const _Self& x) const { return !operator==(x); } + bool operator!=(const ImutAVLTreeGenericIterator &x) const { + return !(*this == x); + } - _Self& operator++() { + ImutAVLTreeGenericIterator &operator++() { assert(!stack.empty()); TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags); assert(Current); @@ -727,7 +729,7 @@ public: return *this; } - _Self& operator--() { + ImutAVLTreeGenericIterator &operator--() { assert(!stack.empty()); TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags); assert(Current); @@ -754,30 +756,34 @@ public: }; template <typename ImutInfo> -class ImutAVLTreeInOrderIterator { +class ImutAVLTreeInOrderIterator + : public std::iterator<std::bidirectional_iterator_tag, + ImutAVLTree<ImutInfo>> { typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy; InternalIteratorTy InternalItr; public: typedef ImutAVLTree<ImutInfo> TreeTy; - typedef ImutAVLTreeInOrderIterator<ImutInfo> _Self; ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) { - if (Root) operator++(); // Advance to first element. + if (Root) + ++*this; // Advance to first element. } ImutAVLTreeInOrderIterator() : InternalItr() {} - inline bool operator==(const _Self& x) const { + bool operator==(const ImutAVLTreeInOrderIterator &x) const { return InternalItr == x.InternalItr; } - inline bool operator!=(const _Self& x) const { return !operator==(x); } + bool operator!=(const ImutAVLTreeInOrderIterator &x) const { + return !(*this == x); + } - inline TreeTy* operator*() const { return *InternalItr; } - inline TreeTy* operator->() const { return *InternalItr; } + TreeTy &operator*() const { return *InternalItr; } + TreeTy *operator->() const { return &*InternalItr; } - inline _Self& operator++() { + ImutAVLTreeInOrderIterator &operator++() { do ++InternalItr; while (!InternalItr.atEnd() && InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft); @@ -785,7 +791,7 @@ public: return *this; } - inline _Self& operator--() { + ImutAVLTreeInOrderIterator &operator--() { do --InternalItr; while (!InternalItr.atBeginning() && InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft); @@ -793,7 +799,7 @@ public: return *this; } - inline void skipSubTree() { + void skipSubTree() { InternalItr.skipToParent(); while (!InternalItr.atEnd() && @@ -802,6 +808,24 @@ public: } }; +/// Generic iterator that wraps a T::TreeTy::iterator and exposes +/// iterator::getValue() on dereference. +template <typename T> +struct ImutAVLValueIterator + : iterator_adaptor_base< + ImutAVLValueIterator<T>, typename T::TreeTy::iterator, + typename std::iterator_traits< + typename T::TreeTy::iterator>::iterator_category, + const typename T::value_type> { + ImutAVLValueIterator() = default; + explicit ImutAVLValueIterator(typename T::TreeTy *Tree) + : ImutAVLValueIterator::iterator_adaptor_base(Tree) {} + + typename ImutAVLValueIterator::reference operator*() const { + return this->I->getValue(); + } +}; + //===----------------------------------------------------------------------===// // Trait classes for Profile information. //===----------------------------------------------------------------------===// @@ -814,7 +838,7 @@ struct ImutProfileInfo { typedef const T value_type; typedef const T& value_type_ref; - static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) { + static void Profile(FoldingSetNodeID &ID, value_type_ref X) { FoldingSetTrait<T>::Profile(X,ID); } }; @@ -825,7 +849,7 @@ struct ImutProfileInteger { typedef const T value_type; typedef const T& value_type_ref; - static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) { + static void Profile(FoldingSetNodeID &ID, value_type_ref X) { ID.AddInteger(X); } }; @@ -852,7 +876,7 @@ struct ImutProfileInfo<bool> { typedef const bool value_type; typedef const bool& value_type_ref; - static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) { + static void Profile(FoldingSetNodeID &ID, value_type_ref X) { ID.AddBoolean(X); } }; @@ -865,7 +889,7 @@ struct ImutProfileInfo<T*> { typedef const T* value_type; typedef value_type value_type_ref; - static inline void Profile(FoldingSetNodeID &ID, value_type_ref X) { + static void Profile(FoldingSetNodeID &ID, value_type_ref X) { ID.AddPointer(X); } }; @@ -890,18 +914,18 @@ struct ImutContainerInfo : public ImutProfileInfo<T> { typedef bool data_type; typedef bool data_type_ref; - static inline key_type_ref KeyOfValue(value_type_ref D) { return D; } - static inline data_type_ref DataOfValue(value_type_ref) { return true; } + static key_type_ref KeyOfValue(value_type_ref D) { return D; } + static data_type_ref DataOfValue(value_type_ref) { return true; } - static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) { + static bool isEqual(key_type_ref LHS, key_type_ref RHS) { return std::equal_to<key_type>()(LHS,RHS); } - static inline bool isLess(key_type_ref LHS, key_type_ref RHS) { + static bool isLess(key_type_ref LHS, key_type_ref RHS) { return std::less<key_type>()(LHS,RHS); } - static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; } + static bool isDataEqual(data_type_ref, data_type_ref) { return true; } }; /// ImutContainerInfo - Specialization for pointer values to treat pointers @@ -916,18 +940,14 @@ struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> { typedef bool data_type; typedef bool data_type_ref; - static inline key_type_ref KeyOfValue(value_type_ref D) { return D; } - static inline data_type_ref DataOfValue(value_type_ref) { return true; } + static key_type_ref KeyOfValue(value_type_ref D) { return D; } + static data_type_ref DataOfValue(value_type_ref) { return true; } - static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) { - return LHS == RHS; - } + static bool isEqual(key_type_ref LHS, key_type_ref RHS) { return LHS == RHS; } - static inline bool isLess(key_type_ref LHS, key_type_ref RHS) { - return LHS < RHS; - } + static bool isLess(key_type_ref LHS, key_type_ref RHS) { return LHS < RHS; } - static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; } + static bool isDataEqual(data_type_ref, data_type_ref) { return true; } }; //===----------------------------------------------------------------------===// @@ -1059,31 +1079,7 @@ public: // Iterators. //===--------------------------------------------------===// - class iterator { - typename TreeTy::iterator itr; - - iterator() {} - iterator(TreeTy* t) : itr(t) {} - friend class ImmutableSet<ValT,ValInfo>; - - public: - typedef ptrdiff_t difference_type; - typedef typename ImmutableSet<ValT,ValInfo>::value_type value_type; - typedef typename ImmutableSet<ValT,ValInfo>::value_type_ref reference; - typedef typename iterator::value_type *pointer; - typedef std::bidirectional_iterator_tag iterator_category; - - typename iterator::reference operator*() const { return itr->getValue(); } - typename iterator::pointer operator->() const { return &(operator*()); } - - 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; } - }; + typedef ImutAVLValueIterator<ImmutableSet> iterator; iterator begin() const { return iterator(Root); } iterator end() const { return iterator(); } @@ -1094,13 +1090,11 @@ public: unsigned getHeight() const { return Root ? Root->getHeight() : 0; } - static inline void Profile(FoldingSetNodeID& ID, const ImmutableSet& S) { + static void Profile(FoldingSetNodeID &ID, const ImmutableSet &S) { ID.AddPointer(S.Root); } - inline void Profile(FoldingSetNodeID& ID) const { - return Profile(ID,*this); - } + void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); } //===--------------------------------------------------===// // For testing. @@ -1150,7 +1144,7 @@ public: if (Root) { Root->release(); } } - static inline ImmutableSetRef getEmptySet(FactoryTy *F) { + static ImmutableSetRef getEmptySet(FactoryTy *F) { return ImmutableSetRef(0, F); } @@ -1195,21 +1189,7 @@ public: // 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*()); } - }; + typedef ImutAVLValueIterator<ImmutableSetRef> iterator; iterator begin() const { return iterator(Root); } iterator end() const { return iterator(); } @@ -1220,13 +1200,11 @@ public: unsigned getHeight() const { return Root ? Root->getHeight() : 0; } - static inline void Profile(FoldingSetNodeID& ID, const ImmutableSetRef& S) { + static void Profile(FoldingSetNodeID &ID, const ImmutableSetRef &S) { ID.AddPointer(S.Root); } - inline void Profile(FoldingSetNodeID& ID) const { - return Profile(ID,*this); - } + void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); } //===--------------------------------------------------===// // For testing. diff --git a/include/llvm/ADT/IndexedMap.h b/include/llvm/ADT/IndexedMap.h index 2ffb505..5ba85c0 100644 --- a/include/llvm/ADT/IndexedMap.h +++ b/include/llvm/ADT/IndexedMap.h @@ -21,16 +21,19 @@ #define LLVM_ADT_INDEXEDMAP_H #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include <cassert> #include <functional> -#include <vector> namespace llvm { template <typename T, typename ToIndexT = llvm::identity<unsigned> > class IndexedMap { typedef typename ToIndexT::argument_type IndexT; - typedef std::vector<T> StorageT; + // Prefer SmallVector with zero inline storage over std::vector. IndexedMaps + // can grow very large and SmallVector grows more efficiently as long as T + // is trivially copyable. + typedef SmallVector<T, 0> StorageT; StorageT storage_; T nullVal_; ToIndexT toIndex_; diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h index 99be38f..f8843b2 100644 --- a/include/llvm/ADT/IntervalMap.h +++ b/include/llvm/ADT/IntervalMap.h @@ -101,6 +101,7 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/AlignOf.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/RecyclingAllocator.h" #include <iterator> @@ -953,11 +954,6 @@ class IntervalMap { RootBranch node; }; - enum { - RootDataSize = sizeof(RootBranchData) > sizeof(RootLeaf) ? - sizeof(RootBranchData) : sizeof(RootLeaf) - }; - public: typedef typename Sizer::Allocator Allocator; typedef KeyT KeyType; @@ -966,13 +962,7 @@ public: private: // The root data is either a RootLeaf or a RootBranchData instance. - // We can't put them in a union since C++03 doesn't allow non-trivial - // constructors in unions. - // Instead, we use a char array with pointer alignment. The alignment is - // ensured by the allocator member in the class, but still verified in the - // constructor. We don't support keys or values that are more aligned than a - // pointer. - char data[RootDataSize]; + AlignedCharArrayUnion<RootLeaf, RootBranchData> data; // Tree height. // 0: Leaves in root. @@ -993,7 +983,7 @@ private: const char *d; T *t; } u; - u.d = data; + u.d = data.buffer; return *u.t; } @@ -1051,7 +1041,7 @@ private: public: explicit IntervalMap(Allocator &a) : height(0), rootSize(0), allocator(a) { - assert((uintptr_t(data) & (alignOf<RootLeaf>() - 1)) == 0 && + assert((uintptr_t(data.buffer) & (alignOf<RootLeaf>() - 1)) == 0 && "Insufficient alignment"); new(&rootLeaf()) RootLeaf(); } diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h index 9b12d04..65b2da7 100644 --- a/include/llvm/ADT/IntrusiveRefCntPtr.h +++ b/include/llvm/ADT/IntrusiveRefCntPtr.h @@ -21,10 +21,9 @@ #ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H #define LLVM_ADT_INTRUSIVEREFCNTPTR_H -#include "llvm/Support/Casting.h" -#include "llvm/Support/Compiler.h" #include <atomic> -#include <memory> +#include <cassert> +#include <cstddef> namespace llvm { @@ -268,6 +267,8 @@ public: // LLVM-style downcasting support for IntrusiveRefCntPtr objects //===----------------------------------------------------------------------===// + template <typename From> struct simplify_type; + template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > { typedef T* SimpleType; static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T>& Val) { diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h index 1331b15..f19a50b 100644 --- a/include/llvm/ADT/MapVector.h +++ b/include/llvm/ADT/MapVector.h @@ -67,6 +67,11 @@ public: Vector.clear(); } + void swap(MapVector &RHS) { + std::swap(Map, RHS.Map); + std::swap(Vector, RHS.Vector); + } + ValueT &operator[](const KeyT &Key) { std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0); std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair); diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h index dfadc3b..fa337e9 100644 --- a/include/llvm/ADT/PostOrderIterator.h +++ b/include/llvm/ADT/PostOrderIterator.h @@ -111,53 +111,52 @@ class po_iterator : public std::iterator<std::forward_iterator_tag, } } - inline po_iterator(NodeType *BB) { + po_iterator(NodeType *BB) { this->insertEdge((NodeType*)nullptr, BB); VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB))); traverseChild(); } - inline po_iterator() {} // End is when stack is empty. + po_iterator() {} // End is when stack is empty. - inline po_iterator(NodeType *BB, SetType &S) : - po_iterator_storage<SetType, ExtStorage>(S) { + po_iterator(NodeType *BB, SetType &S) + : po_iterator_storage<SetType, ExtStorage>(S) { if (this->insertEdge((NodeType*)nullptr, BB)) { VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB))); traverseChild(); } } - inline po_iterator(SetType &S) : - po_iterator_storage<SetType, ExtStorage>(S) { + po_iterator(SetType &S) + : po_iterator_storage<SetType, ExtStorage>(S) { } // End is when stack is empty. public: typedef typename super::pointer pointer; - typedef po_iterator<GraphT, SetType, ExtStorage, GT> _Self; // Provide static "constructors"... - static inline _Self begin(GraphT G) { return _Self(GT::getEntryNode(G)); } - static inline _Self end (GraphT G) { return _Self(); } + static po_iterator begin(GraphT G) { + return po_iterator(GT::getEntryNode(G)); + } + static po_iterator end(GraphT G) { return po_iterator(); } - static inline _Self begin(GraphT G, SetType &S) { - return _Self(GT::getEntryNode(G), S); + static po_iterator begin(GraphT G, SetType &S) { + return po_iterator(GT::getEntryNode(G), S); } - static inline _Self end (GraphT G, SetType &S) { return _Self(S); } + static po_iterator end(GraphT G, SetType &S) { return po_iterator(S); } - inline bool operator==(const _Self& x) const { + bool operator==(const po_iterator &x) const { return VisitStack == x.VisitStack; } - inline bool operator!=(const _Self& x) const { return !operator==(x); } + bool operator!=(const po_iterator &x) const { return !(*this == x); } - inline pointer operator*() const { - return VisitStack.back().first; - } + pointer operator*() const { return VisitStack.back().first; } // This is a nonstandard operator-> that dereferences the pointer an extra // time... so that you can actually call methods ON the BasicBlock, because // the contained type is a pointer. This allows BBIt->getTerminator() f.e. // - inline NodeType *operator->() const { return operator*(); } + NodeType *operator->() const { return **this; } - inline _Self& operator++() { // Preincrement + po_iterator &operator++() { // Preincrement this->finishPostorder(VisitStack.back().first); VisitStack.pop_back(); if (!VisitStack.empty()) @@ -165,8 +164,10 @@ public: return *this; } - inline _Self operator++(int) { // Postincrement - _Self tmp = *this; ++*this; return tmp; + po_iterator operator++(int) { // Postincrement + po_iterator tmp = *this; + ++*this; + return tmp; } }; @@ -260,19 +261,17 @@ template<class GraphT, class GT = GraphTraits<GraphT> > class ReversePostOrderTraversal { typedef typename GT::NodeType NodeType; std::vector<NodeType*> Blocks; // Block list in normal PO order - inline void Initialize(NodeType *BB) { + void Initialize(NodeType *BB) { std::copy(po_begin(BB), po_end(BB), std::back_inserter(Blocks)); } public: typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator; - inline ReversePostOrderTraversal(GraphT G) { - Initialize(GT::getEntryNode(G)); - } + ReversePostOrderTraversal(GraphT G) { Initialize(GT::getEntryNode(G)); } // Because we want a reverse post order, use reverse iterators from the vector - inline rpo_iterator begin() { return Blocks.rbegin(); } - inline rpo_iterator end() { return Blocks.rend(); } + rpo_iterator begin() { return Blocks.rbegin(); } + rpo_iterator end() { return Blocks.rend(); } }; } // End llvm namespace diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index 57af18e..921bd82 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -123,7 +123,6 @@ public: typedef void reference; // Can't modify value returned by fn typedef RootIt iterator_type; - typedef mapped_iterator<RootIt, UnaryFunc> _Self; inline const RootIt &getCurrent() const { return current; } inline const UnaryFunc &getFunc() const { return Fn; } @@ -135,34 +134,56 @@ public: return Fn(*current); // little change } - _Self& operator++() { ++current; return *this; } - _Self& operator--() { --current; return *this; } - _Self operator++(int) { _Self __tmp = *this; ++current; return __tmp; } - _Self operator--(int) { _Self __tmp = *this; --current; return __tmp; } - _Self operator+ (difference_type n) const { - return _Self(current + n, Fn); + mapped_iterator &operator++() { + ++current; + return *this; } - _Self& operator+= (difference_type n) { current += n; return *this; } - _Self operator- (difference_type n) const { - return _Self(current - n, Fn); + mapped_iterator &operator--() { + --current; + return *this; + } + mapped_iterator operator++(int) { + mapped_iterator __tmp = *this; + ++current; + return __tmp; + } + mapped_iterator operator--(int) { + mapped_iterator __tmp = *this; + --current; + return __tmp; + } + mapped_iterator operator+(difference_type n) const { + return mapped_iterator(current + n, Fn); + } + mapped_iterator &operator+=(difference_type n) { + current += n; + return *this; + } + mapped_iterator operator-(difference_type n) const { + return mapped_iterator(current - n, Fn); + } + mapped_iterator &operator-=(difference_type n) { + current -= n; + return *this; } - _Self& operator-= (difference_type n) { current -= n; return *this; } reference operator[](difference_type n) const { return *(*this + n); } - inline bool operator!=(const _Self &X) const { return !operator==(X); } - inline bool operator==(const _Self &X) const { return current == X.current; } - inline bool operator< (const _Self &X) const { return current < X.current; } + bool operator!=(const mapped_iterator &X) const { return !operator==(X); } + bool operator==(const mapped_iterator &X) const { + return current == X.current; + } + bool operator<(const mapped_iterator &X) const { return current < X.current; } - inline difference_type operator-(const _Self &X) const { + difference_type operator-(const mapped_iterator &X) const { return current - X.current; } }; -template <class _Iterator, class Func> -inline mapped_iterator<_Iterator, Func> -operator+(typename mapped_iterator<_Iterator, Func>::difference_type N, - const mapped_iterator<_Iterator, Func>& X) { - return mapped_iterator<_Iterator, Func>(X.getCurrent() - N, X.getFunc()); +template <class Iterator, class Func> +inline mapped_iterator<Iterator, Func> +operator+(typename mapped_iterator<Iterator, Func>::difference_type N, + const mapped_iterator<Iterator, Func> &X) { + return mapped_iterator<Iterator, Func>(X.getCurrent() - N, X.getFunc()); } @@ -263,10 +284,11 @@ inline int (*get_array_pod_sort_comparator(const T &)) /// default to std::less. template<class IteratorTy> inline void array_pod_sort(IteratorTy Start, IteratorTy End) { - // Don't dereference start iterator of empty sequence. - if (Start == End) return; - qsort(&*Start, End-Start, sizeof(*Start), - get_array_pod_sort_comparator(*Start)); + // Don't inefficiently call qsort with one element or trigger undefined + // behavior with an empty sequence. + auto NElts = End - Start; + if (NElts <= 1) return; + qsort(&*Start, NElts, sizeof(*Start), get_array_pod_sort_comparator(*Start)); } template <class IteratorTy> @@ -275,9 +297,11 @@ inline void array_pod_sort( int (*Compare)( const typename std::iterator_traits<IteratorTy>::value_type *, const typename std::iterator_traits<IteratorTy>::value_type *)) { - // Don't dereference start iterator of empty sequence. - if (Start == End) return; - qsort(&*Start, End - Start, sizeof(*Start), + // Don't inefficiently call qsort with one element or trigger undefined + // behavior with an empty sequence. + auto NElts = End - Start; + if (NElts <= 1) return; + qsort(&*Start, NElts, sizeof(*Start), reinterpret_cast<int (*)(const void *, const void *)>(Compare)); } diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index 22e8ccd..ae3d645 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -66,6 +66,8 @@ public: public: reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {} + reference(const reference&) = default; + reference& operator=(reference t) { *this = bool(t); return *this; diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 14e2c7b..5b208b7 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -24,6 +24,7 @@ #include <cstddef> #include <cstdlib> #include <cstring> +#include <initializer_list> #include <iterator> #include <memory> @@ -432,6 +433,10 @@ public: this->setEnd(this->end() + NumInputs); } + void append(std::initializer_list<T> IL) { + append(IL.begin(), IL.end()); + } + void assign(size_type NumElts, const T &Elt) { clear(); if (this->capacity() < NumElts) @@ -440,6 +445,11 @@ public: std::uninitialized_fill(this->begin(), this->end(), Elt); } + void assign(std::initializer_list<T> IL) { + clear(); + append(IL); + } + iterator erase(iterator I) { assert(I >= this->begin() && "Iterator to erase is out of bounds."); assert(I < this->end() && "Erasing at past-the-end iterator."); @@ -633,6 +643,10 @@ public: return I; } + void insert(iterator I, std::initializer_list<T> IL) { + insert(I, IL.begin(), IL.end()); + } + template <typename... ArgTypes> void emplace_back(ArgTypes &&... Args) { if (LLVM_UNLIKELY(this->EndX >= this->CapacityX)) this->grow(); @@ -865,6 +879,10 @@ public: this->append(R.begin(), R.end()); } + SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) { + this->assign(IL); + } + SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) { if (!RHS.empty()) SmallVectorImpl<T>::operator=(RHS); @@ -895,6 +913,10 @@ public: return *this; } + const SmallVector &operator=(std::initializer_list<T> IL) { + this->assign(IL); + return *this; + } }; template<typename T, unsigned N> diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index 6111c42..95660a4 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -238,9 +238,12 @@ namespace llvm { /// \returns The index of the first occurrence of \p C, or npos if not /// found. size_t find(char C, size_t From = 0) const { - for (size_t i = std::min(From, Length), e = Length; i != e; ++i) - if (Data[i] == C) - return i; + size_t FindBegin = std::min(From, Length); + if (FindBegin < Length) { // Avoid calling memchr with nullptr. + // Just forward to memchr, which is faster than a hand-rolled loop. + if (const void *P = ::memchr(Data + FindBegin, C, Length - FindBegin)) + return static_cast<const char *>(P) - Data; + } return npos; } diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 886f6fb..5fda775 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -86,6 +86,7 @@ public: enum SubArchType { NoSubArch, + ARMSubArch_v8_1a, ARMSubArch_v8, ARMSubArch_v7, ARMSubArch_v7em, @@ -93,6 +94,7 @@ public: ARMSubArch_v7s, ARMSubArch_v6, ARMSubArch_v6m, + ARMSubArch_v6k, ARMSubArch_v6t2, ARMSubArch_v5, ARMSubArch_v5te, @@ -120,6 +122,7 @@ public: enum OSType { UnknownOS, + CloudABI, Darwin, DragonFly, FreeBSD, diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h index 9e9a4e1..51bb18d 100644 --- a/include/llvm/ADT/Twine.h +++ b/include/llvm/ADT/Twine.h @@ -10,6 +10,7 @@ #ifndef LLVM_ADT_TWINE_H #define LLVM_ADT_TWINE_H +#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" @@ -17,9 +18,6 @@ #include <string> namespace llvm { - template <typename T> - class SmallVectorImpl; - class StringRef; class raw_ostream; /// Twine - A lightweight data structure for efficiently representing the @@ -100,6 +98,9 @@ namespace llvm { /// A pointer to a StringRef instance. StringRefKind, + /// A pointer to a SmallString instance. + SmallStringKind, + /// A char value reinterpreted as a pointer, to render as a character. CharKind, @@ -136,6 +137,7 @@ namespace llvm { const char *cString; const std::string *stdString; const StringRef *stringRef; + const SmallVectorImpl<char> *smallString;
char character; unsigned int decUI; int decI; @@ -166,17 +168,16 @@ namespace llvm { } /// Construct a binary twine. - explicit Twine(const Twine &_LHS, const Twine &_RHS) - : LHSKind(TwineKind), RHSKind(TwineKind) { - LHS.twine = &_LHS; - RHS.twine = &_RHS; + explicit Twine(const Twine &LHS, const Twine &RHS) + : LHSKind(TwineKind), RHSKind(TwineKind) { + this->LHS.twine = &LHS; + this->RHS.twine = &RHS; assert(isValid() && "Invalid twine!"); } /// Construct a twine from explicit values. - explicit Twine(Child _LHS, NodeKind _LHSKind, - Child _RHS, NodeKind _RHSKind) - : LHS(_LHS), RHS(_RHS), LHSKind(_LHSKind), RHSKind(_RHSKind) { + explicit Twine(Child LHS, NodeKind LHSKind, Child RHS, NodeKind RHSKind) + : LHS(LHS), RHS(RHS), LHSKind(LHSKind), RHSKind(RHSKind) { assert(isValid() && "Invalid twine!"); } @@ -184,32 +185,32 @@ namespace llvm { /// when concatenating might cause undefined behavior or stack corruptions Twine &operator=(const Twine &Other) = delete; - /// isNull - Check for the null twine. + /// Check for the null twine. bool isNull() const { return getLHSKind() == NullKind; } - /// isEmpty - Check for the empty twine. + /// Check for the empty twine. bool isEmpty() const { return getLHSKind() == EmptyKind; } - /// isNullary - Check if this is a nullary twine (null or empty). + /// Check if this is a nullary twine (null or empty). bool isNullary() const { return isNull() || isEmpty(); } - /// isUnary - Check if this is a unary twine. + /// Check if this is a unary twine. bool isUnary() const { return getRHSKind() == EmptyKind && !isNullary(); } - /// isBinary - Check if this is a binary twine. + /// Check if this is a binary twine. bool isBinary() const { return getLHSKind() != NullKind && getRHSKind() != EmptyKind; } - /// isValid - Check if this is a valid twine (satisfying the invariants on + /// Check if this is a valid twine (satisfying the invariants on /// order and number of arguments). bool isValid() const { // Nullary twines always have Empty on the RHS. @@ -235,16 +236,16 @@ namespace llvm { return true; } - /// getLHSKind - Get the NodeKind of the left-hand side. + /// Get the NodeKind of the left-hand side. NodeKind getLHSKind() const { return LHSKind; } - /// getRHSKind - Get the NodeKind of the right-hand side. + /// Get the NodeKind of the right-hand side. NodeKind getRHSKind() const { return RHSKind; } - /// printOneChild - Print one child from a twine. + /// Print one child from a twine. void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const; - /// printOneChildRepr - Print the representation of one child from a twine. + /// Print the representation of one child from a twine. void printOneChildRepr(raw_ostream &OS, Child Ptr, NodeKind Kind) const; @@ -257,6 +258,8 @@ namespace llvm { assert(isValid() && "Invalid twine!"); } + Twine(const Twine &) = default; + /// Construct from a C string. /// /// We take care here to optimize "" into the empty twine -- this will be @@ -287,6 +290,13 @@ namespace llvm { assert(isValid() && "Invalid twine!"); } + /// Construct from a SmallString. + /*implicit*/ Twine(const SmallVectorImpl<char> &Str) + : LHSKind(SmallStringKind), RHSKind(EmptyKind) { + LHS.smallString = &Str; + assert(isValid() && "Invalid twine!"); + } + /// Construct from a char. explicit Twine(char Val) : LHSKind(CharKind), RHSKind(EmptyKind) { @@ -347,18 +357,18 @@ namespace llvm { // right thing. Yet. /// Construct as the concatenation of a C string and a StringRef. - /*implicit*/ Twine(const char *_LHS, const StringRef &_RHS) - : LHSKind(CStringKind), RHSKind(StringRefKind) { - LHS.cString = _LHS; - RHS.stringRef = &_RHS; + /*implicit*/ Twine(const char *LHS, const StringRef &RHS) + : LHSKind(CStringKind), RHSKind(StringRefKind) { + this->LHS.cString = LHS; + this->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) - : LHSKind(StringRefKind), RHSKind(CStringKind) { - LHS.stringRef = &_LHS; - RHS.cString = _RHS; + /*implicit*/ Twine(const StringRef &LHS, const char *RHS) + : LHSKind(StringRefKind), RHSKind(CStringKind) { + this->LHS.stringRef = &LHS; + this->RHS.cString = RHS; assert(isValid() && "Invalid twine!"); } @@ -384,14 +394,14 @@ namespace llvm { /// @name Predicate Operations /// @{ - /// isTriviallyEmpty - Check if this twine is trivially empty; a false - /// return value does not necessarily mean the twine is empty. + /// Check if this twine is trivially empty; a false return value does not + /// necessarily mean the twine is empty. bool isTriviallyEmpty() const { return isNullary(); } - /// isSingleStringRef - Return true if this twine can be dynamically - /// accessed as a single StringRef value with getSingleStringRef(). + /// Return true if this twine can be dynamically accessed as a single + /// StringRef value with getSingleStringRef(). bool isSingleStringRef() const { if (getRHSKind() != EmptyKind) return false; @@ -400,6 +410,7 @@ namespace llvm { case CStringKind: case StdStringKind: case StringRefKind: + case SmallStringKind:
return true; default: return false; @@ -416,15 +427,14 @@ namespace llvm { /// @name Output & Conversion. /// @{ - /// str - Return the twine contents as a std::string. + /// Return the twine contents as a std::string. std::string str() const; - /// toVector - Write the concatenated string into the given SmallString or - /// SmallVector. + /// Write the concatenated string into the given SmallString or SmallVector. void toVector(SmallVectorImpl<char> &Out) const; - /// getSingleStringRef - This returns the twine as a single StringRef. This - /// method is only valid if isSingleStringRef() is true. + /// This returns the twine as a single StringRef. This method is only valid + /// if isSingleStringRef() is true. StringRef getSingleStringRef() const { assert(isSingleStringRef() &&"This cannot be had as a single stringref!"); switch (getLHSKind()) { @@ -433,18 +443,24 @@ namespace llvm { case CStringKind: return StringRef(LHS.cString); case StdStringKind: return StringRef(*LHS.stdString); case StringRefKind: return *LHS.stringRef; + case SmallStringKind: + return StringRef(LHS.smallString->data(), LHS.smallString->size()); } } - /// toStringRef - This returns the twine as a single StringRef if it can be + /// This returns the twine as a single StringRef if it can be /// represented as such. Otherwise the twine is written into the given /// SmallVector and a StringRef to the SmallVector's data is returned. - StringRef toStringRef(SmallVectorImpl<char> &Out) const; + StringRef toStringRef(SmallVectorImpl<char> &Out) const { + if (isSingleStringRef()) + return getSingleStringRef(); + toVector(Out); + return StringRef(Out.data(), Out.size()); + } - /// toNullTerminatedStringRef - This returns the twine as a single null - /// terminated StringRef if it can be represented as such. Otherwise the - /// twine is written into the given SmallVector and a StringRef to the - /// SmallVector's data is returned. + /// This returns the twine as a single null terminated StringRef if it + /// can be represented as such. Otherwise the twine is written into the + /// given SmallVector and a StringRef to the SmallVector's data is returned. /// /// The returned StringRef's size does not include the null terminator. StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const; diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index 763f372..43bcc34 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -68,7 +68,7 @@ protected: /// typically called by the run* methods of these subclasses. This may be /// called multiple times. /// - void InitializeAliasAnalysis(Pass *P); + void InitializeAliasAnalysis(Pass *P, const DataLayout *DL); /// getAnalysisUsage - All alias analysis implementations should invoke this /// directly (using AliasAnalysis::getAnalysisUsage(AU)). @@ -84,11 +84,6 @@ public: /// know the sizes of the potential memory references. static uint64_t const UnknownSize = ~UINT64_C(0); - /// getDataLayout - Return a pointer to the current DataLayout object, or - /// null if no DataLayout object is available. - /// - const DataLayout *getDataLayout() const { return DL; } - /// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo /// object, or null if no TargetLibraryInfo object is available. /// diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index afa7e6f..fc45903 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -192,11 +192,6 @@ public: } bool operator!=(const iterator& x) const { return !operator==(x); } - const iterator &operator=(const iterator &I) { - CurNode = I.CurNode; - return *this; - } - value_type &operator*() const { assert(CurNode && "Dereferencing AliasSet.end()!"); return *CurNode; diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h index 09d45ca..541a210 100644 --- a/include/llvm/Analysis/ConstantFolding.h +++ b/include/llvm/Analysis/ConstantFolding.h @@ -36,16 +36,15 @@ namespace llvm { /// Note that this fails if not all of the operands are constant. Otherwise, /// this function can only fail when attempting to fold instructions like loads /// and stores, which have no constant expression form. -Constant *ConstantFoldInstruction(Instruction *I, - const DataLayout *TD = nullptr, - const TargetLibraryInfo *TLI = nullptr); + Constant *ConstantFoldInstruction(Instruction *I, const DataLayout &DL, + const TargetLibraryInfo *TLI = nullptr); /// ConstantFoldConstantExpression - Attempt to fold the constant expression /// using the specified DataLayout. If successful, the constant result is /// result is returned, if not, null is returned. -Constant *ConstantFoldConstantExpression(const ConstantExpr *CE, - const DataLayout *TD = nullptr, - const TargetLibraryInfo *TLI =nullptr); + Constant * + ConstantFoldConstantExpression(const ConstantExpr *CE, const DataLayout &DL, + const TargetLibraryInfo *TLI = nullptr); /// ConstantFoldInstOperands - Attempt to constant fold an instruction with the /// specified operands. If successful, the constant result is returned, if not, @@ -53,19 +52,19 @@ Constant *ConstantFoldConstantExpression(const ConstantExpr *CE, /// fold instructions like loads and stores, which have no constant expression /// form. /// -Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy, - ArrayRef<Constant *> Ops, - const DataLayout *TD = nullptr, - const TargetLibraryInfo *TLI = nullptr); + Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy, + ArrayRef<Constant *> Ops, + const DataLayout &DL, + const TargetLibraryInfo *TLI = nullptr); /// ConstantFoldCompareInstOperands - Attempt to constant fold a compare /// instruction (icmp/fcmp) with the specified operands. If it fails, it /// returns a constant expression of the specified operands. /// -Constant *ConstantFoldCompareInstOperands(unsigned Predicate, - Constant *LHS, Constant *RHS, - const DataLayout *TD = nullptr, - const TargetLibraryInfo *TLI=nullptr); + Constant * + ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, + Constant *RHS, const DataLayout &DL, + const TargetLibraryInfo *TLI = nullptr); /// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue /// instruction with the specified operands and indices. The constant result is @@ -76,8 +75,7 @@ Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, /// ConstantFoldLoadFromConstPtr - Return the value that a load from C would /// produce if it is constant and determinable. If this is not determinable, /// return null. -Constant *ConstantFoldLoadFromConstPtr(Constant *C, - const DataLayout *TD = nullptr); +Constant *ConstantFoldLoadFromConstPtr(Constant *C, const DataLayout &DL); /// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a /// getelementptr constantexpr, return the constant value being addressed by the diff --git a/include/llvm/Analysis/ConstantsScanner.h b/include/llvm/Analysis/ConstantsScanner.h deleted file mode 100644 index d3d0a44..0000000 --- a/include/llvm/Analysis/ConstantsScanner.h +++ /dev/null @@ -1,93 +0,0 @@ -//==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This class implements an iterator to walk through the constants referenced by -// a method. This is used by the Bitcode & Assembly writers to build constant -// pools. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ANALYSIS_CONSTANTSSCANNER_H -#define LLVM_ANALYSIS_CONSTANTSSCANNER_H - -#include "llvm/IR/InstIterator.h" - -namespace llvm { - -class Constant; - -class constant_iterator : public std::iterator<std::forward_iterator_tag, - const Constant, ptrdiff_t> { - const_inst_iterator InstI; // Method instruction iterator - unsigned OpIdx; // Operand index - - typedef constant_iterator _Self; - - inline bool isAtConstant() const { - assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() && - "isAtConstant called with invalid arguments!"); - return isa<Constant>(InstI->getOperand(OpIdx)); - } - -public: - inline constant_iterator(const Function *F) : InstI(inst_begin(F)), OpIdx(0) { - // Advance to first constant... if we are not already at constant or end - if (InstI != inst_end(F) && // InstI is valid? - (InstI->getNumOperands() == 0 || !isAtConstant())) // Not at constant? - operator++(); - } - - inline constant_iterator(const Function *F, bool) // end ctor - : InstI(inst_end(F)), OpIdx(0) { - } - - inline bool operator==(const _Self& x) const { return OpIdx == x.OpIdx && - InstI == x.InstI; } - inline bool operator!=(const _Self& x) const { return !operator==(x); } - - inline pointer operator*() const { - assert(isAtConstant() && "Dereferenced an iterator at the end!"); - return cast<Constant>(InstI->getOperand(OpIdx)); - } - inline pointer operator->() const { return operator*(); } - - inline _Self& operator++() { // Preincrement implementation - ++OpIdx; - do { - unsigned NumOperands = InstI->getNumOperands(); - while (OpIdx < NumOperands && !isAtConstant()) { - ++OpIdx; - } - - if (OpIdx < NumOperands) return *this; // Found a constant! - ++InstI; - OpIdx = 0; - } while (!InstI.atEnd()); - - return *this; // At the end of the method - } - - inline _Self operator++(int) { // Postincrement - _Self tmp = *this; ++*this; return tmp; - } - - inline bool atEnd() const { return InstI.atEnd(); } -}; - -inline constant_iterator constant_begin(const Function *F) { - return constant_iterator(F); -} - -inline constant_iterator constant_end(const Function *F) { - return constant_iterator(F, true); -} - -} // End llvm namespace - -#endif diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h index e01aa54..ce0b899 100644 --- a/include/llvm/Analysis/DependenceAnalysis.h +++ b/include/llvm/Analysis/DependenceAnalysis.h @@ -217,13 +217,9 @@ namespace llvm { /// input dependences are unordered. class FullDependence : public Dependence { public: - FullDependence(Instruction *Src, - Instruction *Dst, - bool LoopIndependent, + FullDependence(Instruction *Src, Instruction *Dst, bool LoopIndependent, unsigned Levels); - ~FullDependence() { - delete[] DV; - } + ~FullDependence() { delete[] DV; } /// isLoopIndependent - Returns true if this is a loop-independent /// dependence. @@ -266,6 +262,7 @@ namespace llvm { /// if no subscript in the source or destination mention the induction /// variable associated with the loop at this level. bool isScalar(unsigned Level) const override; + private: unsigned short Levels; bool LoopIndependent; diff --git a/include/llvm/Analysis/DominanceFrontierImpl.h b/include/llvm/Analysis/DominanceFrontierImpl.h index 735bfb8..278d298 100644 --- a/include/llvm/Analysis/DominanceFrontierImpl.h +++ b/include/llvm/Analysis/DominanceFrontierImpl.h @@ -23,7 +23,6 @@ namespace llvm { -namespace { template <class BlockT> class DFCalculateWorkObject { public: @@ -37,7 +36,6 @@ public: const DomTreeNodeT *Node; const DomTreeNodeT *parentNode; }; -} template <class BlockT> void DominanceFrontierBase<BlockT>::removeBlock(BlockT *BB) { diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index d1f0370..ae9c1f5 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -122,7 +122,6 @@ class IVUsers : public LoopPass { LoopInfo *LI; DominatorTree *DT; ScalarEvolution *SE; - const DataLayout *DL; SmallPtrSet<Instruction*,16> Processed; /// IVUses - A list of all tracked IV uses of induction variable expressions diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index 1ebf981..706bd80 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -49,7 +49,7 @@ namespace llvm { /// SimplifyAddInst - Given operands for an Add, see if we can /// fold the result. If not, this returns null. Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -58,7 +58,7 @@ namespace llvm { /// SimplifySubInst - Given operands for a Sub, see if we can /// fold the result. If not, this returns null. Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -67,7 +67,7 @@ namespace llvm { /// Given operands for an FAdd, see if we can fold the result. If not, this /// returns null. Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -76,7 +76,7 @@ namespace llvm { /// Given operands for an FSub, see if we can fold the result. If not, this /// returns null. Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -85,7 +85,7 @@ namespace llvm { /// Given operands for an FMul, see if we can fold the result. If not, this /// returns null. Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -93,7 +93,7 @@ namespace llvm { /// SimplifyMulInst - Given operands for a Mul, see if we can /// fold the result. If not, this returns null. - Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr, + Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -101,8 +101,7 @@ namespace llvm { /// SimplifySDivInst - Given operands for an SDiv, see if we can /// fold the result. If not, this returns null. - Value *SimplifySDivInst(Value *LHS, Value *RHS, - const DataLayout *TD = nullptr, + Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -110,8 +109,7 @@ namespace llvm { /// SimplifyUDivInst - Given operands for a UDiv, see if we can /// fold the result. If not, this returns null. - Value *SimplifyUDivInst(Value *LHS, Value *RHS, - const DataLayout *TD = nullptr, + Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -120,7 +118,7 @@ namespace llvm { /// SimplifyFDivInst - Given operands for an FDiv, see if we can /// fold the result. If not, this returns null. Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -128,8 +126,7 @@ namespace llvm { /// SimplifySRemInst - Given operands for an SRem, see if we can /// fold the result. If not, this returns null. - Value *SimplifySRemInst(Value *LHS, Value *RHS, - const DataLayout *TD = nullptr, + Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -137,8 +134,7 @@ namespace llvm { /// SimplifyURemInst - Given operands for a URem, see if we can /// fold the result. If not, this returns null. - Value *SimplifyURemInst(Value *LHS, Value *RHS, - const DataLayout *TD = nullptr, + Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -147,7 +143,7 @@ namespace llvm { /// SimplifyFRemInst - Given operands for an FRem, see if we can /// fold the result. If not, this returns null. Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -156,7 +152,7 @@ namespace llvm { /// SimplifyShlInst - Given operands for a Shl, see if we can /// fold the result. If not, this returns null. Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -165,7 +161,7 @@ namespace llvm { /// SimplifyLShrInst - Given operands for a LShr, see if we can /// fold the result. If not, this returns null. Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -174,7 +170,7 @@ namespace llvm { /// SimplifyAShrInst - Given operands for a AShr, see if we can /// fold the result. If not, this returns null. Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -182,7 +178,7 @@ namespace llvm { /// SimplifyAndInst - Given operands for an And, see if we can /// fold the result. If not, this returns null. - Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr, + Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -190,7 +186,7 @@ namespace llvm { /// SimplifyOrInst - Given operands for an Or, see if we can /// fold the result. If not, this returns null. - Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr, + Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -198,7 +194,7 @@ namespace llvm { /// SimplifyXorInst - Given operands for a Xor, see if we can /// fold the result. If not, this returns null. - Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr, + Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -207,7 +203,7 @@ namespace llvm { /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -216,7 +212,7 @@ namespace llvm { /// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -225,7 +221,7 @@ namespace llvm { /// SimplifySelectInst - Given operands for a SelectInst, see if we can fold /// the result. If not, this returns null. Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -233,7 +229,7 @@ namespace llvm { /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can /// fold the result. If not, this returns null. - Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout *TD = nullptr, + Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -242,8 +238,7 @@ namespace llvm { /// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we /// can fold the result. If not, this returns null. Value *SimplifyInsertValueInst(Value *Agg, Value *Val, - ArrayRef<unsigned> Idxs, - const DataLayout *TD = nullptr, + ArrayRef<unsigned> Idxs, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -251,7 +246,7 @@ namespace llvm { /// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold /// the result. If not, this returns null. - Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout *TD = nullptr, + Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -263,7 +258,7 @@ namespace llvm { /// SimplifyCmpInst - Given operands for a CmpInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -272,7 +267,7 @@ namespace llvm { /// SimplifyBinOp - Given operands for a BinaryOperator, see if we can /// fold the result. If not, this returns null. Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, - const DataLayout *TD = nullptr, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -282,8 +277,7 @@ namespace llvm { /// In contrast to SimplifyBinOp, try to use FastMathFlag when folding the /// result. In case we don't need FastMathFlags, simply fall to SimplifyBinOp. Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS, - const FastMathFlags &FMF, - const DataLayout *TD = nullptr, + const FastMathFlags &FMF, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -294,7 +288,7 @@ namespace llvm { /// /// If this call could not be simplified returns null. Value *SimplifyCall(Value *V, User::op_iterator ArgBegin, - User::op_iterator ArgEnd, const DataLayout *TD = nullptr, + User::op_iterator ArgEnd, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -304,8 +298,7 @@ namespace llvm { /// result. /// /// If this call could not be simplified returns null. - Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, - const DataLayout *TD = nullptr, + Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -313,7 +306,7 @@ namespace llvm { /// SimplifyInstruction - See if we can compute a simplified version of this /// instruction. If not, this returns null. - Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = nullptr, + Value *SimplifyInstruction(Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr); @@ -327,7 +320,6 @@ namespace llvm { /// /// The function returns true if any simplifications were performed. bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV, - const DataLayout *TD = nullptr, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr); @@ -339,7 +331,6 @@ namespace llvm { /// of the users impacted. It returns true if any simplifications were /// performed. bool recursivelySimplifyInstruction(Instruction *I, - const DataLayout *TD = nullptr, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr); diff --git a/include/llvm/Analysis/IntervalIterator.h b/include/llvm/Analysis/IntervalIterator.h index 3b51d44..655ce2d 100644 --- a/include/llvm/Analysis/IntervalIterator.h +++ b/include/llvm/Analysis/IntervalIterator.h @@ -78,7 +78,7 @@ inline void addNodeToInterval(Interval *Int, BasicBlock *BB) { // inline void addNodeToInterval(Interval *Int, Interval *I) { // Add all of the nodes in I as new nodes in Int. - copy(I->Nodes.begin(), I->Nodes.end(), back_inserter(Int->Nodes)); + Int->Nodes.insert(Int->Nodes.end(), I->Nodes.begin(), I->Nodes.end()); } @@ -94,7 +94,6 @@ class IntervalIterator { bool IOwnMem; // If True, delete intervals when done with them // See file header for conditions of use public: - typedef IntervalIterator<NodeTy, OrigContainer_t> _Self; typedef std::forward_iterator_tag iterator_category; IntervalIterator() {} // End iterator, empty stack @@ -105,6 +104,12 @@ public: } } + IntervalIterator(IntervalIterator &&x) + : IntStack(std::move(x.IntStack)), Visited(std::move(x.Visited)), + OrigContainer(x.OrigContainer), IOwnMem(x.IOwnMem) { + x.IOwnMem = false; + } + IntervalIterator(IntervalPartition &IP, bool OwnMemory) : IOwnMem(OwnMemory) { OrigContainer = &IP; if (!ProcessInterval(IP.getRootInterval())) { @@ -112,7 +117,7 @@ public: } } - inline ~IntervalIterator() { + ~IntervalIterator() { if (IOwnMem) while (!IntStack.empty()) { delete operator*(); @@ -120,15 +125,17 @@ public: } } - inline bool operator==(const _Self& x) const { return IntStack == x.IntStack;} - inline bool operator!=(const _Self& x) const { return !operator==(x); } + bool operator==(const IntervalIterator &x) const { + return IntStack == x.IntStack; + } + bool operator!=(const IntervalIterator &x) const { return !(*this == x); } - inline const Interval *operator*() const { return IntStack.back().first; } - inline Interval *operator*() { return IntStack.back().first; } - inline const Interval *operator->() const { return operator*(); } - inline Interval *operator->() { return operator*(); } + const Interval *operator*() const { return IntStack.back().first; } + Interval *operator*() { return IntStack.back().first; } + const Interval *operator->() const { return operator*(); } + Interval *operator->() { return operator*(); } - _Self& operator++() { // Preincrement + IntervalIterator &operator++() { // Preincrement assert(!IntStack.empty() && "Attempting to use interval iterator at end!"); do { // All of the intervals on the stack have been visited. Try visiting @@ -150,8 +157,10 @@ public: return *this; } - inline _Self operator++(int) { // Postincrement - _Self tmp = *this; ++*this; return tmp; + IntervalIterator operator++(int) { // Postincrement + IntervalIterator tmp = *this; + ++*this; + return tmp; } private: diff --git a/include/llvm/Analysis/LazyValueInfo.h b/include/llvm/Analysis/LazyValueInfo.h index 51f6b0c..8e5bbfb 100644 --- a/include/llvm/Analysis/LazyValueInfo.h +++ b/include/llvm/Analysis/LazyValueInfo.h @@ -29,7 +29,6 @@ namespace llvm { /// This pass computes, caches, and vends lazy value constraint information. class LazyValueInfo : public FunctionPass { AssumptionCache *AC; - const DataLayout *DL; class TargetLibraryInfo *TLI; DominatorTree *DT; void *PImpl; diff --git a/include/llvm/Analysis/LibCallAliasAnalysis.h b/include/llvm/Analysis/LibCallAliasAnalysis.h index 4c03c92..49e0dc8 100644 --- a/include/llvm/Analysis/LibCallAliasAnalysis.h +++ b/include/llvm/Analysis/LibCallAliasAnalysis.h @@ -15,6 +15,7 @@ #define LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/IR/Module.h" #include "llvm/Pass.h" namespace llvm { @@ -48,11 +49,8 @@ namespace llvm { void getAnalysisUsage(AnalysisUsage &AU) const override; - bool runOnFunction(Function &F) override { - InitializeAliasAnalysis(this); // set up super class - return false; - } - + bool runOnFunction(Function &F) override; + /// getAdjustedAnalysisPointer - This method is used when a pass implements /// an analysis interface through multiple inheritance. If needed, it /// should override this to adjust the this pointer as needed for the diff --git a/include/llvm/Analysis/LibCallSemantics.h b/include/llvm/Analysis/LibCallSemantics.h index e6427a4..34831b2 100644 --- a/include/llvm/Analysis/LibCallSemantics.h +++ b/include/llvm/Analysis/LibCallSemantics.h @@ -181,7 +181,31 @@ class InvokeInst; /// \brief Returns true if this personality function catches asynchronous /// exceptions. - bool isAsynchronousEHPersonality(EHPersonality Pers); + inline bool isAsynchronousEHPersonality(EHPersonality Pers) { + // The two SEH personality functions can catch asynch exceptions. We assume + // unknown personalities don't catch asynch exceptions. + switch (Pers) { + case EHPersonality::MSVC_X86SEH: + case EHPersonality::MSVC_Win64SEH: + return true; + default: return false; + } + llvm_unreachable("invalid enum"); + } + + /// \brief Returns true if this is an MSVC personality function. + inline bool isMSVCEHPersonality(EHPersonality Pers) { + // The two SEH personality functions can catch asynch exceptions. We assume + // unknown personalities don't catch asynch exceptions. + switch (Pers) { + case EHPersonality::MSVC_CXX: + case EHPersonality::MSVC_X86SEH: + case EHPersonality::MSVC_Win64SEH: + return true; + default: return false; + } + llvm_unreachable("invalid enum"); + } bool canSimplifyInvokeNoUnwind(const InvokeInst *II); diff --git a/include/llvm/Analysis/Loads.h b/include/llvm/Analysis/Loads.h index 0fe3453..42667d2 100644 --- a/include/llvm/Analysis/Loads.h +++ b/include/llvm/Analysis/Loads.h @@ -27,8 +27,7 @@ class MDNode; /// specified pointer, we do a quick local scan of the basic block containing /// ScanFrom, to determine if the address is already accessed. bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, - unsigned Align, - const DataLayout *TD = nullptr); + unsigned Align); /// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at /// the instruction before ScanFrom) checking to see if we have the value at diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h index 323af98..0a9dc07 100644 --- a/include/llvm/Analysis/LoopAccessAnalysis.h +++ b/include/llvm/Analysis/LoopAccessAnalysis.h @@ -86,6 +86,210 @@ struct VectorizerParams { static unsigned RuntimeMemoryCheckThreshold; }; +/// \brief Checks memory dependences among accesses to the same underlying +/// object to determine whether there vectorization is legal or not (and at +/// which vectorization factor). +/// +/// Note: This class will compute a conservative dependence for access to +/// different underlying pointers. Clients, such as the loop vectorizer, will +/// sometimes deal these potential dependencies by emitting runtime checks. +/// +/// We use the ScalarEvolution framework to symbolically evalutate access +/// functions pairs. Since we currently don't restructure the loop we can rely +/// on the program order of memory accesses to determine their safety. +/// At the moment we will only deem accesses as safe for: +/// * A negative constant distance assuming program order. +/// +/// Safe: tmp = a[i + 1]; OR a[i + 1] = x; +/// a[i] = tmp; y = a[i]; +/// +/// The latter case is safe because later checks guarantuee that there can't +/// be a cycle through a phi node (that is, we check that "x" and "y" is not +/// the same variable: a header phi can only be an induction or a reduction, a +/// reduction can't have a memory sink, an induction can't have a memory +/// source). This is important and must not be violated (or we have to +/// resort to checking for cycles through memory). +/// +/// * A positive constant distance assuming program order that is bigger +/// than the biggest memory access. +/// +/// tmp = a[i] OR b[i] = x +/// a[i+2] = tmp y = b[i+2]; +/// +/// Safe distance: 2 x sizeof(a[0]), and 2 x sizeof(b[0]), respectively. +/// +/// * Zero distances and all accesses have the same size. +/// +class MemoryDepChecker { +public: + typedef PointerIntPair<Value *, 1, bool> MemAccessInfo; + typedef SmallPtrSet<MemAccessInfo, 8> MemAccessInfoSet; + /// \brief Set of potential dependent memory accesses. + typedef EquivalenceClasses<MemAccessInfo> DepCandidates; + + /// \brief Dependece between memory access instructions. + struct Dependence { + /// \brief The type of the dependence. + enum DepType { + // No dependence. + NoDep, + // We couldn't determine the direction or the distance. + Unknown, + // Lexically forward. + Forward, + // Forward, but if vectorized, is likely to prevent store-to-load + // forwarding. + ForwardButPreventsForwarding, + // Lexically backward. + Backward, + // Backward, but the distance allows a vectorization factor of + // MaxSafeDepDistBytes. + BackwardVectorizable, + // Same, but may prevent store-to-load forwarding. + BackwardVectorizableButPreventsForwarding + }; + + /// \brief String version of the types. + static const char *DepName[]; + + /// \brief Index of the source of the dependence in the InstMap vector. + unsigned Source; + /// \brief Index of the destination of the dependence in the InstMap vector. + unsigned Destination; + /// \brief The type of the dependence. + DepType Type; + + Dependence(unsigned Source, unsigned Destination, DepType Type) + : Source(Source), Destination(Destination), Type(Type) {} + + /// \brief Dependence types that don't prevent vectorization. + static bool isSafeForVectorization(DepType Type); + + /// \brief Dependence types that can be queried from the analysis. + static bool isInterestingDependence(DepType Type); + + /// \brief Lexically backward dependence types. + bool isPossiblyBackward() const; + + /// \brief Print the dependence. \p Instr is used to map the instruction + /// indices to instructions. + void print(raw_ostream &OS, unsigned Depth, + const SmallVectorImpl<Instruction *> &Instrs) const; + }; + + MemoryDepChecker(ScalarEvolution *Se, const Loop *L) + : SE(Se), InnermostLoop(L), AccessIdx(0), + ShouldRetryWithRuntimeCheck(false), SafeForVectorization(true), + RecordInterestingDependences(true) {} + + /// \brief Register the location (instructions are given increasing numbers) + /// of a write access. + void addAccess(StoreInst *SI) { + Value *Ptr = SI->getPointerOperand(); + Accesses[MemAccessInfo(Ptr, true)].push_back(AccessIdx); + InstMap.push_back(SI); + ++AccessIdx; + } + + /// \brief Register the location (instructions are given increasing numbers) + /// of a write access. + void addAccess(LoadInst *LI) { + Value *Ptr = LI->getPointerOperand(); + Accesses[MemAccessInfo(Ptr, false)].push_back(AccessIdx); + InstMap.push_back(LI); + ++AccessIdx; + } + + /// \brief Check whether the dependencies between the accesses are safe. + /// + /// Only checks sets with elements in \p CheckDeps. + bool areDepsSafe(DepCandidates &AccessSets, MemAccessInfoSet &CheckDeps, + const ValueToValueMap &Strides); + + /// \brief No memory dependence was encountered that would inhibit + /// vectorization. + bool isSafeForVectorization() const { return SafeForVectorization; } + + /// \brief The maximum number of bytes of a vector register we can vectorize + /// the accesses safely with. + unsigned getMaxSafeDepDistBytes() { return MaxSafeDepDistBytes; } + + /// \brief In same cases when the dependency check fails we can still + /// vectorize the loop with a dynamic array access check. + bool shouldRetryWithRuntimeCheck() { return ShouldRetryWithRuntimeCheck; } + + /// \brief Returns the interesting dependences. If null is returned we + /// exceeded the MaxInterestingDependence threshold and this information is + /// not available. + const SmallVectorImpl<Dependence> *getInterestingDependences() const { + return RecordInterestingDependences ? &InterestingDependences : nullptr; + } + + /// \brief The vector of memory access instructions. The indices are used as + /// instruction identifiers in the Dependence class. + const SmallVectorImpl<Instruction *> &getMemoryInstructions() const { + return InstMap; + } + + /// \brief Find the set of instructions that read or write via \p Ptr. + SmallVector<Instruction *, 4> getInstructionsForAccess(Value *Ptr, + bool isWrite) const; + +private: + ScalarEvolution *SE; + const Loop *InnermostLoop; + + /// \brief Maps access locations (ptr, read/write) to program order. + DenseMap<MemAccessInfo, std::vector<unsigned> > Accesses; + + /// \brief Memory access instructions in program order. + SmallVector<Instruction *, 16> InstMap; + + /// \brief The program order index to be used for the next instruction. + unsigned AccessIdx; + + // We can access this many bytes in parallel safely. + unsigned MaxSafeDepDistBytes; + + /// \brief If we see a non-constant dependence distance we can still try to + /// vectorize this loop with runtime checks. + bool ShouldRetryWithRuntimeCheck; + + /// \brief No memory dependence was encountered that would inhibit + /// vectorization. + bool SafeForVectorization; + + //// \brief True if InterestingDependences reflects the dependences in the + //// loop. If false we exceeded MaxInterestingDependence and + //// InterestingDependences is invalid. + bool RecordInterestingDependences; + + /// \brief Interesting memory dependences collected during the analysis as + /// defined by isInterestingDependence. Only valid if + /// RecordInterestingDependences is true. + SmallVector<Dependence, 8> InterestingDependences; + + /// \brief Check whether there is a plausible dependence between the two + /// accesses. + /// + /// Access \p A must happen before \p B in program order. The two indices + /// identify the index into the program order map. + /// + /// This function checks whether there is a plausible dependence (or the + /// absence of such can't be proved) between the two accesses. If there is a + /// plausible dependence but the dependence distance is bigger than one + /// element access it records this distance in \p MaxSafeDepDistBytes (if this + /// distance is smaller than any other distance encountered so far). + /// Otherwise, this function returns true signaling a possible dependence. + Dependence::DepType isDependent(const MemAccessInfo &A, unsigned AIdx, + const MemAccessInfo &B, unsigned BIdx, + const ValueToValueMap &Strides); + + /// \brief Check whether the data dependence could prevent store-load + /// forwarding. + bool couldPreventStoreLoadForward(unsigned Distance, unsigned TypeByteSize); +}; + /// \brief Drive the analysis of memory accesses in the loop /// /// This class is responsible for analyzing the memory accesses of a loop. It @@ -128,10 +332,20 @@ public: /// \brief Decide whether we need to issue a run-time check for pointer at /// index \p I and \p J to prove their independence. - bool needsChecking(unsigned I, unsigned J) const; + /// + /// If \p PtrPartition is set, it contains the partition number for + /// pointers (-1 if the pointer belongs to multiple partitions). In this + /// case omit checks between pointers belonging to the same partition. + bool needsChecking(unsigned I, unsigned J, + const SmallVectorImpl<int> *PtrPartition) const; /// \brief Print the list run-time memory checks necessary. - void print(raw_ostream &OS, unsigned Depth = 0) const; + /// + /// If \p PtrPartition is set, it contains the partition number for + /// pointers (-1 if the pointer belongs to multiple partitions). In this + /// case omit checks between pointers belonging to the same partition. + void print(raw_ostream &OS, unsigned Depth = 0, + const SmallVectorImpl<int> *PtrPartition = nullptr) const; /// This flag indicates if we need to add the runtime check. bool Need; @@ -150,7 +364,7 @@ public: SmallVector<unsigned, 2> AliasSetId; }; - LoopAccessInfo(Loop *L, ScalarEvolution *SE, const DataLayout *DL, + LoopAccessInfo(Loop *L, ScalarEvolution *SE, const DataLayout &DL, const TargetLibraryInfo *TLI, AliasAnalysis *AA, DominatorTree *DT, const ValueToValueMap &Strides); @@ -162,6 +376,10 @@ public: return &PtrRtCheck; } + /// \brief Number of memchecks required to prove independence of otherwise + /// may-alias pointers. + unsigned getNumRuntimePointerChecks() const { return NumComparisons; } + /// Return true if the block BB needs to be predicated in order for the loop /// to be vectorized. static bool blockNeedsPredication(BasicBlock *BB, Loop *TheLoop, @@ -179,13 +397,29 @@ public: /// Returns a pair of instructions where the first element is the first /// instruction generated in possibly a sequence of instructions and the /// second value is the final comparator value or NULL if no check is needed. + /// + /// If \p PtrPartition is set, it contains the partition number for pointers + /// (-1 if the pointer belongs to multiple partitions). In this case omit + /// checks between pointers belonging to the same partition. std::pair<Instruction *, Instruction *> - addRuntimeCheck(Instruction *Loc) const; + addRuntimeCheck(Instruction *Loc, + const SmallVectorImpl<int> *PtrPartition = nullptr) const; /// \brief The diagnostics report generated for the analysis. E.g. why we /// couldn't analyze the loop. const Optional<LoopAccessReport> &getReport() const { return Report; } + /// \brief the Memory Dependence Checker which can determine the + /// loop-independent and loop-carried dependences between memory accesses. + const MemoryDepChecker &getDepChecker() const { return DepChecker; } + + /// \brief Return the list of instructions that use \p Ptr to read or write + /// memory. + SmallVector<Instruction *, 4> getInstructionsForAccess(Value *Ptr, + bool isWrite) const { + return DepChecker.getInstructionsForAccess(Ptr, isWrite); + } + /// \brief Print the information about the memory accesses in the loop. void print(raw_ostream &OS, unsigned Depth = 0) const; @@ -207,9 +441,18 @@ private: /// We need to check that all of the pointers in this list are disjoint /// at runtime. RuntimePointerCheck PtrRtCheck; + + /// \brief the Memory Dependence Checker which can determine the + /// loop-independent and loop-carried dependences between memory accesses. + MemoryDepChecker DepChecker; + + /// \brief Number of memchecks required to prove independence of otherwise + /// may-alias pointers + unsigned NumComparisons; + Loop *TheLoop; ScalarEvolution *SE; - const DataLayout *DL; + const DataLayout &DL; const TargetLibraryInfo *TLI; AliasAnalysis *AA; DominatorTree *DT; @@ -280,7 +523,6 @@ private: // The used analysis passes. ScalarEvolution *SE; - const DataLayout *DL; const TargetLibraryInfo *TLI; AliasAnalysis *AA; DominatorTree *DT; diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index 3321f39..7cc4a77 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -402,7 +402,6 @@ static void discoverAndMapSubloop(LoopT *L, ArrayRef<BlockT*> Backedges, L->reserveBlocks(NumBlocks); } -namespace { /// Populate all loop data in a stable order during a single forward DFS. template<class BlockT, class LoopT> class PopulateLoopsDFS { @@ -430,7 +429,6 @@ protected: DFSStack.push_back(std::make_pair(Block, BlockTraits::child_begin(Block))); } }; -} // anonymous /// Top-level driver for the forward DFS within the loop. template<class BlockT, class LoopT> diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index d414680..805a43d 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -82,12 +82,6 @@ static inline CallInst *extractMallocCall(Value *I, return const_cast<CallInst*>(extractMallocCall((const Value*)I, TLI)); } -/// isArrayMalloc - Returns the corresponding CallInst if the instruction -/// is a call to malloc whose array size can be determined and the array size -/// is not constant 1. Otherwise, return NULL. -const CallInst *isArrayMalloc(const Value *I, const DataLayout *DL, - const TargetLibraryInfo *TLI); - /// getMallocType - Returns the PointerType resulting from the malloc call. /// The PointerType depends on the number of bitcast uses of the malloc call: /// 0: PointerType is the malloc calls' return type. @@ -107,11 +101,10 @@ Type *getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI); /// then return that multiple. For non-array mallocs, the multiple is /// constant 1. Otherwise, return NULL for mallocs whose array size cannot be /// determined. -Value *getMallocArraySize(CallInst *CI, const DataLayout *DL, +Value *getMallocArraySize(CallInst *CI, const DataLayout &DL, const TargetLibraryInfo *TLI, bool LookThroughSExt = false); - //===----------------------------------------------------------------------===// // calloc Call Utility Functions. // @@ -147,11 +140,9 @@ static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) { /// underlying object pointed to by Ptr. /// If RoundToAlign is true, then Size is rounded up to the aligment of allocas, /// byval arguments, and global variables. -bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *DL, +bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, bool RoundToAlign = false); - - typedef std::pair<APInt, APInt> SizeOffsetType; /// \brief Evaluate the size and offset of an object pointed to by a Value* @@ -159,7 +150,7 @@ typedef std::pair<APInt, APInt> SizeOffsetType; class ObjectSizeOffsetVisitor : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> { - const DataLayout *DL; + const DataLayout &DL; const TargetLibraryInfo *TLI; bool RoundToAlign; unsigned IntTyBits; @@ -173,7 +164,7 @@ class ObjectSizeOffsetVisitor } public: - ObjectSizeOffsetVisitor(const DataLayout *DL, const TargetLibraryInfo *TLI, + ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, bool RoundToAlign = false); SizeOffsetType compute(Value *V); @@ -222,7 +213,7 @@ class ObjectSizeOffsetEvaluator typedef DenseMap<const Value*, WeakEvalType> CacheMapTy; typedef SmallPtrSet<const Value*, 8> PtrSetTy; - const DataLayout *DL; + const DataLayout &DL; const TargetLibraryInfo *TLI; LLVMContext &Context; BuilderTy Builder; @@ -238,7 +229,7 @@ class ObjectSizeOffsetEvaluator SizeOffsetEvalType compute_(Value *V); public: - ObjectSizeOffsetEvaluator(const DataLayout *DL, const TargetLibraryInfo *TLI, + ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, bool RoundToAlign = false); SizeOffsetEvalType compute(Value *V); diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index 77610b3..abc2b90 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -29,7 +29,6 @@ namespace llvm { class CallSite; class AliasAnalysis; class AssumptionCache; - class DataLayout; class MemoryDependenceAnalysis; class PredIteratorCache; class DominatorTree; @@ -324,7 +323,6 @@ namespace llvm { /// Current AA implementation, just a cache. AliasAnalysis *AA; - const DataLayout *DL; DominatorTree *DT; AssumptionCache *AC; std::unique_ptr<PredIteratorCache> PredCache; @@ -421,8 +419,7 @@ namespace llvm { static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase, int64_t MemLocOffs, unsigned MemLocSize, - const LoadInst *LI, - const DataLayout &DL); + const LoadInst *LI); private: MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall, diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h index 38730d8..84bb9d8 100644 --- a/include/llvm/Analysis/PHITransAddr.h +++ b/include/llvm/Analysis/PHITransAddr.h @@ -36,9 +36,9 @@ namespace llvm { class PHITransAddr { /// Addr - The actual address we're analyzing. Value *Addr; - - /// The DataLayout we are playing with if known, otherwise null. - const DataLayout *DL; + + /// The DataLayout we are playing with. + const DataLayout &DL; /// TLI - The target library info if known, otherwise null. const TargetLibraryInfo *TLI; @@ -49,7 +49,7 @@ class PHITransAddr { /// InstInputs - The inputs for our symbolic address. SmallVector<Instruction*, 4> InstInputs; public: - PHITransAddr(Value *addr, const DataLayout *DL, AssumptionCache *AC) + PHITransAddr(Value *addr, const DataLayout &DL, AssumptionCache *AC) : Addr(addr), DL(DL), TLI(nullptr), AC(AC) { // If the address is an instruction, the whole thing is considered an input. if (Instruction *I = dyn_cast<Instruction>(Addr)) diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index 530faa7..8d11e80 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -159,10 +159,6 @@ namespace llvm { // FunctionPass *createMemDepPrinter(); - // createJumpInstrTableInfoPass - This creates a pass that stores information - // about the jump tables created by JumpInstrTables - ImmutablePass *createJumpInstrTableInfoPass(); - //===--------------------------------------------------------------------===// // // createMemDerefPrinter - This pass collects memory dereferenceability diff --git a/include/llvm/Analysis/RegionIterator.h b/include/llvm/Analysis/RegionIterator.h index 0daff58..ced58df 100644 --- a/include/llvm/Analysis/RegionIterator.h +++ b/include/llvm/Analysis/RegionIterator.h @@ -145,16 +145,6 @@ public: ++*this; return tmp; } - - inline const Self &operator=(const Self &I) { - if (this != &I) { - assert(getNode()->getParent() == I.getNode()->getParent() - && "Cannot assign iterators of two different regions!"); - Node = I.Node; - BItor = I.BItor; - } - return *this; - } }; @@ -240,16 +230,6 @@ public: ++*this; return tmp; } - - inline const Self &operator=(const Self &I) { - if (this != &I) { - assert(Node->getParent() == I.Node->getParent() - && "Cannot assign iterators to two different regions!"); - Node = I.Node; - Itor = I.Itor; - } - return *this; - } }; template<class NodeType, class BlockT, class RegionT> diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index c60cea9..4360414 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -232,10 +232,6 @@ namespace llvm { /// LoopInfo *LI; - /// The DataLayout information for the target we are targeting. - /// - const DataLayout *DL; - /// TLI - The target library information for the target we are targeting. /// TargetLibraryInfo *TLI; @@ -388,32 +384,31 @@ namespace llvm { /// computeBlockDisposition - Compute a BlockDisposition value. BlockDisposition computeBlockDisposition(const SCEV *S, const BasicBlock *BB); - /// UnsignedRanges - Memoized results from getUnsignedRange + /// UnsignedRanges - Memoized results from getRange DenseMap<const SCEV *, ConstantRange> UnsignedRanges; - /// SignedRanges - Memoized results from getSignedRange + /// SignedRanges - Memoized results from getRange DenseMap<const SCEV *, ConstantRange> SignedRanges; - /// setUnsignedRange - Set the memoized unsigned range for the given SCEV. - const ConstantRange &setUnsignedRange(const SCEV *S, - const ConstantRange &CR) { - std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair = - UnsignedRanges.insert(std::make_pair(S, CR)); - if (!Pair.second) - Pair.first->second = CR; - return Pair.first->second; - } + /// RangeSignHint - Used to parameterize getRange + enum RangeSignHint { HINT_RANGE_UNSIGNED, HINT_RANGE_SIGNED }; + + /// setRange - Set the memoized range for the given SCEV. + const ConstantRange &setRange(const SCEV *S, RangeSignHint Hint, + const ConstantRange &CR) { + DenseMap<const SCEV *, ConstantRange> &Cache = + Hint == HINT_RANGE_UNSIGNED ? UnsignedRanges : SignedRanges; - /// setUnsignedRange - Set the memoized signed range for the given SCEV. - const ConstantRange &setSignedRange(const SCEV *S, - const ConstantRange &CR) { std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair = - SignedRanges.insert(std::make_pair(S, CR)); + Cache.insert(std::make_pair(S, CR)); if (!Pair.second) Pair.first->second = CR; return Pair.first->second; } + /// getRange - Determine the range for a particular SCEV. + ConstantRange getRange(const SCEV *S, RangeSignHint Hint); + /// createSCEV - We know that there is no SCEV for the specified value. /// Analyze the expression. const SCEV *createSCEV(Value *V); @@ -540,6 +535,15 @@ namespace llvm { const SCEV *FoundLHS, const SCEV *FoundRHS); + /// isImpliedCondOperandsViaRanges - Test whether the condition described by + /// Pred, LHS, and RHS is true whenever the condition described by Pred, + /// FoundLHS, and FoundRHS is true. Utility function used by + /// isImpliedCondOperands. + bool isImpliedCondOperandsViaRanges(ICmpInst::Predicate Pred, + const SCEV *LHS, const SCEV *RHS, + const SCEV *FoundLHS, + const SCEV *FoundRHS); + /// getConstantEvolutionLoopExitValue - If we know that the specified Phi is /// in the header of its containing loop, we know the loop executes a /// constant number of times, and the PHI node is just a recurrence @@ -561,6 +565,15 @@ namespace llvm { /// pointer. bool checkValidity(const SCEV *S) const; + // Return true if `ExtendOpTy`({`Start`,+,`Step`}) can be proved to be equal + // to {`ExtendOpTy`(`Start`),+,`ExtendOpTy`(`Step`)}. This is equivalent to + // proving no signed (resp. unsigned) wrap in {`Start`,+,`Step`} if + // `ExtendOpTy` is `SCEVSignExtendExpr` (resp. `SCEVZeroExtendExpr`). + // + template<typename ExtendOpTy> + bool proveNoWrapByVaryingStart(const SCEV *Start, const SCEV *Step, + const Loop *L); + public: static char ID; // Pass identification, replacement for typeid ScalarEvolution(); @@ -834,11 +847,15 @@ namespace llvm { /// getUnsignedRange - Determine the unsigned range for a particular SCEV. /// - ConstantRange getUnsignedRange(const SCEV *S); + ConstantRange getUnsignedRange(const SCEV *S) { + return getRange(S, HINT_RANGE_UNSIGNED); + } /// getSignedRange - Determine the signed range for a particular SCEV. /// - ConstantRange getSignedRange(const SCEV *S); + ConstantRange getSignedRange(const SCEV *S) { + return getRange(S, HINT_RANGE_SIGNED); + } /// isKnownNegative - Test if the given expression is known to be negative. /// diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index b9bef97..b0b0946 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -36,6 +36,7 @@ namespace llvm { /// memory. class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> { ScalarEvolution &SE; + const DataLayout &DL; // New instructions receive a name to identifies them with the current pass. const char* IVName; @@ -91,10 +92,11 @@ namespace llvm { public: /// SCEVExpander - Construct a SCEVExpander in "canonical" mode. - explicit SCEVExpander(ScalarEvolution &se, const char *name) - : SE(se), IVName(name), IVIncInsertLoop(nullptr), IVIncInsertPos(nullptr), - CanonicalMode(true), LSRMode(false), - Builder(se.getContext(), TargetFolder(se.DL)) { + explicit SCEVExpander(ScalarEvolution &se, const DataLayout &DL, + const char *name) + : SE(se), DL(DL), IVName(name), IVIncInsertLoop(nullptr), + IVIncInsertPos(nullptr), CanonicalMode(true), LSRMode(false), + Builder(se.getContext(), TargetFolder(DL)) { #ifndef NDEBUG DebugType = ""; #endif diff --git a/include/llvm/Analysis/TargetFolder.h b/include/llvm/Analysis/TargetFolder.h index 587a7ef..f691296 100644 --- a/include/llvm/Analysis/TargetFolder.h +++ b/include/llvm/Analysis/TargetFolder.h @@ -30,7 +30,7 @@ class DataLayout; /// TargetFolder - Create constants with target dependent folding. class TargetFolder { - const DataLayout *DL; + const DataLayout &DL; /// Fold - Fold the constant using target specific information. Constant *Fold(Constant *C) const { @@ -41,7 +41,7 @@ class TargetFolder { } public: - explicit TargetFolder(const DataLayout *DL) : DL(DL) {} + explicit TargetFolder(const DataLayout &DL) : DL(DL) {} //===--------------------------------------------------------------------===// // Binary Operators diff --git a/include/llvm/Analysis/TargetLibraryInfo.def b/include/llvm/Analysis/TargetLibraryInfo.def new file mode 100644 index 0000000..1c1fdfe --- /dev/null +++ b/include/llvm/Analysis/TargetLibraryInfo.def @@ -0,0 +1,1029 @@ +//===-- TargetLibraryInfo.def - Library information -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// This .def file will either fill in the enum definition or fill in the +// string representation array definition for TargetLibraryInfo. +// Which is defined depends on whether TLI_DEFINE_ENUM is defined or +// TLI_DEFINE_STRING is defined. Only one should be defined at a time. + +#if !(defined(TLI_DEFINE_ENUM) || defined(TLI_DEFINE_STRING)) +#error "Must define TLI_DEFINE_ENUM or TLI_DEFINE_STRING for TLI .def." +#elif defined(TLI_DEFINE_ENUM) && defined(TLI_DEFINE_STRING) +#error "Can only define one of TLI_DEFINE_ENUM or TLI_DEFINE_STRING at a time." +#else +// One of TLI_DEFINE_ENUM/STRING are defined. + +#if defined(TLI_DEFINE_ENUM) +#define TLI_DEFINE_ENUM_INTERNAL(enum_variant) enum_variant, +#define TLI_DEFINE_STRING_INTERNAL(string_repr) +#else +#define TLI_DEFINE_ENUM_INTERNAL(enum_variant) +#define TLI_DEFINE_STRING_INTERNAL(string_repr) string_repr, +#endif + +/// int _IO_getc(_IO_FILE * __fp); +TLI_DEFINE_ENUM_INTERNAL(under_IO_getc) +TLI_DEFINE_STRING_INTERNAL("_IO_getc") +/// int _IO_putc(int __c, _IO_FILE * __fp); +TLI_DEFINE_ENUM_INTERNAL(under_IO_putc) +TLI_DEFINE_STRING_INTERNAL("_IO_putc") +/// void operator delete[](void*); +TLI_DEFINE_ENUM_INTERNAL(ZdaPv) +TLI_DEFINE_STRING_INTERNAL("_ZdaPv") +/// void operator delete[](void*, nothrow); +TLI_DEFINE_ENUM_INTERNAL(ZdaPvRKSt9nothrow_t) +TLI_DEFINE_STRING_INTERNAL("_ZdaPvRKSt9nothrow_t") +/// void operator delete[](void*, unsigned int); +TLI_DEFINE_ENUM_INTERNAL(ZdaPvj) +TLI_DEFINE_STRING_INTERNAL("_ZdaPvj") +/// void operator delete[](void*, unsigned long); +TLI_DEFINE_ENUM_INTERNAL(ZdaPvm) +TLI_DEFINE_STRING_INTERNAL("_ZdaPvm") +/// void operator delete(void*); +TLI_DEFINE_ENUM_INTERNAL(ZdlPv) +TLI_DEFINE_STRING_INTERNAL("_ZdlPv") +/// void operator delete(void*, nothrow); +TLI_DEFINE_ENUM_INTERNAL(ZdlPvRKSt9nothrow_t) +TLI_DEFINE_STRING_INTERNAL("_ZdlPvRKSt9nothrow_t") +/// void operator delete(void*, unsigned int); +TLI_DEFINE_ENUM_INTERNAL(ZdlPvj) +TLI_DEFINE_STRING_INTERNAL("_ZdlPvj") +/// void operator delete(void*, unsigned long); +TLI_DEFINE_ENUM_INTERNAL(ZdlPvm) +TLI_DEFINE_STRING_INTERNAL("_ZdlPvm") +/// void *new[](unsigned int); +TLI_DEFINE_ENUM_INTERNAL(Znaj) +TLI_DEFINE_STRING_INTERNAL("_Znaj") +/// void *new[](unsigned int, nothrow); +TLI_DEFINE_ENUM_INTERNAL(ZnajRKSt9nothrow_t) +TLI_DEFINE_STRING_INTERNAL("_ZnajRKSt9nothrow_t") +/// void *new[](unsigned long); +TLI_DEFINE_ENUM_INTERNAL(Znam) +TLI_DEFINE_STRING_INTERNAL("_Znam") +/// void *new[](unsigned long, nothrow); +TLI_DEFINE_ENUM_INTERNAL(ZnamRKSt9nothrow_t) +TLI_DEFINE_STRING_INTERNAL("_ZnamRKSt9nothrow_t") +/// void *new(unsigned int); +TLI_DEFINE_ENUM_INTERNAL(Znwj) +TLI_DEFINE_STRING_INTERNAL("_Znwj") +/// void *new(unsigned int, nothrow); +TLI_DEFINE_ENUM_INTERNAL(ZnwjRKSt9nothrow_t) +TLI_DEFINE_STRING_INTERNAL("_ZnwjRKSt9nothrow_t") +/// void *new(unsigned long); +TLI_DEFINE_ENUM_INTERNAL(Znwm) +TLI_DEFINE_STRING_INTERNAL("_Znwm") +/// void *new(unsigned long, nothrow); +TLI_DEFINE_ENUM_INTERNAL(ZnwmRKSt9nothrow_t) +TLI_DEFINE_STRING_INTERNAL("_ZnwmRKSt9nothrow_t") +/// double __cospi(double x); +TLI_DEFINE_ENUM_INTERNAL(cospi) +TLI_DEFINE_STRING_INTERNAL("__cospi") +/// float __cospif(float x); +TLI_DEFINE_ENUM_INTERNAL(cospif) +TLI_DEFINE_STRING_INTERNAL("__cospif") +/// int __cxa_atexit(void (*f)(void *), void *p, void *d); +TLI_DEFINE_ENUM_INTERNAL(cxa_atexit) +TLI_DEFINE_STRING_INTERNAL("__cxa_atexit") +/// void __cxa_guard_abort(guard_t *guard); +/// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi. +TLI_DEFINE_ENUM_INTERNAL(cxa_guard_abort) +TLI_DEFINE_STRING_INTERNAL("__cxa_guard_abort") +/// int __cxa_guard_acquire(guard_t *guard); +TLI_DEFINE_ENUM_INTERNAL(cxa_guard_acquire) +TLI_DEFINE_STRING_INTERNAL("__cxa_guard_acquire") +/// void __cxa_guard_release(guard_t *guard); +TLI_DEFINE_ENUM_INTERNAL(cxa_guard_release) +TLI_DEFINE_STRING_INTERNAL("__cxa_guard_release") +/// int __isoc99_scanf (const char *format, ...) +TLI_DEFINE_ENUM_INTERNAL(dunder_isoc99_scanf) +TLI_DEFINE_STRING_INTERNAL("__isoc99_scanf") +/// int __isoc99_sscanf(const char *s, const char *format, ...) +TLI_DEFINE_ENUM_INTERNAL(dunder_isoc99_sscanf) +TLI_DEFINE_STRING_INTERNAL("__isoc99_sscanf") +/// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size); +TLI_DEFINE_ENUM_INTERNAL(memcpy_chk) +TLI_DEFINE_STRING_INTERNAL("__memcpy_chk") +/// void *__memmove_chk(void *s1, const void *s2, size_t n, size_t s1size); +TLI_DEFINE_ENUM_INTERNAL(memmove_chk) +TLI_DEFINE_STRING_INTERNAL("__memmove_chk") +/// void *__memset_chk(void *s, char v, size_t n, size_t s1size); +TLI_DEFINE_ENUM_INTERNAL(memset_chk) +TLI_DEFINE_STRING_INTERNAL("__memset_chk") +/// double __sincospi_stret(double x); +TLI_DEFINE_ENUM_INTERNAL(sincospi_stret) +TLI_DEFINE_STRING_INTERNAL("__sincospi_stret") +/// float __sincospif_stret(float x); +TLI_DEFINE_ENUM_INTERNAL(sincospif_stret) +TLI_DEFINE_STRING_INTERNAL("__sincospif_stret") +/// double __sinpi(double x); +TLI_DEFINE_ENUM_INTERNAL(sinpi) +TLI_DEFINE_STRING_INTERNAL("__sinpi") +/// float __sinpif(float x); +TLI_DEFINE_ENUM_INTERNAL(sinpif) +TLI_DEFINE_STRING_INTERNAL("__sinpif") +/// double __sqrt_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(sqrt_finite) +TLI_DEFINE_STRING_INTERNAL("__sqrt_finite") +/// float __sqrt_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(sqrtf_finite) +TLI_DEFINE_STRING_INTERNAL("__sqrtf_finite") +/// long double __sqrt_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(sqrtl_finite) +TLI_DEFINE_STRING_INTERNAL("__sqrtl_finite") +/// char *__stpcpy_chk(char *s1, const char *s2, size_t s1size); +TLI_DEFINE_ENUM_INTERNAL(stpcpy_chk) +TLI_DEFINE_STRING_INTERNAL("__stpcpy_chk") +/// char *__stpncpy_chk(char *s1, const char *s2, size_t n, size_t s1size); +TLI_DEFINE_ENUM_INTERNAL(stpncpy_chk) +TLI_DEFINE_STRING_INTERNAL("__stpncpy_chk") +/// char *__strcpy_chk(char *s1, const char *s2, size_t s1size); +TLI_DEFINE_ENUM_INTERNAL(strcpy_chk) +TLI_DEFINE_STRING_INTERNAL("__strcpy_chk") +/// char * __strdup(const char *s); +TLI_DEFINE_ENUM_INTERNAL(dunder_strdup) +TLI_DEFINE_STRING_INTERNAL("__strdup") +/// char *__strncpy_chk(char *s1, const char *s2, size_t n, size_t s1size); +TLI_DEFINE_ENUM_INTERNAL(strncpy_chk) +TLI_DEFINE_STRING_INTERNAL("__strncpy_chk") +/// char *__strndup(const char *s, size_t n); +TLI_DEFINE_ENUM_INTERNAL(dunder_strndup) +TLI_DEFINE_STRING_INTERNAL("__strndup") +/// char * __strtok_r(char *s, const char *delim, char **save_ptr); +TLI_DEFINE_ENUM_INTERNAL(dunder_strtok_r) +TLI_DEFINE_STRING_INTERNAL("__strtok_r") +/// int abs(int j); +TLI_DEFINE_ENUM_INTERNAL(abs) +TLI_DEFINE_STRING_INTERNAL("abs") +/// int access(const char *path, int amode); +TLI_DEFINE_ENUM_INTERNAL(access) +TLI_DEFINE_STRING_INTERNAL("access") +/// double acos(double x); +TLI_DEFINE_ENUM_INTERNAL(acos) +TLI_DEFINE_STRING_INTERNAL("acos") +/// float acosf(float x); +TLI_DEFINE_ENUM_INTERNAL(acosf) +TLI_DEFINE_STRING_INTERNAL("acosf") +/// double acosh(double x); +TLI_DEFINE_ENUM_INTERNAL(acosh) +TLI_DEFINE_STRING_INTERNAL("acosh") +/// float acoshf(float x); +TLI_DEFINE_ENUM_INTERNAL(acoshf) +TLI_DEFINE_STRING_INTERNAL("acoshf") +/// long double acoshl(long double x); +TLI_DEFINE_ENUM_INTERNAL(acoshl) +TLI_DEFINE_STRING_INTERNAL("acoshl") +/// long double acosl(long double x); +TLI_DEFINE_ENUM_INTERNAL(acosl) +TLI_DEFINE_STRING_INTERNAL("acosl") +/// double asin(double x); +TLI_DEFINE_ENUM_INTERNAL(asin) +TLI_DEFINE_STRING_INTERNAL("asin") +/// float asinf(float x); +TLI_DEFINE_ENUM_INTERNAL(asinf) +TLI_DEFINE_STRING_INTERNAL("asinf") +/// double asinh(double x); +TLI_DEFINE_ENUM_INTERNAL(asinh) +TLI_DEFINE_STRING_INTERNAL("asinh") +/// float asinhf(float x); +TLI_DEFINE_ENUM_INTERNAL(asinhf) +TLI_DEFINE_STRING_INTERNAL("asinhf") +/// long double asinhl(long double x); +TLI_DEFINE_ENUM_INTERNAL(asinhl) +TLI_DEFINE_STRING_INTERNAL("asinhl") +/// long double asinl(long double x); +TLI_DEFINE_ENUM_INTERNAL(asinl) +TLI_DEFINE_STRING_INTERNAL("asinl") +/// double atan(double x); +TLI_DEFINE_ENUM_INTERNAL(atan) +TLI_DEFINE_STRING_INTERNAL("atan") +/// double atan2(double y, double x); +TLI_DEFINE_ENUM_INTERNAL(atan2) +TLI_DEFINE_STRING_INTERNAL("atan2") +/// float atan2f(float y, float x); +TLI_DEFINE_ENUM_INTERNAL(atan2f) +TLI_DEFINE_STRING_INTERNAL("atan2f") +/// long double atan2l(long double y, long double x); +TLI_DEFINE_ENUM_INTERNAL(atan2l) +TLI_DEFINE_STRING_INTERNAL("atan2l") +/// float atanf(float x); +TLI_DEFINE_ENUM_INTERNAL(atanf) +TLI_DEFINE_STRING_INTERNAL("atanf") +/// double atanh(double x); +TLI_DEFINE_ENUM_INTERNAL(atanh) +TLI_DEFINE_STRING_INTERNAL("atanh") +/// float atanhf(float x); +TLI_DEFINE_ENUM_INTERNAL(atanhf) +TLI_DEFINE_STRING_INTERNAL("atanhf") +/// long double atanhl(long double x); +TLI_DEFINE_ENUM_INTERNAL(atanhl) +TLI_DEFINE_STRING_INTERNAL("atanhl") +/// long double atanl(long double x); +TLI_DEFINE_ENUM_INTERNAL(atanl) +TLI_DEFINE_STRING_INTERNAL("atanl") +/// double atof(const char *str); +TLI_DEFINE_ENUM_INTERNAL(atof) +TLI_DEFINE_STRING_INTERNAL("atof") +/// int atoi(const char *str); +TLI_DEFINE_ENUM_INTERNAL(atoi) +TLI_DEFINE_STRING_INTERNAL("atoi") +/// long atol(const char *str); +TLI_DEFINE_ENUM_INTERNAL(atol) +TLI_DEFINE_STRING_INTERNAL("atol") +/// long long atoll(const char *nptr); +TLI_DEFINE_ENUM_INTERNAL(atoll) +TLI_DEFINE_STRING_INTERNAL("atoll") +/// int bcmp(const void *s1, const void *s2, size_t n); +TLI_DEFINE_ENUM_INTERNAL(bcmp) +TLI_DEFINE_STRING_INTERNAL("bcmp") +/// void bcopy(const void *s1, void *s2, size_t n); +TLI_DEFINE_ENUM_INTERNAL(bcopy) +TLI_DEFINE_STRING_INTERNAL("bcopy") +/// void bzero(void *s, size_t n); +TLI_DEFINE_ENUM_INTERNAL(bzero) +TLI_DEFINE_STRING_INTERNAL("bzero") +/// void *calloc(size_t count, size_t size); +TLI_DEFINE_ENUM_INTERNAL(calloc) +TLI_DEFINE_STRING_INTERNAL("calloc") +/// double cbrt(double x); +TLI_DEFINE_ENUM_INTERNAL(cbrt) +TLI_DEFINE_STRING_INTERNAL("cbrt") +/// float cbrtf(float x); +TLI_DEFINE_ENUM_INTERNAL(cbrtf) +TLI_DEFINE_STRING_INTERNAL("cbrtf") +/// long double cbrtl(long double x); +TLI_DEFINE_ENUM_INTERNAL(cbrtl) +TLI_DEFINE_STRING_INTERNAL("cbrtl") +/// double ceil(double x); +TLI_DEFINE_ENUM_INTERNAL(ceil) +TLI_DEFINE_STRING_INTERNAL("ceil") +/// float ceilf(float x); +TLI_DEFINE_ENUM_INTERNAL(ceilf) +TLI_DEFINE_STRING_INTERNAL("ceilf") +/// long double ceill(long double x); +TLI_DEFINE_ENUM_INTERNAL(ceill) +TLI_DEFINE_STRING_INTERNAL("ceill") +/// int chmod(const char *path, mode_t mode); +TLI_DEFINE_ENUM_INTERNAL(chmod) +TLI_DEFINE_STRING_INTERNAL("chmod") +/// int chown(const char *path, uid_t owner, gid_t group); +TLI_DEFINE_ENUM_INTERNAL(chown) +TLI_DEFINE_STRING_INTERNAL("chown") +/// void clearerr(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(clearerr) +TLI_DEFINE_STRING_INTERNAL("clearerr") +/// int closedir(DIR *dirp); +TLI_DEFINE_ENUM_INTERNAL(closedir) +TLI_DEFINE_STRING_INTERNAL("closedir") +/// double copysign(double x, double y); +TLI_DEFINE_ENUM_INTERNAL(copysign) +TLI_DEFINE_STRING_INTERNAL("copysign") +/// float copysignf(float x, float y); +TLI_DEFINE_ENUM_INTERNAL(copysignf) +TLI_DEFINE_STRING_INTERNAL("copysignf") +/// long double copysignl(long double x, long double y); +TLI_DEFINE_ENUM_INTERNAL(copysignl) +TLI_DEFINE_STRING_INTERNAL("copysignl") +/// double cos(double x); +TLI_DEFINE_ENUM_INTERNAL(cos) +TLI_DEFINE_STRING_INTERNAL("cos") +/// float cosf(float x); +TLI_DEFINE_ENUM_INTERNAL(cosf) +TLI_DEFINE_STRING_INTERNAL("cosf") +/// double cosh(double x); +TLI_DEFINE_ENUM_INTERNAL(cosh) +TLI_DEFINE_STRING_INTERNAL("cosh") +/// float coshf(float x); +TLI_DEFINE_ENUM_INTERNAL(coshf) +TLI_DEFINE_STRING_INTERNAL("coshf") +/// long double coshl(long double x); +TLI_DEFINE_ENUM_INTERNAL(coshl) +TLI_DEFINE_STRING_INTERNAL("coshl") +/// long double cosl(long double x); +TLI_DEFINE_ENUM_INTERNAL(cosl) +TLI_DEFINE_STRING_INTERNAL("cosl") +/// char *ctermid(char *s); +TLI_DEFINE_ENUM_INTERNAL(ctermid) +TLI_DEFINE_STRING_INTERNAL("ctermid") +/// double exp(double x); +TLI_DEFINE_ENUM_INTERNAL(exp) +TLI_DEFINE_STRING_INTERNAL("exp") +/// double exp10(double x); +TLI_DEFINE_ENUM_INTERNAL(exp10) +TLI_DEFINE_STRING_INTERNAL("exp10") +/// float exp10f(float x); +TLI_DEFINE_ENUM_INTERNAL(exp10f) +TLI_DEFINE_STRING_INTERNAL("exp10f") +/// long double exp10l(long double x); +TLI_DEFINE_ENUM_INTERNAL(exp10l) +TLI_DEFINE_STRING_INTERNAL("exp10l") +/// double exp2(double x); +TLI_DEFINE_ENUM_INTERNAL(exp2) +TLI_DEFINE_STRING_INTERNAL("exp2") +/// float exp2f(float x); +TLI_DEFINE_ENUM_INTERNAL(exp2f) +TLI_DEFINE_STRING_INTERNAL("exp2f") +/// long double exp2l(long double x); +TLI_DEFINE_ENUM_INTERNAL(exp2l) +TLI_DEFINE_STRING_INTERNAL("exp2l") +/// float expf(float x); +TLI_DEFINE_ENUM_INTERNAL(expf) +TLI_DEFINE_STRING_INTERNAL("expf") +/// long double expl(long double x); +TLI_DEFINE_ENUM_INTERNAL(expl) +TLI_DEFINE_STRING_INTERNAL("expl") +/// double expm1(double x); +TLI_DEFINE_ENUM_INTERNAL(expm1) +TLI_DEFINE_STRING_INTERNAL("expm1") +/// float expm1f(float x); +TLI_DEFINE_ENUM_INTERNAL(expm1f) +TLI_DEFINE_STRING_INTERNAL("expm1f") +/// long double expm1l(long double x); +TLI_DEFINE_ENUM_INTERNAL(expm1l) +TLI_DEFINE_STRING_INTERNAL("expm1l") +/// double fabs(double x); +TLI_DEFINE_ENUM_INTERNAL(fabs) +TLI_DEFINE_STRING_INTERNAL("fabs") +/// float fabsf(float x); +TLI_DEFINE_ENUM_INTERNAL(fabsf) +TLI_DEFINE_STRING_INTERNAL("fabsf") +/// long double fabsl(long double x); +TLI_DEFINE_ENUM_INTERNAL(fabsl) +TLI_DEFINE_STRING_INTERNAL("fabsl") +/// int fclose(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fclose) +TLI_DEFINE_STRING_INTERNAL("fclose") +/// FILE *fdopen(int fildes, const char *mode); +TLI_DEFINE_ENUM_INTERNAL(fdopen) +TLI_DEFINE_STRING_INTERNAL("fdopen") +/// int feof(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(feof) +TLI_DEFINE_STRING_INTERNAL("feof") +/// int ferror(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(ferror) +TLI_DEFINE_STRING_INTERNAL("ferror") +/// int fflush(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fflush) +TLI_DEFINE_STRING_INTERNAL("fflush") +/// int ffs(int i); +TLI_DEFINE_ENUM_INTERNAL(ffs) +TLI_DEFINE_STRING_INTERNAL("ffs") +/// int ffsl(long int i); +TLI_DEFINE_ENUM_INTERNAL(ffsl) +TLI_DEFINE_STRING_INTERNAL("ffsl") +/// int ffsll(long long int i); +TLI_DEFINE_ENUM_INTERNAL(ffsll) +TLI_DEFINE_STRING_INTERNAL("ffsll") +/// int fgetc(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fgetc) +TLI_DEFINE_STRING_INTERNAL("fgetc") +/// int fgetpos(FILE *stream, fpos_t *pos); +TLI_DEFINE_ENUM_INTERNAL(fgetpos) +TLI_DEFINE_STRING_INTERNAL("fgetpos") +/// char *fgets(char *s, int n, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fgets) +TLI_DEFINE_STRING_INTERNAL("fgets") +/// int fileno(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fileno) +TLI_DEFINE_STRING_INTERNAL("fileno") +/// int fiprintf(FILE *stream, const char *format, ...); +TLI_DEFINE_ENUM_INTERNAL(fiprintf) +TLI_DEFINE_STRING_INTERNAL("fiprintf") +/// void flockfile(FILE *file); +TLI_DEFINE_ENUM_INTERNAL(flockfile) +TLI_DEFINE_STRING_INTERNAL("flockfile") +/// double floor(double x); +TLI_DEFINE_ENUM_INTERNAL(floor) +TLI_DEFINE_STRING_INTERNAL("floor") +/// float floorf(float x); +TLI_DEFINE_ENUM_INTERNAL(floorf) +TLI_DEFINE_STRING_INTERNAL("floorf") +/// long double floorl(long double x); +TLI_DEFINE_ENUM_INTERNAL(floorl) +TLI_DEFINE_STRING_INTERNAL("floorl") +/// double fmax(double x, double y); +TLI_DEFINE_ENUM_INTERNAL(fmax) +TLI_DEFINE_STRING_INTERNAL("fmax") +/// float fmaxf(float x, float y); +TLI_DEFINE_ENUM_INTERNAL(fmaxf) +TLI_DEFINE_STRING_INTERNAL("fmaxf") +/// long double fmaxl(long double x, long double y); +TLI_DEFINE_ENUM_INTERNAL(fmaxl) +TLI_DEFINE_STRING_INTERNAL("fmaxl") +/// double fmin(double x, double y); +TLI_DEFINE_ENUM_INTERNAL(fmin) +TLI_DEFINE_STRING_INTERNAL("fmin") +/// float fminf(float x, float y); +TLI_DEFINE_ENUM_INTERNAL(fminf) +TLI_DEFINE_STRING_INTERNAL("fminf") +/// long double fminl(long double x, long double y); +TLI_DEFINE_ENUM_INTERNAL(fminl) +TLI_DEFINE_STRING_INTERNAL("fminl") +/// double fmod(double x, double y); +TLI_DEFINE_ENUM_INTERNAL(fmod) +TLI_DEFINE_STRING_INTERNAL("fmod") +/// float fmodf(float x, float y); +TLI_DEFINE_ENUM_INTERNAL(fmodf) +TLI_DEFINE_STRING_INTERNAL("fmodf") +/// long double fmodl(long double x, long double y); +TLI_DEFINE_ENUM_INTERNAL(fmodl) +TLI_DEFINE_STRING_INTERNAL("fmodl") +/// FILE *fopen(const char *filename, const char *mode); +TLI_DEFINE_ENUM_INTERNAL(fopen) +TLI_DEFINE_STRING_INTERNAL("fopen") +/// FILE *fopen64(const char *filename, const char *opentype) +TLI_DEFINE_ENUM_INTERNAL(fopen64) +TLI_DEFINE_STRING_INTERNAL("fopen64") +/// int fprintf(FILE *stream, const char *format, ...); +TLI_DEFINE_ENUM_INTERNAL(fprintf) +TLI_DEFINE_STRING_INTERNAL("fprintf") +/// int fputc(int c, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fputc) +TLI_DEFINE_STRING_INTERNAL("fputc") +/// int fputs(const char *s, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fputs) +TLI_DEFINE_STRING_INTERNAL("fputs") +/// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fread) +TLI_DEFINE_STRING_INTERNAL("fread") +/// void free(void *ptr); +TLI_DEFINE_ENUM_INTERNAL(free) +TLI_DEFINE_STRING_INTERNAL("free") +/// double frexp(double num, int *exp); +TLI_DEFINE_ENUM_INTERNAL(frexp) +TLI_DEFINE_STRING_INTERNAL("frexp") +/// float frexpf(float num, int *exp); +TLI_DEFINE_ENUM_INTERNAL(frexpf) +TLI_DEFINE_STRING_INTERNAL("frexpf") +/// long double frexpl(long double num, int *exp); +TLI_DEFINE_ENUM_INTERNAL(frexpl) +TLI_DEFINE_STRING_INTERNAL("frexpl") +/// int fscanf(FILE *stream, const char *format, ... ); +TLI_DEFINE_ENUM_INTERNAL(fscanf) +TLI_DEFINE_STRING_INTERNAL("fscanf") +/// int fseek(FILE *stream, long offset, int whence); +TLI_DEFINE_ENUM_INTERNAL(fseek) +TLI_DEFINE_STRING_INTERNAL("fseek") +/// int fseeko(FILE *stream, off_t offset, int whence); +TLI_DEFINE_ENUM_INTERNAL(fseeko) +TLI_DEFINE_STRING_INTERNAL("fseeko") +/// int fseeko64(FILE *stream, off64_t offset, int whence) +TLI_DEFINE_ENUM_INTERNAL(fseeko64) +TLI_DEFINE_STRING_INTERNAL("fseeko64") +/// int fsetpos(FILE *stream, const fpos_t *pos); +TLI_DEFINE_ENUM_INTERNAL(fsetpos) +TLI_DEFINE_STRING_INTERNAL("fsetpos") +/// int fstat(int fildes, struct stat *buf); +TLI_DEFINE_ENUM_INTERNAL(fstat) +TLI_DEFINE_STRING_INTERNAL("fstat") +/// int fstat64(int filedes, struct stat64 *buf) +TLI_DEFINE_ENUM_INTERNAL(fstat64) +TLI_DEFINE_STRING_INTERNAL("fstat64") +/// int fstatvfs(int fildes, struct statvfs *buf); +TLI_DEFINE_ENUM_INTERNAL(fstatvfs) +TLI_DEFINE_STRING_INTERNAL("fstatvfs") +/// int fstatvfs64(int fildes, struct statvfs64 *buf); +TLI_DEFINE_ENUM_INTERNAL(fstatvfs64) +TLI_DEFINE_STRING_INTERNAL("fstatvfs64") +/// long ftell(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(ftell) +TLI_DEFINE_STRING_INTERNAL("ftell") +/// off_t ftello(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(ftello) +TLI_DEFINE_STRING_INTERNAL("ftello") +/// off64_t ftello64(FILE *stream) +TLI_DEFINE_ENUM_INTERNAL(ftello64) +TLI_DEFINE_STRING_INTERNAL("ftello64") +/// int ftrylockfile(FILE *file); +TLI_DEFINE_ENUM_INTERNAL(ftrylockfile) +TLI_DEFINE_STRING_INTERNAL("ftrylockfile") +/// void funlockfile(FILE *file); +TLI_DEFINE_ENUM_INTERNAL(funlockfile) +TLI_DEFINE_STRING_INTERNAL("funlockfile") +/// size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fwrite) +TLI_DEFINE_STRING_INTERNAL("fwrite") +/// int getc(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(getc) +TLI_DEFINE_STRING_INTERNAL("getc") +/// int getc_unlocked(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(getc_unlocked) +TLI_DEFINE_STRING_INTERNAL("getc_unlocked") +/// int getchar(void); +TLI_DEFINE_ENUM_INTERNAL(getchar) +TLI_DEFINE_STRING_INTERNAL("getchar") +/// char *getenv(const char *name); +TLI_DEFINE_ENUM_INTERNAL(getenv) +TLI_DEFINE_STRING_INTERNAL("getenv") +/// int getitimer(int which, struct itimerval *value); +TLI_DEFINE_ENUM_INTERNAL(getitimer) +TLI_DEFINE_STRING_INTERNAL("getitimer") +/// int getlogin_r(char *name, size_t namesize); +TLI_DEFINE_ENUM_INTERNAL(getlogin_r) +TLI_DEFINE_STRING_INTERNAL("getlogin_r") +/// struct passwd *getpwnam(const char *name); +TLI_DEFINE_ENUM_INTERNAL(getpwnam) +TLI_DEFINE_STRING_INTERNAL("getpwnam") +/// char *gets(char *s); +TLI_DEFINE_ENUM_INTERNAL(gets) +TLI_DEFINE_STRING_INTERNAL("gets") +/// int gettimeofday(struct timeval *tp, void *tzp); +TLI_DEFINE_ENUM_INTERNAL(gettimeofday) +TLI_DEFINE_STRING_INTERNAL("gettimeofday") +/// uint32_t htonl(uint32_t hostlong); +TLI_DEFINE_ENUM_INTERNAL(htonl) +TLI_DEFINE_STRING_INTERNAL("htonl") +/// uint16_t htons(uint16_t hostshort); +TLI_DEFINE_ENUM_INTERNAL(htons) +TLI_DEFINE_STRING_INTERNAL("htons") +/// int iprintf(const char *format, ...); +TLI_DEFINE_ENUM_INTERNAL(iprintf) +TLI_DEFINE_STRING_INTERNAL("iprintf") +/// int isascii(int c); +TLI_DEFINE_ENUM_INTERNAL(isascii) +TLI_DEFINE_STRING_INTERNAL("isascii") +/// int isdigit(int c); +TLI_DEFINE_ENUM_INTERNAL(isdigit) +TLI_DEFINE_STRING_INTERNAL("isdigit") +/// long int labs(long int j); +TLI_DEFINE_ENUM_INTERNAL(labs) +TLI_DEFINE_STRING_INTERNAL("labs") +/// int lchown(const char *path, uid_t owner, gid_t group); +TLI_DEFINE_ENUM_INTERNAL(lchown) +TLI_DEFINE_STRING_INTERNAL("lchown") +/// double ldexp(double x, int n); +TLI_DEFINE_ENUM_INTERNAL(ldexp) +TLI_DEFINE_STRING_INTERNAL("ldexp") +/// float ldexpf(float x, int n); +TLI_DEFINE_ENUM_INTERNAL(ldexpf) +TLI_DEFINE_STRING_INTERNAL("ldexpf") +/// long double ldexpl(long double x, int n); +TLI_DEFINE_ENUM_INTERNAL(ldexpl) +TLI_DEFINE_STRING_INTERNAL("ldexpl") +/// long long int llabs(long long int j); +TLI_DEFINE_ENUM_INTERNAL(llabs) +TLI_DEFINE_STRING_INTERNAL("llabs") +/// double log(double x); +TLI_DEFINE_ENUM_INTERNAL(log) +TLI_DEFINE_STRING_INTERNAL("log") +/// double log10(double x); +TLI_DEFINE_ENUM_INTERNAL(log10) +TLI_DEFINE_STRING_INTERNAL("log10") +/// float log10f(float x); +TLI_DEFINE_ENUM_INTERNAL(log10f) +TLI_DEFINE_STRING_INTERNAL("log10f") +/// long double log10l(long double x); +TLI_DEFINE_ENUM_INTERNAL(log10l) +TLI_DEFINE_STRING_INTERNAL("log10l") +/// double log1p(double x); +TLI_DEFINE_ENUM_INTERNAL(log1p) +TLI_DEFINE_STRING_INTERNAL("log1p") +/// float log1pf(float x); +TLI_DEFINE_ENUM_INTERNAL(log1pf) +TLI_DEFINE_STRING_INTERNAL("log1pf") +/// long double log1pl(long double x); +TLI_DEFINE_ENUM_INTERNAL(log1pl) +TLI_DEFINE_STRING_INTERNAL("log1pl") +/// double log2(double x); +TLI_DEFINE_ENUM_INTERNAL(log2) +TLI_DEFINE_STRING_INTERNAL("log2") +/// float log2f(float x); +TLI_DEFINE_ENUM_INTERNAL(log2f) +TLI_DEFINE_STRING_INTERNAL("log2f") +/// double long double log2l(long double x); +TLI_DEFINE_ENUM_INTERNAL(log2l) +TLI_DEFINE_STRING_INTERNAL("log2l") +/// double logb(double x); +TLI_DEFINE_ENUM_INTERNAL(logb) +TLI_DEFINE_STRING_INTERNAL("logb") +/// float logbf(float x); +TLI_DEFINE_ENUM_INTERNAL(logbf) +TLI_DEFINE_STRING_INTERNAL("logbf") +/// long double logbl(long double x); +TLI_DEFINE_ENUM_INTERNAL(logbl) +TLI_DEFINE_STRING_INTERNAL("logbl") +/// float logf(float x); +TLI_DEFINE_ENUM_INTERNAL(logf) +TLI_DEFINE_STRING_INTERNAL("logf") +/// long double logl(long double x); +TLI_DEFINE_ENUM_INTERNAL(logl) +TLI_DEFINE_STRING_INTERNAL("logl") +/// int lstat(const char *path, struct stat *buf); +TLI_DEFINE_ENUM_INTERNAL(lstat) +TLI_DEFINE_STRING_INTERNAL("lstat") +/// int lstat64(const char *path, struct stat64 *buf); +TLI_DEFINE_ENUM_INTERNAL(lstat64) +TLI_DEFINE_STRING_INTERNAL("lstat64") +/// void *malloc(size_t size); +TLI_DEFINE_ENUM_INTERNAL(malloc) +TLI_DEFINE_STRING_INTERNAL("malloc") +/// void *memalign(size_t boundary, size_t size); +TLI_DEFINE_ENUM_INTERNAL(memalign) +TLI_DEFINE_STRING_INTERNAL("memalign") +/// void *memccpy(void *s1, const void *s2, int c, size_t n); +TLI_DEFINE_ENUM_INTERNAL(memccpy) +TLI_DEFINE_STRING_INTERNAL("memccpy") +/// void *memchr(const void *s, int c, size_t n); +TLI_DEFINE_ENUM_INTERNAL(memchr) +TLI_DEFINE_STRING_INTERNAL("memchr") +/// int memcmp(const void *s1, const void *s2, size_t n); +TLI_DEFINE_ENUM_INTERNAL(memcmp) +TLI_DEFINE_STRING_INTERNAL("memcmp") +/// void *memcpy(void *s1, const void *s2, size_t n); +TLI_DEFINE_ENUM_INTERNAL(memcpy) +TLI_DEFINE_STRING_INTERNAL("memcpy") +/// void *memmove(void *s1, const void *s2, size_t n); +TLI_DEFINE_ENUM_INTERNAL(memmove) +TLI_DEFINE_STRING_INTERNAL("memmove") +// void *memrchr(const void *s, int c, size_t n); +TLI_DEFINE_ENUM_INTERNAL(memrchr) +TLI_DEFINE_STRING_INTERNAL("memrchr") +/// void *memset(void *b, int c, size_t len); +TLI_DEFINE_ENUM_INTERNAL(memset) +TLI_DEFINE_STRING_INTERNAL("memset") +/// void memset_pattern16(void *b, const void *pattern16, size_t len); +TLI_DEFINE_ENUM_INTERNAL(memset_pattern16) +TLI_DEFINE_STRING_INTERNAL("memset_pattern16") +/// int mkdir(const char *path, mode_t mode); +TLI_DEFINE_ENUM_INTERNAL(mkdir) +TLI_DEFINE_STRING_INTERNAL("mkdir") +/// time_t mktime(struct tm *timeptr); +TLI_DEFINE_ENUM_INTERNAL(mktime) +TLI_DEFINE_STRING_INTERNAL("mktime") +/// double modf(double x, double *iptr); +TLI_DEFINE_ENUM_INTERNAL(modf) +TLI_DEFINE_STRING_INTERNAL("modf") +/// float modff(float, float *iptr); +TLI_DEFINE_ENUM_INTERNAL(modff) +TLI_DEFINE_STRING_INTERNAL("modff") +/// long double modfl(long double value, long double *iptr); +TLI_DEFINE_ENUM_INTERNAL(modfl) +TLI_DEFINE_STRING_INTERNAL("modfl") +/// double nearbyint(double x); +TLI_DEFINE_ENUM_INTERNAL(nearbyint) +TLI_DEFINE_STRING_INTERNAL("nearbyint") +/// float nearbyintf(float x); +TLI_DEFINE_ENUM_INTERNAL(nearbyintf) +TLI_DEFINE_STRING_INTERNAL("nearbyintf") +/// long double nearbyintl(long double x); +TLI_DEFINE_ENUM_INTERNAL(nearbyintl) +TLI_DEFINE_STRING_INTERNAL("nearbyintl") +/// uint32_t ntohl(uint32_t netlong); +TLI_DEFINE_ENUM_INTERNAL(ntohl) +TLI_DEFINE_STRING_INTERNAL("ntohl") +/// uint16_t ntohs(uint16_t netshort); +TLI_DEFINE_ENUM_INTERNAL(ntohs) +TLI_DEFINE_STRING_INTERNAL("ntohs") +/// int open(const char *path, int oflag, ... ); +TLI_DEFINE_ENUM_INTERNAL(open) +TLI_DEFINE_STRING_INTERNAL("open") +/// int open64(const char *filename, int flags[, mode_t mode]) +TLI_DEFINE_ENUM_INTERNAL(open64) +TLI_DEFINE_STRING_INTERNAL("open64") +/// DIR *opendir(const char *dirname); +TLI_DEFINE_ENUM_INTERNAL(opendir) +TLI_DEFINE_STRING_INTERNAL("opendir") +/// int pclose(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(pclose) +TLI_DEFINE_STRING_INTERNAL("pclose") +/// void perror(const char *s); +TLI_DEFINE_ENUM_INTERNAL(perror) +TLI_DEFINE_STRING_INTERNAL("perror") +/// FILE *popen(const char *command, const char *mode); +TLI_DEFINE_ENUM_INTERNAL(popen) +TLI_DEFINE_STRING_INTERNAL("popen") +/// int posix_memalign(void **memptr, size_t alignment, size_t size); +TLI_DEFINE_ENUM_INTERNAL(posix_memalign) +TLI_DEFINE_STRING_INTERNAL("posix_memalign") +/// double pow(double x, double y); +TLI_DEFINE_ENUM_INTERNAL(pow) +TLI_DEFINE_STRING_INTERNAL("pow") +/// float powf(float x, float y); +TLI_DEFINE_ENUM_INTERNAL(powf) +TLI_DEFINE_STRING_INTERNAL("powf") +/// long double powl(long double x, long double y); +TLI_DEFINE_ENUM_INTERNAL(powl) +TLI_DEFINE_STRING_INTERNAL("powl") +/// ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset); +TLI_DEFINE_ENUM_INTERNAL(pread) +TLI_DEFINE_STRING_INTERNAL("pread") +/// int printf(const char *format, ...); +TLI_DEFINE_ENUM_INTERNAL(printf) +TLI_DEFINE_STRING_INTERNAL("printf") +/// int putc(int c, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(putc) +TLI_DEFINE_STRING_INTERNAL("putc") +/// int putchar(int c); +TLI_DEFINE_ENUM_INTERNAL(putchar) +TLI_DEFINE_STRING_INTERNAL("putchar") +/// int puts(const char *s); +TLI_DEFINE_ENUM_INTERNAL(puts) +TLI_DEFINE_STRING_INTERNAL("puts") +/// ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset); +TLI_DEFINE_ENUM_INTERNAL(pwrite) +TLI_DEFINE_STRING_INTERNAL("pwrite") +/// void qsort(void *base, size_t nel, size_t width, +/// int (*compar)(const void *, const void *)); +TLI_DEFINE_ENUM_INTERNAL(qsort) +TLI_DEFINE_STRING_INTERNAL("qsort") +/// ssize_t read(int fildes, void *buf, size_t nbyte); +TLI_DEFINE_ENUM_INTERNAL(read) +TLI_DEFINE_STRING_INTERNAL("read") +/// ssize_t readlink(const char *path, char *buf, size_t bufsize); +TLI_DEFINE_ENUM_INTERNAL(readlink) +TLI_DEFINE_STRING_INTERNAL("readlink") +/// void *realloc(void *ptr, size_t size); +TLI_DEFINE_ENUM_INTERNAL(realloc) +TLI_DEFINE_STRING_INTERNAL("realloc") +/// void *reallocf(void *ptr, size_t size); +TLI_DEFINE_ENUM_INTERNAL(reallocf) +TLI_DEFINE_STRING_INTERNAL("reallocf") +/// char *realpath(const char *file_name, char *resolved_name); +TLI_DEFINE_ENUM_INTERNAL(realpath) +TLI_DEFINE_STRING_INTERNAL("realpath") +/// int remove(const char *path); +TLI_DEFINE_ENUM_INTERNAL(remove) +TLI_DEFINE_STRING_INTERNAL("remove") +/// int rename(const char *old, const char *new); +TLI_DEFINE_ENUM_INTERNAL(rename) +TLI_DEFINE_STRING_INTERNAL("rename") +/// void rewind(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(rewind) +TLI_DEFINE_STRING_INTERNAL("rewind") +/// double rint(double x); +TLI_DEFINE_ENUM_INTERNAL(rint) +TLI_DEFINE_STRING_INTERNAL("rint") +/// float rintf(float x); +TLI_DEFINE_ENUM_INTERNAL(rintf) +TLI_DEFINE_STRING_INTERNAL("rintf") +/// long double rintl(long double x); +TLI_DEFINE_ENUM_INTERNAL(rintl) +TLI_DEFINE_STRING_INTERNAL("rintl") +/// int rmdir(const char *path); +TLI_DEFINE_ENUM_INTERNAL(rmdir) +TLI_DEFINE_STRING_INTERNAL("rmdir") +/// double round(double x); +TLI_DEFINE_ENUM_INTERNAL(round) +TLI_DEFINE_STRING_INTERNAL("round") +/// float roundf(float x); +TLI_DEFINE_ENUM_INTERNAL(roundf) +TLI_DEFINE_STRING_INTERNAL("roundf") +/// long double roundl(long double x); +TLI_DEFINE_ENUM_INTERNAL(roundl) +TLI_DEFINE_STRING_INTERNAL("roundl") +/// int scanf(const char *restrict format, ... ); +TLI_DEFINE_ENUM_INTERNAL(scanf) +TLI_DEFINE_STRING_INTERNAL("scanf") +/// void setbuf(FILE *stream, char *buf); +TLI_DEFINE_ENUM_INTERNAL(setbuf) +TLI_DEFINE_STRING_INTERNAL("setbuf") +/// int setitimer(int which, const struct itimerval *value, +/// struct itimerval *ovalue); +TLI_DEFINE_ENUM_INTERNAL(setitimer) +TLI_DEFINE_STRING_INTERNAL("setitimer") +/// int setvbuf(FILE *stream, char *buf, int type, size_t size); +TLI_DEFINE_ENUM_INTERNAL(setvbuf) +TLI_DEFINE_STRING_INTERNAL("setvbuf") +/// double sin(double x); +TLI_DEFINE_ENUM_INTERNAL(sin) +TLI_DEFINE_STRING_INTERNAL("sin") +/// float sinf(float x); +TLI_DEFINE_ENUM_INTERNAL(sinf) +TLI_DEFINE_STRING_INTERNAL("sinf") +/// double sinh(double x); +TLI_DEFINE_ENUM_INTERNAL(sinh) +TLI_DEFINE_STRING_INTERNAL("sinh") +/// float sinhf(float x); +TLI_DEFINE_ENUM_INTERNAL(sinhf) +TLI_DEFINE_STRING_INTERNAL("sinhf") +/// long double sinhl(long double x); +TLI_DEFINE_ENUM_INTERNAL(sinhl) +TLI_DEFINE_STRING_INTERNAL("sinhl") +/// long double sinl(long double x); +TLI_DEFINE_ENUM_INTERNAL(sinl) +TLI_DEFINE_STRING_INTERNAL("sinl") +/// int siprintf(char *str, const char *format, ...); +TLI_DEFINE_ENUM_INTERNAL(siprintf) +TLI_DEFINE_STRING_INTERNAL("siprintf") +/// int snprintf(char *s, size_t n, const char *format, ...); +TLI_DEFINE_ENUM_INTERNAL(snprintf) +TLI_DEFINE_STRING_INTERNAL("snprintf") +/// int sprintf(char *str, const char *format, ...); +TLI_DEFINE_ENUM_INTERNAL(sprintf) +TLI_DEFINE_STRING_INTERNAL("sprintf") +/// double sqrt(double x); +TLI_DEFINE_ENUM_INTERNAL(sqrt) +TLI_DEFINE_STRING_INTERNAL("sqrt") +/// float sqrtf(float x); +TLI_DEFINE_ENUM_INTERNAL(sqrtf) +TLI_DEFINE_STRING_INTERNAL("sqrtf") +/// long double sqrtl(long double x); +TLI_DEFINE_ENUM_INTERNAL(sqrtl) +TLI_DEFINE_STRING_INTERNAL("sqrtl") +/// int sscanf(const char *s, const char *format, ... ); +TLI_DEFINE_ENUM_INTERNAL(sscanf) +TLI_DEFINE_STRING_INTERNAL("sscanf") +/// int stat(const char *path, struct stat *buf); +TLI_DEFINE_ENUM_INTERNAL(stat) +TLI_DEFINE_STRING_INTERNAL("stat") +/// int stat64(const char *path, struct stat64 *buf); +TLI_DEFINE_ENUM_INTERNAL(stat64) +TLI_DEFINE_STRING_INTERNAL("stat64") +/// int statvfs(const char *path, struct statvfs *buf); +TLI_DEFINE_ENUM_INTERNAL(statvfs) +TLI_DEFINE_STRING_INTERNAL("statvfs") +/// int statvfs64(const char *path, struct statvfs64 *buf) +TLI_DEFINE_ENUM_INTERNAL(statvfs64) +TLI_DEFINE_STRING_INTERNAL("statvfs64") +/// char *stpcpy(char *s1, const char *s2); +TLI_DEFINE_ENUM_INTERNAL(stpcpy) +TLI_DEFINE_STRING_INTERNAL("stpcpy") +/// char *stpncpy(char *s1, const char *s2, size_t n); +TLI_DEFINE_ENUM_INTERNAL(stpncpy) +TLI_DEFINE_STRING_INTERNAL("stpncpy") +/// int strcasecmp(const char *s1, const char *s2); +TLI_DEFINE_ENUM_INTERNAL(strcasecmp) +TLI_DEFINE_STRING_INTERNAL("strcasecmp") +/// char *strcat(char *s1, const char *s2); +TLI_DEFINE_ENUM_INTERNAL(strcat) +TLI_DEFINE_STRING_INTERNAL("strcat") +/// char *strchr(const char *s, int c); +TLI_DEFINE_ENUM_INTERNAL(strchr) +TLI_DEFINE_STRING_INTERNAL("strchr") +/// int strcmp(const char *s1, const char *s2); +TLI_DEFINE_ENUM_INTERNAL(strcmp) +TLI_DEFINE_STRING_INTERNAL("strcmp") +/// int strcoll(const char *s1, const char *s2); +TLI_DEFINE_ENUM_INTERNAL(strcoll) +TLI_DEFINE_STRING_INTERNAL("strcoll") +/// char *strcpy(char *s1, const char *s2); +TLI_DEFINE_ENUM_INTERNAL(strcpy) +TLI_DEFINE_STRING_INTERNAL("strcpy") +/// size_t strcspn(const char *s1, const char *s2); +TLI_DEFINE_ENUM_INTERNAL(strcspn) +TLI_DEFINE_STRING_INTERNAL("strcspn") +/// char *strdup(const char *s1); +TLI_DEFINE_ENUM_INTERNAL(strdup) +TLI_DEFINE_STRING_INTERNAL("strdup") +/// size_t strlen(const char *s); +TLI_DEFINE_ENUM_INTERNAL(strlen) +TLI_DEFINE_STRING_INTERNAL("strlen") +/// int strncasecmp(const char *s1, const char *s2, size_t n); +TLI_DEFINE_ENUM_INTERNAL(strncasecmp) +TLI_DEFINE_STRING_INTERNAL("strncasecmp") +/// char *strncat(char *s1, const char *s2, size_t n); +TLI_DEFINE_ENUM_INTERNAL(strncat) +TLI_DEFINE_STRING_INTERNAL("strncat") +/// int strncmp(const char *s1, const char *s2, size_t n); +TLI_DEFINE_ENUM_INTERNAL(strncmp) +TLI_DEFINE_STRING_INTERNAL("strncmp") +/// char *strncpy(char *s1, const char *s2, size_t n); +TLI_DEFINE_ENUM_INTERNAL(strncpy) +TLI_DEFINE_STRING_INTERNAL("strncpy") +/// char *strndup(const char *s1, size_t n); +TLI_DEFINE_ENUM_INTERNAL(strndup) +TLI_DEFINE_STRING_INTERNAL("strndup") +/// size_t strnlen(const char *s, size_t maxlen); +TLI_DEFINE_ENUM_INTERNAL(strnlen) +TLI_DEFINE_STRING_INTERNAL("strnlen") +/// char *strpbrk(const char *s1, const char *s2); +TLI_DEFINE_ENUM_INTERNAL(strpbrk) +TLI_DEFINE_STRING_INTERNAL("strpbrk") +/// char *strrchr(const char *s, int c); +TLI_DEFINE_ENUM_INTERNAL(strrchr) +TLI_DEFINE_STRING_INTERNAL("strrchr") +/// size_t strspn(const char *s1, const char *s2); +TLI_DEFINE_ENUM_INTERNAL(strspn) +TLI_DEFINE_STRING_INTERNAL("strspn") +/// char *strstr(const char *s1, const char *s2); +TLI_DEFINE_ENUM_INTERNAL(strstr) +TLI_DEFINE_STRING_INTERNAL("strstr") +/// double strtod(const char *nptr, char **endptr); +TLI_DEFINE_ENUM_INTERNAL(strtod) +TLI_DEFINE_STRING_INTERNAL("strtod") +/// float strtof(const char *nptr, char **endptr); +TLI_DEFINE_ENUM_INTERNAL(strtof) +TLI_DEFINE_STRING_INTERNAL("strtof") +// char *strtok(char *s1, const char *s2); +TLI_DEFINE_ENUM_INTERNAL(strtok) +TLI_DEFINE_STRING_INTERNAL("strtok") +// char *strtok_r(char *s, const char *sep, char **lasts); +TLI_DEFINE_ENUM_INTERNAL(strtok_r) +TLI_DEFINE_STRING_INTERNAL("strtok_r") +/// long int strtol(const char *nptr, char **endptr, int base); +TLI_DEFINE_ENUM_INTERNAL(strtol) +TLI_DEFINE_STRING_INTERNAL("strtol") +/// long double strtold(const char *nptr, char **endptr); +TLI_DEFINE_ENUM_INTERNAL(strtold) +TLI_DEFINE_STRING_INTERNAL("strtold") +/// long long int strtoll(const char *nptr, char **endptr, int base); +TLI_DEFINE_ENUM_INTERNAL(strtoll) +TLI_DEFINE_STRING_INTERNAL("strtoll") +/// unsigned long int strtoul(const char *nptr, char **endptr, int base); +TLI_DEFINE_ENUM_INTERNAL(strtoul) +TLI_DEFINE_STRING_INTERNAL("strtoul") +/// unsigned long long int strtoull(const char *nptr, char **endptr, int base); +TLI_DEFINE_ENUM_INTERNAL(strtoull) +TLI_DEFINE_STRING_INTERNAL("strtoull") +/// size_t strxfrm(char *s1, const char *s2, size_t n); +TLI_DEFINE_ENUM_INTERNAL(strxfrm) +TLI_DEFINE_STRING_INTERNAL("strxfrm") +/// int system(const char *command); +TLI_DEFINE_ENUM_INTERNAL(system) +TLI_DEFINE_STRING_INTERNAL("system") +/// double tan(double x); +TLI_DEFINE_ENUM_INTERNAL(tan) +TLI_DEFINE_STRING_INTERNAL("tan") +/// float tanf(float x); +TLI_DEFINE_ENUM_INTERNAL(tanf) +TLI_DEFINE_STRING_INTERNAL("tanf") +/// double tanh(double x); +TLI_DEFINE_ENUM_INTERNAL(tanh) +TLI_DEFINE_STRING_INTERNAL("tanh") +/// float tanhf(float x); +TLI_DEFINE_ENUM_INTERNAL(tanhf) +TLI_DEFINE_STRING_INTERNAL("tanhf") +/// long double tanhl(long double x); +TLI_DEFINE_ENUM_INTERNAL(tanhl) +TLI_DEFINE_STRING_INTERNAL("tanhl") +/// long double tanl(long double x); +TLI_DEFINE_ENUM_INTERNAL(tanl) +TLI_DEFINE_STRING_INTERNAL("tanl") +/// clock_t times(struct tms *buffer); +TLI_DEFINE_ENUM_INTERNAL(times) +TLI_DEFINE_STRING_INTERNAL("times") +/// FILE *tmpfile(void); +TLI_DEFINE_ENUM_INTERNAL(tmpfile) +TLI_DEFINE_STRING_INTERNAL("tmpfile") +/// FILE *tmpfile64(void) +TLI_DEFINE_ENUM_INTERNAL(tmpfile64) +TLI_DEFINE_STRING_INTERNAL("tmpfile64") +/// int toascii(int c); +TLI_DEFINE_ENUM_INTERNAL(toascii) +TLI_DEFINE_STRING_INTERNAL("toascii") +/// double trunc(double x); +TLI_DEFINE_ENUM_INTERNAL(trunc) +TLI_DEFINE_STRING_INTERNAL("trunc") +/// float truncf(float x); +TLI_DEFINE_ENUM_INTERNAL(truncf) +TLI_DEFINE_STRING_INTERNAL("truncf") +/// long double truncl(long double x); +TLI_DEFINE_ENUM_INTERNAL(truncl) +TLI_DEFINE_STRING_INTERNAL("truncl") +/// int uname(struct utsname *name); +TLI_DEFINE_ENUM_INTERNAL(uname) +TLI_DEFINE_STRING_INTERNAL("uname") +/// int ungetc(int c, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(ungetc) +TLI_DEFINE_STRING_INTERNAL("ungetc") +/// int unlink(const char *path); +TLI_DEFINE_ENUM_INTERNAL(unlink) +TLI_DEFINE_STRING_INTERNAL("unlink") +/// int unsetenv(const char *name); +TLI_DEFINE_ENUM_INTERNAL(unsetenv) +TLI_DEFINE_STRING_INTERNAL("unsetenv") +/// int utime(const char *path, const struct utimbuf *times); +TLI_DEFINE_ENUM_INTERNAL(utime) +TLI_DEFINE_STRING_INTERNAL("utime") +/// int utimes(const char *path, const struct timeval times[2]); +TLI_DEFINE_ENUM_INTERNAL(utimes) +TLI_DEFINE_STRING_INTERNAL("utimes") +/// void *valloc(size_t size); +TLI_DEFINE_ENUM_INTERNAL(valloc) +TLI_DEFINE_STRING_INTERNAL("valloc") +/// int vfprintf(FILE *stream, const char *format, va_list ap); +TLI_DEFINE_ENUM_INTERNAL(vfprintf) +TLI_DEFINE_STRING_INTERNAL("vfprintf") +/// int vfscanf(FILE *stream, const char *format, va_list arg); +TLI_DEFINE_ENUM_INTERNAL(vfscanf) +TLI_DEFINE_STRING_INTERNAL("vfscanf") +/// int vprintf(const char *restrict format, va_list ap); +TLI_DEFINE_ENUM_INTERNAL(vprintf) +TLI_DEFINE_STRING_INTERNAL("vprintf") +/// int vscanf(const char *format, va_list arg); +TLI_DEFINE_ENUM_INTERNAL(vscanf) +TLI_DEFINE_STRING_INTERNAL("vscanf") +/// int vsnprintf(char *s, size_t n, const char *format, va_list ap); +TLI_DEFINE_ENUM_INTERNAL(vsnprintf) +TLI_DEFINE_STRING_INTERNAL("vsnprintf") +/// int vsprintf(char *s, const char *format, va_list ap); +TLI_DEFINE_ENUM_INTERNAL(vsprintf) +TLI_DEFINE_STRING_INTERNAL("vsprintf") +/// int vsscanf(const char *s, const char *format, va_list arg); +TLI_DEFINE_ENUM_INTERNAL(vsscanf) +TLI_DEFINE_STRING_INTERNAL("vsscanf") +/// ssize_t write(int fildes, const void *buf, size_t nbyte); +TLI_DEFINE_ENUM_INTERNAL(write) +TLI_DEFINE_STRING_INTERNAL("write") + +#undef TLI_DEFINE_ENUM_INTERNAL +#undef TLI_DEFINE_STRING_INTERNAL +#endif // One of TLI_DEFINE_ENUM/STRING are defined. + +#undef TLI_DEFINE_ENUM +#undef TLI_DEFINE_STRING diff --git a/include/llvm/Analysis/TargetLibraryInfo.h b/include/llvm/Analysis/TargetLibraryInfo.h index 5c6f364..9579848 100644 --- a/include/llvm/Analysis/TargetLibraryInfo.h +++ b/include/llvm/Analysis/TargetLibraryInfo.h @@ -11,6 +11,7 @@ #define LLVM_ANALYSIS_TARGETLIBRARYINFO_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/Triple.h" #include "llvm/IR/Function.h" @@ -29,679 +30,20 @@ // END ANDROID-SPECIFIC namespace llvm { +/// VecDesc - Describes a possible vectorization of a function. +/// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized +/// by a factor 'VectorizationFactor'. +struct VecDesc { + const char *ScalarFnName; + const char *VectorFnName; + unsigned VectorizationFactor; +}; class PreservedAnalyses; namespace LibFunc { enum Func { - /// int _IO_getc(_IO_FILE * __fp); - under_IO_getc, - /// int _IO_putc(int __c, _IO_FILE * __fp); - under_IO_putc, - /// void operator delete[](void*); - ZdaPv, - /// void operator delete[](void*, nothrow); - ZdaPvRKSt9nothrow_t, - /// void operator delete[](void*, unsigned int); - ZdaPvj, - /// void operator delete[](void*, unsigned long); - ZdaPvm, - /// void operator delete(void*); - ZdlPv, - /// void operator delete(void*, nothrow); - ZdlPvRKSt9nothrow_t, - /// void operator delete(void*, unsigned int); - ZdlPvj, - /// void operator delete(void*, unsigned long); - ZdlPvm, - /// void *new[](unsigned int); - Znaj, - /// void *new[](unsigned int, nothrow); - ZnajRKSt9nothrow_t, - /// void *new[](unsigned long); - Znam, - /// void *new[](unsigned long, nothrow); - ZnamRKSt9nothrow_t, - /// void *new(unsigned int); - Znwj, - /// void *new(unsigned int, nothrow); - ZnwjRKSt9nothrow_t, - /// void *new(unsigned long); - Znwm, - /// void *new(unsigned long, nothrow); - ZnwmRKSt9nothrow_t, - /// double __cospi(double x); - cospi, - /// float __cospif(float x); - cospif, - /// int __cxa_atexit(void (*f)(void *), void *p, void *d); - cxa_atexit, - /// void __cxa_guard_abort(guard_t *guard); - /// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi. - cxa_guard_abort, - /// int __cxa_guard_acquire(guard_t *guard); - cxa_guard_acquire, - /// void __cxa_guard_release(guard_t *guard); - cxa_guard_release, - /// int __isoc99_scanf (const char *format, ...) - dunder_isoc99_scanf, - /// int __isoc99_sscanf(const char *s, const char *format, ...) - dunder_isoc99_sscanf, - /// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size); - memcpy_chk, - /// void *__memmove_chk(void *s1, const void *s2, size_t n, - /// size_t s1size); - memmove_chk, - /// void *__memset_chk(void *s, char v, size_t n, size_t s1size); - memset_chk, - /// double __sincospi_stret(double x); - sincospi_stret, - /// float __sincospif_stret(float x); - sincospif_stret, - /// double __sinpi(double x); - sinpi, - /// float __sinpif(float x); - sinpif, - /// double __sqrt_finite(double x); - sqrt_finite, - /// float __sqrt_finite(float x); - sqrtf_finite, - /// long double __sqrt_finite(long double x); - sqrtl_finite, - /// char *__stpcpy_chk(char *s1, const char *s2, size_t s1size); - stpcpy_chk, - /// char *__stpncpy_chk(char *s1, const char *s2, size_t n, - /// size_t s1size); - stpncpy_chk, - /// char *__strcpy_chk(char *s1, const char *s2, size_t s1size); - strcpy_chk, - /// char * __strdup(const char *s); - dunder_strdup, - /// char *__strncpy_chk(char *s1, const char *s2, size_t n, - /// size_t s1size); - strncpy_chk, - /// char *__strndup(const char *s, size_t n); - dunder_strndup, - /// char * __strtok_r(char *s, const char *delim, char **save_ptr); - dunder_strtok_r, - /// int abs(int j); - abs, - /// int access(const char *path, int amode); - access, - /// double acos(double x); - acos, - /// float acosf(float x); - acosf, - /// double acosh(double x); - acosh, - /// float acoshf(float x); - acoshf, - /// long double acoshl(long double x); - acoshl, - /// long double acosl(long double x); - acosl, - /// double asin(double x); - asin, - /// float asinf(float x); - asinf, - /// double asinh(double x); - asinh, - /// float asinhf(float x); - asinhf, - /// long double asinhl(long double x); - asinhl, - /// long double asinl(long double x); - asinl, - /// double atan(double x); - atan, - /// double atan2(double y, double x); - atan2, - /// float atan2f(float y, float x); - atan2f, - /// long double atan2l(long double y, long double x); - atan2l, - /// float atanf(float x); - atanf, - /// double atanh(double x); - atanh, - /// float atanhf(float x); - atanhf, - /// long double atanhl(long double x); - atanhl, - /// long double atanl(long double x); - atanl, - /// double atof(const char *str); - atof, - /// int atoi(const char *str); - atoi, - /// long atol(const char *str); - atol, - /// long long atoll(const char *nptr); - atoll, - /// int bcmp(const void *s1, const void *s2, size_t n); - bcmp, - /// void bcopy(const void *s1, void *s2, size_t n); - bcopy, - /// void bzero(void *s, size_t n); - bzero, - /// void *calloc(size_t count, size_t size); - calloc, - /// double cbrt(double x); - cbrt, - /// float cbrtf(float x); - cbrtf, - /// long double cbrtl(long double x); - cbrtl, - /// double ceil(double x); - ceil, - /// float ceilf(float x); - ceilf, - /// long double ceill(long double x); - ceill, - /// int chmod(const char *path, mode_t mode); - chmod, - /// int chown(const char *path, uid_t owner, gid_t group); - chown, - /// void clearerr(FILE *stream); - clearerr, - /// int closedir(DIR *dirp); - closedir, - /// double copysign(double x, double y); - copysign, - /// float copysignf(float x, float y); - copysignf, - /// long double copysignl(long double x, long double y); - copysignl, - /// double cos(double x); - cos, - /// float cosf(float x); - cosf, - /// double cosh(double x); - cosh, - /// float coshf(float x); - coshf, - /// long double coshl(long double x); - coshl, - /// long double cosl(long double x); - cosl, - /// char *ctermid(char *s); - ctermid, - /// double exp(double x); - exp, - /// double exp10(double x); - exp10, - /// float exp10f(float x); - exp10f, - /// long double exp10l(long double x); - exp10l, - /// double exp2(double x); - exp2, - /// float exp2f(float x); - exp2f, - /// long double exp2l(long double x); - exp2l, - /// float expf(float x); - expf, - /// long double expl(long double x); - expl, - /// double expm1(double x); - expm1, - /// float expm1f(float x); - expm1f, - /// long double expm1l(long double x); - expm1l, - /// double fabs(double x); - fabs, - /// float fabsf(float x); - fabsf, - /// long double fabsl(long double x); - fabsl, - /// int fclose(FILE *stream); - fclose, - /// FILE *fdopen(int fildes, const char *mode); - fdopen, - /// int feof(FILE *stream); - feof, - /// int ferror(FILE *stream); - ferror, - /// int fflush(FILE *stream); - fflush, - /// int ffs(int i); - ffs, - /// int ffsl(long int i); - ffsl, - /// int ffsll(long long int i); - ffsll, - /// int fgetc(FILE *stream); - fgetc, - /// int fgetpos(FILE *stream, fpos_t *pos); - fgetpos, - /// char *fgets(char *s, int n, FILE *stream); - fgets, - /// int fileno(FILE *stream); - fileno, - /// int fiprintf(FILE *stream, const char *format, ...); - fiprintf, - /// void flockfile(FILE *file); - flockfile, - /// double floor(double x); - floor, - /// float floorf(float x); - floorf, - /// long double floorl(long double x); - floorl, - /// double fmax(double x, double y); - fmax, - /// float fmaxf(float x, float y); - fmaxf, - /// long double fmaxl(long double x, long double y); - fmaxl, - /// double fmin(double x, double y); - fmin, - /// float fminf(float x, float y); - fminf, - /// long double fminl(long double x, long double y); - fminl, - /// double fmod(double x, double y); - fmod, - /// float fmodf(float x, float y); - fmodf, - /// long double fmodl(long double x, long double y); - fmodl, - /// FILE *fopen(const char *filename, const char *mode); - fopen, - /// FILE *fopen64(const char *filename, const char *opentype) - fopen64, - /// int fprintf(FILE *stream, const char *format, ...); - fprintf, - /// int fputc(int c, FILE *stream); - fputc, - /// int fputs(const char *s, FILE *stream); - fputs, - /// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream); - fread, - /// void free(void *ptr); - free, - /// double frexp(double num, int *exp); - frexp, - /// float frexpf(float num, int *exp); - frexpf, - /// long double frexpl(long double num, int *exp); - frexpl, - /// int fscanf(FILE *stream, const char *format, ... ); - fscanf, - /// int fseek(FILE *stream, long offset, int whence); - fseek, - /// int fseeko(FILE *stream, off_t offset, int whence); - fseeko, - /// int fseeko64(FILE *stream, off64_t offset, int whence) - fseeko64, - /// int fsetpos(FILE *stream, const fpos_t *pos); - fsetpos, - /// int fstat(int fildes, struct stat *buf); - fstat, - /// int fstat64(int filedes, struct stat64 *buf) - fstat64, - /// int fstatvfs(int fildes, struct statvfs *buf); - fstatvfs, - /// int fstatvfs64(int fildes, struct statvfs64 *buf); - fstatvfs64, - /// long ftell(FILE *stream); - ftell, - /// off_t ftello(FILE *stream); - ftello, - /// off64_t ftello64(FILE *stream) - ftello64, - /// int ftrylockfile(FILE *file); - ftrylockfile, - /// void funlockfile(FILE *file); - funlockfile, - /// size_t fwrite(const void *ptr, size_t size, size_t nitems, - /// FILE *stream); - fwrite, - /// int getc(FILE *stream); - getc, - /// int getc_unlocked(FILE *stream); - getc_unlocked, - /// int getchar(void); - getchar, - /// char *getenv(const char *name); - getenv, - /// int getitimer(int which, struct itimerval *value); - getitimer, - /// int getlogin_r(char *name, size_t namesize); - getlogin_r, - /// struct passwd *getpwnam(const char *name); - getpwnam, - /// char *gets(char *s); - gets, - /// int gettimeofday(struct timeval *tp, void *tzp); - gettimeofday, - /// uint32_t htonl(uint32_t hostlong); - htonl, - /// uint16_t htons(uint16_t hostshort); - htons, - /// int iprintf(const char *format, ...); - iprintf, - /// int isascii(int c); - isascii, - /// int isdigit(int c); - isdigit, - /// long int labs(long int j); - labs, - /// int lchown(const char *path, uid_t owner, gid_t group); - lchown, - /// double ldexp(double x, int n); - ldexp, - /// float ldexpf(float x, int n); - ldexpf, - /// long double ldexpl(long double x, int n); - ldexpl, - /// long long int llabs(long long int j); - llabs, - /// double log(double x); - log, - /// double log10(double x); - log10, - /// float log10f(float x); - log10f, - /// long double log10l(long double x); - log10l, - /// double log1p(double x); - log1p, - /// float log1pf(float x); - log1pf, - /// long double log1pl(long double x); - log1pl, - /// double log2(double x); - log2, - /// float log2f(float x); - log2f, - /// double long double log2l(long double x); - log2l, - /// double logb(double x); - logb, - /// float logbf(float x); - logbf, - /// long double logbl(long double x); - logbl, - /// float logf(float x); - logf, - /// long double logl(long double x); - logl, - /// int lstat(const char *path, struct stat *buf); - lstat, - /// int lstat64(const char *path, struct stat64 *buf); - lstat64, - /// void *malloc(size_t size); - malloc, - /// void *memalign(size_t boundary, size_t size); - memalign, - /// void *memccpy(void *s1, const void *s2, int c, size_t n); - memccpy, - /// void *memchr(const void *s, int c, size_t n); - memchr, - /// int memcmp(const void *s1, const void *s2, size_t n); - memcmp, - /// void *memcpy(void *s1, const void *s2, size_t n); - memcpy, - /// void *memmove(void *s1, const void *s2, size_t n); - memmove, - // void *memrchr(const void *s, int c, size_t n); - memrchr, - /// void *memset(void *b, int c, size_t len); - memset, - /// void memset_pattern16(void *b, const void *pattern16, size_t len); - memset_pattern16, - /// int mkdir(const char *path, mode_t mode); - mkdir, - /// time_t mktime(struct tm *timeptr); - mktime, - /// double modf(double x, double *iptr); - modf, - /// float modff(float, float *iptr); - modff, - /// long double modfl(long double value, long double *iptr); - modfl, - /// double nearbyint(double x); - nearbyint, - /// float nearbyintf(float x); - nearbyintf, - /// long double nearbyintl(long double x); - nearbyintl, - /// uint32_t ntohl(uint32_t netlong); - ntohl, - /// uint16_t ntohs(uint16_t netshort); - ntohs, - /// int open(const char *path, int oflag, ... ); - open, - /// int open64(const char *filename, int flags[, mode_t mode]) - open64, - /// DIR *opendir(const char *dirname); - opendir, - /// int pclose(FILE *stream); - pclose, - /// void perror(const char *s); - perror, - /// FILE *popen(const char *command, const char *mode); - popen, - /// int posix_memalign(void **memptr, size_t alignment, size_t size); - posix_memalign, - /// double pow(double x, double y); - pow, - /// float powf(float x, float y); - powf, - /// long double powl(long double x, long double y); - powl, - /// ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset); - pread, - /// int printf(const char *format, ...); - printf, - /// int putc(int c, FILE *stream); - putc, - /// int putchar(int c); - putchar, - /// int puts(const char *s); - puts, - /// ssize_t pwrite(int fildes, const void *buf, size_t nbyte, - /// off_t offset); - pwrite, - /// void qsort(void *base, size_t nel, size_t width, - /// int (*compar)(const void *, const void *)); - qsort, - /// ssize_t read(int fildes, void *buf, size_t nbyte); - read, - /// ssize_t readlink(const char *path, char *buf, size_t bufsize); - readlink, - /// void *realloc(void *ptr, size_t size); - realloc, - /// void *reallocf(void *ptr, size_t size); - reallocf, - /// char *realpath(const char *file_name, char *resolved_name); - realpath, - /// int remove(const char *path); - remove, - /// int rename(const char *old, const char *new); - rename, - /// void rewind(FILE *stream); - rewind, - /// double rint(double x); - rint, - /// float rintf(float x); - rintf, - /// long double rintl(long double x); - rintl, - /// int rmdir(const char *path); - rmdir, - /// double round(double x); - round, - /// float roundf(float x); - roundf, - /// long double roundl(long double x); - roundl, - /// int scanf(const char *restrict format, ... ); - scanf, - /// void setbuf(FILE *stream, char *buf); - setbuf, - /// int setitimer(int which, const struct itimerval *value, - /// struct itimerval *ovalue); - setitimer, - /// int setvbuf(FILE *stream, char *buf, int type, size_t size); - setvbuf, - /// double sin(double x); - sin, - /// float sinf(float x); - sinf, - /// double sinh(double x); - sinh, - /// float sinhf(float x); - sinhf, - /// long double sinhl(long double x); - sinhl, - /// long double sinl(long double x); - sinl, - /// int siprintf(char *str, const char *format, ...); - siprintf, - /// int snprintf(char *s, size_t n, const char *format, ...); - snprintf, - /// int sprintf(char *str, const char *format, ...); - sprintf, - /// double sqrt(double x); - sqrt, - /// float sqrtf(float x); - sqrtf, - /// long double sqrtl(long double x); - sqrtl, - /// int sscanf(const char *s, const char *format, ... ); - sscanf, - /// int stat(const char *path, struct stat *buf); - stat, - /// int stat64(const char *path, struct stat64 *buf); - stat64, - /// int statvfs(const char *path, struct statvfs *buf); - statvfs, - /// int statvfs64(const char *path, struct statvfs64 *buf) - statvfs64, - /// char *stpcpy(char *s1, const char *s2); - stpcpy, - /// char *stpncpy(char *s1, const char *s2, size_t n); - stpncpy, - /// int strcasecmp(const char *s1, const char *s2); - strcasecmp, - /// char *strcat(char *s1, const char *s2); - strcat, - /// char *strchr(const char *s, int c); - strchr, - /// int strcmp(const char *s1, const char *s2); - strcmp, - /// int strcoll(const char *s1, const char *s2); - strcoll, - /// char *strcpy(char *s1, const char *s2); - strcpy, - /// size_t strcspn(const char *s1, const char *s2); - strcspn, - /// char *strdup(const char *s1); - strdup, - /// size_t strlen(const char *s); - strlen, - /// int strncasecmp(const char *s1, const char *s2, size_t n); - strncasecmp, - /// char *strncat(char *s1, const char *s2, size_t n); - strncat, - /// int strncmp(const char *s1, const char *s2, size_t n); - strncmp, - /// char *strncpy(char *s1, const char *s2, size_t n); - strncpy, - /// char *strndup(const char *s1, size_t n); - strndup, - /// size_t strnlen(const char *s, size_t maxlen); - strnlen, - /// char *strpbrk(const char *s1, const char *s2); - strpbrk, - /// char *strrchr(const char *s, int c); - strrchr, - /// size_t strspn(const char *s1, const char *s2); - strspn, - /// char *strstr(const char *s1, const char *s2); - strstr, - /// double strtod(const char *nptr, char **endptr); - strtod, - /// float strtof(const char *nptr, char **endptr); - strtof, - // char *strtok(char *s1, const char *s2); - strtok, - // char *strtok_r(char *s, const char *sep, char **lasts); - strtok_r, - /// long int strtol(const char *nptr, char **endptr, int base); - strtol, - /// long double strtold(const char *nptr, char **endptr); - strtold, - /// long long int strtoll(const char *nptr, char **endptr, int base); - strtoll, - /// unsigned long int strtoul(const char *nptr, char **endptr, int base); - strtoul, - /// unsigned long long int strtoull(const char *nptr, char **endptr, - /// int base); - strtoull, - /// size_t strxfrm(char *s1, const char *s2, size_t n); - strxfrm, - /// int system(const char *command); - system, - /// double tan(double x); - tan, - /// float tanf(float x); - tanf, - /// double tanh(double x); - tanh, - /// float tanhf(float x); - tanhf, - /// long double tanhl(long double x); - tanhl, - /// long double tanl(long double x); - tanl, - /// clock_t times(struct tms *buffer); - times, - /// FILE *tmpfile(void); - tmpfile, - /// FILE *tmpfile64(void) - tmpfile64, - /// int toascii(int c); - toascii, - /// double trunc(double x); - trunc, - /// float truncf(float x); - truncf, - /// long double truncl(long double x); - truncl, - /// int uname(struct utsname *name); - uname, - /// int ungetc(int c, FILE *stream); - ungetc, - /// int unlink(const char *path); - unlink, - /// int unsetenv(const char *name); - unsetenv, - /// int utime(const char *path, const struct utimbuf *times); - utime, - /// int utimes(const char *path, const struct timeval times[2]); - utimes, - /// void *valloc(size_t size); - valloc, - /// int vfprintf(FILE *stream, const char *format, va_list ap); - vfprintf, - /// int vfscanf(FILE *stream, const char *format, va_list arg); - vfscanf, - /// int vprintf(const char *restrict format, va_list ap); - vprintf, - /// int vscanf(const char *format, va_list arg); - vscanf, - /// int vsnprintf(char *s, size_t n, const char *format, va_list ap); - vsnprintf, - /// int vsprintf(char *s, const char *format, va_list ap); - vsprintf, - /// int vsscanf(const char *s, const char *format, va_list arg); - vsscanf, - /// ssize_t write(int fildes, const void *buf, size_t nbyte); - write, +#define TLI_DEFINE_ENUM +#include "llvm/Analysis/TargetLibraryInfo.def" NumLibFuncs }; @@ -718,7 +60,7 @@ class TargetLibraryInfoImpl { unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4]; llvm::DenseMap<unsigned, std::string> CustomNames; - static const char* StandardNames[LibFunc::NumLibFuncs]; + static const char *const StandardNames[LibFunc::NumLibFuncs]; enum AvailabilityState { StandardName = 3, // (memset to all ones) @@ -733,7 +75,25 @@ class TargetLibraryInfoImpl { return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3); } + /// Vectorization descriptors - sorted by ScalarFnName. + std::vector<VecDesc> VectorDescs; + /// Scalarization descriptors - same content as VectorDescs but sorted based + /// on VectorFnName rather than ScalarFnName. + std::vector<VecDesc> ScalarDescs; + public: + /// \brief List of known vector-functions libraries. + /// + /// The vector-functions library defines, which functions are vectorizable + /// and with which factor. The library can be specified by either frontend, + /// or a commandline option, and then used by + /// addVectorizableFunctionsFromVecLib for filling up the tables of + /// vectorizable functions. + enum VectorLibrary { + NoLibrary, // Don't use any vector library. + Accelerate // Use Accelerate framework. + }; + TargetLibraryInfoImpl(); explicit TargetLibraryInfoImpl(const Triple &T); @@ -775,6 +135,41 @@ public: /// /// This can be used for options like -fno-builtin. void disableAllFunctions(); + + /// addVectorizableFunctions - Add a set of scalar -> vector mappings, + /// queryable via getVectorizedFunction and getScalarizedFunction. + void addVectorizableFunctions(ArrayRef<VecDesc> Fns); + + /// Calls addVectorizableFunctions with a known preset of functions for the + /// given vector library. + void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib); + + /// isFunctionVectorizable - Return true if the function F has a + /// vector equivalent with vectorization factor VF. + bool isFunctionVectorizable(StringRef F, unsigned VF) const { + return !getVectorizedFunction(F, VF).empty(); + } + + /// isFunctionVectorizable - Return true if the function F has a + /// vector equivalent with any vectorization factor. + bool isFunctionVectorizable(StringRef F) const; + + /// getVectorizedFunction - Return the name of the equivalent of + /// F, vectorized with factor VF. If no such mapping exists, + /// return the empty string. + StringRef getVectorizedFunction(StringRef F, unsigned VF) const; + + /// isFunctionScalarizable - Return true if the function F has a + /// scalar equivalent, and set VF to be the vectorization factor. + bool isFunctionScalarizable(StringRef F, unsigned &VF) const { + return !getScalarizedFunction(F, VF).empty(); + } + + /// getScalarizedFunction - Return the name of the equivalent of + /// F, scalarized. If no such mapping exists, return the empty string. + /// + /// Set VF to the vectorization factor. + StringRef getScalarizedFunction(StringRef F, unsigned &VF) const; }; /// \brief Provides information about what library functions are available for @@ -811,10 +206,19 @@ public: return Impl->getLibFunc(funcName, F); } - /// \brief Tests wether a library function is available. + /// \brief Tests whether a library function is available. bool has(LibFunc::Func F) const { return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable; } + bool isFunctionVectorizable(StringRef F, unsigned VF) const { + return Impl->isFunctionVectorizable(F, VF); + }; + bool isFunctionVectorizable(StringRef F) const { + return Impl->isFunctionVectorizable(F); + }; + StringRef getVectorizedFunction(StringRef F, unsigned VF) const { + return Impl->getVectorizedFunction(F, VF); + }; /// \brief Tests if the function is both available and a candidate for /// optimized code generation. diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h index 4998141..fdb2010 100644 --- a/include/llvm/Analysis/TargetTransformInfo.h +++ b/include/llvm/Analysis/TargetTransformInfo.h @@ -27,6 +27,7 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/Pass.h" #include "llvm/Support/DataTypes.h" +#include <functional> namespace llvm { @@ -330,6 +331,9 @@ public: /// target. bool shouldBuildLookupTables() const; + /// \brief Don't restrict interleaved unrolling to small loops. + bool enableAggressiveInterleaving(bool LoopHasReductions) const; + /// \brief Return hardware support for population count. PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const; @@ -448,6 +452,10 @@ public: unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, ArrayRef<Type *> Tys) const; + /// \returns The cost of Call instructions. + unsigned getCallInstrCost(Function *F, Type *RetTy, + ArrayRef<Type *> Tys) const; + /// \returns The number of pieces into which the provided type must be /// split during legalization. Zero is returned when the answer is unknown. unsigned getNumberOfParts(Type *Tp) const; @@ -530,6 +538,7 @@ public: virtual unsigned getJumpBufAlignment() = 0; virtual unsigned getJumpBufSize() = 0; virtual bool shouldBuildLookupTables() = 0; + virtual bool enableAggressiveInterleaving(bool LoopHasReductions) = 0; virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) = 0; virtual bool haveFastSqrt(Type *Ty) = 0; virtual unsigned getFPOpCost(Type *Ty) = 0; @@ -564,6 +573,8 @@ public: bool IsPairwiseForm) = 0; virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, ArrayRef<Type *> Tys) = 0; + virtual unsigned getCallInstrCost(Function *F, Type *RetTy, + ArrayRef<Type *> Tys) = 0; virtual unsigned getNumberOfParts(Type *Tp) = 0; virtual unsigned getAddressComputationCost(Type *Ty, bool IsComplex) = 0; virtual unsigned getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) = 0; @@ -647,6 +658,9 @@ public: bool shouldBuildLookupTables() override { return Impl.shouldBuildLookupTables(); } + bool enableAggressiveInterleaving(bool LoopHasReductions) override { + return Impl.enableAggressiveInterleaving(LoopHasReductions); + } PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) override { return Impl.getPopcntSupport(IntTyWidthInBit); } @@ -718,6 +732,10 @@ public: ArrayRef<Type *> Tys) override { return Impl.getIntrinsicInstrCost(ID, RetTy, Tys); } + unsigned getCallInstrCost(Function *F, Type *RetTy, + ArrayRef<Type *> Tys) override { + return Impl.getCallInstrCost(F, RetTy, Tys); + } unsigned getNumberOfParts(Type *Tp) override { return Impl.getNumberOfParts(Tp); } diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h index 3e02c0c..f4bf07f 100644 --- a/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -235,6 +235,8 @@ public: bool shouldBuildLookupTables() { return true; } + bool enableAggressiveInterleaving(bool LoopHasReductions) { return false; } + TTI::PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) { return TTI::PSK_Software; } @@ -301,6 +303,10 @@ public: return 1; } + unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys) { + return 1; + } + unsigned getNumberOfParts(Type *Tp) { return 0; } unsigned getAddressComputationCost(Type *Tp, bool) { return 0; } diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index ac8c3b7..8955b7c 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -33,12 +33,12 @@ namespace llvm { /// them in the KnownZero/KnownOne bit sets. /// /// This function is defined on values with integer type, values with pointer - /// type (but only if TD is non-null), and vectors of integers. In the case + /// type, and vectors of integers. In the case /// where V is a vector, the known zero and known one values are the /// same width as the vector element, and the bit is set only if it is true /// for all of the elements in the vector. void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne, - const DataLayout *TD = nullptr, unsigned Depth = 0, + const DataLayout &DL, unsigned Depth = 0, AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr); @@ -50,7 +50,7 @@ namespace llvm { /// ComputeSignBit - Determine whether the sign bit is known to be zero or /// one. Convenience wrapper around computeKnownBits. void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne, - const DataLayout *TD = nullptr, unsigned Depth = 0, + const DataLayout &DL, unsigned Depth = 0, AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr); @@ -60,7 +60,8 @@ namespace llvm { /// element is known to be a power of two when defined. Supports values with /// integer or pointer type and vectors of integers. If 'OrZero' is set then /// returns true if the given value is either a power of two or zero. - bool isKnownToBeAPowerOfTwo(Value *V, bool OrZero = false, unsigned Depth = 0, + bool isKnownToBeAPowerOfTwo(Value *V, const DataLayout &DL, + bool OrZero = false, unsigned Depth = 0, AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr); @@ -69,8 +70,8 @@ namespace llvm { /// when defined. For vectors return true if every element is known to be /// non-zero when defined. Supports values with integer or pointer type and /// vectors of integers. - bool isKnownNonZero(Value *V, const DataLayout *TD = nullptr, - unsigned Depth = 0, AssumptionCache *AC = nullptr, + bool isKnownNonZero(Value *V, const DataLayout &DL, unsigned Depth = 0, + AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr); @@ -79,13 +80,12 @@ namespace llvm { /// zero for bits that V cannot have. /// /// This function is defined on values with integer type, values with pointer - /// type (but only if TD is non-null), and vectors of integers. In the case + /// type, and vectors of integers. In the case /// where V is a vector, the mask, known zero, and known one values are the /// same width as the vector element, and the bit is set only if it is true /// for all of the elements in the vector. - bool MaskedValueIsZero(Value *V, const APInt &Mask, - const DataLayout *TD = nullptr, unsigned Depth = 0, - AssumptionCache *AC = nullptr, + bool MaskedValueIsZero(Value *V, const APInt &Mask, const DataLayout &DL, + unsigned Depth = 0, AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr); @@ -97,7 +97,7 @@ namespace llvm { /// /// 'Op' must have a scalar integer type. /// - unsigned ComputeNumSignBits(Value *Op, const DataLayout *TD = nullptr, + unsigned ComputeNumSignBits(Value *Op, const DataLayout &DL, unsigned Depth = 0, AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr); @@ -142,11 +142,12 @@ namespace llvm { /// it can be expressed as a base pointer plus a constant offset. Return the /// base and offset to the caller. Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, - const DataLayout *TD); + const DataLayout &DL); static inline const Value * GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset, - const DataLayout *TD) { - return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD); + const DataLayout &DL) { + return GetPointerBaseWithConstantOffset(const_cast<Value *>(Ptr), Offset, + DL); } /// getConstantStringInfo - This function computes the length of a @@ -167,21 +168,19 @@ namespace llvm { /// being addressed. Note that the returned value has pointer type if the /// specified value does. If the MaxLookup value is non-zero, it limits the /// number of instructions to be stripped off. - Value *GetUnderlyingObject(Value *V, const DataLayout *TD = nullptr, + Value *GetUnderlyingObject(Value *V, const DataLayout &DL, unsigned MaxLookup = 6); - static inline const Value * - GetUnderlyingObject(const Value *V, const DataLayout *TD = nullptr, - unsigned MaxLookup = 6) { - return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup); + static inline const Value *GetUnderlyingObject(const Value *V, + const DataLayout &DL, + unsigned MaxLookup = 6) { + return GetUnderlyingObject(const_cast<Value *>(V), DL, MaxLookup); } /// GetUnderlyingObjects - This method is similar to GetUnderlyingObject /// except that it can look through phi and select instructions and return /// multiple objects. - void GetUnderlyingObjects(Value *V, - SmallVectorImpl<Value *> &Objects, - const DataLayout *TD = nullptr, - unsigned MaxLookup = 6); + void GetUnderlyingObjects(Value *V, SmallVectorImpl<Value *> &Objects, + const DataLayout &DL, unsigned MaxLookup = 6); /// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer /// are lifetime markers. @@ -205,8 +204,7 @@ namespace llvm { /// the correct dominance relationships for the operands and users hold. /// However, this method can return true for instructions that read memory; /// for such instructions, moving them may change the resulting value. - bool isSafeToSpeculativelyExecute(const Value *V, - const DataLayout *TD = nullptr); + bool isSafeToSpeculativelyExecute(const Value *V); /// isKnownNonNull - Return true if this pointer couldn't possibly be null by /// its definition. This returns true for allocas, non-extern-weak globals @@ -217,17 +215,16 @@ namespace llvm { /// assume intrinsic, I, at the point in the control-flow identified by the /// context instruction, CxtI. bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI, - const DataLayout *DL = nullptr, const DominatorTree *DT = nullptr); enum class OverflowResult { AlwaysOverflows, MayOverflow, NeverOverflows }; OverflowResult computeOverflowForUnsignedMul(Value *LHS, Value *RHS, - const DataLayout *DL, + const DataLayout &DL, AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT); OverflowResult computeOverflowForUnsignedAdd(Value *LHS, Value *RHS, - const DataLayout *DL, + const DataLayout &DL, AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT); diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h index c20a160..18f6b9e 100644 --- a/include/llvm/Bitcode/BitstreamReader.h +++ b/include/llvm/Bitcode/BitstreamReader.h @@ -24,8 +24,6 @@ namespace llvm { -class Deserializer; - /// This class is used to read from an LLVM bitcode stream, maintaining /// information that is global to decoding the entire file. While a file is /// being read, multiple cursors can be independently advanced or skipped around @@ -164,7 +162,6 @@ struct BitstreamEntry { /// Unlike iterators, BitstreamCursors are heavy-weight objects that should not /// be passed by value. class BitstreamCursor { - friend class Deserializer; BitstreamReader *BitStream; size_t NextChar; diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h index 48bdabc..254949d 100644 --- a/include/llvm/Bitcode/ReaderWriter.h +++ b/include/llvm/Bitcode/ReaderWriter.h @@ -29,12 +29,14 @@ namespace llvm { class raw_ostream; /// Read the header of the specified bitcode buffer and prepare for lazy - /// deserialization of function bodies. If successful, this moves Buffer. On + /// deserialization of function bodies. If ShouldLazyLoadMetadata is true, + /// lazily load metadata as well. If successful, this moves Buffer. On /// error, this *does not* move Buffer. ErrorOr<Module *> getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer, LLVMContext &Context, - DiagnosticHandlerFunction DiagnosticHandler = nullptr); + DiagnosticHandlerFunction DiagnosticHandler = nullptr, + bool ShouldLazyLoadMetadata = false); /// Read the header of the specified stream and prepare for lazy /// deserialization and streaming of function bodies. diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index ac224d8..d364012 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -16,6 +16,7 @@ #ifndef LLVM_CODEGEN_ASMPRINTER_H #define LLVM_CODEGEN_ASMPRINTER_H +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/Twine.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/IR/InlineAsm.h" @@ -29,6 +30,8 @@ class ByteStreamer; class GCStrategy; class Constant; class ConstantArray; +class DIE; +class DIEAbbrev; class GCMetadataPrinter; class GlobalValue; class GlobalVariable; @@ -100,9 +103,13 @@ public: /// Map global GOT equivalent MCSymbols to GlobalVariables and keep track of /// its number of uses by other globals. typedef std::pair<const GlobalVariable *, unsigned> GOTEquivUsePair; - DenseMap<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs; + MapVector<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs; private: + MCSymbol *CurrentFnBegin; + MCSymbol *CurrentFnEnd; + MCSymbol *CurExceptionSym; + // The garbage collection metadata printer table. void *GCMetadataPrinters; // Really a DenseMap. @@ -146,6 +153,10 @@ public: /// unsigned getFunctionNumber() const; + MCSymbol *getFunctionBegin() const { return CurrentFnBegin; } + MCSymbol *getFunctionEnd() const { return CurrentFnEnd; } + MCSymbol *getCurExceptionSym(); + /// Return information about object file lowering. const TargetLoweringObjectFile &getObjFileLowering() const; @@ -187,7 +198,6 @@ public: /// Emit the specified function out to the OutStreamer. bool runOnMachineFunction(MachineFunction &MF) override { SetupMachineFunction(MF); - EmitFunctionHeader(); EmitFunctionBody(); return false; } @@ -200,9 +210,6 @@ public: /// runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); - /// This method emits the header for the current function. - void EmitFunctionHeader(); - /// This method emits the body and trailer for a function. void EmitFunctionBody(); @@ -324,12 +331,7 @@ public: // Symbol Lowering Routines. //===------------------------------------------------------------------===// public: - /// Return the MCSymbol corresponding to the assembler temporary label with - /// the specified stem and unique ID. - MCSymbol *GetTempSymbol(const Twine &Name, unsigned ID) const; - - /// Return an assembler temporary label with the specified stem. - MCSymbol *GetTempSymbol(const Twine &Name) const; + MCSymbol *createTempSymbol(const Twine &Name) const; /// Return the MCSymbol for a private symbol with global value name as its /// base, with the specified suffix. @@ -417,37 +419,10 @@ public: /// Emit the 4-byte offset of Label from the start of its section. This can /// be done with a special directive if the target supports it (e.g. cygwin) /// or by emitting it as an offset from a label at the start of the section. - /// - /// SectionLabel is a temporary label emitted at the start of the section - /// that Label lives in. - void EmitSectionOffset(const MCSymbol *Label, - const MCSymbol *SectionLabel) const; + void emitSectionOffset(const MCSymbol *Label) const; /// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified. - virtual unsigned getISAEncoding(const Function *) { return 0; } - - /// Emit a dwarf register operation for describing - /// - a small value occupying only part of a register or - /// - a register representing only part of a value. - void EmitDwarfOpPiece(ByteStreamer &Streamer, unsigned SizeInBits, - unsigned OffsetInBits = 0) const; - - - /// \brief Emit a partial DWARF register operation. - /// \param MLoc the register - /// \param PieceSize size and - /// \param PieceOffset offset of the piece in bits, if this is one - /// piece of an aggregate value. - /// - /// If size and offset is zero an operation for the entire - /// register is emitted: Some targets do not provide a DWARF - /// register number for every register. If this is the case, this - /// function will attempt to emit a DWARF register by emitting a - /// piece of a super-register or by piecing together multiple - /// subregisters that alias the register. - void EmitDwarfRegOpPiece(ByteStreamer &BS, const MachineLocation &MLoc, - unsigned PieceSize = 0, - unsigned PieceOffset = 0) const; + virtual unsigned getISAEncoding() { return 0; } /// EmitDwarfRegOp - Emit a dwarf register operation. virtual void EmitDwarfRegOp(ByteStreamer &BS, @@ -460,6 +435,12 @@ public: /// \brief Emit frame instruction to describe the layout of the frame. void emitCFIInstruction(const MCCFIInstruction &Inst) const; + /// \brief Emit Dwarf abbreviation table. + void emitDwarfAbbrevs(const std::vector<DIEAbbrev *>& Abbrevs) const; + + /// \brief Recursively emit Dwarf DIE tree. + void emitDwarfDIE(const DIE &Die) const; + //===------------------------------------------------------------------===// // Inline Asm Support //===------------------------------------------------------------------===// @@ -510,11 +491,14 @@ private: mutable const MachineInstr *LastMI; mutable unsigned LastFn; mutable unsigned Counter; - mutable unsigned SetCounter; + + /// This method emits the header for the current function. + void EmitFunctionHeader(); /// Emit a blob of inline asm to the output streamer. void - EmitInlineAsm(StringRef Str, const MDNode *LocMDNode = nullptr, + EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI, + const MDNode *LocMDNode = nullptr, InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const; /// This method formats and emits the specified machine instruction that is an diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h index ff85b06..e1e5112 100644 --- a/include/llvm/CodeGen/BasicTTIImpl.h +++ b/include/llvm/CodeGen/BasicTTIImpl.h @@ -21,6 +21,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/Analysis/TargetLibraryInfo.h" namespace llvm { @@ -527,18 +528,29 @@ public: // Assume that we need to scalarize this intrinsic. unsigned ScalarizationCost = 0; unsigned ScalarCalls = 1; + Type *ScalarRetTy = RetTy; if (RetTy->isVectorTy()) { ScalarizationCost = getScalarizationOverhead(RetTy, true, false); ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements()); + ScalarRetTy = RetTy->getScalarType(); } + SmallVector<Type *, 4> ScalarTys; for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) { - if (Tys[i]->isVectorTy()) { - ScalarizationCost += getScalarizationOverhead(Tys[i], false, true); - ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements()); + Type *Ty = Tys[i]; + if (Ty->isVectorTy()) { + ScalarizationCost += getScalarizationOverhead(Ty, false, true); + ScalarCalls = std::max(ScalarCalls, Ty->getVectorNumElements()); + Ty = Ty->getScalarType(); } + ScalarTys.push_back(Ty); } + if (ScalarCalls == 1) + return 1; // Return cost of a scalar intrinsic. Assume it to be cheap. - return ScalarCalls + ScalarizationCost; + unsigned ScalarCost = static_cast<T *>(this)->getIntrinsicInstrCost( + IID, ScalarRetTy, ScalarTys); + + return ScalarCalls * ScalarCost + ScalarizationCost; } // Look for intrinsics that can be lowered directly or turned into a scalar // intrinsic call. @@ -648,16 +660,46 @@ public: // this will emit a costly libcall, adding call overhead and spills. Make it // very expensive. if (RetTy->isVectorTy()) { - unsigned Num = RetTy->getVectorNumElements(); - unsigned Cost = static_cast<T *>(this)->getIntrinsicInstrCost( - IID, RetTy->getScalarType(), Tys); - return 10 * Cost * Num; + unsigned ScalarizationCost = getScalarizationOverhead(RetTy, true, false); + unsigned ScalarCalls = RetTy->getVectorNumElements(); + SmallVector<Type *, 4> ScalarTys; + for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) { + Type *Ty = Tys[i]; + if (Ty->isVectorTy()) + Ty = Ty->getScalarType(); + ScalarTys.push_back(Ty); + } + unsigned ScalarCost = static_cast<T *>(this)->getIntrinsicInstrCost( + IID, RetTy->getScalarType(), ScalarTys); + for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) { + if (Tys[i]->isVectorTy()) { + ScalarizationCost += getScalarizationOverhead(Tys[i], false, true); + ScalarCalls = std::max(ScalarCalls, Tys[i]->getVectorNumElements()); + } + } + + return ScalarCalls * ScalarCost + ScalarizationCost; } // This is going to be turned into a library call, make it expensive. return 10; } + /// \brief Compute a cost of the given call instruction. + /// + /// Compute the cost of calling function F with return type RetTy and + /// argument types Tys. F might be nullptr, in this case the cost of an + /// arbitrary call with the specified signature will be returned. + /// This is used, for instance, when we estimate call of a vector + /// counterpart of the given function. + /// \param F Called function, might be nullptr. + /// \param RetTy Return value types. + /// \param Tys Argument types. + /// \returns The cost of Call instruction. + unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys) { + return 10; + } + unsigned getNumberOfParts(Type *Tp) { std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(Tp); return LT.first; diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h index e310aef..7803898 100644 --- a/include/llvm/CodeGen/DIE.h +++ b/include/llvm/CodeGen/DIE.h @@ -95,7 +95,7 @@ public: /// Emit - Print the abbreviation using the specified asm printer. /// - void Emit(AsmPrinter *AP) const; + void Emit(const AsmPrinter *AP) const; #ifndef NDEBUG void print(raw_ostream &O); @@ -230,11 +230,11 @@ public: /// EmitValue - Emit value via the Dwarf writer. /// - virtual void EmitValue(AsmPrinter *AP, dwarf::Form Form) const = 0; + virtual void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const = 0; /// SizeOf - Return the size of a value in bytes. /// - virtual unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const = 0; + virtual unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const = 0; #ifndef NDEBUG virtual void print(raw_ostream &O) const = 0; @@ -275,13 +275,14 @@ public: /// EmitValue - Emit integer of appropriate size. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; uint64_t getValue() const { return Integer; } + void setValue(uint64_t Val) { Integer = Val; } /// SizeOf - Determine size of integer value in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *I) { return I->getType() == isInteger; } @@ -302,7 +303,7 @@ public: /// EmitValue - Emit expression value. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// getValue - Get MCExpr. /// @@ -310,7 +311,7 @@ public: /// SizeOf - Determine size of expression value in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *E) { return E->getType() == isExpr; } @@ -331,7 +332,7 @@ public: /// EmitValue - Emit label value. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// getValue - Get MCSymbol. /// @@ -339,7 +340,7 @@ public: /// SizeOf - Determine size of label value in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *L) { return L->getType() == isLabel; } @@ -362,11 +363,11 @@ public: /// EmitValue - Emit delta value. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// SizeOf - Determine size of delta value in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *D) { return D->getType() == isDelta; } @@ -392,11 +393,11 @@ public: /// EmitValue - Emit delta value. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// SizeOf - Determine size of delta value in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *D) { return D->getType() == isString; } @@ -421,17 +422,17 @@ public: /// EmitValue - Emit debug information entry offset. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// SizeOf - Determine size of debug information entry in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override { + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override { return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP) : sizeof(int32_t); } /// Returns size of a ref_addr entry. - static unsigned getRefAddrSize(AsmPrinter *AP); + static unsigned getRefAddrSize(const AsmPrinter *AP); // Implement isa/cast/dyncast. static bool classof(const DIEValue *E) { return E->getType() == isEntry; } @@ -451,10 +452,10 @@ public: : DIEValue(isTypeSignature), Unit(Unit) {} /// \brief Emit type unit signature. - void EmitValue(AsmPrinter *Asm, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const override; /// Returns size of a ref_sig8 entry. - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override { + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override { assert(Form == dwarf::DW_FORM_ref_sig8); return 8; } @@ -479,7 +480,7 @@ public: /// ComputeSize - Calculate the size of the location expression. /// - unsigned ComputeSize(AsmPrinter *AP) const; + unsigned ComputeSize(const AsmPrinter *AP) const; /// BestForm - Choose the best form for data. /// @@ -498,11 +499,11 @@ public: /// EmitValue - Emit location data. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// SizeOf - Determine size of location data in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *E) { return E->getType() == isLoc; } @@ -522,7 +523,7 @@ public: /// ComputeSize - Calculate the size of the location expression. /// - unsigned ComputeSize(AsmPrinter *AP) const; + unsigned ComputeSize(const AsmPrinter *AP) const; /// BestForm - Choose the best form for data. /// @@ -538,11 +539,11 @@ public: /// EmitValue - Emit location data. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// SizeOf - Determine size of location data in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *E) { return E->getType() == isBlock; } @@ -568,11 +569,11 @@ public: /// EmitValue - Emit location data. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// SizeOf - Determine size of location data in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *E) { return E->getType() == isLocList; } diff --git a/include/llvm/CodeGen/ForwardControlFlowIntegrity.h b/include/llvm/CodeGen/ForwardControlFlowIntegrity.h deleted file mode 100644 index ec8e2ef..0000000 --- a/include/llvm/CodeGen/ForwardControlFlowIntegrity.h +++ /dev/null @@ -1,122 +0,0 @@ -//===-- ForwardControlFlowIntegrity.h: Forward-Edge CFI ---------*- C++ -*-===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass instruments indirect calls with checks to ensure that these calls -// pass through the appropriate jump-instruction table generated by -// JumpInstrTables. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H -#define LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Pass.h" -#include "llvm/Target/TargetOptions.h" -#include <string> - -namespace llvm { - -class AnalysisUsage; -class BasicBlock; -class Constant; -class Function; -class Instruction; -class Module; -class Value; - -/// ForwardControlFlowIntegrity uses the information from JumpInstrTableInfo to -/// prepend checks to indirect calls to make sure that these calls target valid -/// locations. -class ForwardControlFlowIntegrity : public ModulePass { -public: - static char ID; - - ForwardControlFlowIntegrity(); - ForwardControlFlowIntegrity(JumpTable::JumpTableType JTT, - CFIntegrity CFIType, - bool CFIEnforcing, std::string CFIFuncName); - ~ForwardControlFlowIntegrity() override; - - /// Runs the CFI pass on a given module. This works best if the module in - /// question is the result of link-time optimization (see lib/LTO). - bool runOnModule(Module &M) override; - const char *getPassName() const override { - return "Forward Control-Flow Integrity"; - } - void getAnalysisUsage(AnalysisUsage &AU) const override; - -private: - typedef SmallVector<Instruction *, 64> CallSet; - - /// A structure that is used to keep track of constant table information. - struct CFIConstants { - Constant *StartValue; - Constant *MaskValue; - Constant *Size; - }; - - /// A map from function type to the base of the table for this type and a mask - /// for the table - typedef DenseMap<FunctionType *, CFIConstants> CFITables; - - CallSet IndirectCalls; - - /// The type of jumptable implementation. - JumpTable::JumpTableType JTType; - - /// The type of CFI check to add before each indirect call. - CFIntegrity CFIType; - - /// A value that controls whether or not CFI violations cause a halt. - bool CFIEnforcing; - - /// The name of the function to call in case of a CFI violation when - /// CFIEnforcing is false. There is a default function that ignores - /// violations. - std::string CFIFuncName; - - /// The alignment of each entry in the table, from JumpInstrTableInfo. The - /// JumpInstrTableInfo class always makes this a power of two. - uint64_t ByteAlignment; - - /// The base-2 logarithm of ByteAlignment, needed for some of the transforms - /// (like CFIntegrity::Ror) - unsigned LogByteAlignment; - - /// Adds checks to each indirect call site to make sure that it is calling a - /// function in our jump table. - void updateIndirectCalls(Module &M, CFITables &CFIT); - - /// Walks the instructions to find all the indirect calls. - void getIndirectCalls(Module &M); - - /// Adds a function that handles violations in non-enforcing mode - /// (!CFIEnforcing). The default warning function simply returns, since the - /// exact details of how to handle CFI violations depend on the application. - void addWarningFunction(Module &M); - - /// Rewrites a function pointer in a call/invoke instruction to force it into - /// a table. - void rewriteFunctionPointer(Module &M, Instruction *I, Value *FunPtr, - Constant *JumpTableStart, Constant *JumpTableMask, - Constant *JumpTableSize); - - /// Inserts a check and a call to a warning function at a given instruction - /// that must be an indirect call. - void insertWarning(Module &M, BasicBlock *Block, Instruction *I, - Value *FunPtr); -}; - -ModulePass * -createForwardControlFlowIntegrityPass(JumpTable::JumpTableType JTT, - CFIntegrity CFIType, - bool CFIEnforcing, StringRef CFIFuncName); -} - -#endif // LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index 8a31f7e..2d1c8cd 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -689,8 +689,6 @@ namespace ISD { // Masked load and store MLOAD, MSTORE, - // Masked gather and scatter - MGATHER, MSCATTER, /// This corresponds to the llvm.lifetime.* intrinsics. The first operand /// is the chain and the second operand is the alloca pointer. diff --git a/include/llvm/CodeGen/JumpInstrTables.h b/include/llvm/CodeGen/JumpInstrTables.h deleted file mode 100644 index 005bc1e..0000000 --- a/include/llvm/CodeGen/JumpInstrTables.h +++ /dev/null @@ -1,105 +0,0 @@ -//===-- JumpInstrTables.h: Jump-Instruction Tables --------------*- C++ -*-===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief An implementation of tables consisting of jump instructions -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_JUMPINSTRTABLES_H -#define LLVM_CODEGEN_JUMPINSTRTABLES_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/Pass.h" -#include "llvm/Target/TargetOptions.h" - -namespace llvm { -class Constant; -class Function; -class FunctionType; -class JumpInstrTableInfo; -class Module; - -/// A class to manage a set of jump tables indexed on function type. It looks at -/// each function in the module to find all the functions that have the -/// jumptable attribute set. For each such function, it creates a new -/// jump-instruction-table function and stores the mapping in the ImmutablePass -/// JumpInstrTableInfo. -/// -/// These special functions get lowered in AsmPrinter to assembly of the form: -/// \verbatim -/// .globl f -/// .type f,@function -/// .align 8,0x90 -/// f: -/// jmp f_orig@PLT -/// \endverbatim -/// -/// Support for an architecture depends on three functions in TargetInstrInfo: -/// getUnconditionalBranch, getTrap, and getJumpInstrTableEntryBound. AsmPrinter -/// uses these to generate the appropriate instructions for the jump statement -/// (an unconditional branch) and for padding to make the table have a size that -/// is a power of two. This padding uses a trap instruction to ensure that calls -/// to this area halt the program. The default implementations of these -/// functions call llvm_unreachable, except for getJumpInstrTableEntryBound, -/// which returns 0 by default. -class JumpInstrTables : public ModulePass { -public: - static char ID; - - JumpInstrTables(); - JumpInstrTables(JumpTable::JumpTableType JTT); - virtual ~JumpInstrTables(); - bool runOnModule(Module &M) override; - const char *getPassName() const override { return "Jump-Instruction Tables"; } - void getAnalysisUsage(AnalysisUsage &AU) const override; - - /// Creates a jump-instruction table function for the Target and adds it to - /// the tables. - Function *insertEntry(Module &M, Function *Target); - - /// Checks to see if there is already a table for the given FunctionType. - bool hasTable(FunctionType *FunTy); - - /// Maps the function into a subset of function types, depending on the - /// jump-instruction table style selected from JumpTableTypes in - /// JumpInstrTables.cpp. The choice of mapping determines the number of - /// jump-instruction tables generated by this pass. E.g., the simplest mapping - /// converts every function type into void f(); so, all functions end up in a - /// single table. - static FunctionType *transformType(JumpTable::JumpTableType JTT, - FunctionType *FunTy); -private: - /// The metadata used while a jump table is being built - struct TableMeta { - /// The number of this table - unsigned TableNum; - - /// The current number of jump entries in the table. - unsigned Count; - }; - - typedef DenseMap<FunctionType *, struct TableMeta> JumpMap; - - /// The current state of functions and jump entries in the table(s). - JumpMap Metadata; - - /// The ImmutablePass that stores information about the generated tables. - JumpInstrTableInfo *JITI; - - /// The total number of tables. - unsigned TableCount; - - /// The type of tables to build. - JumpTable::JumpTableType JTType; -}; - -/// Creates a JumpInstrTables pass for the given type of jump table. -ModulePass *createJumpInstrTablesPass(JumpTable::JumpTableType JTT); -} - -#endif /* LLVM_CODEGEN_JUMPINSTRTABLES_H */ diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h index cf601ae..f347f66 100644 --- a/include/llvm/CodeGen/LatencyPriorityQueue.h +++ b/include/llvm/CodeGen/LatencyPriorityQueue.h @@ -83,8 +83,6 @@ namespace llvm { void remove(SUnit *SU) override; - void dump(ScheduleDAG* DAG) const override; - // scheduledNode - As nodes are scheduled, we look to see if there are any // successor nodes that have a single unscheduled predecessor. If so, that // single predecessor has a higher priority, since scheduling it will make diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 21634cb..9b8b91c 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -199,7 +199,7 @@ namespace llvm { // of live ranges of physical registers in computeRegUnitRange. // After that the set is flushed to the segment vector and deleted. typedef std::set<Segment> SegmentSet; - SegmentSet *segmentSet; + std::unique_ptr<SegmentSet> segmentSet; typedef Segments::iterator iterator; iterator begin() { return segments.begin(); } @@ -218,15 +218,13 @@ namespace llvm { const_vni_iterator vni_end() const { return valnos.end(); } /// Constructs a new LiveRange object. - LiveRange(bool UseSegmentSet = false) : segmentSet(nullptr) { - if (UseSegmentSet) - segmentSet = new SegmentSet(); - } + LiveRange(bool UseSegmentSet = false) + : segmentSet(UseSegmentSet ? llvm::make_unique<SegmentSet>() + : nullptr) {} /// Constructs a new LiveRange object by copying segments and valnos from /// another LiveRange. - LiveRange(const LiveRange &Other, BumpPtrAllocator &Allocator) - : segmentSet(nullptr) { + LiveRange(const LiveRange &Other, BumpPtrAllocator &Allocator) { assert(Other.segmentSet == nullptr && "Copying of LiveRanges with active SegmentSets is not supported"); @@ -240,8 +238,6 @@ namespace llvm { } } - ~LiveRange() { delete segmentSet; } - /// advanceTo - Advance the specified iterator to point to the Segment /// containing the specified position, or end() if the position is past the /// end of the range. If no Segment contains this position, but the @@ -745,8 +741,6 @@ namespace llvm { #endif private: - LiveInterval& operator=(const LiveInterval& rhs) = delete; - /// Appends @p Range to SubRanges list. void appendSubRange(SubRange *Range) { Range->Next = SubRanges; diff --git a/include/llvm/CodeGen/LivePhysRegs.h b/include/llvm/CodeGen/LivePhysRegs.h index 4aa53a9..f44d627 100644 --- a/include/llvm/CodeGen/LivePhysRegs.h +++ b/include/llvm/CodeGen/LivePhysRegs.h @@ -57,9 +57,9 @@ public: } /// \brief Clear and initialize the LivePhysRegs set. - void init(const TargetRegisterInfo *_TRI) { - assert(_TRI && "Invalid TargetRegisterInfo pointer."); - TRI = _TRI; + void init(const TargetRegisterInfo *TRI) { + assert(TRI && "Invalid TargetRegisterInfo pointer."); + this->TRI = TRI; LiveRegs.clear(); LiveRegs.setUniverse(TRI->getNumRegs()); } diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h index df68398..f495507 100644 --- a/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/include/llvm/CodeGen/LiveStackAnalysis.h @@ -21,6 +21,7 @@ #include "llvm/Support/Allocator.h" #include "llvm/Target/TargetRegisterInfo.h" #include <map> +#include <unordered_map> namespace llvm { @@ -33,7 +34,7 @@ namespace llvm { /// S2IMap - Stack slot indices to live interval mapping. /// - typedef std::map<int, LiveInterval> SS2IntervalMap; + typedef std::unordered_map<int, LiveInterval> SS2IntervalMap; SS2IntervalMap S2IMap; /// S2RCMap - Stack slot indices to register class mapping. diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h index a6980a6..19f4e2d 100644 --- a/include/llvm/CodeGen/MachineDominators.h +++ b/include/llvm/CodeGen/MachineDominators.h @@ -45,9 +45,6 @@ class MachineDominatorTree : public MachineFunctionPass { MachineBasicBlock *FromBB; MachineBasicBlock *ToBB; MachineBasicBlock *NewBB; - CriticalEdge(MachineBasicBlock *FromBB, MachineBasicBlock *ToBB, - MachineBasicBlock *NewBB) - : FromBB(FromBB), ToBB(ToBB), NewBB(NewBB) {} }; /// \brief Pile up all the critical edges to be split. @@ -67,74 +64,7 @@ class MachineDominatorTree : public MachineFunctionPass { /// the fast query path of DT as much as possible. /// /// \post CriticalEdgesToSplit.empty(). - void applySplitCriticalEdges() const { - // Bail out early if there is nothing to do. - if (CriticalEdgesToSplit.empty()) - return; - - // For each element in CriticalEdgesToSplit, remember whether or - // not element is the new immediate domminator of its successor. - // The mapping is done by index, i.e., the information for the ith - // element of CriticalEdgesToSplit is the ith element of IsNewIDom. - SmallVector<bool, 32> IsNewIDom; - IsNewIDom.resize(CriticalEdgesToSplit.size()); - size_t Idx = 0; - - // Collect all the dominance properties info, before invalidating - // the underlying DT. - for (CriticalEdge &Edge : CriticalEdgesToSplit) { - // Update dominator information. - MachineBasicBlock *Succ = Edge.ToBB; - MachineDomTreeNode *SucccDTNode = DT->getNode(Succ); - - IsNewIDom[Idx] = true; - for (MachineBasicBlock *PredBB : Succ->predecessors()) { - if (PredBB == Edge.NewBB) - continue; - // If we are in this situation: - // FromBB1 FromBB2 - // + + - // + + + + - // + + + + - // ... Split1 Split2 ... - // + + - // + + - // + - // Succ - // Instead of checking the domiance property with Split2, we - // check it with FromBB2 since Split2 is still unknown of the - // underlying DT structure. - if (NewBBs.count(PredBB)) { - assert(PredBB->pred_size() == 1 && "A basic block resulting from a " - "critical edge split has more " - "than one predecessor!"); - PredBB = *PredBB->pred_begin(); - } - if (!DT->dominates(SucccDTNode, DT->getNode(PredBB))) { - IsNewIDom[Idx] = false; - break; - } - } - ++Idx; - } - - // Now, update DT with the collected dominance properties info. - Idx = 0; - for (CriticalEdge &Edge : CriticalEdgesToSplit) { - // We know FromBB dominates NewBB. - MachineDomTreeNode *NewDTNode = DT->addNewBlock(Edge.NewBB, Edge.FromBB); - MachineDomTreeNode *SucccDTNode = DT->getNode(Edge.ToBB); - - // If all the other predecessors of "Succ" are dominated by "Succ" itself - // then the new block is the new immediate dominator of "Succ". Otherwise, - // the new block doesn't dominate anything. - if (IsNewIDom[Idx]) - DT->changeImmediateDominator(SucccDTNode, NewDTNode); - ++Idx; - } - NewBBs.clear(); - CriticalEdgesToSplit.clear(); - } + void applySplitCriticalEdges() const; public: static char ID; // Pass ID, replacement for typeid @@ -307,7 +237,7 @@ public: (void)Inserted; assert(Inserted && "A basic block inserted via edge splitting cannot appear twice"); - CriticalEdgesToSplit.push_back(CriticalEdge(FromBB, ToBB, NewBB)); + CriticalEdgesToSplit.push_back({FromBB, ToBB, NewBB}); } }; diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 4ba4a97..333dcdb 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -257,9 +257,7 @@ public: /// this DBG_VALUE instruction. DIExpression getDebugExpression() const { assert(isDebugValue() && "not a DBG_VALUE"); - DIExpression Expr(getOperand(3).getMetadata()); - assert(Expr.Verify() && "not a DIExpression"); - return Expr; + return cast<MDExpression>(getOperand(3).getMetadata()); } /// emitError - Emit an error referring to the source location of this @@ -1113,8 +1111,7 @@ public: // // Debugging support // - void print(raw_ostream &OS, const TargetMachine *TM = nullptr, - bool SkipOpers = false) const; + void print(raw_ostream &OS, bool SkipOpers = false) const; void dump() const; //===--------------------------------------------------------------------===// @@ -1170,6 +1167,12 @@ public: assert(NumMemRefs == NewMemRefsEnd - NewMemRefs && "Too many memrefs"); } + /// clearMemRefs - Clear this MachineInstr's memory reference descriptor list. + void clearMemRefs() { + MemRefs = nullptr; + NumMemRefs = 0; + } + private: /// getRegInfo - If this instruction is embedded into a MachineFunction, /// return the MachineRegisterInfo object for the current function, otherwise diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 8859b6a..e6cb494 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -356,7 +356,7 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, unsigned Reg, unsigned Offset, const MDNode *Variable, const MDNode *Expr) { assert(DIVariable(Variable).Verify() && "not a DIVariable"); - assert(DIExpression(Expr).Verify() && "not a DIExpression"); + assert(DIExpression(Expr)->isValid() && "not a DIExpression"); if (IsIndirect) return BuildMI(MF, DL, MCID) .addReg(Reg, RegState::Debug) @@ -383,7 +383,7 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, unsigned Reg, unsigned Offset, const MDNode *Variable, const MDNode *Expr) { assert(DIVariable(Variable).Verify() && "not a DIVariable"); - assert(DIExpression(Expr).Verify() && "not a DIExpression"); + assert(DIExpression(Expr)->isValid() && "not a DIExpression"); MachineFunction &MF = *BB.getParent(); MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Variable, Expr); diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h index eb5086c..a16c294 100644 --- a/include/llvm/CodeGen/MachineMemOperand.h +++ b/include/llvm/CodeGen/MachineMemOperand.h @@ -199,6 +199,24 @@ public: /// Profile - Gather unique data for the object. /// void Profile(FoldingSetNodeID &ID) const; + + friend bool operator==(const MachineMemOperand &LHS, + const MachineMemOperand &RHS) { + return LHS.getValue() == RHS.getValue() && + LHS.getPseudoValue() == RHS.getPseudoValue() && + LHS.getSize() == RHS.getSize() && + LHS.getOffset() == RHS.getOffset() && + LHS.getFlags() == RHS.getFlags() && + LHS.getAAInfo() == RHS.getAAInfo() && + LHS.getRanges() == RHS.getRanges() && + LHS.getAlignment() == RHS.getAlignment() && + LHS.getAddrSpace() == RHS.getAddrSpace(); + } + + friend bool operator!=(const MachineMemOperand &LHS, + const MachineMemOperand &RHS) { + return !(LHS == RHS); + } }; raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MRO); diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index eed1e57..04d5361 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -217,7 +217,7 @@ public: /// void clearParent() { ParentMI = nullptr; } - void print(raw_ostream &os, const TargetMachine *TM = nullptr) const; + void print(raw_ostream &os, const TargetRegisterInfo *TRI = nullptr) const; //===--------------------------------------------------------------------===// // Accessors that tell you what kind of MachineOperand you're looking at. diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index abb04de..001d09f 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -182,7 +182,18 @@ public: /// information. void invalidateLiveness() { TracksLiveness = false; } - bool tracksSubRegLiveness() const { return TracksSubRegLiveness; } + /// Returns true if liveness for register class @p RC should be tracked at + /// the subregister level. + bool shouldTrackSubRegLiveness(const TargetRegisterClass &RC) const { + return subRegLivenessEnabled() && RC.HasDisjunctSubRegs; + } + bool shouldTrackSubRegLiveness(unsigned VReg) const { + assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Must pass a VReg"); + return shouldTrackSubRegLiveness(*getRegClass(VReg)); + } + bool subRegLivenessEnabled() const { + return TracksSubRegLiveness; + } void enableSubRegLiveness(bool Enable = true) { TracksSubRegLiveness = Enable; @@ -829,7 +840,6 @@ public: typedef std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t>::pointer pointer; - defusechain_iterator(const defusechain_iterator &I) : Op(I.Op) {} defusechain_iterator() : Op(nullptr) {} bool operator==(const defusechain_iterator &x) const { @@ -932,7 +942,6 @@ public: typedef std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t>::pointer pointer; - defusechain_instr_iterator(const defusechain_instr_iterator &I) : Op(I.Op){} defusechain_instr_iterator() : Op(nullptr) {} bool operator==(const defusechain_instr_iterator &x) const { diff --git a/include/llvm/CodeGen/MachineValueType.h b/include/llvm/CodeGen/MachineValueType.h index 7ad782f..3eb4d0b 100644 --- a/include/llvm/CodeGen/MachineValueType.h +++ b/include/llvm/CodeGen/MachineValueType.h @@ -161,8 +161,8 @@ namespace llvm { SimpleValueType SimpleTy; - MVT() : SimpleTy((SimpleValueType)(INVALID_SIMPLE_VALUE_TYPE)) {} - MVT(SimpleValueType SVT) : SimpleTy(SVT) { } + LLVM_CONSTEXPR MVT() : SimpleTy(INVALID_SIMPLE_VALUE_TYPE) {} + LLVM_CONSTEXPR MVT(SimpleValueType SVT) : SimpleTy(SVT) { } bool operator>(const MVT& S) const { return SimpleTy > S.SimpleTy; } bool operator<(const MVT& S) const { return SimpleTy < S.SimpleTy; } diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 65b17d3..48e1f21 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -612,13 +612,13 @@ namespace llvm { ModulePass *createForwardControlFlowIntegrityPass(); } // End llvm namespace -/// This initializer registers TargetMachine constructor, so the pass being -/// initialized can use target dependent interfaces. Please do not move this -/// macro to be together with INITIALIZE_PASS, which is a complete target -/// independent initializer, and we don't want to make libScalarOpts depend -/// on libCodeGen. -#define INITIALIZE_TM_PASS(passName, arg, name, cfg, analysis) \ - static void* initialize##passName##PassOnce(PassRegistry &Registry) { \ +/// Target machine pass initializer for passes with dependencies. Use with +/// INITIALIZE_TM_PASS_END. +#define INITIALIZE_TM_PASS_BEGIN INITIALIZE_PASS_BEGIN + +/// Target machine pass initializer for passes with dependencies. Use with +/// INITIALIZE_TM_PASS_BEGIN. +#define INITIALIZE_TM_PASS_END(passName, arg, name, cfg, analysis) \ PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \ PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis, \ PassInfo::TargetMachineCtor_t(callTargetMachineCtor< passName >)); \ @@ -629,4 +629,13 @@ namespace llvm { CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ } +/// This initializer registers TargetMachine constructor, so the pass being +/// initialized can use target dependent interfaces. Please do not move this +/// macro to be together with INITIALIZE_PASS, which is a complete target +/// independent initializer, and we don't want to make libScalarOpts depend +/// on libCodeGen. +#define INITIALIZE_TM_PASS(passName, arg, name, cfg, analysis) \ + INITIALIZE_TM_PASS_BEGIN(passName, arg, name, cfg, analysis) \ + INITIALIZE_TM_PASS_END(passName, arg, name, cfg, analysis) + #endif diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h index c7bb07b..6046e46 100644 --- a/include/llvm/CodeGen/RegAllocPBQP.h +++ b/include/llvm/CodeGen/RegAllocPBQP.h @@ -544,8 +544,10 @@ private: public: SpillCostComparator(const Graph& G) : G(G) {} bool operator()(NodeId N1Id, NodeId N2Id) { - PBQPNum N1SC = G.getNodeCosts(N1Id)[0] / G.getNodeDegree(N1Id); - PBQPNum N2SC = G.getNodeCosts(N2Id)[0] / G.getNodeDegree(N2Id); + PBQPNum N1SC = G.getNodeCosts(N1Id)[0]; + PBQPNum N2SC = G.getNodeCosts(N2Id)[0]; + if (N1SC == N2SC) + return G.getNodeDegree(N1Id) < G.getNodeDegree(N2Id); return N1SC < N2SC; } private: diff --git a/include/llvm/CodeGen/ResourcePriorityQueue.h b/include/llvm/CodeGen/ResourcePriorityQueue.h index 114fe7c..0097e04 100644 --- a/include/llvm/CodeGen/ResourcePriorityQueue.h +++ b/include/llvm/CodeGen/ResourcePriorityQueue.h @@ -64,7 +64,7 @@ namespace llvm { /// ResourcesModel - Represents VLIW state. /// Not limited to VLIW targets per say, but assumes /// definition of DFA by a target. - DFAPacketizer *ResourcesModel; + std::unique_ptr<DFAPacketizer> ResourcesModel; /// Resource model - packet/bundle model. Purely /// internal at the time. @@ -77,10 +77,6 @@ namespace llvm { public: ResourcePriorityQueue(SelectionDAGISel *IS); - ~ResourcePriorityQueue() { - delete ResourcesModel; - } - bool isBottomUp() const override { return false; } void initNodes(std::vector<SUnit> &sunits) override; @@ -124,8 +120,6 @@ namespace llvm { void remove(SUnit *SU) override; - void dump(ScheduleDAG* DAG) const override; - /// scheduledNode - Main resource tracking point. void scheduledNode(SUnit *Node) override; bool isResourceAvailable(SUnit *SU); diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h index 64c9c47..2be5de6 100644 --- a/include/llvm/CodeGen/RuntimeLibcalls.h +++ b/include/llvm/CodeGen/RuntimeLibcalls.h @@ -425,6 +425,10 @@ namespace RTLIB { /// getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or /// UNKNOWN_LIBCALL if there is none. Libcall getUINTTOFP(EVT OpVT, EVT RetVT); + + /// Return the SYNC_FETCH_AND_* value for the given opcode and type, or + /// UNKNOWN_LIBCALL if there is none. + Libcall getATOMIC(unsigned Opc, MVT VT); } } diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 80aee8c..8391314 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -628,12 +628,6 @@ namespace llvm { } bool operator!=(const SUnitIterator& x) const { return !operator==(x); } - const SUnitIterator &operator=(const SUnitIterator &I) { - assert(I.Node==Node && "Cannot assign iterators to two different nodes!"); - Operand = I.Operand; - return *this; - } - pointer operator*() const { return Node->Preds[Operand].getSUnit(); } diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index d53e66d..7acdfc7 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -80,12 +80,12 @@ public: virtual SDNode *Select(SDNode *N) = 0; /// SelectInlineAsmMemoryOperand - Select the specified address as a target - /// addressing mode, according to the specified constraint code. If this does + /// addressing mode, according to the specified constraint. If this does /// not match or is not implemented, return true. The resultant operands /// (which will appear in the machine instruction) should be added to the /// OutOps vector. virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, - char ConstraintCode, + unsigned ConstraintID, std::vector<SDValue> &OutOps) { return true; } diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 0b6240f..2b3e08c 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -50,8 +50,7 @@ template <typename T> struct DenseMapInfo; template <typename T> struct simplify_type; template <typename T> struct ilist_traits; -/// isBinOpWithFlags - Returns true if the opcode is a binary operation -/// with flags. +/// Returns true if the opcode is a binary operation with flags. static bool isBinOpWithFlags(unsigned Opcode) { switch (Opcode) { case ISD::SDIV: @@ -71,7 +70,7 @@ static bool isBinOpWithFlags(unsigned Opcode) { void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr, bool force = false); -/// SDVTList - This represents a list of ValueType's that has been intern'd by +/// This represents a list of ValueType's that has been intern'd by /// a SelectionDAG. Instances of this simple value class are returned by /// SelectionDAG::getVTList(...). /// @@ -83,11 +82,11 @@ struct SDVTList { namespace ISD { /// Node predicates - /// isBuildVectorAllOnes - Return true if the specified node is a + /// Return true if the specified node is a /// BUILD_VECTOR where all of the elements are ~0 or undef. bool isBuildVectorAllOnes(const SDNode *N); - /// isBuildVectorAllZeros - Return true if the specified node is a + /// Return true if the specified node is a /// BUILD_VECTOR where all of the elements are 0 or undef. bool isBuildVectorAllZeros(const SDNode *N); @@ -95,18 +94,22 @@ namespace ISD { /// all ConstantSDNode or undef. bool isBuildVectorOfConstantSDNodes(const SDNode *N); - /// isScalarToVector - Return true if the specified node is a + /// \brief Return true if the specified node is a BUILD_VECTOR node of + /// all ConstantFPSDNode or undef. + bool isBuildVectorOfConstantFPSDNodes(const SDNode *N); + + /// Return true if the specified node is a /// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node where only the low /// element is not an undef. bool isScalarToVector(const SDNode *N); - /// allOperandsUndef - Return true if the node has at least one operand + /// Return true if the node has at least one operand /// and all operands of the specified node are ISD::UNDEF. bool allOperandsUndef(const SDNode *N); } // end llvm:ISD namespace //===----------------------------------------------------------------------===// -/// SDValue - Unlike LLVM values, Selection DAG nodes may return multiple +/// Unlike LLVM values, Selection DAG nodes may return multiple /// values as the result of a computation. Many nodes return multiple values, /// from loads (which define a token and a return value) to ADDC (which returns /// a result and a carry value), to calls (which may return an arbitrary number @@ -153,11 +156,10 @@ public: return SDValue(Node, R); } - // isOperandOf - Return true if this node is an operand of N. + // Return true if this node is an operand of N. bool isOperandOf(SDNode *N) const; - /// getValueType - Return the ValueType of the referenced return value. - /// + /// Return the ValueType of the referenced return value. inline EVT getValueType() const; /// Return the simple ValueType of the referenced return value. @@ -165,8 +167,7 @@ public: return getValueType().getSimpleVT(); } - /// getValueSizeInBits - Returns the size of the value in bits. - /// + /// Returns the size of the value in bits. unsigned getValueSizeInBits() const { return getValueType().getSizeInBits(); } @@ -188,22 +189,18 @@ public: inline void dump() const; inline void dumpr() const; - /// reachesChainWithoutSideEffects - Return true if this operand (which must - /// be a chain) reaches the specified operand without crossing any - /// side-effecting instructions. In practice, this looks through token - /// factors and non-volatile loads. In order to remain efficient, this only + /// Return true if this operand (which must be a chain) reaches the + /// specified operand without crossing any side-effecting instructions. + /// In practice, this looks through token factors and non-volatile loads. + /// In order to remain efficient, this only /// looks a couple of nodes in, it does not do an exhaustive search. bool reachesChainWithoutSideEffects(SDValue Dest, unsigned Depth = 2) const; - /// use_empty - Return true if there are no nodes using value ResNo - /// of Node. - /// + /// Return true if there are no nodes using value ResNo of Node. inline bool use_empty() const; - /// hasOneUse - Return true if there is exactly one node using value - /// ResNo of Node. - /// + /// Return true if there is exactly one node using value ResNo of Node. inline bool hasOneUse() const; }; @@ -230,7 +227,7 @@ template<> struct DenseMapInfo<SDValue> { template <> struct isPodLike<SDValue> { static const bool value = true; }; -/// simplify_type specializations - Allow casting operators to work directly on +/// Allow casting operators to work directly on /// SDValues as if they were SDNode*'s. template<> struct simplify_type<SDValue> { typedef SDNode* SimpleType; @@ -245,7 +242,7 @@ template<> struct simplify_type<const SDValue> { } }; -/// SDUse - Represents a use of a SDNode. This class holds an SDValue, +/// Represents a use of a SDNode. This class holds an SDValue, /// which records the SDNode being used and the result number, a /// pointer to the SDNode using the value, and Next and Prev pointers, /// which link together all the uses of an SDNode. @@ -272,30 +269,30 @@ public: /// the SDValue. const SDValue &get() const { return Val; } - /// getUser - This returns the SDNode that contains this Use. + /// This returns the SDNode that contains this Use. SDNode *getUser() { return User; } - /// getNext - Get the next SDUse in the use list. + /// Get the next SDUse in the use list. SDUse *getNext() const { return Next; } - /// getNode - Convenience function for get().getNode(). + /// Convenience function for get().getNode(). SDNode *getNode() const { return Val.getNode(); } - /// getResNo - Convenience function for get().getResNo(). + /// Convenience function for get().getResNo(). unsigned getResNo() const { return Val.getResNo(); } - /// getValueType - Convenience function for get().getValueType(). + /// Convenience function for get().getValueType(). EVT getValueType() const { return Val.getValueType(); } - /// operator== - Convenience function for get().operator== + /// Convenience function for get().operator== bool operator==(const SDValue &V) const { return Val == V; } - /// operator!= - Convenience function for get().operator!= + /// Convenience function for get().operator!= bool operator!=(const SDValue &V) const { return Val != V; } - /// operator< - Convenience function for get().operator< + /// Convenience function for get().operator< bool operator<(const SDValue &V) const { return Val < V; } @@ -306,13 +303,13 @@ private: void setUser(SDNode *p) { User = p; } - /// set - Remove this use from its existing use list, assign it the + /// Remove this use from its existing use list, assign it the /// given value, and add it to the new value's node's use list. inline void set(const SDValue &V); - /// setInitial - like set, but only supports initializing a newly-allocated + /// Like set, but only supports initializing a newly-allocated /// SDUse with a non-null value. inline void setInitial(const SDValue &V); - /// setNode - like set, but only sets the Node portion of the value, + /// Like set, but only sets the Node portion of the value, /// leaving the ResNo portion unmodified. inline void setNode(SDNode *N); @@ -339,47 +336,45 @@ template<> struct simplify_type<SDUse> { }; -/// SDNode - Represents one node in the SelectionDAG. +/// Represents one node in the SelectionDAG. /// class SDNode : public FoldingSetNode, public ilist_node<SDNode> { private: - /// NodeType - The operation that this node performs. - /// + /// The operation that this node performs. int16_t NodeType; - /// OperandsNeedDelete - This is true if OperandList was new[]'d. If true, + /// This is true if OperandList was new[]'d. If true, /// then they will be delete[]'d when the node is destroyed. uint16_t OperandsNeedDelete : 1; - /// HasDebugValue - This tracks whether this node has one or more dbg_value + /// This tracks whether this node has one or more dbg_value /// nodes corresponding to it. uint16_t HasDebugValue : 1; protected: - /// SubclassData - This member is defined by this class, but is not used for + /// This member is defined by this class, but is not used for /// anything. Subclasses can use it to hold whatever state they find useful. /// This field is initialized to zero by the ctor. uint16_t SubclassData : 14; private: - /// NodeId - Unique id per SDNode in the DAG. + /// Unique id per SDNode in the DAG. int NodeId; - /// OperandList - The values that are used by this operation. - /// + /// The values that are used by this operation. SDUse *OperandList; - /// ValueList - The types of the values this node defines. SDNode's may + /// The types of the values this node defines. SDNode's may /// define multiple values simultaneously. const EVT *ValueList; - /// UseList - List of uses for this SDNode. + /// List of uses for this SDNode. SDUse *UseList; - /// NumOperands/NumValues - The number of entries in the Operand/Value list. + /// The number of entries in the Operand/Value list. unsigned short NumOperands, NumValues; - /// debugLoc - source line information. + /// Source line information. DebugLoc debugLoc; // The ordering of the SDNodes. It roughly corresponds to the ordering of the @@ -389,7 +384,7 @@ private: // this ordering. unsigned IROrder; - /// getValueTypeList - Return a pointer to the specified value type. + /// Return a pointer to the specified value type. static const EVT *getValueTypeList(EVT VT); friend class SelectionDAG; @@ -400,17 +395,17 @@ public: // Accessors // - /// getOpcode - Return the SelectionDAG opcode value for this node. For + /// Return the SelectionDAG opcode value for this node. For /// pre-isel nodes (those for which isMachineOpcode returns false), these /// are the opcode values in the ISD and <target>ISD namespaces. For /// post-isel opcodes, see getMachineOpcode. unsigned getOpcode() const { return (unsigned short)NodeType; } - /// isTargetOpcode - Test if this node has a target-specific opcode (in the + /// Test if this node has a target-specific opcode (in the /// \<target\>ISD namespace). bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; } - /// isTargetMemoryOpcode - Test if this node has a target-specific + /// Test if this node has a target-specific /// memory-referencing opcode (in the \<target\>ISD namespace and /// greater than FIRST_TARGET_MEMORY_OPCODE). bool isTargetMemoryOpcode() const { @@ -427,11 +422,11 @@ public: NodeType == ISD::INTRINSIC_VOID) && ((SubclassData >> 13) & 1); } - /// isMachineOpcode - Test if this node has a post-isel opcode, directly + /// Test if this node has a post-isel opcode, directly /// corresponding to a MachineInstr opcode. bool isMachineOpcode() const { return NodeType < 0; } - /// getMachineOpcode - This may only be called if isMachineOpcode returns + /// This may only be called if isMachineOpcode returns /// true. It returns the MachineInstr opcode value that the node's opcode /// corresponds to. unsigned getMachineOpcode() const { @@ -439,50 +434,44 @@ public: return ~NodeType; } - /// getHasDebugValue - get this bit. + /// Get this bit. bool getHasDebugValue() const { return HasDebugValue; } - /// setHasDebugValue - set this bit. + /// Set this bit. void setHasDebugValue(bool b) { HasDebugValue = b; } - /// use_empty - Return true if there are no uses of this node. - /// + /// Return true if there are no uses of this node. bool use_empty() const { return UseList == nullptr; } - /// hasOneUse - Return true if there is exactly one use of this node. - /// + /// Return true if there is exactly one use of this node. bool hasOneUse() const { return !use_empty() && std::next(use_begin()) == use_end(); } - /// use_size - Return the number of uses of this node. This method takes + /// Return the number of uses of this node. This method takes /// time proportional to the number of uses. - /// size_t use_size() const { return std::distance(use_begin(), use_end()); } - /// getNodeId - Return the unique node id. - /// + /// Return the unique node id. int getNodeId() const { return NodeId; } - /// setNodeId - Set unique node id. + /// Set unique node id. void setNodeId(int Id) { NodeId = Id; } - /// getIROrder - Return the node ordering. - /// + /// Return the node ordering. unsigned getIROrder() const { return IROrder; } - /// setIROrder - Set the node ordering. - /// + /// Set the node ordering. void setIROrder(unsigned Order) { IROrder = Order; } - /// getDebugLoc - Return the source location info. + /// Return the source location info. const DebugLoc &getDebugLoc() const { return debugLoc; } - /// setDebugLoc - Set source location info. Try to avoid this, putting + /// Set source location info. Try to avoid this, putting /// it in the constructor is preferable. void setDebugLoc(DebugLoc dl) { debugLoc = std::move(dl); } - /// use_iterator - This class provides iterator support for SDUse + /// This class provides iterator support for SDUse /// operands that use a specific SDNode. class use_iterator : public std::iterator<std::forward_iterator_tag, SDUse, ptrdiff_t> { @@ -506,7 +495,7 @@ public: return !operator==(x); } - /// atEnd - return true if this iterator is at the end of uses list. + /// Return true if this iterator is at the end of uses list. bool atEnd() const { return Op == nullptr; } // Iterator traversal: forward iteration only. @@ -530,17 +519,14 @@ public: SDUse &getUse() const { return *Op; } - /// getOperandNo - Retrieve the operand # of this use in its user. - /// + /// Retrieve the operand # of this use in its user. unsigned getOperandNo() const { assert(Op && "Cannot dereference end iterator!"); return (unsigned)(Op - Op->getUser()->OperandList); } }; - /// use_begin/use_end - Provide iteration support to walk over all uses - /// of an SDNode. - + /// Provide iteration support to walk over all uses of an SDNode. use_iterator use_begin() const { return use_iterator(UseList); } @@ -554,37 +540,34 @@ public: return iterator_range<use_iterator>(use_begin(), use_end()); } - /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the - /// indicated value. This method ignores uses of other values defined by this - /// operation. + /// Return true if there are exactly NUSES uses of the indicated value. + /// This method ignores uses of other values defined by this operation. bool hasNUsesOfValue(unsigned NUses, unsigned Value) const; - /// hasAnyUseOfValue - Return true if there are any use of the indicated - /// value. This method ignores uses of other values defined by this operation. + /// Return true if there are any use of the indicated value. + /// This method ignores uses of other values defined by this operation. bool hasAnyUseOfValue(unsigned Value) const; - /// isOnlyUserOf - Return true if this node is the only use of N. - /// + /// Return true if this node is the only use of N. bool isOnlyUserOf(SDNode *N) const; - /// isOperandOf - Return true if this node is an operand of N. - /// + /// Return true if this node is an operand of N. bool isOperandOf(SDNode *N) const; - /// isPredecessorOf - Return true if this node is a predecessor of N. + /// Return true if this node is a predecessor of N. /// NOTE: Implemented on top of hasPredecessor and every bit as /// expensive. Use carefully. bool isPredecessorOf(const SDNode *N) const { return N->hasPredecessor(this); } - /// hasPredecessor - Return true if N is a predecessor of this node. + /// Return true if N is a predecessor of this node. /// N is either an operand of this node, or can be reached by recursively /// traversing up the operands. /// NOTE: This is an expensive method. Use it carefully. bool hasPredecessor(const SDNode *N) const; - /// hasPredecesorHelper - Return true if N is a predecessor of this node. + /// Return true if N is a predecessor of this node. /// N is either an operand of this node, or can be reached by recursively /// traversing up the operands. /// In this helper the Visited and worklist sets are held externally to @@ -597,12 +580,10 @@ public: SmallPtrSetImpl<const SDNode *> &Visited, SmallVectorImpl<const SDNode *> &Worklist) const; - /// getNumOperands - Return the number of values used by this operation. - /// + /// Return the number of values used by this operation. unsigned getNumOperands() const { return NumOperands; } - /// getConstantOperandVal - Helper method returns the integer value of a - /// ConstantSDNode operand. + /// Helper method returns the integer value of a ConstantSDNode operand. uint64_t getConstantOperandVal(unsigned Num) const; const SDValue &getOperand(unsigned Num) const { @@ -620,7 +601,7 @@ public: return X; } - /// getGluedNode - If this node has a glue operand, return the node + /// If this node has a glue operand, return the node /// to which the glue operand points. Otherwise return NULL. SDNode *getGluedNode() const { if (getNumOperands() != 0 && @@ -645,7 +626,7 @@ public: return FoundNode; } - /// getGluedUser - If this node has a glue value with a user, return + /// If this node has a glue value with a user, return /// the user (there is at most one). Otherwise return NULL. SDNode *getGluedUser() const { for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI) @@ -654,26 +635,21 @@ public: return nullptr; } - /// getNumValues - Return the number of values defined/returned by this - /// operator. - /// + /// Return the number of values defined/returned by this operator. unsigned getNumValues() const { return NumValues; } - /// getValueType - Return the type of a specified result. - /// + /// Return the type of a specified result. EVT getValueType(unsigned ResNo) const { assert(ResNo < NumValues && "Illegal result number!"); return ValueList[ResNo]; } /// Return the type of a specified result as a simple type. - /// MVT getSimpleValueType(unsigned ResNo) const { return getValueType(ResNo).getSimpleVT(); } - /// getValueSizeInBits - Returns MVT::getSizeInBits(getValueType(ResNo)). - /// + /// Returns MVT::getSizeInBits(getValueType(ResNo)). unsigned getValueSizeInBits(unsigned ResNo) const { return getValueType(ResNo).getSizeInBits(); } @@ -682,8 +658,7 @@ public: value_iterator value_begin() const { return ValueList; } value_iterator value_end() const { return ValueList+NumValues; } - /// getOperationName - Return the opcode of this operation for printing. - /// + /// Return the opcode of this operation for printing. std::string getOperationName(const SelectionDAG *G = nullptr) const; static const char* getIndexedModeName(ISD::MemIndexedMode AM); void print_types(raw_ostream &OS, const SelectionDAG *G) const; @@ -691,7 +666,7 @@ public: void print(raw_ostream &OS, const SelectionDAG *G = nullptr) const; void printr(raw_ostream &OS, const SelectionDAG *G = nullptr) const; - /// printrFull - Print a SelectionDAG node and all children down to + /// Print a SelectionDAG node and all children down to /// the leaves. The given SelectionDAG allows target-specific nodes /// to be printed in human-readable form. Unlike printr, this will /// print the whole DAG, including children that appear multiple @@ -699,7 +674,7 @@ public: /// void printrFull(raw_ostream &O, const SelectionDAG *G = nullptr) const; - /// printrWithDepth - Print a SelectionDAG node and children up to + /// Print a SelectionDAG node and children up to /// depth "depth." The given SelectionDAG allows target-specific /// nodes to be printed in human-readable form. Unlike printr, this /// will print children that appear multiple times wherever they are @@ -709,30 +684,29 @@ public: unsigned depth = 100) const; - /// dump - Dump this node, for debugging. + /// Dump this node, for debugging. void dump() const; - /// dumpr - Dump (recursively) this node and its use-def subgraph. + /// Dump (recursively) this node and its use-def subgraph. void dumpr() const; - /// dump - Dump this node, for debugging. + /// Dump this node, for debugging. /// The given SelectionDAG allows target-specific nodes to be printed /// in human-readable form. void dump(const SelectionDAG *G) const; - /// dumpr - Dump (recursively) this node and its use-def subgraph. + /// Dump (recursively) this node and its use-def subgraph. /// The given SelectionDAG allows target-specific nodes to be printed /// in human-readable form. void dumpr(const SelectionDAG *G) const; - /// dumprFull - printrFull to dbgs(). The given SelectionDAG allows + /// printrFull to dbgs(). The given SelectionDAG allows /// target-specific nodes to be printed in human-readable form. /// Unlike dumpr, this will print the whole DAG, including children /// that appear multiple times. - /// void dumprFull(const SelectionDAG *G = nullptr) const; - /// dumprWithDepth - printrWithDepth to dbgs(). The given + /// printrWithDepth to dbgs(). The given /// SelectionDAG allows target-specific nodes to be printed in /// human-readable form. Unlike dumpr, this will print children /// that appear multiple times wherever they are used. @@ -740,12 +714,10 @@ public: void dumprWithDepth(const SelectionDAG *G = nullptr, unsigned depth = 100) const; - /// Profile - Gather unique data for the node. - /// + /// Gather unique data for the node. void Profile(FoldingSetNodeID &ID) const; - /// addUse - This method should only be used by the SDUse class. - /// + /// This method should only be used by the SDUse class. void addUse(SDUse &U) { U.addToList(&UseList); } protected: @@ -786,7 +758,7 @@ protected: "NumValues wasn't wide enough for its operands!"); } - /// InitOperands - Initialize the operands list of this with 1 operand. + /// Initialize the operands list of this with 1 operand. void InitOperands(SDUse *Ops, const SDValue &Op0) { Ops[0].setUser(this); Ops[0].setInitial(Op0); @@ -795,7 +767,7 @@ protected: checkForCycles(this); } - /// InitOperands - Initialize the operands list of this with 2 operands. + /// Initialize the operands list of this with 2 operands. void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1) { Ops[0].setUser(this); Ops[0].setInitial(Op0); @@ -806,7 +778,7 @@ protected: checkForCycles(this); } - /// InitOperands - Initialize the operands list of this with 3 operands. + /// Initialize the operands list of this with 3 operands. void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1, const SDValue &Op2) { Ops[0].setUser(this); @@ -820,7 +792,7 @@ protected: checkForCycles(this); } - /// InitOperands - Initialize the operands list of this with 4 operands. + /// Initialize the operands list of this with 4 operands. void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1, const SDValue &Op2, const SDValue &Op3) { Ops[0].setUser(this); @@ -836,7 +808,7 @@ protected: checkForCycles(this); } - /// InitOperands - Initialize the operands list of this with N operands. + /// Initialize the operands list of this with N operands. void InitOperands(SDUse *Ops, const SDValue *Vals, unsigned N) { for (unsigned i = 0; i != N; ++i) { Ops[i].setUser(this); @@ -849,8 +821,7 @@ protected: checkForCycles(this); } - /// DropOperands - Release the operands and set this node to have - /// zero operands. + /// Release the operands and set this node to have zero operands. void DropOperands(); }; @@ -972,7 +943,7 @@ inline void SDUse::setNode(SDNode *N) { if (N) N->addUse(*this); } -/// UnarySDNode - This class is used for single-operand SDNodes. This is solely +/// This class is used for single-operand SDNodes. This is solely /// to allow co-allocation of node operands with the node itself. class UnarySDNode : public SDNode { SDUse Op; @@ -984,7 +955,7 @@ public: } }; -/// BinarySDNode - This class is used for two-operand SDNodes. This is solely +/// This class is used for two-operand SDNodes. This is solely /// to allow co-allocation of node operands with the node itself. class BinarySDNode : public SDNode { SDUse Ops[2]; @@ -996,7 +967,7 @@ public: } }; -/// BinaryWithFlagsSDNode - This class is an extension of BinarySDNode +/// This class is an extension of BinarySDNode /// used from those opcodes that have associated extra flags. class BinaryWithFlagsSDNode : public BinarySDNode { enum { NUW = (1 << 0), NSW = (1 << 1), EXACT = (1 << 2) }; @@ -1005,8 +976,7 @@ public: BinaryWithFlagsSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y) : BinarySDNode(Opc, Order, dl, VTs, X, Y) {} - /// getRawSubclassData - Return the SubclassData value, which contains an - /// encoding of the flags. + /// Return the SubclassData value, which contains an encoding of the flags. /// This function should be used to add subclass data to the NodeID value. unsigned getRawSubclassData() const { return SubclassData; } void setHasNoUnsignedWrap(bool b) { @@ -1026,7 +996,7 @@ public: } }; -/// TernarySDNode - This class is used for three-operand SDNodes. This is solely +/// This class is used for three-operand SDNodes. This is solely /// to allow co-allocation of node operands with the node itself. class TernarySDNode : public SDNode { SDUse Ops[3]; @@ -1039,7 +1009,7 @@ public: }; -/// HandleSDNode - This class is used to form a handle around another node that +/// This class is used to form a handle around another node that /// is persistent and is updated across invocations of replaceAllUsesWith on its /// operand. This node should be directly created by end-users and not added to /// the AllNodes list. @@ -1074,11 +1044,11 @@ public: /// Abstact virtual class for operations for memory operations class MemSDNode : public SDNode { private: - // MemoryVT - VT of in-memory value. + // VT of in-memory value. EVT MemoryVT; protected: - /// MMO - Memory reference information. + /// Memory reference information. MachineMemOperand *MMO; public: @@ -1099,7 +1069,7 @@ public: return MMO->getAlignment(); } - /// getRawSubclassData - Return the SubclassData value, which contains an + /// Return the SubclassData value, which contains an /// encoding of the volatile flag, as well as bits used by subclasses. This /// function should only be used to compute a FoldingSetNodeID value. unsigned getRawSubclassData() const { @@ -1128,10 +1098,10 @@ public: /// Returns the Ranges that describes the dereference. const MDNode *getRanges() const { return MMO->getRanges(); } - /// getMemoryVT - Return the type of the in-memory value. + /// Return the type of the in-memory value. EVT getMemoryVT() const { return MemoryVT; } - /// getMemOperand - Return a MachineMemOperand object describing the memory + /// Return a MachineMemOperand object describing the memory /// reference performed by operation. MachineMemOperand *getMemOperand() const { return MMO; } @@ -1139,12 +1109,12 @@ public: return MMO->getPointerInfo(); } - /// getAddressSpace - Return the address space for the associated pointer + /// Return the address space for the associated pointer unsigned getAddressSpace() const { return getPointerInfo().getAddrSpace(); } - /// refineAlignment - Update this MemSDNode's MachineMemOperand information + /// Update this MemSDNode's MachineMemOperand information /// to reflect the alignment of NewMMO, if it has a greater alignment. /// This must only be used when the new alignment applies to all users of /// this MachineMemOperand. @@ -1186,8 +1156,7 @@ public: } }; -/// AtomicSDNode - A SDNode reprenting atomic operations. -/// +/// A SDNode reprenting atomic operations. class AtomicSDNode : public MemSDNode { SDUse Ops[4]; @@ -1300,7 +1269,7 @@ public: } }; -/// MemIntrinsicSDNode - This SDNode is used for target intrinsics that touch +/// This SDNode is used for target intrinsics that touch /// memory and need an associated MachineMemOperand. Its opcode may be /// INTRINSIC_VOID, INTRINSIC_W_CHAIN, PREFETCH, or a target-specific opcode /// with a value not less than FIRST_TARGET_MEMORY_OPCODE. @@ -1323,7 +1292,7 @@ public: } }; -/// ShuffleVectorSDNode - This SDNode is used to implement the code generator +/// This SDNode is used to implement the code generator /// support for the llvm IR shufflevector instruction. It combines elements /// from two input vectors into a new input vector, with the selection and /// ordering of elements determined by an array of integers, referred to as @@ -1367,6 +1336,21 @@ public: } static bool isSplatMask(const int *Mask, EVT VT); + /// Change values in a shuffle permute mask assuming + /// the two vector operands have swapped position. + static void commuteMask(SmallVectorImpl<int> &Mask) { + unsigned NumElems = Mask.size(); + for (unsigned i = 0; i != NumElems; ++i) { + int idx = Mask[i]; + if (idx < 0) + continue; + else if (idx < (int)NumElems) + Mask[i] = idx + NumElems; + else + Mask[i] = idx - NumElems; + } + } + static bool classof(const SDNode *N) { return N->getOpcode() == ISD::VECTOR_SHUFFLE; } @@ -1411,19 +1395,19 @@ public: const APFloat& getValueAPF() const { return Value->getValueAPF(); } const ConstantFP *getConstantFPValue() const { return Value; } - /// isZero - Return true if the value is positive or negative zero. + /// Return true if the value is positive or negative zero. bool isZero() const { return Value->isZero(); } - /// isNaN - Return true if the value is a NaN. + /// Return true if the value is a NaN. bool isNaN() const { return Value->isNaN(); } - /// isInfinity - Return true if the value is an infinity + /// Return true if the value is an infinity bool isInfinity() const { return Value->isInfinity(); } - /// isNegative - Return true if the value is negative. + /// Return true if the value is negative. bool isNegative() const { return Value->isNegative(); } - /// isExactlyValue - We don't rely on operator== working on double values, as + /// We don't rely on operator== working on double values, as /// it returns true for things that are clearly not equal, like -0.0 and 0.0. /// As such, this method can be used to do an exact bit-for-bit comparison of /// two floating point values. @@ -1607,13 +1591,12 @@ public: } }; -/// BuildVectorSDNode - A "pseudo-class" with methods for operating on -/// BUILD_VECTORs. +/// A "pseudo-class" with methods for operating on BUILD_VECTORs. class BuildVectorSDNode : public SDNode { // These are constructed as SDNodes and then cast to BuildVectorSDNodes. explicit BuildVectorSDNode() = delete; public: - /// isConstantSplat - Check if this is a constant splat, and if so, find the + /// Check if this is a constant splat, and if so, find the /// smallest element size that splats the vector. If MinSplatBits is /// nonzero, the element size must be at least that large. Note that the /// splat element may be the entire vector (i.e., a one element vector). @@ -1656,7 +1639,7 @@ public: } }; -/// SrcValueSDNode - An SDNode that holds an arbitrary LLVM IR Value. This is +/// An SDNode that holds an arbitrary LLVM IR Value. This is /// used when the SelectionDAG needs to make a simple reference to something /// in the LLVM IR representation. /// @@ -1668,7 +1651,7 @@ class SrcValueSDNode : public SDNode { : SDNode(ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {} public: - /// getValue - return the contained Value. + /// Return the contained Value. const Value *getValue() const { return V; } static bool classof(const SDNode *N) { @@ -1795,7 +1778,7 @@ public: } }; -/// CvtRndSatSDNode - NOTE: avoid using this node as this may disappear in the +/// NOTE: avoid using this node as this may disappear in the /// future and most targets don't support it. class CvtRndSatSDNode : public SDNode { ISD::CvtCode CvtCode; @@ -1814,7 +1797,7 @@ public: } }; -/// VTSDNode - This class is used to represent EVT's, which are used +/// This class is used to represent EVT's, which are used /// to parameterize some operations. class VTSDNode : public SDNode { EVT ValueType; @@ -1832,8 +1815,7 @@ public: } }; -/// LSBaseSDNode - Base class for LoadSDNode and StoreSDNode -/// +/// Base class for LoadSDNode and StoreSDNode class LSBaseSDNode : public MemSDNode { //! Operand array for load and store /*! @@ -1859,16 +1841,16 @@ public: return getOperand(getOpcode() == ISD::LOAD ? 2 : 3); } - /// getAddressingMode - Return the addressing mode for this load or store: + /// Return the addressing mode for this load or store: /// unindexed, pre-inc, pre-dec, post-inc, or post-dec. ISD::MemIndexedMode getAddressingMode() const { return ISD::MemIndexedMode((SubclassData >> 2) & 7); } - /// isIndexed - Return true if this is a pre/post inc/dec load/store. + /// Return true if this is a pre/post inc/dec load/store. bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; } - /// isUnindexed - Return true if this is NOT a pre/post inc/dec load/store. + /// Return true if this is NOT a pre/post inc/dec load/store. bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; } static bool classof(const SDNode *N) { @@ -1877,8 +1859,7 @@ public: } }; -/// LoadSDNode - This class is used to represent ISD::LOAD nodes. -/// +/// This class is used to represent ISD::LOAD nodes. class LoadSDNode : public LSBaseSDNode { friend class SelectionDAG; LoadSDNode(SDValue *ChainPtrOff, unsigned Order, DebugLoc dl, SDVTList VTs, @@ -1892,7 +1873,7 @@ class LoadSDNode : public LSBaseSDNode { } public: - /// getExtensionType - Return whether this is a plain node, + /// Return whether this is a plain node, /// or one of the varieties of value-extending loads. ISD::LoadExtType getExtensionType() const { return ISD::LoadExtType(SubclassData & 3); @@ -1906,8 +1887,7 @@ public: } }; -/// StoreSDNode - This class is used to represent ISD::STORE nodes. -/// +/// This class is used to represent ISD::STORE nodes. class StoreSDNode : public LSBaseSDNode { friend class SelectionDAG; StoreSDNode(SDValue *ChainValuePtrOff, unsigned Order, DebugLoc dl, @@ -1922,7 +1902,7 @@ class StoreSDNode : public LSBaseSDNode { } public: - /// isTruncatingStore - Return true if the op does a truncation before store. + /// Return true if the op does a truncation before store. /// For integers this is the same as doing a TRUNCATE and storing the result. /// For floats, it is the same as doing an FP_ROUND and storing the result. bool isTruncatingStore() const { return SubclassData & 1; } @@ -1936,9 +1916,7 @@ public: } }; -/// MaskedLoadStoreSDNode - This is a base class is used to represent MLOAD and -/// MSTORE nodes -/// +/// This base class is used to represent MLOAD and MSTORE nodes class MaskedLoadStoreSDNode : public MemSDNode { // Operands SDUse Ops[4]; @@ -1964,8 +1942,7 @@ public: } }; -/// MaskedLoadSDNode - This class is used to represent an MLOAD node -/// +/// This class is used to represent an MLOAD node class MaskedLoadSDNode : public MaskedLoadStoreSDNode { public: friend class SelectionDAG; @@ -1986,8 +1963,7 @@ public: } }; -/// MaskedStoreSDNode - This class is used to represent an MSTORE node -/// +/// This class is used to represent an MSTORE node class MaskedStoreSDNode : public MaskedLoadStoreSDNode { public: @@ -1999,7 +1975,7 @@ public: VTs, MemVT, MMO) { SubclassData |= (unsigned short)isTrunc; } - /// isTruncatingStore - Return true if the op does a truncation before store. + /// Return true if the op does a truncation before store. /// For integers this is the same as doing a TRUNCATE and storing the result. /// For floats, it is the same as doing an FP_ROUND and storing the result. bool isTruncatingStore() const { return SubclassData & 1; } @@ -2011,10 +1987,9 @@ public: } }; -/// MachineSDNode - An SDNode that represents everything that will be needed +/// An SDNode that represents everything that will be needed /// to construct a MachineInstr. These nodes are created during the /// instruction selection proper phase. -/// class MachineSDNode : public SDNode { public: typedef MachineMemOperand **mmo_iterator; @@ -2024,11 +1999,11 @@ private: MachineSDNode(unsigned Opc, unsigned Order, const DebugLoc DL, SDVTList VTs) : SDNode(Opc, Order, DL, VTs), MemRefs(nullptr), MemRefsEnd(nullptr) {} - /// LocalOperands - Operands for this instruction, if they fit here. If + /// Operands for this instruction, if they fit here. If /// they don't, this field is unused. SDUse LocalOperands[4]; - /// MemRefs - Memory reference descriptions for this instruction. + /// Memory reference descriptions for this instruction. mmo_iterator MemRefs; mmo_iterator MemRefsEnd; @@ -2037,7 +2012,7 @@ public: mmo_iterator memoperands_end() const { return MemRefsEnd; } bool memoperands_empty() const { return MemRefsEnd == MemRefs; } - /// setMemRefs - Assign this MachineSDNodes's memory reference descriptor + /// Assign this MachineSDNodes's memory reference descriptor /// list. This does not transfer ownership. void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd) { for (mmo_iterator MMI = NewMemRefs, MME = NewMemRefsEnd; MMI != MME; ++MMI) @@ -2063,12 +2038,6 @@ public: } bool operator!=(const SDNodeIterator& x) const { return !operator==(x); } - const SDNodeIterator &operator=(const SDNodeIterator &I) { - assert(I.Node == Node && "Cannot assign iterators to two different nodes!"); - Operand = I.Operand; - return *this; - } - pointer operator*() const { return Node->getOperand(Operand).getNode(); } @@ -2108,60 +2077,51 @@ template <> struct GraphTraits<SDNode*> { } }; -/// LargestSDNode - The largest SDNode class. -/// +/// The largest SDNode class. typedef AtomicSDNode LargestSDNode; -/// MostAlignedSDNode - The SDNode class with the greatest alignment -/// requirement. -/// +/// The SDNode class with the greatest alignment requirement. typedef GlobalAddressSDNode MostAlignedSDNode; namespace ISD { - /// isNormalLoad - Returns true if the specified node is a non-extending - /// and unindexed load. + /// Returns true if the specified node is a non-extending and unindexed load. inline bool isNormalLoad(const SDNode *N) { const LoadSDNode *Ld = dyn_cast<LoadSDNode>(N); return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD && Ld->getAddressingMode() == ISD::UNINDEXED; } - /// isNON_EXTLoad - Returns true if the specified node is a non-extending - /// load. + /// Returns true if the specified node is a non-extending load. inline bool isNON_EXTLoad(const SDNode *N) { return isa<LoadSDNode>(N) && cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD; } - /// isEXTLoad - Returns true if the specified node is a EXTLOAD. - /// + /// Returns true if the specified node is a EXTLOAD. inline bool isEXTLoad(const SDNode *N) { return isa<LoadSDNode>(N) && cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD; } - /// isSEXTLoad - Returns true if the specified node is a SEXTLOAD. - /// + /// Returns true if the specified node is a SEXTLOAD. inline bool isSEXTLoad(const SDNode *N) { return isa<LoadSDNode>(N) && cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD; } - /// isZEXTLoad - Returns true if the specified node is a ZEXTLOAD. - /// + /// Returns true if the specified node is a ZEXTLOAD. inline bool isZEXTLoad(const SDNode *N) { return isa<LoadSDNode>(N) && cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD; } - /// isUNINDEXEDLoad - Returns true if the specified node is an unindexed load. - /// + /// Returns true if the specified node is an unindexed load. inline bool isUNINDEXEDLoad(const SDNode *N) { return isa<LoadSDNode>(N) && cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; } - /// isNormalStore - Returns true if the specified node is a non-truncating + /// Returns true if the specified node is a non-truncating /// and unindexed store. inline bool isNormalStore(const SDNode *N) { const StoreSDNode *St = dyn_cast<StoreSDNode>(N); @@ -2169,20 +2129,17 @@ namespace ISD { St->getAddressingMode() == ISD::UNINDEXED; } - /// isNON_TRUNCStore - Returns true if the specified node is a non-truncating - /// store. + /// Returns true if the specified node is a non-truncating store. inline bool isNON_TRUNCStore(const SDNode *N) { return isa<StoreSDNode>(N) && !cast<StoreSDNode>(N)->isTruncatingStore(); } - /// isTRUNCStore - Returns true if the specified node is a truncating - /// store. + /// Returns true if the specified node is a truncating store. inline bool isTRUNCStore(const SDNode *N) { return isa<StoreSDNode>(N) && cast<StoreSDNode>(N)->isTruncatingStore(); } - /// isUNINDEXEDStore - Returns true if the specified node is an - /// unindexed store. + /// Returns true if the specified node is an unindexed store. inline bool isUNINDEXEDStore(const SDNode *N) { return isa<StoreSDNode>(N) && cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; diff --git a/include/llvm/CodeGen/StackMapLivenessAnalysis.h b/include/llvm/CodeGen/StackMapLivenessAnalysis.h deleted file mode 100644 index f67a6e9..0000000 --- a/include/llvm/CodeGen/StackMapLivenessAnalysis.h +++ /dev/null @@ -1,64 +0,0 @@ -//===--- StackMapLivenessAnalysis - StackMap Liveness Analysis --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass calculates the liveness for each basic block in a function and -// attaches the register live-out information to a patchpoint intrinsic (if -// present). -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_STACKMAPLIVENESSANALYSIS_H -#define LLVM_CODEGEN_STACKMAPLIVENESSANALYSIS_H - -#include "llvm/CodeGen/LivePhysRegs.h" -#include "llvm/CodeGen/MachineFunctionPass.h" - - -namespace llvm { - -/// \brief This pass calculates the liveness information for each basic block in -/// a function and attaches the register live-out information to a patchpoint -/// intrinsic if present. -/// -/// This pass can be disabled via the -enable-patchpoint-liveness=false flag. -/// The pass skips functions that don't have any patchpoint intrinsics. The -/// information provided by this pass is optional and not required by the -/// aformentioned intrinsic to function. -class StackMapLiveness : public MachineFunctionPass { - MachineFunction *MF; - const TargetRegisterInfo *TRI; - LivePhysRegs LiveRegs; -public: - static char ID; - - /// \brief Default construct and initialize the pass. - StackMapLiveness(); - - /// \brief Tell the pass manager which passes we depend on and what - /// information we preserve. - void getAnalysisUsage(AnalysisUsage &AU) const override; - - /// \brief Calculate the liveness information for the given machine function. - bool runOnMachineFunction(MachineFunction &MF) override; - -private: - /// \brief Performs the actual liveness calculation for the function. - bool calculateLiveness(); - - /// \brief Add the current register live set to the instruction. - void addLiveOutSetToMI(MachineInstr &MI); - - /// \brief Create a register mask and initialize it with the registers from - /// the register live set. - uint32_t *createRegisterMask() const; -}; - -} // llvm namespace - -#endif diff --git a/include/llvm/CodeGen/StackMaps.h b/include/llvm/CodeGen/StackMaps.h index 4e48afe..caec994 100644 --- a/include/llvm/CodeGen/StackMaps.h +++ b/include/llvm/CodeGen/StackMaps.h @@ -14,6 +14,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Support/Debug.h" #include <map> #include <vector> @@ -245,7 +246,10 @@ private: void emitConstantPoolEntries(MCStreamer &OS); /// \brief Emit the callsite info for each stackmap/patchpoint intrinsic call. - void emitCallsiteEntries(MCStreamer &OS, const TargetRegisterInfo *TRI); + void emitCallsiteEntries(MCStreamer &OS); + + void print(raw_ostream &OS); + void debug() { print(dbgs()); } }; } diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 348c634..75920a3 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -88,6 +88,7 @@ public: class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { public: virtual ~TargetLoweringObjectFileMachO() {} + TargetLoweringObjectFileMachO(); /// Extract the dependent library name from a linker option string. Returns /// StringRef() if the option does not specify a library. @@ -122,6 +123,12 @@ public: MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM, MachineModuleInfo *MMI) const override; + + /// Get MachO PC relative GOT entry relocation + const MCExpr *getIndirectSymViaGOTPCRel(const MCSymbol *Sym, + const MCValue &MV, int64_t Offset, + MachineModuleInfo *MMI, + MCStreamer &Streamer) const override; }; @@ -140,6 +147,14 @@ public: SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const override; + void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV, + bool CannotUsePrivateLabel, Mangler &Mang, + const TargetMachine &TM) const override; + + const MCSection * + getSectionForJumpTable(const Function &F, Mangler &Mang, + const TargetMachine &TM) const override; + /// Extract the dependent library name from a linker option string. Returns /// StringRef() if the option does not specify a library. StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const override; diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 4e93940..e1a9fd3 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -34,10 +34,9 @@ namespace llvm { Type *LLVMTy; public: - EVT() : V((MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE)), - LLVMTy(nullptr) {} - EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(nullptr) { } - EVT(MVT S) : V(S), LLVMTy(nullptr) {} + LLVM_CONSTEXPR EVT() : V(MVT::INVALID_SIMPLE_VALUE_TYPE), LLVMTy(nullptr) {} + LLVM_CONSTEXPR EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(nullptr) {} + LLVM_CONSTEXPR EVT(MVT S) : V(S), LLVMTy(nullptr) {} bool operator==(EVT VT) const { return !(*this != VT); diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index 86ae8bb..bd50d6e 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -33,9 +33,6 @@ /* Define to 1 if you have the `bcopy' function. */ #undef HAVE_BCOPY -/* Define to 1 if you have the `ceilf' function. */ -#cmakedefine HAVE_CEILF ${HAVE_CEILF} - /* Define to 1 if you have the `closedir' function. */ #cmakedefine HAVE_CLOSEDIR ${HAVE_CLOSEDIR} @@ -95,33 +92,6 @@ /* Define to 1 if you have the <ffi.h> header file. */ #cmakedefine HAVE_FFI_H ${HAVE_FFI_H} -/* Set to 1 if the finite function is found in <ieeefp.h> */ -#cmakedefine HAVE_FINITE_IN_IEEEFP_H ${HAVE_FINITE_IN_IEEEFP_H} - -/* Define to 1 if you have the `floorf' function. */ -#cmakedefine HAVE_FLOORF ${HAVE_FLOORF} - -/* Define to 1 if you have the `log' function. */ -#cmakedefine HAVE_LOG ${HAVE_LOG} - -/* Define to 1 if you have the `log2' function. */ -#cmakedefine HAVE_LOG2 ${HAVE_LOG2} - -/* Define to 1 if you have the `log10' function. */ -#cmakedefine HAVE_LOG10 ${HAVE_LOG10} - -/* Define to 1 if you have the `exp' function. */ -#cmakedefine HAVE_EXP ${HAVE_EXP} - -/* Define to 1 if you have the `exp2' function. */ -#cmakedefine HAVE_EXP2 ${HAVE_EXP2} - -/* Define to 1 if you have the `exp10' function. */ -#cmakedefine HAVE_EXP10 ${HAVE_EXP10} - -/* Define to 1 if you have the `fmodf' function. */ -#cmakedefine HAVE_FMODF ${HAVE_FMODF} - /* Define to 1 if you have the `futimes' function. */ #cmakedefine HAVE_FUTIMES ${HAVE_FUTIMES} @@ -152,18 +122,6 @@ /* Define to 1 if you have the `isatty' function. */ #cmakedefine HAVE_ISATTY 1 -/* Set to 1 if the isinf function is found in <cmath> */ -#cmakedefine HAVE_ISINF_IN_CMATH ${HAVE_ISINF_IN_CMATH} - -/* Set to 1 if the isinf function is found in <math.h> */ -#cmakedefine HAVE_ISINF_IN_MATH_H ${HAVE_ISINF_IN_MATH_H} - -/* Set to 1 if the isnan function is found in <cmath> */ -#cmakedefine HAVE_ISNAN_IN_CMATH ${HAVE_ISNAN_IN_CMATH} - -/* Set to 1 if the isnan function is found in <math.h> */ -#cmakedefine HAVE_ISNAN_IN_MATH_H ${HAVE_ISNAN_IN_MATH_H} - /* Define if you have the libdl library or equivalent. */ #cmakedefine HAVE_LIBDL ${HAVE_LIBDL} @@ -247,18 +205,12 @@ /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ #cmakedefine HAVE_NDIR_H ${HAVE_NDIR_H} -/* Define to 1 if you have the `nearbyintf' function. */ -#cmakedefine HAVE_NEARBYINTF ${HAVE_NEARBYINTF} - /* Define to 1 if you have the `opendir' function. */ #cmakedefine HAVE_OPENDIR ${HAVE_OPENDIR} /* Define to 1 if you have the `posix_spawn' function. */ #cmakedefine HAVE_POSIX_SPAWN ${HAVE_POSIX_SPAWN} -/* Define to 1 if you have the `powf' function. */ -#cmakedefine HAVE_POWF ${HAVE_POWF} - /* Define to 1 if you have the `pread' function. */ #cmakedefine HAVE_PREAD ${HAVE_PREAD} @@ -289,15 +241,6 @@ /* Define to 1 if you have the `realpath' function. */ #cmakedefine HAVE_REALPATH ${HAVE_REALPATH} -/* Define to 1 if you have the `rintf' function. */ -#undef HAVE_RINTF - -/* Define to 1 if you have the `round' function. */ -#cmakedefine HAVE_ROUND ${HAVE_ROUND} - -/* Define to 1 if you have the `roundf' function. */ -#undef HAVE_ROUNDF - /* Define to 1 if you have the `sbrk' function. */ #cmakedefine HAVE_SBRK ${HAVE_SBRK} @@ -340,9 +283,6 @@ /* Define to 1 if you have the `strerror_r' function. */ #cmakedefine HAVE_STRERROR_R ${HAVE_STRERROR_R} -/* Define to 1 if you have the `strtof' function. */ -#cmakedefine HAVE_STRTOF ${HAVE_STRTOF} - /* Define to 1 if you have the `strtoll' function. */ #cmakedefine HAVE_STRTOLL ${HAVE_STRTOLL} diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index c317bb1..67d7c84 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -39,9 +39,6 @@ /* Define to 1 if you have the `backtrace' function. */ #undef HAVE_BACKTRACE -/* Define to 1 if you have the `ceilf' function. */ -#undef HAVE_CEILF - /* Define to 1 if you have the <CrashReporterClient.h> header file. */ #undef HAVE_CRASHREPORTERCLIENT_H @@ -67,9 +64,6 @@ don't. */ #undef HAVE_DECL_STRERROR_S -/* Define to 1 if you have the DIA SDK installed, and to 0 if you don't. */ -#undef HAVE_DIA_SDK - /* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'. */ #undef HAVE_DIRENT_H @@ -89,12 +83,6 @@ /* Define to 1 if you have the <execinfo.h> header file. */ #undef HAVE_EXECINFO_H -/* Define to 1 if you have the `exp' function. */ -#undef HAVE_EXP - -/* Define to 1 if you have the `exp2' function. */ -#undef HAVE_EXP2 - /* Define to 1 if you have the <fcntl.h> header file. */ #undef HAVE_FCNTL_H @@ -110,15 +98,6 @@ /* Define to 1 if you have the <ffi.h> header file. */ #undef HAVE_FFI_H -/* Set to 1 if the finite function is found in <ieeefp.h> */ -#undef HAVE_FINITE_IN_IEEEFP_H - -/* Define to 1 if you have the `floorf' function. */ -#undef HAVE_FLOORF - -/* Define to 1 if you have the `fmodf' function. */ -#undef HAVE_FMODF - /* Define to 1 if you have the `futimens' function. */ #undef HAVE_FUTIMENS @@ -149,18 +128,6 @@ /* Define to 1 if you have the `isatty' function. */ #undef HAVE_ISATTY -/* Set to 1 if the isinf function is found in <cmath> */ -#undef HAVE_ISINF_IN_CMATH - -/* Set to 1 if the isinf function is found in <math.h> */ -#undef HAVE_ISINF_IN_MATH_H - -/* Set to 1 if the isnan function is found in <cmath> */ -#undef HAVE_ISNAN_IN_CMATH - -/* Set to 1 if the isnan function is found in <math.h> */ -#undef HAVE_ISNAN_IN_MATH_H - /* Define if libedit is available on this platform. */ #undef HAVE_LIBEDIT @@ -192,15 +159,6 @@ the current directory to the dynamic linker search path. */ #undef HAVE_LINK_R -/* Define to 1 if you have the `log' function. */ -#undef HAVE_LOG - -/* Define to 1 if you have the `log10' function. */ -#undef HAVE_LOG10 - -/* Define to 1 if you have the `log2' function. */ -#undef HAVE_LOG2 - /* Define to 1 if you have the `longjmp' function. */ #undef HAVE_LONGJMP @@ -210,9 +168,6 @@ /* Define if mallinfo() is available on this platform. */ #undef HAVE_MALLINFO -/* Define if mallctl() is available on this plaform. */ -#undef HAVE_MALLCTL - /* Define to 1 if you have the <malloc.h> header file. */ #undef HAVE_MALLOC_H @@ -247,15 +202,9 @@ /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ #undef HAVE_NDIR_H -/* Define to 1 if you have the `nearbyintf' function. */ -#undef HAVE_NEARBYINTF - /* Define to 1 if you have the `posix_spawn' function. */ #undef HAVE_POSIX_SPAWN -/* Define to 1 if you have the `powf' function. */ -#undef HAVE_POWF - /* Define to 1 if you have the `pread' function. */ #undef HAVE_PREAD @@ -280,15 +229,6 @@ /* Define to 1 if you have the `realpath' function. */ #undef HAVE_REALPATH -/* Define to 1 if you have the `rintf' function. */ -#undef HAVE_RINTF - -/* Define to 1 if you have the `round' function. */ -#undef HAVE_ROUND - -/* Define to 1 if you have the `roundf' function. */ -#undef HAVE_ROUNDF - /* Define to 1 if you have the `sbrk' function. */ #undef HAVE_SBRK @@ -319,12 +259,6 @@ /* Define to 1 if you have the <stdlib.h> header file. */ #undef HAVE_STDLIB_H -/* Set to 1 if the std::isinf function is found in <cmath> */ -#undef HAVE_STD_ISINF_IN_CMATH - -/* Set to 1 if the std::isnan function is found in <cmath> */ -#undef HAVE_STD_ISNAN_IN_CMATH - /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR @@ -337,9 +271,6 @@ /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H -/* Define to 1 if you have the `strtof' function. */ -#undef HAVE_STRTOF - /* Define to 1 if you have the `strtoll' function. */ #undef HAVE_STRTOLL @@ -486,6 +417,9 @@ /* Installation directory for documentation */ #undef LLVM_DOCSDIR +/* Define to enable checks that alter the LLVM C++ ABI */ +#undef LLVM_ENABLE_ABI_BREAKING_CHECKS + /* Define if threads enabled */ #undef LLVM_ENABLE_THREADS diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake index d54003d..bb7dc06 100644 --- a/include/llvm/Config/llvm-config.h.cmake +++ b/include/llvm/Config/llvm-config.h.cmake @@ -101,4 +101,8 @@ /* Define if we link Polly to the tools */ #cmakedefine LINK_POLLY_INTO_TOOLS +/* Define if LLVM is built with asserts and checks that change the layout of + client-visible data structures. */ +#cmakedefine LLVM_ENABLE_ABI_BREAKING_CHECKS + #endif diff --git a/include/llvm/Config/llvm-config.h.in b/include/llvm/Config/llvm-config.h.in index 25a9295..03e482a 100644 --- a/include/llvm/Config/llvm-config.h.in +++ b/include/llvm/Config/llvm-config.h.in @@ -98,4 +98,7 @@ /* LLVM version string */ #undef LLVM_VERSION_STRING +/* Define to enable checks that alter the LLVM C++ ABI */ +#undef LLVM_ENABLE_ABI_BREAKING_CHECKS + #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h index bb05c30..6ab5d5c 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h @@ -18,18 +18,14 @@ namespace llvm { class raw_ostream; class DWARFAbbreviationDeclaration { - uint32_t Code; - uint32_t Tag; - bool HasChildren; - +public: struct AttributeSpec { AttributeSpec(uint16_t Attr, uint16_t Form) : Attr(Attr), Form(Form) {} uint16_t Attr; uint16_t Form; }; typedef SmallVector<AttributeSpec, 8> AttributeSpecVector; - AttributeSpecVector AttributeSpecs; -public: + DWARFAbbreviationDeclaration(); uint32_t getCode() const { return Code; } @@ -53,6 +49,12 @@ public: private: void clear(); + + uint32_t Code; + uint32_t Tag; + bool HasChildren; + + AttributeSpecVector AttributeSpecs; }; } diff --git a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h index e34f096..47dbf5f 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h @@ -7,6 +7,9 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_LIB_DEBUGINFO_DWARFACCELERATORTABLE_H +#define LLVM_LIB_DEBUGINFO_DWARFACCELERATORTABLE_H + #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" @@ -47,3 +50,5 @@ public: }; } + +#endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h index 4ee3bda..c930bd6 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -66,6 +66,8 @@ public: void clear(); void dump(raw_ostream &OS) const; bool extract(DataExtractor data, uint32_t *offset_ptr); + const std::vector<RangeListEntry> &getEntries() { return Entries; } + /// getAbsoluteRanges - Returns absolute address ranges defined by this range /// list. Has to be passed base address of the compile unit referencing this /// range list. diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index 5bb6d1b..02f4681 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -63,7 +63,7 @@ public: /// The passed DWARFUnit is allowed to be nullptr, in which /// case no relocation processing will be performed and some /// kind of forms that depend on Unit information are disallowed. - /// \returns wether the extraction succeeded. + /// \returns whether the extraction succeeded. bool extractValue(DataExtractor data, uint32_t *offset_ptr, const DWARFUnit *u); bool isInlinedCStr() const { @@ -74,6 +74,7 @@ public: /// DWARFFormValue has form class is suitable for representing Foo. Optional<uint64_t> getAsReference(const DWARFUnit *U) const; Optional<uint64_t> getAsUnsignedConstant() const; + Optional<int64_t> getAsSignedConstant() const; Optional<const char *> getAsCString(const DWARFUnit *U) const; Optional<uint64_t> getAsAddress(const DWARFUnit *U) const; Optional<uint64_t> getAsSectionOffset() const; diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index 628852f..29fa4a3 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -10,6 +10,7 @@ #ifndef LLVM_LIB_DEBUGINFO_DWARFUNIT_H #define LLVM_LIB_DEBUGINFO_DWARFUNIT_H +#include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" diff --git a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h index c71f35c..9308b8e 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h @@ -24,7 +24,7 @@ public: CComPtr<IDiaSymbol> getDiaSymbol() const { return Symbol; } std::unique_ptr<IPDBEnumSymbols> - DIARawSymbol::findChildren(PDB_SymType Type) const override; + findChildren(PDB_SymType Type) const override; std::unique_ptr<IPDBEnumSymbols> findChildren(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags) const override; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/include/llvm/DebugInfo/PDB/DIA/DIASession.h index 141b9b0..6c72c3e 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIASession.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIASession.h @@ -19,7 +19,8 @@ class DIASession : public IPDBSession { public: explicit DIASession(CComPtr<IDiaSession> DiaSession); - static DIASession *createFromPdb(StringRef Path); + static PDB_ErrorCode createFromPdb(StringRef Path, + std::unique_ptr<IPDBSession> &Session); uint64_t getLoadAddress() const override; void setLoadAddress(uint64_t Address) override; diff --git a/include/llvm/DebugInfo/PDB/PDB.h b/include/llvm/DebugInfo/PDB/PDB.h index 7193eef..67878e9 100644 --- a/include/llvm/DebugInfo/PDB/PDB.h +++ b/include/llvm/DebugInfo/PDB/PDB.h @@ -16,8 +16,8 @@ namespace llvm { class StringRef; -std::unique_ptr<IPDBSession> createPDBReader(PDB_ReaderType Type, - StringRef Path); +PDB_ErrorCode createPDBReader(PDB_ReaderType Type, StringRef Path, + std::unique_ptr<IPDBSession> &Session); } #endif diff --git a/include/llvm/DebugInfo/PDB/PDBExtras.h b/include/llvm/DebugInfo/PDB/PDBExtras.h index cbbe171..48ce1c1 100644 --- a/include/llvm/DebugInfo/PDB/PDBExtras.h +++ b/include/llvm/DebugInfo/PDB/PDBExtras.h @@ -26,7 +26,8 @@ raw_ostream &operator<<(raw_ostream &OS, const PDB_ThunkOrdinal &Thunk); raw_ostream &operator<<(raw_ostream &OS, const PDB_Checksum &Checksum); raw_ostream &operator<<(raw_ostream &OS, const PDB_Lang &Lang); raw_ostream &operator<<(raw_ostream &OS, const PDB_SymType &Tag); -raw_ostream &operator<<(raw_ostream &OS, const PDB_BuiltinType &Type); +raw_ostream &operator<<(raw_ostream &OS, const PDB_MemberAccess &Access); +raw_ostream &operator<<(raw_ostream &OS, const PDB_UdtType &Type); raw_ostream &operator<<(raw_ostream &OS, const PDB_UniqueId &Id); raw_ostream &operator<<(raw_ostream &OS, const Variant &Value); diff --git a/include/llvm/DebugInfo/PDB/PDBSymDumper.h b/include/llvm/DebugInfo/PDB/PDBSymDumper.h index dee601c..65110f3 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymDumper.h +++ b/include/llvm/DebugInfo/PDB/PDBSymDumper.h @@ -21,61 +21,37 @@ public: PDBSymDumper(bool ShouldRequireImpl); virtual ~PDBSymDumper(); - virtual void dump(const PDBSymbolAnnotation &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolBlock &Symbol, raw_ostream &OS, int Indent); - virtual void dump(const PDBSymbolCompiland &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolCompilandDetails &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolCompilandEnv &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolCustom &Symbol, raw_ostream &OS, int Indent); - virtual void dump(const PDBSymbolData &Symbol, raw_ostream &OS, int Indent); - virtual void dump(const PDBSymbolExe &Symbol, raw_ostream &OS, int Indent); - virtual void dump(const PDBSymbolFunc &Symbol, raw_ostream &OS, int Indent); - virtual void dump(const PDBSymbolFuncDebugEnd &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolFuncDebugStart &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolLabel &Symbol, raw_ostream &OS, int Indent); - virtual void dump(const PDBSymbolPublicSymbol &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolThunk &Symbol, raw_ostream &OS, int Indent); - virtual void dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeBaseClass &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeCustom &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeDimension &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeFriend &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeFunctionArg &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeFunctionSig &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeManaged &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeVTable &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolTypeVTableShape &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolUnknown &Symbol, raw_ostream &OS, - int Indent); - virtual void dump(const PDBSymbolUsingNamespace &Symbol, raw_ostream &OS, - int Indent); + virtual void dump(const PDBSymbolAnnotation &Symbol); + virtual void dump(const PDBSymbolBlock &Symbol); + virtual void dump(const PDBSymbolCompiland &Symbol); + virtual void dump(const PDBSymbolCompilandDetails &Symbol); + virtual void dump(const PDBSymbolCompilandEnv &Symbol); + virtual void dump(const PDBSymbolCustom &Symbol); + virtual void dump(const PDBSymbolData &Symbol); + virtual void dump(const PDBSymbolExe &Symbol); + virtual void dump(const PDBSymbolFunc &Symbol); + virtual void dump(const PDBSymbolFuncDebugEnd &Symbol); + virtual void dump(const PDBSymbolFuncDebugStart &Symbol); + virtual void dump(const PDBSymbolLabel &Symbol); + virtual void dump(const PDBSymbolPublicSymbol &Symbol); + virtual void dump(const PDBSymbolThunk &Symbol); + virtual void dump(const PDBSymbolTypeArray &Symbol); + virtual void dump(const PDBSymbolTypeBaseClass &Symbol); + virtual void dump(const PDBSymbolTypeBuiltin &Symbol); + virtual void dump(const PDBSymbolTypeCustom &Symbol); + virtual void dump(const PDBSymbolTypeDimension &Symbol); + virtual void dump(const PDBSymbolTypeEnum &Symbol); + virtual void dump(const PDBSymbolTypeFriend &Symbol); + virtual void dump(const PDBSymbolTypeFunctionArg &Symbol); + virtual void dump(const PDBSymbolTypeFunctionSig &Symbol); + virtual void dump(const PDBSymbolTypeManaged &Symbol); + virtual void dump(const PDBSymbolTypePointer &Symbol); + virtual void dump(const PDBSymbolTypeTypedef &Symbol); + virtual void dump(const PDBSymbolTypeUDT &Symbol); + virtual void dump(const PDBSymbolTypeVTable &Symbol); + virtual void dump(const PDBSymbolTypeVTableShape &Symbol); + virtual void dump(const PDBSymbolUnknown &Symbol); + virtual void dump(const PDBSymbolUsingNamespace &Symbol); private: bool RequireImpl; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbol.h b/include/llvm/DebugInfo/PDB/PDBSymbol.h index 36005eb..4360c54 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbol.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbol.h @@ -53,8 +53,7 @@ public: /// call dump() on the underlying RawSymbol, which allows us to discover /// unknown properties, but individual implementations of PDBSymbol may /// override the behavior to only dump known fields. - virtual void dump(raw_ostream &OS, int Indent, - PDBSymDumper &Dumper) const = 0; + virtual void dump(PDBSymDumper &Dumper) const = 0; void defaultDump(raw_ostream &OS, int Indent) const; PDB_SymType getSymTag() const; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h b/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h index 347e30a..c055dd7 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Annotation) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAddressOffset) FORWARD_SYMBOL_METHOD(getAddressSection) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h b/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h index a0091be..2ca1250 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Block) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAddressOffset) FORWARD_SYMBOL_METHOD(getAddressSection) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h index 055e444..f8c796a 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Compiland) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(isEditAndContinueEnabled) FORWARD_SYMBOL_METHOD(getLexicalParentId) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h index 8836828..7f29d6b 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::CompilandDetails) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; void getFrontEndVersion(VersionInfo &Version) const { RawSymbol->getFrontEndVersion(Version); diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h index c3502a0..7e2ea90 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::CompilandEnv) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getLexicalParentId) FORWARD_SYMBOL_METHOD(getName) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h b/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h index b433dde..86bfd57 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h @@ -28,7 +28,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Custom) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; void getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes); FORWARD_SYMBOL_METHOD(getSymIndexId) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolData.h b/include/llvm/DebugInfo/PDB/PDBSymbolData.h index 8b9a657..79cbbf0 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolData.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolData.h @@ -26,7 +26,7 @@ public: std::unique_ptr<PDBSymbol> getType() const; - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAccess) FORWARD_SYMBOL_METHOD(getAddressOffset) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolExe.h b/include/llvm/DebugInfo/PDB/PDBSymbolExe.h index 33046f3..7c5f302 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolExe.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolExe.h @@ -25,7 +25,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Exe) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAge) FORWARD_SYMBOL_METHOD(getGuid) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h index 22ae6e0..9db41d5 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h @@ -22,7 +22,7 @@ public: PDBSymbolFunc(const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> FuncSymbol); - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; std::unique_ptr<PDBSymbolTypeFunctionSig> getSignature() const; std::unique_ptr<PDBSymbolTypeUDT> getClassParent() const; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h index bd49314..34d551c 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FuncDebugEnd) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAddressOffset) FORWARD_SYMBOL_METHOD(getAddressSection) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h index a62eada..7671be4 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FuncDebugStart) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAddressOffset) FORWARD_SYMBOL_METHOD(getAddressSection) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h b/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h index d006495..9d9903a 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Label) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAddressOffset) FORWARD_SYMBOL_METHOD(getAddressSection) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h b/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h index a8de89d..70dfcb5 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::PublicSymbol) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAddressOffset) FORWARD_SYMBOL_METHOD(getAddressSection) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h b/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h index 88588f1..bd5a9b2 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h @@ -25,7 +25,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Thunk) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAccess) FORWARD_SYMBOL_METHOD(getAddressOffset) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h index ca925f9..513a9ec 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h @@ -26,7 +26,7 @@ public: std::unique_ptr<PDBSymbol> getElementType() const; - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getArrayIndexTypeId) FORWARD_SYMBOL_METHOD(isConstType) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h index a3dcc02..2a9a8a0 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::BaseClass) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAccess) FORWARD_SYMBOL_METHOD(getClassParentId) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h index 1cede08..69a2028 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::BuiltinType) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getBuiltinType) FORWARD_SYMBOL_METHOD(isConstType) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h index 90a043f..c41c489 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::CustomType) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getOemId) FORWARD_SYMBOL_METHOD(getOemSymbolId) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h index f871681..3f22ed8 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Dimension) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getLowerBoundId) FORWARD_SYMBOL_METHOD(getUpperBoundId) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h index 2479f46..3188c71 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h @@ -24,7 +24,10 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Enum) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; + + std::unique_ptr<PDBSymbolTypeUDT> getClassParent() const; + std::unique_ptr<PDBSymbolTypeBuiltin> getUnderlyingType() const; FORWARD_SYMBOL_METHOD(getBuiltinType) FORWARD_SYMBOL_METHOD(getClassParentId) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h index 964246f..4d393d7 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Friend) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getClassParentId) FORWARD_SYMBOL_METHOD(getName) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h index 22f1455..14f79d9 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FunctionArg) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getClassParentId) FORWARD_SYMBOL_METHOD(getLexicalParentId) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h index 82bb1fd..4bb4265 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h @@ -28,7 +28,7 @@ public: std::unique_ptr<IPDBEnumSymbols> getArguments() const; std::unique_ptr<PDBSymbol> getClassParent() const; - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; void dumpArgList(raw_ostream &OS) const; FORWARD_SYMBOL_METHOD(getCallingConvention) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h index 42f5867..cbfcec8 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::ManagedType) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getName) FORWARD_SYMBOL_METHOD(getSymIndexId) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h index 8b2806f..33578ba 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h @@ -26,7 +26,7 @@ public: std::unique_ptr<PDBSymbol> getPointeeType() const; - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(getLength) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h index d3a9ca2..5ad83bb 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Typedef) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getBuiltinType) FORWARD_SYMBOL_METHOD(getClassParentId) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h index bf912b8..99cc307 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::UDT) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getClassParentId) FORWARD_SYMBOL_METHOD(getUnmodifiedTypeId) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h index 6b6d99b..6efc549 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::VTable) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getClassParentId) FORWARD_SYMBOL_METHOD(isConstType) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h index e866106..f407595 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::VTableShape) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(getCount) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h b/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h index 7f8c6f9..94bd2c1 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h @@ -21,7 +21,7 @@ public: PDBSymbolUnknown(const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> UnknownSymbol); - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; static bool classof(const PDBSymbol *S) { return (S->getSymTag() == PDB_SymType::None || diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h b/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h index 59ec16b..7072f34 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h @@ -24,7 +24,7 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::UsingNamespace) - void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override; + void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getLexicalParentId) FORWARD_SYMBOL_METHOD(getName) diff --git a/include/llvm/DebugInfo/PDB/PDBTypes.h b/include/llvm/DebugInfo/PDB/PDBTypes.h index 75b6475..686e08f 100644 --- a/include/llvm/DebugInfo/PDB/PDBTypes.h +++ b/include/llvm/DebugInfo/PDB/PDBTypes.h @@ -418,6 +418,17 @@ enum class PDB_RegisterId { enum class PDB_MemberAccess { Private = 1, Protected = 2, Public = 3 }; +enum class PDB_ErrorCode { + Success, + NoPdbImpl, + InvalidPath, + InvalidFileFormat, + InvalidParameter, + AlreadyLoaded, + UnknownError, + NoMemory +}; + struct VersionInfo { uint32_t Major; uint32_t Minor; @@ -459,8 +470,31 @@ struct Variant { uint16_t UInt16; uint32_t UInt32; uint64_t UInt64; - void* Pointer; }; +#define VARIANT_EQUAL_CASE(Enum) \ + case PDB_VariantType::Enum: \ + return Enum == Other.Enum; + bool operator==(const Variant &Other) const { + if (Type != Other.Type) + return false; + switch (Type) { + VARIANT_EQUAL_CASE(Bool) + VARIANT_EQUAL_CASE(Int8) + VARIANT_EQUAL_CASE(Int16) + VARIANT_EQUAL_CASE(Int32) + VARIANT_EQUAL_CASE(Int64) + VARIANT_EQUAL_CASE(Single) + VARIANT_EQUAL_CASE(Double) + VARIANT_EQUAL_CASE(UInt8) + VARIANT_EQUAL_CASE(UInt16) + VARIANT_EQUAL_CASE(UInt32) + VARIANT_EQUAL_CASE(UInt64) + default: + return true; + } + } +#undef VARIANT_EQUAL_CASE + bool operator!=(const Variant &Other) const { return !(*this == Other); } }; } // namespace llvm diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 17de5c7..abdaa0c 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -510,9 +510,6 @@ private: bool VerifyModules; bool UseOrcMCJITReplacement; - /// InitEngine - Does the common initialization of default options. - void InitEngine(); - public: /// Default constructor for EngineBuilder. EngineBuilder(); diff --git a/include/llvm/ExecutionEngine/JITSymbolFlags.h b/include/llvm/ExecutionEngine/JITSymbolFlags.h new file mode 100644 index 0000000..450e948 --- /dev/null +++ b/include/llvm/ExecutionEngine/JITSymbolFlags.h @@ -0,0 +1,81 @@ +//===------ JITSymbolFlags.h - Flags for symbols in the JIT -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Symbol flags for symbols in the JIT (e.g. weak, exported). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_JITSYMBOLFLAGS_H +#define LLVM_EXECUTIONENGINE_JITSYMBOLFLAGS_H + +#include "llvm/IR/GlobalValue.h" + +namespace llvm { + +/// @brief Flags for symbols in the JIT. +enum class JITSymbolFlags : char { + None = 0, + Weak = 1U << 0, + Exported = 1U << 1 +}; + +inline JITSymbolFlags operator|(JITSymbolFlags LHS, JITSymbolFlags RHS) { + typedef std::underlying_type<JITSymbolFlags>::type UT; + return static_cast<JITSymbolFlags>( + static_cast<UT>(LHS) | static_cast<UT>(RHS)); +} + +inline JITSymbolFlags& operator |=(JITSymbolFlags &LHS, JITSymbolFlags RHS) { + LHS = LHS | RHS; + return LHS; +} + +inline JITSymbolFlags operator&(JITSymbolFlags LHS, JITSymbolFlags RHS) { + typedef std::underlying_type<JITSymbolFlags>::type UT; + return static_cast<JITSymbolFlags>( + static_cast<UT>(LHS) & static_cast<UT>(RHS)); +} + +inline JITSymbolFlags& operator &=(JITSymbolFlags &LHS, JITSymbolFlags RHS) { + LHS = LHS & RHS; + return LHS; +} + +/// @brief Base class for symbols in the JIT. +class JITSymbolBase { +public: + JITSymbolBase(JITSymbolFlags Flags) : Flags(Flags) {} + + JITSymbolFlags getFlags() const { return Flags; } + + bool isWeak() const { + return (Flags & JITSymbolFlags::Weak) == JITSymbolFlags::Weak; + } + + bool isExported() const { + return (Flags & JITSymbolFlags::Exported) == JITSymbolFlags::Exported; + } + + static JITSymbolFlags flagsFromGlobalValue(const GlobalValue &GV) { + JITSymbolFlags Flags = JITSymbolFlags::None; + if (GV.hasWeakLinkage()) + Flags |= JITSymbolFlags::Weak; + if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility()) + Flags |= JITSymbolFlags::Exported; + return Flags; + + } + +private: + JITSymbolFlags Flags; +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 0e218e2..77b0c48 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -142,9 +142,8 @@ public: typedef std::function<uint64_t(const std::string &)> LookupFtor; /// @brief Construct a compile-on-demand layer instance. - CompileOnDemandLayer(BaseLayerT &BaseLayer, LLVMContext &Context) - : BaseLayer(BaseLayer), - CompileCallbackMgr(BaseLayer, Context, 0, 64) {} + CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr) + : BaseLayer(BaseLayer), CompileCallbackMgr(CallbackMgr) {} /// @brief Add a module to the compile-on-demand layer. template <typename ModuleSetT> @@ -194,8 +193,8 @@ public: /// below this one. JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { - BaseLayerModuleSetHandleListT &BaseLayerHandles = H->second; - for (auto &BH : BaseLayerHandles) { + + for (auto &BH : H->BaseLayerModuleSetHandles) { if (auto Symbol = BaseLayer.findSymbolIn(BH, Name, ExportedSymbolsOnly)) return Symbol; } @@ -274,7 +273,7 @@ private: // Set the compile actions for this module: for (auto &KVPair : NewStubInfos) { std::string BodyName = Mangle(KVPair->first + BodySuffix, - *M.getDataLayout()); + M.getDataLayout()); auto &CCInfo = KVPair->second; CCInfo.setCompileAction( [=](){ @@ -291,10 +290,10 @@ private: for (auto &KVPair : StubInfos) { std::string AddrName = Mangle(KVPair.first + AddrSuffix, - *M.getDataLayout()); + M.getDataLayout()); auto &CCInfo = KVPair.second; CCInfo.setUpdateAction( - CompileCallbackMgr.getLocalFPUpdater(StubsH, AddrName)); + getLocalFPUpdater(BaseLayer, StubsH, AddrName)); } } @@ -345,7 +344,7 @@ private: } BaseLayerT &BaseLayer; - CompileCallbackMgrT CompileCallbackMgr; + CompileCallbackMgrT &CompileCallbackMgr; ModuleSetInfoListT ModuleSetInfos; }; diff --git a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h index e9d3d34..8ce1d4d 100644 --- a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h +++ b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h @@ -26,10 +26,34 @@ namespace orc { /// @brief Base class for JITLayer independent aspects of /// JITCompileCallbackManager. -template <typename TargetT> class JITCompileCallbackManagerBase { public: + typedef std::function<TargetAddress()> CompileFtor; + typedef std::function<void(TargetAddress)> UpdateFtor; + + /// @brief Handle to a newly created compile callback. Can be used to get an + /// IR constant representing the address of the trampoline, and to set + /// the compile and update actions for the callback. + class CompileCallbackInfo { + public: + CompileCallbackInfo(Constant *Addr, CompileFtor &Compile, + UpdateFtor &Update) + : Addr(Addr), Compile(Compile), Update(Update) {} + + Constant* getAddress() const { return Addr; } + void setCompileAction(CompileFtor Compile) { + this->Compile = std::move(Compile); + } + void setUpdateAction(UpdateFtor Update) { + this->Update = std::move(Update); + } + private: + Constant *Addr; + CompileFtor &Compile; + UpdateFtor &Update; + }; + /// @brief Construct a JITCompileCallbackManagerBase. /// @param ErrorHandlerAddress The address of an error handler in the target /// process to be used if a compile callback fails. @@ -41,10 +65,12 @@ public: : ErrorHandlerAddress(ErrorHandlerAddress), NumTrampolinesPerBlock(NumTrampolinesPerBlock) {} + virtual ~JITCompileCallbackManagerBase() {} + /// @brief Execute the callback for the given trampoline id. Called by the JIT /// to compile functions on demand. TargetAddress executeCompileCallback(TargetAddress TrampolineID) { - typename TrampolineMapT::iterator I = ActiveTrampolines.find(TrampolineID); + TrampolineMapT::iterator I = ActiveTrampolines.find(TrampolineID); // FIXME: Also raise an error in the Orc error-handler when we finally have // one. if (I == ActiveTrampolines.end()) @@ -56,7 +82,7 @@ public: // Moving the trampoline ID back to the available list first means there's at // least one available trampoline if the compile action triggers a request for // a new one. - AvailableTrampolines.push_back(I->first - TargetT::CallSize); + AvailableTrampolines.push_back(I->first); auto CallbackHandler = std::move(I->second); ActiveTrampolines.erase(I); @@ -67,14 +93,14 @@ public: return ErrorHandlerAddress; } -protected: + /// @brief Get/create a compile callback with the given signature. + virtual CompileCallbackInfo getCompileCallback(FunctionType &FT) = 0; - typedef std::function<TargetAddress()> CompileFtorT; - typedef std::function<void(TargetAddress)> UpdateFtorT; +protected: struct CallbackHandler { - CompileFtorT Compile; - UpdateFtorT Update; + CompileFtor Compile; + UpdateFtor Update; }; TargetAddress ErrorHandlerAddress; @@ -87,15 +113,9 @@ protected: /// @brief Manage compile callbacks. template <typename JITLayerT, typename TargetT> -class JITCompileCallbackManager : - public JITCompileCallbackManagerBase<TargetT> { +class JITCompileCallbackManager : public JITCompileCallbackManagerBase { public: - typedef typename JITCompileCallbackManagerBase<TargetT>::CompileFtorT - CompileFtorT; - typedef typename JITCompileCallbackManagerBase<TargetT>::UpdateFtorT - UpdateFtorT; - /// @brief Construct a JITCompileCallbackManager. /// @param JIT JIT layer to emit callback trampolines, etc. into. /// @param Context LLVMContext to use for trampoline & resolve block modules. @@ -108,39 +128,17 @@ public: JITCompileCallbackManager(JITLayerT &JIT, LLVMContext &Context, TargetAddress ErrorHandlerAddress, unsigned NumTrampolinesPerBlock) - : JITCompileCallbackManagerBase<TargetT>(ErrorHandlerAddress, - NumTrampolinesPerBlock), + : JITCompileCallbackManagerBase(ErrorHandlerAddress, + NumTrampolinesPerBlock), JIT(JIT) { emitResolverBlock(Context); } - /// @brief Handle to a newly created compile callback. Can be used to get an - /// IR constant representing the address of the trampoline, and to set - /// the compile and update actions for the callback. - class CompileCallbackInfo { - public: - CompileCallbackInfo(Constant *Addr, CompileFtorT &Compile, - UpdateFtorT &Update) - : Addr(Addr), Compile(Compile), Update(Update) {} - - Constant* getAddress() const { return Addr; } - void setCompileAction(CompileFtorT Compile) { - this->Compile = std::move(Compile); - } - void setUpdateAction(UpdateFtorT Update) { - this->Update = std::move(Update); - } - private: - Constant *Addr; - CompileFtorT &Compile; - UpdateFtorT &Update; - }; - /// @brief Get/create a compile callback with the given signature. - CompileCallbackInfo getCompileCallback(FunctionType &FT) { + CompileCallbackInfo getCompileCallback(FunctionType &FT) final { TargetAddress TrampolineAddr = getAvailableTrampolineAddr(FT.getContext()); auto &CallbackHandler = - this->ActiveTrampolines[TrampolineAddr + TargetT::CallSize]; + this->ActiveTrampolines[TrampolineAddr]; Constant *AddrIntVal = ConstantInt::get(Type::getInt64Ty(FT.getContext()), TrampolineAddr); Constant *AddrPtrVal = @@ -151,19 +149,6 @@ public: CallbackHandler.Update); } - /// @brief Get a functor for updating the value of a named function pointer. - UpdateFtorT getLocalFPUpdater(typename JITLayerT::ModuleSetHandleT H, - std::string Name) { - // FIXME: Move-capture Name once we can use C++14. - return [=](TargetAddress Addr) { - auto FPSym = JIT.findSymbolIn(H, Name, true); - assert(FPSym && "Cannot find function pointer to update."); - void *FPAddr = reinterpret_cast<void*>( - static_cast<uintptr_t>(FPSym.getAddress())); - memcpy(FPAddr, &Addr, sizeof(uintptr_t)); - }; - } - private: std::vector<std::unique_ptr<Module>> @@ -216,6 +201,22 @@ private: TargetAddress ResolverBlockAddr; }; +/// @brief Get an update functor for updating the value of a named function +/// pointer. +template <typename JITLayerT> +JITCompileCallbackManagerBase::UpdateFtor +getLocalFPUpdater(JITLayerT &JIT, typename JITLayerT::ModuleSetHandleT H, + std::string Name) { + // FIXME: Move-capture Name once we can use C++14. + return [=,&JIT](TargetAddress Addr) { + auto FPSym = JIT.findSymbolIn(H, Name, true); + assert(FPSym && "Cannot find function pointer to update."); + void *FPAddr = reinterpret_cast<void*>( + static_cast<uintptr_t>(FPSym.getAddress())); + memcpy(FPAddr, &Addr, sizeof(uintptr_t)); + }; + } + GlobalVariable* createImplPointer(Function &F, const Twine &Name, Constant *Initializer); diff --git a/include/llvm/ExecutionEngine/Orc/JITSymbol.h b/include/llvm/ExecutionEngine/Orc/JITSymbol.h index a670222..7c3ad56 100644 --- a/include/llvm/ExecutionEngine/Orc/JITSymbol.h +++ b/include/llvm/ExecutionEngine/Orc/JITSymbol.h @@ -14,6 +14,7 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H #define LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H +#include "llvm/ExecutionEngine/JITSymbolFlags.h" #include "llvm/Support/DataTypes.h" #include <cassert> #include <functional> @@ -25,17 +26,19 @@ namespace orc { typedef uint64_t TargetAddress; /// @brief Represents a symbol in the JIT. -class JITSymbol { -public: +class JITSymbol : public JITSymbolBase { +public: + typedef std::function<TargetAddress()> GetAddressFtor; /// @brief Create a 'null' symbol that represents failure to find a symbol /// definition. - JITSymbol(std::nullptr_t) : CachedAddr(0) {} + JITSymbol(std::nullptr_t) + : JITSymbolBase(JITSymbolFlags::None), CachedAddr(0) {} /// @brief Create a symbol for a definition with a known address. - JITSymbol(TargetAddress Addr) - : CachedAddr(Addr) {} + JITSymbol(TargetAddress Addr, JITSymbolFlags Flags) + : JITSymbolBase(Flags), CachedAddr(Addr) {} /// @brief Create a symbol for a definition that doesn't have a known address /// yet. @@ -46,8 +49,8 @@ public: /// definition without actually materializing the definition up front. The /// user can materialize the definition at any time by calling the getAddress /// method. - JITSymbol(GetAddressFtor GetAddress) - : CachedAddr(0), GetAddress(std::move(GetAddress)) {} + JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags) + : JITSymbolBase(Flags), GetAddress(std::move(GetAddress)), CachedAddr(0) {} /// @brief Returns true if the symbol exists, false otherwise. explicit operator bool() const { return CachedAddr || GetAddress; } @@ -64,8 +67,8 @@ public: } private: - TargetAddress CachedAddr; GetAddressFtor GetAddress; + TargetAddress CachedAddr; }; } // End namespace orc. diff --git a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h index 2a94abe..ac5fccf 100644 --- a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h @@ -45,23 +45,25 @@ private: JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) { switch (EmitState) { case NotEmitted: - if (provides(Name, ExportedSymbolsOnly)) { + if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) { // Create a std::string version of Name to capture here - the argument // (a StringRef) may go away before the lambda is executed. - // FIXME: Use capture-init when we move to C++14. + // FIXME: Use capture-init when we move to C++14. std::string PName = Name; - return JITSymbol( - [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress { - if (this->EmitState == Emitting) - return 0; - else if (this->EmitState == NotEmitted) { - this->EmitState = Emitting; - Handle = this->emitToBaseLayer(B); - this->EmitState = Emitted; - } - return B.findSymbolIn(Handle, PName, ExportedSymbolsOnly) - .getAddress(); - }); + JITSymbolFlags Flags = JITSymbolBase::flagsFromGlobalValue(*GV); + auto GetAddress = + [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress { + if (this->EmitState == Emitting) + return 0; + else if (this->EmitState == NotEmitted) { + this->EmitState = Emitting; + Handle = this->emitToBaseLayer(B); + this->EmitState = Emitted; + } + auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly); + return Sym.getAddress(); + }; + return JITSymbol(std::move(GetAddress), Flags); } else return nullptr; case Emitting: @@ -98,7 +100,8 @@ private: std::unique_ptr<RTDyldMemoryManager> MM); protected: - virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0; + virtual const GlobalValue* searchGVs(StringRef Name, + bool ExportedSymbolsOnly) const = 0; virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0; private: @@ -115,46 +118,48 @@ private: protected: - BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override { - // We don't need the mangled names set any more: Once we've emitted this - // to the base layer we'll just look for symbols there. - MangledNames.reset(); - return BaseLayer.addModuleSet(std::move(Ms), std::move(MM)); - } - - bool provides(StringRef Name, bool ExportedSymbolsOnly) const override { + const GlobalValue* searchGVs(StringRef Name, + bool ExportedSymbolsOnly) const override { // FIXME: We could clean all this up if we had a way to reliably demangle // names: We could just demangle name and search, rather than // mangling everything else. // If we have already built the mangled name set then just search it. - if (MangledNames) { - auto VI = MangledNames->find(Name); - if (VI == MangledNames->end()) - return false; - return !ExportedSymbolsOnly || VI->second; + if (MangledSymbols) { + auto VI = MangledSymbols->find(Name); + if (VI == MangledSymbols->end()) + return nullptr; + auto GV = VI->second; + if (!ExportedSymbolsOnly || GV->hasDefaultVisibility()) + return GV; + return nullptr; } // If we haven't built the mangled name set yet, try to build it. As an // optimization this will leave MangledNames set to nullptr if we find // Name in the process of building the set. - buildMangledNames(Name, ExportedSymbolsOnly); - if (!MangledNames) - return true; - return false; + return buildMangledSymbols(Name, ExportedSymbolsOnly); + } + + BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override { + // We don't need the mangled names set any more: Once we've emitted this + // to the base layer we'll just look for symbols there. + MangledSymbols.reset(); + return BaseLayer.addModuleSet(std::move(Ms), std::move(MM)); } private: // If the mangled name of the given GlobalValue matches the given search // name (and its visibility conforms to the ExportedSymbolsOnly flag) then - // just return 'true'. Otherwise, add the mangled name to the Names map and - // return 'false'. - bool addGlobalValue(StringMap<bool> &Names, const GlobalValue &GV, - const Mangler &Mang, StringRef SearchName, - bool ExportedSymbolsOnly) const { + // return the symbol. Otherwise, add the mangled name to the Names map and + // return nullptr. + const GlobalValue* addGlobalValue(StringMap<const GlobalValue*> &Names, + const GlobalValue &GV, + const Mangler &Mang, StringRef SearchName, + bool ExportedSymbolsOnly) const { // Modules don't "provide" decls or common symbols. if (GV.isDeclaration() || GV.hasCommonLinkage()) - return false; + return nullptr; // Mangle the GV name. std::string MangledName; @@ -167,39 +172,42 @@ private: // bail out early. if (MangledName == SearchName) if (!ExportedSymbolsOnly || GV.hasDefaultVisibility()) - return true; + return &GV; // Otherwise add this to the map for later. - Names[MangledName] = GV.hasDefaultVisibility(); - return false; + Names[MangledName] = &GV; + return nullptr; } - // Build the MangledNames map. Bails out early (with MangledNames left set + // Build the MangledSymbols map. Bails out early (with MangledSymbols left set // to nullptr) if the given SearchName is found while building the map. - void buildMangledNames(StringRef SearchName, - bool ExportedSymbolsOnly) const { - assert(!MangledNames && "Mangled names map already exists?"); + const GlobalValue* buildMangledSymbols(StringRef SearchName, + bool ExportedSymbolsOnly) const { + assert(!MangledSymbols && "Mangled symbols map already exists?"); - auto Names = llvm::make_unique<StringMap<bool>>(); + auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>(); for (const auto &M : Ms) { - Mangler Mang(M->getDataLayout()); + Mangler Mang(&M->getDataLayout()); - for (const auto &GV : M->globals()) - if (addGlobalValue(*Names, GV, Mang, SearchName, ExportedSymbolsOnly)) - return; + for (const auto &V : M->globals()) + if (auto GV = addGlobalValue(*Symbols, V, Mang, SearchName, + ExportedSymbolsOnly)) + return GV; for (const auto &F : *M) - if (addGlobalValue(*Names, F, Mang, SearchName, ExportedSymbolsOnly)) - return; + if (auto GV = addGlobalValue(*Symbols, F, Mang, SearchName, + ExportedSymbolsOnly)) + return GV; } - MangledNames = std::move(Names); + MangledSymbols = std::move(Symbols); + return nullptr; } ModuleSetT Ms; std::unique_ptr<RTDyldMemoryManager> MM; - mutable std::unique_ptr<StringMap<bool>> MangledNames; + mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols; }; typedef std::list<std::unique_ptr<EmissionDeferredSet>> ModuleSetListT; diff --git a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h index 36af0fe..9838991 100644 --- a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h @@ -51,10 +51,8 @@ protected: return RTDyld->loadObject(Obj); } - TargetAddress getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) { - if (ExportedSymbolsOnly) - return RTDyld->getExportedSymbolLoadAddress(Name); - return RTDyld->getSymbolLoadAddress(Name); + RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const { + return RTDyld->getSymbol(Name); } bool NeedsFinalization() const { return (State == Raw); } @@ -214,28 +212,32 @@ public: /// given object set. JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name, bool ExportedSymbolsOnly) { - if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) { - if (!H->NeedsFinalization()) { - // If this instance has already been finalized then we can just return - // the address. - return JITSymbol(Addr); - } else { - // If this instance needs finalization return a functor that will do it. - // The functor still needs to double-check whether finalization is - // required, in case someone else finalizes this set before the functor - // is called. - return JITSymbol( - [this, Addr, H]() { - if (H->NeedsFinalization()) { - H->Finalize(); - if (NotifyFinalized) - NotifyFinalized(H); - } - return Addr; - }); + if (auto Sym = H->getSymbol(Name)) { + if (Sym.isExported() || !ExportedSymbolsOnly) { + auto Addr = Sym.getAddress(); + auto Flags = Sym.getFlags(); + if (!H->NeedsFinalization()) { + // If this instance has already been finalized then we can just return + // the address. + return JITSymbol(Addr, Flags); + } else { + // If this instance needs finalization return a functor that will do + // it. The functor still needs to double-check whether finalization is + // required, in case someone else finalizes this set before the + // functor is called. + auto GetAddress = + [this, Addr, H]() { + if (H->NeedsFinalization()) { + H->Finalize(); + if (NotifyFinalized) + NotifyFinalized(H); + } + return Addr; + }; + return JITSymbol(std::move(GetAddress), Flags); + } } } - return nullptr; } diff --git a/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h b/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h index c6f866a..309f5a9 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h +++ b/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h @@ -25,15 +25,12 @@ public: /// @brief Insert module-level inline callback asm into module M for the /// symbols managed by JITResolveCallbackHandler J. - static void insertResolverBlock( - Module &M, - JITCompileCallbackManagerBase<OrcX86_64> &JCBM); + static void insertResolverBlock(Module &M, + JITCompileCallbackManagerBase &JCBM); /// @brief Get a label name from the given index. typedef std::function<std::string(unsigned)> LabelNameFtor; - static const unsigned CallSize = 6; - /// @brief Insert the requested number of trampolines into the given module. /// @param M Module to insert the call block into. /// @param NumCalls Number of calls to create in the call block. diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index 08cfa39..fe0ccda 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -14,6 +14,7 @@ #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H +#include "JITSymbolFlags.h" #include "llvm/ADT/StringRef.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" #include "llvm/Support/Memory.h" @@ -28,7 +29,7 @@ namespace object { class RuntimeDyldImpl; class RuntimeDyldCheckerImpl; - + class RuntimeDyld { friend class RuntimeDyldCheckerImpl; @@ -47,6 +48,18 @@ protected: void reassignSectionAddress(unsigned SectionID, uint64_t Addr); public: + /// \brief Information about a named symbol. + class SymbolInfo : public JITSymbolBase { + public: + SymbolInfo(std::nullptr_t) : JITSymbolBase(JITSymbolFlags::None), Address(0) {} + SymbolInfo(uint64_t Address, JITSymbolFlags Flags) + : JITSymbolBase(Flags), Address(Address) {} + explicit operator bool() const { return Address != 0; } + uint64_t getAddress() const { return Address; } + private: + uint64_t Address; + }; + /// \brief Information about the loaded object. class LoadedObjectInfo { friend class RuntimeDyldImpl; @@ -79,15 +92,11 @@ public: /// Get the address of our local copy of the symbol. This may or may not /// be the address used for relocation (clients can copy the data around /// and resolve relocatons based on where they put it). - void *getSymbolAddress(StringRef Name) const; - - /// Get the address of the target copy of the symbol (works for both exported - /// and non-exported symbols). This is the address used for relocation. - uint64_t getSymbolLoadAddress(StringRef Name) const; + void *getSymbolLocalAddress(StringRef Name) const; - /// Get the address of the target copy of the symbol (works for exported - /// symbols only). This is the address used for relocation. - uint64_t getExportedSymbolLoadAddress(StringRef Name) const; + /// Get the target address and flags for the named symbol. + /// This address is the one used for relocation. + SymbolInfo getSymbol(StringRef Name) const; /// Resolve the relocations for all symbols we currently know about. void resolveRelocations(); diff --git a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h index 23936a6..31ce151 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h +++ b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h @@ -86,12 +86,12 @@ public: /// \brief Returns the address of the requested section (or an error message /// in the second element of the pair if the address cannot be found). /// - /// if 'LinkerAddress' is true, this returns the address of the section - /// within the linker's memory. If 'LinkerAddress' is false it returns the + /// if 'LocalAddress' is true, this returns the address of the section + /// within the linker's memory. If 'LocalAddress' is false it returns the /// address within the target process (i.e. the load address). std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName, StringRef SectionName, - bool LinkerAddress); + bool LocalAddress); private: std::unique_ptr<RuntimeDyldCheckerImpl> Impl; diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index 185fc29..8f5cdeb 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -119,7 +119,11 @@ public: const Function *getParent() const { return Parent; } Function *getParent() { return Parent; } - const DataLayout *getDataLayout() const; + /// \brief Return the module owning the function this basic block belongs to, + /// or nullptr it the function does not have a module. + /// + /// Note: this is undefined behavior if the block does not have a parent. + const Module *getModule() const; /// \brief Returns the terminator instruction if the block is well formed or /// null if the block is not well formed. diff --git a/include/llvm/IR/CFG.h b/include/llvm/IR/CFG.h index 8476431..f78220a 100644 --- a/include/llvm/IR/CFG.h +++ b/include/llvm/IR/CFG.h @@ -121,7 +121,7 @@ public: typedef typename super::reference reference; private: - const Term_ Term; + Term_ Term; unsigned idx; typedef SuccIterator<Term_, BB_> Self; @@ -136,6 +136,8 @@ private: public: explicit SuccessorProxy(const Self &it) : it(it) {} + SuccessorProxy(const SuccessorProxy&) = default; + SuccessorProxy &operator=(SuccessorProxy r) { *this = reference(r); return *this; @@ -165,12 +167,6 @@ public: idx = 0; } - inline const Self &operator=(const Self &I) { - assert(Term == I.Term &&"Cannot assign iterators to two different blocks!"); - idx = I.idx; - return *this; - } - /// getSuccessorIndex - This is used to interface between code that wants to /// operate on terminator instructions directly. unsigned getSuccessorIndex() const { return idx; } diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index a4ea243..9c87936 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -151,7 +151,7 @@ public: IterTy arg_end() const { return (*this)->op_end() - getArgumentEndOffset(); } bool arg_empty() const { return arg_end() == arg_begin(); } unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); } - + /// getType - Return the type of the instruction that generated this call site /// Type *getType() const { return (*this)->getType(); } diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h index 5e8cd34..9ded3ca 100644 --- a/include/llvm/IR/ConstantRange.h +++ b/include/llvm/IR/ConstantRange.h @@ -33,6 +33,7 @@ #define LLVM_IR_CONSTANTRANGE_H #include "llvm/ADT/APInt.h" +#include "llvm/IR/InstrTypes.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -59,15 +60,27 @@ public: /// assert out if the two APInt's are not the same bit width. ConstantRange(APIntMoveTy Lower, APIntMoveTy Upper); - /// Produce the smallest range that contains all values that - /// might satisfy the comparison specified by Pred when compared to any value - /// contained within Other. + /// Produce the smallest range such that all values that may satisfy the given + /// predicate with any value contained within Other is contained in the + /// returned range. Formally, this returns a superset of + /// 'union over all y in Other . { x : icmp op x y is true }'. If the exact + /// answer is not representable as a ConstantRange, the return value will be a + /// proper superset of the above. /// - /// Solves for range X in 'for all x in X, there exists a y in Y such that - /// icmp op x, y is true'. Every value that might make the comparison true - /// is included in the resulting range. - static ConstantRange makeICmpRegion(unsigned Pred, - const ConstantRange &Other); + /// Example: Pred = ult and Other = i8 [2, 5) returns Result = [0, 4) + static ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, + const ConstantRange &Other); + + /// Produce the largest range such that all values in the returned range + /// satisfy the given predicate with all values contained within Other. + /// Formally, this returns a subset of + /// 'intersection over all y in Other . { x : icmp op x y is true }'. If the + /// exact answer is not representable as a ConstantRange, the return value + /// will be a proper subset of the above. + /// + /// Example: Pred = ult and Other = i8 [2, 5) returns [0, 2) + static ConstantRange makeSatisfyingICmpRegion(CmpInst::Predicate Pred, + const ConstantRange &Other); /// Return the lower value for this range. /// @@ -208,8 +221,8 @@ public: ConstantRange sub(const ConstantRange &Other) const; /// Return a new range representing the possible values resulting - /// from a multiplication of a value in this range and a value in \p Other. - /// TODO: This isn't fully implemented yet. + /// from a multiplication of a value in this range and a value in \p Other, + /// treating both this and \p Other as unsigned ranges. ConstantRange multiply(const ConstantRange &Other) const; /// Return a new range representing the possible values resulting diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h index 9479ba4..3e1f974 100644 --- a/include/llvm/IR/DataLayout.h +++ b/include/llvm/IR/DataLayout.h @@ -108,7 +108,14 @@ private: unsigned StackNaturalAlign; - enum ManglingModeT { MM_None, MM_ELF, MM_MachO, MM_WINCOFF, MM_Mips }; + enum ManglingModeT { + MM_None, + MM_ELF, + MM_MachO, + MM_WinCOFF, + MM_WinCOFFX86, + MM_Mips + }; ManglingModeT ManglingMode; SmallVector<unsigned char, 8> LegalIntWidths; @@ -116,6 +123,9 @@ private: /// \brief Primitive type alignment data. SmallVector<LayoutAlignElem, 16> Alignments; + /// \brief The string representation used to create this DataLayout + std::string StringRepresentation; + typedef SmallVector<PointerAlignElem, 8> PointersTy; PointersTy Pointers; @@ -185,6 +195,7 @@ public: DataLayout &operator=(const DataLayout &DL) { clear(); + StringRepresentation = DL.StringRepresentation; BigEndian = DL.isBigEndian(); StackNaturalAlign = DL.StackNaturalAlign; ManglingMode = DL.ManglingMode; @@ -209,8 +220,12 @@ public: /// \brief Returns the string representation of the DataLayout. /// /// This representation is in the same format accepted by the string - /// constructor above. - std::string getStringRepresentation() const; + /// constructor above. This should not be used to compare two DataLayout as + /// different string can represent the same layout. + std::string getStringRepresentation() const { return StringRepresentation; } + + /// \brief Test if the DataLayout was constructed from an empty string. + bool isDefault() const { return StringRepresentation.empty(); } /// \brief Returns true if the specified type is known to be a native integer /// type supported by the CPU. @@ -236,7 +251,7 @@ public: unsigned getStackAlignment() const { return StackNaturalAlign; } bool hasMicrosoftFastStdCallMangling() const { - return ManglingMode == MM_WINCOFF; + return ManglingMode == MM_WinCOFFX86; } bool hasLinkerPrivateGlobalPrefix() const { return ManglingMode == MM_MachO; } @@ -244,7 +259,7 @@ public: const char *getLinkerPrivateGlobalPrefix() const { if (ManglingMode == MM_MachO) return "l"; - return getPrivateGlobalPrefix(); + return ""; } char getGlobalPrefix() const { @@ -252,9 +267,10 @@ public: case MM_None: case MM_ELF: case MM_Mips: + case MM_WinCOFF: return '\0'; case MM_MachO: - case MM_WINCOFF: + case MM_WinCOFFX86: return '_'; } llvm_unreachable("invalid mangling mode"); @@ -269,7 +285,8 @@ public: case MM_Mips: return "$"; case MM_MachO: - case MM_WINCOFF: + case MM_WinCOFF: + case MM_WinCOFFX86: return "L"; } llvm_unreachable("invalid mangling mode"); @@ -451,22 +468,6 @@ inline LLVMTargetDataRef wrap(const DataLayout *P) { return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout *>(P)); } -class DataLayoutPass : public ImmutablePass { - DataLayout DL; - -public: - /// This has to exist, because this is a pass, but it should never be used. - DataLayoutPass(); - ~DataLayoutPass(); - - const DataLayout &getDataLayout() const { return DL; } - - static char ID; // Pass identification, replacement for typeid - - bool doFinalization(Module &M) override; - bool doInitialization(Module &M) override; -}; - /// Used to lazily calculate structure layout information for a target machine, /// based on the DataLayout structure. class StructLayout { diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h index d2e5975..0163c05 100644 --- a/include/llvm/IR/DebugInfo.h +++ b/include/llvm/IR/DebugInfo.h @@ -165,7 +165,6 @@ protected: GlobalVariable *getGlobalVariableField(unsigned Elt) const; Constant *getConstantField(unsigned Elt) const; Function *getFunctionField(unsigned Elt) const; - void replaceFunctionField(unsigned Elt, Function *F); public: explicit DIDescriptor(const MDNode *N = nullptr) : DbgNode(N) {} @@ -175,6 +174,10 @@ public: MDNode *get() const { return const_cast<MDNode *>(DbgNode); } operator MDNode *() const { return get(); } MDNode *operator->() const { return get(); } + MDNode &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } // An explicit operator bool so that we can do testing of DI values // easily. @@ -215,29 +218,49 @@ public: return getHeaderIterator(Index).getNumber<T>(); } - uint16_t getTag() const { return getHeaderFieldAs<uint16_t>(0); } - - bool isDerivedType() const; - bool isCompositeType() const; - bool isSubroutineType() const; - bool isBasicType() const; - bool isVariable() const; - bool isSubprogram() const; - bool isGlobalVariable() const; - bool isScope() const; - bool isFile() const; - bool isCompileUnit() const; - bool isNameSpace() const; - bool isLexicalBlockFile() const; - bool isLexicalBlock() const; - bool isSubrange() const; - bool isEnumerator() const; - bool isType() const; - bool isTemplateTypeParameter() const; - bool isTemplateValueParameter() const; - bool isObjCProperty() const; - bool isImportedEntity() const; - bool isExpression() const; + uint16_t getTag() const { + if (auto *N = dyn_cast_or_null<DebugNode>(get())) + return N->getTag(); + return 0; + } + + bool isDerivedType() const { return get() && isa<MDDerivedTypeBase>(get()); } + bool isCompositeType() const { + return get() && isa<MDCompositeTypeBase>(get()); + } + bool isSubroutineType() const { + return get() && isa<MDSubroutineType>(get()); + } + bool isBasicType() const { return get() && isa<MDBasicType>(get()); } + bool isVariable() const { return get() && isa<MDLocalVariable>(get()); } + bool isSubprogram() const { return get() && isa<MDSubprogram>(get()); } + bool isGlobalVariable() const { + return get() && isa<MDGlobalVariable>(get()); + } + bool isScope() const { return get() && isa<MDScope>(get()); } + bool isFile() const { return get() && isa<MDFile>(get()); } + bool isCompileUnit() const { return get() && isa<MDCompileUnit>(get()); } + bool isNameSpace() const{ return get() && isa<MDNamespace>(get()); } + bool isLexicalBlockFile() const { + return get() && isa<MDLexicalBlockFile>(get()); + } + bool isLexicalBlock() const { + return get() && isa<MDLexicalBlockBase>(get()); + } + bool isSubrange() const { return get() && isa<MDSubrange>(get()); } + bool isEnumerator() const { return get() && isa<MDEnumerator>(get()); } + bool isType() const { return get() && isa<MDType>(get()); } + bool isTemplateTypeParameter() const { + return get() && isa<MDTemplateTypeParameter>(get()); + } + bool isTemplateValueParameter() const { + return get() && isa<MDTemplateValueParameter>(get()); + } + bool isObjCProperty() const { return get() && isa<MDObjCProperty>(get()); } + bool isImportedEntity() const { + return get() && isa<MDImportedEntity>(get()); + } + bool isExpression() const { return get() && isa<MDExpression>(get()); } void print(raw_ostream &OS) const; void dump() const; @@ -247,29 +270,43 @@ public: void replaceAllUsesWith(MDNode *D); }; -#define RETURN_FROM_RAW(VALID, DEFAULT) \ +#define RETURN_FROM_RAW(VALID, UNUSED) \ do { \ - if (auto *N = getRaw()) \ - return VALID; \ - return DEFAULT; \ + auto *N = get(); \ + assert(N && "Expected non-null in accessor"); \ + return VALID; \ } while (false) #define RETURN_DESCRIPTOR_FROM_RAW(DESC, VALID) \ do { \ - if (auto *N = getRaw()) \ - return DESC(dyn_cast_or_null<MDNode>(VALID)); \ - return DESC(static_cast<const MDNode *>(nullptr)); \ + auto *N = get(); \ + assert(N && "Expected non-null in accessor"); \ + return DESC(dyn_cast_or_null<MDNode>(VALID)); \ + } while (false) +#define RETURN_REF_FROM_RAW(REF, VALID) \ + do { \ + auto *N = get(); \ + assert(N && "Expected non-null in accessor"); \ + return REF::get(VALID); \ } while (false) /// \brief This is used to represent ranges, for array bounds. class DISubrange : public DIDescriptor { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: explicit DISubrange(const MDNode *N = nullptr) : DIDescriptor(N) {} + DISubrange(const MDSubrange *N) : DIDescriptor(N) {} + + MDSubrange *get() const { + return cast_or_null<MDSubrange>(DIDescriptor::get()); + } + operator MDSubrange *() const { return get(); } + MDSubrange *operator->() const { return get(); } + MDSubrange &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } - int64_t getLo() const { return getHeaderFieldAs<int64_t>(1); } - int64_t getCount() const { return getHeaderFieldAs<int64_t>(2); } + int64_t getLo() const { RETURN_FROM_RAW(N->getLo(), 0); } + int64_t getCount() const { RETURN_FROM_RAW(N->getCount(), 0); } bool Verify() const; }; @@ -290,14 +327,22 @@ typedef DITypedArray<DIDescriptor> DIArray; /// FIXME: it seems strange that this doesn't have either a reference to the /// type/precision or a file/line pair for location info. class DIEnumerator : public DIDescriptor { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: explicit DIEnumerator(const MDNode *N = nullptr) : DIDescriptor(N) {} + DIEnumerator(const MDEnumerator *N) : DIDescriptor(N) {} - StringRef getName() const { return getHeaderField(1); } - int64_t getEnumValue() const { return getHeaderFieldAs<int64_t>(2); } + MDEnumerator *get() const { + return cast_or_null<MDEnumerator>(DIDescriptor::get()); + } + operator MDEnumerator *() const { return get(); } + MDEnumerator *operator->() const { return get(); } + MDEnumerator &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + + StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); } + int64_t getEnumValue() const { RETURN_FROM_RAW(N->getValue(), 0); } bool Verify() const; }; @@ -316,12 +361,17 @@ typedef DITypedArray<DITypeRef> DITypeArray; /// DIScopes that are scopes in the strict lexical scope sense /// (DICompileUnit, DISubprogram, etc.), but not for, e.g., a DIType. class DIScope : public DIDescriptor { -protected: - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: explicit DIScope(const MDNode *N = nullptr) : DIDescriptor(N) {} + DIScope(const MDScope *N) : DIDescriptor(N) {} + + MDScope *get() const { return cast_or_null<MDScope>(DIDescriptor::get()); } + operator MDScope *() const { return get(); } + MDScope *operator->() const { return get(); } + MDScope &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } /// \brief Get the parent scope. /// @@ -362,6 +412,8 @@ public: T resolve(const DITypeIdentifierMap &Map) const; StringRef getName() const; operator Metadata *() const { return const_cast<Metadata *>(Val); } + + static DIRef get(const Metadata *MD) { return DIRef(MD); } }; template <typename T> @@ -413,12 +465,18 @@ template <> DIRef<DIType>::DIRef(const Metadata *V); /// FIXME: Types should be factored much better so that CV qualifiers and /// others do not require a huge and empty descriptor full of zeros. class DIType : public DIScope { -protected: - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: explicit DIType(const MDNode *N = nullptr) : DIScope(N) {} + DIType(const MDType *N) : DIScope(N) {} + + MDType *get() const { return cast_or_null<MDType>(DIDescriptor::get()); } + operator MDType *() const { return get(); } + MDType *operator->() const { return get(); } + MDType &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + operator DITypeRef() const { assert(isType() && "constructing DITypeRef from an MDNode that is not a type"); @@ -427,15 +485,17 @@ public: bool Verify() const; - DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); } - StringRef getName() const { return getHeaderField(1); } - unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); } - uint64_t getSizeInBits() const { return getHeaderFieldAs<unsigned>(3); } - uint64_t getAlignInBits() const { return getHeaderFieldAs<unsigned>(4); } + DIScopeRef getContext() const { + RETURN_REF_FROM_RAW(DIScopeRef, N->getScope()); + } + StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); } + unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); } + uint64_t getSizeInBits() const { RETURN_FROM_RAW(N->getSizeInBits(), 0); } + uint64_t getAlignInBits() const { RETURN_FROM_RAW(N->getAlignInBits(), 0); } // FIXME: Offset is only used for DW_TAG_member nodes. Making every type // carry this is just plain insane. - uint64_t getOffsetInBits() const { return getHeaderFieldAs<unsigned>(5); } - unsigned getFlags() const { return getHeaderFieldAs<unsigned>(6); } + uint64_t getOffsetInBits() const { RETURN_FROM_RAW(N->getOffsetInBits(), 0); } + unsigned getFlags() const { RETURN_FROM_RAW(N->getFlags(), 0); } bool isPrivate() const { return (getFlags() & FlagAccessibility) == FlagPrivate; } @@ -473,8 +533,19 @@ public: class DIBasicType : public DIType { public: explicit DIBasicType(const MDNode *N = nullptr) : DIType(N) {} + DIBasicType(const MDBasicType *N) : DIType(N) {} - unsigned getEncoding() const { return getHeaderFieldAs<unsigned>(7); } + MDBasicType *get() const { + return cast_or_null<MDBasicType>(DIDescriptor::get()); + } + operator MDBasicType *() const { return get(); } + MDBasicType *operator->() const { return get(); } + MDBasicType &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + + unsigned getEncoding() const { RETURN_FROM_RAW(N->getEncoding(), 0); } bool Verify() const; }; @@ -484,25 +555,45 @@ public: /// Like a const qualified type, a typedef, a pointer or reference, et cetera. /// Or, a data member of a class/struct/union. class DIDerivedType : public DIType { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: explicit DIDerivedType(const MDNode *N = nullptr) : DIType(N) {} + DIDerivedType(const MDDerivedTypeBase *N) : DIType(N) {} - DITypeRef getTypeDerivedFrom() const { return getFieldAs<DITypeRef>(3); } + MDDerivedTypeBase *get() const { + return cast_or_null<MDDerivedTypeBase>(DIDescriptor::get()); + } + operator MDDerivedTypeBase *() const { return get(); } + MDDerivedTypeBase *operator->() const { return get(); } + MDDerivedTypeBase &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + + DITypeRef getTypeDerivedFrom() const { + RETURN_REF_FROM_RAW(DITypeRef, N->getBaseType()); + } /// \brief Return property node, if this ivar is associated with one. - MDNode *getObjCProperty() const; + MDNode *getObjCProperty() const { + if (auto *N = dyn_cast<MDDerivedType>(get())) + return dyn_cast_or_null<MDNode>(N->getExtraData()); + return nullptr; + } DITypeRef getClassType() const { assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); - return getFieldAs<DITypeRef>(4); + if (auto *N = dyn_cast<MDDerivedType>(get())) + return DITypeRef::get(N->getExtraData()); + return DITypeRef::get(nullptr); } Constant *getConstant() const { assert((getTag() == dwarf::DW_TAG_member) && isStaticMember()); - return getConstantField(4); + if (auto *N = dyn_cast<MDDerivedType>(get())) + if (auto *C = dyn_cast_or_null<ConstantAsMetadata>(N->getExtraData())) + return C->getValue(); + + return nullptr; } bool Verify() const; @@ -519,18 +610,27 @@ public: // base type in a single DIType field. class DICompositeType : public DIDerivedType { friend class DIBuilder; - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; /// \brief Set the array of member DITypes. void setArraysHelper(MDNode *Elements, MDNode *TParams); public: explicit DICompositeType(const MDNode *N = nullptr) : DIDerivedType(N) {} + DICompositeType(const MDCompositeTypeBase *N) : DIDerivedType(N) {} + + MDCompositeTypeBase *get() const { + return cast_or_null<MDCompositeTypeBase>(DIDescriptor::get()); + } + operator MDCompositeTypeBase *() const { return get(); } + MDCompositeTypeBase *operator->() const { return get(); } + MDCompositeTypeBase &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } DIArray getElements() const { assert(!isSubroutineType() && "no elements for DISubroutineType"); - return getFieldAs<DIArray>(4); + RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getElements()); } private: @@ -544,16 +644,22 @@ private: } public: - unsigned getRunTimeLang() const { return getHeaderFieldAs<unsigned>(7); } - DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(5); } + unsigned getRunTimeLang() const { RETURN_FROM_RAW(N->getRuntimeLang(), 0); } + DITypeRef getContainingType() const { + RETURN_REF_FROM_RAW(DITypeRef, N->getVTableHolder()); + } private: /// \brief Set the containing type. void setContainingType(DICompositeType ContainingType); public: - DIArray getTemplateParams() const { return getFieldAs<DIArray>(6); } - MDString *getIdentifier() const; + DIArray getTemplateParams() const { + RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getTemplateParams()); + } + MDString *getIdentifier() const { + RETURN_FROM_RAW(N->getRawIdentifier(), nullptr); + } bool Verify() const; }; @@ -561,100 +667,163 @@ public: class DISubroutineType : public DICompositeType { public: explicit DISubroutineType(const MDNode *N = nullptr) : DICompositeType(N) {} + DISubroutineType(const MDSubroutineType *N) : DICompositeType(N) {} + + MDSubroutineType *get() const { + return cast_or_null<MDSubroutineType>(DIDescriptor::get()); + } + operator MDSubroutineType *() const { return get(); } + MDSubroutineType *operator->() const { return get(); } + MDSubroutineType &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + DITypedArray<DITypeRef> getTypeArray() const { - return getFieldAs<DITypedArray<DITypeRef>>(4); + RETURN_DESCRIPTOR_FROM_RAW(DITypedArray<DITypeRef>, N->getTypeArray()); } }; /// \brief This is a wrapper for a file. class DIFile : public DIScope { - friend class DIDescriptor; - public: explicit DIFile(const MDNode *N = nullptr) : DIScope(N) {} + DIFile(const MDFile *N) : DIScope(N) {} + + MDFile *get() const { return cast_or_null<MDFile>(DIDescriptor::get()); } + operator MDFile *() const { return get(); } + MDFile *operator->() const { return get(); } + MDFile &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } /// \brief Retrieve the MDNode for the directory/file pair. - MDNode *getFileNode() const; + MDNode *getFileNode() const { return get(); } bool Verify() const; }; /// \brief A wrapper for a compile unit. class DICompileUnit : public DIScope { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: explicit DICompileUnit(const MDNode *N = nullptr) : DIScope(N) {} + DICompileUnit(const MDCompileUnit *N) : DIScope(N) {} - dwarf::SourceLanguage getLanguage() const { - return static_cast<dwarf::SourceLanguage>(getHeaderFieldAs<unsigned>(1)); + MDCompileUnit *get() const { + return cast_or_null<MDCompileUnit>(DIDescriptor::get()); + } + operator MDCompileUnit *() const { return get(); } + MDCompileUnit *operator->() const { return get(); } + MDCompileUnit &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); } - StringRef getProducer() const { return getHeaderField(2); } - bool isOptimized() const { return getHeaderFieldAs<bool>(3) != 0; } - StringRef getFlags() const { return getHeaderField(4); } - unsigned getRunTimeVersion() const { return getHeaderFieldAs<unsigned>(5); } + dwarf::SourceLanguage getLanguage() const { + RETURN_FROM_RAW(static_cast<dwarf::SourceLanguage>(N->getSourceLanguage()), + static_cast<dwarf::SourceLanguage>(0)); + } + StringRef getProducer() const { RETURN_FROM_RAW(N->getProducer(), ""); } + bool isOptimized() const { RETURN_FROM_RAW(N->isOptimized(), false); } + StringRef getFlags() const { RETURN_FROM_RAW(N->getFlags(), ""); } + unsigned getRunTimeVersion() const { + RETURN_FROM_RAW(N->getRuntimeVersion(), 0); + } - DIArray getEnumTypes() const; - DIArray getRetainedTypes() const; - DIArray getSubprograms() const; - DIArray getGlobalVariables() const; - DIArray getImportedEntities() const; + DIArray getEnumTypes() const { + RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getEnumTypes()); + } + DIArray getRetainedTypes() const { + RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getRetainedTypes()); + } + DIArray getSubprograms() const { + RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getSubprograms()); + } + DIArray getGlobalVariables() const { + RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getGlobalVariables()); + } + DIArray getImportedEntities() const { + RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getImportedEntities()); + } void replaceSubprograms(DIArray Subprograms); void replaceGlobalVariables(DIArray GlobalVariables); - StringRef getSplitDebugFilename() const { return getHeaderField(6); } - unsigned getEmissionKind() const { return getHeaderFieldAs<unsigned>(7); } + StringRef getSplitDebugFilename() const { + RETURN_FROM_RAW(N->getSplitDebugFilename(), ""); + } + unsigned getEmissionKind() const { RETURN_FROM_RAW(N->getEmissionKind(), 0); } bool Verify() const; }; /// \brief This is a wrapper for a subprogram (e.g. a function). class DISubprogram : public DIScope { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: explicit DISubprogram(const MDNode *N = nullptr) : DIScope(N) {} + DISubprogram(const MDSubprogram *N) : DIScope(N) {} - StringRef getName() const { return getHeaderField(1); } - StringRef getDisplayName() const { return getHeaderField(2); } - StringRef getLinkageName() const { return getHeaderField(3); } - unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(4); } + MDSubprogram *get() const { + return cast_or_null<MDSubprogram>(DIDescriptor::get()); + } + operator MDSubprogram *() const { return get(); } + MDSubprogram *operator->() const { return get(); } + MDSubprogram &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + + StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); } + StringRef getDisplayName() const { RETURN_FROM_RAW(N->getDisplayName(), ""); } + StringRef getLinkageName() const { RETURN_FROM_RAW(N->getLinkageName(), ""); } + unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); } /// \brief Check if this is local (like 'static' in C). - unsigned isLocalToUnit() const { return getHeaderFieldAs<unsigned>(5); } - unsigned isDefinition() const { return getHeaderFieldAs<unsigned>(6); } + unsigned isLocalToUnit() const { RETURN_FROM_RAW(N->isLocalToUnit(), 0); } + unsigned isDefinition() const { RETURN_FROM_RAW(N->isDefinition(), 0); } - unsigned getVirtuality() const { return getHeaderFieldAs<unsigned>(7); } - unsigned getVirtualIndex() const { return getHeaderFieldAs<unsigned>(8); } + unsigned getVirtuality() const { RETURN_FROM_RAW(N->getVirtuality(), 0); } + unsigned getVirtualIndex() const { RETURN_FROM_RAW(N->getVirtualIndex(), 0); } - unsigned getFlags() const { return getHeaderFieldAs<unsigned>(9); } + unsigned getFlags() const { RETURN_FROM_RAW(N->getFlags(), 0); } - unsigned isOptimized() const { return getHeaderFieldAs<bool>(10); } + unsigned isOptimized() const { RETURN_FROM_RAW(N->isOptimized(), 0); } /// \brief Get the beginning of the scope of the function (not the name). - unsigned getScopeLineNumber() const { return getHeaderFieldAs<unsigned>(11); } + unsigned getScopeLineNumber() const { RETURN_FROM_RAW(N->getScopeLine(), 0); } - DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); } - DISubroutineType getType() const { return getFieldAs<DISubroutineType>(3); } + DIScopeRef getContext() const { + RETURN_REF_FROM_RAW(DIScopeRef, N->getScope()); + } + DISubroutineType getType() const { + RETURN_DESCRIPTOR_FROM_RAW(DISubroutineType, N->getType()); + } - DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(4); } + DITypeRef getContainingType() const { + RETURN_REF_FROM_RAW(DITypeRef, N->getContainingType()); + } bool Verify() const; /// \brief Check if this provides debugging information for the function F. bool describes(const Function *F); - Function *getFunction() const { return getFunctionField(5); } - void replaceFunction(Function *F) { replaceFunctionField(5, F); } - DIArray getTemplateParams() const { return getFieldAs<DIArray>(6); } + Function *getFunction() const; + + void replaceFunction(Function *F) { + if (auto *N = get()) + N->replaceFunction(F); + } + DIArray getTemplateParams() const { + RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getTemplateParams()); + } DISubprogram getFunctionDeclaration() const { - return getFieldAs<DISubprogram>(7); + RETURN_DESCRIPTOR_FROM_RAW(DISubprogram, N->getDeclaration()); + } + MDNode *getVariablesNodes() const { return getVariables(); } + DIArray getVariables() const { + RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getVariables()); } - MDNode *getVariablesNodes() const; - DIArray getVariables() const; unsigned isArtificial() const { return (getFlags() & FlagArtificial) != 0; } /// \brief Check for the "private" access specifier. @@ -695,9 +864,31 @@ public: class DILexicalBlock : public DIScope { public: explicit DILexicalBlock(const MDNode *N = nullptr) : DIScope(N) {} - DIScope getContext() const { return getFieldAs<DIScope>(2); } - unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(1); } - unsigned getColumnNumber() const { return getHeaderFieldAs<unsigned>(2); } + DILexicalBlock(const MDLexicalBlock *N) : DIScope(N) {} + + MDLexicalBlockBase *get() const { + return cast_or_null<MDLexicalBlockBase>(DIDescriptor::get()); + } + operator MDLexicalBlockBase *() const { return get(); } + MDLexicalBlockBase *operator->() const { return get(); } + MDLexicalBlockBase &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + + DIScope getContext() const { + RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope()); + } + unsigned getLineNumber() const { + if (auto *N = dyn_cast<MDLexicalBlock>(get())) + return N->getLine(); + return 0; + } + unsigned getColumnNumber() const { + if (auto *N = dyn_cast<MDLexicalBlock>(get())) + return N->getColumn(); + return 0; + } bool Verify() const; }; @@ -705,6 +896,18 @@ public: class DILexicalBlockFile : public DIScope { public: explicit DILexicalBlockFile(const MDNode *N = nullptr) : DIScope(N) {} + DILexicalBlockFile(const MDLexicalBlockFile *N) : DIScope(N) {} + + MDLexicalBlockFile *get() const { + return cast_or_null<MDLexicalBlockFile>(DIDescriptor::get()); + } + operator MDLexicalBlockFile *() const { return get(); } + MDLexicalBlockFile *operator->() const { return get(); } + MDLexicalBlockFile &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + DIScope getContext() const { // FIXME: This logic is horrible. getScope() returns a DILexicalBlock, but // then we check if it's a subprogram? WHAT?!? @@ -714,21 +917,36 @@ public: } unsigned getLineNumber() const { return getScope().getLineNumber(); } unsigned getColumnNumber() const { return getScope().getColumnNumber(); } - DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); } - unsigned getDiscriminator() const { return getHeaderFieldAs<unsigned>(1); } + DILexicalBlock getScope() const { + RETURN_DESCRIPTOR_FROM_RAW(DILexicalBlock, N->getScope()); + } + unsigned getDiscriminator() const { + RETURN_FROM_RAW(N->getDiscriminator(), 0); + } bool Verify() const; }; /// \brief A wrapper for a C++ style name space. class DINameSpace : public DIScope { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: explicit DINameSpace(const MDNode *N = nullptr) : DIScope(N) {} - StringRef getName() const { return getHeaderField(1); } - unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); } - DIScope getContext() const { return getFieldAs<DIScope>(2); } + DINameSpace(const MDNamespace *N) : DIScope(N) {} + + MDNamespace *get() const { + return cast_or_null<MDNamespace>(DIDescriptor::get()); + } + operator MDNamespace *() const { return get(); } + MDNamespace *operator->() const { return get(); } + MDNamespace &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + + StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); } + unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); } + DIScope getContext() const { + RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope()); + } bool Verify() const; }; @@ -737,10 +955,21 @@ class DITemplateTypeParameter : public DIDescriptor { public: explicit DITemplateTypeParameter(const MDNode *N = nullptr) : DIDescriptor(N) {} + DITemplateTypeParameter(const MDTemplateTypeParameter *N) : DIDescriptor(N) {} - StringRef getName() const { return getHeaderField(1); } + MDTemplateTypeParameter *get() const { + return cast_or_null<MDTemplateTypeParameter>(DIDescriptor::get()); + } + operator MDTemplateTypeParameter *() const { return get(); } + MDTemplateTypeParameter *operator->() const { return get(); } + MDTemplateTypeParameter &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + + StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); } - DITypeRef getType() const { return getFieldAs<DITypeRef>(2); } + DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); } bool Verify() const; }; @@ -749,40 +978,67 @@ class DITemplateValueParameter : public DIDescriptor { public: explicit DITemplateValueParameter(const MDNode *N = nullptr) : DIDescriptor(N) {} + DITemplateValueParameter(const MDTemplateValueParameter *N) + : DIDescriptor(N) {} - StringRef getName() const { return getHeaderField(1); } + MDTemplateValueParameter *get() const { + return cast_or_null<MDTemplateValueParameter>(DIDescriptor::get()); + } + operator MDTemplateValueParameter *() const { return get(); } + MDTemplateValueParameter *operator->() const { return get(); } + MDTemplateValueParameter &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } - DITypeRef getType() const { return getFieldAs<DITypeRef>(2); } - Metadata *getValue() const; + StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); } + DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); } + Metadata *getValue() const { RETURN_FROM_RAW(N->getValue(), nullptr); } bool Verify() const; }; /// \brief This is a wrapper for a global variable. class DIGlobalVariable : public DIDescriptor { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; + DIFile getFile() const { RETURN_DESCRIPTOR_FROM_RAW(DIFile, N->getFile()); } public: explicit DIGlobalVariable(const MDNode *N = nullptr) : DIDescriptor(N) {} + DIGlobalVariable(const MDGlobalVariable *N) : DIDescriptor(N) {} - StringRef getName() const { return getHeaderField(1); } - StringRef getDisplayName() const { return getHeaderField(2); } - StringRef getLinkageName() const { return getHeaderField(3); } - unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(4); } - unsigned isLocalToUnit() const { return getHeaderFieldAs<bool>(5); } - unsigned isDefinition() const { return getHeaderFieldAs<bool>(6); } + MDGlobalVariable *get() const { + return cast_or_null<MDGlobalVariable>(DIDescriptor::get()); + } + operator MDGlobalVariable *() const { return get(); } + MDGlobalVariable *operator->() const { return get(); } + MDGlobalVariable &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + + StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); } + StringRef getDisplayName() const { RETURN_FROM_RAW(N->getDisplayName(), ""); } + StringRef getLinkageName() const { RETURN_FROM_RAW(N->getLinkageName(), ""); } + unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); } + unsigned isLocalToUnit() const { RETURN_FROM_RAW(N->isLocalToUnit(), 0); } + unsigned isDefinition() const { RETURN_FROM_RAW(N->isDefinition(), 0); } - DIScope getContext() const { return getFieldAs<DIScope>(1); } - StringRef getFilename() const { return getFieldAs<DIFile>(2).getFilename(); } - StringRef getDirectory() const { - return getFieldAs<DIFile>(2).getDirectory(); + DIScope getContext() const { + RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope()); } - DITypeRef getType() const { return getFieldAs<DITypeRef>(3); } + StringRef getFilename() const { return getFile().getFilename(); } + StringRef getDirectory() const { return getFile().getDirectory(); } + DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); } - GlobalVariable *getGlobal() const { return getGlobalVariableField(4); } - Constant *getConstant() const { return getConstantField(4); } + GlobalVariable *getGlobal() const; + Constant *getConstant() const { + if (auto *N = get()) + if (auto *C = dyn_cast_or_null<ConstantAsMetadata>(N->getVariable())) + return C->getValue(); + return nullptr; + } DIDerivedType getStaticDataMemberDeclaration() const { - return getFieldAs<DIDerivedType>(5); + RETURN_DESCRIPTOR_FROM_RAW(DIDerivedType, + N->getStaticDataMemberDeclaration()); } bool Verify() const; @@ -790,34 +1046,45 @@ public: /// \brief This is a wrapper for a variable (e.g. parameter, local, global etc). class DIVariable : public DIDescriptor { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; + unsigned getFlags() const { RETURN_FROM_RAW(N->getFlags(), 0); } public: explicit DIVariable(const MDNode *N = nullptr) : DIDescriptor(N) {} + DIVariable(const MDLocalVariable *N) : DIDescriptor(N) {} - StringRef getName() const { return getHeaderField(1); } - unsigned getLineNumber() const { - // FIXME: Line number and arg number shouldn't be merged together like this. - return (getHeaderFieldAs<unsigned>(2) << 8) >> 8; + MDLocalVariable *get() const { + return cast_or_null<MDLocalVariable>(DIDescriptor::get()); + } + operator MDLocalVariable *() const { return get(); } + MDLocalVariable *operator->() const { return get(); } + MDLocalVariable &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); } - unsigned getArgNumber() const { return getHeaderFieldAs<unsigned>(2) >> 24; } - DIScope getContext() const { return getFieldAs<DIScope>(1); } - DIFile getFile() const { return getFieldAs<DIFile>(2); } - DITypeRef getType() const { return getFieldAs<DITypeRef>(3); } + StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); } + unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); } + unsigned getArgNumber() const { RETURN_FROM_RAW(N->getArg(), 0); } + + DIScope getContext() const { + RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope()); + } + DIFile getFile() const { RETURN_DESCRIPTOR_FROM_RAW(DIFile, N->getFile()); } + DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); } /// \brief Return true if this variable is marked as "artificial". bool isArtificial() const { - return (getHeaderFieldAs<unsigned>(3) & FlagArtificial) != 0; + return (getFlags() & FlagArtificial) != 0; } bool isObjectPointer() const { - return (getHeaderFieldAs<unsigned>(3) & FlagObjectPointer) != 0; + return (getFlags() & FlagObjectPointer) != 0; } /// \brief If this variable is inlined then return inline location. - MDNode *getInlinedAt() const; + MDNode *getInlinedAt() const { + RETURN_DESCRIPTOR_FROM_RAW(DIDescriptor, N->getInlinedAt()); + } bool Verify() const; @@ -843,25 +1110,28 @@ public: /// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const /// and have DW_OP_plus consume the topmost elements on the stack. class DIExpression : public DIDescriptor { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: explicit DIExpression(const MDNode *N = nullptr) : DIDescriptor(N) {} + DIExpression(const MDExpression *N) : DIDescriptor(N) {} - bool Verify() const; + MDExpression *get() const { + return cast_or_null<MDExpression>(DIDescriptor::get()); + } + operator MDExpression *() const { return get(); } + MDExpression *operator->() const { return get(); } + MDExpression &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + + // Don't call this. Call isValid() directly. + bool Verify() const = delete; /// \brief Return the number of elements in the complex expression. - unsigned getNumElements() const { - if (!DbgNode) - return 0; - unsigned N = getNumHeaderFields(); - assert(N > 0 && "missing tag"); - return N - 1; - } + unsigned getNumElements() const { return get()->getNumElements(); } /// \brief return the Idx'th complex address element. - uint64_t getElement(unsigned Idx) const; + uint64_t getElement(unsigned I) const { return get()->getElement(I); } /// \brief Return whether this is a piece of an aggregate variable. bool isBitPiece() const; @@ -874,34 +1144,33 @@ public: /// \brief A lightweight wrapper around an element of a DIExpression. class Operand { friend class iterator; - DIHeaderFieldIterator I; + MDExpression::element_iterator I; Operand() {} - Operand(DIHeaderFieldIterator I) : I(I) {} + Operand(MDExpression::element_iterator I) : I(I) {} public: /// \brief Operands such as DW_OP_piece have explicit (non-stack) arguments. /// Argument 0 is the operand itself. uint64_t getArg(unsigned N) const { - DIHeaderFieldIterator In = I; + MDExpression::element_iterator In = I; std::advance(In, N); - return In.getNumber<uint64_t>(); + return *In; } - operator uint64_t () const { return I.getNumber<uint64_t>(); } - /// \brief Returns underlying DIHeaderFieldIterator. - const DIHeaderFieldIterator &getBase() const { return I; } + operator uint64_t () const { return *I; } + /// \brief Returns underlying MDExpression::element_iterator. + const MDExpression::element_iterator &getBase() const { return I; } /// \brief Returns the next operand. - Operand getNext() const; + iterator getNext() const; }; /// \brief An iterator for DIExpression elements. class iterator : public std::iterator<std::input_iterator_tag, StringRef, unsigned, const Operand*, Operand> { friend class Operand; - DIHeaderFieldIterator I; + MDExpression::element_iterator I; Operand Tmp; - iterator(DIHeaderFieldIterator I) : I(I) {} + public: - iterator() {} - iterator(const DIExpression &Expr) : I(++Expr.header_begin()) {} + iterator(MDExpression::element_iterator I) : I(I) {} const Operand &operator*() { return Tmp = Operand(I); } const Operand *operator->() { return &(Tmp = Operand(I)); } iterator &operator++() { @@ -928,19 +1197,27 @@ public: } }; - iterator begin() const; - iterator end() const; + iterator begin() const { return get()->elements_begin(); } + iterator end() const { return get()->elements_end(); } }; /// \brief This object holds location information. /// /// This object is not associated with any DWARF tag. class DILocation : public DIDescriptor { - MDLocation *getRaw() const { return dyn_cast_or_null<MDLocation>(get()); } - public: explicit DILocation(const MDNode *N) : DIDescriptor(N) {} + MDLocation *get() const { + return cast_or_null<MDLocation>(DIDescriptor::get()); + } + operator MDLocation *() const { return get(); } + MDLocation *operator->() const { return get(); } + MDLocation &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); } unsigned getColumnNumber() const { RETURN_FROM_RAW(N->getColumn(), 0); } DIScope getScope() const { @@ -983,19 +1260,31 @@ public: }; class DIObjCProperty : public DIDescriptor { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) {} + DIObjCProperty(const MDObjCProperty *N) : DIDescriptor(N) {} + + MDObjCProperty *get() const { + return cast_or_null<MDObjCProperty>(DIDescriptor::get()); + } + operator MDObjCProperty *() const { return get(); } + MDObjCProperty *operator->() const { return get(); } + MDObjCProperty &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } - StringRef getObjCPropertyName() const { return getHeaderField(1); } - DIFile getFile() const { return getFieldAs<DIFile>(1); } - unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); } + StringRef getObjCPropertyName() const { RETURN_FROM_RAW(N->getName(), ""); } + DIFile getFile() const { RETURN_DESCRIPTOR_FROM_RAW(DIFile, N->getFile()); } + unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); } - StringRef getObjCPropertyGetterName() const { return getHeaderField(3); } - StringRef getObjCPropertySetterName() const { return getHeaderField(4); } - unsigned getAttributes() const { return getHeaderFieldAs<unsigned>(5); } + StringRef getObjCPropertyGetterName() const { + RETURN_FROM_RAW(N->getGetterName(), ""); + } + StringRef getObjCPropertySetterName() const { + RETURN_FROM_RAW(N->getSetterName(), ""); + } + unsigned getAttributes() const { RETURN_FROM_RAW(N->getAttributes(), 0); } bool isReadOnlyObjCProperty() const { return (getAttributes() & dwarf::DW_APPLE_PROPERTY_readonly) != 0; } @@ -1019,28 +1308,42 @@ public: /// /// \note Objective-C doesn't have an ODR, so there is no benefit in storing /// the type as a DITypeRef here. - DIType getType() const { return getFieldAs<DIType>(2); } + DIType getType() const { RETURN_DESCRIPTOR_FROM_RAW(DIType, N->getType()); } bool Verify() const; }; /// \brief An imported module (C++ using directive or similar). class DIImportedEntity : public DIDescriptor { - friend class DIDescriptor; - void printInternal(raw_ostream &OS) const; - public: DIImportedEntity() = default; explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {} - DIScope getContext() const { return getFieldAs<DIScope>(1); } - DIDescriptorRef getEntity() const { return getFieldAs<DIDescriptorRef>(2); } - unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(1); } - StringRef getName() const { return getHeaderField(2); } + DIImportedEntity(const MDImportedEntity *N) : DIDescriptor(N) {} + + MDImportedEntity *get() const { + return cast_or_null<MDImportedEntity>(DIDescriptor::get()); + } + operator MDImportedEntity *() const { return get(); } + MDImportedEntity *operator->() const { return get(); } + MDImportedEntity &operator*() const { + assert(get() && "Expected valid pointer"); + return *get(); + } + + DIScope getContext() const { + RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope()); + } + DIDescriptorRef getEntity() const { + RETURN_REF_FROM_RAW(DIDescriptorRef, N->getEntity()); + } + unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); } + StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); } bool Verify() const; }; #undef RETURN_FROM_RAW #undef RETURN_DESCRIPTOR_FROM_RAW +#undef RETURN_REF_FROM_RAW /// \brief Find subprogram that is enclosing this scope. DISubprogram getDISubprogram(const MDNode *Scope); @@ -1098,9 +1401,6 @@ public: /// \brief Process DILocation. void processLocation(const Module &M, DILocation Loc); - /// \brief Process DIExpression. - void processExpression(DIExpression Expr); - /// \brief Clear all lists. void reset(); diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 4534a14..d7563fc 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -41,53 +41,6 @@ namespace llvm { -/// \brief Debug location. -/// -/// A debug location in source code, used for debug info and otherwise. -class MDLocation : public MDNode { - friend class LLVMContextImpl; - friend class MDNode; - - MDLocation(LLVMContext &C, StorageType Storage, unsigned Line, - unsigned Column, ArrayRef<Metadata *> MDs); - ~MDLocation() { dropAllReferences(); } - - static MDLocation *getImpl(LLVMContext &Context, unsigned Line, - unsigned Column, Metadata *Scope, - Metadata *InlinedAt, StorageType Storage, - bool ShouldCreate = true); - - TempMDLocation cloneImpl() const { - return getTemporary(getContext(), getLine(), getColumn(), getScope(), - getInlinedAt()); - } - - // Disallow replacing operands. - void replaceOperandWith(unsigned I, Metadata *New) = delete; - -public: - DEFINE_MDNODE_GET(MDLocation, - (unsigned Line, unsigned Column, Metadata *Scope, - Metadata *InlinedAt = nullptr), - (Line, Column, Scope, InlinedAt)) - - /// \brief Return a (temporary) clone of this. - TempMDLocation clone() const { return cloneImpl(); } - - unsigned getLine() const { return SubclassData32; } - unsigned getColumn() const { return SubclassData16; } - Metadata *getScope() const { return getOperand(0); } - Metadata *getInlinedAt() const { - if (getNumOperands() == 2) - return getOperand(1); - return nullptr; - } - - static bool classof(const Metadata *MD) { - return MD->getMetadataID() == MDLocationKind; - } -}; - /// \brief Tagged DWARF-like metadata node. /// /// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*, @@ -146,7 +99,6 @@ public: case MDTemplateValueParameterKind: case MDGlobalVariableKind: case MDLocalVariableKind: - case MDExpressionKind: case MDObjCPropertyKind: case MDImportedEntityKind: return true; @@ -330,7 +282,16 @@ protected: ~MDScope() {} public: - Metadata *getFile() const { return getOperand(0); } + /// \brief Return the underlying file. + /// + /// An \a MDFile is an \a MDScope, but it doesn't point at a separate file + /// (it\em is the file). If \c this is an \a MDFile, we need to return \c + /// this. Otherwise, return the first operand, which is where all other + /// subclasses store their file pointer. + Metadata *getFile() const { + return isa<MDFile>(this) ? const_cast<MDScope *>(this) + : static_cast<Metadata *>(getOperand(0)); + } static bool classof(const Metadata *MD) { switch (MD->getMetadataID()) { @@ -351,6 +312,52 @@ public: } }; +/// \brief File. +/// +/// TODO: Merge with directory/file node (including users). +/// TODO: Canonicalize paths on creation. +class MDFile : public MDScope { + friend class LLVMContextImpl; + friend class MDNode; + + MDFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops) + : MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {} + ~MDFile() {} + + static MDFile *getImpl(LLVMContext &Context, StringRef Filename, + StringRef Directory, StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, getCanonicalMDString(Context, Filename), + getCanonicalMDString(Context, Directory), Storage, + ShouldCreate); + } + static MDFile *getImpl(LLVMContext &Context, MDString *Filename, + MDString *Directory, StorageType Storage, + bool ShouldCreate = true); + + TempMDFile cloneImpl() const { + return getTemporary(getContext(), getFilename(), getDirectory()); + } + +public: + DEFINE_MDNODE_GET(MDFile, (StringRef Filename, StringRef Directory), + (Filename, Directory)) + DEFINE_MDNODE_GET(MDFile, (MDString * Filename, MDString *Directory), + (Filename, Directory)) + + TempMDFile clone() const { return cloneImpl(); } + + StringRef getFilename() const { return getStringOperand(0); } + StringRef getDirectory() const { return getStringOperand(1); } + + MDString *getRawFilename() const { return getOperandAs<MDString>(0); } + MDString *getRawDirectory() const { return getOperandAs<MDString>(1); } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == MDFileKind; + } +}; + /// \brief Base class for types. /// /// TODO: Remove the hardcoded name and context, since many types don't use @@ -373,6 +380,10 @@ protected: ~MDType() {} public: + TempMDType clone() const { + return TempMDType(cast<MDType>(MDNode::clone().release())); + } + unsigned getLine() const { return Line; } uint64_t getSizeInBits() const { return SizeInBits; } uint64_t getAlignInBits() const { return AlignInBits; } @@ -384,6 +395,11 @@ public: MDString *getRawName() const { return getOperandAs<MDString>(2); } + void setFlags(unsigned NewFlags) { + assert(!isUniqued() && "Cannot set flags on uniqued nodes"); + Flags = NewFlags; + } + static bool classof(const Metadata *MD) { switch (MD->getMetadataID()) { default: @@ -433,6 +449,8 @@ class MDBasicType : public MDType { } public: + DEFINE_MDNODE_GET(MDBasicType, (unsigned Tag, StringRef Name), + (Tag, Name, 0, 0, 0)) DEFINE_MDNODE_GET(MDBasicType, (unsigned Tag, StringRef Name, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Encoding), @@ -719,52 +737,6 @@ public: } }; -/// \brief File. -/// -/// TODO: Merge with directory/file node (including users). -/// TODO: Canonicalize paths on creation. -class MDFile : public MDScope { - friend class LLVMContextImpl; - friend class MDNode; - - MDFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops) - : MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {} - ~MDFile() {} - - static MDFile *getImpl(LLVMContext &Context, StringRef Filename, - StringRef Directory, StorageType Storage, - bool ShouldCreate = true) { - return getImpl(Context, getCanonicalMDString(Context, Filename), - getCanonicalMDString(Context, Directory), Storage, - ShouldCreate); - } - static MDFile *getImpl(LLVMContext &Context, MDString *Filename, - MDString *Directory, StorageType Storage, - bool ShouldCreate = true); - - TempMDFile cloneImpl() const { - return getTemporary(getContext(), getFilename(), getDirectory()); - } - -public: - DEFINE_MDNODE_GET(MDFile, (StringRef Filename, StringRef Directory), - (Filename, Directory)) - DEFINE_MDNODE_GET(MDFile, (MDString * Filename, MDString *Directory), - (Filename, Directory)) - - TempMDFile clone() const { return cloneImpl(); } - - StringRef getFilename() const { return getStringOperand(0); } - StringRef getDirectory() const { return getStringOperand(1); } - - MDString *getRawFilename() const { return getOperandAs<MDString>(0); } - MDString *getRawDirectory() const { return getOperandAs<MDString>(1); } - - static bool classof(const Metadata *MD) { - return MD->getMetadataID() == MDFileKind; - } -}; - /// \brief Compile unit. class MDCompileUnit : public MDScope { friend class LLVMContextImpl; @@ -875,11 +847,96 @@ public: } }; +/// \brief A scope for locals. +/// +/// A legal scope for lexical blocks, local variables, and debug info +/// locations. Subclasses are \a MDSubprogram, \a MDLexicalBlock, and \a +/// MDLexicalBlockFile. +class MDLocalScope : public MDScope { +protected: + MDLocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, + ArrayRef<Metadata *> Ops) + : MDScope(C, ID, Storage, Tag, Ops) {} + ~MDLocalScope() {} + +public: + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == MDSubprogramKind || + MD->getMetadataID() == MDLexicalBlockKind || + MD->getMetadataID() == MDLexicalBlockFileKind; + } +}; + +/// \brief Debug location. +/// +/// A debug location in source code, used for debug info and otherwise. +class MDLocation : public MDNode { + friend class LLVMContextImpl; + friend class MDNode; + + MDLocation(LLVMContext &C, StorageType Storage, unsigned Line, + unsigned Column, ArrayRef<Metadata *> MDs); + ~MDLocation() { dropAllReferences(); } + + static MDLocation *getImpl(LLVMContext &Context, unsigned Line, + unsigned Column, Metadata *Scope, + Metadata *InlinedAt, StorageType Storage, + bool ShouldCreate = true); + static MDLocation *getImpl(LLVMContext &Context, unsigned Line, + unsigned Column, MDLocalScope *Scope, + MDLocation *InlinedAt, StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope), + static_cast<Metadata *>(InlinedAt), Storage, ShouldCreate); + } + + TempMDLocation cloneImpl() const { + return getTemporary(getContext(), getLine(), getColumn(), getScope(), + getInlinedAt()); + } + + // Disallow replacing operands. + void replaceOperandWith(unsigned I, Metadata *New) = delete; + +public: + DEFINE_MDNODE_GET(MDLocation, + (unsigned Line, unsigned Column, Metadata *Scope, + Metadata *InlinedAt = nullptr), + (Line, Column, Scope, InlinedAt)) + DEFINE_MDNODE_GET(MDLocation, + (unsigned Line, unsigned Column, MDLocalScope *Scope, + MDLocation *InlinedAt = nullptr), + (Line, Column, Scope, InlinedAt)) + + /// \brief Return a (temporary) clone of this. + TempMDLocation clone() const { return cloneImpl(); } + + unsigned getLine() const { return SubclassData32; } + unsigned getColumn() const { return SubclassData16; } + MDLocalScope *getScope() const { + return cast_or_null<MDLocalScope>(getRawScope()); + } + MDLocation *getInlinedAt() const { + return cast_or_null<MDLocation>(getRawInlinedAt()); + } + + Metadata *getRawScope() const { return getOperand(0); } + Metadata *getRawInlinedAt() const { + if (getNumOperands() == 2) + return getOperand(1); + return nullptr; + } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == MDLocationKind; + } +}; + /// \brief Subprogram description. /// /// TODO: Remove DisplayName. It's always equal to Name. /// TODO: Split up flags. -class MDSubprogram : public MDScope { +class MDSubprogram : public MDLocalScope { friend class LLVMContextImpl; friend class MDNode; @@ -896,7 +953,8 @@ class MDSubprogram : public MDScope { unsigned ScopeLine, unsigned Virtuality, unsigned VirtualIndex, unsigned Flags, bool IsLocalToUnit, bool IsDefinition, bool IsOptimized, ArrayRef<Metadata *> Ops) - : MDScope(C, MDSubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops), + : MDLocalScope(C, MDSubprogramKind, Storage, dwarf::DW_TAG_subprogram, + Ops), Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality), VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), IsOptimized(IsOptimized) {} @@ -1004,11 +1062,11 @@ public: } }; -class MDLexicalBlockBase : public MDScope { +class MDLexicalBlockBase : public MDLocalScope { protected: MDLexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage, ArrayRef<Metadata *> Ops) - : MDScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {} + : MDLocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {} ~MDLexicalBlockBase() {} public: @@ -1407,6 +1465,18 @@ public: unsigned getFlags() const { return Flags; } Metadata *getInlinedAt() const { return getOperand(4); } + /// \brief Get an inlined version of this variable. + /// + /// Returns a version of this with \a getAlinedAt() set to \c InlinedAt. + MDLocalVariable *withInline(MDLocation *InlinedAt) const { + if (InlinedAt == getInlinedAt()) + return const_cast<MDLocalVariable *>(this); + auto Temp = clone(); + Temp->replaceOperandWith(4, InlinedAt); + return replaceWithUniqued(std::move(Temp)); + } + MDLocalVariable *withoutInline() const { return withInline(nullptr); } + static bool classof(const Metadata *MD) { return MD->getMetadataID() == MDLocalVariableKind; } @@ -1415,17 +1485,16 @@ public: /// \brief DWARF expression. /// /// TODO: Co-allocate the expression elements. -/// TODO: Drop fake DW_TAG_expression and separate from DebugNode. /// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary /// storage types. -class MDExpression : public DebugNode { +class MDExpression : public MDNode { friend class LLVMContextImpl; friend class MDNode; std::vector<uint64_t> Elements; MDExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements) - : DebugNode(C, MDExpressionKind, Storage, dwarf::DW_TAG_expression, None), + : MDNode(C, MDExpressionKind, Storage, None), Elements(Elements.begin(), Elements.end()) {} ~MDExpression() {} diff --git a/include/llvm/IR/DebugLoc.h b/include/llvm/IR/DebugLoc.h index 86e6441..c29d5bf 100644 --- a/include/llvm/IR/DebugLoc.h +++ b/include/llvm/IR/DebugLoc.h @@ -103,7 +103,6 @@ namespace llvm { void dump(const LLVMContext &) const { dump(); } /// \brief prints source location /path/to/file.exe:line:col @[inlined at] void print(raw_ostream &OS) const; - void print(const LLVMContext &, raw_ostream &OS) const { print(OS); } }; } // end namespace llvm diff --git a/include/llvm/IR/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h index c6a8854..6db5a40 100644 --- a/include/llvm/IR/DiagnosticInfo.h +++ b/include/llvm/IR/DiagnosticInfo.h @@ -20,6 +20,7 @@ #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Module.h" #include "llvm/Support/Casting.h" +#include <functional> namespace llvm { diff --git a/include/llvm/IR/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h index 6f57dc2..ae2f2e1 100644 --- a/include/llvm/IR/GVMaterializer.h +++ b/include/llvm/IR/GVMaterializer.h @@ -53,6 +53,8 @@ public: /// virtual std::error_code MaterializeModule(Module *M) = 0; + virtual std::error_code materializeMetadata() = 0; + virtual std::vector<StructType *> getIdentifiedStructTypes() const = 0; }; diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index aaecc1d..002e5e7 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -346,8 +346,6 @@ public: inline Module *getParent() { return Parent; } inline const Module *getParent() const { return Parent; } - const DataLayout *getDataLayout() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { return V->getValueID() == Value::FunctionVal || diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index 33649d7..617e2bc 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -351,8 +351,8 @@ public: } /// \brief Fetch the type representing a pointer to an integer value. - IntegerType* getIntPtrTy(const DataLayout *DL, unsigned AddrSpace = 0) { - return DL->getIntPtrType(Context, AddrSpace); + IntegerType *getIntPtrTy(const DataLayout &DL, unsigned AddrSpace = 0) { + return DL.getIntPtrType(Context, AddrSpace); } //===--------------------------------------------------------------------===// @@ -1017,6 +1017,10 @@ public: } Value *CreateGEP(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &Name = "") { + return CreateGEP(nullptr, Ptr, IdxList, Name); + } + Value *CreateGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList, + const Twine &Name = "") { if (Constant *PC = dyn_cast<Constant>(Ptr)) { // Every index must be constant. size_t i, e; @@ -1026,7 +1030,7 @@ public: if (i == e) return Insert(Folder.CreateGetElementPtr(PC, IdxList), Name); } - return Insert(GetElementPtrInst::Create(Ptr, IdxList), Name); + return Insert(GetElementPtrInst::Create(Ty, Ptr, IdxList), Name); } Value *CreateInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &Name = "") { @@ -1039,19 +1043,19 @@ public: if (i == e) return Insert(Folder.CreateInBoundsGetElementPtr(PC, IdxList), Name); } - return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxList), Name); + return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, IdxList), Name); } Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") { if (Constant *PC = dyn_cast<Constant>(Ptr)) if (Constant *IC = dyn_cast<Constant>(Idx)) return Insert(Folder.CreateGetElementPtr(PC, IC), Name); - return Insert(GetElementPtrInst::Create(Ptr, Idx), Name); + return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name); } Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const Twine &Name = "") { if (Constant *PC = dyn_cast<Constant>(Ptr)) if (Constant *IC = dyn_cast<Constant>(Idx)) return Insert(Folder.CreateInBoundsGetElementPtr(PC, IC), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name); + return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name); } Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0); @@ -1059,7 +1063,7 @@ public: if (Constant *PC = dyn_cast<Constant>(Ptr)) return Insert(Folder.CreateGetElementPtr(PC, Idx), Name); - return Insert(GetElementPtrInst::Create(Ptr, Idx), Name); + return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name); } Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") { @@ -1068,7 +1072,7 @@ public: if (Constant *PC = dyn_cast<Constant>(Ptr)) return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name); + return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name); } Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1, const Twine &Name = "") { @@ -1080,7 +1084,7 @@ public: if (Constant *PC = dyn_cast<Constant>(Ptr)) return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name); - return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name); + return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idxs), Name); } Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1, const Twine &Name = "") { @@ -1092,7 +1096,7 @@ public: if (Constant *PC = dyn_cast<Constant>(Ptr)) return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name); + return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idxs), Name); } Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0); @@ -1100,7 +1104,7 @@ public: if (Constant *PC = dyn_cast<Constant>(Ptr)) return Insert(Folder.CreateGetElementPtr(PC, Idx), Name); - return Insert(GetElementPtrInst::Create(Ptr, Idx), Name); + return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name); } Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") { @@ -1109,7 +1113,7 @@ public: if (Constant *PC = dyn_cast<Constant>(Ptr)) return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name); + return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name); } Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name = "") { @@ -1121,7 +1125,7 @@ public: if (Constant *PC = dyn_cast<Constant>(Ptr)) return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name); - return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name); + return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idxs), Name); } Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name = "") { @@ -1133,7 +1137,7 @@ public: if (Constant *PC = dyn_cast<Constant>(Ptr)) return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name); + return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idxs), Name); } Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") { return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name); @@ -1486,6 +1490,16 @@ public: return Insert(new ShuffleVectorInst(V1, V2, Mask), Name); } + Value *CreateShuffleVector(Value *V1, Value *V2, ArrayRef<int> IntMask, + const Twine &Name = "") { + size_t MaskSize = IntMask.size(); + SmallVector<Constant*, 8> MaskVec(MaskSize); + for (size_t i = 0; i != MaskSize; ++i) + MaskVec[i] = getInt32(IntMask[i]); + Value *Mask = ConstantVector::get(MaskVec); + return CreateShuffleVector(V1, V2, Mask, Name); + } + Value *CreateExtractValue(Value *Agg, ArrayRef<unsigned> Idxs, const Twine &Name = "") { @@ -1595,7 +1609,7 @@ public: "trying to create an alignment assumption on a non-pointer?"); PointerType *PtrTy = cast<PointerType>(PtrValue->getType()); - Type *IntPtrTy = getIntPtrTy(&DL, PtrTy->getAddressSpace()); + Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); Value *PtrIntValue = CreatePtrToInt(PtrValue, IntPtrTy, "ptrint"); Value *Mask = ConstantInt::get(IntPtrTy, diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h index 84ae9df..6ae4122 100644 --- a/include/llvm/IR/InlineAsm.h +++ b/include/llvm/IR/InlineAsm.h @@ -189,6 +189,20 @@ public: // These are helper methods for dealing with flags in the INLINEASM SDNode // in the backend. + // + // The encoding of the flag word is currently: + // Bits 2-0 - A Kind_* value indicating the kind of the operand. + // Bits 15-3 - The number of SDNode operands associated with this inline + // assembly operand. + // If bit 31 is set: + // Bit 30-16 - The operand number that this operand must match. + // When bits 2-0 are Kind_Mem, the Constraint_* value must be + // obtained from the flags for this operand number. + // Else if bits 2-0 are Kind_Mem: + // Bit 30-16 - A Constraint_* value indicating the original constraint + // code. + // Else: + // Bit 30-16 - The register class ID to use for the operand. enum : uint32_t { // Fixed operands on an INLINEASM SDNode. @@ -220,6 +234,26 @@ public: Kind_Imm = 5, // Immediate. Kind_Mem = 6, // Memory operand, "m". + // Memory constraint codes. + // These could be tablegenerated but there's little need to do that since + // there's plenty of space in the encoding to support the union of all + // constraint codes for all targets. + Constraint_Unknown = 0, + Constraint_es, + Constraint_i, + Constraint_m, + Constraint_o, + Constraint_v, + Constraint_Q, + Constraint_R, + Constraint_S, + Constraint_T, + Constraint_Z, + Constraint_ZC, + Constraint_Zy, + Constraints_Max = Constraint_Zy, + Constraints_ShiftAmount = 16, + Flag_MatchingOperand = 0x80000000 }; @@ -252,6 +286,20 @@ public: return InputFlag | (RC << 16); } + /// Augment an existing flag word returned by getFlagWord with the constraint + /// code for a memory constraint. + static unsigned getFlagWordForMem(unsigned InputFlag, unsigned Constraint) { + assert(Constraint <= 0x7fff && "Too large a memory constraint ID"); + assert(Constraint <= Constraints_Max && "Unknown constraint ID"); + assert((InputFlag & ~0xffff) == 0 && "High bits already contain data"); + return InputFlag | (Constraint << Constraints_ShiftAmount); + } + + static unsigned convertMemFlagWordToMatchingFlagWord(unsigned InputFlag) { + assert(isMemKind(InputFlag)); + return InputFlag & ~(0x7fff << Constraints_ShiftAmount); + } + static unsigned getKind(unsigned Flags) { return Flags & 7; } @@ -266,6 +314,11 @@ public: return getKind(Flag) == Kind_Clobber; } + static unsigned getMemoryConstraintID(unsigned Flag) { + assert(isMemKind(Flag)); + return (Flag >> Constraints_ShiftAmount) & 0x7fff; + } + /// getNumOperandRegisters - Extract the number of registers field from the /// inline asm operand flag. static unsigned getNumOperandRegisters(unsigned Flag) { diff --git a/include/llvm/IR/InstIterator.h b/include/llvm/IR/InstIterator.h index 0bb2854..f3ce649 100644 --- a/include/llvm/IR/InstIterator.h +++ b/include/llvm/IR/InstIterator.h @@ -27,15 +27,14 @@ namespace llvm { // This class implements inst_begin() & inst_end() for // inst_iterator and const_inst_iterator's. // -template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t> -class InstIterator { - typedef _BB_t BBty; - typedef _BB_i_t BBIty; - typedef _BI_t BIty; - typedef _II_t IIty; - _BB_t *BBs; // BasicBlocksType - _BB_i_t BB; // BasicBlocksType::iterator - _BI_t BI; // BasicBlock::iterator +template <class BB_t, class BB_i_t, class BI_t, class II_t> class InstIterator { + typedef BB_t BBty; + typedef BB_i_t BBIty; + typedef BI_t BIty; + typedef II_t IIty; + BB_t *BBs; // BasicBlocksType + BB_i_t BB; // BasicBlocksType::iterator + BI_t BI; // BasicBlock::iterator public: typedef std::bidirectional_iterator_tag iterator_category; typedef IIty value_type; diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index e086282..3a33f43 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -570,10 +570,9 @@ public: /// This ensures that any pointer<->integer cast has enough bits in the /// integer and any other cast is a bitcast. static bool isBitOrNoopPointerCastable( - Type *SrcTy, ///< The Type from which the value should be cast. - Type *DestTy, ///< The Type to which the value should be cast. - const DataLayout *Layout = 0 ///< Optional DataLayout. - ); + Type *SrcTy, ///< The Type from which the value should be cast. + Type *DestTy, ///< The Type to which the value should be cast. + const DataLayout &DL); /// Returns the opcode necessary to cast Val into Ty using usual casting /// rules. @@ -621,9 +620,9 @@ public: ) const; /// @brief Determine if this cast is a no-op cast. - bool isNoopCast( - const DataLayout *DL ///< DataLayout to get the Int Ptr type from. - ) const; + /// + /// \param DL is the DataLayout to get the Int Ptr type from. + bool isNoopCast(const DataLayout &DL) const; /// Determine how a pair of casts can be eliminated, if they can be at all. /// This is a helper function for both CastInst and ConstantExpr. diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index dfece3e..dc96b57 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -54,7 +54,12 @@ public: inline const BasicBlock *getParent() const { return Parent; } inline BasicBlock *getParent() { return Parent; } - const DataLayout *getDataLayout() const; + /// \brief Return the module owning the function this instruction belongs to + /// or nullptr it the function does not have a module. + /// + /// Note: this is undefined behavior if the instruction does not have a + /// parent, or the parent basic block does not have a parent function. + const Module *getModule() const; /// removeFromParent - This method unlinks 'this' from the containing basic /// block, but does not delete it. diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 83f9d04..52fa360 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -794,28 +794,31 @@ class GetElementPtrInst : public Instruction { /// list of indices. The first ctor can optionally insert before an existing /// instruction, the second appends the new instruction to the specified /// BasicBlock. - inline GetElementPtrInst(Value *Ptr, ArrayRef<Value *> IdxList, - unsigned Values, const Twine &NameStr, - Instruction *InsertBefore); - inline GetElementPtrInst(Value *Ptr, ArrayRef<Value *> IdxList, - unsigned Values, const Twine &NameStr, - BasicBlock *InsertAtEnd); + inline GetElementPtrInst(Type *PointeeType, Value *Ptr, + ArrayRef<Value *> IdxList, unsigned Values, + const Twine &NameStr, Instruction *InsertBefore); + inline GetElementPtrInst(Type *PointeeType, Value *Ptr, + ArrayRef<Value *> IdxList, unsigned Values, + const Twine &NameStr, BasicBlock *InsertAtEnd); + protected: GetElementPtrInst *clone_impl() const override; public: - static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList, + static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr, + ArrayRef<Value *> IdxList, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { unsigned Values = 1 + unsigned(IdxList.size()); - return new(Values) - GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertBefore); + return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values, + NameStr, InsertBefore); } - static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList, + static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr, + ArrayRef<Value *> IdxList, const Twine &NameStr, BasicBlock *InsertAtEnd) { unsigned Values = 1 + unsigned(IdxList.size()); - return new(Values) - GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertAtEnd); + return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values, + NameStr, InsertAtEnd); } /// Create an "inbounds" getelementptr. See the documentation for the @@ -824,7 +827,14 @@ public: ArrayRef<Value *> IdxList, const Twine &NameStr = "", Instruction *InsertBefore = nullptr){ - GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertBefore); + return CreateInBounds(nullptr, Ptr, IdxList, NameStr, InsertBefore); + } + static GetElementPtrInst * + CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef<Value *> IdxList, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + GetElementPtrInst *GEP = + Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore); GEP->setIsInBounds(true); return GEP; } @@ -832,7 +842,14 @@ public: ArrayRef<Value *> IdxList, const Twine &NameStr, BasicBlock *InsertAtEnd) { - GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertAtEnd); + return CreateInBounds(nullptr, Ptr, IdxList, NameStr, InsertAtEnd); + } + static GetElementPtrInst *CreateInBounds(Type *PointeeType, Value *Ptr, + ArrayRef<Value *> IdxList, + const Twine &NameStr, + BasicBlock *InsertAtEnd) { + GetElementPtrInst *GEP = + Create(PointeeType, Ptr, IdxList, NameStr, InsertAtEnd); GEP->setIsInBounds(true); return GEP; } @@ -846,12 +863,12 @@ public: } Type *getSourceElementType() const { - SequentialType *Ty = cast<SequentialType>(getPointerOperandType()); - if (VectorType *VTy = dyn_cast<VectorType>(Ty)) - Ty = cast<SequentialType>(VTy->getElementType()); - return Ty->getElementType(); + return cast<SequentialType>(getPointerOperandType()->getScalarType()) + ->getElementType(); } + Type *getResultElementType() const { return getType()->getElementType(); } + /// \brief Returns the address space of this instruction's pointer type. unsigned getAddressSpace() const { // Note that this is always the same as the pointer operand's address space @@ -960,27 +977,25 @@ struct OperandTraits<GetElementPtrInst> : public VariadicOperandTraits<GetElementPtrInst, 1> { }; -GetElementPtrInst::GetElementPtrInst(Value *Ptr, - ArrayRef<Value *> IdxList, - unsigned Values, +GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, + ArrayRef<Value *> IdxList, unsigned Values, const Twine &NameStr, Instruction *InsertBefore) - : Instruction(getGEPReturnType(Ptr, IdxList), - GetElementPtr, - OperandTraits<GetElementPtrInst>::op_end(this) - Values, - Values, InsertBefore) { + : Instruction(getGEPReturnType(Ptr, IdxList), GetElementPtr, + OperandTraits<GetElementPtrInst>::op_end(this) - Values, + Values, InsertBefore) { init(Ptr, IdxList, NameStr); + assert(!PointeeType || PointeeType == getSourceElementType()); } -GetElementPtrInst::GetElementPtrInst(Value *Ptr, - ArrayRef<Value *> IdxList, - unsigned Values, +GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, + ArrayRef<Value *> IdxList, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) - : Instruction(getGEPReturnType(Ptr, IdxList), - GetElementPtr, - OperandTraits<GetElementPtrInst>::op_end(this) - Values, - Values, InsertAtEnd) { + : Instruction(getGEPReturnType(Ptr, IdxList), GetElementPtr, + OperandTraits<GetElementPtrInst>::op_end(this) - Values, + Values, InsertAtEnd) { init(Ptr, IdxList, NameStr); + assert(!PointeeType || PointeeType == getSourceElementType()); } @@ -1201,11 +1216,15 @@ public: /// @returns true if the predicate of this instruction is EQ or NE. /// \brief Determine if this is an equality predicate. - bool isEquality() const { - return getPredicate() == FCMP_OEQ || getPredicate() == FCMP_ONE || - getPredicate() == FCMP_UEQ || getPredicate() == FCMP_UNE; + static bool isEquality(Predicate Pred) { + return Pred == FCMP_OEQ || Pred == FCMP_ONE || Pred == FCMP_UEQ || + Pred == FCMP_UNE; } + /// @returns true if the predicate of this instruction is EQ or NE. + /// \brief Determine if this is an equality predicate. + bool isEquality() const { return isEquality(getPredicate()); } + /// @returns true if the predicate of this instruction is commutative. /// \brief Determine if this is a commutative predicate. bool isCommutative() const { @@ -1908,6 +1927,9 @@ public: typedef const unsigned* idx_iterator; inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_end() const { return Indices.end(); } + inline iterator_range<idx_iterator> indices() const { + return iterator_range<idx_iterator>(idx_begin(), idx_end()); + } Value *getAggregateOperand() { return getOperand(0); @@ -2019,6 +2041,9 @@ public: typedef const unsigned* idx_iterator; inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_end() const { return Indices.end(); } + inline iterator_range<idx_iterator> indices() const { + return iterator_range<idx_iterator>(idx_begin(), idx_end()); + } Value *getAggregateOperand() { return getOperand(0); diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h index d434432..bf0adc3 100644 --- a/include/llvm/IR/IntrinsicInst.h +++ b/include/llvm/IR/IntrinsicInst.h @@ -82,13 +82,18 @@ namespace llvm { class DbgDeclareInst : public DbgInfoIntrinsic { public: Value *getAddress() const; - MDNode *getVariable() const { - return cast<MDNode>( - cast<MetadataAsValue>(getArgOperand(1))->getMetadata()); + MDLocalVariable *getVariable() const { + return cast<MDLocalVariable>(getRawVariable()); } - MDNode *getExpression() const { - return cast<MDNode>( - cast<MetadataAsValue>(getArgOperand(2))->getMetadata()); + MDExpression *getExpression() const { + return cast<MDExpression>(getRawExpression()); + } + + Metadata *getRawVariable() const { + return cast<MetadataAsValue>(getArgOperand(1))->getMetadata(); + } + Metadata *getRawExpression() const { + return cast<MetadataAsValue>(getArgOperand(2))->getMetadata(); } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -110,13 +115,18 @@ namespace llvm { return cast<ConstantInt>( const_cast<Value*>(getArgOperand(1)))->getZExtValue(); } - MDNode *getVariable() const { - return cast<MDNode>( - cast<MetadataAsValue>(getArgOperand(2))->getMetadata()); + MDLocalVariable *getVariable() const { + return cast<MDLocalVariable>(getRawVariable()); + } + MDExpression *getExpression() const { + return cast<MDExpression>(getRawExpression()); + } + + Metadata *getRawVariable() const { + return cast<MetadataAsValue>(getArgOperand(2))->getMetadata(); } - MDNode *getExpression() const { - return cast<MDNode>( - cast<MetadataAsValue>(getArgOperand(3))->getMetadata()); + Metadata *getRawExpression() const { + return cast<MetadataAsValue>(getArgOperand(3))->getMetadata(); } // Methods for support type inquiry through isa, cast, and dyn_cast: diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index e89e65d..da9d8cb 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -261,10 +261,10 @@ def int_gcwrite : Intrinsic<[], // def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>; def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>; -def int_frameallocate : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>; +def int_frameescape : Intrinsic<[], [llvm_vararg_ty]>; def int_framerecover : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty, llvm_ptr_ty], - [IntrNoMem]>; + [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], + [IntrNoMem]>; def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty], [IntrNoMem], "llvm.read_register">; def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty], @@ -412,10 +412,19 @@ def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>; def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>; // eh.begincatch takes a pointer returned by a landingpad instruction and -// returns the exception object pointer for the exception to be handled. -def int_eh_begincatch : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty]>; +// copies the exception object into the memory pointed to by the second +// parameter. If the second parameter is null, no copy occurs. +def int_eh_begincatch : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], + [NoCapture<0>, NoCapture<1>]>; def int_eh_endcatch : Intrinsic<[], []>; +// Represents the list of actions to take when an exception is thrown. +def int_eh_actions : Intrinsic<[llvm_ptr_ty], [llvm_vararg_ty], []>; + +// Designates the provided static alloca as the unwind help object. Required +// for WinEH. +def int_eh_unwindhelp : Intrinsic<[], [llvm_ptr_ty], []>; + // __builtin_unwind_init is an undocumented GCC intrinsic that causes all // callee-saved registers to be saved and restored (regardless of whether they // are used) in the calling function. It is used by libgcc_eh. diff --git a/include/llvm/IR/IntrinsicsHexagon.td b/include/llvm/IR/IntrinsicsHexagon.td index b566956..78ee651 100644 --- a/include/llvm/IR/IntrinsicsHexagon.td +++ b/include/llvm/IR/IntrinsicsHexagon.td @@ -422,12 +422,42 @@ class Hexagon_di_didisisi_Intrinsic<string GCCIntSuffix> llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +class Hexagon_mem_memmemsi_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty, + llvm_i32_ty], + [IntrReadWriteArgMem]>; + +class Hexagon_mem_memsisi_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty, + llvm_i32_ty], + [IntrReadWriteArgMem]>; + +class Hexagon_mem_memdisi_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty, + llvm_i32_ty], + [IntrReadWriteArgMem]>; + class Hexagon_mem_memmemsisi_Intrinsic<string GCCIntSuffix> : Hexagon_Intrinsic<GCCIntSuffix, [llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>; +class Hexagon_mem_memsisisi_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + +class Hexagon_mem_memdisisi_Intrinsic<string GCCIntSuffix> + : Hexagon_Intrinsic<GCCIntSuffix, + [llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty, + llvm_i32_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + // // Hexagon_sf_df_Intrinsic<string GCCIntSuffix> // @@ -606,20 +636,126 @@ class Hexagon_df_dfdfdfqi_Intrinsic<string GCCIntSuffix> [IntrNoMem, Throws]>; -// This one below will not be generated from iset.py. -// So make sure, you don't overwrite this one. +// This one below will not be auto-generated, +// so make sure, you don't overwrite this one. // // BUILTIN_INFO(SI_to_SXTHI_asrh,SI_ftype_SI,1) // def int_hexagon_SI_to_SXTHI_asrh : Hexagon_si_si_Intrinsic<"SI_to_SXTHI_asrh">; // +// BUILTIN_INFO_NONCONST(brev_ldd,PTR_ftype_PTRPTRSI,3) +// +def int_hexagon_brev_ldd : +Hexagon_mem_memmemsi_Intrinsic<"brev_ldd">; +// +// BUILTIN_INFO_NONCONST(brev_ldw,PTR_ftype_PTRPTRSI,3) +// +def int_hexagon_brev_ldw : +Hexagon_mem_memmemsi_Intrinsic<"brev_ldw">; +// +// BUILTIN_INFO_NONCONST(brev_ldh,PTR_ftype_PTRPTRSI,3) +// +def int_hexagon_brev_ldh : +Hexagon_mem_memmemsi_Intrinsic<"brev_ldh">; +// +// BUILTIN_INFO_NONCONST(brev_lduh,PTR_ftype_PTRPTRSI,3) +// +def int_hexagon_brev_lduh : +Hexagon_mem_memmemsi_Intrinsic<"brev_lduh">; +// +// BUILTIN_INFO_NONCONST(brev_ldb,PTR_ftype_PTRPTRSI,3) +// +def int_hexagon_brev_ldb : +Hexagon_mem_memmemsi_Intrinsic<"brev_ldb">; +// +// BUILTIN_INFO_NONCONST(brev_ldub,PTR_ftype_PTRPTRSI,3) +// +def int_hexagon_brev_ldub : +Hexagon_mem_memmemsi_Intrinsic<"brev_ldub">; +// // BUILTIN_INFO_NONCONST(circ_ldd,PTR_ftype_PTRPTRSISI,4) // def int_hexagon_circ_ldd : Hexagon_mem_memmemsisi_Intrinsic<"circ_ldd">; -// This one above will not be generated from iset.py. -// So make sure, you don't overwrite this one. +// +// BUILTIN_INFO_NONCONST(circ_ldw,PTR_ftype_PTRPTRSISI,4) +// +def int_hexagon_circ_ldw : +Hexagon_mem_memmemsisi_Intrinsic<"circ_ldw">; +// +// BUILTIN_INFO_NONCONST(circ_ldh,PTR_ftype_PTRPTRSISI,4) +// +def int_hexagon_circ_ldh : +Hexagon_mem_memmemsisi_Intrinsic<"circ_ldh">; +// +// BUILTIN_INFO_NONCONST(circ_lduh,PTR_ftype_PTRPTRSISI,4) +// +def int_hexagon_circ_lduh : +Hexagon_mem_memmemsisi_Intrinsic<"circ_lduh">; +// +// BUILTIN_INFO_NONCONST(circ_ldb,PTR_ftype_PTRPTRSISI,4) +// +def int_hexagon_circ_ldb : +Hexagon_mem_memmemsisi_Intrinsic<"circ_ldb">; +// +// BUILTIN_INFO_NONCONST(circ_ldub,PTR_ftype_PTRPTRSISI,4) +// +def int_hexagon_circ_ldub : +Hexagon_mem_memmemsisi_Intrinsic<"circ_ldub">; + +// +// BUILTIN_INFO_NONCONST(brev_stb,PTR_ftype_PTRSISI,3) +// +def int_hexagon_brev_stb : +Hexagon_mem_memsisi_Intrinsic<"brev_stb">; +// +// BUILTIN_INFO_NONCONST(brev_sthhi,PTR_ftype_PTRSISI,3) +// +def int_hexagon_brev_sthhi : +Hexagon_mem_memsisi_Intrinsic<"brev_sthhi">; +// +// BUILTIN_INFO_NONCONST(brev_sth,PTR_ftype_PTRSISI,3) +// +def int_hexagon_brev_sth : +Hexagon_mem_memsisi_Intrinsic<"brev_sth">; +// +// BUILTIN_INFO_NONCONST(brev_stw,PTR_ftype_PTRSISI,3) +// +def int_hexagon_brev_stw : +Hexagon_mem_memsisi_Intrinsic<"brev_stw">; +// +// BUILTIN_INFO_NONCONST(brev_std,PTR_ftype_PTRSISI,3) +// +def int_hexagon_brev_std : +Hexagon_mem_memdisi_Intrinsic<"brev_std">; +// +// BUILTIN_INFO_NONCONST(circ_std,PTR_ftype_PTRDISISI,4) +// +def int_hexagon_circ_std : +Hexagon_mem_memdisisi_Intrinsic<"circ_std">; +// +// BUILTIN_INFO_NONCONST(circ_stw,PTR_ftype_PTRSISISI,4) +// +def int_hexagon_circ_stw : +Hexagon_mem_memsisisi_Intrinsic<"circ_stw">; +// +// BUILTIN_INFO_NONCONST(circ_sth,PTR_ftype_PTRSISISI,4) +// +def int_hexagon_circ_sth : +Hexagon_mem_memsisisi_Intrinsic<"circ_sth">; +// +// BUILTIN_INFO_NONCONST(circ_sthhi,PTR_ftype_PTRSISISI,4) +// +def int_hexagon_circ_sthhi : +Hexagon_mem_memsisisi_Intrinsic<"circ_sthhi">; +// +// BUILTIN_INFO_NONCONST(circ_stb,PTR_ftype_PTRSISISI,4) +// +def int_hexagon_circ_stb : +Hexagon_mem_memsisisi_Intrinsic<"circ_stb">; + + // // BUILTIN_INFO(HEXAGON.C2_cmpeq,QI_ftype_SISI,2) // diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td index 110d55d..95fc3e5 100644 --- a/include/llvm/IR/IntrinsicsPowerPC.td +++ b/include/llvm/IR/IntrinsicsPowerPC.td @@ -73,7 +73,7 @@ class PowerPC_Vec_FFF_Intrinsic<string GCCIntSuffix> [llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; -/// PowerPC_Vec_BBB_Intrinsic - A PowerPC intrinsic that takes two v16f8 +/// PowerPC_Vec_BBB_Intrinsic - A PowerPC intrinsic that takes two v16i8 /// vectors and returns one. These intrinsics have no side effects. class PowerPC_Vec_BBB_Intrinsic<string GCCIntSuffix> : PowerPC_Vec_Intrinsic<GCCIntSuffix, @@ -94,6 +94,12 @@ class PowerPC_Vec_WWW_Intrinsic<string GCCIntSuffix> [llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; +/// PowerPC_Vec_DDD_Intrinsic - A PowerPC intrinsic that takes two v2i64 +/// vectors and returns one. These intrinsics have no side effects. +class PowerPC_Vec_DDD_Intrinsic<string GCCIntSuffix> + : PowerPC_Vec_Intrinsic<GCCIntSuffix, + [llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], + [IntrNoMem]>; //===----------------------------------------------------------------------===// // PowerPC VSX Intrinsic Class Definitions. @@ -120,7 +126,6 @@ class PowerPC_VSX_Sca_DDD_Intrinsic<string GCCIntSuffix> [llvm_double_ty], [llvm_double_ty, llvm_double_ty], [IntrNoMem]>; - //===----------------------------------------------------------------------===// // PowerPC Altivec Intrinsic Definitions. @@ -198,7 +203,17 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". def int_ppc_altivec_vcmpgtfp : GCCBuiltin<"__builtin_altivec_vcmpgtfp">, Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; - + + def int_ppc_altivec_vcmpequd : GCCBuiltin<"__builtin_altivec_vcmpequd">, + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], + [IntrNoMem]>; + def int_ppc_altivec_vcmpgtsd : GCCBuiltin<"__builtin_altivec_vcmpgtsd">, + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], + [IntrNoMem]>; + def int_ppc_altivec_vcmpgtud : GCCBuiltin<"__builtin_altivec_vcmpgtud">, + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], + [IntrNoMem]>; + def int_ppc_altivec_vcmpequw : GCCBuiltin<"__builtin_altivec_vcmpequw">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; @@ -242,7 +257,17 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". def int_ppc_altivec_vcmpgtfp_p : GCCBuiltin<"__builtin_altivec_vcmpgtfp_p">, Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty], [IntrNoMem]>; - + + def int_ppc_altivec_vcmpequd_p : GCCBuiltin<"__builtin_altivec_vcmpequd_p">, + Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v2i64_ty,llvm_v2i64_ty], + [IntrNoMem]>; + def int_ppc_altivec_vcmpgtsd_p : GCCBuiltin<"__builtin_altivec_vcmpgtsd_p">, + Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v2i64_ty,llvm_v2i64_ty], + [IntrNoMem]>; + def int_ppc_altivec_vcmpgtud_p : GCCBuiltin<"__builtin_altivec_vcmpgtud_p">, + Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v2i64_ty,llvm_v2i64_ty], + [IntrNoMem]>; + def int_ppc_altivec_vcmpequw_p : GCCBuiltin<"__builtin_altivec_vcmpequw_p">, Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4i32_ty,llvm_v4i32_ty], [IntrNoMem]>; @@ -287,18 +312,22 @@ def int_ppc_altivec_vmaxfp : PowerPC_Vec_FFF_Intrinsic<"vmaxfp">; def int_ppc_altivec_vmaxsb : PowerPC_Vec_BBB_Intrinsic<"vmaxsb">; def int_ppc_altivec_vmaxsh : PowerPC_Vec_HHH_Intrinsic<"vmaxsh">; def int_ppc_altivec_vmaxsw : PowerPC_Vec_WWW_Intrinsic<"vmaxsw">; +def int_ppc_altivec_vmaxsd : PowerPC_Vec_DDD_Intrinsic<"vmaxsd">; def int_ppc_altivec_vmaxub : PowerPC_Vec_BBB_Intrinsic<"vmaxub">; def int_ppc_altivec_vmaxuh : PowerPC_Vec_HHH_Intrinsic<"vmaxuh">; def int_ppc_altivec_vmaxuw : PowerPC_Vec_WWW_Intrinsic<"vmaxuw">; +def int_ppc_altivec_vmaxud : PowerPC_Vec_DDD_Intrinsic<"vmaxud">; // Vector minimum. def int_ppc_altivec_vminfp : PowerPC_Vec_FFF_Intrinsic<"vminfp">; def int_ppc_altivec_vminsb : PowerPC_Vec_BBB_Intrinsic<"vminsb">; def int_ppc_altivec_vminsh : PowerPC_Vec_HHH_Intrinsic<"vminsh">; def int_ppc_altivec_vminsw : PowerPC_Vec_WWW_Intrinsic<"vminsw">; +def int_ppc_altivec_vminsd : PowerPC_Vec_DDD_Intrinsic<"vminsd">; def int_ppc_altivec_vminub : PowerPC_Vec_BBB_Intrinsic<"vminub">; def int_ppc_altivec_vminuh : PowerPC_Vec_HHH_Intrinsic<"vminuh">; def int_ppc_altivec_vminuw : PowerPC_Vec_WWW_Intrinsic<"vminuw">; +def int_ppc_altivec_vminud : PowerPC_Vec_DDD_Intrinsic<"vminud">; // Saturating adds. def int_ppc_altivec_vaddubs : PowerPC_Vec_BBB_Intrinsic<"vaddubs">; @@ -361,12 +390,18 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.". def int_ppc_altivec_vmulesh : GCCBuiltin<"__builtin_altivec_vmulesh">, Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; + def int_ppc_altivec_vmulesw : GCCBuiltin<"__builtin_altivec_vmulesw">, + Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], + [IntrNoMem]>; def int_ppc_altivec_vmuleub : GCCBuiltin<"__builtin_altivec_vmuleub">, Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; def int_ppc_altivec_vmuleuh : GCCBuiltin<"__builtin_altivec_vmuleuh">, Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; + def int_ppc_altivec_vmuleuw : GCCBuiltin<"__builtin_altivec_vmuleuw">, + Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], + [IntrNoMem]>; def int_ppc_altivec_vmulosb : GCCBuiltin<"__builtin_altivec_vmulosb">, Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], @@ -374,12 +409,18 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.". def int_ppc_altivec_vmulosh : GCCBuiltin<"__builtin_altivec_vmulosh">, Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; + def int_ppc_altivec_vmulosw : GCCBuiltin<"__builtin_altivec_vmulosw">, + Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], + [IntrNoMem]>; def int_ppc_altivec_vmuloub : GCCBuiltin<"__builtin_altivec_vmuloub">, Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; def int_ppc_altivec_vmulouh : GCCBuiltin<"__builtin_altivec_vmulouh">, Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; + def int_ppc_altivec_vmulouw : GCCBuiltin<"__builtin_altivec_vmulouw">, + Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], + [IntrNoMem]>; // Vector Sum Intructions. def int_ppc_altivec_vsumsws : GCCBuiltin<"__builtin_altivec_vsumsws">, @@ -489,6 +530,7 @@ def int_ppc_altivec_vsraw : PowerPC_Vec_WWW_Intrinsic<"vsraw">; def int_ppc_altivec_vrlb : PowerPC_Vec_BBB_Intrinsic<"vrlb">; def int_ppc_altivec_vrlh : PowerPC_Vec_HHH_Intrinsic<"vrlh">; def int_ppc_altivec_vrlw : PowerPC_Vec_WWW_Intrinsic<"vrlw">; +def int_ppc_altivec_vrld : PowerPC_Vec_DDD_Intrinsic<"vrld">; let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.". // Miscellaneous. @@ -510,6 +552,41 @@ def int_ppc_altivec_vlogefp : PowerPC_Vec_FF_Intrinsic<"vlogefp">; def int_ppc_altivec_vrefp : PowerPC_Vec_FF_Intrinsic<"vrefp">; def int_ppc_altivec_vrsqrtefp : PowerPC_Vec_FF_Intrinsic<"vrsqrtefp">; +// Power8 Intrinsics +// Crypto +let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.". + def int_ppc_altivec_crypto_vsbox : + GCCBuiltin<"__builtin_altivec_crypto_vsbox">, + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>; + def int_ppc_altivec_crypto_vpermxor : + GCCBuiltin<"__builtin_altivec_crypto_vpermxor">, + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, + llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; + +// These need diagnostics for invalid arguments so don't inherit from GCCBuiltin +def int_ppc_altivec_crypto_vshasigmad : + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, + llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_ppc_altivec_crypto_vshasigmaw : + Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, + llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +} +def int_ppc_altivec_crypto_vcipher : + PowerPC_Vec_DDD_Intrinsic<"crypto_vcipher">; +def int_ppc_altivec_crypto_vcipherlast : + PowerPC_Vec_DDD_Intrinsic<"crypto_vcipherlast">; +def int_ppc_altivec_crypto_vncipher : + PowerPC_Vec_DDD_Intrinsic<"crypto_vncipher">; +def int_ppc_altivec_crypto_vncipherlast : + PowerPC_Vec_DDD_Intrinsic<"crypto_vncipherlast">; +def int_ppc_altivec_crypto_vpmsumb : + PowerPC_Vec_BBB_Intrinsic<"crypto_vpmsumb">; +def int_ppc_altivec_crypto_vpmsumh : + PowerPC_Vec_HHH_Intrinsic<"crypto_vpmsumh">; +def int_ppc_altivec_crypto_vpmsumw : + PowerPC_Vec_WWW_Intrinsic<"crypto_vpmsumw">; +def int_ppc_altivec_crypto_vpmsumd : + PowerPC_Vec_DDD_Intrinsic<"crypto_vpmsumd">; //===----------------------------------------------------------------------===// // PowerPC VSX Intrinsic Definitions. @@ -719,3 +796,62 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". [llvm_v4f64_ty], [llvm_i32_ty], [IntrNoMem]>; } +//===----------------------------------------------------------------------===// +// PowerPC HTM Intrinsic Definitions. + +let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". + +def int_ppc_tbegin : + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; +def int_ppc_tend : + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; + +def int_ppc_tabort : GCCBuiltin<"__builtin_tabort">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; +def int_ppc_tabortwc : + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; +def int_ppc_tabortwci : + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; +def int_ppc_tabortdc : + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; +def int_ppc_tabortdci : + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + +def int_ppc_tcheck : GCCBuiltin<"__builtin_tcheck">, + Intrinsic<[llvm_i32_ty], [], []>; +def int_ppc_treclaim : GCCBuiltin<"__builtin_treclaim">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; +def int_ppc_trechkpt : GCCBuiltin<"__builtin_trechkpt">, + Intrinsic<[llvm_i32_ty], [], []>; +def int_ppc_tsr : + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; + +def int_ppc_get_texasr : GCCBuiltin<"__builtin_get_texasr">, + Intrinsic<[llvm_i64_ty], [], []>; +def int_ppc_get_texasru : GCCBuiltin<"__builtin_get_texasru">, + Intrinsic<[llvm_i64_ty], [], []>; +def int_ppc_get_tfhar : GCCBuiltin<"__builtin_get_tfhar">, + Intrinsic<[llvm_i64_ty], [], []>; +def int_ppc_get_tfiar : GCCBuiltin<"__builtin_get_tfiar">, + Intrinsic<[llvm_i64_ty], [], []>; + +def int_ppc_set_texasr : GCCBuiltin<"__builtin_set_texasr">, + Intrinsic<[], [llvm_i64_ty], []>; +def int_ppc_set_texasru : GCCBuiltin<"__builtin_set_texasru">, + Intrinsic<[], [llvm_i64_ty], []>; +def int_ppc_set_tfhar : GCCBuiltin<"__builtin_set_tfhar">, + Intrinsic<[], [llvm_i64_ty], []>; +def int_ppc_set_tfiar : GCCBuiltin<"__builtin_set_tfiar">, + Intrinsic<[], [llvm_i64_ty], []>; + +// Extended mnemonics +def int_ppc_tendall : GCCBuiltin<"__builtin_tendall">, + Intrinsic<[llvm_i32_ty], [], []>; +def int_ppc_tresume : GCCBuiltin<"__builtin_tresume">, + Intrinsic<[llvm_i32_ty], [], []>; +def int_ppc_tsuspend : GCCBuiltin<"__builtin_tsuspend">, + Intrinsic<[llvm_i32_ty], [], []>; + +def int_ppc_ttest : GCCBuiltin<"__builtin_ttest">, + Intrinsic<[llvm_i64_ty], [], []>; +} diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td index 60deb32..39b8e3b 100644 --- a/include/llvm/IR/IntrinsicsX86.td +++ b/include/llvm/IR/IntrinsicsX86.td @@ -882,15 +882,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse41_pblendvb : GCCBuiltin<"__builtin_ia32_pblendvb128">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,llvm_v16i8_ty], [IntrNoMem]>; - def int_x86_sse41_pblendw : GCCBuiltin<"__builtin_ia32_pblendw128">, - Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_sse41_blendpd : GCCBuiltin<"__builtin_ia32_blendpd">, - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_sse41_blendps : GCCBuiltin<"__builtin_ia32_blendps">, - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrNoMem]>; def int_x86_sse41_blendvpd : GCCBuiltin<"__builtin_ia32_blendvpd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,llvm_v2f64_ty], [IntrNoMem]>; @@ -1156,12 +1147,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Vector blend let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_avx_blend_pd_256 : GCCBuiltin<"__builtin_ia32_blendpd256">, - Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, - llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_blend_ps_256 : GCCBuiltin<"__builtin_ia32_blendps256">, - Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, - llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; def int_x86_avx_blendv_pd_256 : GCCBuiltin<"__builtin_ia32_blendvpd256">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; @@ -1187,32 +1172,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; } -// Vector extract and insert -let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_avx_vextractf128_pd_256 : - GCCBuiltin<"__builtin_ia32_vextractf128_pd256">, - Intrinsic<[llvm_v2f64_ty], [llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_vextractf128_ps_256 : - GCCBuiltin<"__builtin_ia32_vextractf128_ps256">, - Intrinsic<[llvm_v4f32_ty], [llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_vextractf128_si_256 : - GCCBuiltin<"__builtin_ia32_vextractf128_si256">, - Intrinsic<[llvm_v4i32_ty], [llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx_vinsertf128_pd_256 : - GCCBuiltin<"__builtin_ia32_vinsertf128_pd256">, - Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, - llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_vinsertf128_ps_256 : - GCCBuiltin<"__builtin_ia32_vinsertf128_ps256">, - Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, - llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_vinsertf128_si_256 : - GCCBuiltin<"__builtin_ia32_vinsertf128_si256">, - Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, - llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; -} - // Vector convert let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx_cvtdq2_pd_256 : GCCBuiltin<"__builtin_ia32_cvtdq2pd256">, @@ -1734,15 +1693,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx2_pblendvb : GCCBuiltin<"__builtin_ia32_pblendvb256">, Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; - def int_x86_avx2_pblendw : GCCBuiltin<"__builtin_ia32_pblendw256">, - Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx2_pblendd_128 : GCCBuiltin<"__builtin_ia32_pblendd128">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx2_pblendd_256 : GCCBuiltin<"__builtin_ia32_pblendd256">, - Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, - llvm_i8_ty], [IntrNoMem]>; } // Vector load with broadcast @@ -1756,8 +1706,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx2_vbroadcast_ss_ps_256 : GCCBuiltin<"__builtin_ia32_vbroadcastss_ps256">, Intrinsic<[llvm_v8f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; - def int_x86_avx2_vbroadcasti128 : - Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty], [IntrReadArgMem]>; def int_x86_avx2_pbroadcastb_128 : GCCBuiltin<"__builtin_ia32_pbroadcastb128">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>; @@ -1811,13 +1759,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Vector extract and insert let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_avx2_vextracti128 : GCCBuiltin<"__builtin_ia32_extract128i256">, - Intrinsic<[llvm_v2i64_ty], [llvm_v4i64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx2_vinserti128 : GCCBuiltin<"__builtin_ia32_insert128i256">, - Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, - llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vextractf32x4_512 : GCCBuiltin<"__builtin_ia32_extractf32x4_mask">, Intrinsic<[llvm_v4f32_ty], [llvm_v16f32_ty, llvm_i8_ty, diff --git a/include/llvm/IR/Metadata.def b/include/llvm/IR/Metadata.def index 66589e0..0eb29bc 100644 --- a/include/llvm/IR/Metadata.def +++ b/include/llvm/IR/Metadata.def @@ -61,6 +61,7 @@ HANDLE_METADATA_LEAF(LocalAsMetadata) HANDLE_MDNODE_BRANCH(MDNode) HANDLE_MDNODE_LEAF(MDTuple) HANDLE_SPECIALIZED_MDNODE_LEAF(MDLocation) +HANDLE_SPECIALIZED_MDNODE_LEAF(MDExpression) HANDLE_SPECIALIZED_MDNODE_BRANCH(DebugNode) HANDLE_SPECIALIZED_MDNODE_LEAF(GenericDebugNode) HANDLE_SPECIALIZED_MDNODE_LEAF(MDSubrange) @@ -75,6 +76,7 @@ HANDLE_SPECIALIZED_MDNODE_LEAF(MDCompositeType) HANDLE_SPECIALIZED_MDNODE_LEAF(MDSubroutineType) HANDLE_SPECIALIZED_MDNODE_LEAF(MDFile) HANDLE_SPECIALIZED_MDNODE_LEAF(MDCompileUnit) +HANDLE_SPECIALIZED_MDNODE_BRANCH(MDLocalScope) HANDLE_SPECIALIZED_MDNODE_LEAF(MDSubprogram) HANDLE_SPECIALIZED_MDNODE_BRANCH(MDLexicalBlockBase) HANDLE_SPECIALIZED_MDNODE_LEAF(MDLexicalBlock) @@ -86,7 +88,6 @@ HANDLE_SPECIALIZED_MDNODE_LEAF(MDTemplateValueParameter) HANDLE_SPECIALIZED_MDNODE_BRANCH(MDVariable) HANDLE_SPECIALIZED_MDNODE_LEAF(MDGlobalVariable) HANDLE_SPECIALIZED_MDNODE_LEAF(MDLocalVariable) -HANDLE_SPECIALIZED_MDNODE_LEAF(MDExpression) HANDLE_SPECIALIZED_MDNODE_LEAF(MDObjCProperty) HANDLE_SPECIALIZED_MDNODE_LEAF(MDImportedEntity) diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index ff8f837..a31bdbf 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -32,9 +32,8 @@ class Module; template<typename ValueSubClass, typename ItemParentClass> class SymbolTableListTraits; - enum LLVMConstants : uint32_t { - DEBUG_METADATA_VERSION = 2 // Current debug info version number. + DEBUG_METADATA_VERSION = 3 // Current debug info version number. }; /// \brief Root of the metadata hierarchy. @@ -104,15 +103,48 @@ public: unsigned getMetadataID() const { return SubclassID; } /// \brief User-friendly dump. + /// + /// If \c M is provided, metadata nodes will be numbered canonically; + /// otherwise, pointer addresses are substituted. + /// + /// Note: this uses an explicit overload instead of default arguments so that + /// the nullptr version is easy to call from a debugger. + /// + /// @{ void dump() const; - void print(raw_ostream &OS) const; - void printAsOperand(raw_ostream &OS, bool PrintType = true, - const Module *M = nullptr) const; + void dump(const Module *M) const; + /// @} + + /// \brief Print. + /// + /// Prints definition of \c this. + /// + /// If \c M is provided, metadata nodes will be numbered canonically; + /// otherwise, pointer addresses are substituted. + void print(raw_ostream &OS, const Module *M = nullptr) const; + + /// \brief Print as operand. + /// + /// Prints reference of \c this. + /// + /// If \c M is provided, metadata nodes will be numbered canonically; + /// otherwise, pointer addresses are substituted. + void printAsOperand(raw_ostream &OS, const Module *M = nullptr) const; }; #define HANDLE_METADATA(CLASS) class CLASS; #include "llvm/IR/Metadata.def" +// Provide specializations of isa so that we don't need definitions of +// subclasses to see if the metadata is a subclass. +#define HANDLE_METADATA_LEAF(CLASS) \ + template <> struct isa_impl<CLASS, Metadata> { \ + static inline bool doit(const Metadata &MD) { \ + return MD.getMetadataID() == Metadata::CLASS##Kind; \ + } \ + }; +#include "llvm/IR/Metadata.def" + inline raw_ostream &operator<<(raw_ostream &OS, const Metadata &MD) { MD.print(OS); return OS; diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index 62f4194..ac60c8e 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -219,14 +219,7 @@ private: std::string TargetTriple; ///< Platform target triple Module compiled on ///< Format: (arch)(sub)-(vendor)-(sys0-(abi) void *NamedMDSymTab; ///< NamedMDNode names. - - // We need to keep the string because the C API expects us to own the string - // representation. - // Since we have it, we also use an empty string to represent a module without - // a DataLayout. If it has a DataLayout, these variables are in sync and the - // string is just a cache of getDataLayout()->getStringRepresentation(). - std::string DataLayoutStr; - DataLayout DL; + DataLayout DL; ///< DataLayout associated with the module friend class Constant; @@ -256,10 +249,12 @@ public: /// Get the data layout string for the module's target platform. This is /// equivalent to getDataLayout()->getStringRepresentation(). - const std::string &getDataLayoutStr() const { return DataLayoutStr; } + const std::string getDataLayoutStr() const { + return DL.getStringRepresentation(); + } /// Get the data layout for the module's target platform. - const DataLayout *getDataLayout() const; + const DataLayout &getDataLayout() const; /// Get the target triple which is a string describing the target host. /// @returns a string containing the target triple. @@ -293,12 +288,13 @@ public: /// Set the data layout void setDataLayout(StringRef Desc); - void setDataLayout(const DataLayout *Other); + void setDataLayout(const DataLayout &Other); /// Set the target triple. void setTargetTriple(StringRef T) { TargetTriple = T; } /// Set the module-scope inline assembly blocks. + /// A trailing newline is added if the input doesn't have one. void setModuleInlineAsm(StringRef Asm) { GlobalScopeAsm = Asm; if (!GlobalScopeAsm.empty() && @@ -306,8 +302,8 @@ public: GlobalScopeAsm += '\n'; } - /// Append to the module-scope inline assembly blocks, automatically inserting - /// a separating newline if necessary. + /// Append to the module-scope inline assembly blocks. + /// A trailing newline is added if the input doesn't have one. void appendModuleInlineAsm(StringRef Asm) { GlobalScopeAsm += Asm; if (!GlobalScopeAsm.empty() && @@ -506,6 +502,8 @@ public: /// Materializer. std::error_code materializeAllPermanently(); + std::error_code materializeMetadata(); + /// @} /// @name Direct access to the globals list, functions list, and symbol table /// @{ diff --git a/include/llvm/IR/NoFolder.h b/include/llvm/IR/NoFolder.h index a9cdfc3..ab7bed6 100644 --- a/include/llvm/IR/NoFolder.h +++ b/include/llvm/IR/NoFolder.h @@ -189,7 +189,7 @@ public: } Instruction *CreateGetElementPtr(Constant *C, ArrayRef<Value *> IdxList) const { - return GetElementPtrInst::Create(C, IdxList); + return GetElementPtrInst::Create(nullptr, C, IdxList); } Constant *CreateInBoundsGetElementPtr(Constant *C, @@ -204,7 +204,7 @@ public: } Instruction *CreateInBoundsGetElementPtr(Constant *C, ArrayRef<Value *> IdxList) const { - return GetElementPtrInst::CreateInBounds(C, IdxList); + return GetElementPtrInst::CreateInBounds(nullptr, C, IdxList); } //===--------------------------------------------------------------------===// diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h index 46935ce..c87f89c 100644 --- a/include/llvm/IR/Operator.h +++ b/include/llvm/IR/Operator.h @@ -400,6 +400,11 @@ public: return getPointerOperand()->getType(); } + Type *getSourceElementType() const { + return cast<SequentialType>(getPointerOperandType()->getScalarType()) + ->getElementType(); + } + /// Method to return the address space of the pointer operand. unsigned getPointerAddressSpace() const { return getPointerOperandType()->getPointerAddressSpace(); diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index c92e7c9..3c24e72 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -46,6 +46,7 @@ #include "llvm/IR/PassManagerInternal.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Support/type_traits.h" #include <list> #include <memory> @@ -471,6 +472,12 @@ private: dbgs() << "Running analysis: " << P.name() << "\n"; AnalysisResultListT &ResultList = AnalysisResultLists[&IR]; ResultList.emplace_back(PassID, P.run(IR, this)); + + // P.run may have inserted elements into AnalysisResults and invalidated + // RI. + RI = AnalysisResults.find(std::make_pair(PassID, &IR)); + assert(RI != AnalysisResults.end() && "we just inserted it!"); + RI->second = std::prev(ResultList.end()); } diff --git a/include/llvm/IR/PassManagerInternal.h b/include/llvm/IR/PassManagerInternal.h index 297f5f4..92de10b 100644 --- a/include/llvm/IR/PassManagerInternal.h +++ b/include/llvm/IR/PassManagerInternal.h @@ -19,6 +19,7 @@ #define LLVM_IR_PASSMANAGERINTERNAL_H #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/STLExtras.h" namespace llvm { diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index b7213a6..8217ef7 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -450,7 +450,7 @@ public: /// /// Test if this value is always a pointer to allocated and suitably aligned /// memory for a simple load or store. - bool isDereferenceablePointer(const DataLayout *DL = nullptr) const; + bool isDereferenceablePointer(const DataLayout &DL) const; /// \brief Translate PHI node to its predecessor from the given basic block. /// diff --git a/include/llvm/IR/Verifier.h b/include/llvm/IR/Verifier.h index 43bd123..89039d2 100644 --- a/include/llvm/IR/Verifier.h +++ b/include/llvm/IR/Verifier.h @@ -56,20 +56,9 @@ bool verifyModule(const Module &M, raw_ostream *OS = nullptr); /// printed to stderr, and by default they are fatal. You can override that by /// passing \c false to \p FatalErrors. /// -/// Note that this creates a pass suitable for the legacy pass manager. It has nothing to do with \c VerifierPass. -FunctionPass *createVerifierPass(bool FatalErrors = true); - -/// \brief Create a debug-info verifier pass. -/// -/// Check a module for validity of debug info. This is essentially a pass -/// wrapped around the debug-info parts of \a verifyModule(). When the pass -/// detects a verification error it is always printed to stderr, and by default -/// they are fatal. You can override that by passing \c false to \p -/// FatalErrors. -/// /// Note that this creates a pass suitable for the legacy pass manager. It has /// nothing to do with \c VerifierPass. -ModulePass *createDebugInfoVerifierPass(bool FatalErrors = true); +FunctionPass *createVerifierPass(bool FatalErrors = true); class VerifierPass { bool FatalErrors; diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index bcf8cf2..1d428b0 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -106,7 +106,6 @@ void initializeDAEPass(PassRegistry&); void initializeDAHPass(PassRegistry&); void initializeDCEPass(PassRegistry&); void initializeDSEPass(PassRegistry&); -void initializeDebugInfoVerifierLegacyPassPass(PassRegistry &); void initializeDeadInstEliminationPass(PassRegistry&); void initializeDeadMachineInstructionElimPass(PassRegistry&); void initializeDelinearizationPass(PassRegistry &); @@ -150,8 +149,6 @@ void initializeInstCountPass(PassRegistry&); void initializeInstNamerPass(PassRegistry&); void initializeInternalizePassPass(PassRegistry&); void initializeIntervalPartitionPass(PassRegistry&); -void initializeJumpInstrTableInfoPass(PassRegistry&); -void initializeJumpInstrTablesPass(PassRegistry&); void initializeJumpThreadingPass(PassRegistry&); void initializeLCSSAPass(PassRegistry&); void initializeLICMPass(PassRegistry&); @@ -168,6 +165,7 @@ void initializeLocalStackSlotPassPass(PassRegistry&); void initializeLoopDeletionPass(PassRegistry&); void initializeLoopExtractorPass(PassRegistry&); void initializeLoopInfoWrapperPassPass(PassRegistry&); +void initializeLoopInterchangePass(PassRegistry &); void initializeLoopInstSimplifyPass(PassRegistry&); void initializeLoopRotatePass(PassRegistry&); void initializeLoopSimplifyPass(PassRegistry&); diff --git a/include/llvm/LTO/LTOCodeGenerator.h b/include/llvm/LTO/LTOCodeGenerator.h index 56d27ca..820d6d5 100644 --- a/include/llvm/LTO/LTOCodeGenerator.h +++ b/include/llvm/LTO/LTOCodeGenerator.h @@ -76,6 +76,7 @@ struct LTOCodeGenerator { void setCpu(const char *mCpu) { MCpu = mCpu; } void setAttr(const char *mAttr) { MAttr = mAttr; } + void setOptLevel(unsigned optLevel) { OptLevel = optLevel; } void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; } @@ -102,7 +103,6 @@ struct LTOCodeGenerator { // Do not try to remove the object file in LTOCodeGenerator's destructor // as we don't who (LTOCodeGenerator or the obj file) will last longer. bool compile_to_file(const char **name, - bool disableOpt, bool disableInline, bool disableGVNLoadPRE, bool disableVectorization, @@ -114,15 +114,13 @@ struct LTOCodeGenerator { // caller. This function should delete intermediate object file once its content // is brought to memory. Return NULL if the compilation was not successful. const void *compile(size_t *length, - bool disableOpt, bool disableInline, bool disableGVNLoadPRE, bool disableVectorization, std::string &errMsg); // Optimizes the merged module. Returns true on success. - bool optimize(bool disableOpt, - bool disableInline, + bool optimize(bool disableInline, bool disableGVNLoadPRE, bool disableVectorization, std::string &errMsg); @@ -171,6 +169,7 @@ private: std::string MAttr; std::string NativeObjectPath; TargetOptions Options; + unsigned OptLevel; lto_diagnostic_handler_t DiagHandler; void *DiagContext; LTOModule *OwnedModule; diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 18343e2..391267c 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -91,12 +91,11 @@ namespace { (void) llvm::createIndVarSimplifyPass(); (void) llvm::createInstructionCombiningPass(); (void) llvm::createInternalizePass(); - (void) llvm::createJumpInstrTableInfoPass(); - (void) llvm::createJumpInstrTablesPass(); (void) llvm::createLCSSAPass(); (void) llvm::createLICMPass(); (void) llvm::createLazyValueInfoPass(); (void) llvm::createLoopExtractorPass(); + (void)llvm::createLoopInterchangePass(); (void) llvm::createLoopSimplifyPass(); (void) llvm::createLoopStrengthReducePass(); (void) llvm::createLoopRerollPass(); diff --git a/include/llvm/Linker/Linker.h b/include/llvm/Linker/Linker.h index aac9dcd..5ca815c 100644 --- a/include/llvm/Linker/Linker.h +++ b/include/llvm/Linker/Linker.h @@ -54,6 +54,7 @@ public: NonOpaqueStructTypeSet NonOpaqueStructTypes; void addNonOpaque(StructType *Ty); + void switchToNonOpaque(StructType *Ty); void addOpaque(StructType *Ty); StructType *findNonOpaque(ArrayRef<Type *> ETypes, bool IsPacked); bool hasType(StructType *Ty); diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index ee245e9..658d77c 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -118,6 +118,9 @@ protected: // Print the EH begin symbol with an assignment. Defaults to false. bool UseAssignmentForEHBegin; + // Do we need to create a local symbol for .size? + bool NeedsLocalForSize; + /// This prefix is used for globals like constant pool entries that are /// completely private to the .s file and should not have names in the .o /// file. Defaults to "L" @@ -253,6 +256,10 @@ protected: /// argument and how it is interpreted. Defaults to NoAlignment. LCOMM::LCOMMType LCOMMDirectiveAlignmentType; + // True if the target allows .align directives on funtions. This is true for + // most targets, so defaults to true. + bool HasFunctionAlignment; + /// True if the target has .type and .size directives, this is true for most /// ELF targets. Defaults to true. bool HasDotTypeDotSizeDirective; @@ -427,6 +434,7 @@ public: const char *getLabelSuffix() const { return LabelSuffix; } bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; } + bool needsLocalForSize() const { return NeedsLocalForSize; } const char *getPrivateGlobalPrefix() const { return PrivateGlobalPrefix; } const char *getPrivateLabelPrefix() const { return PrivateLabelPrefix; } bool hasLinkerPrivateGlobalPrefix() const { @@ -463,6 +471,7 @@ public: LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const { return LCOMMDirectiveAlignmentType; } + bool hasFunctionAlignment() const { return HasFunctionAlignment; } bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; } bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } bool hasIdentDirective() const { return HasIdentDirective; } diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index f048e34..4d1590a 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -56,7 +56,7 @@ private: uint64_t FOffset, uint64_t FSize); public: - MCAsmLayout(MCAssembler &_Assembler); + MCAsmLayout(MCAssembler &Assembler); /// Get the assembler object this is a layout for. MCAssembler &getAssembler() const { return Assembler; } diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 8c56f88..9a85293 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -88,7 +88,7 @@ private: /// @} protected: - MCFragment(FragmentType _Kind, MCSectionData *_Parent = nullptr); + MCFragment(FragmentType Kind, MCSectionData *Parent = nullptr); public: // Only for sentinel. @@ -307,11 +307,9 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups { SmallVector<MCFixup, 1> Fixups; public: - MCRelaxableFragment(const MCInst &_Inst, - const MCSubtargetInfo &_STI, + MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI, MCSectionData *SD = nullptr) - : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) { - } + : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(Inst), STI(STI) {} SmallVectorImpl<char> &getContents() override { return Contents; } const SmallVectorImpl<char> &getContents() const override { return Contents; } @@ -364,11 +362,10 @@ class MCAlignFragment : public MCFragment { bool EmitNops : 1; public: - MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize, - unsigned _MaxBytesToEmit, MCSectionData *SD = nullptr) - : MCFragment(FT_Align, SD), Alignment(_Alignment), - Value(_Value),ValueSize(_ValueSize), - MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {} + MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize, + unsigned MaxBytesToEmit, MCSectionData *SD = nullptr) + : MCFragment(FT_Align, SD), Alignment(Alignment), Value(Value), + ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit), EmitNops(false) {} /// @name Accessors /// @{ @@ -405,10 +402,10 @@ class MCFillFragment : public MCFragment { uint64_t Size; public: - MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size, + MCFillFragment(int64_t Value, unsigned ValueSize, uint64_t Size, MCSectionData *SD = nullptr) - : MCFragment(FT_Fill, SD), - Value(_Value), ValueSize(_ValueSize), Size(_Size) { + : MCFragment(FT_Fill, SD), Value(Value), ValueSize(ValueSize), + Size(Size) { assert((!ValueSize || (Size % ValueSize) == 0) && "Fill size must be a multiple of the value size!"); } @@ -439,10 +436,8 @@ class MCOrgFragment : public MCFragment { int8_t Value; public: - MCOrgFragment(const MCExpr &_Offset, int8_t _Value, - MCSectionData *SD = nullptr) - : MCFragment(FT_Org, SD), - Offset(&_Offset), Value(_Value) {} + MCOrgFragment(const MCExpr &Offset, int8_t Value, MCSectionData *SD = nullptr) + : MCFragment(FT_Org, SD), Offset(&Offset), Value(Value) {} /// @name Accessors /// @{ @@ -505,10 +500,11 @@ class MCDwarfLineAddrFragment : public MCFragment { SmallString<8> Contents; public: - MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta, - MCSectionData *SD = nullptr) - : MCFragment(FT_Dwarf, SD), - LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); } + MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta, + MCSectionData *SD = nullptr) + : MCFragment(FT_Dwarf, SD), LineDelta(LineDelta), AddrDelta(&AddrDelta) { + Contents.push_back(0); + } /// @name Accessors /// @{ @@ -537,10 +533,10 @@ class MCDwarfCallFrameFragment : public MCFragment { SmallString<8> Contents; public: - MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, - MCSectionData *SD = nullptr) - : MCFragment(FT_DwarfFrame, SD), - AddrDelta(&_AddrDelta) { Contents.push_back(0); } + MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSectionData *SD = nullptr) + : MCFragment(FT_DwarfFrame, SD), AddrDelta(&AddrDelta) { + Contents.push_back(0); + } /// @name Accessors /// @{ @@ -722,7 +718,7 @@ class MCSymbolData : public ilist_node<MCSymbolData> { public: // Only for use as sentinel. MCSymbolData(); - MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset, + MCSymbolData(const MCSymbol &Symbol, MCFragment *Fragment, uint64_t Offset, MCAssembler *A = nullptr); /// @name Accessors diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index cd96dfd..064f471 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -15,8 +15,8 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/Twine.h" #include "llvm/MC/MCDwarf.h" -#include "llvm/MC/MCStreamer.h" #include "llvm/MC/SectionKind.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" @@ -37,14 +37,12 @@ namespace llvm { class MCRegisterInfo; class MCLineSection; class SMLoc; - class StringRef; - class Twine; class MCSectionMachO; class MCSectionELF; class MCSectionCOFF; - /// MCContext - Context object for machine code objects. This class owns all - /// of the sections that it creates. + /// Context object for machine code objects. This class owns all of the + /// sections that it creates. /// class MCContext { MCContext(const MCContext&) = delete; @@ -64,13 +62,13 @@ namespace llvm { /// The MCObjectFileInfo for this target. const MCObjectFileInfo *MOFI; - /// Allocator - Allocator object used for creating machine code objects. + /// Allocator object used for creating machine code objects. /// /// We use a bump pointer allocator to avoid the need to track all allocated /// objects. BumpPtrAllocator Allocator; - /// Symbols - Bindings of names to symbols. + /// Bindings of names to symbols. SymbolTable Symbols; /// ELF sections can have a corresponding symbol. This maps one to the @@ -85,13 +83,13 @@ namespace llvm { /// We have three labels represented by the pairs (1, 0), (2, 0) and (1, 1) DenseMap<std::pair<unsigned, unsigned>, MCSymbol*> LocalSymbols; - /// UsedNames - Keeps tracks of names that were used both for used declared - /// and artificial symbols. + /// Keeps tracks of names that were used both for used declared and + /// artificial symbols. StringMap<bool, BumpPtrAllocator&> UsedNames; - /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary - /// symbol. - unsigned NextUniqueID; + /// The next ID to dole out to an unnamed assembler temporary symbol with + /// a given prefix. + StringMap<unsigned> NextID; /// Instances of directional local labels. DenseMap<unsigned, MCLabel *> Instances; @@ -174,7 +172,7 @@ namespace llvm { /// Do automatic reset in destructor bool AutoReset; - MCSymbol *CreateSymbol(StringRef Name); + MCSymbol *CreateSymbol(StringRef Name, bool AlwaysAddSuffix); MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, unsigned Instance); @@ -207,17 +205,15 @@ namespace llvm { /// @name Symbol Management /// @{ - /// CreateLinkerPrivateTempSymbol - Create and return a new linker temporary - /// symbol with a unique but unspecified name. + /// Create and return a new linker temporary symbol with a unique but + /// unspecified name. MCSymbol *CreateLinkerPrivateTempSymbol(); - /// CreateTempSymbol - Create and return a new assembler temporary symbol - /// with a unique but unspecified name. + /// Create and return a new assembler temporary symbol with a unique but + /// unspecified name. MCSymbol *CreateTempSymbol(); - /// getUniqueSymbolID() - Return a unique identifier for use in constructing - /// symbol names. - unsigned getUniqueSymbolID() { return NextUniqueID++; } + MCSymbol *createTempSymbol(const Twine &Name, bool AlwaysAddSuffix); /// Create the definition of a directional local symbol for numbered label /// (used for "1:" definitions). @@ -227,20 +223,17 @@ namespace llvm { /// for "1b" or 1f" references). MCSymbol *GetDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before); - /// GetOrCreateSymbol - Lookup the symbol inside with the specified - /// @p Name. If it exists, return it. If not, create a forward - /// reference and return it. + /// Lookup the symbol inside with the specified @p Name. If it exists, + /// return it. If not, create a forward reference and return it. /// /// @param Name - The symbol name, which must be unique across all symbols. - MCSymbol *GetOrCreateSymbol(StringRef Name); MCSymbol *GetOrCreateSymbol(const Twine &Name); MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section); - MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName); + MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx); - /// LookupSymbol - Get the symbol for \p Name, or null. - MCSymbol *LookupSymbol(StringRef Name) const; + /// Get the symbol for \p Name, or null. MCSymbol *LookupSymbol(const Twine &Name) const; /// getSymbols - Get a reference for the symbol table for clients that @@ -256,30 +249,34 @@ namespace llvm { /// @name Section Management /// @{ - /// getMachOSection - Return the MCSection for the specified mach-o section. - /// This requires the operands to be valid. - const MCSectionMachO *getMachOSection(StringRef Segment, - StringRef Section, + /// Return the MCSection for the specified mach-o section. This requires + /// the operands to be valid. + const MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section, unsigned TypeAndAttributes, - unsigned Reserved2, - SectionKind K); - const MCSectionMachO *getMachOSection(StringRef Segment, - StringRef Section, + unsigned Reserved2, SectionKind K, + const char *BeginSymName = nullptr); + + const MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section, unsigned TypeAndAttributes, - SectionKind K) { - return getMachOSection(Segment, Section, TypeAndAttributes, 0, K); + SectionKind K, + const char *BeginSymName = nullptr) { + return getMachOSection(Segment, Section, TypeAndAttributes, 0, K, + BeginSymName); } const MCSectionELF *getELFSection(StringRef Section, unsigned Type, - unsigned Flags); + unsigned Flags, + const char *BeginSymName = nullptr); const MCSectionELF *getELFSection(StringRef Section, unsigned Type, unsigned Flags, unsigned EntrySize, - StringRef Group); + StringRef Group, + const char *BeginSymName = nullptr); const MCSectionELF *getELFSection(StringRef Section, unsigned Type, unsigned Flags, unsigned EntrySize, - StringRef Group, bool Unique); + StringRef Group, bool Unique, + const char *BeginSymName = nullptr); void renameELFSection(const MCSectionELF *Section, StringRef Name); @@ -288,11 +285,13 @@ namespace llvm { const MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, SectionKind Kind, - StringRef COMDATSymName, int Selection); + StringRef COMDATSymName, int Selection, + const char *BeginSymName = nullptr); const MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, - SectionKind Kind); + SectionKind Kind, + const char *BeginSymName = nullptr); const MCSectionCOFF *getCOFFSection(StringRef Section); @@ -327,7 +326,7 @@ namespace llvm { /// \brief Set the main file name and override the default. void setMainFileName(StringRef S) { MainFileName = S; } - /// GetDwarfFile - creates an entry in the dwarf file and directory tables. + /// Creates an entry in the dwarf file and directory tables. unsigned GetDwarfFile(StringRef Directory, StringRef FileName, unsigned FileNumber, unsigned CUID); @@ -370,10 +369,10 @@ namespace llvm { getMCDwarfLineTable(CUID).setCompilationDir(CompilationDir); } - /// setCurrentDwarfLoc - saves the information from the currently parsed - /// dwarf .loc directive and sets DwarfLocSeen. When the next instruction - /// is assembled an entry in the line number table with this information and - /// the address of the instruction will be created. + /// Saves the information from the currently parsed dwarf .loc directive + /// and sets DwarfLocSeen. When the next instruction is assembled an entry + /// in the line number table with this information and the address of the + /// instruction will be created. void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator) { diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index 9763635..7493507 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -41,6 +41,8 @@ protected: public: static uint8_t getOSABI(Triple::OSType OSType) { switch (OSType) { + case Triple::CloudABI: + return ELF::ELFOSABI_CLOUDABI; case Triple::PS4: case Triple::FreeBSD: return ELF::ELFOSABI_FREEBSD; diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 5e2ef3f..d5a68be 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -56,13 +56,12 @@ private: const SectionAddrMap *Addrs, bool InSet) const; protected: - explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {} + explicit MCExpr(ExprKind Kind) : Kind(Kind) {} bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, const MCFixup *Fixup, - const SectionAddrMap *Addrs, bool InSet, - bool ForceVarExpansion) const; + const SectionAddrMap *Addrs, bool InSet) const; public: /// @name Accessors @@ -94,7 +93,7 @@ public: bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; - int64_t evaluateKnownAbsolute(const MCAsmLayout &Layout) const; + bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable /// value, i.e. an expression of the fixed form (a - b + constant). @@ -110,10 +109,8 @@ public: /// neither a nor b are variables. /// /// This is a more aggressive variant of EvaluateAsRelocatable. The intended - /// use is for when relocations are not available, like the symbol value in - /// the symbol table. - bool EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout, - const MCFixup *Fixup) const; + /// use is for when relocations are not available, like the .size directive. + bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const; /// FindAssociatedSection - Find the "associated section" for this expression, /// which is currently defined as the absolute section for constants, or @@ -133,8 +130,8 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { class MCConstantExpr : public MCExpr { int64_t Value; - explicit MCConstantExpr(int64_t _Value) - : MCExpr(MCExpr::Constant), Value(_Value) {} + explicit MCConstantExpr(int64_t Value) + : MCExpr(MCExpr::Constant), Value(Value) {} public: /// @name Construction @@ -188,6 +185,7 @@ public: VK_GOTPAGE, VK_GOTPAGEOFF, VK_SECREL, + VK_SIZE, // symbol@SIZE VK_WEAKREF, // The link between the symbols in .weakref foo, bar VK_ARM_NONE, @@ -353,8 +351,8 @@ private: Opcode Op; const MCExpr *Expr; - MCUnaryExpr(Opcode _Op, const MCExpr *_Expr) - : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {} + MCUnaryExpr(Opcode Op, const MCExpr *Expr) + : MCExpr(MCExpr::Unary), Op(Op), Expr(Expr) {} public: /// @name Construction @@ -424,8 +422,8 @@ private: Opcode Op; const MCExpr *LHS, *RHS; - MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS) - : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {} + MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS) + : MCExpr(MCExpr::Binary), Op(Op), LHS(LHS), RHS(RHS) {} public: /// @name Construction diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index e4681c0..514700b 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -119,10 +119,9 @@ class MachObjectWriter : public MCObjectWriter { MachSymbolData *findSymbolData(const MCSymbol &Sym); public: - MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS, - bool _IsLittleEndian) - : MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) { - } + MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &OS, + bool IsLittleEndian) + : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {} /// @name Lifetime management Methods /// @{ diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index 321043c..025a76a 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -99,7 +99,6 @@ protected: const MCSection *DwarfLocSection; const MCSection *DwarfARangesSection; const MCSection *DwarfRangesSection; - const MCSection *DwarfMacroInfoSection; // The pubnames section is no longer generated by default. The generation // can be enabled by a compiler flag. const MCSection *DwarfPubNamesSection; @@ -241,9 +240,6 @@ public: const MCSection *getDwarfLocSection() const { return DwarfLocSection; } const MCSection *getDwarfARangesSection() const { return DwarfARangesSection;} const MCSection *getDwarfRangesSection() const { return DwarfRangesSection; } - const MCSection *getDwarfMacroInfoSection() const { - return DwarfMacroInfoSection; - } // DWARF5 Experimental Debug Info Sections const MCSection *getDwarfAccelNamesSection() const { diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 0866ff5..2420072 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -49,10 +49,10 @@ class MCObjectStreamer : public MCStreamer { void flushPendingLabels(MCFragment *F); protected: - MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, - MCCodeEmitter *_Emitter); - MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, - MCCodeEmitter *_Emitter, MCAssembler *_Assembler); + MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter); + MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter, MCAssembler *Assembler); ~MCObjectStreamer(); public: @@ -85,6 +85,8 @@ protected: /// fragment is not a data fragment. MCDataFragment *getOrCreateDataFragment(); + bool changeSectionImpl(const MCSection *Section, const MCExpr *Subsection); + public: void visitUsedSymbol(const MCSymbol &Sym) override; diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 430075c..fcfa968 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -46,8 +46,8 @@ protected: unsigned IsLittleEndian : 1; protected: // Can only create subclasses. - MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian) - : OS(_OS), IsLittleEndian(_IsLittleEndian) {} + MCObjectWriter(raw_ostream &OS, bool IsLittleEndian) + : OS(OS), IsLittleEndian(IsLittleEndian) {} public: virtual ~MCObjectWriter(); @@ -86,11 +86,10 @@ public: /// /// Clients are not required to answer precisely and may conservatively return /// false, even when a difference is fully resolved. - bool - IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, - const MCSymbolRefExpr *A, - const MCSymbolRefExpr *B, - bool InSet) const; + bool IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, + const MCSymbolRefExpr *A, + const MCSymbolRefExpr *B, + bool InSet) const; virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, @@ -99,6 +98,11 @@ public: bool InSet, bool IsPCRel) const; + /// \brief True if this symbol (which is a variable) is weak. This is not + /// just STB_WEAK, but more generally whether or not we can evaluate + /// past it. + virtual bool isWeak(const MCSymbolData &SD) const; + /// \brief Write the object file. /// /// This routine is called by the assembler after layout and relaxation is diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 14f8ade..71f15b3 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -63,10 +63,10 @@ private: public: AsmToken() {} - AsmToken(TokenKind _Kind, StringRef _Str, APInt _IntVal) - : Kind(_Kind), Str(_Str), IntVal(_IntVal) {} - AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0) - : Kind(_Kind), Str(_Str), IntVal(64, _IntVal, true) {} + AsmToken(TokenKind Kind, StringRef Str, APInt IntVal) + : Kind(Kind), Str(Str), IntVal(IntVal) {} + AsmToken(TokenKind Kind, StringRef Str, int64_t IntVal = 0) + : Kind(Kind), Str(Str), IntVal(64, IntVal, true) {} TokenKind getKind() const { return Kind; } bool is(TokenKind K) const { return Kind == K; } diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 8aec9c8..ab8968e 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -19,60 +19,53 @@ #include "llvm/Support/Compiler.h" namespace llvm { - class MCAsmInfo; - class MCExpr; - class raw_ostream; - - /// MCSection - Instances of this class represent a uniqued identifier for a - /// section in the current translation unit. The MCContext class uniques and - /// creates these. - class MCSection { - public: - enum SectionVariant { - SV_COFF = 0, - SV_ELF, - SV_MachO - }; - - private: - MCSection(const MCSection&) = delete; - void operator=(const MCSection&) = delete; - protected: - MCSection(SectionVariant V, SectionKind K) : Variant(V), Kind(K) {} - SectionVariant Variant; - SectionKind Kind; - public: - virtual ~MCSection(); - - SectionKind getKind() const { return Kind; } - - SectionVariant getVariant() const { return Variant; } - - virtual void PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS, - const MCExpr *Subsection) const = 0; - - // Convenience routines to get label names for the beginning/end of a - // section. - virtual std::string getLabelBeginName() const = 0; - virtual std::string getLabelEndName() const = 0; - - /// isBaseAddressKnownZero - Return true if we know that this section will - /// get a base address of zero. In cases where we know that this is true we - /// can emit section offsets as direct references to avoid a subtraction - /// from the base of the section, saving a relocation. - virtual bool isBaseAddressKnownZero() const { - return false; - } - - // UseCodeAlign - Return true if a .align directive should use - // "optimized nops" to fill instead of 0s. - virtual bool UseCodeAlign() const = 0; - - /// isVirtualSection - Check whether this section is "virtual", that is - /// has no actual object file contents. - virtual bool isVirtualSection() const = 0; - }; +class MCAsmInfo; +class MCContext; +class MCExpr; +class MCSymbol; +class raw_ostream; + +/// Instances of this class represent a uniqued identifier for a section in the +/// current translation unit. The MCContext class uniques and creates these. +class MCSection { +public: + enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO }; + +private: + MCSection(const MCSection &) = delete; + void operator=(const MCSection &) = delete; + + MCSymbol *Begin; + mutable MCSymbol *End; + +protected: + MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin) + : Begin(Begin), End(nullptr), Variant(V), Kind(K) {} + SectionVariant Variant; + SectionKind Kind; + +public: + virtual ~MCSection(); + + SectionKind getKind() const { return Kind; } + + SectionVariant getVariant() const { return Variant; } + + MCSymbol *getBeginSymbol() const { return Begin; } + MCSymbol *getEndSymbol(MCContext &Ctx) const; + bool hasEnded() const; + + virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, + const MCExpr *Subsection) const = 0; + + /// Return true if a .align directive should use "optimized nops" to fill + /// instead of 0s. + virtual bool UseCodeAlign() const = 0; + + /// Check whether this section is "virtual", that is has no actual object + /// file contents. + virtual bool isVirtualSection() const = 0; +}; } // end namespace llvm diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index 0bbf369..b6ec1d8 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -45,8 +45,9 @@ class MCSymbol; private: friend class MCContext; MCSectionCOFF(StringRef Section, unsigned Characteristics, - MCSymbol *COMDATSymbol, int Selection, SectionKind K) - : MCSection(SV_COFF, K), SectionName(Section), + MCSymbol *COMDATSymbol, int Selection, SectionKind K, + MCSymbol *Begin) + : MCSection(SV_COFF, K, Begin), SectionName(Section), Characteristics(Characteristics), COMDATSymbol(COMDATSymbol), Selection(Selection) { assert ((Characteristics & 0x00F00000) == 0 && @@ -60,12 +61,6 @@ class MCSymbol; bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; StringRef getSectionName() const { return SectionName; } - std::string getLabelBeginName() const override { - return SectionName.str() + "_begin"; - } - std::string getLabelEndName() const override { - return SectionName.str() + "_end"; - } unsigned getCharacteristics() const { return Characteristics; } MCSymbol *getCOMDATSymbol() const { return COMDATSymbol; } int getSelection() const { return Selection; } diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 6d864b4..434a5b6 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -51,9 +51,10 @@ class MCSectionELF : public MCSection { private: friend class MCContext; MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K, - unsigned entrySize, const MCSymbol *group, bool Unique) - : MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags), - Unique(Unique), EntrySize(entrySize), Group(group) {} + unsigned entrySize, const MCSymbol *group, bool Unique, + MCSymbol *Begin) + : MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type), + Flags(flags), Unique(Unique), EntrySize(entrySize), Group(group) {} ~MCSectionELF(); void setSectionName(StringRef Name) { SectionName = Name; } @@ -65,16 +66,6 @@ public: bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; StringRef getSectionName() const { return SectionName; } - std::string getLabelBeginName() const override { - if (Group) - return (SectionName.str() + '_' + Group->getName() + "_begin").str(); - return SectionName.str() + "_begin"; - } - std::string getLabelEndName() const override { - if (Group) - return (SectionName.str() + '_' + Group->getName() + "_end").str(); - return SectionName.str() + "_end"; - } unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } unsigned getEntrySize() const { return EntrySize; } @@ -85,12 +76,6 @@ public: bool UseCodeAlign() const override; bool isVirtualSection() const override; - /// isBaseAddressKnownZero - We know that non-allocatable sections (like - /// debug info) have a base of zero. - bool isBaseAddressKnownZero() const override { - return (getFlags() & ELF::SHF_ALLOC) == 0; - } - static bool classof(const MCSection *S) { return S->getVariant() == SV_ELF; } diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index a5a2089..9722751 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -35,8 +35,8 @@ class MCSectionMachO : public MCSection { /// size of stubs, for example. unsigned Reserved2; - MCSectionMachO(StringRef Segment, StringRef Section, - unsigned TAA, unsigned reserved2, SectionKind K); + MCSectionMachO(StringRef Segment, StringRef Section, unsigned TAA, + unsigned reserved2, SectionKind K, MCSymbol *Begin); friend class MCContext; public: @@ -53,14 +53,6 @@ public: return StringRef(SectionName); } - std::string getLabelBeginName() const override { - return StringRef(getSegmentName().str() + getSectionName().str() + "_begin"); - } - - std::string getLabelEndName() const override { - return StringRef(getSegmentName().str() + getSectionName().str() + "_end"); - } - unsigned getTypeAndAttributes() const { return TypeAndAttributes; } unsigned getStubSize() const { return Reserved2; } diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index f0be77f..df7610b 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -344,20 +344,12 @@ public: return true; } - /// SwitchSection - Set the current section where code is being emitted to - /// @p Section. This is required to update CurSection. + /// Set the current section where code is being emitted to @p Section. This + /// is required to update CurSection. /// /// This corresponds to assembler directives like .section, .text, etc. virtual void SwitchSection(const MCSection *Section, - const MCExpr *Subsection = nullptr) { - assert(Section && "Cannot switch to a null section!"); - MCSectionSubPair curSection = SectionStack.back().first; - SectionStack.back().second = curSection; - if (MCSectionSubPair(Section, Subsection) != curSection) { - SectionStack.back().first = MCSectionSubPair(Section, Subsection); - ChangeSection(Section, Subsection); - } - } + const MCExpr *Subsection = nullptr); /// SwitchSectionNoChange - Set the current section where code is being /// emitted to @p Section. This is required to update CurSection. This @@ -374,6 +366,8 @@ public: /// Create the default sections and set the initial one. virtual void InitSections(bool NoExecStack); + MCSymbol *endSection(const MCSection *Section); + /// AssignSection - Sets the symbol's section. /// /// Each emitted symbol will be tracked in the ordering table, @@ -732,13 +726,12 @@ public: virtual bool mayHaveInstructions() const { return true; } }; -/// createNullStreamer - Create a dummy machine code streamer, which does -/// nothing. This is useful for timing the assembler front end. +/// Create a dummy machine code streamer, which does nothing. This is useful for +/// timing the assembler front end. MCStreamer *createNullStreamer(MCContext &Ctx); -/// createAsmStreamer - Create a machine code streamer which will print out -/// assembly for the native target, suitable for compiling with a native -/// assembler. +/// Create a machine code streamer which will print out assembly for the native +/// target, suitable for compiling with a native assembler. /// /// \param InstPrint - If given, the instruction printer to use. If not given /// the MCInst representation will be printed. This method takes ownership of @@ -757,22 +750,6 @@ MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, bool isVerboseAsm, bool useDwarfDirectory, MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst); - -/// createMachOStreamer - Create a machine code streamer which will generate -/// Mach-O format object files. -/// -/// Takes ownership of \p TAB and \p CE. -MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *CE, - bool RelaxAll = false, - bool LabelSections = false); - -/// createELFStreamer - Create a machine code streamer which will generate -/// ELF format object files. -MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *CE, - bool RelaxAll); - } // end namespace llvm #endif diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index 4f8e281..d40dc9d 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -155,9 +155,8 @@ public: Symbol symbol; public: symbol_iterator(const Symbol &s) : symbol(s) {} - const Symbol *operator->() const { - return &symbol; - } + const Symbol *operator->() const { return &symbol; } + const Symbol &operator*() const { return symbol; } bool operator==(const symbol_iterator &other) const { return symbol == other.symbol; @@ -194,6 +193,9 @@ public: symbol_iterator symbol_begin() const; symbol_iterator symbol_end() const; + iterator_range<symbol_iterator> symbols() const { + return iterator_range<symbol_iterator>(symbol_begin(), symbol_end()); + } // Cast methods. static inline bool classof(Binary const *v) { diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 7c10bbf..ddabf59 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -94,18 +94,24 @@ public: return *this; } + ELFEntityIterator &operator+(difference_type n) { + assert(Current && "Attempted to increment an invalid iterator!"); + Current += (n * EntitySize); + return *this; + } + + ELFEntityIterator &operator-(difference_type n) { + assert(Current && "Attempted to subtract an invalid iterator!"); + Current -= (n * EntitySize); + return *this; + } + ELFEntityIterator operator ++(int) { ELFEntityIterator Tmp = *this; ++*this; return Tmp; } - ELFEntityIterator &operator =(const ELFEntityIterator &Other) { - EntitySize = Other.EntitySize; - Current = Other.Current; - return *this; - } - difference_type operator -(const ELFEntityIterator &Other) const { assert(EntitySize == Other.EntitySize && "Subtracting iterators of different EntitySize!"); @@ -203,12 +209,6 @@ public: return *this; } - Elf_Sym_Iter &operator=(const Elf_Sym_Iter &Other) { - EntitySize = Other.EntitySize; - Current = Other.Current; - return *this; - } - difference_type operator-(const Elf_Sym_Iter &Other) const { assert(EntitySize == Other.EntitySize && "Subtracting iterators of different EntitySize!"); diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h index 9a97f7b..5a4e03e 100644 --- a/include/llvm/Object/ELFTypes.h +++ b/include/llvm/Object/ELFTypes.h @@ -189,7 +189,15 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> { } /// Access to the STV_xxx flag stored in the first two bits of st_other. + /// STV_DEFAULT: 0 + /// STV_INTERNAL: 1 + /// STV_HIDDEN: 2 + /// STV_PROTECTED: 3 unsigned char getVisibility() const { return st_other & 0x3; } + void setVisibility(unsigned char v) { + assert(v < 4 && "Invalid value for visibility"); + st_other = (st_other & ~0x3) | v; + } }; /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h index 93f6654..05119b2 100644 --- a/include/llvm/Object/MachOUniversal.h +++ b/include/llvm/Object/MachOUniversal.h @@ -16,6 +16,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Object/Archive.h" #include "llvm/Object/Binary.h" #include "llvm/Object/MachO.h" @@ -69,9 +70,8 @@ public: ObjectForArch Obj; public: object_iterator(const ObjectForArch &Obj) : Obj(Obj) {} - const ObjectForArch* operator->() const { - return &Obj; - } + const ObjectForArch *operator->() const { return &Obj; } + const ObjectForArch &operator*() const { return Obj; } bool operator==(const object_iterator &Other) const { return Obj == Other.Obj; @@ -97,6 +97,10 @@ public: return ObjectForArch(nullptr, 0); } + iterator_range<object_iterator> objects() const { + return make_range(begin_objects(), end_objects()); + } + uint32_t getNumberOfObjects() const { return NumberOfObjects; } // Cast methods. diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h index f7b7cb4..b6a8b4d 100644 --- a/include/llvm/Object/SymbolicFile.h +++ b/include/llvm/Object/SymbolicFile.h @@ -45,7 +45,9 @@ inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) { return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0; } -template <class content_type> class content_iterator { +template <class content_type> +class content_iterator + : public std::iterator<std::forward_iterator_tag, content_type> { content_type Current; public: diff --git a/include/llvm/Option/Arg.h b/include/llvm/Option/Arg.h index 9459a3d..5f6941a 100644 --- a/include/llvm/Option/Arg.h +++ b/include/llvm/Option/Arg.h @@ -78,9 +78,7 @@ public: const Arg &getBaseArg() const { return BaseArg ? *BaseArg : *this; } - void setBaseArg(const Arg *_BaseArg) { - BaseArg = _BaseArg; - } + void setBaseArg(const Arg *BaseArg) { this->BaseArg = BaseArg; } bool getOwnsValues() const { return OwnsValues; } void setOwnsValues(bool Value) const { OwnsValues = Value; } diff --git a/include/llvm/Option/ArgList.h b/include/llvm/Option/ArgList.h index f5ded94..9a09309 100644 --- a/include/llvm/Option/ArgList.h +++ b/include/llvm/Option/ArgList.h @@ -11,7 +11,9 @@ #define LLVM_OPTION_ARGLIST_H #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" #include "llvm/Option/OptSpecifier.h" #include "llvm/Option/Option.h" #include <list> @@ -52,10 +54,10 @@ public: typedef std::forward_iterator_tag iterator_category; typedef std::ptrdiff_t difference_type; - arg_iterator(SmallVectorImpl<Arg*>::const_iterator it, - const ArgList &_Args, OptSpecifier _Id0 = 0U, - OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U) - : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) { + arg_iterator(SmallVectorImpl<Arg *>::const_iterator it, const ArgList &Args, + OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U, + OptSpecifier Id2 = 0U) + : Current(it), Args(Args), Id0(Id0), Id1(Id1), Id2(Id2) { SkipToNextArg(); } @@ -188,6 +190,10 @@ public: /// \p Claim Whether the argument should be claimed, if it exists. Arg *getLastArgNoClaim(OptSpecifier Id) const; Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1) const; + Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1, + OptSpecifier Id2) const; + Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, + OptSpecifier Id3) const; Arg *getLastArg(OptSpecifier Id) const; Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const; Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const; @@ -277,16 +283,13 @@ public: /// @name Arg Synthesis /// @{ - /// MakeArgString - Construct a constant string pointer whose + /// Construct a constant string pointer whose /// lifetime will match that of the ArgList. - virtual const char *MakeArgString(StringRef Str) const = 0; - const char *MakeArgString(const char *Str) const { - return MakeArgString(StringRef(Str)); + virtual const char *MakeArgStringRef(StringRef Str) const = 0; + const char *MakeArgString(const Twine &Str) const { + SmallString<256> Buf; + return MakeArgStringRef(Str.toStringRef(Buf)); } - const char *MakeArgString(std::string Str) const { - return MakeArgString(StringRef(Str)); - } - const char *MakeArgString(const Twine &Str) const; /// \brief Create an arg string for (\p LHS + \p RHS), reusing the /// string at \p Index if possible. @@ -336,7 +339,7 @@ public: unsigned MakeIndex(StringRef String0, StringRef String1) const; using ArgList::MakeArgString; - const char *MakeArgString(StringRef Str) const override; + const char *MakeArgStringRef(StringRef Str) const override; /// @} }; @@ -374,7 +377,7 @@ public: void AddSynthesizedArg(Arg *A); using ArgList::MakeArgString; - const char *MakeArgString(StringRef Str) const override; + const char *MakeArgStringRef(StringRef Str) const override; /// AddFlagArg - Construct a new FlagArg for the given option \p Id and /// append it to the argument list. diff --git a/include/llvm/Option/OptSpecifier.h b/include/llvm/Option/OptSpecifier.h index 7206bf2..0b2aaae 100644 --- a/include/llvm/Option/OptSpecifier.h +++ b/include/llvm/Option/OptSpecifier.h @@ -25,7 +25,7 @@ namespace opt { public: OptSpecifier() : ID(0) {} - /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {} + /*implicit*/ OptSpecifier(unsigned ID) : ID(ID) {} /*implicit*/ OptSpecifier(const Option *Opt); bool isValid() const { return ID != 0; } diff --git a/include/llvm/Option/OptTable.h b/include/llvm/Option/OptTable.h index 5035940..a7ff469 100644 --- a/include/llvm/Option/OptTable.h +++ b/include/llvm/Option/OptTable.h @@ -73,8 +73,9 @@ private: } protected: - OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos, - bool _IgnoreCase = false); + OptTable(const Info *OptionInfos, unsigned NumOptionInfos, + bool IgnoreCase = false); + public: ~OptTable(); diff --git a/include/llvm/Option/Option.h b/include/llvm/Option/Option.h index b2cfacb..09be26c 100644 --- a/include/llvm/Option/Option.h +++ b/include/llvm/Option/Option.h @@ -70,7 +70,6 @@ protected: public: Option(const OptTable::Info *Info, const OptTable *Owner); - ~Option(); bool isValid() const { return Info != nullptr; diff --git a/include/llvm/Passes/PassBuilder.h b/include/llvm/Passes/PassBuilder.h new file mode 100644 index 0000000..1e605e3 --- /dev/null +++ b/include/llvm/Passes/PassBuilder.h @@ -0,0 +1,105 @@ +//===- Parsing, selection, and construction of pass pipelines --*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// Interfaces for registering analysis passes, producing common pass manager +/// configurations, and parsing of pass pipelines. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_PASSES_PASSBUILDER_H +#define LLVM_PASSES_PASSBUILDER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/CGSCCPassManager.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { +class TargetMachine; + +/// \brief This class provides access to building LLVM's passes. +/// +/// It's members provide the baseline state available to passes during their +/// construction. The \c PassRegistry.def file specifies how to construct all +/// of the built-in passes, and those may reference these members during +/// construction. +class PassBuilder { + TargetMachine *TM; + +public: + explicit PassBuilder(TargetMachine *TM = nullptr) : TM(TM) {} + + /// \brief Registers all available module analysis passes. + /// + /// This is an interface that can be used to populate a \c + /// ModuleAnalysisManager with all registered module analyses. Callers can + /// still manually register any additional analyses. + void registerModuleAnalyses(ModuleAnalysisManager &MAM); + + /// \brief Registers all available CGSCC analysis passes. + /// + /// This is an interface that can be used to populate a \c CGSCCAnalysisManager + /// with all registered CGSCC analyses. Callers can still manually register any + /// additional analyses. + void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM); + + /// \brief Registers all available function analysis passes. + /// + /// This is an interface that can be used to populate a \c + /// FunctionAnalysisManager with all registered function analyses. Callers can + /// still manually register any additional analyses. + void registerFunctionAnalyses(FunctionAnalysisManager &FAM); + + /// \brief Parse a textual pass pipeline description into a \c ModulePassManager. + /// + /// The format of the textual pass pipeline description looks something like: + /// + /// module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...) + /// + /// Pass managers have ()s describing the nest structure of passes. All passes + /// are comma separated. As a special shortcut, if the very first pass is not + /// a module pass (as a module pass manager is), this will automatically form + /// the shortest stack of pass managers that allow inserting that first pass. + /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop passes + /// 'lpassN', all of these are valid: + /// + /// fpass1,fpass2,fpass3 + /// cgpass1,cgpass2,cgpass3 + /// lpass1,lpass2,lpass3 + /// + /// And they are equivalent to the following (resp.): + /// + /// module(function(fpass1,fpass2,fpass3)) + /// module(cgscc(cgpass1,cgpass2,cgpass3)) + /// module(function(loop(lpass1,lpass2,lpass3))) + /// + /// This shortcut is especially useful for debugging and testing small pass + /// combinations. Note that these shortcuts don't introduce any other magic. If + /// the sequence of passes aren't all the exact same kind of pass, it will be + /// an error. You cannot mix different levels implicitly, you must explicitly + /// form a pass manager in which to nest passes. + bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, + bool VerifyEachPass = true, bool DebugLogging = false); + +private: + bool parseModulePassName(ModulePassManager &MPM, StringRef Name); + bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name); + bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name); + bool parseFunctionPassPipeline(FunctionPassManager &FPM, + StringRef &PipelineText, bool VerifyEachPass, + bool DebugLogging); + bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM, StringRef &PipelineText, + bool VerifyEachPass, bool DebugLogging); + bool parseModulePassPipeline(ModulePassManager &MPM, StringRef &PipelineText, + bool VerifyEachPass, bool DebugLogging); +}; + +} + +#endif diff --git a/include/llvm/ProfileData/CoverageMapping.h b/include/llvm/ProfileData/CoverageMapping.h index 4d393b3..e9d6ea5 100644 --- a/include/llvm/ProfileData/CoverageMapping.h +++ b/include/llvm/ProfileData/CoverageMapping.h @@ -18,11 +18,13 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Hashing.h" +#include "llvm/ADT/Triple.h" #include "llvm/ADT/iterator.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/raw_ostream.h" #include <system_error> +#include <tuple> namespace llvm { class IndexedInstrProfReader; @@ -407,7 +409,8 @@ public: /// \brief Load the coverage mapping from the given files. static ErrorOr<std::unique_ptr<CoverageMapping>> - load(StringRef ObjectFilename, StringRef ProfileFilename); + load(StringRef ObjectFilename, StringRef ProfileFilename, + Triple::ArchType Arch = Triple::ArchType::UnknownArch); /// \brief The number of functions that couldn't have their profiles mapped. /// diff --git a/include/llvm/ProfileData/CoverageMappingReader.h b/include/llvm/ProfileData/CoverageMappingReader.h index 6714366..bc68f0b 100644 --- a/include/llvm/ProfileData/CoverageMappingReader.h +++ b/include/llvm/ProfileData/CoverageMappingReader.h @@ -17,6 +17,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h" #include "llvm/Object/ObjectFile.h" #include "llvm/ProfileData/CoverageMapping.h" #include "llvm/ProfileData/InstrProf.h" @@ -175,7 +176,8 @@ private: public: static ErrorOr<std::unique_ptr<BinaryCoverageReader>> - create(std::unique_ptr<MemoryBuffer> &ObjectBuffer); + create(std::unique_ptr<MemoryBuffer> &ObjectBuffer, + Triple::ArchType Arch = Triple::ArchType::UnknownArch); std::error_code readNextRecord(CoverageMappingRecord &Record) override; }; diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h index 96a8219..fc14cb2 100644 --- a/include/llvm/Support/ARMBuildAttributes.h +++ b/include/llvm/Support/ARMBuildAttributes.h @@ -100,13 +100,13 @@ enum CPUArch { v5TEJ = 5, // e.g. ARM926EJ_S v6 = 6, // e.g. ARM1136J_S v6KZ = 7, // e.g. ARM1176JZ_S - v6T2 = 8, // e.g. ARM1156T2F_S - v6K = 9, // e.g. ARM1136J_S + v6T2 = 8, // e.g. ARM1156T2_S + v6K = 9, // e.g. ARM1176JZ_S v7 = 10, // e.g. Cortex A8, Cortex M3 v6_M = 11, // e.g. Cortex M1 v6S_M = 12, // v6_M with the System extensions v7E_M = 13, // v7_M with DSP extensions - v8 = 14 // v8, AArch32 + v8 = 14, // v8,v8.1a AArch32 }; enum CPUArchProfile { // (=7), uleb128 @@ -145,6 +145,7 @@ enum { AllowNeon = 1, // SIMDv1 was permitted AllowNeon2 = 2, // SIMDv2 was permitted (Half-precision FP, MAC operations) AllowNeonARMv8 = 3, // ARM v8-A SIMD was permitted + AllowNeonARMv8_1a = 4,// ARM v8.1-A SIMD was permitted (RDMA) // Tag_ABI_PCS_R9_use, (=14), uleb128 R9IsGPR = 0, // R9 used as v6 (just another callee-saved register) diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 64c5d96..bd1d1cb 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -352,9 +352,14 @@ struct cat { // Support value comparison outside the template. struct GenericOptionValue { - virtual ~GenericOptionValue() {} virtual bool compare(const GenericOptionValue &V) const = 0; +protected: + ~GenericOptionValue() = default; + GenericOptionValue() = default; + GenericOptionValue(const GenericOptionValue&) = default; + GenericOptionValue &operator=(const GenericOptionValue &) = default; + private: virtual void anchor(); }; @@ -380,6 +385,9 @@ struct OptionValueBase : public GenericOptionValue { bool compare(const GenericOptionValue & /*V*/) const override { return false; } + +protected: + ~OptionValueBase() = default; }; // Simple copy of the option value. @@ -387,6 +395,11 @@ template <class DataType> class OptionValueCopy : public GenericOptionValue { DataType Value; bool Valid; +protected: + ~OptionValueCopy() = default; + OptionValueCopy(const OptionValueCopy&) = default; + OptionValueCopy &operator=(const OptionValueCopy&) = default; + public: OptionValueCopy() : Valid(false) {} @@ -417,12 +430,19 @@ public: template <class DataType> struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> { typedef DataType WrapperType; + +protected: + ~OptionValueBase() = default; + OptionValueBase() = default; + OptionValueBase(const OptionValueBase&) = default; + OptionValueBase &operator=(const OptionValueBase&) = default; }; // Top-level option class. template <class DataType> -struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> { - OptionValue() {} +struct OptionValue final + : OptionValueBase<DataType, std::is_class<DataType>::value> { + OptionValue() = default; OptionValue(const DataType &V) { this->setValue(V); } // Some options may take their value from a different data type. @@ -435,7 +455,8 @@ struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> { // Other safe-to-copy-by-value common option types. enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE }; template <> -struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> { +struct OptionValue<cl::boolOrDefault> final + : OptionValueCopy<cl::boolOrDefault> { typedef cl::boolOrDefault WrapperType; OptionValue() {} @@ -450,7 +471,8 @@ private: void anchor() override; }; -template <> struct OptionValue<std::string> : OptionValueCopy<std::string> { +template <> +struct OptionValue<std::string> final : OptionValueCopy<std::string> { typedef StringRef WrapperType; OptionValue() {} @@ -692,7 +714,6 @@ class basic_parser_impl { // non-template implementation of basic_parser<t> public: basic_parser_impl(Option &O) {} - virtual ~basic_parser_impl() {} enum ValueExpected getValueExpectedFlagDefault() const { return ValueRequired; @@ -721,6 +742,7 @@ public: virtual void anchor(); protected: + ~basic_parser_impl() = default; // A helper for basic_parser::printOptionDiff. void printOptionName(const Option &O, size_t GlobalWidth) const; }; @@ -733,12 +755,16 @@ public: basic_parser(Option &O) : basic_parser_impl(O) {} typedef DataType parser_data_type; typedef OptionValue<DataType> OptVal; + +protected: + // Workaround Clang PR22793 + ~basic_parser() {} }; //-------------------------------------------------- // parser<bool> // -template <> class parser<bool> : public basic_parser<bool> { +template <> class parser<bool> final : public basic_parser<bool> { public: parser(Option &O) : basic_parser(O) {} @@ -765,7 +791,8 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>); //-------------------------------------------------- // parser<boolOrDefault> -template <> class parser<boolOrDefault> : public basic_parser<boolOrDefault> { +template <> +class parser<boolOrDefault> final : public basic_parser<boolOrDefault> { public: parser(Option &O) : basic_parser(O) {} @@ -791,7 +818,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>); //-------------------------------------------------- // parser<int> // -template <> class parser<int> : public basic_parser<int> { +template <> class parser<int> final : public basic_parser<int> { public: parser(Option &O) : basic_parser(O) {} @@ -813,7 +840,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>); //-------------------------------------------------- // parser<unsigned> // -template <> class parser<unsigned> : public basic_parser<unsigned> { +template <> class parser<unsigned> final : public basic_parser<unsigned> { public: parser(Option &O) : basic_parser(O) {} @@ -836,7 +863,8 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>); // parser<unsigned long long> // template <> -class parser<unsigned long long> : public basic_parser<unsigned long long> { +class parser<unsigned long long> final + : public basic_parser<unsigned long long> { public: parser(Option &O) : basic_parser(O) {} @@ -859,7 +887,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>); //-------------------------------------------------- // parser<double> // -template <> class parser<double> : public basic_parser<double> { +template <> class parser<double> final : public basic_parser<double> { public: parser(Option &O) : basic_parser(O) {} @@ -881,7 +909,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>); //-------------------------------------------------- // parser<float> // -template <> class parser<float> : public basic_parser<float> { +template <> class parser<float> final : public basic_parser<float> { public: parser(Option &O) : basic_parser(O) {} @@ -903,7 +931,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>); //-------------------------------------------------- // parser<std::string> // -template <> class parser<std::string> : public basic_parser<std::string> { +template <> class parser<std::string> final : public basic_parser<std::string> { public: parser(Option &O) : basic_parser(O) {} @@ -928,7 +956,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>); //-------------------------------------------------- // parser<char> // -template <> class parser<char> : public basic_parser<char> { +template <> class parser<char> final : public basic_parser<char> { public: parser(Option &O) : basic_parser(O) {} @@ -967,7 +995,7 @@ void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V, // This is instantiated for basic parsers when the parsed value has a different // type than the option value. e.g. HelpPrinter. template <class ParserDT, class ValDT> struct OptionDiffPrinter { - void print(const Option &O, const parser<ParserDT> P, const ValDT & /*V*/, + void print(const Option &O, const parser<ParserDT> &P, const ValDT & /*V*/, const OptionValue<ValDT> & /*Default*/, size_t GlobalWidth) { P.printOptionNoValue(O, GlobalWidth); } @@ -976,7 +1004,7 @@ template <class ParserDT, class ValDT> struct OptionDiffPrinter { // This is instantiated for basic parsers when the parsed value has the same // type as the option value. template <class DT> struct OptionDiffPrinter<DT, DT> { - void print(const Option &O, const parser<DT> P, const DT &V, + void print(const Option &O, const parser<DT> &P, const DT &V, const OptionValue<DT> &Default, size_t GlobalWidth) { P.printOptionDiff(O, V, Default, GlobalWidth); } diff --git a/include/llvm/Support/Compression.h b/include/llvm/Support/Compression.h index 88727fa..28274d6 100644 --- a/include/llvm/Support/Compression.h +++ b/include/llvm/Support/Compression.h @@ -14,12 +14,10 @@ #ifndef LLVM_SUPPORT_COMPRESSION_H #define LLVM_SUPPORT_COMPRESSION_H -#include "llvm/ADT/SmallVector.h" #include "llvm/Support/DataTypes.h" -#include <memory> namespace llvm { - +template <typename T> class SmallVectorImpl; class StringRef; namespace zlib { diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h index 1f3965c..c08c3c1 100644 --- a/include/llvm/Support/CrashRecoveryContext.h +++ b/include/llvm/Support/CrashRecoveryContext.h @@ -14,8 +14,6 @@ #include <string> namespace llvm { -class StringRef; - class CrashRecoveryContextCleanup; /// \brief Crash recovery helper object. diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h index 48235d4..3ffa9bc 100644 --- a/include/llvm/Support/DataExtractor.h +++ b/include/llvm/Support/DataExtractor.h @@ -10,7 +10,6 @@ #ifndef LLVM_SUPPORT_DATAEXTRACTOR_H #define LLVM_SUPPORT_DATAEXTRACTOR_H -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h index e93e6ca..fff4f98 100644 --- a/include/llvm/Support/Debug.h +++ b/include/llvm/Support/Debug.h @@ -28,9 +28,8 @@ #ifndef LLVM_SUPPORT_DEBUG_H #define LLVM_SUPPORT_DEBUG_H -#include "llvm/Support/raw_ostream.h" - namespace llvm { +class raw_ostream; #ifndef NDEBUG /// DebugFlag - This boolean is set to true if the '-debug' command line option diff --git a/include/llvm/Support/Dwarf.def b/include/llvm/Support/Dwarf.def index c663af9..4b923b8 100644 --- a/include/llvm/Support/Dwarf.def +++ b/include/llvm/Support/Dwarf.def @@ -102,7 +102,6 @@ HANDLE_DW_TAG(0x0043, template_alias) // Mock tags we use as discriminators. HANDLE_DW_TAG(0x0100, auto_variable) // Tag for local (auto) variables. HANDLE_DW_TAG(0x0101, arg_variable) // Tag for argument variables. -HANDLE_DW_TAG(0x0102, expression) // Tag for complex address expressions. // New in DWARF v5. HANDLE_DW_TAG(0x0044, coarray_type) diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index fc6f314..d7f1533 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -344,6 +344,7 @@ enum { ELFOSABI_NSK = 14, // Hewlett-Packard Non-Stop Kernel ELFOSABI_AROS = 15, // AROS ELFOSABI_FENIXOS = 16, // FenixOS + ELFOSABI_CLOUDABI = 17, // Nuxi CloudABI ELFOSABI_C6000_ELFABI = 64, // Bare-metal TMS320C6000 ELFOSABI_C6000_LINUX = 65, // Linux TMS320C6000 ELFOSABI_ARM = 97, // ARM diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h index 47b82fd..e9fe22e 100644 --- a/include/llvm/Support/Endian.h +++ b/include/llvm/Support/Endian.h @@ -58,8 +58,9 @@ inline value_type read(const void *memory) { /// Read a value of a particular endianness from a buffer, and increment the /// buffer past that value. -template<typename value_type, endianness endian, std::size_t alignment> -inline value_type readNext(const unsigned char *&memory) { +template<typename value_type, endianness endian, std::size_t alignment, + typename CharT> +inline value_type readNext(const CharT *&memory) { value_type ret = read<value_type, endian, alignment>(memory); memory += sizeof(value_type); return ret; @@ -195,7 +196,23 @@ typedef detail::packed_endian_specific_integral <int32_t, native, unaligned> unaligned_int32_t; typedef detail::packed_endian_specific_integral <int64_t, native, unaligned> unaligned_int64_t; -} // end namespace llvm + +namespace endian { +inline uint16_t read16le(const void *p) { return *(const ulittle16_t *)p; } +inline uint32_t read32le(const void *p) { return *(const ulittle32_t *)p; } +inline uint64_t read64le(const void *p) { return *(const ulittle64_t *)p; } +inline uint16_t read16be(const void *p) { return *(const ubig16_t *)p; } +inline uint32_t read32be(const void *p) { return *(const ubig32_t *)p; } +inline uint64_t read64be(const void *p) { return *(const ubig64_t *)p; } + +inline void write16le(void *p, uint16_t v) { *(ulittle16_t *)p = v; } +inline void write32le(void *p, uint32_t v) { *(ulittle32_t *)p = v; } +inline void write64le(void *p, uint64_t v) { *(ulittle64_t *)p = v; } +inline void write16be(void *p, uint16_t v) { *(ubig16_t *)p = v; } +inline void write32be(void *p, uint32_t v) { *(ubig32_t *)p = v; } +inline void write64be(void *p, uint64_t v) { *(ubig64_t *)p = v; } +} // end namespace endian } // end namespace support +} // end namespace llvm #endif diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h index 3f2f176..2ee2c60 100644 --- a/include/llvm/Support/FileUtilities.h +++ b/include/llvm/Support/FileUtilities.h @@ -51,7 +51,7 @@ namespace llvm { ~FileRemover() { if (DeleteIt) { // Ignore problems deleting the file. - sys::fs::remove(Filename.str()); + sys::fs::remove(Filename); } } @@ -61,7 +61,7 @@ namespace llvm { void setFile(const Twine& filename, bool deleteIt = true) { if (DeleteIt) { // Ignore problems deleting the file. - sys::fs::remove(Filename.str()); + sys::fs::remove(Filename); } Filename.clear(); diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h index 682c5a9..4319a3b 100644 --- a/include/llvm/Support/Format.h +++ b/include/llvm/Support/Format.h @@ -37,7 +37,8 @@ namespace llvm { class format_object_base { protected: const char *Fmt; - ~format_object_base() {} // Disallow polymorphic deletion. + ~format_object_base() = default; // Disallow polymorphic deletion. + format_object_base(const format_object_base &) = default; virtual void home(); // Out of line virtual method. /// Call snprintf() for this object, on the given buffer and size. diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h index 2f02aa7..7d1c273 100644 --- a/include/llvm/Support/GraphWriter.h +++ b/include/llvm/Support/GraphWriter.h @@ -24,10 +24,9 @@ #define LLVM_SUPPORT_GRAPHWRITER_H #include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/DOTGraphTraits.h" -#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" -#include <cassert> #include <vector> namespace llvm { diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index acffb46..388d82c 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -534,14 +534,6 @@ inline uint32_t FloatToBits(float Float) { return T.I; } -/// Platform-independent wrappers for the C99 isnan() function. -int IsNAN(float f); -int IsNAN(double d); - -/// Platform-independent wrappers for the C99 isinf() function. -int IsInf(float f); -int IsInf(double d); - /// MinAlign - A and B are either alignments or offsets. Return the minimum /// alignment that may be assumed after adding the two together. inline uint64_t MinAlign(uint64_t A, uint64_t B) { @@ -612,13 +604,6 @@ inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) { return RoundUpToAlignment(Value, Align) - Value; } -/// abs64 - absolute value of a 64-bit int. Not all environments support -/// "abs" on whatever their name for the 64-bit int type is. The absolute -/// value of the largest negative number is undefined, as with "abs". -inline int64_t abs64(int64_t x) { - return (x < 0) ? -x : x; -} - /// SignExtend32 - Sign extend B-bit number x to 32-bit int. /// Usage int32_t r = SignExtend32<5>(x); template <unsigned B> inline int32_t SignExtend32(uint32_t x) { diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h index cc65ca5..35a7bdb 100644 --- a/include/llvm/Support/MemoryBuffer.h +++ b/include/llvm/Support/MemoryBuffer.h @@ -17,11 +17,9 @@ #include "llvm-c/Support.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/CBindingWrapping.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorOr.h" #include <memory> -#include <system_error> namespace llvm { class MemoryBufferRef; diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h index 40dc60f..b89a0f7 100644 --- a/include/llvm/Support/Program.h +++ b/include/llvm/Support/Program.h @@ -16,10 +16,11 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/ErrorOr.h" -#include "llvm/Support/Path.h" #include <system_error> namespace llvm { +class StringRef; + namespace sys { /// This is the OS-specific separator for PATH like environment variables: diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h index 5e5a5a3..31b35ed 100644 --- a/include/llvm/Support/Regex.h +++ b/include/llvm/Support/Regex.h @@ -17,7 +17,6 @@ #ifndef LLVM_SUPPORT_REGEX_H #define LLVM_SUPPORT_REGEX_H -#include "llvm/Support/Compiler.h" #include <string> struct llvm_regex; diff --git a/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h index 6b1da2a..a067b13 100644 --- a/include/llvm/Support/Signals.h +++ b/include/llvm/Support/Signals.h @@ -15,10 +15,12 @@ #ifndef LLVM_SUPPORT_SIGNALS_H #define LLVM_SUPPORT_SIGNALS_H -#include "llvm/Support/Path.h" -#include <cstdio> +#include <string> namespace llvm { +class StringRef; +class raw_ostream; + namespace sys { /// This function runs all the registered interrupt handlers, including the @@ -42,8 +44,8 @@ namespace sys { /// Disable all system dialog boxes that appear when the process crashes. void DisableSystemDialogsOnCrash(); - /// \brief Print the stack trace using the given \c FILE object. - void PrintStackTrace(FILE *); + /// \brief Print the stack trace using the given \c raw_ostream object. + void PrintStackTrace(raw_ostream &OS); /// AddSignalHandler - Add a function to be called when an abort/kill signal /// is delivered to the process. The handler can have a cookie passed to it diff --git a/include/llvm/Support/StreamingMemoryObject.h b/include/llvm/Support/StreamingMemoryObject.h index f914817..fb63da7 100644 --- a/include/llvm/Support/StreamingMemoryObject.h +++ b/include/llvm/Support/StreamingMemoryObject.h @@ -14,7 +14,6 @@ #include "llvm/Support/DataStream.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryObject.h" -#include <cassert> #include <memory> #include <vector> diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h index 675adde..2ec0c3b 100644 --- a/include/llvm/Support/StringPool.h +++ b/include/llvm/Support/StringPool.h @@ -30,9 +30,7 @@ #define LLVM_SUPPORT_STRINGPOOL_H #include "llvm/ADT/StringMap.h" -#include "llvm/Support/Compiler.h" #include <cassert> -#include <new> namespace llvm { diff --git a/include/llvm/Support/SystemUtils.h b/include/llvm/Support/SystemUtils.h index d2d08b2..2997b1b 100644 --- a/include/llvm/Support/SystemUtils.h +++ b/include/llvm/Support/SystemUtils.h @@ -15,8 +15,6 @@ #ifndef LLVM_SUPPORT_SYSTEMUTILS_H #define LLVM_SUPPORT_SYSTEMUTILS_H -#include <string> - namespace llvm { class raw_ostream; diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index 7a71f6d..ba6bbde 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -28,8 +28,6 @@ namespace llvm { class AsmPrinter; - class Module; - class MCAssembler; class MCAsmBackend; class MCAsmInfo; class MCAsmParser; @@ -59,6 +57,15 @@ namespace llvm { MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst); + /// Takes ownership of \p TAB and \p CE. + MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *CE, + bool RelaxAll); + MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *CE, + bool RelaxAll, bool DWARFMustBeAtTheEnd, + bool LabelSections = false); + MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx); MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo, @@ -125,21 +132,24 @@ namespace llvm { const MCSubtargetInfo &STI); typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, MCContext &Ctx); - typedef MCStreamer *(*MCObjectStreamerCtorTy)( - const Target &T, StringRef TT, MCContext &Ctx, MCAsmBackend &TAB, - raw_ostream &_OS, MCCodeEmitter *_Emitter, const MCSubtargetInfo &STI, - bool RelaxAll); - typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx, - formatted_raw_ostream &OS, - bool isVerboseAsm, - bool useDwarfDirectory, - MCInstPrinter *InstPrint, - MCCodeEmitter *CE, - MCAsmBackend *TAB, - bool ShowInst); + typedef MCStreamer *(*ELFStreamerCtorTy)(const Triple &T, MCContext &Ctx, + MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter, + bool RelaxAll); + typedef MCStreamer *(*MachOStreamerCtorTy)( + MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter, bool RelaxAll, bool DWARFMustBeAtTheEnd); + typedef MCStreamer *(*COFFStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB, + raw_ostream &OS, + MCCodeEmitter *Emitter, + bool RelaxAll); typedef MCTargetStreamer *(*NullTargetStreamerCtorTy)(MCStreamer &S); + typedef MCTargetStreamer *(*AsmTargetStreamerCtorTy)( + MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint, + bool IsVerboseAsm); + typedef MCTargetStreamer *(*ObjectTargetStreamerCtorTy)( + MCStreamer &S, const MCSubtargetInfo &STI); typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(StringRef TT, MCContext &Ctx); typedef MCSymbolizer *(*MCSymbolizerCtorTy)( @@ -216,18 +226,23 @@ namespace llvm { /// CodeEmitter, if registered. MCCodeEmitterCtorTy MCCodeEmitterCtorFn; - /// MCObjectStreamerCtorFn - Construction function for this target's - /// MCObjectStreamer, if registered. - MCObjectStreamerCtorTy MCObjectStreamerCtorFn; - - /// AsmStreamerCtorFn - Construction function for this target's - /// AsmStreamer, if registered (default = llvm::createAsmStreamer). - AsmStreamerCtorTy AsmStreamerCtorFn; + // Construction functions for the various object formats, if registered. + COFFStreamerCtorTy COFFStreamerCtorFn; + MachOStreamerCtorTy MachOStreamerCtorFn; + ELFStreamerCtorTy ELFStreamerCtorFn; /// Construction function for this target's null TargetStreamer, if /// registered (default = nullptr). NullTargetStreamerCtorTy NullTargetStreamerCtorFn; + /// Construction function for this target's asm TargetStreamer, if + /// registered (default = nullptr). + AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn; + + /// Construction function for this target's obj TargetStreamer, if + /// registered (default = nullptr). + ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn; + /// MCRelocationInfoCtorFn - Construction function for this target's /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo) MCRelocationInfoCtorTy MCRelocationInfoCtorFn; @@ -238,8 +253,10 @@ namespace llvm { public: Target() - : AsmStreamerCtorFn(nullptr), MCRelocationInfoCtorFn(nullptr), - MCSymbolizerCtorFn(nullptr) {} + : COFFStreamerCtorFn(nullptr), MachOStreamerCtorFn(nullptr), + ELFStreamerCtorFn(nullptr), NullTargetStreamerCtorFn(nullptr), + AsmTargetStreamerCtorFn(nullptr), ObjectTargetStreamerCtorFn(nullptr), + MCRelocationInfoCtorFn(nullptr), MCSymbolizerCtorFn(nullptr) {} /// @name Target Information /// @{ @@ -406,46 +423,72 @@ namespace llvm { /// createMCCodeEmitter - Create a target specific code emitter. MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, MCContext &Ctx) const { if (!MCCodeEmitterCtorFn) return nullptr; - return MCCodeEmitterCtorFn(II, MRI, STI, Ctx); + return MCCodeEmitterCtorFn(II, MRI, Ctx); } - /// createMCObjectStreamer - Create a target specific MCStreamer. + /// Create a target specific MCStreamer. /// - /// \param TT The target triple. + /// \param T The target triple. /// \param Ctx The target context. /// \param TAB The target assembler backend object. Takes ownership. - /// \param _OS The stream object. - /// \param _Emitter The target independent assembler object.Takes ownership. + /// \param OS The stream object. + /// \param Emitter The target independent assembler object.Takes ownership. /// \param RelaxAll Relax all fixups? - MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx, - MCAsmBackend &TAB, raw_ostream &_OS, - MCCodeEmitter *_Emitter, + MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx, + MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter, const MCSubtargetInfo &STI, - bool RelaxAll) const { - if (!MCObjectStreamerCtorFn) - return nullptr; - return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, STI, - RelaxAll); - } - - /// createAsmStreamer - Create a target specific MCStreamer. - MCStreamer *createAsmStreamer(MCContext &Ctx, - formatted_raw_ostream &OS, - bool isVerboseAsm, - bool useDwarfDirectory, - MCInstPrinter *InstPrint, - MCCodeEmitter *CE, - MCAsmBackend *TAB, - bool ShowInst) const { - if (AsmStreamerCtorFn) - return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useDwarfDirectory, - InstPrint, CE, TAB, ShowInst); - return llvm::createAsmStreamer(Ctx, OS, isVerboseAsm, useDwarfDirectory, - InstPrint, CE, TAB, ShowInst); + bool RelaxAll, + bool DWARFMustBeAtTheEnd) const { + MCStreamer *S; + switch (T.getObjectFormat()) { + default: + llvm_unreachable("Unknown object format"); + case Triple::COFF: + assert(T.isOSWindows() && "only Windows COFF is supported"); + S = COFFStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll); + break; + case Triple::MachO: + if (MachOStreamerCtorFn) + S = MachOStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll, + DWARFMustBeAtTheEnd); + else + S = createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll, + DWARFMustBeAtTheEnd); + break; + case Triple::ELF: + if (ELFStreamerCtorFn) + S = ELFStreamerCtorFn(T, Ctx, TAB, OS, Emitter, RelaxAll); + else + S = createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll); + break; + } + if (ObjectTargetStreamerCtorFn) + ObjectTargetStreamerCtorFn(*S, STI); + return S; + } + + MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, + bool IsVerboseAsm, bool UseDwarfDirectory, + MCInstPrinter *InstPrint, MCCodeEmitter *CE, + MCAsmBackend *TAB, bool ShowInst) const { + MCStreamer *S = + llvm::createAsmStreamer(Ctx, OS, IsVerboseAsm, UseDwarfDirectory, + InstPrint, CE, TAB, ShowInst); + createAsmTargetStreamer(*S, OS, InstPrint, IsVerboseAsm); + return S; + } + + MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S, + formatted_raw_ostream &OS, + MCInstPrinter *InstPrint, + bool IsVerboseAsm) const { + if (AsmTargetStreamerCtorFn) + return AsmTargetStreamerCtorFn(S, OS, InstPrint, IsVerboseAsm); + return nullptr; } MCStreamer *createNullStreamer(MCContext &Ctx) const { @@ -759,31 +802,17 @@ namespace llvm { T.MCCodeEmitterCtorFn = Fn; } - /// RegisterMCObjectStreamer - Register a object code MCStreamer - /// implementation for the given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct an MCStreamer for the target. - static void RegisterMCObjectStreamer(Target &T, - Target::MCObjectStreamerCtorTy Fn) { - T.MCObjectStreamerCtorFn = Fn; + static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn) { + T.COFFStreamerCtorFn = Fn; } - /// RegisterAsmStreamer - Register an assembly MCStreamer implementation - /// for the given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct an MCStreamer for the target. - static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) { - T.AsmStreamerCtorFn = Fn; + static void RegisterMachOStreamer(Target &T, + Target::MachOStreamerCtorTy Fn) { + T.MachOStreamerCtorFn = Fn; + } + + static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn) { + T.ELFStreamerCtorFn = Fn; } static void @@ -791,6 +820,17 @@ namespace llvm { T.NullTargetStreamerCtorFn = Fn; } + static void RegisterAsmTargetStreamer(Target &T, + Target::AsmTargetStreamerCtorTy Fn) { + T.AsmTargetStreamerCtorFn = Fn; + } + + static void + RegisterObjectTargetStreamer(Target &T, + Target::ObjectTargetStreamerCtorTy Fn) { + T.ObjectTargetStreamerCtorFn = Fn; + } + /// RegisterMCRelocationInfo - Register an MCRelocationInfo /// implementation for the given target. /// @@ -1152,10 +1192,9 @@ namespace llvm { } private: - static MCCodeEmitter *Allocator(const MCInstrInfo &/*II*/, - const MCRegisterInfo &/*MRI*/, - const MCSubtargetInfo &/*STI*/, - MCContext &/*Ctx*/) { + static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/, + const MCRegisterInfo & /*MRI*/, + MCContext & /*Ctx*/) { return new MCCodeEmitterImpl(); } }; diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h index 442b361..2cd30e2 100644 --- a/include/llvm/Support/Timer.h +++ b/include/llvm/Support/Timer.h @@ -11,7 +11,6 @@ #define LLVM_SUPPORT_TIMER_H #include "llvm/ADT/StringRef.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" #include <cassert> #include <string> diff --git a/include/llvm/Support/UnicodeCharRanges.h b/include/llvm/Support/UnicodeCharRanges.h index 79137bf..9f738df 100644 --- a/include/llvm/Support/UnicodeCharRanges.h +++ b/include/llvm/Support/UnicodeCharRanges.h @@ -50,9 +50,13 @@ public: /// the UnicodeCharSet instance, and should not change. Array is validated by /// the constructor, so it makes sense to create as few UnicodeCharSet /// instances per each array of ranges, as possible. +#ifdef NDEBUG + LLVM_CONSTEXPR UnicodeCharSet(CharRanges Ranges) : Ranges(Ranges) {} +#else UnicodeCharSet(CharRanges Ranges) : Ranges(Ranges) { assert(rangesAreValid()); } +#endif /// \brief Returns true if the character set contains the Unicode code point /// \p C. diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h index de6e654..3d42329 100644 --- a/include/llvm/Support/YAMLParser.h +++ b/include/llvm/Support/YAMLParser.h @@ -38,19 +38,18 @@ #ifndef LLVM_SUPPORT_YAMLPARSER_H #define LLVM_SUPPORT_YAMLPARSER_H -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" -#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SMLoc.h" #include <limits> #include <map> #include <utility> namespace llvm { +class MemoryBufferRef; class SourceMgr; -class raw_ostream; class Twine; +class raw_ostream; namespace yaml { diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 94686d9..12783c7 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -14,8 +14,8 @@ #ifndef LLVM_SUPPORT_RAW_OSTREAM_H #define LLVM_SUPPORT_RAW_OSTREAM_H +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" #include <system_error> @@ -185,6 +185,10 @@ public: return write(Str.data(), Str.length()); } + raw_ostream &operator<<(const llvm::SmallVectorImpl<char> &Str) { + return write(Str.data(), Str.size()); + } + raw_ostream &operator<<(unsigned long N); raw_ostream &operator<<(long N); raw_ostream &operator<<(unsigned long long N); diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index e8d22d9..5233493 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -1477,7 +1477,7 @@ public: return false; } bool isTemplateArg(StringRef Name) const { - return isTemplateArg(StringInit::get(Name.str())); + return isTemplateArg(StringInit::get(Name)); } const RecordVal *getValue(const Init *Name) const { @@ -1502,7 +1502,7 @@ public: TemplateArgs.push_back(Name); } void addTemplateArg(StringRef Name) { - addTemplateArg(StringInit::get(Name.str())); + addTemplateArg(StringInit::get(Name)); } void addValue(const RecordVal &RV) { @@ -1527,7 +1527,7 @@ public: } void removeValue(StringRef Name) { - removeValue(StringInit::get(Name.str())); + removeValue(StringInit::get(Name)); } bool isSubClassOf(const Record *R) const { diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 3e65a5d..6c970d0 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -397,8 +397,7 @@ class Instruction { // captured by any operands of the instruction or other flags. // bit hasSideEffects = ?; - bit hasTwoExplicitDefs = 0; // Does this instruction have 2 explicit - // destinations? + // Is this instruction a "real" instruction (with a distinct machine // encoding), or is it a pseudo instruction used for codegen modeling // purposes. diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 247f9d8..110976a 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -207,7 +207,7 @@ public: /// this, particularly to support spilled vector registers. virtual bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx, unsigned &Size, unsigned &Offset, - const TargetMachine *TM) const; + const MachineFunction &MF) const; /// isAsCheapAsAMove - Return true if the instruction is as cheap as a move /// instruction. @@ -672,16 +672,15 @@ public: /// operand folded, otherwise NULL is returned. /// The new instruction is inserted before MI, and the client is responsible /// for removing the old instruction. - MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI, - const SmallVectorImpl<unsigned> &Ops, - int FrameIndex) const; + MachineInstr *foldMemoryOperand(MachineBasicBlock::iterator MI, + ArrayRef<unsigned> Ops, int FrameIndex) const; /// foldMemoryOperand - Same as the previous version except it allows folding /// of any load and store from / to any address, not just from a specific /// stack slot. - MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI, - const SmallVectorImpl<unsigned> &Ops, - MachineInstr* LoadMI) const; + MachineInstr *foldMemoryOperand(MachineBasicBlock::iterator MI, + ArrayRef<unsigned> Ops, + MachineInstr *LoadMI) const; /// hasPattern - return true when there is potentially a faster code sequence /// for an instruction chain ending in \p Root. All potential pattern are @@ -723,20 +722,20 @@ protected: /// foldMemoryOperandImpl - Target-dependent implementation for /// foldMemoryOperand. Target-independent code in foldMemoryOperand will /// take care of adding a MachineMemOperand to the newly created instruction. - virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl<unsigned> &Ops, - int FrameIndex) const { + virtual MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr *MI, + ArrayRef<unsigned> Ops, + int FrameIndex) const { return nullptr; } /// foldMemoryOperandImpl - Target-dependent implementation for /// foldMemoryOperand. Target-independent code in foldMemoryOperand will /// take care of adding a MachineMemOperand to the newly created instruction. - virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl<unsigned> &Ops, - MachineInstr* LoadMI) const { + virtual MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr *MI, + ArrayRef<unsigned> Ops, + MachineInstr *LoadMI) const { return nullptr; } @@ -786,9 +785,8 @@ protected: public: /// canFoldMemoryOperand - Returns true for the specified load / store if /// folding is possible. - virtual - bool canFoldMemoryOperand(const MachineInstr *MI, - const SmallVectorImpl<unsigned> &Ops) const; + virtual bool canFoldMemoryOperand(const MachineInstr *MI, + ArrayRef<unsigned> Ops) const; /// unfoldMemoryOperand - Separate a single instruction which folded a load or /// a store or a load and a store into two or more instruction. If this is diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 4118917..29ecedc 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -123,6 +123,18 @@ public: // mask (ex: x86 blends). }; + /// Enum that specifies what a AtomicRMWInst is expanded to, if at all. Exists + /// because different targets have different levels of support for these + /// atomic RMW instructions, and also have different options w.r.t. what they should + /// expand to. + enum class AtomicRMWExpansionKind { + None, // Don't expand the instruction. + LLSC, // Expand the instruction into loadlinked/storeconditional; used + // by ARM/AArch64. Implies `hasLoadLinkedStoreConditional` + // returns true. + CmpXChg, // Expand the instruction into cmpxchg; used by at least X86. + }; + static ISD::NodeType getExtendForContent(BooleanContent Content) { switch (Content) { case UndefinedBooleanContent: @@ -148,7 +160,7 @@ protected: public: const TargetMachine &getTargetMachine() const { return TM; } - const DataLayout *getDataLayout() const { return DL; } + const DataLayout *getDataLayout() const { return TM.getDataLayout(); } bool isBigEndian() const { return !IsLittleEndian; } bool isLittleEndian() const { return IsLittleEndian; } @@ -964,6 +976,15 @@ public: return false; } + /// Return true if the pointer arguments to CI should be aligned by aligning + /// the object whose address is being passed. If so then MinSize is set to the + /// minimum size the object must be to be aligned and PrefAlign is set to the + /// preferred alignment. + virtual bool shouldAlignPointerArgs(CallInst * /*CI*/, unsigned & /*MinSize*/, + unsigned & /*PrefAlign*/) const { + return false; + } + //===--------------------------------------------------------------------===// /// \name Helpers for TargetTransformInfo implementations /// @{ @@ -1059,15 +1080,21 @@ public: return false; } + /// Returns true if arguments should be sign-extended in lib calls. + virtual bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const { + return IsSigned; + } + /// Returns true if the given (atomic) load should be expanded by the /// IR-level AtomicExpand pass into a load-linked instruction /// (through emitLoadLinked()). virtual bool shouldExpandAtomicLoadInIR(LoadInst *LI) const { return false; } - /// Returns true if the given AtomicRMW should be expanded by the - /// IR-level AtomicExpand pass into a loop using LoadLinked/StoreConditional. - virtual bool shouldExpandAtomicRMWInIR(AtomicRMWInst *RMWI) const { - return false; + /// Returns how the IR-level AtomicExpand pass should expand the given + /// AtomicRMW, if at all. Default is to never expand. + virtual AtomicRMWExpansionKind + shouldExpandAtomicRMWInIR(AtomicRMWInst *) const { + return AtomicRMWExpansionKind::None; } /// On some platforms, an AtomicRMW that never actually modifies the value @@ -1084,6 +1111,25 @@ public: virtual LoadInst *lowerIdempotentRMWIntoFencedLoad(AtomicRMWInst *RMWI) const { return nullptr; } + + /// Returns true if we should normalize + /// select(N0&N1, X, Y) => select(N0, select(N1, X, Y), Y) and + /// select(N0|N1, X, Y) => select(N0, select(N1, X, Y, Y)) if it is likely + /// that it saves us from materializing N0 and N1 in an integer register. + /// Targets that are able to perform and/or on flags should return false here. + virtual bool shouldNormalizeToSelectSequence(LLVMContext &Context, + EVT VT) const { + // If a target has multiple condition registers, then it likely has logical + // operations on those registers. + if (hasMultipleConditionRegisters()) + return false; + // Only do the transform if the value won't be split into multiple + // registers. + LegalizeTypeAction Action = getTypeAction(Context, VT); + return Action != TypeExpandInteger && Action != TypeExpandFloat && + Action != TypeSplitVector; + } + //===--------------------------------------------------------------------===// // TargetLowering Configuration Methods - These methods should be invoked by // the derived class constructor to configure this object for the target. @@ -1452,6 +1498,33 @@ public: virtual bool isProfitableToHoist(Instruction *I) const { return true; } + /// Return true if the extension represented by \p I is free. + /// Unlikely the is[Z|FP]ExtFree family which is based on types, + /// this method can use the context provided by \p I to decide + /// whether or not \p I is free. + /// This method extends the behavior of the is[Z|FP]ExtFree family. + /// In other words, if is[Z|FP]Free returns true, then this method + /// returns true as well. The converse is not true. + /// The target can perform the adequate checks by overriding isExtFreeImpl. + /// \pre \p I must be a sign, zero, or fp extension. + bool isExtFree(const Instruction *I) const { + switch (I->getOpcode()) { + case Instruction::FPExt: + if (isFPExtFree(EVT::getEVT(I->getType()))) + return true; + break; + case Instruction::ZExt: + if (isZExtFree(I->getOperand(0)->getType(), I->getType())) + return true; + break; + case Instruction::SExt: + break; + default: + llvm_unreachable("Instruction is not an extension"); + } + return isExtFreeImpl(I); + } + /// Return true if any actual instruction that defines a value of type Ty1 /// implicitly zero-extends the value to Ty2 in the result register. /// @@ -1607,7 +1680,6 @@ public: private: const TargetMachine &TM; - const DataLayout *DL; /// True if this is a little endian target. bool IsLittleEndian; @@ -1816,6 +1888,11 @@ private: CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL]; protected: + /// Return true if the extension represented by \p I is free. + /// \pre \p I is a sign, zero, or fp extension and + /// is[Z|FP]ExtFree of the related types is not true. + virtual bool isExtFreeImpl(const Instruction *I) const { return false; } + /// \brief Specify maximum number of store instructions per memset call. /// /// When lowering \@llvm.memset this field specifies the maximum number of @@ -1953,6 +2030,7 @@ public: ISD::CondCode &CCCode, SDLoc DL) const; /// Returns a pair of (return value, chain). + /// It is an error to pass RTLIB::UNKNOWN_LIBCALL as \p LC. std::pair<SDValue, SDValue> makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned, @@ -2562,6 +2640,15 @@ public: getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, const std::string &Constraint, MVT VT) const; + virtual unsigned + getInlineAsmMemConstraint(const std::string &ConstraintCode) const { + if (ConstraintCode == "i") + return InlineAsm::Constraint_i; + else if (ConstraintCode == "m") + return InlineAsm::Constraint_m; + return InlineAsm::Constraint_Unknown; + } + /// Try to replace an X constraint, which matches anything, with another that /// has more specific requirements based on the type of the corresponding /// operand. This returns null if there is no replacement to make. @@ -2664,6 +2751,8 @@ public: /// is created but not inserted into any basic blocks, and this method is /// called to expand it into a sequence of instructions, potentially also /// creating new basic blocks and control flow. + /// As long as the returned basic block is different (i.e., we created a new + /// one), the custom inserter is free to modify the rest of \p MBB. virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 57c2606..62ae237 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -29,26 +29,29 @@ namespace llvm { class MCSymbol; class MCSymbolRefExpr; class MCStreamer; + class MCValue; class ConstantExpr; class GlobalValue; class TargetMachine; class TargetLoweringObjectFile : public MCObjectFileInfo { MCContext *Ctx; - const DataLayout *DL; TargetLoweringObjectFile( const TargetLoweringObjectFile&) = delete; void operator=(const TargetLoweringObjectFile&) = delete; protected: + const DataLayout *DL; bool SupportIndirectSymViaGOTPCRel; + bool SupportGOTPCRelWithOffset; public: MCContext &getContext() const { return *Ctx; } TargetLoweringObjectFile() : MCObjectFileInfo(), Ctx(nullptr), DL(nullptr), - SupportIndirectSymViaGOTPCRel(false) {} + SupportIndirectSymViaGOTPCRel(false), + SupportGOTPCRelWithOffset(true) {} virtual ~TargetLoweringObjectFile(); @@ -98,6 +101,11 @@ public: return SectionForGlobal(GV, getKindForGlobal(GV, TM), Mang, TM); } + virtual void getNameWithPrefix(SmallVectorImpl<char> &OutName, + const GlobalValue *GV, + bool CannotUsePrivateLabel, Mangler &Mang, + const TargetMachine &TM) const; + virtual const MCSection * getSectionForJumpTable(const Function &F, Mangler &Mang, const TargetMachine &TM) const; @@ -168,9 +176,18 @@ public: return SupportIndirectSymViaGOTPCRel; } + /// \brief Target GOT "PC"-relative relocation supports encoding an additional + /// binary expression with an offset? + bool supportGOTPCRelWithOffset() const { + return SupportGOTPCRelWithOffset; + } + /// \brief Get the target specific PC relative GOT entry relocation virtual const MCExpr *getIndirectSymViaGOTPCRel(const MCSymbol *Sym, - int64_t Offset) const { + const MCValue &MV, + int64_t Offset, + MachineModuleInfo *MMI, + MCStreamer &Streamer) const { return nullptr; } diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index cdf643d..87aba9f 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -15,6 +15,7 @@ #define LLVM_TARGET_TARGETMACHINE_H #include "llvm/ADT/StringRef.h" +#include "llvm/IR/DataLayout.h" #include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" #include "llvm/Target/TargetOptions.h" @@ -29,6 +30,9 @@ class Mangler; class MCAsmInfo; class MCCodeGenInfo; class MCContext; +class MCInstrInfo; +class MCRegisterInfo; +class MCSubtargetInfo; class MCSymbol; class Target; class DataLayout; @@ -62,12 +66,16 @@ class TargetMachine { TargetMachine(const TargetMachine &) = delete; void operator=(const TargetMachine &) = delete; protected: // Can only create subclasses. - TargetMachine(const Target &T, StringRef TargetTriple, - StringRef CPU, StringRef FS, const TargetOptions &Options); + TargetMachine(const Target &T, StringRef DataLayoutString, + StringRef TargetTriple, StringRef CPU, StringRef FS, + const TargetOptions &Options); /// TheTarget - The Target that this machine was created for. const Target &TheTarget; + /// DataLayout - For ABI type size and alignment. + const DataLayout DL; + /// TargetTriple, TargetCPU, TargetFS - Triple string, CPU name, and target /// feature strings the TargetMachine instance is created with. std::string TargetTriple; @@ -81,6 +89,9 @@ protected: // Can only create subclasses. /// AsmInfo - Contains target specific asm information. /// const MCAsmInfo *AsmInfo; + const MCRegisterInfo *MRI; + const MCInstrInfo *MII; + const MCSubtargetInfo *STI; unsigned RequireStructuredCFG : 1; @@ -97,11 +108,8 @@ public: /// getSubtargetImpl - virtual method implemented by subclasses that returns /// a reference to that target's TargetSubtargetInfo-derived member variable. - virtual const TargetSubtargetInfo *getSubtargetImpl() const { - return nullptr; - } virtual const TargetSubtargetInfo *getSubtargetImpl(const Function &) const { - return getSubtargetImpl(); + return nullptr; } virtual TargetLoweringObjectFile *getObjFileLowering() const { return nullptr; @@ -110,18 +118,13 @@ public: /// getSubtarget - This method returns a pointer to the specified type of /// TargetSubtargetInfo. In debug builds, it verifies that the object being /// returned is of the correct type. - template<typename STC> const STC &getSubtarget() const { - return *static_cast<const STC*>(getSubtargetImpl()); - } - template <typename STC> const STC &getSubtarget(const Function &) const { - return *static_cast<const STC*>(getSubtargetImpl()); + template <typename STC> const STC &getSubtarget(const Function &F) const { + return *static_cast<const STC*>(getSubtargetImpl(F)); } /// getDataLayout - This method returns a pointer to the DataLayout for /// the target. It should be unchanging for every subtarget. - virtual const DataLayout *getDataLayout() const { - return nullptr; - } + const DataLayout *getDataLayout() const { return &DL; } /// \brief Reset the target options based on the function's attributes. // FIXME: Remove TargetOptions that affect per-function code generation @@ -131,6 +134,9 @@ public: /// getMCAsmInfo - Return target specific asm information. /// const MCAsmInfo *getMCAsmInfo() const { return AsmInfo; } + const MCRegisterInfo *getMCRegisterInfo() const { return MRI; } + const MCInstrInfo *getMCInstrInfo() const { return MII; } + const MCSubtargetInfo *getMCSubtargetInfo() const { return STI; } /// getIntrinsicInfo - If intrinsic information is available, return it. If /// not, return null. @@ -236,9 +242,9 @@ public: /// class LLVMTargetMachine : public TargetMachine { protected: // Can only create subclasses. - LLVMTargetMachine(const Target &T, StringRef TargetTriple, - StringRef CPU, StringRef FS, TargetOptions Options, - Reloc::Model RM, CodeModel::Model CM, + LLVMTargetMachine(const Target &T, StringRef DataLayoutString, + StringRef TargetTriple, StringRef CPU, StringRef FS, + TargetOptions Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL); void initAsmInfo(); diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index fc94a84..4184052 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -46,6 +46,8 @@ public: const uint32_t *SubClassMask; const uint16_t *SuperRegIndices; const unsigned LaneMask; + /// Whether the class supports two (or more) disjunct subregister indices. + const bool HasDisjunctSubRegs; const sc_iterator SuperClasses; ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&); @@ -357,13 +359,13 @@ public: /// /// then: /// - /// getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B) != 0 + /// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0 /// /// The converse is not necessarily true. If two lane masks have a common /// bit, the corresponding sub-registers may not overlap, but it can be /// assumed that they usually will. + /// SubIdx == 0 is allowed, it has the lane mask ~0u. unsigned getSubRegIndexLaneMask(unsigned SubIdx) const { - // SubIdx == 0 is allowed, it has the lane mask ~0u. assert(SubIdx < getNumSubRegIndices() && "This is not a subregister index"); return SubRegIndexLaneMasks[SubIdx]; } @@ -425,10 +427,10 @@ public: /// closest to the incoming stack pointer if stack grows down, and vice versa. /// virtual const MCPhysReg* - getCalleeSavedRegs(const MachineFunction *MF = nullptr) const = 0; + getCalleeSavedRegs(const MachineFunction *MF) const = 0; /// getCallPreservedMask - Return a mask of call-preserved registers for the - /// given calling convention on the current sub-target. The mask should + /// given calling convention on the current function. The mask should /// include all call-preserved aliases. This is used by the register /// allocator to determine which registers can be live across a call. /// @@ -445,7 +447,8 @@ public: /// instructions should use implicit-def operands to indicate call clobbered /// registers. /// - virtual const uint32_t *getCallPreservedMask(CallingConv::ID) const { + virtual const uint32_t *getCallPreservedMask(const MachineFunction &MF, + CallingConv::ID) const { // The default mask clobbers everything. All targets should override. return nullptr; } @@ -622,8 +625,9 @@ public: /// legal to use in the current sub-target and has the same spill size. /// The returned register class can be used to create virtual registers which /// means that all its registers can be copied and spilled. - virtual const TargetRegisterClass* - getLargestLegalSuperClass(const TargetRegisterClass *RC) const { + virtual const TargetRegisterClass * + getLargestLegalSuperClass(const TargetRegisterClass *RC, + const MachineFunction &) const { /// The default implementation is very conservative and doesn't allow the /// register allocator to inflate register classes. return RC; @@ -655,7 +659,8 @@ public: /// Get the register unit pressure limit for this dimension. /// This limit must be adjusted dynamically for reserved registers. - virtual unsigned getRegPressureSetLimit(unsigned Idx) const = 0; + virtual unsigned getRegPressureSetLimit(const MachineFunction &MF, + unsigned Idx) const = 0; /// Get the dimensions of register pressure impacted by this register class. /// Returns a -1 terminated array of pressure set IDs. @@ -686,14 +691,6 @@ public: const MachineFunction &MF, const VirtRegMap *VRM = nullptr) const; - /// avoidWriteAfterWrite - Return true if the register allocator should avoid - /// writing a register from RC in two consecutive instructions. - /// This can avoid pipeline stalls on certain architectures. - /// It does cause increased register pressure, though. - virtual bool avoidWriteAfterWrite(const TargetRegisterClass *RC) const { - return false; - } - /// updateRegAllocHint - A callback to allow target a chance to update /// register allocation hints when a register is "changed" (e.g. coalesced) /// to another register. e.g. On ARM, some virtual registers should target @@ -802,9 +799,9 @@ public: llvm_unreachable("resolveFrameIndex does not exist on this target"); } - /// isFrameOffsetLegal - Determine whether a given offset immediate is - /// encodable to resolve a frame index. - virtual bool isFrameOffsetLegal(const MachineInstr *MI, + /// isFrameOffsetLegal - Determine whether a given base register plus offset + /// immediate is encodable to resolve a frame index. + virtual bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg, int64_t Offset) const { llvm_unreachable("isFrameOffsetLegal does not exist on this target"); } diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index d297162..5388962 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -68,6 +68,18 @@ class SDTCisSubVecOfVec<int ThisOp, int OtherOp> int OtherOpNum = OtherOp; } +// SDTCVecEltisVT - The specified operand is vector type with element type +// of VT. +class SDTCVecEltisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> { + ValueType VT = vt; +} + +// SDTCisSameNumEltsAs - The two specified operands have identical number +// of elements. +class SDTCisSameNumEltsAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { + int OtherOperandNum = OtherOp; +} + //===----------------------------------------------------------------------===// // Selection DAG Type Profile definitions. // @@ -196,14 +208,6 @@ def SDTMaskedLoad: SDTypeProfile<1, 3, [ // masked load SDTCisVec<0>, SDTCisPtrTy<1>, SDTCisVec<2>, SDTCisSameAs<0, 3> ]>; -def SDTMaskedGather: SDTypeProfile<1, 3, [ // masked gather - SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisVec<2> -]>; - -def SDTMaskedScatter: SDTypeProfile<1, 3, [ // masked scatter - SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<0, 2> -]>; - def SDTVecShuffle : SDTypeProfile<1, 2, [ SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2> ]>; @@ -476,10 +480,6 @@ def masked_store : SDNode<"ISD::MSTORE", SDTMaskedStore, [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; def masked_load : SDNode<"ISD::MLOAD", SDTMaskedLoad, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; -def masked_scatter : SDNode<"ISD::MSCATTER", SDTMaskedScatter, - [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; -def masked_gather : SDNode<"ISD::MGATHER", SDTMaskedGather, - [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; // Do not use ld, st directly. Use load, extload, sextload, zextload, store, // and truncst (see below). diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h index 83ab4ec..bb5409b6 100644 --- a/include/llvm/Target/TargetSubtargetInfo.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -94,16 +94,24 @@ public: return 0; } - /// \brief Temporary API to test migration to MI scheduler. - bool useMachineScheduler() const; - /// \brief True if the subtarget should run MachineScheduler after aggressive /// coalescing. /// /// This currently replaces the SelectionDAG scheduler with the "source" order - /// scheduler. It does not yet disable the postRA scheduler. + /// scheduler (though see below for an option to turn this off and use the + /// TargetLowering preference). It does not yet disable the postRA scheduler. virtual bool enableMachineScheduler() const; + /// \brief True if the machine scheduler should disable the TLI preference + /// for preRA scheduling with the source level scheduler. + virtual bool enableMachineSchedDefaultSched() const { return true; } + + /// \brief True if the subtarget should enable joining global copies. + /// + /// By default this is enabled if the machine scheduler is enabled, but + /// can be overridden. + virtual bool enableJoinGlobalCopies() const; + /// \brief True if the subtarget should run PostMachineScheduler. /// /// This only takes effect if the target has configured the diff --git a/include/llvm/Transforms/IPO/LowerBitSets.h b/include/llvm/Transforms/IPO/LowerBitSets.h index 0f60617..55d7d84 100644 --- a/include/llvm/Transforms/IPO/LowerBitSets.h +++ b/include/llvm/Transforms/IPO/LowerBitSets.h @@ -30,8 +30,8 @@ class GlobalVariable; class Value; struct BitSetInfo { - // The actual bitset. - std::vector<uint8_t> Bits; + // The indices of the set bits in the bitset. + std::set<uint64_t> Bits; // The byte offset into the combined global represented by the bitset. uint64_t ByteOffset; @@ -45,26 +45,18 @@ struct BitSetInfo { unsigned AlignLog2; bool isSingleOffset() const { - return Bits.size() == 1 && Bits[0] == 1; + return Bits.size() == 1; } bool isAllOnes() const { - for (unsigned I = 0; I != Bits.size() - 1; ++I) - if (Bits[I] != 0xFF) - return false; - - if (BitSize % 8 == 0) - return Bits[Bits.size() - 1] == 0xFF; - - return Bits[Bits.size() - 1] == (1 << (BitSize % 8)) - 1; + return Bits.size() == BitSize; } bool containsGlobalOffset(uint64_t Offset) const; - bool containsValue(const DataLayout *DL, + bool containsValue(const DataLayout &DL, const DenseMap<GlobalVariable *, uint64_t> &GlobalLayout, Value *V, uint64_t COffset = 0) const; - }; struct BitSetBuilder { @@ -148,6 +140,59 @@ struct GlobalLayoutBuilder { void addFragment(const std::set<uint64_t> &F); }; +/// This class is used to build a byte array containing overlapping bit sets. By +/// loading from indexed offsets into the byte array and applying a mask, a +/// program can test bits from the bit set with a relatively short instruction +/// sequence. For example, suppose we have 15 bit sets to lay out: +/// +/// A (16 bits), B (15 bits), C (14 bits), D (13 bits), E (12 bits), +/// F (11 bits), G (10 bits), H (9 bits), I (7 bits), J (6 bits), K (5 bits), +/// L (4 bits), M (3 bits), N (2 bits), O (1 bit) +/// +/// These bits can be laid out in a 16-byte array like this: +/// +/// Byte Offset +/// 0123456789ABCDEF +/// Bit +/// 7 HHHHHHHHHIIIIIII +/// 6 GGGGGGGGGGJJJJJJ +/// 5 FFFFFFFFFFFKKKKK +/// 4 EEEEEEEEEEEELLLL +/// 3 DDDDDDDDDDDDDMMM +/// 2 CCCCCCCCCCCCCCNN +/// 1 BBBBBBBBBBBBBBBO +/// 0 AAAAAAAAAAAAAAAA +/// +/// For example, to test bit X of A, we evaluate ((bits[X] & 1) != 0), or to +/// test bit X of I, we evaluate ((bits[9 + X] & 0x80) != 0). This can be done +/// in 1-2 machine instructions on x86, or 4-6 instructions on ARM. +/// +/// This is a byte array, rather than (say) a 2-byte array or a 4-byte array, +/// because for one thing it gives us better packing (the more bins there are, +/// the less evenly they will be filled), and for another, the instruction +/// sequences can be slightly shorter, both on x86 and ARM. +struct ByteArrayBuilder { + /// The byte array built so far. + std::vector<uint8_t> Bytes; + + enum { BitsPerByte = 8 }; + + /// The number of bytes allocated so far for each of the bits. + uint64_t BitAllocs[BitsPerByte]; + + ByteArrayBuilder() { + memset(BitAllocs, 0, sizeof(BitAllocs)); + } + + /// Allocate BitSize bits in the byte array where Bits contains the bits to + /// set. AllocByteOffset is set to the offset within the byte array and + /// AllocMask is set to the bitmask for those bits. This uses the LPT (Longest + /// Processing Time) multiprocessor scheduling algorithm to lay out the bits + /// efficiently; the pass allocates bit sets in decreasing size order. + void allocate(const std::set<uint64_t> &Bits, uint64_t BitSize, + uint64_t &AllocByteOffset, uint8_t &AllocMask); +}; + } // namespace llvm #endif diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h index 65f4712..5d574ae 100644 --- a/include/llvm/Transforms/IPO/PassManagerBuilder.h +++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -120,7 +120,6 @@ public: bool DisableGVNLoadPRE; bool VerifyInput; bool VerifyOutput; - bool StripDebug; bool MergeFunctions; private: @@ -141,6 +140,7 @@ private: legacy::PassManagerBase &PM) const; void addInitialAliasAnalysisPasses(legacy::PassManagerBase &PM) const; void addLTOOptimizationPasses(legacy::PassManagerBase &PM); + void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM); public: /// populateFunctionPassManager - This fills in the function pass manager, diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index 8fac6ca..a147793 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -60,6 +60,10 @@ struct GCOVOptions { // Emit the name of the function in the .gcda files. This is redundant, as // the function identifier can be used to find the name from the .gcno file. bool FunctionNamesInData; + + // Emit the exit block immediately after the start block, rather than after + // all of the function body's blocks. + bool ExitBlockBeforeBody; }; ModulePass *createGCOVProfilerPass(const GCOVOptions &Options = GCOVOptions::getDefault()); diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index 558b81e..2d754d0 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -140,6 +140,13 @@ Pass *createLICMPass(); //===----------------------------------------------------------------------===// // +// LoopInterchange - This pass interchanges loops to provide a more +// cache-friendly memory access patterns. +// +Pass *createLoopInterchangePass(); + +//===----------------------------------------------------------------------===// +// // LoopStrengthReduce - This pass is strength reduces GEP instructions that use // a loop's canonical induction variable as one of their indices. // @@ -422,7 +429,6 @@ BasicBlockPass *createLoadCombinePass(); FunctionPass *createStraightLineStrengthReducePass(); - //===----------------------------------------------------------------------===// // // PlaceSafepoints - Rewrite any IR calls to gc.statepoints and insert any diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h index 6387c16..879f295 100644 --- a/include/llvm/Transforms/Utils/BuildLibCalls.h +++ b/include/llvm/Transforms/Utils/BuildLibCalls.h @@ -28,52 +28,50 @@ namespace llvm { /// EmitStrLen - Emit a call to the strlen function to the builder, for the /// specified pointer. Ptr is required to be some pointer type, and the /// return value has 'intptr_t' type. - Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD, + Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL, const TargetLibraryInfo *TLI); /// EmitStrNLen - Emit a call to the strnlen function to the builder, for the /// specified pointer. Ptr is required to be some pointer type, MaxLen must /// be of size_t type, and the return value has 'intptr_t' type. Value *EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B, - const DataLayout *TD, const TargetLibraryInfo *TLI); + const DataLayout &DL, const TargetLibraryInfo *TLI); /// EmitStrChr - Emit a call to the strchr function to the builder, for the /// specified pointer and character. Ptr is required to be some pointer type, /// and the return value has 'i8*' type. - Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const DataLayout *TD, + Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const TargetLibraryInfo *TLI); /// EmitStrNCmp - Emit a call to the strncmp function to the builder. Value *EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - const DataLayout *TD, const TargetLibraryInfo *TLI); + const DataLayout &DL, const TargetLibraryInfo *TLI); /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the /// specified pointer arguments. Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, - const DataLayout *TD, const TargetLibraryInfo *TLI, - StringRef Name = "strcpy"); + const TargetLibraryInfo *TLI, StringRef Name = "strcpy"); /// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the /// specified pointer arguments and length. Value *EmitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, - const DataLayout *TD, const TargetLibraryInfo *TLI, - StringRef Name = "strncpy"); + const TargetLibraryInfo *TLI, StringRef Name = "strncpy"); /// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder. /// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src /// are pointers. Value *EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, - IRBuilder<> &B, const DataLayout *TD, + IRBuilder<> &B, const DataLayout &DL, const TargetLibraryInfo *TLI); /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, - const DataLayout *TD, const TargetLibraryInfo *TLI); + const DataLayout &DL, const TargetLibraryInfo *TLI); /// EmitMemCmp - Emit a call to the memcmp function. Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, - const DataLayout *TD, const TargetLibraryInfo *TLI); + const DataLayout &DL, const TargetLibraryInfo *TLI); /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' /// (e.g. 'floor'). This function is known to take a single of type matching @@ -93,28 +91,26 @@ namespace llvm { /// EmitPutChar - Emit a call to the putchar function. This assumes that Char /// is an integer. - Value *EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD, - const TargetLibraryInfo *TLI); + Value *EmitPutChar(Value *Char, IRBuilder<> &B, const TargetLibraryInfo *TLI); /// EmitPutS - Emit a call to the puts function. This assumes that Str is /// some pointer. - Value *EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD, - const TargetLibraryInfo *TLI); + Value *EmitPutS(Value *Str, IRBuilder<> &B, const TargetLibraryInfo *TLI); /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is /// an i32, and File is a pointer to FILE. Value *EmitFPutC(Value *Char, Value *File, IRBuilder<> &B, - const DataLayout *TD, const TargetLibraryInfo *TLI); + const TargetLibraryInfo *TLI); /// EmitFPutS - Emit a call to the puts function. Str is required to be a /// pointer and File is a pointer to FILE. - Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const DataLayout *TD, + Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const TargetLibraryInfo *TLI); /// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE. Value *EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B, - const DataLayout *TD, const TargetLibraryInfo *TLI); + const DataLayout &DL, const TargetLibraryInfo *TLI); } #endif diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index d1563ef..cb187ec 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -144,7 +144,9 @@ public: ///< Skip this instruction but continue cloning the current basic block. SkipInstruction, ///< Skip this instruction and stop cloning the current basic block. - StopCloningBB + StopCloningBB, + ///< Don't clone the terminator but clone the current block's successors. + CloneSuccessors }; virtual ~CloningDirector() {} @@ -164,7 +166,6 @@ void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, SmallVectorImpl<ReturnInst*> &Returns, const char *NameSuffix = "", ClonedCodeInfo *CodeInfo = nullptr, - const DataLayout *DL = nullptr, CloningDirector *Director = nullptr); @@ -184,7 +185,6 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, SmallVectorImpl<ReturnInst*> &Returns, const char *NameSuffix = "", ClonedCodeInfo *CodeInfo = nullptr, - const DataLayout *DL = nullptr, Instruction *TheCall = nullptr); /// InlineFunctionInfo - This class captures the data input to the @@ -192,15 +192,13 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, class InlineFunctionInfo { public: explicit InlineFunctionInfo(CallGraph *cg = nullptr, - const DataLayout *DL = nullptr, AliasAnalysis *AA = nullptr, AssumptionCacheTracker *ACT = nullptr) - : CG(cg), DL(DL), AA(AA), ACT(ACT) {} + : CG(cg), AA(AA), ACT(ACT) {} /// CG - If non-null, InlineFunction will update the callgraph to reflect the /// changes it makes. CallGraph *CG; - const DataLayout *DL; AliasAnalysis *AA; AssumptionCacheTracker *ACT; diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 463ab96..e89169c 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -88,7 +88,7 @@ bool RecursivelyDeleteDeadPHINode(PHINode *PN, /// /// This returns true if it changed the code, note that it can delete /// instructions in other blocks as well in this block. -bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = nullptr, +bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetLibraryInfo *TLI = nullptr); //===----------------------------------------------------------------------===// @@ -106,8 +106,7 @@ bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = nullptr, /// /// .. and delete the predecessor corresponding to the '1', this will attempt to /// recursively fold the 'and' to 0. -void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred, - DataLayout *TD = nullptr); +void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred); /// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its /// predecessor is known to have one successor (BB!). Eliminate the edge @@ -137,8 +136,7 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB); /// the basic block that was pointed to. /// bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI, - unsigned BonusInstThreshold, const DataLayout *TD = nullptr, - AssumptionCache *AC = nullptr); + unsigned BonusInstThreshold, AssumptionCache *AC = nullptr); /// FlatternCFG - This function is used to flatten a CFG. For /// example, it uses parallel-and and parallel-or mode to collapse @@ -150,8 +148,7 @@ bool FlattenCFG(BasicBlock *BB, AliasAnalysis *AA = nullptr); /// and if a predecessor branches to us and one of our successors, fold the /// setcc into the predecessor and use logical operations to pick the right /// destination. -bool FoldBranchToCommonDest(BranchInst *BI, const DataLayout *DL = nullptr, - unsigned BonusInstThreshold = 1); +bool FoldBranchToCommonDest(BranchInst *BI, unsigned BonusInstThreshold = 1); /// DemoteRegToStack - This function takes a virtual register computed by an /// Instruction and replaces it with a slot in the stack frame, allocated via @@ -173,18 +170,17 @@ AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = nullptr); /// and it is more than the alignment of the ultimate object, see if we can /// increase the alignment of the ultimate object, making this check succeed. unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign, - const DataLayout *TD = nullptr, - AssumptionCache *AC = nullptr, + const DataLayout &DL, const Instruction *CxtI = nullptr, + AssumptionCache *AC = nullptr, const DominatorTree *DT = nullptr); /// getKnownAlignment - Try to infer an alignment for the specified pointer. -static inline unsigned getKnownAlignment(Value *V, - const DataLayout *TD = nullptr, - AssumptionCache *AC = nullptr, +static inline unsigned getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CxtI = nullptr, + AssumptionCache *AC = nullptr, const DominatorTree *DT = nullptr) { - return getOrEnforceKnownAlignment(V, 0, TD, AC, CxtI, DT); + return getOrEnforceKnownAlignment(V, 0, DL, CxtI, AC, DT); } /// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the @@ -192,11 +188,11 @@ static inline unsigned getKnownAlignment(Value *V, /// in the base pointer). Return the result as a signed integer of intptr size. /// When NoAssumptions is true, no assumptions about index computation not /// overflowing is made. -template<typename IRBuilderTy> -Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP, +template <typename IRBuilderTy> +Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions = false) { GEPOperator *GEPOp = cast<GEPOperator>(GEP); - Type *IntPtrTy = TD.getIntPtrType(GEP->getType()); + Type *IntPtrTy = DL.getIntPtrType(GEP->getType()); Value *Result = Constant::getNullValue(IntPtrTy); // If the GEP is inbounds, we know that none of the addressing operations will @@ -211,7 +207,7 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP, for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e; ++i, ++GTI) { Value *Op = *i; - uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask; + uint64_t Size = DL.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask; if (Constant *OpC = dyn_cast<Constant>(Op)) { if (OpC->isZeroValue()) continue; @@ -222,7 +218,7 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP, OpC = OpC->getSplatValue(); uint64_t OpValue = cast<ConstantInt>(OpC)->getZExtValue(); - Size = TD.getStructLayout(STy)->getElementOffset(OpValue); + Size = DL.getStructLayout(STy)->getElementOffset(OpValue); if (Size) Result = Builder->CreateAdd(Result, ConstantInt::get(IntPtrTy, Size), diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h index bb80f20..2eb2555 100644 --- a/include/llvm/Transforms/Utils/LoopUtils.h +++ b/include/llvm/Transforms/Utils/LoopUtils.h @@ -52,7 +52,6 @@ BasicBlock *InsertPreheaderForLoop(Loop *L, Pass *P); /// passed into it. bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, Pass *PP, AliasAnalysis *AA = nullptr, ScalarEvolution *SE = nullptr, - const DataLayout *DL = nullptr, AssumptionCache *AC = nullptr); /// \brief Put loop into LCSSA form. @@ -85,13 +84,13 @@ bool formLCSSARecursively(Loop &L, DominatorTree &DT, LoopInfo *LI, /// dominated by the specified block, and that are in the current loop) in /// reverse depth first order w.r.t the DominatorTree. This allows us to visit /// uses before definitions, allowing us to sink a loop body in one pass without -/// iteration. Takes DomTreeNode, AliasAnalysis, LoopInfo, DominatorTree, -/// DataLayout, TargetLibraryInfo, Loop, AliasSet information for all -/// instructions of the loop and loop safety information as arguments. -/// It returns changed status. +/// iteration. Takes DomTreeNode, AliasAnalysis, LoopInfo, DominatorTree, +/// DataLayout, TargetLibraryInfo, Loop, AliasSet information for all +/// instructions of the loop and loop safety information as arguments. +/// It returns changed status. bool sinkRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *, - const DataLayout *, TargetLibraryInfo *, Loop *, - AliasSetTracker *, LICMSafetyInfo *); + TargetLibraryInfo *, Loop *, AliasSetTracker *, + LICMSafetyInfo *); /// \brief Walk the specified region of the CFG (defined by all blocks /// dominated by the specified block, and that are in the current loop) in depth @@ -101,8 +100,8 @@ bool sinkRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *, /// TargetLibraryInfo, Loop, AliasSet information for all instructions of the /// loop and loop safety information as arguments. It returns changed status. bool hoistRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *, - const DataLayout *, TargetLibraryInfo *, Loop *, - AliasSetTracker *, LICMSafetyInfo *); + TargetLibraryInfo *, Loop *, AliasSetTracker *, + LICMSafetyInfo *); /// \brief Try to promote memory values to scalars by sinking stores out of /// the loop and moving loads to before the loop. We do this by looping over diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h index 08358e1..4115960 100644 --- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -15,6 +15,7 @@ #ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H #define LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/IRBuilder.h" @@ -36,12 +37,11 @@ class Function; /// is unknown) by passing true for OnlyLowerUnknownSize. class FortifiedLibCallSimplifier { private: - const DataLayout *DL; const TargetLibraryInfo *TLI; bool OnlyLowerUnknownSize; public: - FortifiedLibCallSimplifier(const DataLayout *DL, const TargetLibraryInfo *TLI, + FortifiedLibCallSimplifier(const TargetLibraryInfo *TLI, bool OnlyLowerUnknownSize = false); /// \brief Take the given call instruction and return a more @@ -71,7 +71,7 @@ private: class LibCallSimplifier { private: FortifiedLibCallSimplifier FortifiedSimplifier; - const DataLayout *DL; + const DataLayout &DL; const TargetLibraryInfo *TLI; bool UnsafeFPShrink; function_ref<void(Instruction *, Value *)> Replacer; @@ -86,7 +86,7 @@ private: void replaceAllUsesWith(Instruction *I, Value *With); public: - LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI, + LibCallSimplifier(const DataLayout &DL, const TargetLibraryInfo *TLI, function_ref<void(Instruction *, Value *)> Replacer = &replaceAllUsesWithDefault); @@ -116,6 +116,7 @@ private: Value *optimizeStrSpn(CallInst *CI, IRBuilder<> &B); Value *optimizeStrCSpn(CallInst *CI, IRBuilder<> &B); Value *optimizeStrStr(CallInst *CI, IRBuilder<> &B); + Value *optimizeMemChr(CallInst *CI, IRBuilder<> &B); Value *optimizeMemCmp(CallInst *CI, IRBuilder<> &B); Value *optimizeMemCpy(CallInst *CI, IRBuilder<> &B); Value *optimizeMemMove(CallInst *CI, IRBuilder<> &B); diff --git a/include/llvm/module.modulemap b/include/llvm/module.modulemap index 0f9c22e..dc6e136 100644 --- a/include/llvm/module.modulemap +++ b/include/llvm/module.modulemap @@ -2,7 +2,12 @@ module LLVM_Analysis { requires cplusplus umbrella "Analysis" module * { export * } + + // FIXME: Why is this excluded? exclude header "Analysis/BlockFrequencyInfoImpl.h" + + // This is intended for (repeated) textual inclusion. + textual header "Analysis/TargetLibraryInfo.def" } module LLVM_AsmParser { requires cplusplus umbrella "AsmParser" module * { export * } } |