diff options
Diffstat (limited to 'include')
441 files changed, 4713 insertions, 2241 deletions
diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h index 9f37dd71e31c..42c05a2fc59e 100644 --- a/include/llvm-c/lto.h +++ b/include/llvm-c/lto.h @@ -40,7 +40,7 @@ typedef bool lto_bool_t; * @{ */ -#define LTO_API_VERSION 15 +#define LTO_API_VERSION 16 /** * \since prior to LTO_API_VERSION=3 @@ -280,39 +280,15 @@ lto_module_get_symbol_attribute(lto_module_t mod, unsigned int index); /** - * Returns the number of dependent libraries in the object module. + * Returns the module's linker options. * - * \since LTO_API_VERSION=8 - */ -extern unsigned int -lto_module_get_num_deplibs(lto_module_t mod); - - -/** - * Returns the ith dependent library in the module. - * - * \since LTO_API_VERSION=8 - */ -extern const char* -lto_module_get_deplib(lto_module_t mod, unsigned int index); - - -/** - * Returns the number of linker options in the object module. - * - * \since LTO_API_VERSION=8 - */ -extern unsigned int -lto_module_get_num_linkeropts(lto_module_t mod); - - -/** - * Returns the ith linker option in the module. + * The linker options may consist of multiple flags. It is the linker's + * responsibility to split the flags using a platform-specific mechanism. * - * \since LTO_API_VERSION=8 + * \since LTO_API_VERSION=16 */ extern const char* -lto_module_get_linkeropt(lto_module_t mod, unsigned int index); +lto_module_get_linkeropts(lto_module_t mod); /** diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index a790203434b7..5013f295f5c7 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -1038,7 +1038,9 @@ public: /// the validity of the less-than relationship. /// /// \returns true if *this < RHS when considered unsigned. - bool ult(uint64_t RHS) const { return ult(APInt(getBitWidth(), RHS)); } + bool ult(uint64_t RHS) const { + return getActiveBits() > 64 ? false : getZExtValue() < RHS; + } /// \brief Signed less than comparison /// @@ -1054,7 +1056,9 @@ public: /// the validity of the less-than relationship. /// /// \returns true if *this < RHS when considered signed. - bool slt(uint64_t RHS) const { return slt(APInt(getBitWidth(), RHS)); } + bool slt(int64_t RHS) const { + return getMinSignedBits() > 64 ? isNegative() : getSExtValue() < RHS; + } /// \brief Unsigned less or equal comparison /// @@ -1070,7 +1074,7 @@ public: /// the validity of the less-or-equal relationship. /// /// \returns true if *this <= RHS when considered unsigned. - bool ule(uint64_t RHS) const { return ule(APInt(getBitWidth(), RHS)); } + bool ule(uint64_t RHS) const { return !ugt(RHS); } /// \brief Signed less or equal comparison /// @@ -1086,7 +1090,7 @@ public: /// validity of the less-or-equal relationship. /// /// \returns true if *this <= RHS when considered signed. - bool sle(uint64_t RHS) const { return sle(APInt(getBitWidth(), RHS)); } + bool sle(uint64_t RHS) const { return !sgt(RHS); } /// \brief Unsigned greather than comparison /// @@ -1102,7 +1106,9 @@ public: /// the validity of the greater-than relationship. /// /// \returns true if *this > RHS when considered unsigned. - bool ugt(uint64_t RHS) const { return ugt(APInt(getBitWidth(), RHS)); } + bool ugt(uint64_t RHS) const { + return getActiveBits() > 64 ? true : getZExtValue() > RHS; + } /// \brief Signed greather than comparison /// @@ -1118,7 +1124,9 @@ public: /// the validity of the greater-than relationship. /// /// \returns true if *this > RHS when considered signed. - bool sgt(uint64_t RHS) const { return sgt(APInt(getBitWidth(), RHS)); } + bool sgt(int64_t RHS) const { + return getMinSignedBits() > 64 ? !isNegative() : getSExtValue() > RHS; + } /// \brief Unsigned greater or equal comparison /// @@ -1134,7 +1142,7 @@ public: /// the validity of the greater-or-equal relationship. /// /// \returns true if *this >= RHS when considered unsigned. - bool uge(uint64_t RHS) const { return uge(APInt(getBitWidth(), RHS)); } + bool uge(uint64_t RHS) const { return !ult(RHS); } /// \brief Signed greather or equal comparison /// @@ -1150,7 +1158,7 @@ public: /// the validity of the greater-or-equal relationship. /// /// \returns true if *this >= RHS when considered signed. - bool sge(uint64_t RHS) const { return sge(APInt(getBitWidth(), RHS)); } + bool sge(int64_t RHS) const { return !slt(RHS); } /// This operation tests if there are any pairs of corresponding bits /// between this APInt and RHS that are both set. @@ -1896,11 +1904,11 @@ inline APInt Xor(const APInt &LHS, const APInt &RHS) { return LHS ^ RHS; } /// Performs a bitwise complement operation on APInt. inline APInt Not(const APInt &APIVal) { return ~APIVal; } -} // namespace APIntOps +} // End of APIntOps namespace // See friend declaration above. This additional declaration is required in // order to compile LLVM with IBM xlC compiler. hash_code hash_value(const APInt &Arg); -} // namespace llvm +} // End of llvm namespace #endif diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h index 91ccda22f2f0..a187515f8592 100644 --- a/include/llvm/ADT/APSInt.h +++ b/include/llvm/ADT/APSInt.h @@ -33,6 +33,15 @@ public: explicit APSInt(APInt I, bool isUnsigned = true) : APInt(std::move(I)), IsUnsigned(isUnsigned) {} + /// Construct an APSInt from a string representation. + /// + /// This constructor interprets the string \p Str using the radix of 10. + /// The interpretation stops at the end of the string. The bit width of the + /// constructed APSInt is determined automatically. + /// + /// \param Str the string to be interpreted. + explicit APSInt(StringRef Str); + APSInt &operator=(APInt RHS) { // Retain our current sign. APInt::operator=(std::move(RHS)); diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index 397e2ee1f6e4..c8795fd89e33 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -286,6 +286,11 @@ namespace llvm { return MutableArrayRef<T>(data()+N, M); } + MutableArrayRef<T> drop_back(unsigned N) const { + assert(this->size() >= N && "Dropping more elements than exist"); + return slice(0, this->size() - N); + } + /// @} /// @name Operator Overloads /// @{ @@ -361,6 +366,6 @@ namespace llvm { template <typename T> struct isPodLike<ArrayRef<T> > { static const bool value = true; }; -} // namespace llvm +} #endif diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index e57171de9cd7..f58dd7356c7d 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -568,7 +568,7 @@ private: } }; -} // namespace llvm +} // End llvm namespace namespace std { /// Implement std::swap in terms of BitVector swap. diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index bf58becd722d..27f73157a29f 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -42,7 +42,7 @@ struct DenseMapPair : public std::pair<KeyT, ValueT> { ValueT &getSecond() { return std::pair<KeyT, ValueT>::second; } const ValueT &getSecond() const { return std::pair<KeyT, ValueT>::second; } }; -} // namespace detail +} template < typename KeyT, typename ValueT, typename KeyInfoT = DenseMapInfo<KeyT>, diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h index 6f17a647b63d..b0a053072079 100644 --- a/include/llvm/ADT/DenseMapInfo.h +++ b/include/llvm/ADT/DenseMapInfo.h @@ -14,6 +14,8 @@ #ifndef LLVM_ADT_DENSEMAPINFO_H #define LLVM_ADT_DENSEMAPINFO_H +#include "llvm/ADT/Hashing.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include "llvm/Support/type_traits.h" @@ -163,6 +165,31 @@ struct DenseMapInfo<std::pair<T, U> > { } }; +// Provide DenseMapInfo for StringRefs. +template <> struct DenseMapInfo<StringRef> { + static inline StringRef getEmptyKey() { + return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)), + 0); + } + static inline StringRef getTombstoneKey() { + return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)), + 0); + } + static unsigned getHashValue(StringRef Val) { + assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!"); + assert(Val.data() != getTombstoneKey().data() && + "Cannot hash the tombstone key!"); + return (unsigned)(hash_value(Val)); + } + static bool isEqual(StringRef LHS, StringRef RHS) { + if (RHS.data() == getEmptyKey().data()) + return LHS.data() == getEmptyKey().data(); + if (RHS.data() == getTombstoneKey().data()) + return LHS.data() == getTombstoneKey().data(); + return LHS == RHS; + } +}; + } // end namespace llvm #endif diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h index b1631be77ad9..d34024005dfe 100644 --- a/include/llvm/ADT/DenseSet.h +++ b/include/llvm/ADT/DenseSet.h @@ -32,7 +32,7 @@ public: DenseSetEmpty &getSecond() { return *this; } const DenseSetEmpty &getSecond() const { return *this; } }; -} // namespace detail +} /// DenseSet - This implements a dense probed hash-table based set. template<typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT> > diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h index 01bbe1a2dcf9..d79b9acacfa9 100644 --- a/include/llvm/ADT/DepthFirstIterator.h +++ b/include/llvm/ADT/DepthFirstIterator.h @@ -288,6 +288,6 @@ iterator_range<idf_ext_iterator<T, SetTy>> inverse_depth_first_ext(const T& G, return make_range(idf_ext_begin(G, S), idf_ext_end(G, S)); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h index 6e87dbd96ba7..d6a26f88e67d 100644 --- a/include/llvm/ADT/EquivalenceClasses.h +++ b/include/llvm/ADT/EquivalenceClasses.h @@ -278,6 +278,6 @@ public: }; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/GraphTraits.h b/include/llvm/ADT/GraphTraits.h index 21bf23b92af4..823caef7647e 100644 --- a/include/llvm/ADT/GraphTraits.h +++ b/include/llvm/ADT/GraphTraits.h @@ -101,6 +101,6 @@ struct GraphTraits<Inverse<Inverse<T> > > { } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/IndexedMap.h b/include/llvm/ADT/IndexedMap.h index ae9c695ec12f..5ba85c027920 100644 --- a/include/llvm/ADT/IndexedMap.h +++ b/include/llvm/ADT/IndexedMap.h @@ -80,6 +80,6 @@ template <typename T, typename ToIndexT = llvm::identity<unsigned> > } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/IntEqClasses.h b/include/llvm/ADT/IntEqClasses.h index 9dbc228383e8..8e75c48e3764 100644 --- a/include/llvm/ADT/IntEqClasses.h +++ b/include/llvm/ADT/IntEqClasses.h @@ -83,6 +83,6 @@ public: void uncompress(); }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h index dd484979aedc..855ab890392e 100644 --- a/include/llvm/ADT/Optional.h +++ b/include/llvm/ADT/Optional.h @@ -204,6 +204,6 @@ void operator>=(const Optional<T> &X, const Optional<U> &Y); template<typename T, typename U> void operator>(const Optional<T> &X, const Optional<U> &Y); -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index 3c63a522e1c7..f27b81113ec5 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -507,6 +507,6 @@ namespace llvm { RHS.template get<U>())); } }; -} // namespace llvm +} #endif diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h index 059d7b001194..759a2db24f2a 100644 --- a/include/llvm/ADT/PostOrderIterator.h +++ b/include/llvm/ADT/PostOrderIterator.h @@ -295,6 +295,6 @@ public: rpo_iterator end() { return Blocks.rend(); } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/PriorityQueue.h b/include/llvm/ADT/PriorityQueue.h index 869ef815b06e..827d0b346e59 100644 --- a/include/llvm/ADT/PriorityQueue.h +++ b/include/llvm/ADT/PriorityQueue.h @@ -79,6 +79,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h index dc78274fb5f5..bc74416ac88b 100644 --- a/include/llvm/ADT/SCCIterator.h +++ b/include/llvm/ADT/SCCIterator.h @@ -240,6 +240,6 @@ template <class T> scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) { return scc_iterator<Inverse<T> >::end(G); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index 14204c130af6..b68345a1dcf6 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -417,6 +417,6 @@ template <typename T> struct deref { } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/SetOperations.h b/include/llvm/ADT/SetOperations.h index b5f41776caf0..71f5db380f6e 100644 --- a/include/llvm/ADT/SetOperations.h +++ b/include/llvm/ADT/SetOperations.h @@ -66,6 +66,6 @@ void set_subtract(S1Ty &S1, const S2Ty &S2) { S1.erase(*SI); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h index f15f4f7ac245..a7fd408c854a 100644 --- a/include/llvm/ADT/SetVector.h +++ b/include/llvm/ADT/SetVector.h @@ -225,7 +225,7 @@ public: } }; -} // namespace llvm +} // End llvm namespace // vim: sw=2 ai #endif diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index a74b7bf68d25..ae3d645396fd 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -588,7 +588,7 @@ operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) { return Result; } -} // namespace llvm +} // End llvm namespace namespace std { /// Implement std::swap in terms of BitVector swap. diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index 0d1635ae01e9..3e3c9c154ef4 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -334,7 +334,7 @@ public: } }; -} // namespace llvm +} namespace std { /// Implement std::swap in terms of SmallPtrSet swap. diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h index 92cd6892621c..e569f54481a2 100644 --- a/include/llvm/ADT/SmallString.h +++ b/include/llvm/ADT/SmallString.h @@ -292,6 +292,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index b334ac0423a0..5b208b76a21f 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -924,7 +924,7 @@ static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) { return X.capacity_in_bytes(); } -} // namespace llvm +} // End llvm namespace namespace std { /// Implement std::swap in terms of SmallVector swap. @@ -940,6 +940,6 @@ namespace std { swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) { LHS.swap(RHS); } -} // namespace std +} #endif diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h index 264c6b54eccd..d98abc375e8a 100644 --- a/include/llvm/ADT/Statistic.h +++ b/include/llvm/ADT/Statistic.h @@ -176,6 +176,6 @@ void PrintStatistics(); /// \brief Print statistics to the given output stream. void PrintStatistics(raw_ostream &OS); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 5e8c072761af..0992f5d4a549 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -207,6 +207,6 @@ inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) { return join_impl(Begin, End, Separator, tag()); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index c8ece8fb307d..8721c73b95b1 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -447,6 +447,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index 163ec6361944..95660a49f1f1 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -566,6 +566,6 @@ namespace llvm { // StringRefs can be treated like a POD type. template <typename T> struct isPodLike; template <> struct isPodLike<StringRef> { static const bool value = true; }; -} // namespace llvm +} #endif diff --git a/include/llvm/ADT/StringSet.h b/include/llvm/ADT/StringSet.h index 7c5247692225..3e0cc200b6dd 100644 --- a/include/llvm/ADT/StringSet.h +++ b/include/llvm/ADT/StringSet.h @@ -29,6 +29,6 @@ namespace llvm { return base::insert(std::make_pair(Key, '\0')); } }; -} // namespace llvm +} #endif // LLVM_ADT_STRINGSET_H diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index cb6edc8c3e95..06f5870119c8 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -85,7 +85,9 @@ public: spir64, // SPIR: standard portable IR for OpenCL 64-bit version kalimba, // Kalimba: generic kalimba shave, // SHAVE: Movidius vector VLIW processors - LastArchType = shave + wasm32, // WebAssembly with 32-bit pointers + wasm64, // WebAssembly with 64-bit pointers + LastArchType = wasm64 }; enum SubArchType { NoSubArch, @@ -609,7 +611,7 @@ public: /// @} }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h index db4a5be54917..db0bf4b68de8 100644 --- a/include/llvm/ADT/Twine.h +++ b/include/llvm/ADT/Twine.h @@ -537,6 +537,6 @@ namespace llvm { } /// @} -} // namespace llvm +} #endif diff --git a/include/llvm/ADT/edit_distance.h b/include/llvm/ADT/edit_distance.h index 5fc4beea782e..c2b2041242aa 100644 --- a/include/llvm/ADT/edit_distance.h +++ b/include/llvm/ADT/edit_distance.h @@ -97,6 +97,6 @@ unsigned ComputeEditDistance(ArrayRef<T> FromArray, ArrayRef<T> ToArray, return Result; } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h index 4f101674e716..a7b9306b3a73 100644 --- a/include/llvm/ADT/ilist.h +++ b/include/llvm/ADT/ilist.h @@ -655,7 +655,7 @@ struct ilist : public iplist<NodeTy> { void resize(size_type newsize) { resize(newsize, NodeTy()); } }; -} // namespace llvm +} // End llvm namespace namespace std { // Ensure that swap uses the fast list swap... diff --git a/include/llvm/ADT/ilist_node.h b/include/llvm/ADT/ilist_node.h index 14ca26bffd33..26d0b55e4093 100644 --- a/include/llvm/ADT/ilist_node.h +++ b/include/llvm/ADT/ilist_node.h @@ -101,6 +101,6 @@ public: /// @} }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ADT/iterator.h b/include/llvm/ADT/iterator.h index 28728cac0f57..c30792892703 100644 --- a/include/llvm/ADT/iterator.h +++ b/include/llvm/ADT/iterator.h @@ -162,6 +162,8 @@ protected: int>::type = 0) : I(std::forward<U &&>(u)) {} + const WrappedIteratorT &wrapped() const { return I; } + public: typedef DifferenceTypeT difference_type; @@ -239,6 +241,6 @@ struct pointee_iterator T &operator*() const { return **this->I; } }; -} // namespace llvm +} #endif diff --git a/include/llvm/ADT/iterator_range.h b/include/llvm/ADT/iterator_range.h index 009b7161aada..523a86f02e08 100644 --- a/include/llvm/ADT/iterator_range.h +++ b/include/llvm/ADT/iterator_range.h @@ -51,6 +51,6 @@ template <class T> iterator_range<T> make_range(T x, T y) { template <typename T> iterator_range<T> make_range(std::pair<T, T> p) { return iterator_range<T>(std::move(p.first), std::move(p.second)); } -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index 7f037fb5e813..f4c1167314a1 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -56,6 +56,34 @@ class MemTransferInst; class MemIntrinsic; class DominatorTree; +/// The possible results of an alias query. +/// +/// These results are always computed between two MemoryLocation objects as +/// a query to some alias analysis. +/// +/// Note that these are unscoped enumerations because we would like to support +/// implicitly testing a result for the existence of any possible aliasing with +/// a conversion to bool, but an "enum class" doesn't support this. The +/// canonical names from the literature are suffixed and unique anyways, and so +/// they serve as global constants in LLVM for these results. +/// +/// See docs/AliasAnalysis.html for more information on the specific meanings +/// of these values. +enum AliasResult { + /// The two locations do not alias at all. + /// + /// This value is arranged to convert to false, while all other values + /// convert to true. This allows a boolean context to convert the result to + /// a binary flag indicating whether there is the possibility of aliasing. + NoAlias = 0, + /// The two locations may or may not alias. This is the least precise result. + MayAlias, + /// The two locations alias, but only due to a partial overlap. + PartialAlias, + /// The two locations precisely alias each other. + MustAlias, +}; + class AliasAnalysis { protected: const DataLayout *DL; @@ -95,22 +123,6 @@ public: /// Alias Queries... /// - /// Alias analysis result - Either we know for sure that it does not alias, we - /// know for sure it must alias, or we don't know anything: The two pointers - /// _might_ alias. This enum is designed so you can do things like: - /// if (AA.alias(P1, P2)) { ... } - /// to check to see if two pointers might alias. - /// - /// See docs/AliasAnalysis.html for more information on the specific meanings - /// of these values. - /// - enum AliasResult { - NoAlias = 0, ///< No dependencies. - MayAlias, ///< Anything goes. - PartialAlias, ///< Pointers differ, but pointees overlap. - MustAlias ///< Pointers are equal. - }; - /// alias - The main low level interface to the alias analysis implementation. /// Returns an AliasResult indicating whether the two pointers are aliased to /// each other. This is the interface that must be implemented by specific @@ -558,6 +570,6 @@ bool isIdentifiedObject(const Value *V); /// IdentifiedObjects. bool isIdentifiedFunctionLocal(const Value *V); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index ba2eae903da6..881699d09225 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -117,24 +117,30 @@ class AliasSet : public ilist_node<AliasSet> { // AliasSets forwarding to it. unsigned RefCount : 28; - /// AccessType - Keep track of whether this alias set merely refers to the - /// locations of memory, whether it modifies the memory, or whether it does - /// both. The lattice goes from "NoModRef" to either Refs or Mods, then to - /// ModRef as necessary. + /// The kinds of access this alias set models. /// - enum AccessType { - NoModRef = 0, Refs = 1, // Ref = bit 1 - Mods = 2, ModRef = 3 // Mod = bit 2 + /// We keep track of whether this alias set merely refers to the locations of + /// memory (and not any particular access), whether it modifies or references + /// the memory, or whether it does both. The lattice goes from "NoAccess" to + /// either RefAccess or ModAccess, then to ModRefAccess as necessary. + enum AccessLattice { + NoAccess = 0, + RefAccess = 1, + ModAccess = 2, + ModRefAccess = RefAccess | ModAccess }; - unsigned AccessTy : 2; + unsigned Access : 2; - /// AliasType - Keep track the relationships between the pointers in the set. - /// Lattice goes from MustAlias to MayAlias. + /// The kind of alias relationship between pointers of the set. /// - enum AliasType { - MustAlias = 0, MayAlias = 1 + /// These represent conservatively correct alias results between any members + /// of the set. We represent these independently of the values of alias + /// results in order to pack it into a single bit. Lattice goes from + /// MustAlias to MayAlias. + enum AliasLattice { + SetMustAlias = 0, SetMayAlias = 1 }; - unsigned AliasTy : 1; + unsigned Alias : 1; // Volatile - True if this alias set contains volatile loads or stores. bool Volatile : 1; @@ -153,10 +159,10 @@ class AliasSet : public ilist_node<AliasSet> { public: /// Accessors... - bool isRef() const { return AccessTy & Refs; } - bool isMod() const { return AccessTy & Mods; } - bool isMustAlias() const { return AliasTy == MustAlias; } - bool isMayAlias() const { return AliasTy == MayAlias; } + bool isRef() const { return Access & RefAccess; } + bool isMod() const { return Access & ModAccess; } + bool isMustAlias() const { return Alias == SetMustAlias; } + bool isMayAlias() const { return Alias == SetMayAlias; } // isVolatile - Return true if this alias set contains volatile loads or // stores. @@ -218,7 +224,7 @@ private: friend struct ilist_sentinel_traits<AliasSet>; AliasSet() : PtrList(nullptr), PtrListEnd(&PtrList), Forward(nullptr), RefCount(0), - AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) { + Access(NoAccess), Alias(SetMustAlias), Volatile(false) { } AliasSet(const AliasSet &AS) = delete; @@ -419,11 +425,11 @@ private: } AliasSet &addPointer(Value *P, uint64_t Size, const AAMDNodes &AAInfo, - AliasSet::AccessType E, + AliasSet::AccessLattice E, bool &NewSet) { NewSet = false; AliasSet &AS = getAliasSetForPointer(P, Size, AAInfo, &NewSet); - AS.AccessTy |= E; + AS.Access |= E; return AS; } AliasSet *findAliasSetForPointer(const Value *Ptr, uint64_t Size, @@ -437,6 +443,6 @@ inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) { return OS; } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/BlockFrequencyInfo.h b/include/llvm/Analysis/BlockFrequencyInfo.h index 382c080a2c03..f27c32df9283 100644 --- a/include/llvm/Analysis/BlockFrequencyInfo.h +++ b/include/llvm/Analysis/BlockFrequencyInfo.h @@ -63,6 +63,6 @@ public: }; -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h index bf24f66cbca9..32d96090f456 100644 --- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h @@ -628,7 +628,7 @@ void IrreducibleGraph::addEdges(const BlockNode &Node, else addBlockEdges(*this, Irr, OuterLoop); } -} // namespace bfi_detail +} /// \brief Shared implementation for block frequency analysis. /// @@ -1133,7 +1133,7 @@ template <class BT> struct BlockEdgesAdder { G.addEdge(Irr, BFI.getNode(*I), OuterLoop); } }; -} // namespace bfi_detail +} template <class BT> void BlockFrequencyInfoImpl<BT>::computeIrreducibleMass( LoopData *OuterLoop, std::list<LoopData>::iterator Insert) { diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h index f2ca3e0d07cf..9d867567ba29 100644 --- a/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/include/llvm/Analysis/BranchProbabilityInfo.h @@ -158,6 +158,6 @@ private: bool calcInvokeHeuristics(BasicBlock *BB); }; -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/CFG.h b/include/llvm/Analysis/CFG.h index f837cb4f59cb..7c4df780198c 100644 --- a/include/llvm/Analysis/CFG.h +++ b/include/llvm/Analysis/CFG.h @@ -78,6 +78,17 @@ bool isPotentiallyReachable(const BasicBlock *From, const BasicBlock *To, const DominatorTree *DT = nullptr, const LoopInfo *LI = nullptr); -} // namespace llvm +/// \brief Determine whether there is at least one path from a block in +/// 'Worklist' to 'StopBB', returning true if uncertain. +/// +/// Determine whether there is a path from at least one block in Worklist to +/// StopBB within a single function. Returns false only if we can prove that +/// once any block in 'Worklist' has been reached then 'StopBB' can not be +/// executed. Conservatively returns true. +bool isPotentiallyReachableFromMany(SmallVectorImpl<BasicBlock *> &Worklist, + BasicBlock *StopBB, + const DominatorTree *DT = nullptr, + const LoopInfo *LI = nullptr); +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/CFGPrinter.h b/include/llvm/Analysis/CFGPrinter.h index 0cc4e5d33975..035764837e6f 100644 --- a/include/llvm/Analysis/CFGPrinter.h +++ b/include/llvm/Analysis/CFGPrinter.h @@ -119,7 +119,7 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits { return ""; } }; -} // namespace llvm +} // End llvm namespace namespace llvm { class FunctionPass; diff --git a/include/llvm/Analysis/CGSCCPassManager.h b/include/llvm/Analysis/CGSCCPassManager.h index 42f0e651ec94..6a406cd24402 100644 --- a/include/llvm/Analysis/CGSCCPassManager.h +++ b/include/llvm/Analysis/CGSCCPassManager.h @@ -485,6 +485,6 @@ CGSCCToFunctionPassAdaptor<FunctionPassT> createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) { return CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)); } -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index ed52e864a059..662ae0e6363c 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -481,6 +481,6 @@ struct GraphTraits<const CallGraph *> : public GraphTraits< static const CallGraphNode &CGdereference(PairTy P) { return *P.second; } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/CallGraphSCCPass.h b/include/llvm/Analysis/CallGraphSCCPass.h index 94fa5bd7fb2a..667e1715775f 100644 --- a/include/llvm/Analysis/CallGraphSCCPass.h +++ b/include/llvm/Analysis/CallGraphSCCPass.h @@ -102,6 +102,6 @@ public: iterator end() const { return Nodes.end(); } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h index 6ab83aefe81b..2f5969129e02 100644 --- a/include/llvm/Analysis/CodeMetrics.h +++ b/include/llvm/Analysis/CodeMetrics.h @@ -102,6 +102,6 @@ struct CodeMetrics { SmallPtrSetImpl<const Value *> &EphValues); }; -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h index a0d5eaba9c7b..541a2109af6c 100644 --- a/include/llvm/Analysis/ConstantFolding.h +++ b/include/llvm/Analysis/ConstantFolding.h @@ -97,6 +97,6 @@ bool canConstantFoldCallTo(const Function *F); /// with the specified arguments, returning null if unsuccessful. Constant *ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands, const TargetLibraryInfo *TLI = nullptr); -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/DomPrinter.h b/include/llvm/Analysis/DomPrinter.h index 1402d7749d79..0ed28994995a 100644 --- a/include/llvm/Analysis/DomPrinter.h +++ b/include/llvm/Analysis/DomPrinter.h @@ -25,6 +25,6 @@ namespace llvm { FunctionPass *createPostDomOnlyPrinterPass(); FunctionPass *createPostDomViewerPass(); FunctionPass *createPostDomOnlyViewerPass(); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/DominanceFrontier.h b/include/llvm/Analysis/DominanceFrontier.h index 0cdd73e01630..996700efdb60 100644 --- a/include/llvm/Analysis/DominanceFrontier.h +++ b/include/llvm/Analysis/DominanceFrontier.h @@ -205,6 +205,6 @@ public: EXTERN_TEMPLATE_INSTANTIATION(class DominanceFrontierBase<BasicBlock>); EXTERN_TEMPLATE_INSTANTIATION(class ForwardDominanceFrontierBase<BasicBlock>); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/DominanceFrontierImpl.h b/include/llvm/Analysis/DominanceFrontierImpl.h index 4904f93c17ac..629ae3809045 100644 --- a/include/llvm/Analysis/DominanceFrontierImpl.h +++ b/include/llvm/Analysis/DominanceFrontierImpl.h @@ -221,6 +221,6 @@ ForwardDominanceFrontierBase<BlockT>::calculate(const DomTreeT &DT, return *Result; } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index 2ad0ae74eb10..ae9c1f5bd9ac 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -178,6 +178,6 @@ protected: Pass *createIVUsersPass(); -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index 57da1325ec35..79ed74d82411 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -36,7 +36,7 @@ namespace InlineConstants { /// Do not inline functions which allocate this many bytes on the stack /// when the caller is recursive. const unsigned TotalAllocaSizeRecursiveCaller = 1024; -} // namespace InlineConstants +} /// \brief Represents the cost of inlining a function. /// @@ -138,6 +138,6 @@ public: bool isInlineViable(Function &Callee); }; -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/Interval.h b/include/llvm/Analysis/Interval.h index cbdb0c033499..01eba3f16c01 100644 --- a/include/llvm/Analysis/Interval.h +++ b/include/llvm/Analysis/Interval.h @@ -145,6 +145,6 @@ template <> struct GraphTraits<Inverse<Interval*> > { } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/IntervalIterator.h b/include/llvm/Analysis/IntervalIterator.h index 5ec50d46a9e7..655ce2dab413 100644 --- a/include/llvm/Analysis/IntervalIterator.h +++ b/include/llvm/Analysis/IntervalIterator.h @@ -263,6 +263,6 @@ inline interval_part_interval_iterator intervals_end(IntervalPartition &IP) { return interval_part_interval_iterator(); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/IntervalPartition.h b/include/llvm/Analysis/IntervalPartition.h index 2176d0c509f1..274be2bdcfa9 100644 --- a/include/llvm/Analysis/IntervalPartition.h +++ b/include/llvm/Analysis/IntervalPartition.h @@ -106,6 +106,6 @@ private: void updatePredecessors(Interval *Int); }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/IteratedDominanceFrontier.h b/include/llvm/Analysis/IteratedDominanceFrontier.h index eea0d81a8889..5a339f10f50f 100644 --- a/include/llvm/Analysis/IteratedDominanceFrontier.h +++ b/include/llvm/Analysis/IteratedDominanceFrontier.h @@ -92,5 +92,5 @@ private: const SmallPtrSetImpl<BasicBlock *> *DefBlocks; SmallVector<BasicBlock *, 32> PHIBlocks; }; -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/JumpInstrTableInfo.h b/include/llvm/Analysis/JumpInstrTableInfo.h index ea331a4f516a..b6dad478cdf2 100644 --- a/include/llvm/Analysis/JumpInstrTableInfo.h +++ b/include/llvm/Analysis/JumpInstrTableInfo.h @@ -66,6 +66,6 @@ private: /// bound specifies the maximum number of bytes needed to represent an /// unconditional jump or a trap instruction in the back end currently in use. ModulePass *createJumpInstrTableInfoPass(unsigned Bound); -} // namespace llvm +} #endif /* LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H */ diff --git a/include/llvm/Analysis/LazyCallGraph.h b/include/llvm/Analysis/LazyCallGraph.h index af4861ff35bf..b0b9068de34b 100644 --- a/include/llvm/Analysis/LazyCallGraph.h +++ b/include/llvm/Analysis/LazyCallGraph.h @@ -569,6 +569,6 @@ public: static StringRef name() { return "LazyCallGraphPrinterPass"; } }; -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/LibCallAliasAnalysis.h b/include/llvm/Analysis/LibCallAliasAnalysis.h index a4b7e5d871fe..6589ac13c746 100644 --- a/include/llvm/Analysis/LibCallAliasAnalysis.h +++ b/include/llvm/Analysis/LibCallAliasAnalysis.h @@ -66,6 +66,6 @@ namespace llvm { ImmutableCallSite CS, const MemoryLocation &Loc); }; -} // namespace llvm +} // End of llvm namespace #endif diff --git a/include/llvm/Analysis/Lint.h b/include/llvm/Analysis/Lint.h index 79cd82ff1337..7c88b137ec3b 100644 --- a/include/llvm/Analysis/Lint.h +++ b/include/llvm/Analysis/Lint.h @@ -44,6 +44,6 @@ void lintFunction( const Function &F ///< The function to be checked ); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/Loads.h b/include/llvm/Analysis/Loads.h index c8a6e4a0e1d7..42667d2af14a 100644 --- a/include/llvm/Analysis/Loads.h +++ b/include/llvm/Analysis/Loads.h @@ -52,6 +52,6 @@ Value *FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, AliasAnalysis *AA = nullptr, AAMDNodes *AATags = nullptr); -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h index 0f3c73147e11..7b635a8b4960 100644 --- a/include/llvm/Analysis/LoopAccessAnalysis.h +++ b/include/llvm/Analysis/LoopAccessAnalysis.h @@ -555,6 +555,6 @@ private: DominatorTree *DT; LoopInfo *LI; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 7bfebab46e20..bbcde8d9721a 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -763,6 +763,6 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index b8f80df34bf9..f5cc856f6247 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -535,6 +535,6 @@ void LoopInfoBase<BlockT, LoopT>::verify() const { #endif } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h index 57ad79319756..8650000fcfb6 100644 --- a/include/llvm/Analysis/LoopPass.h +++ b/include/llvm/Analysis/LoopPass.h @@ -169,6 +169,6 @@ private: Loop *CurrentLoop; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index 557d6fcc0cb9..805a43dfb070 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -262,6 +262,6 @@ public: SizeOffsetEvalType visitInstruction(Instruction &I); }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index 9c50ae08f986..511898071c22 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -445,6 +445,6 @@ namespace llvm { }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/MemoryLocation.h b/include/llvm/Analysis/MemoryLocation.h index ea69633a922c..426b49a3ecd7 100644 --- a/include/llvm/Analysis/MemoryLocation.h +++ b/include/llvm/Analysis/MemoryLocation.h @@ -137,6 +137,6 @@ template <> struct DenseMapInfo<MemoryLocation> { return LHS == RHS; } }; -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index ffaf871cf9e5..d112ab1823b4 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -173,6 +173,6 @@ namespace llvm { // FunctionPass *createMemDerefPrinter(); -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h index f654652a97c3..0f7e2b88d2d7 100644 --- a/include/llvm/Analysis/PostDominators.h +++ b/include/llvm/Analysis/PostDominators.h @@ -112,6 +112,6 @@ template <> struct GraphTraits<PostDominatorTree*> } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/PtrUseVisitor.h b/include/llvm/Analysis/PtrUseVisitor.h index 8b5b90a3402e..6e61fc3be384 100644 --- a/include/llvm/Analysis/PtrUseVisitor.h +++ b/include/llvm/Analysis/PtrUseVisitor.h @@ -280,6 +280,6 @@ protected: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h index 22fd1dfc0e78..7ceb086ee0a1 100644 --- a/include/llvm/Analysis/RegionInfo.h +++ b/include/llvm/Analysis/RegionInfo.h @@ -906,5 +906,5 @@ EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<Function>>); EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<Function>>); EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<Function>>); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/RegionPass.h b/include/llvm/Analysis/RegionPass.h index 5866fc5abc8c..bd51c49e87db 100644 --- a/include/llvm/Analysis/RegionPass.h +++ b/include/llvm/Analysis/RegionPass.h @@ -123,6 +123,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 1c814084c090..d47cab829ced 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -954,6 +954,86 @@ namespace llvm { void print(raw_ostream &OS, const Module* = nullptr) const override; void verifyAnalysis() const override; + /// Collect parametric terms occurring in step expressions. + void collectParametricTerms(const SCEV *Expr, + SmallVectorImpl<const SCEV *> &Terms); + + + + /// Return in Subscripts the access functions for each dimension in Sizes. + void computeAccessFunctions(const SCEV *Expr, + SmallVectorImpl<const SCEV *> &Subscripts, + SmallVectorImpl<const SCEV *> &Sizes); + + /// Split this SCEVAddRecExpr into two vectors of SCEVs representing the + /// subscripts and sizes of an array access. + /// + /// The delinearization is a 3 step process: the first two steps compute the + /// sizes of each subscript and the third step computes the access functions + /// for the delinearized array: + /// + /// 1. Find the terms in the step functions + /// 2. Compute the array size + /// 3. Compute the access function: divide the SCEV by the array size + /// starting with the innermost dimensions found in step 2. The Quotient + /// is the SCEV to be divided in the next step of the recursion. The + /// Remainder is the subscript of the innermost dimension. Loop over all + /// array dimensions computed in step 2. + /// + /// To compute a uniform array size for several memory accesses to the same + /// object, one can collect in step 1 all the step terms for all the memory + /// accesses, and compute in step 2 a unique array shape. This guarantees + /// that the array shape will be the same across all memory accesses. + /// + /// FIXME: We could derive the result of steps 1 and 2 from a description of + /// the array shape given in metadata. + /// + /// Example: + /// + /// A[][n][m] + /// + /// for i + /// for j + /// for k + /// A[j+k][2i][5i] = + /// + /// The initial SCEV: + /// + /// A[{{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k] + /// + /// 1. Find the different terms in the step functions: + /// -> [2*m, 5, n*m, n*m] + /// + /// 2. Compute the array size: sort and unique them + /// -> [n*m, 2*m, 5] + /// find the GCD of all the terms = 1 + /// divide by the GCD and erase constant terms + /// -> [n*m, 2*m] + /// GCD = m + /// divide by GCD -> [n, 2] + /// remove constant terms + /// -> [n] + /// size of the array is A[unknown][n][m] + /// + /// 3. Compute the access function + /// a. Divide {{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k by the innermost size m + /// Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k + /// Remainder: {{{0,+,5}_i, +, 0}_j, +, 0}_k + /// The remainder is the subscript of the innermost array dimension: [5i]. + /// + /// b. Divide Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k by next outer size n + /// Quotient: {{{0,+,0}_i, +, 1}_j, +, 1}_k + /// Remainder: {{{0,+,2}_i, +, 0}_j, +, 0}_k + /// The Remainder is the subscript of the next array dimension: [2i]. + /// + /// The subscript of the outermost dimension is the Quotient: [j+k]. + /// + /// Overall, we have: A[][n][m], and the access function: A[j+k][2i][5i]. + void delinearize(const SCEV *Expr, + SmallVectorImpl<const SCEV *> &Subscripts, + SmallVectorImpl<const SCEV *> &Sizes, + const SCEV *ElementSize); + private: /// Compute the backedge taken count knowing the interval difference, the /// stride and presence of the equality in the comparison. @@ -981,6 +1061,6 @@ namespace llvm { /// to locate them all and call their destructors. SCEVUnknown *FirstUnknown; }; -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 83493fad713b..8ec2078258d1 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -275,6 +275,6 @@ namespace llvm { Value *expandIVInc(PHINode *PN, Value *StepV, const Loop *L, Type *ExpandTy, Type *IntTy, bool useSubtract); }; -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index 14feeed5c5dd..da24de281d47 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -356,84 +356,6 @@ namespace llvm { static inline bool classof(const SCEV *S) { return S->getSCEVType() == scAddRecExpr; } - - /// Collect parametric terms occurring in step expressions. - void collectParametricTerms(ScalarEvolution &SE, - SmallVectorImpl<const SCEV *> &Terms) const; - - /// Return in Subscripts the access functions for each dimension in Sizes. - void computeAccessFunctions(ScalarEvolution &SE, - SmallVectorImpl<const SCEV *> &Subscripts, - SmallVectorImpl<const SCEV *> &Sizes) const; - - /// Split this SCEVAddRecExpr into two vectors of SCEVs representing the - /// subscripts and sizes of an array access. - /// - /// The delinearization is a 3 step process: the first two steps compute the - /// sizes of each subscript and the third step computes the access functions - /// for the delinearized array: - /// - /// 1. Find the terms in the step functions - /// 2. Compute the array size - /// 3. Compute the access function: divide the SCEV by the array size - /// starting with the innermost dimensions found in step 2. The Quotient - /// is the SCEV to be divided in the next step of the recursion. The - /// Remainder is the subscript of the innermost dimension. Loop over all - /// array dimensions computed in step 2. - /// - /// To compute a uniform array size for several memory accesses to the same - /// object, one can collect in step 1 all the step terms for all the memory - /// accesses, and compute in step 2 a unique array shape. This guarantees - /// that the array shape will be the same across all memory accesses. - /// - /// FIXME: We could derive the result of steps 1 and 2 from a description of - /// the array shape given in metadata. - /// - /// Example: - /// - /// A[][n][m] - /// - /// for i - /// for j - /// for k - /// A[j+k][2i][5i] = - /// - /// The initial SCEV: - /// - /// A[{{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k] - /// - /// 1. Find the different terms in the step functions: - /// -> [2*m, 5, n*m, n*m] - /// - /// 2. Compute the array size: sort and unique them - /// -> [n*m, 2*m, 5] - /// find the GCD of all the terms = 1 - /// divide by the GCD and erase constant terms - /// -> [n*m, 2*m] - /// GCD = m - /// divide by GCD -> [n, 2] - /// remove constant terms - /// -> [n] - /// size of the array is A[unknown][n][m] - /// - /// 3. Compute the access function - /// a. Divide {{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k by the innermost size m - /// Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k - /// Remainder: {{{0,+,5}_i, +, 0}_j, +, 0}_k - /// The remainder is the subscript of the innermost array dimension: [5i]. - /// - /// b. Divide Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k by next outer size n - /// Quotient: {{{0,+,0}_i, +, 1}_j, +, 1}_k - /// Remainder: {{{0,+,2}_i, +, 0}_j, +, 0}_k - /// The Remainder is the subscript of the next array dimension: [2i]. - /// - /// The subscript of the outermost dimension is the Quotient: [j+k]. - /// - /// Overall, we have: A[][n][m], and the access function: A[j+k][2i][5i]. - void delinearize(ScalarEvolution &SE, - SmallVectorImpl<const SCEV *> &Subscripts, - SmallVectorImpl<const SCEV *> &Sizes, - const SCEV *ElementSize) const; }; //===--------------------------------------------------------------------===// @@ -829,6 +751,6 @@ static inline const SCEV *apply(const SCEV *Scev, LoopToScevMapT &Map, return SCEVApplyRewriter::rewrite(Scev, Map, SE); } -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/ScalarEvolutionNormalization.h b/include/llvm/Analysis/ScalarEvolutionNormalization.h index 4133864cc3c3..7c6423a21cfa 100644 --- a/include/llvm/Analysis/ScalarEvolutionNormalization.h +++ b/include/llvm/Analysis/ScalarEvolutionNormalization.h @@ -73,6 +73,6 @@ const SCEV *TransformForPostIncUse(TransformKind Kind, ScalarEvolution &SE, DominatorTree &DT); -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/TargetFolder.h b/include/llvm/Analysis/TargetFolder.h index 0e17a58069d7..12bf9fe78a47 100644 --- a/include/llvm/Analysis/TargetFolder.h +++ b/include/llvm/Analysis/TargetFolder.h @@ -265,6 +265,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h index d863b4f76880..bb6e266b1f5b 100644 --- a/include/llvm/Analysis/TargetTransformInfo.h +++ b/include/llvm/Analysis/TargetTransformInfo.h @@ -519,6 +519,11 @@ public: Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst, Type *ExpectedType) const; + /// \returns True if the two functions have compatible attributes for inlining + /// purposes. + bool hasCompatibleFunctionAttributes(const Function *Caller, + const Function *Callee) const; + /// @} private: @@ -619,6 +624,8 @@ public: MemIntrinsicInfo &Info) = 0; virtual Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst, Type *ExpectedType) = 0; + virtual bool hasCompatibleFunctionAttributes(const Function *Caller, + const Function *Callee) const = 0; }; template <typename T> @@ -804,6 +811,10 @@ public: Type *ExpectedType) override { return Impl.getOrCreateResultFromMemIntrinsic(Inst, ExpectedType); } + bool hasCompatibleFunctionAttributes(const Function *Caller, + const Function *Callee) const override { + return Impl.hasCompatibleFunctionAttributes(Caller, Callee); + } }; template <typename T> @@ -908,6 +919,6 @@ public: /// clients. ImmutablePass *createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h index 59b95a8da1e8..403175acae02 100644 --- a/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -335,6 +335,14 @@ public: Type *ExpectedType) { return nullptr; } + + bool hasCompatibleFunctionAttributes(const Function *Caller, + const Function *Callee) const { + return (Caller->getFnAttribute("target-cpu") == + Callee->getFnAttribute("target-cpu")) && + (Caller->getFnAttribute("target-features") == + Callee->getFnAttribute("target-features")); + } }; /// \brief CRTP base class for use as a mix-in that aids implementing @@ -446,6 +454,6 @@ public: U->getNumOperands() == 1 ? U->getOperand(0)->getType() : nullptr); } }; -} // namespace llvm +} #endif diff --git a/include/llvm/Analysis/VectorUtils.h b/include/llvm/Analysis/VectorUtils.h new file mode 100644 index 000000000000..aa538ecc0137 --- /dev/null +++ b/include/llvm/Analysis/VectorUtils.h @@ -0,0 +1,56 @@ +//===- llvm/Transforms/Utils/VectorUtils.h - Vector utilities -*- 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 some vectorizer utilities. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_VECTORUTILS_H +#define LLVM_TRANSFORMS_UTILS_VECTORUTILS_H + +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Intrinsics.h" + +namespace llvm { + +/// \brief Identify if the intrinsic is trivially vectorizable. +/// This method returns true if the intrinsic's argument types are all +/// scalars for the scalar form of the intrinsic and all vectors for +/// the vector form of the intrinsic. +bool isTriviallyVectorizable(Intrinsic::ID ID); + +/// \brief Identifies if the intrinsic has a scalar operand. It checks for +/// ctlz,cttz and powi special intrinsics whose argument is scalar. +bool hasVectorInstrinsicScalarOpd(Intrinsic::ID ID, unsigned ScalarOpdIdx); + +/// \brief Identify if call has a unary float signature +/// It returns input intrinsic ID if call has a single argument, +/// argument type and call instruction type should be floating +/// point type and call should only reads memory. +/// else return not_intrinsic. +Intrinsic::ID checkUnaryFloatSignature(const CallInst &I, + Intrinsic::ID ValidIntrinsicID); + +/// \brief Identify if call has a binary float signature +/// It returns input intrinsic ID if call has two arguments, +/// arguments type and call instruction type should be floating +/// point type and call should only reads memory. +/// else return not_intrinsic. +Intrinsic::ID checkBinaryFloatSignature(const CallInst &I, + Intrinsic::ID ValidIntrinsicID); + +/// \brief Returns intrinsic ID for call. +/// For the input call instruction it finds mapping intrinsic and returns +/// its intrinsic ID, in case it does not found it return not_intrinsic. +Intrinsic::ID getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI); + +} // llvm namespace + +#endif diff --git a/include/llvm/AsmParser/Parser.h b/include/llvm/AsmParser/Parser.h index 0c37a9b57069..52151409f946 100644 --- a/include/llvm/AsmParser/Parser.h +++ b/include/llvm/AsmParser/Parser.h @@ -18,55 +18,67 @@ namespace llvm { +class LLVMContext; class Module; +struct SlotMapping; class SMDiagnostic; -class LLVMContext; /// This function is the main interface to the LLVM Assembly Parser. It parses /// an ASCII file that (presumably) contains LLVM Assembly code. It returns a /// Module (intermediate representation) with the corresponding features. Note /// that this does not verify that the generated Module is valid, so you should /// run the verifier after parsing the file to check that it is okay. -/// @brief Parse LLVM Assembly from a file -/// @param Filename The name of the file to parse -/// @param Error Error result info. -/// @param Context Context in which to allocate globals info. +/// \brief Parse LLVM Assembly from a file +/// \param Filename The name of the file to parse +/// \param Error Error result info. +/// \param Context Context in which to allocate globals info. +/// \param Slots The optional slot mapping that will be initialized during +/// parsing. std::unique_ptr<Module> parseAssemblyFile(StringRef Filename, SMDiagnostic &Error, - LLVMContext &Context); + LLVMContext &Context, + SlotMapping *Slots = nullptr); /// The function is a secondary interface to the LLVM Assembly Parser. It parses /// an ASCII string that (presumably) contains LLVM Assembly code. It returns a /// Module (intermediate representation) with the corresponding features. Note /// that this does not verify that the generated Module is valid, so you should /// run the verifier after parsing the file to check that it is okay. -/// @brief Parse LLVM Assembly from a string -/// @param AsmString The string containing assembly -/// @param Error Error result info. -/// @param Context Context in which to allocate globals info. +/// \brief Parse LLVM Assembly from a string +/// \param AsmString The string containing assembly +/// \param Error Error result info. +/// \param Context Context in which to allocate globals info. +/// \param Slots The optional slot mapping that will be initialized during +/// parsing. std::unique_ptr<Module> parseAssemblyString(StringRef AsmString, SMDiagnostic &Error, - LLVMContext &Context); + LLVMContext &Context, + SlotMapping *Slots = nullptr); /// parseAssemblyFile and parseAssemblyString are wrappers around this function. -/// @brief Parse LLVM Assembly from a MemoryBuffer. -/// @param F The MemoryBuffer containing assembly -/// @param Err Error result info. -/// @param Context Context in which to allocate globals info. +/// \brief Parse LLVM Assembly from a MemoryBuffer. +/// \param F The MemoryBuffer containing assembly +/// \param Err Error result info. +/// \param Slots The optional slot mapping that will be initialized during +/// parsing. std::unique_ptr<Module> parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, - LLVMContext &Context); + LLVMContext &Context, + SlotMapping *Slots = nullptr); /// This function is the low-level interface to the LLVM Assembly Parser. /// This is kept as an independent function instead of being inlined into /// parseAssembly for the convenience of interactive users that want to add /// recently parsed bits to an existing module. /// -/// @param F The MemoryBuffer containing assembly -/// @param M The module to add data to. -/// @param Err Error result info. -/// @return true on error. -bool parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err); +/// \param F The MemoryBuffer containing assembly +/// \param M The module to add data to. +/// \param Err Error result info. +/// \param Slots The optional slot mapping that will be initialized during +/// parsing. +/// \return true on error. +bool parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err, + SlotMapping *Slots = nullptr); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/AsmParser/SlotMapping.h b/include/llvm/AsmParser/SlotMapping.h new file mode 100644 index 000000000000..c5f61d25c3a8 --- /dev/null +++ b/include/llvm/AsmParser/SlotMapping.h @@ -0,0 +1,34 @@ +//===-- SlotMapping.h - Slot number mapping for unnamed values --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the SlotMapping struct. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ASMPARSER_SLOTMAPPING_H +#define LLVM_ASMPARSER_SLOTMAPPING_H + +#include "llvm/IR/TrackingMDRef.h" +#include <map> +#include <vector> + +namespace llvm { + +class GlobalValue; + +/// This struct contains the mapping from the slot numbers to unnamed metadata +/// nodes and global values. +struct SlotMapping { + std::vector<GlobalValue *> GlobalValues; + std::map<unsigned, TrackingMDNodeRef> MetadataNodes; +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/Bitcode/BitCodes.h b/include/llvm/Bitcode/BitCodes.h index 6b23eb966ed9..96c420151858 100644 --- a/include/llvm/Bitcode/BitCodes.h +++ b/include/llvm/Bitcode/BitCodes.h @@ -77,7 +77,7 @@ namespace bitc { // [id, name] }; -} // namespace bitc +} // End bitc namespace /// BitCodeAbbrevOp - This describes one or more operands in an abbreviation. /// This is actually a union of two different things: @@ -180,6 +180,6 @@ public: OperandList.push_back(OpInfo); } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Bitcode/BitcodeWriterPass.h b/include/llvm/Bitcode/BitcodeWriterPass.h index cc742f19b590..ae915c688ba0 100644 --- a/include/llvm/Bitcode/BitcodeWriterPass.h +++ b/include/llvm/Bitcode/BitcodeWriterPass.h @@ -56,6 +56,6 @@ public: static StringRef name() { return "BitcodeWriterPass"; } }; -} // namespace llvm +} #endif diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h index 9201daf936d7..4c040a7f3e22 100644 --- a/include/llvm/Bitcode/BitstreamReader.h +++ b/include/llvm/Bitcode/BitstreamReader.h @@ -512,6 +512,6 @@ public: bool ReadBlockInfoBlock(); }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h index eef6076d6a45..9f23023a1419 100644 --- a/include/llvm/Bitcode/BitstreamWriter.h +++ b/include/llvm/Bitcode/BitstreamWriter.h @@ -520,6 +520,6 @@ public: }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 41aa148b2564..605c4172dd87 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -167,6 +167,7 @@ namespace bitc { METADATA_EXPRESSION = 29, // [distinct, n x element] METADATA_OBJC_PROPERTY = 30, // [distinct, name, file, line, ...] METADATA_IMPORTED_ENTITY=31, // [distinct, tag, scope, entity, line, name] + METADATA_MODULE=32, // [distinct, scope, name, ...] }; // The constants block (CONSTANTS_BLOCK_ID) describes emission for each @@ -416,7 +417,7 @@ namespace bitc { COMDAT_SELECTION_KIND_SAME_SIZE = 5, }; -} // namespace bitc -} // namespace llvm +} // End bitc namespace +} // End llvm namespace #endif diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h index d158569b810a..6797aa133c42 100644 --- a/include/llvm/Bitcode/ReaderWriter.h +++ b/include/llvm/Bitcode/ReaderWriter.h @@ -166,7 +166,7 @@ namespace llvm { } }; -} // namespace llvm +} // End llvm namespace namespace std { template <> struct is_error_code_enum<llvm::BitcodeError> : std::true_type {}; diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h index 96e955467010..c4b94ede4f55 100644 --- a/include/llvm/CodeGen/Analysis.h +++ b/include/llvm/CodeGen/Analysis.h @@ -115,6 +115,6 @@ bool returnTypeIsEligibleForTailCall(const Function *F, // or we are in LTO. bool canBeOmittedFromSymbolTable(const GlobalValue *GV); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 8a0989f1782c..fe7efae325c4 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -535,6 +535,6 @@ private: void EmitXXStructorList(const Constant *List, bool isCtor); GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &C); }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h index cb61cc7fd50e..3e464f4f1e5a 100644 --- a/include/llvm/CodeGen/BasicTTIImpl.h +++ b/include/llvm/CodeGen/BasicTTIImpl.h @@ -830,6 +830,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h index 7c9019063080..91fb0a9d7e77 100644 --- a/include/llvm/CodeGen/CalcSpillWeights.h +++ b/include/llvm/CodeGen/CalcSpillWeights.h @@ -74,6 +74,6 @@ namespace llvm { const MachineBlockFrequencyInfo &MBFI, VirtRegAuxInfo::NormalizingFn norm = normalizeSpillWeight); -} // namespace llvm +} #endif // LLVM_CODEGEN_CALCSPILLWEIGHTS_H diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h index 3c3f770f92b5..554511d6f4ab 100644 --- a/include/llvm/CodeGen/CommandFlags.h +++ b/include/llvm/CodeGen/CommandFlags.h @@ -17,6 +17,8 @@ #define LLVM_CODEGEN_COMMANDFLAGS_H #include "llvm/ADT/StringExtras.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" #include "llvm/MC/MCTargetOptionsCommandFlags.h" #include "llvm//MC/SubtargetFeature.h" @@ -249,7 +251,6 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() { Options.NoZerosInBSS = DontPlaceZerosInBSS; Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; Options.StackAlignmentOverride = OverrideStackAlignment; - Options.TrapFuncName = TrapFuncName; Options.PositionIndependentExecutable = EnablePIE; Options.UseInitArray = !UseCtors; Options.DataSections = DataSections; @@ -320,6 +321,16 @@ static inline void setFunctionAttributes(StringRef CPU, StringRef Features, "disable-tail-calls", toStringRef(DisableTailCalls)); + if (TrapFuncName.getNumOccurrences() > 0) + for (auto &B : F) + for (auto &I : B) + if (auto *Call = dyn_cast<CallInst>(&I)) + if (const auto *F = Call->getCalledFunction()) + if (F->getIntrinsicID() == Intrinsic::debugtrap || + F->getIntrinsicID() == Intrinsic::trap) + Call->addAttribute(llvm::AttributeSet::FunctionIndex, + "trap-func-name", TrapFuncName); + // Let NewAttrs override Attrs. NewAttrs = Attrs.addAttributes(Ctx, AttributeSet::FunctionIndex, NewAttrs); F.setAttributes(NewAttrs); diff --git a/include/llvm/CodeGen/DFAPacketizer.h b/include/llvm/CodeGen/DFAPacketizer.h index ccff3883f2bb..c44a7e0b6736 100644 --- a/include/llvm/CodeGen/DFAPacketizer.h +++ b/include/llvm/CodeGen/DFAPacketizer.h @@ -91,7 +91,7 @@ public: // API call is made to prune the dependence. class VLIWPacketizerList { protected: - const MachineFunction &MF; + MachineFunction &MF; const TargetInstrInfo *TII; // The VLIW Scheduler. @@ -159,6 +159,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h index 1ea3217978d1..f07712a676da 100644 --- a/include/llvm/CodeGen/DIE.h +++ b/include/llvm/CodeGen/DIE.h @@ -15,6 +15,8 @@ #define LLVM_LIB_CODEGEN_ASMPRINTER_DIE_H #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/DwarfStringPoolEntry.h" #include "llvm/Support/Dwarf.h" @@ -436,11 +438,11 @@ public: /// EmitValue - Emit value via the Dwarf writer. /// - void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP) const; /// SizeOf - Return the size of a value in bytes. /// - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP) const; #ifndef NDEBUG void print(raw_ostream &O) const; @@ -448,10 +450,179 @@ public: #endif }; +struct IntrusiveBackListNode { + PointerIntPair<IntrusiveBackListNode *, 1> Next; + IntrusiveBackListNode() : Next(this, true) {} + + IntrusiveBackListNode *getNext() const { + return Next.getInt() ? nullptr : Next.getPointer(); + } +}; + +struct IntrusiveBackListBase { + typedef IntrusiveBackListNode Node; + Node *Last = nullptr; + + bool empty() const { return !Last; } + void push_back(Node &N) { + assert(N.Next.getPointer() == &N && "Expected unlinked node"); + assert(N.Next.getInt() == true && "Expected unlinked node"); + + if (Last) { + N.Next = Last->Next; + Last->Next.setPointerAndInt(&N, false); + } + Last = &N; + } +}; + +template <class T> class IntrusiveBackList : IntrusiveBackListBase { +public: + using IntrusiveBackListBase::empty; + void push_back(T &N) { IntrusiveBackListBase::push_back(N); } + T &back() { return *static_cast<T *>(Last); } + const T &back() const { return *static_cast<T *>(Last); } + + class const_iterator; + class iterator + : public iterator_facade_base<iterator, std::forward_iterator_tag, T> { + friend class const_iterator; + Node *N = nullptr; + + public: + iterator() = default; + explicit iterator(T *N) : N(N) {} + + iterator &operator++() { + N = N->getNext(); + return *this; + } + + explicit operator bool() const { return N; } + T &operator*() const { return *static_cast<T *>(N); } + + bool operator==(const iterator &X) const { return N == X.N; } + bool operator!=(const iterator &X) const { return N != X.N; } + }; + + class const_iterator + : public iterator_facade_base<const_iterator, std::forward_iterator_tag, + const T> { + const Node *N = nullptr; + + public: + const_iterator() = default; + // Placate MSVC by explicitly scoping 'iterator'. + const_iterator(typename IntrusiveBackList<T>::iterator X) : N(X.N) {} + explicit const_iterator(const T *N) : N(N) {} + + const_iterator &operator++() { + N = N->getNext(); + return *this; + } + + explicit operator bool() const { return N; } + const T &operator*() const { return *static_cast<const T *>(N); } + + bool operator==(const const_iterator &X) const { return N == X.N; } + bool operator!=(const const_iterator &X) const { return N != X.N; } + }; + + iterator begin() { + return Last ? iterator(static_cast<T *>(Last->Next.getPointer())) : end(); + } + const_iterator begin() const { + return const_cast<IntrusiveBackList *>(this)->begin(); + } + iterator end() { return iterator(); } + const_iterator end() const { return const_iterator(); } + + static iterator toIterator(T &N) { return iterator(&N); } + static const_iterator toIterator(const T &N) { return const_iterator(&N); } +}; + +/// A list of DIE values. +/// +/// This is a singly-linked list, but instead of reversing the order of +/// insertion, we keep a pointer to the back of the list so we can push in +/// order. +/// +/// There are two main reasons to choose a linked list over a customized +/// vector-like data structure. +/// +/// 1. For teardown efficiency, we want DIEs to be BumpPtrAllocated. Using a +/// linked list here makes this way easier to accomplish. +/// 2. Carrying an extra pointer per \a DIEValue isn't expensive. 45% of DIEs +/// have 2 or fewer values, and 90% have 5 or fewer. A vector would be +/// over-allocated by 50% on average anyway, the same cost as the +/// linked-list node. +class DIEValueList { + struct Node : IntrusiveBackListNode { + DIEValue V; + explicit Node(DIEValue V) : V(V) {} + }; + + typedef IntrusiveBackList<Node> ListTy; + ListTy List; + +public: + bool empty() const { return List.empty(); } + + class const_iterator; + class iterator + : public iterator_adaptor_base<iterator, ListTy::iterator, + std::forward_iterator_tag, DIEValue> { + friend class const_iterator; + typedef iterator_adaptor_base<iterator, ListTy::iterator, + std::forward_iterator_tag, + DIEValue> iterator_adaptor; + + public: + iterator() = default; + explicit iterator(ListTy::iterator X) : iterator_adaptor(X) {} + + explicit operator bool() const { return bool(wrapped()); } + DIEValue &operator*() const { return wrapped()->V; } + }; + + class const_iterator + : public iterator_adaptor_base<const_iterator, ListTy::const_iterator, + std::forward_iterator_tag, + const DIEValue> { + typedef iterator_adaptor_base<const_iterator, ListTy::const_iterator, + std::forward_iterator_tag, + const DIEValue> iterator_adaptor; + + public: + const_iterator() = default; + const_iterator(DIEValueList::iterator X) : iterator_adaptor(X.wrapped()) {} + explicit const_iterator(ListTy::const_iterator X) : iterator_adaptor(X) {} + + explicit operator bool() const { return bool(wrapped()); } + const DIEValue &operator*() const { return wrapped()->V; } + }; + + iterator insert(BumpPtrAllocator &Alloc, DIEValue V) { + List.push_back(*new (Alloc) Node(V)); + return iterator(ListTy::toIterator(List.back())); + } + template <class... Ts> + iterator emplace(BumpPtrAllocator &Alloc, Ts &&... Args) { + return insert(Alloc, DIEValue(std::forward<Ts>(Args)...)); + } + + iterator begin() { return iterator(List.begin()); } + iterator end() { return iterator(List.end()); } + const_iterator begin() const { return const_iterator(List.begin()); } + const_iterator end() const { return const_iterator(List.end()); } +}; + //===--------------------------------------------------------------------===// /// DIE - A structured debug information entry. Has an abbreviation which /// describes its organization. -class DIE { +class DIE : IntrusiveBackListNode { + friend class IntrusiveBackList<DIE>; + protected: /// Offset - Offset in debug info section. /// @@ -468,27 +639,24 @@ protected: dwarf::Tag Tag = (dwarf::Tag)0; /// Children DIEs. - /// - // This can't be a vector<DIE> because pointer validity is requirent for the - // Parent pointer and DIEEntry. - // It can't be a list<DIE> because some clients need pointer validity before - // the object has been added to any child list - // (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may - // be more convoluted than beneficial. - std::vector<std::unique_ptr<DIE>> Children; + IntrusiveBackList<DIE> Children; - DIE *Parent; + DIE *Parent = nullptr; /// Attribute values. /// - SmallVector<DIEValue, 12> Values; + DIEValueList Values; protected: - DIE() : Offset(0), Size(0), Parent(nullptr) {} + DIE() : Offset(0), Size(0) {} + +private: + explicit DIE(dwarf::Tag Tag) : Offset(0), Size(0), Tag(Tag) {} public: - explicit DIE(dwarf::Tag Tag) - : Offset(0), Size(0), Tag(Tag), Parent(nullptr) {} + static DIE *get(BumpPtrAllocator &Alloc, dwarf::Tag Tag) { + return new (Alloc) DIE(Tag); + } // Accessors. unsigned getAbbrevNumber() const { return AbbrevNumber; } @@ -497,26 +665,32 @@ public: unsigned getSize() const { return Size; } bool hasChildren() const { return !Children.empty(); } - typedef std::vector<std::unique_ptr<DIE>>::const_iterator child_iterator; + typedef IntrusiveBackList<DIE>::iterator child_iterator; + typedef IntrusiveBackList<DIE>::const_iterator const_child_iterator; typedef iterator_range<child_iterator> child_range; + typedef iterator_range<const_child_iterator> const_child_range; - child_range children() const { + child_range children() { + return llvm::make_range(Children.begin(), Children.end()); + } + const_child_range children() const { return llvm::make_range(Children.begin(), Children.end()); } - typedef SmallVectorImpl<DIEValue>::const_iterator value_iterator; + typedef DIEValueList::iterator value_iterator; typedef iterator_range<value_iterator> value_range; - value_iterator values_begin() const { return Values.begin(); } - value_iterator values_end() const { return Values.end(); } - value_range values() const { - return llvm::make_range(values_begin(), values_end()); + value_range values() { + return llvm::make_range(Values.begin(), Values.end()); } - void setValue(unsigned I, DIEValue New) { - assert(I < Values.size()); - Values[I] = New; + typedef DIEValueList::const_iterator const_value_iterator; + typedef iterator_range<const_value_iterator> const_value_range; + + const_value_range values() const { + return llvm::make_range(Values.begin(), Values.end()); } + DIE *getParent() const { return Parent; } /// Generate the abbreviation for this DIE. @@ -539,19 +713,21 @@ public: /// addValue - Add a value and attributes to a DIE. /// - void addValue(DIEValue Value) { Values.push_back(Value); } + value_iterator addValue(BumpPtrAllocator &Alloc, DIEValue Value) { + return Values.insert(Alloc, Value); + } template <class T> - void addValue(dwarf::Attribute Attribute, dwarf::Form Form, T &&Value) { - Values.emplace_back(Attribute, Form, std::forward<T>(Value)); + value_iterator addValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute, + dwarf::Form Form, T &&Value) { + return Values.emplace(Alloc, Attribute, Form, std::forward<T>(Value)); } - /// addChild - Add a child to the DIE. - /// - DIE &addChild(std::unique_ptr<DIE> Child) { - assert(!Child->getParent()); + /// Add a child to the DIE. + DIE &addChild(DIE *Child) { + assert(!Child->getParent() && "Child should be orphaned"); Child->Parent = this; - Children.push_back(std::move(Child)); - return *Children.back(); + Children.push_back(*Child); + return Children.back(); } /// Find a value in the DIE with the attribute given. @@ -635,6 +811,6 @@ public: #endif }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 1dca2ce1ab22..f04a7cd69664 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -69,7 +69,7 @@ public: unsigned NumFixedArgs; CallingConv::ID CallConv; const Value *Callee; - const char *SymName; + MCSymbol *Symbol; ArgListTy Args; ImmutableCallSite *CS; MachineInstr *Call; @@ -88,7 +88,7 @@ public: : RetTy(nullptr), RetSExt(false), RetZExt(false), IsVarArg(false), IsInReg(false), DoesNotReturn(false), IsReturnValueUsed(true), IsTailCall(false), NumFixedArgs(-1), CallConv(CallingConv::C), - Callee(nullptr), SymName(nullptr), CS(nullptr), Call(nullptr), + Callee(nullptr), Symbol(nullptr), CS(nullptr), Call(nullptr), ResultReg(0), NumResultRegs(0), IsPatchPoint(false) {} CallLoweringInfo &setCallee(Type *ResultTy, FunctionType *FuncTy, @@ -114,12 +114,12 @@ public: } CallLoweringInfo &setCallee(Type *ResultTy, FunctionType *FuncTy, - const char *Target, ArgListTy &&ArgsList, + MCSymbol *Target, ArgListTy &&ArgsList, ImmutableCallSite &Call, unsigned FixedArgs = ~0U) { RetTy = ResultTy; Callee = Call.getCalledValue(); - SymName = Target; + Symbol = Target; IsInReg = Call.paramHasAttr(0, Attribute::InReg); DoesNotReturn = Call.doesNotReturn(); @@ -148,11 +148,16 @@ public: return *this; } - CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultTy, + CallLoweringInfo &setCallee(const DataLayout &DL, MCContext &Ctx, + CallingConv::ID CC, Type *ResultTy, const char *Target, ArgListTy &&ArgsList, + unsigned FixedArgs = ~0U); + + CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultTy, + MCSymbol *Target, ArgListTy &&ArgsList, unsigned FixedArgs = ~0U) { RetTy = ResultTy; - SymName = Target; + Symbol = Target; CallConv = CC; Args = std::move(ArgsList); NumFixedArgs = (FixedArgs == ~0U) ? Args.size() : FixedArgs; @@ -504,7 +509,9 @@ protected: CmpInst::Predicate optimizeCmpPredicate(const CmpInst *CI) const; - bool lowerCallTo(const CallInst *CI, const char *SymName, unsigned NumArgs); + bool lowerCallTo(const CallInst *CI, MCSymbol *Symbol, unsigned NumArgs); + bool lowerCallTo(const CallInst *CI, const char *SymbolName, + unsigned NumArgs); bool lowerCallTo(CallLoweringInfo &CLI); bool isCommutativeIntrinsic(IntrinsicInst const *II) { diff --git a/include/llvm/CodeGen/FaultMaps.h b/include/llvm/CodeGen/FaultMaps.h index d5c2feefaa67..f4b646322143 100644 --- a/include/llvm/CodeGen/FaultMaps.h +++ b/include/llvm/CodeGen/FaultMaps.h @@ -1,4 +1,4 @@ -//===------------------- FaultMaps.h - StackMaps ----------------*- C++ -*-===// +//===------------------- FaultMaps.h - The "FaultMaps" section --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,6 +12,8 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Format.h" #include <vector> #include <map> @@ -68,6 +70,151 @@ private: void emitFunctionInfo(const MCSymbol *FnLabel, const FunctionFaultInfos &FFI); }; + +/// A parser for the __llvm_faultmaps section generated by the FaultMaps class +/// above. This parser is version locked with with the __llvm_faultmaps section +/// generated by the version of LLVM that includes it. No guarantees are made +/// with respect to forward or backward compatibility. +class FaultMapParser { + typedef uint8_t FaultMapVersionType; + static const size_t FaultMapVersionOffset = 0; + + typedef uint8_t Reserved0Type; + static const size_t Reserved0Offset = + FaultMapVersionOffset + sizeof(FaultMapVersionType); + + typedef uint16_t Reserved1Type; + static const size_t Reserved1Offset = Reserved0Offset + sizeof(Reserved0Type); + + typedef uint32_t NumFunctionsType; + static const size_t NumFunctionsOffset = + Reserved1Offset + sizeof(Reserved1Type); + + static const size_t FunctionInfosOffset = + NumFunctionsOffset + sizeof(NumFunctionsType); + + const uint8_t *P; + const uint8_t *E; + + template <typename T> static T read(const uint8_t *P, const uint8_t *E) { + assert(P + sizeof(T) <= E && "out of bounds read!"); + return support::endian::read<T, support::little, 1>(P); + } + +public: + class FunctionFaultInfoAccessor { + typedef uint32_t FaultKindType; + static const size_t FaultKindOffset = 0; + + typedef uint32_t FaultingPCOffsetType; + static const size_t FaultingPCOffsetOffset = + FaultKindOffset + sizeof(FaultKindType); + + typedef uint32_t HandlerPCOffsetType; + static const size_t HandlerPCOffsetOffset = + FaultingPCOffsetOffset + sizeof(FaultingPCOffsetType); + + const uint8_t *P; + const uint8_t *E; + + public: + static const size_t Size = + HandlerPCOffsetOffset + sizeof(HandlerPCOffsetType); + + explicit FunctionFaultInfoAccessor(const uint8_t *P, const uint8_t *E) + : P(P), E(E) {} + + FaultKindType getFaultKind() const { + return read<FaultKindType>(P + FaultKindOffset, E); + } + + FaultingPCOffsetType getFaultingPCOffset() const { + return read<FaultingPCOffsetType>(P + FaultingPCOffsetOffset, E); + } + + HandlerPCOffsetType getHandlerPCOffset() const { + return read<HandlerPCOffsetType>(P + HandlerPCOffsetOffset, E); + } + }; + + class FunctionInfoAccessor { + typedef uint64_t FunctionAddrType; + static const size_t FunctionAddrOffset = 0; + + typedef uint32_t NumFaultingPCsType; + static const size_t NumFaultingPCsOffset = + FunctionAddrOffset + sizeof(FunctionAddrType); + + typedef uint32_t ReservedType; + static const size_t ReservedOffset = + NumFaultingPCsOffset + sizeof(NumFaultingPCsType); + + static const size_t FunctionFaultInfosOffset = + ReservedOffset + sizeof(ReservedType); + + static const size_t FunctionInfoHeaderSize = FunctionFaultInfosOffset; + + const uint8_t *P; + const uint8_t *E; + + public: + FunctionInfoAccessor() : P(nullptr), E(nullptr) {} + + explicit FunctionInfoAccessor(const uint8_t *P, const uint8_t *E) + : P(P), E(E) {} + + FunctionAddrType getFunctionAddr() const { + return read<FunctionAddrType>(P + FunctionAddrOffset, E); + } + + NumFaultingPCsType getNumFaultingPCs() const { + return read<NumFaultingPCsType>(P + NumFaultingPCsOffset, E); + } + + FunctionFaultInfoAccessor getFunctionFaultInfoAt(uint32_t Index) const { + assert(Index < getNumFaultingPCs() && "index out of bounds!"); + const uint8_t *Begin = P + FunctionFaultInfosOffset + + FunctionFaultInfoAccessor::Size * Index; + return FunctionFaultInfoAccessor(Begin, E); + } + + FunctionInfoAccessor getNextFunctionInfo() const { + size_t MySize = FunctionInfoHeaderSize + + getNumFaultingPCs() * FunctionFaultInfoAccessor::Size; + + const uint8_t *Begin = P + MySize; + assert(Begin < E && "out of bounds!"); + return FunctionInfoAccessor(Begin, E); + } + }; + + explicit FaultMapParser(const uint8_t *Begin, const uint8_t *End) + : P(Begin), E(End) {} + + FaultMapVersionType getFaultMapVersion() const { + auto Version = read<FaultMapVersionType>(P + FaultMapVersionOffset, E); + assert(Version == 1 && "only version 1 supported!"); + return Version; + } + + NumFunctionsType getNumFunctions() const { + return read<NumFunctionsType>(P + NumFunctionsOffset, E); + } + + FunctionInfoAccessor getFirstFunctionInfo() const { + const uint8_t *Begin = P + FunctionInfosOffset; + return FunctionInfoAccessor(Begin, E); + } +}; + +raw_ostream & +operator<<(raw_ostream &OS, const FaultMapParser::FunctionFaultInfoAccessor &); + +raw_ostream &operator<<(raw_ostream &OS, + const FaultMapParser::FunctionInfoAccessor &); + +raw_ostream &operator<<(raw_ostream &OS, const FaultMapParser &); + } // namespace llvm #endif diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h index b34f67a023ca..e883bd196ea3 100644 --- a/include/llvm/CodeGen/GCMetadata.h +++ b/include/llvm/CodeGen/GCMetadata.h @@ -201,6 +201,6 @@ public: /// will soon change. GCFunctionInfo &getFunctionInfo(const Function &F); }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/GCMetadataPrinter.h b/include/llvm/CodeGen/GCMetadataPrinter.h index e451cd276346..220847029113 100644 --- a/include/llvm/CodeGen/GCMetadataPrinter.h +++ b/include/llvm/CodeGen/GCMetadataPrinter.h @@ -59,6 +59,6 @@ public: virtual ~GCMetadataPrinter(); }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/GCStrategy.h b/include/llvm/CodeGen/GCStrategy.h index 2a4dabb01b9b..a1b8e895898f 100644 --- a/include/llvm/CodeGen/GCStrategy.h +++ b/include/llvm/CodeGen/GCStrategy.h @@ -172,6 +172,6 @@ public: /// register your GCMetadataPrinter subclass with the /// GCMetadataPrinterRegistery as well. typedef Registry<GCStrategy> GCRegistry; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/GCs.h b/include/llvm/CodeGen/GCs.h index 5418fff0b592..5207f801c84e 100644 --- a/include/llvm/CodeGen/GCs.h +++ b/include/llvm/CodeGen/GCs.h @@ -41,6 +41,6 @@ void linkErlangGCPrinter(); void linkShadowStackGC(); void linkStatepointExampleGC(); -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index 5a1cf59024bf..c7237fd55b27 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -124,6 +124,8 @@ namespace ISD { TargetExternalSymbol, TargetBlockAddress, + MCSymbol, + /// TargetIndex - Like a constant pool entry, but with completely /// target-dependent semantics. Holds target flags, a 32-bit index, and a /// 64-bit index. Targets can use this however they like. @@ -890,8 +892,8 @@ namespace ISD { CVT_INVALID /// Marker - Invalid opcode }; -} // namespace ISD +} // end llvm::ISD namespace -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/CodeGen/IntrinsicLowering.h b/include/llvm/CodeGen/IntrinsicLowering.h index a76464522aaa..9e6ab7d45977 100644 --- a/include/llvm/CodeGen/IntrinsicLowering.h +++ b/include/llvm/CodeGen/IntrinsicLowering.h @@ -54,6 +54,6 @@ namespace llvm { /// simple integer bswap. static bool LowerToByteSwap(CallInst *CI); }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h index cc33f3491242..f347f66e0981 100644 --- a/include/llvm/CodeGen/LatencyPriorityQueue.h +++ b/include/llvm/CodeGen/LatencyPriorityQueue.h @@ -93,6 +93,6 @@ private: void AdjustPriorityOfUnscheduledPreds(SUnit *SU); SUnit *getSingleUnscheduledPred(SUnit *SU); }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h index 7478c3a678af..7d7e48af2a0f 100644 --- a/include/llvm/CodeGen/LexicalScopes.h +++ b/include/llvm/CodeGen/LexicalScopes.h @@ -252,6 +252,6 @@ private: LexicalScope *CurrentFnLexicalScope; }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index ea44ab10792b..9b8b91c9b80e 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -866,5 +866,5 @@ namespace llvm { }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 9d688412897c..9673f80e0856 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -444,6 +444,6 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs; class HMEditor; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/LivePhysRegs.h b/include/llvm/CodeGen/LivePhysRegs.h index 6ffd3eeea351..6475e7b4af37 100644 --- a/include/llvm/CodeGen/LivePhysRegs.h +++ b/include/llvm/CodeGen/LivePhysRegs.h @@ -116,19 +116,15 @@ public: void stepForward(const MachineInstr &MI, SmallVectorImpl<std::pair<unsigned, const MachineOperand*>> &Clobbers); - /// \brief Adds all live-in registers of basic block @p MBB. - void addLiveIns(const MachineBasicBlock *MBB) { - for (MachineBasicBlock::livein_iterator LI = MBB->livein_begin(), - LE = MBB->livein_end(); LI != LE; ++LI) - addReg(*LI); - } - - /// \brief Adds all live-out registers of basic block @p MBB. - void addLiveOuts(const MachineBasicBlock *MBB) { - for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(), - SE = MBB->succ_end(); SI != SE; ++SI) - addLiveIns(*SI); - } + /// \brief Adds all live-in registers of basic block @p MBB; After prologue/ + /// epilogue insertion \p AddPristines should be set to true to insert the + /// pristine registers. + void addLiveIns(const MachineBasicBlock *MBB, bool AddPristines = false); + + /// \brief Adds all live-out registers of basic block @p MBB; After prologue/ + /// epilogue insertion \p AddPristines should be set to true to insert the + /// pristine registers. + void addLiveOuts(const MachineBasicBlock *MBB, bool AddPristines = false); typedef SparseSet<unsigned>::const_iterator const_iterator; const_iterator begin() const { return LiveRegs.begin(); } diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h index f04efc3d9f78..c97c636abbb4 100644 --- a/include/llvm/CodeGen/LiveRangeEdit.h +++ b/include/llvm/CodeGen/LiveRangeEdit.h @@ -228,6 +228,6 @@ public: const MachineBlockFrequencyInfo&); }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h index b4808ab1f1d4..f495507c66ec 100644 --- a/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/include/llvm/CodeGen/LiveStackAnalysis.h @@ -95,6 +95,6 @@ namespace llvm { /// print - Implement the dump method. void print(raw_ostream &O, const Module* = nullptr) const override; }; -} // namespace llvm +} #endif /* LLVM_CODEGEN_LIVESTACK_ANALYSIS_H */ diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index 334e8c5eab6c..55b97dc3e71d 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -306,6 +306,6 @@ public: void setPHIJoin(unsigned Reg) { PHIJoins.set(Reg); } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MIRYamlMapping.h b/include/llvm/CodeGen/MIRYamlMapping.h index b1fe47a17a2d..a6ffeb382978 100644 --- a/include/llvm/CodeGen/MIRYamlMapping.h +++ b/include/llvm/CodeGen/MIRYamlMapping.h @@ -25,22 +25,84 @@ namespace llvm { namespace yaml { +/// A wrapper around std::string which contains a source range that's being +/// set during parsing. +struct StringValue { + std::string Value; + SMRange SourceRange; + + StringValue() {} + StringValue(std::string Value) : Value(std::move(Value)) {} + + bool operator==(const StringValue &Other) const { + return Value == Other.Value; + } +}; + +template <> struct ScalarTraits<StringValue> { + static void output(const StringValue &S, void *, llvm::raw_ostream &OS) { + OS << S.Value; + } + + static StringRef input(StringRef Scalar, void *Ctx, StringValue &S) { + S.Value = Scalar.str(); + if (const auto *Node = + reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode()) + S.SourceRange = Node->getSourceRange(); + return ""; + } + + static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); } +}; + +struct FlowStringValue : StringValue { + FlowStringValue() {} + FlowStringValue(std::string Value) : StringValue(Value) {} +}; + +template <> struct ScalarTraits<FlowStringValue> { + static void output(const FlowStringValue &S, void *, llvm::raw_ostream &OS) { + return ScalarTraits<StringValue>::output(S, nullptr, OS); + } + + static StringRef input(StringRef Scalar, void *Ctx, FlowStringValue &S) { + return ScalarTraits<StringValue>::input(Scalar, Ctx, S); + } + + static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); } +}; + +} // end namespace yaml +} // end namespace llvm + +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue) +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue) + +namespace llvm { +namespace yaml { + struct MachineBasicBlock { + unsigned ID; std::string Name; unsigned Alignment = 0; bool IsLandingPad = false; bool AddressTaken = false; - // TODO: Serialize the successors and liveins. - // TODO: Serialize machine instructions. + // TODO: Serialize the successor weights and liveins. + std::vector<FlowStringValue> Successors; + + std::vector<StringValue> Instructions; }; template <> struct MappingTraits<MachineBasicBlock> { static void mapping(IO &YamlIO, MachineBasicBlock &MBB) { + YamlIO.mapRequired("id", MBB.ID); YamlIO.mapOptional("name", MBB.Name, std::string()); // Don't print out an empty name. YamlIO.mapOptional("alignment", MBB.Alignment); YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad); YamlIO.mapOptional("addressTaken", MBB.AddressTaken); + YamlIO.mapOptional("successors", MBB.Successors); + YamlIO.mapOptional("instructions", MBB.Instructions); } }; @@ -57,6 +119,13 @@ struct MachineFunction { unsigned Alignment = 0; bool ExposesReturnsTwice = false; bool HasInlineAsm = false; + // Register information + bool IsSSA = false; + bool TracksRegLiveness = false; + bool TracksSubRegLiveness = false; + // TODO: Serialize virtual register definitions. + // TODO: Serialize the various register masks. + // TODO: Serialize live in registers. std::vector<MachineBasicBlock> BasicBlocks; }; @@ -67,6 +136,9 @@ template <> struct MappingTraits<MachineFunction> { YamlIO.mapOptional("alignment", MF.Alignment); YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice); YamlIO.mapOptional("hasInlineAsm", MF.HasInlineAsm); + YamlIO.mapOptional("isSSA", MF.IsSSA); + YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness); + YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness); YamlIO.mapOptional("body", MF.BasicBlocks); } }; diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 619894c077ce..5e5f45cae8fb 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -461,16 +461,27 @@ public: /// instruction of this basic block. If a terminator does not exist, /// it returns end() iterator getFirstTerminator(); - const_iterator getFirstTerminator() const; + const_iterator getFirstTerminator() const { + return const_cast<MachineBasicBlock *>(this)->getFirstTerminator(); + } /// getFirstInstrTerminator - Same getFirstTerminator but it ignores bundles /// and return an instr_iterator instead. instr_iterator getFirstInstrTerminator(); + /// getFirstNonDebugInstr - returns an iterator to the first non-debug + /// instruction in the basic block, or end() + iterator getFirstNonDebugInstr(); + const_iterator getFirstNonDebugInstr() const { + return const_cast<MachineBasicBlock *>(this)->getFirstNonDebugInstr(); + } + /// getLastNonDebugInstr - returns an iterator to the last non-debug /// instruction in the basic block, or end() iterator getLastNonDebugInstr(); - const_iterator getLastNonDebugInstr() const; + const_iterator getLastNonDebugInstr() const { + return const_cast<MachineBasicBlock *>(this)->getLastNonDebugInstr(); + } /// SplitCriticalEdge - Split the critical edge from this block to the /// given successor block, and return the newly created block, or null @@ -649,6 +660,8 @@ public: // Debugging methods. void dump() const; void print(raw_ostream &OS, SlotIndexes* = nullptr) const; + void print(raw_ostream &OS, ModuleSlotTracker &MST, + SlotIndexes * = nullptr) const; // Printing method used by LoopInfo. void printAsOperand(raw_ostream &OS, bool PrintType = true) const; @@ -801,6 +814,6 @@ public: MachineBasicBlock::iterator getInitial() { return I; } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineBlockFrequencyInfo.h b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h index 9d0a069a0b22..feb394e7a69e 100644 --- a/include/llvm/CodeGen/MachineBlockFrequencyInfo.h +++ b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h @@ -66,6 +66,6 @@ public: }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h index da6ea1dbfe40..7ba749559c0f 100644 --- a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h +++ b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h @@ -84,7 +84,7 @@ public: const MachineBasicBlock *Dst) const; }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h index 8a915fb428c3..c619afb83333 100644 --- a/include/llvm/CodeGen/MachineConstantPool.h +++ b/include/llvm/CodeGen/MachineConstantPool.h @@ -174,6 +174,6 @@ public: void dump() const; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineDominanceFrontier.h b/include/llvm/CodeGen/MachineDominanceFrontier.h index f8dd2cd34a82..4131194a0c0f 100644 --- a/include/llvm/CodeGen/MachineDominanceFrontier.h +++ b/include/llvm/CodeGen/MachineDominanceFrontier.h @@ -104,6 +104,6 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override; }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h index 6518114f1952..4428fa618fb0 100644 --- a/include/llvm/CodeGen/MachineDominators.h +++ b/include/llvm/CodeGen/MachineDominators.h @@ -270,6 +270,6 @@ template <> struct GraphTraits<MachineDominatorTree*> } }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index ac92a4b07915..0f5a4b1b09ec 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -600,6 +600,6 @@ public: void dump(const MachineFunction &MF) const; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index d838cad82b0d..94610cabf566 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -546,6 +546,6 @@ template <> struct GraphTraits<Inverse<const MachineFunction*> > : } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineFunctionAnalysis.h b/include/llvm/CodeGen/MachineFunctionAnalysis.h index 576e72bcc002..4c0f5e63ea1d 100644 --- a/include/llvm/CodeGen/MachineFunctionAnalysis.h +++ b/include/llvm/CodeGen/MachineFunctionAnalysis.h @@ -50,6 +50,6 @@ private: void getAnalysisUsage(AnalysisUsage &AU) const override; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineFunctionPass.h b/include/llvm/CodeGen/MachineFunctionPass.h index 0e09c90a9a5a..50a1f6e96217 100644 --- a/include/llvm/CodeGen/MachineFunctionPass.h +++ b/include/llvm/CodeGen/MachineFunctionPass.h @@ -54,6 +54,6 @@ private: bool runOnFunction(Function &F) override; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 0313e93f551d..de7e0a29ea0d 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -1105,6 +1105,8 @@ public: // Debugging support // void print(raw_ostream &OS, bool SkipOpers = false) const; + void print(raw_ostream &OS, ModuleSlotTracker &MST, + bool SkipOpers = false) const; void dump() const; //===--------------------------------------------------------------------===// @@ -1235,6 +1237,6 @@ inline raw_ostream& operator<<(raw_ostream &OS, const MachineInstr &MI) { return OS; } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 0778ff453c38..4f68f38b7bbf 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -40,7 +40,7 @@ namespace RegState { ImplicitDefine = Implicit | Define, ImplicitKill = Implicit | Kill }; -} // namespace RegState +} class MachineInstrBuilder { MachineFunction *MF; @@ -185,8 +185,9 @@ public: return *this; } - const MachineInstrBuilder &addSym(MCSymbol *Sym) const { - MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym)); + const MachineInstrBuilder &addSym(MCSymbol *Sym, + unsigned char TargetFlags = 0) const { + MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym, TargetFlags)); return *this; } @@ -502,6 +503,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineInstrBundle.h b/include/llvm/CodeGen/MachineInstrBundle.h index edebfa63b8b9..122022486345 100644 --- a/include/llvm/CodeGen/MachineInstrBundle.h +++ b/include/llvm/CodeGen/MachineInstrBundle.h @@ -247,6 +247,6 @@ public: const MachineOperand *operator->() const { return &deref(); } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h index b59b58522264..adcd1d0de63d 100644 --- a/include/llvm/CodeGen/MachineJumpTableInfo.h +++ b/include/llvm/CodeGen/MachineJumpTableInfo.h @@ -125,6 +125,6 @@ public: void dump() const; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h index 8c245ae3080f..438ef2e37255 100644 --- a/include/llvm/CodeGen/MachineLoopInfo.h +++ b/include/llvm/CodeGen/MachineLoopInfo.h @@ -186,6 +186,6 @@ template <> struct GraphTraits<MachineLoop*> { } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h index 9962ff9dbc01..a73b92f9a252 100644 --- a/include/llvm/CodeGen/MachineMemOperand.h +++ b/include/llvm/CodeGen/MachineMemOperand.h @@ -27,6 +27,7 @@ namespace llvm { class FoldingSetNodeID; class MDNode; class raw_ostream; +class ModuleSlotTracker; /// MachinePointerInfo - This class contains a discriminated union of /// information about pointers in memory operands, relating them back to LLVM IR @@ -200,6 +201,12 @@ public: /// void Profile(FoldingSetNodeID &ID) const; + /// Support for operator<<. + /// @{ + void print(raw_ostream &OS) const; + void print(raw_ostream &OS, ModuleSlotTracker &MST) const; + /// @} + friend bool operator==(const MachineMemOperand &LHS, const MachineMemOperand &RHS) { return LHS.getValue() == RHS.getValue() && @@ -219,8 +226,11 @@ public: } }; -raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MRO); +inline raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MRO) { + MRO.print(OS); + return OS; +} -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index 5faf8de28ee6..ccaa83a238a6 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -284,12 +284,14 @@ public: /// getAddrLabelSymbol - Return the symbol to be used for the specified basic /// block when its address is taken. This cannot be its normal LBB label /// because the block may be accessed outside its containing function. - MCSymbol *getAddrLabelSymbol(const BasicBlock *BB); + MCSymbol *getAddrLabelSymbol(const BasicBlock *BB) { + return getAddrLabelSymbolToEmit(BB).front(); + } /// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified /// basic block when its address is taken. If other blocks were RAUW'd to /// this one, we may have to emit them as well, return the whole set. - std::vector<MCSymbol*> getAddrLabelSymbolToEmit(const BasicBlock *BB); + ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(const BasicBlock *BB); /// takeDeletedSymbolsForFunction - If the specified function has had any /// references to address-taken blocks generated, but the block got deleted, @@ -441,6 +443,6 @@ public: }; // End class MachineModuleInfo -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 8c8ce71253e6..c43e47c36d06 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -27,6 +27,7 @@ class MachineBasicBlock; class MachineInstr; class MachineRegisterInfo; class MDNode; +class ModuleSlotTracker; class TargetMachine; class TargetRegisterInfo; class hash_code; @@ -218,6 +219,8 @@ public: void clearParent() { ParentMI = nullptr; } void print(raw_ostream &os, const TargetRegisterInfo *TRI = nullptr) const; + void print(raw_ostream &os, ModuleSlotTracker &MST, + const TargetRegisterInfo *TRI = nullptr) const; //===--------------------------------------------------------------------===// // Accessors that tell you what kind of MachineOperand you're looking at. @@ -450,11 +453,12 @@ public: return Contents.CFIIndex; } - /// getOffset - Return the offset from the symbol in this operand. This always - /// returns 0 for ExternalSymbol operands. + /// Return the offset from the symbol in this operand. This always returns 0 + /// for ExternalSymbol operands. int64_t getOffset() const { - assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() || - isBlockAddress()) && "Wrong MachineOperand accessor"); + assert((isGlobal() || isSymbol() || isMCSymbol() || isCPI() || + isTargetIndex() || isBlockAddress()) && + "Wrong MachineOperand accessor"); return int64_t(uint64_t(Contents.OffsetedInfo.OffsetHi) << 32) | SmallContents.OffsetLo; } @@ -512,8 +516,9 @@ public: } void setOffset(int64_t Offset) { - assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() || - isBlockAddress()) && "Wrong MachineOperand accessor"); + assert((isGlobal() || isSymbol() || isMCSymbol() || isCPI() || + isTargetIndex() || isBlockAddress()) && + "Wrong MachineOperand accessor"); SmallContents.OffsetLo = unsigned(Offset); Contents.OffsetedInfo.OffsetHi = int(Offset >> 32); } @@ -703,9 +708,12 @@ public: return Op; } - static MachineOperand CreateMCSymbol(MCSymbol *Sym) { + static MachineOperand CreateMCSymbol(MCSymbol *Sym, + unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_MCSymbol); Op.Contents.Sym = Sym; + Op.setOffset(0); + Op.setTargetFlags(TargetFlags); return Op; } @@ -741,6 +749,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) { // See friend declaration above. This additional declaration is required in // order to compile LLVM with IBM xlC compiler. hash_code hash_value(const MachineOperand &MO); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineRegionInfo.h b/include/llvm/CodeGen/MachineRegionInfo.h index 794f1d6a4d60..cf49c297c288 100644 --- a/include/llvm/CodeGen/MachineRegionInfo.h +++ b/include/llvm/CodeGen/MachineRegionInfo.h @@ -176,6 +176,6 @@ EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<MachineFunction>>); EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<MachineFunction>>); EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<MachineFunction>>); -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index c17ad38a177b..e5b837aeea28 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -1036,6 +1036,6 @@ getPressureSets(unsigned RegUnit) const { return PSetIterator(RegUnit, this); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineSSAUpdater.h b/include/llvm/CodeGen/MachineSSAUpdater.h index dad0c4620805..5f988ad86320 100644 --- a/include/llvm/CodeGen/MachineSSAUpdater.h +++ b/include/llvm/CodeGen/MachineSSAUpdater.h @@ -111,6 +111,6 @@ private: MachineSSAUpdater(const MachineSSAUpdater&) = delete; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/MachineValueType.h b/include/llvm/CodeGen/MachineValueType.h index a3eea5b34072..a728df354677 100644 --- a/include/llvm/CodeGen/MachineValueType.h +++ b/include/llvm/CodeGen/MachineValueType.h @@ -644,6 +644,6 @@ class MVT { /// @} }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/PBQPRAConstraint.h b/include/llvm/CodeGen/PBQPRAConstraint.h index 832c043e2f5b..833b9bad613f 100644 --- a/include/llvm/CodeGen/PBQPRAConstraint.h +++ b/include/llvm/CodeGen/PBQPRAConstraint.h @@ -64,6 +64,6 @@ private: void anchor() override; }; -} // namespace llvm +} #endif /* LLVM_CODEGEN_PBQPRACONSTRAINT_H */ diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 3aeec2ac9cab..538c995a7b44 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -637,7 +637,12 @@ namespace llvm { /// createForwardControlFlowIntegrityPass - This pass adds control-flow /// integrity. ModulePass *createForwardControlFlowIntegrityPass(); -} // namespace llvm + + /// InterleavedAccess Pass - This pass identifies and matches interleaved + /// memory accesses to target specific intrinsics. + /// + FunctionPass *createInterleavedAccessPass(const TargetMachine *TM); +} // End llvm namespace /// Target machine pass initializer for passes with dependencies. Use with /// INITIALIZE_TM_PASS_END. diff --git a/include/llvm/CodeGen/PseudoSourceValue.h b/include/llvm/CodeGen/PseudoSourceValue.h index e0ec72f1afa2..a518b6233250 100644 --- a/include/llvm/CodeGen/PseudoSourceValue.h +++ b/include/llvm/CodeGen/PseudoSourceValue.h @@ -29,8 +29,7 @@ namespace llvm { /// space), or constant pool. class PseudoSourceValue { private: - friend raw_ostream &llvm::operator<<(raw_ostream &OS, - const MachineMemOperand &MMO); + friend class MachineMemOperand; // For printCustom(). /// printCustom - Implement printing for PseudoSourceValue. This is called /// from Value::print or Value's operator<<. @@ -106,6 +105,6 @@ namespace llvm { int getFrameIndex() const { return FI; } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h index b2e31fa9a1a1..df3fd34e0af6 100644 --- a/include/llvm/CodeGen/RegisterScavenging.h +++ b/include/llvm/CodeGen/RegisterScavenging.h @@ -184,6 +184,6 @@ private: }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/ResourcePriorityQueue.h b/include/llvm/CodeGen/ResourcePriorityQueue.h index d1ea9ffff9e6..0097e0472e5c 100644 --- a/include/llvm/CodeGen/ResourcePriorityQueue.h +++ b/include/llvm/CodeGen/ResourcePriorityQueue.h @@ -131,6 +131,6 @@ private: unsigned numberRCValPredInSU (SUnit *SU, unsigned RCId); unsigned numberRCValSuccInSU (SUnit *SU, unsigned RCId); }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h index 34adde592950..2be5de640e29 100644 --- a/include/llvm/CodeGen/RuntimeLibcalls.h +++ b/include/llvm/CodeGen/RuntimeLibcalls.h @@ -429,7 +429,7 @@ namespace RTLIB { /// 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); -} // namespace RTLIB -} // namespace llvm +} +} #endif diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 9b5d59c28105..839131416560 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -748,6 +748,6 @@ namespace llvm { reverse_iterator rend() { return Index2Node.rend(); } const_reverse_iterator rend() const { return Index2Node.rend(); } }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/ScheduleHazardRecognizer.h b/include/llvm/CodeGen/ScheduleHazardRecognizer.h index ef872a2b9100..8a40e7212ff6 100644 --- a/include/llvm/CodeGen/ScheduleHazardRecognizer.h +++ b/include/llvm/CodeGen/ScheduleHazardRecognizer.h @@ -106,6 +106,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h index 5911cfbefc81..ab14c2de32b0 100644 --- a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h +++ b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h @@ -121,6 +121,6 @@ public: void RecedeCycle() override; }; -} // namespace llvm +} #endif //!LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index aa50dea25765..c2b1243ee26e 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -495,6 +495,8 @@ public: SDValue getExternalSymbol(const char *Sym, SDLoc dl, EVT VT); SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned char TargetFlags = 0); + SDValue getMCSymbol(MCSymbol *Sym, EVT VT); + SDValue getValueType(EVT); SDValue getRegister(unsigned Reg, EVT VT); SDValue getRegisterMask(const uint32_t *RegMask); @@ -1278,6 +1280,7 @@ private: StringMap<SDNode*> ExternalSymbols; std::map<std::pair<std::string, unsigned char>,SDNode*> TargetExternalSymbols; + DenseMap<MCSymbol *, SDNode *> MCSymbols; }; template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> { diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index dc4fa2b68488..a011e4c338c4 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -301,6 +301,6 @@ private: }; -} // namespace llvm +} #endif /* LLVM_CODEGEN_SELECTIONDAGISEL_H */ diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 4b65eaa4f209..619119096d20 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -89,7 +89,7 @@ namespace ISD { /// 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); -} // namespace ISD +} // end llvm:ISD namespace //===----------------------------------------------------------------------===// /// Unlike LLVM values, Selection DAG nodes may return multiple @@ -579,6 +579,23 @@ public: op_iterator op_end() const { return OperandList+NumOperands; } ArrayRef<SDUse> ops() const { return makeArrayRef(op_begin(), op_end()); } + /// Iterator for directly iterating over the operand SDValue's. + struct value_op_iterator + : iterator_adaptor_base<value_op_iterator, op_iterator, + std::random_access_iterator_tag, SDValue, + ptrdiff_t, value_op_iterator *, + value_op_iterator *> { + explicit value_op_iterator(SDUse *U = nullptr) + : iterator_adaptor_base(U) {} + + const SDValue &operator*() const { return I->get(); } + }; + + iterator_range<value_op_iterator> op_values() const { + return iterator_range<value_op_iterator>(value_op_iterator(op_begin()), + value_op_iterator(op_end())); + } + SDVTList getVTList() const { SDVTList X = { ValueList, NumValues }; return X; @@ -1810,6 +1827,21 @@ public: } }; +class MCSymbolSDNode : public SDNode { + MCSymbol *Symbol; + + friend class SelectionDAG; + MCSymbolSDNode(MCSymbol *Symbol, EVT VT) + : SDNode(ISD::MCSymbol, 0, DebugLoc(), getSDVTList(VT)), Symbol(Symbol) {} + +public: + MCSymbol *getMCSymbol() const { return Symbol; } + + static bool classof(const SDNode *N) { + return N->getOpcode() == ISD::MCSymbol; + } +}; + class CondCodeSDNode : public SDNode { ISD::CondCode Condition; friend class SelectionDAG; @@ -2268,8 +2300,8 @@ namespace ISD { return isa<StoreSDNode>(N) && cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; } -} // namespace ISD +} -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 5f213979b61b..9d6d6f5b1be0 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -705,6 +705,6 @@ namespace llvm { struct IntervalMapInfo<SlotIndex> : IntervalMapHalfOpenInfo<SlotIndex> { }; -} // namespace llvm +} #endif // LLVM_CODEGEN_SLOTINDEXES_H diff --git a/include/llvm/CodeGen/StackMaps.h b/include/llvm/CodeGen/StackMaps.h index ba2740452069..46a773f74aac 100644 --- a/include/llvm/CodeGen/StackMaps.h +++ b/include/llvm/CodeGen/StackMaps.h @@ -255,6 +255,6 @@ private: void debug() { print(dbgs()); } }; -} // namespace llvm +} #endif diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 9a1b63f91bd4..10c099d2c2f5 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -90,10 +90,6 @@ public: ~TargetLoweringObjectFileMachO() override {} TargetLoweringObjectFileMachO(); - /// 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; - /// Emit the module flags that specify the garbage collection information. void emitModuleFlags(MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, @@ -150,10 +146,6 @@ public: 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; - /// Emit Obj-C garbage collection and linker options. Only linker option /// emission is implemented for COFF. void emitModuleFlags(MCStreamer &Streamer, @@ -164,6 +156,9 @@ public: const MCSymbol *KeySym) const override; MCSection *getStaticDtorSection(unsigned Priority, const MCSymbol *KeySym) const override; + + void emitLinkerFlagsForGlobal(raw_ostream &OS, const GlobalValue *GV, + const Mangler &Mang) const override; }; } // end namespace llvm diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index e02d7db3f50e..e1a9fd38290b 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -361,6 +361,6 @@ namespace llvm { unsigned getExtendedSizeInBits() const; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/VirtRegMap.h b/include/llvm/CodeGen/VirtRegMap.h index 5b771d068fb8..d7e92094877d 100644 --- a/include/llvm/CodeGen/VirtRegMap.h +++ b/include/llvm/CodeGen/VirtRegMap.h @@ -185,6 +185,6 @@ namespace llvm { VRM.print(OS); return OS; } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/CodeGen/WinEHFuncInfo.h b/include/llvm/CodeGen/WinEHFuncInfo.h index 5c1b3dfa48aa..291f3905512c 100644 --- a/include/llvm/CodeGen/WinEHFuncInfo.h +++ b/include/llvm/CodeGen/WinEHFuncInfo.h @@ -161,5 +161,5 @@ struct WinEHFuncInfo { void calculateWinCXXEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo); -} // namespace llvm +} #endif // LLVM_CODEGEN_WINEHFUNCINFO_H diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index 1712e5860895..b9fd4504ad76 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -125,9 +125,6 @@ /* Define if you have the libdl library or equivalent. */ #cmakedefine HAVE_LIBDL ${HAVE_LIBDL} -/* Define to 1 if you have the `imagehlp' library (-limagehlp). */ -#cmakedefine HAVE_LIBIMAGEHLP ${HAVE_LIBIMAGEHLP} - /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index 49d1b1f8a6f1..09706499ea30 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -137,9 +137,6 @@ /* Define if libedit is available on this platform. */ #undef HAVE_LIBEDIT -/* Define to 1 if you have the `imagehlp' library (-limagehlp). */ -#undef HAVE_LIBIMAGEHLP - /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index 8e5794dd746e..871e60c56b13 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -172,6 +172,6 @@ public: virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h index 72f304a740a4..6ab5d5ce6f6e 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h @@ -57,6 +57,6 @@ private: AttributeSpecVector AttributeSpecs; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h index f89143854e68..47dbf5fd4f56 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h @@ -49,6 +49,6 @@ public: void dump(raw_ostream &OS) const; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h index 9f7527fc66ea..743f9c696e9e 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h @@ -26,6 +26,6 @@ public: ~DWARFCompileUnit() override; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index 0e29ad6102e6..423c0d32f1b5 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -295,6 +295,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h index 88519ce62875..21142089da6b 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h @@ -58,6 +58,6 @@ private: void clear(); }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h b/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h index 15850b2a6f2c..837a8e63469e 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h @@ -65,6 +65,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h index 58359fa9efbf..791f010a8892 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h @@ -82,6 +82,6 @@ private: DenseSet<uint32_t> ParsedCUOffsets; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h b/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h index 3cbae4119781..f29d5fe9ecde 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h @@ -155,6 +155,6 @@ struct DWARFDebugInfoEntryInlinedChain { const DWARFUnit *U; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index e728d59ebb84..93e7c790ccf9 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -248,6 +248,6 @@ private: LineTableMapTy LineTableMap; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h index 6a3f2adeb8f7..bd44c2e5aab9 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -76,6 +76,6 @@ public: void parse(DataExtractor data); void dump(raw_ostream &OS) const; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index 2d6bb0e00537..7ddcc0d81d59 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -91,6 +91,6 @@ private: void dumpString(raw_ostream &OS, const DWARFUnit *U) const; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h index de853c35cd89..f24e27819da2 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h @@ -32,7 +32,7 @@ protected: bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) override; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index 54209cff57b5..5604b93f2205 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -279,6 +279,6 @@ private: const DWARFDebugInfoEntryMinimal *getSubprogramForAddress(uint64_t Address); }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h b/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h index 8a06d55392d9..b5fa8c33414d 100644 --- a/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h +++ b/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h @@ -54,6 +54,6 @@ private: std::unique_ptr<IPDBEnumSymbols> Enumerator; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/PDB/IPDBDataStream.h b/include/llvm/DebugInfo/PDB/IPDBDataStream.h index 429cd7e7ef74..808a0f3ec3a9 100644 --- a/include/llvm/DebugInfo/PDB/IPDBDataStream.h +++ b/include/llvm/DebugInfo/PDB/IPDBDataStream.h @@ -32,6 +32,6 @@ public: virtual void reset() = 0; virtual IPDBDataStream *clone() const = 0; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h b/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h index 5001a95c25de..645ac96e23a5 100644 --- a/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h +++ b/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h @@ -28,6 +28,6 @@ public: virtual void reset() = 0; virtual MyType *clone() const = 0; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/PDB/IPDBLineNumber.h b/include/llvm/DebugInfo/PDB/IPDBLineNumber.h index 30036df42c91..92cd58d86649 100644 --- a/include/llvm/DebugInfo/PDB/IPDBLineNumber.h +++ b/include/llvm/DebugInfo/PDB/IPDBLineNumber.h @@ -31,6 +31,6 @@ public: virtual uint32_t getCompilandId() const = 0; virtual bool isStatement() const = 0; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/PDB/IPDBSession.h b/include/llvm/DebugInfo/PDB/IPDBSession.h index 1dca9117134d..a130a38a6538 100644 --- a/include/llvm/DebugInfo/PDB/IPDBSession.h +++ b/include/llvm/DebugInfo/PDB/IPDBSession.h @@ -56,6 +56,6 @@ public: virtual std::unique_ptr<IPDBEnumDataStreams> getDebugStreams() const = 0; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/PDB/IPDBSourceFile.h b/include/llvm/DebugInfo/PDB/IPDBSourceFile.h index 8081ea5d7712..55000eff02f0 100644 --- a/include/llvm/DebugInfo/PDB/IPDBSourceFile.h +++ b/include/llvm/DebugInfo/PDB/IPDBSourceFile.h @@ -32,6 +32,6 @@ public: virtual PDB_Checksum getChecksumType() const = 0; virtual std::unique_ptr<IPDBEnumSymbols> getCompilands() const = 0; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/PDB/PDBContext.h b/include/llvm/DebugInfo/PDB/PDBContext.h index 3b4a77ec721f..2bb97463f90d 100644 --- a/include/llvm/DebugInfo/PDB/PDBContext.h +++ b/include/llvm/DebugInfo/PDB/PDBContext.h @@ -55,6 +55,6 @@ private: std::string getFunctionName(uint64_t Address, DINameKind NameKind) const; std::unique_ptr<IPDBSession> Session; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/PDB/PDBExtras.h b/include/llvm/DebugInfo/PDB/PDBExtras.h index 64f9694147df..48ce1c127196 100644 --- a/include/llvm/DebugInfo/PDB/PDBExtras.h +++ b/include/llvm/DebugInfo/PDB/PDBExtras.h @@ -33,6 +33,6 @@ raw_ostream &operator<<(raw_ostream &OS, const PDB_UniqueId &Id); raw_ostream &operator<<(raw_ostream &OS, const Variant &Value); raw_ostream &operator<<(raw_ostream &OS, const VersionInfo &Version); raw_ostream &operator<<(raw_ostream &OS, const TagStats &Stats); -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/PDB/PDBSymDumper.h b/include/llvm/DebugInfo/PDB/PDBSymDumper.h index ffd31a55116d..65110f39366f 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymDumper.h +++ b/include/llvm/DebugInfo/PDB/PDBSymDumper.h @@ -56,6 +56,6 @@ public: private: bool RequireImpl; }; -} // namespace llvm +} #endif diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h b/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h index bd85e600a17b..c055dd7f3d49 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h @@ -34,6 +34,6 @@ public: // FORWARD_SYMBOL_METHOD(getValue) FORWARD_SYMBOL_METHOD(getVirtualAddress) }; -} // namespace llvm +} #endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLANNOTATION_H diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h b/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h index 67821793561d..2ca12501d9f6 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h @@ -36,6 +36,6 @@ public: FORWARD_SYMBOL_METHOD(getSymIndexId) FORWARD_SYMBOL_METHOD(getVirtualAddress) }; -} // namespace llvm +} #endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLBLOCK_H diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h index d92830fe3fec..f8c796ae5bdc 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h @@ -33,6 +33,6 @@ public: FORWARD_SYMBOL_METHOD(getSourceFileName) FORWARD_SYMBOL_METHOD(getSymIndexId) }; -} // namespace llvm +} #endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLCOMPILAND_H diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index f86490b55bdc..e8af601d83b6 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -634,6 +634,6 @@ public: // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRef) -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/ExecutionEngine/GenericValue.h b/include/llvm/ExecutionEngine/GenericValue.h index ea5ddfc3274e..0e92f79eba8f 100644 --- a/include/llvm/ExecutionEngine/GenericValue.h +++ b/include/llvm/ExecutionEngine/GenericValue.h @@ -49,5 +49,5 @@ struct GenericValue { inline GenericValue PTOGV(void *P) { return GenericValue(P); } inline void* GVTOP(const GenericValue &GV) { return GV.PointerVal; } -} // namespace llvm +} // End llvm namespace. #endif diff --git a/include/llvm/ExecutionEngine/MCJIT.h b/include/llvm/ExecutionEngine/MCJIT.h index 294f11d332c2..66ddb7cdb875 100644 --- a/include/llvm/ExecutionEngine/MCJIT.h +++ b/include/llvm/ExecutionEngine/MCJIT.h @@ -33,6 +33,6 @@ namespace { LLVMLinkInMCJIT(); } } ForceMCJITLinking; -} // namespace +} #endif diff --git a/include/llvm/ExecutionEngine/ObjectCache.h b/include/llvm/ExecutionEngine/ObjectCache.h index 1084de82a49b..cc01a4e58999 100644 --- a/include/llvm/ExecutionEngine/ObjectCache.h +++ b/include/llvm/ExecutionEngine/ObjectCache.h @@ -35,6 +35,6 @@ public: virtual std::unique_ptr<MemoryBuffer> getObject(const Module* M) = 0; }; -} // namespace llvm +} #endif diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 4c515dbfa8e8..9694b80d1928 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -241,11 +241,10 @@ private: } static std::string Mangle(StringRef Name, const DataLayout &DL) { - Mangler M(&DL); std::string MangledName; { raw_string_ostream MangledNameStream(MangledName); - M.getNameWithPrefix(MangledNameStream, Name); + Mangler::getNameWithPrefix(MangledNameStream, Name, DL); } return MangledName; } diff --git a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h index 71c83f7e05f6..93ba02b38706 100644 --- a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h @@ -193,7 +193,7 @@ private: auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>(); for (const auto &M : Ms) { - Mangler Mang(&M->getDataLayout()); + Mangler Mang; for (const auto &V : M->globals()) if (auto GV = addGlobalValue(*Symbols, V, Mang, SearchName, diff --git a/include/llvm/ExecutionEngine/Orc/NullResolver.h b/include/llvm/ExecutionEngine/Orc/NullResolver.h new file mode 100644 index 000000000000..1560c6d86e0f --- /dev/null +++ b/include/llvm/ExecutionEngine/Orc/NullResolver.h @@ -0,0 +1,36 @@ +//===------ NullResolver.h - Reject symbol lookup requests ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Defines a RuntimeDyld::SymbolResolver subclass that rejects all symbol +// resolution requests, for clients that have no cross-object fixups. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H +#define LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H + +#include "llvm/ExecutionEngine/RuntimeDyld.h" + +namespace llvm { +namespace orc { + +/// SymbolResolver impliementation that rejects all resolution requests. +/// Useful for clients that have no cross-object fixups. +class NullResolver : public RuntimeDyld::SymbolResolver { +public: + RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) final; + + RuntimeDyld::SymbolInfo + findSymbolInLogicalDylib(const std::string &Name) final; +}; + +} // End namespace orc. +} // End namespace llvm. + +#endif // LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H diff --git a/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h new file mode 100644 index 000000000000..7af662085474 --- /dev/null +++ b/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h @@ -0,0 +1,112 @@ +//===- ObjectTransformLayer.h - Run all objects through functor -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Run all objects passed in through a user supplied functor. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTTRANSFORMLAYER_H +#define LLVM_EXECUTIONENGINE_ORC_OBJECTTRANSFORMLAYER_H + +#include "JITSymbol.h" + +namespace llvm { +namespace orc { + +/// @brief Object mutating layer. +/// +/// This layer accepts sets of ObjectFiles (via addObjectSet). It +/// immediately applies the user supplied functor to each object, then adds +/// the set of transformed objects to the layer below. +template <typename BaseLayerT, typename TransformFtor> +class ObjectTransformLayer { +public: + /// @brief Handle to a set of added objects. + typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT; + + /// @brief Construct an ObjectTransformLayer with the given BaseLayer + ObjectTransformLayer(BaseLayerT &BaseLayer, + TransformFtor Transform = TransformFtor()) + : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} + + /// @brief Apply the transform functor to each object in the object set, then + /// add the resulting set of objects to the base layer, along with the + /// memory manager and symbol resolver. + /// + /// @return A handle for the added objects. + template <typename ObjSetT, typename MemoryManagerPtrT, + typename SymbolResolverPtrT> + ObjSetHandleT addObjectSet(ObjSetT &Objects, MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { + + for (auto I = Objects.begin(), E = Objects.end(); I != E; ++I) + *I = Transform(std::move(*I)); + + return BaseLayer.addObjectSet(Objects, std::move(MemMgr), + std::move(Resolver)); + } + + /// @brief Remove the object set associated with the handle H. + void removeObjectSet(ObjSetHandleT H) { BaseLayer.removeObjectSet(H); } + + /// @brief Search for the given named symbol. + /// @param Name The name of the symbol to search for. + /// @param ExportedSymbolsOnly If true, search only for exported symbols. + /// @return A handle for the given named symbol, if it exists. + JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { + return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); + } + + /// @brief Get the address of the given symbol in the context of the set of + /// objects represented by the handle H. This call is forwarded to the + /// base layer's implementation. + /// @param H The handle for the object set to search in. + /// @param Name The name of the symbol to search for. + /// @param ExportedSymbolsOnly If true, search only for exported symbols. + /// @return A handle for the given named symbol, if it is found in the + /// given object set. + JITSymbol findSymbolIn(ObjSetHandleT H, const std::string &Name, + bool ExportedSymbolsOnly) { + return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly); + } + + /// @brief Immediately emit and finalize the object set represented by the + /// given handle. + /// @param H Handle for object set to emit/finalize. + void emitAndFinalize(ObjSetHandleT H) { BaseLayer.emitAndFinalize(H); } + + /// @brief Map section addresses for the objects associated with the handle H. + void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress, + TargetAddress TargetAddr) { + BaseLayer.mapSectionAddress(H, LocalAddress, TargetAddr); + } + + // Ownership hack. + // FIXME: Remove this as soon as RuntimeDyldELF can apply relocations without + // referencing the original object. + template <typename OwningMBSet> + void takeOwnershipOfBuffers(ObjSetHandleT H, OwningMBSet MBs) { + BaseLayer.takeOwnershipOfBuffers(H, std::move(MBs)); + } + + /// @brief Access the transform functor directly. + TransformFtor &getTransform() { return Transform; } + + /// @brief Access the mumate functor directly. + const TransformFtor &getTransform() const { return Transform; } + +private: + BaseLayerT &BaseLayer; + TransformFtor Transform; +}; + +} // End namespace orc. +} // End namespace llvm. + +#endif // LLVM_EXECUTIONENGINE_ORC_OBJECTTRANSFORMLAYER_H diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h index bbf996842188..0b0dcb021f14 100644 --- a/include/llvm/ExecutionEngine/SectionMemoryManager.h +++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h @@ -100,7 +100,7 @@ private: MemoryGroup RODataMem; }; -} // namespace llvm +} #endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h index 12c8df570cce..fc04fe71cbf0 100644 --- a/include/llvm/IR/Argument.h +++ b/include/llvm/IR/Argument.h @@ -131,6 +131,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/AssemblyAnnotationWriter.h b/include/llvm/IR/AssemblyAnnotationWriter.h index 1ae30188770c..19e32a2dcdcc 100644 --- a/include/llvm/IR/AssemblyAnnotationWriter.h +++ b/include/llvm/IR/AssemblyAnnotationWriter.h @@ -58,6 +58,6 @@ public: virtual void printInfoComment(const Value &, formatted_raw_ostream &) {} }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 1d92d187d54e..366bf709ab16 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -575,6 +575,6 @@ AttrBuilder typeIncompatible(const Type *Ty); } // end AttributeFuncs namespace -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/IR/AutoUpgrade.h b/include/llvm/IR/AutoUpgrade.h index 9ecabec63f65..a4b3c410c4f6 100644 --- a/include/llvm/IR/AutoUpgrade.h +++ b/include/llvm/IR/AutoUpgrade.h @@ -66,6 +66,6 @@ namespace llvm { /// Upgrade a metadata string constant in place. void UpgradeMDStringConstant(std::string &String); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index b0fad4f2981f..66581bfedbe6 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -346,6 +346,6 @@ inline BasicBlock *ilist_traits<BasicBlock>::createSentinel() const { // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef) -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/CFG.h b/include/llvm/IR/CFG.h index e6e21b4b3be1..f78220a52033 100644 --- a/include/llvm/IR/CFG.h +++ b/include/llvm/IR/CFG.h @@ -396,6 +396,6 @@ template <> struct GraphTraits<Inverse<const Function*> > : } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index 0270caaaf137..dd2903e807e1 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -38,6 +38,7 @@ class CallInst; class InvokeInst; template <typename FunTy = const Function, + typename BBTy = const BasicBlock, typename ValTy = const Value, typename UserTy = const User, typename InstrTy = const Instruction, @@ -82,6 +83,9 @@ public: InstrTy *operator->() const { return I.getPointer(); } explicit operator bool() const { return I.getPointer(); } + /// Get the basic block containing the call site + BBTy* getParent() const { return getInstruction()->getParent(); } + /// getCalledValue - Return the pointer to function that is being called. /// ValTy *getCalledValue() const { @@ -189,6 +193,20 @@ public: else \ cast<InvokeInst>(II)->METHOD + unsigned getNumArgOperands() const { + CALLSITE_DELEGATE_GETTER(getNumArgOperands()); + } + + ValTy *getArgOperand(unsigned i) const { + CALLSITE_DELEGATE_GETTER(getArgOperand(i)); + } + + bool isInlineAsm() const { + if (isCall()) + return cast<CallInst>(getInstruction())->isInlineAsm(); + return false; + } + /// getCallingConv/setCallingConv - get or set the calling convention of the /// call. CallingConv::ID getCallingConv() const { @@ -366,8 +384,9 @@ private: } }; -class CallSite : public CallSiteBase<Function, Value, User, Instruction, - CallInst, InvokeInst, User::op_iterator> { +class CallSite : public CallSiteBase<Function, BasicBlock, Value, User, + Instruction, CallInst, InvokeInst, + User::op_iterator> { public: CallSite() {} CallSite(CallSiteBase B) : CallSiteBase(B) {} @@ -397,6 +416,6 @@ public: ImmutableCallSite(CallSite CS) : CallSiteBase(CS.getInstruction()) {} }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/CallingConv.h b/include/llvm/IR/CallingConv.h index 846e58c714c3..9872e6ec794d 100644 --- a/include/llvm/IR/CallingConv.h +++ b/include/llvm/IR/CallingConv.h @@ -146,8 +146,8 @@ namespace CallingConv { /// in SSE registers. X86_VectorCall = 80 }; -} // namespace CallingConv +} // End CallingConv namespace -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Comdat.h b/include/llvm/IR/Comdat.h index 50b11be6c818..4d4c15fb68cd 100644 --- a/include/llvm/IR/Comdat.h +++ b/include/llvm/IR/Comdat.h @@ -61,6 +61,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Comdat &C) { return OS; } -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/IR/Constant.h b/include/llvm/IR/Constant.h index 7db09d0b108f..019b4343a133 100644 --- a/include/llvm/IR/Constant.h +++ b/include/llvm/IR/Constant.h @@ -47,9 +47,6 @@ protected: Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps) : User(ty, vty, Ops, NumOps) {} - void destroyConstantImpl(); - void replaceUsesOfWithOnConstantImpl(Constant *Replacement); - public: /// isNullValue - Return true if this is the value that would be returned by /// getNullValue. @@ -126,14 +123,14 @@ public: /// vector of constant integers, all equal, and the common value is returned. const APInt &getUniqueInteger() const; - /// destroyConstant - Called if some element of this constant is no longer - /// valid. At this point only other constants may be on the use_list for this + /// Called if some element of this constant is no longer valid. + /// At this point only other constants may be on the use_list for this /// constant. Any constants on our Use list must also be destroy'd. The /// implementation must be sure to remove the constant from the list of - /// available cached constants. Implementations should call - /// destroyConstantImpl as the last thing they do, to destroy all users and - /// delete this. - virtual void destroyConstant() { llvm_unreachable("Not reached!"); } + /// available cached constants. Implementations should implement + /// destroyConstantImpl to remove constants from any pools/maps they are + /// contained it. + void destroyConstant(); //// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { @@ -141,8 +138,8 @@ public: V->getValueID() <= ConstantLastVal; } - /// replaceUsesOfWithOnConstant - This method is a special form of - /// User::replaceUsesOfWith (which does not work on constants) that does work + /// This method is a special form of User::replaceUsesOfWith + /// (which does not work on constants) that does work /// on constants. Basically this method goes through the trouble of building /// a new constant that is equivalent to the current one, with all uses of /// From replaced with uses of To. After this construction is completed, all @@ -151,15 +148,7 @@ public: /// use Value::replaceAllUsesWith, which automatically dispatches to this /// method as needed. /// - virtual void replaceUsesOfWithOnConstant(Value *, Value *, Use *) { - // Provide a default implementation for constants (like integers) that - // cannot use any other values. This cannot be called at runtime, but needs - // to be here to avoid link errors. - assert(getNumOperands() == 0 && "replaceUsesOfWithOnConstant must be " - "implemented for all constants that have operands!"); - llvm_unreachable("Constants that do not have operands cannot be using " - "'From'!"); - } + void handleOperandChange(Value *, Value *, Use *); static Constant *getNullValue(Type* Ty); @@ -187,6 +176,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/ConstantFolder.h b/include/llvm/IR/ConstantFolder.h index 4e87cd052afd..fb6ca3b3184c 100644 --- a/include/llvm/IR/ConstantFolder.h +++ b/include/llvm/IR/ConstantFolder.h @@ -240,6 +240,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h index 8a7488e13125..9ded3ca36a70 100644 --- a/include/llvm/IR/ConstantRange.h +++ b/include/llvm/IR/ConstantRange.h @@ -273,6 +273,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, const ConstantRange &CR) { return OS; } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h index b2ef77b2c3ec..0c7a84fc8bfe 100644 --- a/include/llvm/IR/Constants.h +++ b/include/llvm/IR/Constants.h @@ -50,6 +50,11 @@ class ConstantInt : public Constant { ConstantInt(const ConstantInt &) = delete; ConstantInt(IntegerType *Ty, const APInt& V); APInt Val; + + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + protected: // allocate space for exactly zero operands void *operator new(size_t s) { @@ -231,6 +236,11 @@ class ConstantFP : public Constant { void *operator new(size_t, unsigned) = delete; ConstantFP(const ConstantFP &) = delete; friend class LLVMContextImpl; + + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + protected: ConstantFP(Type *Ty, const APFloat& V); protected: @@ -297,6 +307,11 @@ public: class ConstantAggregateZero : public Constant { void *operator new(size_t, unsigned) = delete; ConstantAggregateZero(const ConstantAggregateZero &) = delete; + + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + protected: explicit ConstantAggregateZero(Type *ty) : Constant(ty, ConstantAggregateZeroVal, nullptr, 0) {} @@ -308,8 +323,6 @@ protected: public: static ConstantAggregateZero *get(Type *Ty); - void destroyConstant() override; - /// getSequentialElement - If this CAZ has array or vector type, return a zero /// with the right element type. Constant *getSequentialElement() const; @@ -343,6 +356,11 @@ public: class ConstantArray : public Constant { friend struct ConstantAggrKeyType<ConstantArray>; ConstantArray(const ConstantArray &) = delete; + + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + protected: ConstantArray(ArrayType *T, ArrayRef<Constant *> Val); public: @@ -363,9 +381,6 @@ public: return cast<ArrayType>(Value::getType()); } - void destroyConstant() override; - void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override; - /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Value *V) { return V->getValueID() == ConstantArrayVal; @@ -385,6 +400,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantArray, Constant) class ConstantStruct : public Constant { friend struct ConstantAggrKeyType<ConstantStruct>; ConstantStruct(const ConstantStruct &) = delete; + + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + protected: ConstantStruct(StructType *T, ArrayRef<Constant *> Val); public: @@ -421,9 +441,6 @@ public: return cast<StructType>(Value::getType()); } - void destroyConstant() override; - void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override; - /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Value *V) { return V->getValueID() == ConstantStructVal; @@ -444,6 +461,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantStruct, Constant) class ConstantVector : public Constant { friend struct ConstantAggrKeyType<ConstantVector>; ConstantVector(const ConstantVector &) = delete; + + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + protected: ConstantVector(VectorType *T, ArrayRef<Constant *> Val); public: @@ -472,9 +494,6 @@ public: /// elements have the same value, return that value. Otherwise return NULL. Constant *getSplatValue() const; - void destroyConstant() override; - void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override; - /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Value *V) { return V->getValueID() == ConstantVectorVal; @@ -494,6 +513,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantVector, Constant) class ConstantPointerNull : public Constant { void *operator new(size_t, unsigned) = delete; ConstantPointerNull(const ConstantPointerNull &) = delete; + + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + protected: explicit ConstantPointerNull(PointerType *T) : Constant(T, @@ -508,8 +532,6 @@ public: /// get() - Static factory methods - Return objects of the specified value static ConstantPointerNull *get(PointerType *T); - void destroyConstant() override; - /// getType - Specialize the getType() method to always return an PointerType, /// which reduces the amount of casting needed in parts of the compiler. /// @@ -545,6 +567,11 @@ class ConstantDataSequential : public Constant { ConstantDataSequential *Next; void *operator new(size_t, unsigned) = delete; ConstantDataSequential(const ConstantDataSequential &) = delete; + + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + protected: explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data) : Constant(ty, VT, nullptr, 0), DataElements(Data), Next(nullptr) {} @@ -635,8 +662,6 @@ public: /// host endianness of the data elements. StringRef getRawDataValues() const; - void destroyConstant() override; - /// Methods for support type inquiry through isa, cast, and dyn_cast: /// static bool classof(const Value *V) { @@ -778,6 +803,11 @@ class BlockAddress : public Constant { void *operator new(size_t, unsigned) = delete; void *operator new(size_t s) { return User::operator new(s, 2); } BlockAddress(Function *F, BasicBlock *BB); + + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + public: /// get - Return a BlockAddress for the specified function and basic block. static BlockAddress *get(Function *F, BasicBlock *BB); @@ -798,9 +828,6 @@ public: Function *getFunction() const { return (Function*)Op<0>().get(); } BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); } - void destroyConstant() override; - void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override; - /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { return V->getValueID() == BlockAddressVal; @@ -825,6 +852,10 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BlockAddress, Value) class ConstantExpr : public Constant { friend struct ConstantExprKeyType; + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + protected: ConstantExpr(Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps) : Constant(ty, ConstantExprVal, Ops, NumOps) { @@ -1156,9 +1187,6 @@ public: /// would make it harder to remove ConstantExprs altogether. Instruction *getAsInstruction(); - void destroyConstant() override; - void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override; - /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { return V->getValueID() == ConstantExprVal; @@ -1192,6 +1220,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantExpr, Constant) class UndefValue : public Constant { void *operator new(size_t, unsigned) = delete; UndefValue(const UndefValue &) = delete; + + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + protected: explicit UndefValue(Type *T) : Constant(T, UndefValueVal, nullptr, 0) {} protected: @@ -1224,14 +1257,12 @@ public: /// \brief Return the number of elements in the array, vector, or struct. unsigned getNumElements() const; - void destroyConstant() override; - /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Value *V) { return V->getValueID() == UndefValueVal; } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h index 997113191d19..d6296b622aab 100644 --- a/include/llvm/IR/DIBuilder.h +++ b/include/llvm/IR/DIBuilder.h @@ -36,14 +36,9 @@ namespace llvm { Module &M; LLVMContext &VMContext; - TempMDTuple TempEnumTypes; - TempMDTuple TempRetainTypes; - TempMDTuple TempSubprograms; - TempMDTuple TempGVs; - TempMDTuple TempImportedModules; - - Function *DeclareFn; // llvm.dbg.declare - Function *ValueFn; // llvm.dbg.value + DICompileUnit *CUNode; ///< The one compile unit created by this DIBuiler. + Function *DeclareFn; ///< llvm.dbg.declare + Function *ValueFn; ///< llvm.dbg.value SmallVector<Metadata *, 4> AllEnumTypes; /// Track the RetainTypes, since they can be updated later on. @@ -566,6 +561,20 @@ namespace llvm { DINamespace *createNameSpace(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo); + /// createModule - This creates new descriptor for a module + /// with the specified parent scope. + /// @param Scope Parent scope + /// @param Name Name of this module + /// @param ConfigurationMacros + /// A space-separated shell-quoted list of -D macro + /// definitions as they would appear on a command line. + /// @param IncludePath The path to the module map file. + /// @param ISysRoot The clang system root (value of -isysroot). + DIModule *createModule(DIScope *Scope, StringRef Name, + StringRef ConfigurationMacros, + StringRef IncludePath, + StringRef ISysRoot); + /// createLexicalBlockFile - This creates a descriptor for a lexical /// block with a new file attached. This merely extends the existing /// lexical block as it crosses a file. @@ -598,6 +607,13 @@ namespace llvm { DIImportedEntity *createImportedModule(DIScope *Context, DIImportedEntity *NS, unsigned Line); + /// \brief Create a descriptor for an imported module. + /// @param Context The scope this module is imported into + /// @param M The module being imported here + /// @param Line Line number + DIImportedEntity *createImportedModule(DIScope *Context, DIModule *M, + unsigned Line); + /// \brief Create a descriptor for an imported function. /// @param Context The scope this module is imported into /// @param Decl The declaration (or definition) of a function, type, or diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h index 81cf66509042..892d6c9936c0 100644 --- a/include/llvm/IR/DataLayout.h +++ b/include/llvm/IR/DataLayout.h @@ -222,7 +222,9 @@ public: /// This representation is in the same format accepted by the string /// 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; } + const std::string &getStringRepresentation() const { + return StringRepresentation; + } /// \brief Test if the DataLayout was constructed from an empty string. bool isDefault() const { return StringRepresentation.empty(); } @@ -542,6 +544,6 @@ inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const { } } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 03dd90159468..5c99300c35c7 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -218,6 +218,7 @@ public: case DILocalVariableKind: case DIObjCPropertyKind: case DIImportedEntityKind: + case DIModuleKind: return true; } } @@ -443,6 +444,7 @@ public: case DILexicalBlockKind: case DILexicalBlockFileKind: case DINamespaceKind: + case DIModuleKind: return true; } } @@ -1083,12 +1085,21 @@ public: /// deleted on a uniquing collision. In practice, uniquing collisions on \a /// DICompileUnit should be fairly rare. /// @{ + void replaceEnumTypes(DISubprogramArray N) { + replaceOperandWith(4, N.get()); + } + void replaceRetainedTypes(DISubprogramArray N) { + replaceOperandWith(5, N.get()); + } void replaceSubprograms(DISubprogramArray N) { replaceOperandWith(6, N.get()); } void replaceGlobalVariables(DIGlobalVariableArray N) { replaceOperandWith(7, N.get()); } + void replaceImportedEntities(DIGlobalVariableArray N) { + replaceOperandWith(8, N.get()); + } /// @} static bool classof(const Metadata *MD) { @@ -1623,6 +1634,66 @@ public: } }; +/// \brief A (clang) module that has been imported by the compile unit. +/// +class DIModule : public DIScope { + friend class LLVMContextImpl; + friend class MDNode; + + DIModule(LLVMContext &Context, StorageType Storage, ArrayRef<Metadata *> Ops) + : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {} + ~DIModule() {} + + static DIModule *getImpl(LLVMContext &Context, DIScope *Scope, + StringRef Name, StringRef ConfigurationMacros, + StringRef IncludePath, StringRef ISysRoot, + StorageType Storage, bool ShouldCreate = true) { + return getImpl(Context, Scope, getCanonicalMDString(Context, Name), + getCanonicalMDString(Context, ConfigurationMacros), + getCanonicalMDString(Context, IncludePath), + getCanonicalMDString(Context, ISysRoot), + Storage, ShouldCreate); + } + static DIModule *getImpl(LLVMContext &Context, Metadata *Scope, + MDString *Name, MDString *ConfigurationMacros, + MDString *IncludePath, MDString *ISysRoot, + StorageType Storage, bool ShouldCreate = true); + + TempDIModule cloneImpl() const { + return getTemporary(getContext(), getScope(), getName(), + getConfigurationMacros(), getIncludePath(), + getISysRoot()); + } + +public: + DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name, + StringRef ConfigurationMacros, StringRef IncludePath, + StringRef ISysRoot), + (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot)) + DEFINE_MDNODE_GET(DIModule, + (Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, + MDString *IncludePath, MDString *ISysRoot), + (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot)) + + TempDIModule clone() const { return cloneImpl(); } + + DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); } + StringRef getName() const { return getStringOperand(1); } + StringRef getConfigurationMacros() const { return getStringOperand(2); } + StringRef getIncludePath() const { return getStringOperand(3); } + StringRef getISysRoot() const { return getStringOperand(4); } + + Metadata *getRawScope() const { return getOperand(0); } + MDString *getRawName() const { return getOperandAs<MDString>(1); } + MDString *getRawConfigurationMacros() const { return getOperandAs<MDString>(2); } + MDString *getRawIncludePath() const { return getOperandAs<MDString>(3); } + MDString *getRawISysRoot() const { return getOperandAs<MDString>(4); } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == DIModuleKind; + } +}; + /// \brief Base class for template parameters. class DITemplateParameter : public DINode { protected: diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h index 9f2671a08dc1..4a94499b4cf5 100644 --- a/include/llvm/IR/DerivedTypes.h +++ b/include/llvm/IR/DerivedTypes.h @@ -477,6 +477,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h index 93f5ede5fc9c..c1f208e3d72f 100644 --- a/include/llvm/IR/Dominators.h +++ b/include/llvm/IR/Dominators.h @@ -230,6 +230,6 @@ public: void print(raw_ostream &OS, const Module *M = nullptr) const override; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index f66ac0b69b4b..02ea056de39b 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -618,6 +618,6 @@ struct OperandTraits<Function> : public OptionalOperandTraits<Function> {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(Function, Value) -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h index 433de3feecdc..1d6c9157f0b8 100644 --- a/include/llvm/IR/GVMaterializer.h +++ b/include/llvm/IR/GVMaterializer.h @@ -59,6 +59,6 @@ public: virtual std::vector<StructType *> getIdentifiedStructTypes() const = 0; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h index 2316749584c6..ce73b7af8ca1 100644 --- a/include/llvm/IR/GlobalAlias.h +++ b/include/llvm/IR/GlobalAlias.h @@ -118,6 +118,6 @@ struct OperandTraits<GlobalAlias> : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalAlias, Constant) -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h index 5f58c9c6a52c..f0552410b61d 100644 --- a/include/llvm/IR/GlobalObject.h +++ b/include/llvm/IR/GlobalObject.h @@ -71,6 +71,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index 5e1c5ffe9b13..f2379705d460 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -90,6 +90,10 @@ private: // (19 + 3 + 2 + 1 + 2 + 5) == 32. unsigned SubClassData : GlobalValueSubClassDataBits; + friend class Constant; + void destroyConstantImpl(); + Value *handleOperandChangeImpl(Value *From, Value *To, Use *U); + protected: /// \brief The intrinsic ID for this subclass (which must be a Function). /// @@ -334,9 +338,6 @@ public: /// @} - /// Override from Constant class. - void destroyConstant() override; - /// Return true if the primary definition of this global value is outside of /// the current translation unit. bool isDeclaration() const; @@ -367,6 +368,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h index 4269a70666f7..a0159830ba3b 100644 --- a/include/llvm/IR/GlobalVariable.h +++ b/include/llvm/IR/GlobalVariable.h @@ -45,7 +45,6 @@ class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> { // can change from its initial // value before global // initializers are run? - public: // allocate space for exactly one operand void *operator new(size_t s) { @@ -166,10 +165,6 @@ public: /// void eraseFromParent() override; - /// Override Constant's implementation of this method so we can - /// replace constant initializers. - void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { return V->getValueID() == Value::GlobalVariableVal; @@ -183,6 +178,6 @@ struct OperandTraits<GlobalVariable> : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalVariable, Value) -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index 0472ec553ce4..e6b5393c3397 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -101,19 +101,8 @@ public: void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { BB = TheBB; InsertPt = IP; - } - - /// \brief Find the nearest point that dominates this use, and specify that - /// created instructions should be inserted at this point. - void SetInsertPoint(Use &U) { - Instruction *UseInst = cast<Instruction>(U.getUser()); - if (PHINode *Phi = dyn_cast<PHINode>(UseInst)) { - BasicBlock *PredBB = Phi->getIncomingBlock(U); - assert(U != PredBB->getTerminator() && "critical edge not split"); - SetInsertPoint(PredBB, PredBB->getTerminator()); - return; - } - SetInsertPoint(UseInst); + if (IP != TheBB->end()) + SetCurrentDebugLocation(IP->getDebugLoc()); } /// \brief Set location information used by debugging information. @@ -550,13 +539,6 @@ public: explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = nullptr) : IRBuilderBase(IP->getContext(), FPMathTag), Folder() { SetInsertPoint(IP); - SetCurrentDebugLocation(IP->getDebugLoc()); - } - - explicit IRBuilder(Use &U, MDNode *FPMathTag = nullptr) - : IRBuilderBase(U->getContext(), FPMathTag), Folder() { - SetInsertPoint(U); - SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc()); } IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F, @@ -1679,6 +1661,6 @@ public: // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef) -} // namespace llvm +} #endif diff --git a/include/llvm/IR/IRPrintingPasses.h b/include/llvm/IR/IRPrintingPasses.h index 3969c838758f..5f1d56f7e831 100644 --- a/include/llvm/IR/IRPrintingPasses.h +++ b/include/llvm/IR/IRPrintingPasses.h @@ -83,6 +83,6 @@ public: static StringRef name() { return "PrintFunctionPass"; } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h index b5174c81b160..08b51021116c 100644 --- a/include/llvm/IR/InlineAsm.h +++ b/include/llvm/IR/InlineAsm.h @@ -358,6 +358,6 @@ public: }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/InstIterator.h b/include/llvm/IR/InstIterator.h index a73d4898c142..f3ce6490fb66 100644 --- a/include/llvm/IR/InstIterator.h +++ b/include/llvm/IR/InstIterator.h @@ -153,6 +153,6 @@ inline iterator_range<const_inst_iterator> inst_range(const Function &F) { return iterator_range<const_inst_iterator>(inst_begin(F), inst_end(F)); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/InstVisitor.h b/include/llvm/IR/InstVisitor.h index 0eb337e816ba..581e860b8382 100644 --- a/include/llvm/IR/InstVisitor.h +++ b/include/llvm/IR/InstVisitor.h @@ -284,6 +284,6 @@ private: #undef DELEGATE -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index 9df70436a825..b791ded0e194 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -139,7 +139,11 @@ protected: const Twine &Name, Instruction *InsertBefore); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd); - BinaryOperator *clone_impl() const override; + + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + BinaryOperator *cloneImpl() const; + public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -894,6 +898,6 @@ struct OperandTraits<CmpInst> : public FixedNumOperandTraits<CmpInst, 2> { DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value) -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index 6fea926e7e9f..6e3de1f13545 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -509,8 +509,10 @@ protected: Instruction *InsertBefore = nullptr); Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd); - virtual Instruction *clone_impl() const = 0; +private: + /// Create a copy of this instruction. + Instruction *cloneImpl() const; }; inline Instruction *ilist_traits<Instruction>::createSentinel() const { @@ -536,6 +538,6 @@ public: enum { NumLowBitsAvailable = 2 }; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 369b7db0d295..c5890f01ea70 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -22,6 +22,7 @@ #include "llvm/IR/Attributes.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" #include "llvm/Support/ErrorHandling.h" #include <iterator> @@ -76,7 +77,10 @@ class AllocaInst : public UnaryInstruction { Type *AllocatedType; protected: - AllocaInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + AllocaInst *cloneImpl() const; + public: explicit AllocaInst(Type *Ty, Value *ArraySize = nullptr, const Twine &Name = "", @@ -173,7 +177,10 @@ private: class LoadInst : public UnaryInstruction { void AssertOK(); protected: - LoadInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + LoadInst *cloneImpl() const; + public: LoadInst(Value *Ptr, const Twine &NameStr, Instruction *InsertBefore); LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd); @@ -310,7 +317,10 @@ class StoreInst : public Instruction { void *operator new(size_t, unsigned) = delete; void AssertOK(); protected: - StoreInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + StoreInst *cloneImpl() const; + public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -436,7 +446,10 @@ class FenceInst : public Instruction { void *operator new(size_t, unsigned) = delete; void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope); protected: - FenceInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + FenceInst *cloneImpl() const; + public: // allocate space for exactly zero operands void *operator new(size_t s) { @@ -505,7 +518,10 @@ class AtomicCmpXchgInst : public Instruction { AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SynchronizationScope SynchScope); protected: - AtomicCmpXchgInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + AtomicCmpXchgInst *cloneImpl() const; + public: // allocate space for exactly three operands void *operator new(size_t s) { @@ -658,7 +674,10 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicCmpXchgInst, Value) class AtomicRMWInst : public Instruction { void *operator new(size_t, unsigned) = delete; protected: - AtomicRMWInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + AtomicRMWInst *cloneImpl() const; + public: /// This enumeration lists the possible modifications atomicrmw can make. In /// the descriptions, 'p' is the pointer to the instruction's memory location, @@ -827,7 +846,10 @@ class GetElementPtrInst : public Instruction { const Twine &NameStr, BasicBlock *InsertAtEnd); protected: - GetElementPtrInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + GetElementPtrInst *cloneImpl() const; + public: static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr, ArrayRef<Value *> IdxList, @@ -1078,8 +1100,11 @@ class ICmpInst: public CmpInst { } protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical ICmpInst - ICmpInst *clone_impl() const override; + ICmpInst *cloneImpl() const; + public: /// \brief Constructor with insert-before-instruction semantics. ICmpInst( @@ -1210,8 +1235,11 @@ public: /// \brief Represents a floating point comparison operator. class FCmpInst: public CmpInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical FCmpInst - FCmpInst *clone_impl() const override; + FCmpInst *cloneImpl() const; + public: /// \brief Constructor with insert-before-instruction semantics. FCmpInst( @@ -1350,7 +1378,10 @@ class CallInst : public Instruction { Instruction *InsertBefore); CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd); protected: - CallInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + CallInst *cloneImpl() const; + public: static CallInst *Create(Value *Func, ArrayRef<Value *> Args, @@ -1478,6 +1509,9 @@ public: /// addAttribute - adds the attribute to the list of attributes. void addAttribute(unsigned i, Attribute::AttrKind attr); + /// addAttribute - adds the attribute to the list of attributes. + void addAttribute(unsigned i, StringRef Kind, StringRef Value); + /// removeAttribute - removes the attribute from the list of attributes. void removeAttribute(unsigned i, Attribute attr); @@ -1495,6 +1529,11 @@ public: return hasFnAttrImpl(A); } + /// \brief Determine whether this call has the given attribute. + bool hasFnAttr(StringRef A) const { + return hasFnAttrImpl(A); + } + /// \brief Determine whether the call or the callee has the given attributes. bool paramHasAttr(unsigned i, Attribute::AttrKind A) const; @@ -1621,7 +1660,14 @@ public: } private: - bool hasFnAttrImpl(Attribute::AttrKind A) const; + template<typename AttrKind> + bool hasFnAttrImpl(AttrKind A) const { + if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A)) + return true; + if (const Function *F = getCalledFunction()) + return F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, A); + return false; + } // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -1687,7 +1733,10 @@ class SelectInst : public Instruction { setName(NameStr); } protected: - SelectInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + SelectInst *cloneImpl() const; + public: static SelectInst *Create(Value *C, Value *S1, Value *S2, const Twine &NameStr = "", @@ -1742,7 +1791,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectInst, Value) /// class VAArgInst : public UnaryInstruction { protected: - VAArgInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + VAArgInst *cloneImpl() const; public: VAArgInst(Value *List, Type *Ty, const Twine &NameStr = "", @@ -1782,7 +1833,9 @@ class ExtractElementInst : public Instruction { ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); protected: - ExtractElementInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + ExtractElementInst *cloneImpl() const; public: static ExtractElementInst *Create(Value *Vec, Value *Idx, @@ -1843,7 +1896,9 @@ class InsertElementInst : public Instruction { InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); protected: - InsertElementInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + InsertElementInst *cloneImpl() const; public: static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx, @@ -1896,7 +1951,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value) /// class ShuffleVectorInst : public Instruction { protected: - ShuffleVectorInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + ShuffleVectorInst *cloneImpl() const; public: // allocate space for exactly three operands @@ -1997,7 +2054,9 @@ class ExtractValueInst : public UnaryInstruction { return User::operator new(s, 1); } protected: - ExtractValueInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + ExtractValueInst *cloneImpl() const; public: static ExtractValueInst *Create(Value *Agg, @@ -2111,7 +2170,10 @@ class InsertValueInst : public Instruction { InsertValueInst(Value *Agg, Value *Val, unsigned Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); protected: - InsertValueInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + InsertValueInst *cloneImpl() const; + public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -2252,7 +2314,10 @@ protected: User::allocHungoffUses(N, /* IsPhi */ true); } - PHINode *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + PHINode *cloneImpl() const; + public: /// Constructors - NumReservedValues is a hint for the number of incoming /// edges that this phi node will have (use 0 if you really have no idea). @@ -2445,7 +2510,10 @@ private: const Twine &NameStr, BasicBlock *InsertAtEnd); protected: - LandingPadInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + LandingPadInst *cloneImpl() const; + public: /// Constructors - NumReservedClauses is a hint for the number of incoming /// clauses that this landingpad will have (use 0 if you really have no idea). @@ -2538,7 +2606,10 @@ private: ReturnInst(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd); explicit ReturnInst(LLVMContext &C, BasicBlock *InsertAtEnd); protected: - ReturnInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + ReturnInst *cloneImpl() const; + public: static ReturnInst* Create(LLVMContext &C, Value *retVal = nullptr, Instruction *InsertBefore = nullptr) { @@ -2610,7 +2681,10 @@ class BranchInst : public TerminatorInst { BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BasicBlock *InsertAtEnd); protected: - BranchInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + BranchInst *cloneImpl() const; + public: static BranchInst *Create(BasicBlock *IfTrue, Instruction *InsertBefore = nullptr) { @@ -2717,7 +2791,10 @@ class SwitchInst : public TerminatorInst { SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd); protected: - SwitchInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + SwitchInst *cloneImpl() const; + public: // -2 @@ -3022,7 +3099,10 @@ class IndirectBrInst : public TerminatorInst { /// autoinserts at the end of the specified BasicBlock. IndirectBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd); protected: - IndirectBrInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + IndirectBrInst *cloneImpl() const; + public: static IndirectBrInst *Create(Value *Address, unsigned NumDests, Instruction *InsertBefore = nullptr) { @@ -3129,7 +3209,10 @@ class InvokeInst : public TerminatorInst { ArrayRef<Value *> Args, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd); protected: - InvokeInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + InvokeInst *cloneImpl() const; + public: static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, @@ -3424,7 +3507,10 @@ class ResumeInst : public TerminatorInst { explicit ResumeInst(Value *Exn, Instruction *InsertBefore=nullptr); ResumeInst(Value *Exn, BasicBlock *InsertAtEnd); protected: - ResumeInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + ResumeInst *cloneImpl() const; + public: static ResumeInst *Create(Value *Exn, Instruction *InsertBefore = nullptr) { return new(1) ResumeInst(Exn, InsertBefore); @@ -3473,7 +3559,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value) class UnreachableInst : public TerminatorInst { void *operator new(size_t, unsigned) = delete; protected: - UnreachableInst *clone_impl() const override; + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + UnreachableInst *cloneImpl() const; public: // allocate space for exactly zero operands @@ -3505,8 +3593,10 @@ private: /// \brief This class represents a truncation of integer types. class TruncInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical TruncInst - TruncInst *clone_impl() const override; + TruncInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3541,8 +3631,10 @@ public: /// \brief This class represents zero extension of integer types. class ZExtInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical ZExtInst - ZExtInst *clone_impl() const override; + ZExtInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3577,8 +3669,10 @@ public: /// \brief This class represents a sign extension of integer types. class SExtInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical SExtInst - SExtInst *clone_impl() const override; + SExtInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3613,8 +3707,10 @@ public: /// \brief This class represents a truncation of floating point types. class FPTruncInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical FPTruncInst - FPTruncInst *clone_impl() const override; + FPTruncInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3649,8 +3745,10 @@ public: /// \brief This class represents an extension of floating point types. class FPExtInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical FPExtInst - FPExtInst *clone_impl() const override; + FPExtInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3685,8 +3783,10 @@ public: /// \brief This class represents a cast unsigned integer to floating point. class UIToFPInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical UIToFPInst - UIToFPInst *clone_impl() const override; + UIToFPInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3721,8 +3821,10 @@ public: /// \brief This class represents a cast from signed integer to floating point. class SIToFPInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical SIToFPInst - SIToFPInst *clone_impl() const override; + SIToFPInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3757,8 +3859,10 @@ public: /// \brief This class represents a cast from floating point to unsigned integer class FPToUIInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical FPToUIInst - FPToUIInst *clone_impl() const override; + FPToUIInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3793,8 +3897,10 @@ public: /// \brief This class represents a cast from floating point to signed integer. class FPToSIInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical FPToSIInst - FPToSIInst *clone_impl() const override; + FPToSIInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3845,8 +3951,10 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical IntToPtrInst - IntToPtrInst *clone_impl() const override; + IntToPtrInst *cloneImpl() const; /// \brief Returns the address space of this instruction's pointer type. unsigned getAddressSpace() const { @@ -3869,8 +3977,10 @@ public: /// \brief This class represents a cast from a pointer to an integer class PtrToIntInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical PtrToIntInst - PtrToIntInst *clone_impl() const override; + PtrToIntInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3917,8 +4027,10 @@ public: /// \brief This class represents a no-op cast from one type to another. class BitCastInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical BitCastInst - BitCastInst *clone_impl() const override; + BitCastInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3954,8 +4066,10 @@ public: /// one address space to another. class AddrSpaceCastInst : public CastInst { protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; /// \brief Clone an identical AddrSpaceCastInst - AddrSpaceCastInst *clone_impl() const override; + AddrSpaceCastInst *cloneImpl() const; public: /// \brief Constructor with insert-before-instruction semantics @@ -3983,6 +4097,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h index 102cbef3b680..2c8b6eb6f39a 100644 --- a/include/llvm/IR/IntrinsicInst.h +++ b/include/llvm/IR/IntrinsicInst.h @@ -372,6 +372,6 @@ namespace llvm { return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); } }; -} // namespace llvm +} #endif diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h index 01781d51bec1..43b8325107fa 100644 --- a/include/llvm/IR/Intrinsics.h +++ b/include/llvm/IR/Intrinsics.h @@ -126,8 +126,8 @@ namespace Intrinsic { /// of IITDescriptors. void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T); -} // namespace Intrinsic +} // End Intrinsic namespace -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td index ce758e257312..1dff80878592 100644 --- a/include/llvm/IR/IntrinsicsARM.td +++ b/include/llvm/IR/IntrinsicsARM.td @@ -83,11 +83,9 @@ def int_arm_vcvtru : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty], // Move to coprocessor def int_arm_mcr : GCCBuiltin<"__builtin_arm_mcr">, - MSBuiltin<"_MoveToCoprocessor">, Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; def int_arm_mcr2 : GCCBuiltin<"__builtin_arm_mcr2">, - MSBuiltin<"_MoveToCoprocessor2">, Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td index d680085eaf32..05adc5a757be 100644 --- a/include/llvm/IR/IntrinsicsPowerPC.td +++ b/include/llvm/IR/IntrinsicsPowerPC.td @@ -687,6 +687,32 @@ def int_ppc_vsx_xsmindp : PowerPC_VSX_Sca_DDD_Intrinsic<"xsmindp">; // Vector divide. def int_ppc_vsx_xvdivdp : PowerPC_VSX_Vec_DDD_Intrinsic<"xvdivdp">; def int_ppc_vsx_xvdivsp : PowerPC_VSX_Vec_FFF_Intrinsic<"xvdivsp">; + +// Vector round-to-infinity (ceil) +def int_ppc_vsx_xvrspip : + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xvrdpip : + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; + +// Vector compare +def int_ppc_vsx_xvcmpeqdp : + PowerPC_VSX_Intrinsic<"xvcmpeqdp", [llvm_v2i64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpeqsp : + PowerPC_VSX_Intrinsic<"xvcmpeqsp", [llvm_v4i32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpgedp : + PowerPC_VSX_Intrinsic<"xvcmpgedp", [llvm_v2i64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpgesp : + PowerPC_VSX_Intrinsic<"xvcmpgesp", [llvm_v4i32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpgtdp : + PowerPC_VSX_Intrinsic<"xvcmpgtdp", [llvm_v2i64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; +def int_ppc_vsx_xvcmpgtsp : + PowerPC_VSX_Intrinsic<"xvcmpgtsp", [llvm_v4i32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; } //===----------------------------------------------------------------------===// diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td index 1bed31c842bb..b90825db93cd 100644 --- a/include/llvm/IR/IntrinsicsX86.td +++ b/include/llvm/IR/IntrinsicsX86.td @@ -21,9 +21,17 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // SEH intrinsics for Windows let TargetPrefix = "x86" in { def int_x86_seh_lsda : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], [IntrNoMem]>; - def int_x86_seh_exceptioninfo : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty, llvm_ptr_ty], - [IntrReadMem]>; + + // Restores the frame, base, and stack pointers as necessary after recovering + // from an exception. Any block resuming control flow in the parent function + // should call this before accessing any stack memory. + def int_x86_seh_restoreframe : Intrinsic<[], [], []>; + + // Given a pointer to the end of an EH registration object, returns the true + // parent frame address that can be used with llvm.framerecover. + def int_x86_seh_recoverfp : Intrinsic<[llvm_ptr_ty], + [llvm_ptr_ty, llvm_ptr_ty], + [IntrNoMem]>; } //===----------------------------------------------------------------------===// @@ -1132,28 +1140,292 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpermt_d_512: + def int_x86_avx512_mask_vpermi2var_d_128 : + GCCBuiltin<"__builtin_ia32_vpermi2vard128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_d_256 : + GCCBuiltin<"__builtin_ia32_vpermi2vard256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_d_512 : + GCCBuiltin<"__builtin_ia32_vpermi2vard512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_hi_128 : + GCCBuiltin<"__builtin_ia32_vpermi2varhi128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_hi_256 : + GCCBuiltin<"__builtin_ia32_vpermi2varhi256_mask">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_hi_512 : + GCCBuiltin<"__builtin_ia32_vpermi2varhi512_mask">, + Intrinsic<[llvm_v32i16_ty], + [llvm_v32i16_ty, llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_pd_128 : + GCCBuiltin<"__builtin_ia32_vpermi2varpd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_pd_256 : + GCCBuiltin<"__builtin_ia32_vpermi2varpd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_pd_512 : + GCCBuiltin<"__builtin_ia32_vpermi2varpd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8i64_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_ps_128 : + GCCBuiltin<"__builtin_ia32_vpermi2varps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_ps_256 : + GCCBuiltin<"__builtin_ia32_vpermi2varps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_ps_512 : + GCCBuiltin<"__builtin_ia32_vpermi2varps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16i32_ty, llvm_v16f32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_q_128 : + GCCBuiltin<"__builtin_ia32_vpermi2varq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_q_256 : + GCCBuiltin<"__builtin_ia32_vpermi2varq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermi2var_q_512 : + GCCBuiltin<"__builtin_ia32_vpermi2varq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermt2var_d_512: GCCBuiltin<"__builtin_ia32_vpermt2vard512_mask">, Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpermt_q_512: + def int_x86_avx512_mask_vpermt2var_q_512: GCCBuiltin<"__builtin_ia32_vpermt2varq512_mask">, Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpermt_ps_512: + def int_x86_avx512_mask_vpermt2var_ps_512: GCCBuiltin<"__builtin_ia32_vpermt2varps512_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpermt_pd_512: + def int_x86_avx512_mask_vpermt2var_pd_512: GCCBuiltin<"__builtin_ia32_vpermt2varpd512_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_v8i64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_vpermt2var_d_128 : + GCCBuiltin<"__builtin_ia32_vpermt2vard128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_d_128 : + GCCBuiltin<"__builtin_ia32_vpermt2vard128_maskz">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermt2var_d_256 : + GCCBuiltin<"__builtin_ia32_vpermt2vard256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_d_256 : + GCCBuiltin<"__builtin_ia32_vpermt2vard256_maskz">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_d_512 : + GCCBuiltin<"__builtin_ia32_vpermt2vard512_maskz">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermt2var_hi_128 : + GCCBuiltin<"__builtin_ia32_vpermt2varhi128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_hi_128 : + GCCBuiltin<"__builtin_ia32_vpermt2varhi128_maskz">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermt2var_hi_256 : + GCCBuiltin<"__builtin_ia32_vpermt2varhi256_mask">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_hi_256 : + GCCBuiltin<"__builtin_ia32_vpermt2varhi256_maskz">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermt2var_hi_512 : + GCCBuiltin<"__builtin_ia32_vpermt2varhi512_mask">, + Intrinsic<[llvm_v32i16_ty], + [llvm_v32i16_ty, llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_hi_512 : + GCCBuiltin<"__builtin_ia32_vpermt2varhi512_maskz">, + Intrinsic<[llvm_v32i16_ty], + [llvm_v32i16_ty, llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermt2var_pd_128 : + GCCBuiltin<"__builtin_ia32_vpermt2varpd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2i64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_pd_128 : + GCCBuiltin<"__builtin_ia32_vpermt2varpd128_maskz">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2i64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermt2var_pd_256 : + GCCBuiltin<"__builtin_ia32_vpermt2varpd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4i64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_pd_256 : + GCCBuiltin<"__builtin_ia32_vpermt2varpd256_maskz">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4i64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_pd_512 : + GCCBuiltin<"__builtin_ia32_vpermt2varpd512_maskz">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8i64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermt2var_ps_128 : + GCCBuiltin<"__builtin_ia32_vpermt2varps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4i32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_ps_128 : + GCCBuiltin<"__builtin_ia32_vpermt2varps128_maskz">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4i32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermt2var_ps_256 : + GCCBuiltin<"__builtin_ia32_vpermt2varps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8i32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_ps_256 : + GCCBuiltin<"__builtin_ia32_vpermt2varps256_maskz">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8i32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_ps_512 : + GCCBuiltin<"__builtin_ia32_vpermt2varps512_maskz">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16i32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermt2var_q_128 : + GCCBuiltin<"__builtin_ia32_vpermt2varq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_q_128 : + GCCBuiltin<"__builtin_ia32_vpermt2varq128_maskz">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vpermt2var_q_256 : + GCCBuiltin<"__builtin_ia32_vpermt2varq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_q_256 : + GCCBuiltin<"__builtin_ia32_vpermt2varq256_maskz">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vpermt2var_q_512 : + GCCBuiltin<"__builtin_ia32_vpermt2varq512_maskz">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pshuf_b_128 : + GCCBuiltin<"__builtin_ia32_pshufb128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pshuf_b_256 : + GCCBuiltin<"__builtin_ia32_pshufb256_mask">, + Intrinsic<[llvm_v32i8_ty], + [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pshuf_b_512 : + GCCBuiltin<"__builtin_ia32_pshufb512_mask">, + Intrinsic<[llvm_v64i8_ty], + [llvm_v64i8_ty, llvm_v64i8_ty, llvm_v64i8_ty, llvm_i64_ty], + [IntrNoMem]>; } + // Vector blend let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx_blendv_pd_256 : GCCBuiltin<"__builtin_ia32_blendvpd256">, @@ -1718,12 +1990,78 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty], [IntrNoMem]>; def int_x86_avx2_pabs_d : GCCBuiltin<"__builtin_ia32_pabsd256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_pabs_d_512 : GCCBuiltin<"__builtin_ia32_pabsd512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_pabs_q_512 : GCCBuiltin<"__builtin_ia32_pabsq512_mask">, - Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, - llvm_i8_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_pabs_b_128 : + GCCBuiltin<"__builtin_ia32_pabsb128_mask">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pabs_b_256 : + GCCBuiltin<"__builtin_ia32_pabsb256_mask">, + Intrinsic<[llvm_v32i8_ty], + [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pabs_b_512 : + GCCBuiltin<"__builtin_ia32_pabsb512_mask">, + Intrinsic<[llvm_v64i8_ty], + [llvm_v64i8_ty, llvm_v64i8_ty, llvm_i64_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pabs_d_128 : + GCCBuiltin<"__builtin_ia32_pabsd128_mask">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pabs_d_256 : + GCCBuiltin<"__builtin_ia32_pabsd256_mask">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pabs_d_512 : + GCCBuiltin<"__builtin_ia32_pabsd512_mask">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pabs_q_128 : + GCCBuiltin<"__builtin_ia32_pabsq128_mask">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pabs_q_256 : + GCCBuiltin<"__builtin_ia32_pabsq256_mask">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pabs_q_512 : + GCCBuiltin<"__builtin_ia32_pabsq512_mask">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pabs_w_128 : + GCCBuiltin<"__builtin_ia32_pabsw128_mask">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pabs_w_256 : + GCCBuiltin<"__builtin_ia32_pabsw256_mask">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i16_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_pabs_w_512 : + GCCBuiltin<"__builtin_ia32_pabsw512_mask">, + Intrinsic<[llvm_v32i16_ty], + [llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty], + [IntrNoMem]>; } // Horizontal arithmetic ops @@ -2120,36 +2458,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; - def int_x86_fma_mask_vfmadd_ps_512 : GCCBuiltin<"__builtin_ia32_vfmaddps512_mask">, - Intrinsic<[llvm_v16f32_ty], - [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i16_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmadd_ps_256 : GCCBuiltin<"__builtin_ia32_vfmaddps256_mask">, - Intrinsic<[llvm_v8f32_ty], - [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmadd_ps_128 : GCCBuiltin<"__builtin_ia32_vfmaddps128_mask">, - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmadd_pd_512 : GCCBuiltin<"__builtin_ia32_vfmaddpd512_mask">, - Intrinsic<[llvm_v8f64_ty], - [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmadd_pd_256 : GCCBuiltin<"__builtin_ia32_vfmaddpd256_mask">, - Intrinsic<[llvm_v4f64_ty], - [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmadd_pd_128 : GCCBuiltin<"__builtin_ia32_vfmaddpd128_mask">, - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, - llvm_i8_ty], - [IntrNoMem]>; + def int_x86_fma_vfmsub_ss : GCCBuiltin<"__builtin_ia32_vfmsubss">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], @@ -2174,36 +2483,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; - def int_x86_fma_mask_vfmsub_ps_512 : GCCBuiltin<"__builtin_ia32_vfmsubps512_mask">, - Intrinsic<[llvm_v16f32_ty], - [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i16_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmsub_ps_256 : GCCBuiltin<"__builtin_ia32_vfmsubps256_mask">, - Intrinsic<[llvm_v8f32_ty], - [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmsub_ps_128 : GCCBuiltin<"__builtin_ia32_vfmsubps128_mask">, - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmsub_pd_512 : GCCBuiltin<"__builtin_ia32_vfmsubpd512_mask">, - Intrinsic<[llvm_v8f64_ty], - [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmsub_pd_256 : GCCBuiltin<"__builtin_ia32_vfmsubpd256_mask">, - Intrinsic<[llvm_v4f64_ty], - [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmsub_pd_128 : GCCBuiltin<"__builtin_ia32_vfmsubpd128_mask">, - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, - llvm_i8_ty], - [IntrNoMem]>; def int_x86_fma_vfnmadd_ss : GCCBuiltin<"__builtin_ia32_vfnmaddss">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], @@ -2228,36 +2507,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; - def int_x86_fma_mask_vfnmadd_ps_512 : GCCBuiltin<"__builtin_ia32_vfnmaddps512_mask">, - Intrinsic<[llvm_v16f32_ty], - [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i16_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfnmadd_ps_256 : GCCBuiltin<"__builtin_ia32_vfnmaddps256_mask">, - Intrinsic<[llvm_v8f32_ty], - [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfnmadd_ps_128 : GCCBuiltin<"__builtin_ia32_vfnmaddps128_mask">, - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfnmadd_pd_512 : GCCBuiltin<"__builtin_ia32_vfnmaddpd512_mask">, - Intrinsic<[llvm_v8f64_ty], - [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfnmadd_pd_256 : GCCBuiltin<"__builtin_ia32_vfnmaddpd256_mask">, - Intrinsic<[llvm_v4f64_ty], - [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfnmadd_pd_128 : GCCBuiltin<"__builtin_ia32_vfnmaddpd128_mask">, - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, - llvm_i8_ty], - [IntrNoMem]>; def int_x86_fma_vfnmsub_ss : GCCBuiltin<"__builtin_ia32_vfnmsubss">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], @@ -2282,36 +2531,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; - def int_x86_fma_mask_vfnmsub_ps_512 : GCCBuiltin<"__builtin_ia32_vfnmsubps512_mask">, - Intrinsic<[llvm_v16f32_ty], - [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i16_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfnmsub_ps_256 : GCCBuiltin<"__builtin_ia32_vfnmsubps256_mask">, - Intrinsic<[llvm_v8f32_ty], - [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfnmsub_ps_128 : GCCBuiltin<"__builtin_ia32_vfnmsubps128_mask">, - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfnmsub_pd_512 : GCCBuiltin<"__builtin_ia32_vfnmsubpd512_mask">, - Intrinsic<[llvm_v8f64_ty], - [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfnmsub_pd_256 : GCCBuiltin<"__builtin_ia32_vfnmsubpd256_mask">, - Intrinsic<[llvm_v4f64_ty], - [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfnmsub_pd_128 : GCCBuiltin<"__builtin_ia32_vfnmsubpd128_mask">, - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, - llvm_i8_ty], - [IntrNoMem]>; def int_x86_fma_vfmaddsub_ps : GCCBuiltin<"__builtin_ia32_vfmaddsubps">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], @@ -2330,36 +2549,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; - def int_x86_fma_mask_vfmaddsub_ps_512 : GCCBuiltin<"__builtin_ia32_vfmaddsubps512_mask">, - Intrinsic<[llvm_v16f32_ty], - [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i16_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmaddsub_ps_256 : GCCBuiltin<"__builtin_ia32_vfmaddsubps256_mask">, - Intrinsic<[llvm_v8f32_ty], - [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmaddsub_ps_128 : GCCBuiltin<"__builtin_ia32_vfmaddsubps128_mask">, - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmaddsub_pd_512 : GCCBuiltin<"__builtin_ia32_vfmaddsubpd512_mask">, - Intrinsic<[llvm_v8f64_ty], - [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmaddsub_pd_256 : GCCBuiltin<"__builtin_ia32_vfmaddsubpd256_mask">, - Intrinsic<[llvm_v4f64_ty], - [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmaddsub_pd_128 : GCCBuiltin<"__builtin_ia32_vfmaddsubpd128_mask">, - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, - llvm_i8_ty], - [IntrNoMem]>; def int_x86_fma_vfmsubadd_ps : GCCBuiltin<"__builtin_ia32_vfmsubaddps">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], @@ -2378,36 +2567,403 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; - def int_x86_fma_mask_vfmsubadd_ps_512 : GCCBuiltin<"__builtin_ia32_vfmsubaddps512_mask">, - Intrinsic<[llvm_v16f32_ty], - [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, - llvm_i16_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmsubadd_ps_256 : GCCBuiltin<"__builtin_ia32_vfmsubaddps256_mask">, - Intrinsic<[llvm_v8f32_ty], - [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmsubadd_ps_128 : GCCBuiltin<"__builtin_ia32_vfmsubaddps128_mask">, - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmsubadd_pd_512 : GCCBuiltin<"__builtin_ia32_vfmsubaddpd512_mask">, - Intrinsic<[llvm_v8f64_ty], - [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, - llvm_i8_ty, llvm_i32_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmsubadd_pd_256 : GCCBuiltin<"__builtin_ia32_vfmsubaddpd256_mask">, - Intrinsic<[llvm_v4f64_ty], - [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, - llvm_i8_ty], - [IntrNoMem]>; - def int_x86_fma_mask_vfmsubadd_pd_128 : GCCBuiltin<"__builtin_ia32_vfmsubaddpd128_mask">, - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, - llvm_i8_ty], - [IntrNoMem]>; + + def int_x86_avx512_mask_vfmadd_pd_128 : + GCCBuiltin<"__builtin_ia32_vfmaddpd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmadd_pd_128 : + GCCBuiltin<"__builtin_ia32_vfmaddpd128_mask3">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vfmadd_pd_128 : + GCCBuiltin<"__builtin_ia32_vfmaddpd128_maskz">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfmadd_pd_256 : + GCCBuiltin<"__builtin_ia32_vfmaddpd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmadd_pd_256 : + GCCBuiltin<"__builtin_ia32_vfmaddpd256_mask3">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vfmadd_pd_256 : + GCCBuiltin<"__builtin_ia32_vfmaddpd256_maskz">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfmadd_pd_512 : + GCCBuiltin<"__builtin_ia32_vfmaddpd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmadd_pd_512 : + GCCBuiltin<"__builtin_ia32_vfmaddpd512_mask3">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_maskz_vfmadd_pd_512 : + GCCBuiltin<"__builtin_ia32_vfmaddpd512_maskz">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_vfmadd_ps_128 : + GCCBuiltin<"__builtin_ia32_vfmaddps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmadd_ps_128 : + GCCBuiltin<"__builtin_ia32_vfmaddps128_mask3">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vfmadd_ps_128 : + GCCBuiltin<"__builtin_ia32_vfmaddps128_maskz">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfmadd_ps_256 : + GCCBuiltin<"__builtin_ia32_vfmaddps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmadd_ps_256 : + GCCBuiltin<"__builtin_ia32_vfmaddps256_mask3">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vfmadd_ps_256 : + GCCBuiltin<"__builtin_ia32_vfmaddps256_maskz">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfmadd_ps_512 : + GCCBuiltin<"__builtin_ia32_vfmaddps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmadd_ps_512 : + GCCBuiltin<"__builtin_ia32_vfmaddps512_mask3">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_maskz_vfmadd_ps_512 : + GCCBuiltin<"__builtin_ia32_vfmaddps512_maskz">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_vfmaddsub_pd_128 : + GCCBuiltin<"__builtin_ia32_vfmaddsubpd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmaddsub_pd_128 : + GCCBuiltin<"__builtin_ia32_vfmaddsubpd128_mask3">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vfmaddsub_pd_128 : + GCCBuiltin<"__builtin_ia32_vfmaddsubpd128_maskz">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfmaddsub_pd_256 : + GCCBuiltin<"__builtin_ia32_vfmaddsubpd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmaddsub_pd_256 : + GCCBuiltin<"__builtin_ia32_vfmaddsubpd256_mask3">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vfmaddsub_pd_256 : + GCCBuiltin<"__builtin_ia32_vfmaddsubpd256_maskz">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfmaddsub_pd_512 : + GCCBuiltin<"__builtin_ia32_vfmaddsubpd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmaddsub_pd_512 : + GCCBuiltin<"__builtin_ia32_vfmaddsubpd512_mask3">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_maskz_vfmaddsub_pd_512 : + GCCBuiltin<"__builtin_ia32_vfmaddsubpd512_maskz">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_vfmaddsub_ps_128 : + GCCBuiltin<"__builtin_ia32_vfmaddsubps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmaddsub_ps_128 : + GCCBuiltin<"__builtin_ia32_vfmaddsubps128_mask3">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vfmaddsub_ps_128 : + GCCBuiltin<"__builtin_ia32_vfmaddsubps128_maskz">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfmaddsub_ps_256 : + GCCBuiltin<"__builtin_ia32_vfmaddsubps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmaddsub_ps_256 : + GCCBuiltin<"__builtin_ia32_vfmaddsubps256_mask3">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_maskz_vfmaddsub_ps_256 : + GCCBuiltin<"__builtin_ia32_vfmaddsubps256_maskz">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfmaddsub_ps_512 : + GCCBuiltin<"__builtin_ia32_vfmaddsubps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmaddsub_ps_512 : + GCCBuiltin<"__builtin_ia32_vfmaddsubps512_mask3">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_maskz_vfmaddsub_ps_512 : + GCCBuiltin<"__builtin_ia32_vfmaddsubps512_maskz">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmsub_pd_128 : + GCCBuiltin<"__builtin_ia32_vfmsubpd128_mask3">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmsub_pd_256 : + GCCBuiltin<"__builtin_ia32_vfmsubpd256_mask3">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmsub_pd_512 : + GCCBuiltin<"__builtin_ia32_vfmsubpd512_mask3">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmsub_ps_128 : + GCCBuiltin<"__builtin_ia32_vfmsubps128_mask3">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmsub_ps_256 : + GCCBuiltin<"__builtin_ia32_vfmsubps256_mask3">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmsub_ps_512 : + GCCBuiltin<"__builtin_ia32_vfmsubps512_mask3">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmsubadd_pd_128 : + GCCBuiltin<"__builtin_ia32_vfmsubaddpd128_mask3">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmsubadd_pd_256 : + GCCBuiltin<"__builtin_ia32_vfmsubaddpd256_mask3">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmsubadd_pd_512 : + GCCBuiltin<"__builtin_ia32_vfmsubaddpd512_mask3">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmsubadd_ps_128 : + GCCBuiltin<"__builtin_ia32_vfmsubaddps128_mask3">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmsubadd_ps_256 : + GCCBuiltin<"__builtin_ia32_vfmsubaddps256_mask3">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfmsubadd_ps_512 : + GCCBuiltin<"__builtin_ia32_vfmsubaddps512_mask3">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_vfnmadd_pd_128 : + GCCBuiltin<"__builtin_ia32_vfnmaddpd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfnmadd_pd_256 : + GCCBuiltin<"__builtin_ia32_vfnmaddpd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfnmadd_pd_512 : + GCCBuiltin<"__builtin_ia32_vfnmaddpd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_vfnmadd_ps_128 : + GCCBuiltin<"__builtin_ia32_vfnmaddps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfnmadd_ps_256 : + GCCBuiltin<"__builtin_ia32_vfnmaddps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfnmadd_ps_512 : + GCCBuiltin<"__builtin_ia32_vfnmaddps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_vfnmsub_pd_128 : + GCCBuiltin<"__builtin_ia32_vfnmsubpd128_mask">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfnmsub_pd_128 : + GCCBuiltin<"__builtin_ia32_vfnmsubpd128_mask3">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfnmsub_pd_256 : + GCCBuiltin<"__builtin_ia32_vfnmsubpd256_mask">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfnmsub_pd_256 : + GCCBuiltin<"__builtin_ia32_vfnmsubpd256_mask3">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfnmsub_pd_512 : + GCCBuiltin<"__builtin_ia32_vfnmsubpd512_mask">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask3_vfnmsub_pd_512 : + GCCBuiltin<"__builtin_ia32_vfnmsubpd512_mask3">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_vfnmsub_ps_128 : + GCCBuiltin<"__builtin_ia32_vfnmsubps128_mask">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfnmsub_ps_128 : + GCCBuiltin<"__builtin_ia32_vfnmsubps128_mask3">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfnmsub_ps_256 : + GCCBuiltin<"__builtin_ia32_vfnmsubps256_mask">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask3_vfnmsub_ps_256 : + GCCBuiltin<"__builtin_ia32_vfnmsubps256_mask3">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfnmsub_ps_512 : + GCCBuiltin<"__builtin_ia32_vfnmsubps512_mask">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, + llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask3_vfnmsub_ps_512 : + GCCBuiltin<"__builtin_ia32_vfnmsubps512_mask3">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, + llvm_i32_ty], [IntrNoMem]>; + } //===----------------------------------------------------------------------===// @@ -2967,6 +3523,19 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". } //===----------------------------------------------------------------------===// +// FXSR +let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". + def int_x86_fxrstor : GCCBuiltin<"__builtin_ia32_fxrstor">, + Intrinsic<[], [llvm_ptr_ty], []>; + def int_x86_fxrstor64 : GCCBuiltin<"__builtin_ia32_fxrstor64">, + Intrinsic<[], [llvm_ptr_ty], []>; + def int_x86_fxsave : GCCBuiltin<"__builtin_ia32_fxsave">, + Intrinsic<[], [llvm_ptr_ty], []>; + def int_x86_fxsave64 : GCCBuiltin<"__builtin_ia32_fxsave64">, + Intrinsic<[], [llvm_ptr_ty], []>; +} + +//===----------------------------------------------------------------------===// // Half float conversion let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". @@ -3501,6 +4070,26 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + + def int_x86_avx512_mask_scalef_pd_128 : GCCBuiltin<"__builtin_ia32_scalefpd128_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, + llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_scalef_pd_256 : GCCBuiltin<"__builtin_ia32_scalefpd256_mask">, + Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, + llvm_v4f64_ty, llvm_i8_ty],[IntrNoMem]>; + def int_x86_avx512_mask_scalef_pd_512 : GCCBuiltin<"__builtin_ia32_scalefpd512_mask">, + Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, + llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_scalef_ps_128 : GCCBuiltin<"__builtin_ia32_scalefps128_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, + llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_scalef_ps_256 : GCCBuiltin<"__builtin_ia32_scalefps256_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, + llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_scalef_ps_512 : GCCBuiltin<"__builtin_ia32_scalefps512_mask">, + Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, + llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_sqrt_ss : GCCBuiltin<"__builtin_ia32_sqrtrndss">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; @@ -3934,6 +4523,102 @@ let TargetPrefix = "x86" in { llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], [IntrReadArgMem]>; + def int_x86_avx512_gather3div2_df : + GCCBuiltin<"__builtin_ia32_gather3div2df">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3div2_di : + GCCBuiltin<"__builtin_ia32_gather3div2di">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3div4_df : + GCCBuiltin<"__builtin_ia32_gather3div4df">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3div4_di : + GCCBuiltin<"__builtin_ia32_gather3div4di">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3div4_sf : + GCCBuiltin<"__builtin_ia32_gather3div4sf">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3div4_si : + GCCBuiltin<"__builtin_ia32_gather3div4si">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3div8_sf : + GCCBuiltin<"__builtin_ia32_gather3div8sf">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3div8_si : + GCCBuiltin<"__builtin_ia32_gather3div8si">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3siv2_df : + GCCBuiltin<"__builtin_ia32_gather3siv2df">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3siv2_di : + GCCBuiltin<"__builtin_ia32_gather3siv2di">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3siv4_df : + GCCBuiltin<"__builtin_ia32_gather3siv4df">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3siv4_di : + GCCBuiltin<"__builtin_ia32_gather3siv4di">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3siv4_sf : + GCCBuiltin<"__builtin_ia32_gather3siv4sf">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3siv4_si : + GCCBuiltin<"__builtin_ia32_gather3siv4si">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3siv8_sf : + GCCBuiltin<"__builtin_ia32_gather3siv8sf">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + + def int_x86_avx512_gather3siv8_si : + GCCBuiltin<"__builtin_ia32_gather3siv8si">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], + [IntrReadArgMem]>; + // scatter def int_x86_avx512_scatter_dpd_512 : GCCBuiltin<"__builtin_ia32_scattersiv8df">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, @@ -3970,6 +4655,102 @@ let TargetPrefix = "x86" in { llvm_i32_ty], [IntrReadWriteArgMem]>; + def int_x86_avx512_scatterdiv2_df : + GCCBuiltin<"__builtin_ia32_scatterdiv2df">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scatterdiv2_di : + GCCBuiltin<"__builtin_ia32_scatterdiv2di">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scatterdiv4_df : + GCCBuiltin<"__builtin_ia32_scatterdiv4df">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scatterdiv4_di : + GCCBuiltin<"__builtin_ia32_scatterdiv4di">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scatterdiv4_sf : + GCCBuiltin<"__builtin_ia32_scatterdiv4sf">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scatterdiv4_si : + GCCBuiltin<"__builtin_ia32_scatterdiv4si">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scatterdiv8_sf : + GCCBuiltin<"__builtin_ia32_scatterdiv8sf">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scatterdiv8_si : + GCCBuiltin<"__builtin_ia32_scatterdiv8si">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scattersiv2_df : + GCCBuiltin<"__builtin_ia32_scattersiv2df">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scattersiv2_di : + GCCBuiltin<"__builtin_ia32_scattersiv2di">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scattersiv4_df : + GCCBuiltin<"__builtin_ia32_scattersiv4df">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scattersiv4_di : + GCCBuiltin<"__builtin_ia32_scattersiv4di">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scattersiv4_sf : + GCCBuiltin<"__builtin_ia32_scattersiv4sf">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scattersiv4_si : + GCCBuiltin<"__builtin_ia32_scattersiv4si">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scattersiv8_sf : + GCCBuiltin<"__builtin_ia32_scattersiv8sf">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + + def int_x86_avx512_scattersiv8_si : + GCCBuiltin<"__builtin_ia32_scattersiv8si">, + Intrinsic<[], + [llvm_ptr_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], + [IntrReadWriteArgMem]>; + // gather prefetch def int_x86_avx512_gatherpf_dpd_512 : GCCBuiltin<"__builtin_ia32_gatherpfdpd">, Intrinsic<[], [llvm_i8_ty, llvm_v8i32_ty, llvm_ptr_ty, diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h index 53c8b3a3fdeb..e6c22090ab6d 100644 --- a/include/llvm/IR/LLVMContext.h +++ b/include/llvm/IR/LLVMContext.h @@ -209,6 +209,6 @@ inline LLVMContextRef *wrap(const LLVMContext **Tys) { return reinterpret_cast<LLVMContextRef*>(const_cast<LLVMContext**>(Tys)); } -} // namespace llvm +} #endif diff --git a/include/llvm/IR/LegacyPassManager.h b/include/llvm/IR/LegacyPassManager.h index 7c678fb321f9..5257a0eed488 100644 --- a/include/llvm/IR/LegacyPassManager.h +++ b/include/llvm/IR/LegacyPassManager.h @@ -93,11 +93,11 @@ private: Module *M; }; -} // namespace legacy +} // End legacy namespace // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_STDCXX_CONVERSION_FUNCTIONS(legacy::PassManagerBase, LLVMPassManagerRef) -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/LegacyPassManagers.h b/include/llvm/IR/LegacyPassManagers.h index e2f1ab48b725..7f7889ad5fb3 100644 --- a/include/llvm/IR/LegacyPassManagers.h +++ b/include/llvm/IR/LegacyPassManagers.h @@ -474,6 +474,6 @@ public: Timer *getPassTimer(Pass *); -} // namespace llvm +} #endif diff --git a/include/llvm/IR/LegacyPassNameParser.h b/include/llvm/IR/LegacyPassNameParser.h index 3f98e764fbc4..39ae80d797c7 100644 --- a/include/llvm/IR/LegacyPassNameParser.h +++ b/include/llvm/IR/LegacyPassNameParser.h @@ -134,6 +134,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Mangler.h b/include/llvm/IR/Mangler.h index 6bda3190db0e..b72b259097c3 100644 --- a/include/llvm/IR/Mangler.h +++ b/include/llvm/IR/Mangler.h @@ -25,28 +25,15 @@ template <typename T> class SmallVectorImpl; class Twine; class Mangler { -public: - enum ManglerPrefixTy { - Default, ///< Emit default string before each symbol. - Private, ///< Emit "private" prefix before each symbol. - LinkerPrivate ///< Emit "linker private" prefix before each symbol. - }; - -private: - const DataLayout *DL; - - /// AnonGlobalIDs - We need to give global values the same name every time - /// they are mangled. This keeps track of the number we give to anonymous - /// ones. - /// + /// We need to give global values the same name every time they are mangled. + /// This keeps track of the number we give to anonymous ones. mutable DenseMap<const GlobalValue*, unsigned> AnonGlobalIDs; - /// NextAnonGlobalID - This simple counter is used to unique value names. - /// + /// This simple counter is used to unique value names. mutable unsigned NextAnonGlobalID; public: - Mangler(const DataLayout *DL) : DL(DL), NextAnonGlobalID(1) {} + Mangler() : NextAnonGlobalID(1) {} /// Print the appropriate prefix and the specified global variable's name. /// If the global variable doesn't have a name, this fills in a unique name @@ -58,12 +45,12 @@ public: /// Print the appropriate prefix and the specified name as the global variable /// name. GVName must not be empty. - void getNameWithPrefix(raw_ostream &OS, const Twine &GVName, - ManglerPrefixTy PrefixTy = Mangler::Default) const; - void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName, - ManglerPrefixTy PrefixTy = Mangler::Default) const; + static void getNameWithPrefix(raw_ostream &OS, const Twine &GVName, + const DataLayout &DL); + static void getNameWithPrefix(SmallVectorImpl<char> &OutName, + const Twine &GVName, const DataLayout &DL); }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Metadata.def b/include/llvm/IR/Metadata.def index f2abff4752f7..857e4637d1e4 100644 --- a/include/llvm/IR/Metadata.def +++ b/include/llvm/IR/Metadata.def @@ -82,6 +82,7 @@ HANDLE_SPECIALIZED_MDNODE_BRANCH(DILexicalBlockBase) HANDLE_SPECIALIZED_MDNODE_LEAF(DILexicalBlock) HANDLE_SPECIALIZED_MDNODE_LEAF(DILexicalBlockFile) HANDLE_SPECIALIZED_MDNODE_LEAF(DINamespace) +HANDLE_SPECIALIZED_MDNODE_LEAF(DIModule) HANDLE_SPECIALIZED_MDNODE_BRANCH(DITemplateParameter) HANDLE_SPECIALIZED_MDNODE_LEAF(DITemplateTypeParameter) HANDLE_SPECIALIZED_MDNODE_LEAF(DITemplateValueParameter) diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index bf4a030cd362..c639625bf16c 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -27,8 +27,11 @@ #include <type_traits> namespace llvm { + class LLVMContext; class Module; +class ModuleSlotTracker; + template<typename ValueSubClass, typename ItemParentClass> class SymbolTableListTraits; @@ -73,6 +76,7 @@ public: DILexicalBlockKind, DILexicalBlockFileKind, DINamespaceKind, + DIModuleKind, DITemplateTypeParameterKind, DITemplateValueParameterKind, DIGlobalVariableKind, @@ -121,7 +125,11 @@ public: /// /// 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; + void print(raw_ostream &OS, ModuleSlotTracker &MST, + const Module *M = nullptr) const; + /// @} /// \brief Print as operand. /// @@ -129,7 +137,11 @@ public: /// /// 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; + void printAsOperand(raw_ostream &OS, ModuleSlotTracker &MST, + const Module *M = nullptr) const; + /// @} }; #define HANDLE_METADATA(CLASS) class CLASS; @@ -1203,6 +1215,6 @@ public: } }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index 598a58e2bd92..1668b95c8bd1 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -249,7 +249,7 @@ public: /// Get the data layout string for the module's target platform. This is /// equivalent to getDataLayout()->getStringRepresentation(). - const std::string getDataLayoutStr() const { + const std::string &getDataLayoutStr() const { return DL.getStringRepresentation(); } @@ -694,6 +694,6 @@ inline Module *unwrap(LLVMModuleProviderRef MP) { return reinterpret_cast<Module*>(MP); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/ModuleSlotTracker.h b/include/llvm/IR/ModuleSlotTracker.h new file mode 100644 index 000000000000..c37dcecf8e40 --- /dev/null +++ b/include/llvm/IR/ModuleSlotTracker.h @@ -0,0 +1,68 @@ +//===-- llvm/IR/ModuleSlotTracker.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_MODULESLOTTRACKER_H +#define LLVM_IR_MODULESLOTTRACKER_H + +#include <memory> + +namespace llvm { + +class Module; +class Function; +class SlotTracker; + +/// Manage lifetime of a slot tracker for printing IR. +/// +/// Wrapper around the \a SlotTracker used internally by \a AsmWriter. This +/// class allows callers to share the cost of incorporating the metadata in a +/// module or a function. +/// +/// If the IR changes from underneath \a ModuleSlotTracker, strings like +/// "<badref>" will be printed, or, worse, the wrong slots entirely. +class ModuleSlotTracker { + /// Storage for a slot tracker. + std::unique_ptr<SlotTracker> MachineStorage; + + const Module *M = nullptr; + const Function *F = nullptr; + SlotTracker *Machine = nullptr; + +public: + /// Wrap a preinitialized SlotTracker. + ModuleSlotTracker(SlotTracker &Machine, const Module *M, + const Function *F = nullptr); + + /// Construct a slot tracker from a module. + /// + /// If \a M is \c nullptr, uses a null slot tracker. Otherwise, initializes + /// a slot tracker, and initializes all metadata slots. \c + /// ShouldInitializeAllMetadata defaults to true because this is expected to + /// be shared between multiple callers, and otherwise MDNode references will + /// not match up. + explicit ModuleSlotTracker(const Module *M, + bool ShouldInitializeAllMetadata = true); + + /// Destructor to clean up storage. + ~ModuleSlotTracker(); + + SlotTracker *getMachine() const { return Machine; } + const Module *getModule() const { return M; } + const Function *getCurrentFunction() const { return F; } + + /// Incorporate the given function. + /// + /// Purge the currently incorporated function and incorporate \c F. If \c F + /// is currently incorporated, this is a no-op. + void incorporateFunction(const Function &F); +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/IR/NoFolder.h b/include/llvm/IR/NoFolder.h index 55b6798c7b3e..61f4817a9b62 100644 --- a/include/llvm/IR/NoFolder.h +++ b/include/llvm/IR/NoFolder.h @@ -294,6 +294,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/IR/OperandTraits.h b/include/llvm/IR/OperandTraits.h index 91ec8d2db750..e97a8009ccc0 100644 --- a/include/llvm/IR/OperandTraits.h +++ b/include/llvm/IR/OperandTraits.h @@ -155,6 +155,6 @@ template <int Idx_nocapture> const Use &CLASS::Op() const { \ } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h index 82f516eb8869..1b9102ecc7e4 100644 --- a/include/llvm/IR/Operator.h +++ b/include/llvm/IR/Operator.h @@ -491,6 +491,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index 2ff1a6fb2fa2..4166babd63e5 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -890,6 +890,6 @@ struct InvalidateAllAnalysesPass { static StringRef name() { return "InvalidateAllAnalysesPass"; } }; -} // namespace llvm +} #endif diff --git a/include/llvm/IR/PassManagerInternal.h b/include/llvm/IR/PassManagerInternal.h index 7921b4f95369..92de10bcd75b 100644 --- a/include/llvm/IR/PassManagerInternal.h +++ b/include/llvm/IR/PassManagerInternal.h @@ -345,6 +345,6 @@ struct AnalysisPassModel<IRUnitT, PassT, false> : AnalysisPassConcept<IRUnitT> { }; } // End namespace detail -} // namespace llvm +} #endif diff --git a/include/llvm/IR/Statepoint.h b/include/llvm/IR/Statepoint.h index 8159cde34251..4ab1f8497adb 100644 --- a/include/llvm/IR/Statepoint.h +++ b/include/llvm/IR/Statepoint.h @@ -20,6 +20,7 @@ #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/Support/Compiler.h" @@ -39,13 +40,13 @@ class GCRelocateOperands; class ImmutableStatepoint; bool isStatepoint(const ImmutableCallSite &CS); -bool isStatepoint(const Value *inst); -bool isStatepoint(const Value &inst); +bool isStatepoint(const Value *V); +bool isStatepoint(const Value &V); -bool isGCRelocate(const Value *inst); +bool isGCRelocate(const Value *V); bool isGCRelocate(const ImmutableCallSite &CS); -bool isGCResult(const Value *inst); +bool isGCResult(const Value *V); bool isGCResult(const ImmutableCallSite &CS); /// Analogous to CallSiteBase, this provides most of the actual @@ -54,20 +55,23 @@ bool isGCResult(const ImmutableCallSite &CS); /// concrete subtypes. This is structured analogous to CallSite /// rather than the IntrinsicInst.h helpers since we want to support /// invokable statepoints in the near future. -/// TODO: This does not currently allow the if(Statepoint S = ...) -/// idiom used with CallSites. Consider refactoring to support. -template <typename InstructionTy, typename ValueTy, typename CallSiteTy> +template <typename FunTy, typename InstructionTy, typename ValueTy, + typename CallSiteTy> class StatepointBase { CallSiteTy StatepointCS; void *operator new(size_t, unsigned) = delete; void *operator new(size_t s) = delete; protected: - explicit StatepointBase(InstructionTy *I) : StatepointCS(I) { - assert(isStatepoint(I)); + explicit StatepointBase(InstructionTy *I) { + if (isStatepoint(I)) { + StatepointCS = CallSiteTy(I); + assert(StatepointCS && "isStatepoint implies CallSite"); + } } - explicit StatepointBase(CallSiteTy CS) : StatepointCS(CS) { - assert(isStatepoint(CS)); + explicit StatepointBase(CallSiteTy CS) { + if (isStatepoint(CS)) + StatepointCS = CS; } public: @@ -76,29 +80,37 @@ public: enum { IDPos = 0, NumPatchBytesPos = 1, - ActualCalleePos = 2, + CalledFunctionPos = 2, NumCallArgsPos = 3, FlagsPos = 4, CallArgsBeginPos = 5, }; + explicit operator bool() const { + // We do not assign non-statepoint CallSites to StatepointCS. + return (bool)StatepointCS; + } + /// Return the underlying CallSite. - CallSiteTy getCallSite() { return StatepointCS; } + CallSiteTy getCallSite() const { + assert(*this && "check validity first!"); + return StatepointCS; + } uint64_t getFlags() const { - return cast<ConstantInt>(StatepointCS.getArgument(FlagsPos)) + return cast<ConstantInt>(getCallSite().getArgument(FlagsPos)) ->getZExtValue(); } /// Return the ID associated with this statepoint. - uint64_t getID() { - const Value *IDVal = StatepointCS.getArgument(IDPos); + uint64_t getID() const { + const Value *IDVal = getCallSite().getArgument(IDPos); return cast<ConstantInt>(IDVal)->getZExtValue(); } /// Return the number of patchable bytes associated with this statepoint. - uint32_t getNumPatchBytes() { - const Value *NumPatchBytesVal = StatepointCS.getArgument(NumPatchBytesPos); + uint32_t getNumPatchBytes() const { + const Value *NumPatchBytesVal = getCallSite().getArgument(NumPatchBytesPos); uint64_t NumPatchBytes = cast<ConstantInt>(NumPatchBytesVal)->getZExtValue(); assert(isInt<32>(NumPatchBytes) && "should fit in 32 bits!"); @@ -106,91 +118,125 @@ public: } /// Return the value actually being called or invoked. - ValueTy *getActualCallee() { - return StatepointCS.getArgument(ActualCalleePos); + ValueTy *getCalledValue() const { + return getCallSite().getArgument(CalledFunctionPos); + } + + InstructionTy *getInstruction() const { + return getCallSite().getInstruction(); + } + + /// Return the function being called if this is a direct call, otherwise + /// return null (if it's an indirect call). + FunTy *getCalledFunction() const { + return dyn_cast<Function>(getCalledValue()); + } + + /// Return the caller function for this statepoint. + FunTy *getCaller() const { return getCallSite().getCaller(); } + + /// Determine if the statepoint cannot unwind. + bool doesNotThrow() const { + Function *F = getCalledFunction(); + return getCallSite().doesNotThrow() || (F ? F->doesNotThrow() : false); } /// Return the type of the value returned by the call underlying the /// statepoint. - Type *getActualReturnType() { + Type *getActualReturnType() const { auto *FTy = cast<FunctionType>( - cast<PointerType>(getActualCallee()->getType())->getElementType()); + cast<PointerType>(getCalledValue()->getType())->getElementType()); return FTy->getReturnType(); } /// Number of arguments to be passed to the actual callee. - int getNumCallArgs() { - const Value *NumCallArgsVal = StatepointCS.getArgument(NumCallArgsPos); + int getNumCallArgs() const { + const Value *NumCallArgsVal = getCallSite().getArgument(NumCallArgsPos); return cast<ConstantInt>(NumCallArgsVal)->getZExtValue(); } - typename CallSiteTy::arg_iterator call_args_begin() { - assert(CallArgsBeginPos <= (int)StatepointCS.arg_size()); - return StatepointCS.arg_begin() + CallArgsBeginPos; + size_t arg_size() const { return getNumCallArgs(); } + typename CallSiteTy::arg_iterator arg_begin() const { + assert(CallArgsBeginPos <= (int)getCallSite().arg_size()); + return getCallSite().arg_begin() + CallArgsBeginPos; } - typename CallSiteTy::arg_iterator call_args_end() { - auto I = call_args_begin() + getNumCallArgs(); - assert((StatepointCS.arg_end() - I) >= 0); + typename CallSiteTy::arg_iterator arg_end() const { + auto I = arg_begin() + arg_size(); + assert((getCallSite().arg_end() - I) >= 0); return I; } + ValueTy *getArgument(unsigned Index) { + assert(Index < arg_size() && "out of bounds!"); + return *(arg_begin() + Index); + } + /// range adapter for call arguments - iterator_range<arg_iterator> call_args() { - return iterator_range<arg_iterator>(call_args_begin(), call_args_end()); + iterator_range<arg_iterator> call_args() const { + return iterator_range<arg_iterator>(arg_begin(), arg_end()); + } + + /// \brief Return true if the call or the callee has the given attribute. + bool paramHasAttr(unsigned i, Attribute::AttrKind A) const { + Function *F = getCalledFunction(); + return getCallSite().paramHasAttr(i + CallArgsBeginPos, A) || + (F ? F->getAttributes().hasAttribute(i, A) : false); } /// Number of GC transition args. - int getNumTotalGCTransitionArgs() { - const Value *NumGCTransitionArgs = *call_args_end(); + int getNumTotalGCTransitionArgs() const { + const Value *NumGCTransitionArgs = *arg_end(); return cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue(); } - typename CallSiteTy::arg_iterator gc_transition_args_begin() { - auto I = call_args_end() + 1; - assert((StatepointCS.arg_end() - I) >= 0); + typename CallSiteTy::arg_iterator gc_transition_args_begin() const { + auto I = arg_end() + 1; + assert((getCallSite().arg_end() - I) >= 0); return I; } - typename CallSiteTy::arg_iterator gc_transition_args_end() { + typename CallSiteTy::arg_iterator gc_transition_args_end() const { auto I = gc_transition_args_begin() + getNumTotalGCTransitionArgs(); - assert((StatepointCS.arg_end() - I) >= 0); + assert((getCallSite().arg_end() - I) >= 0); return I; } /// range adapter for GC transition arguments - iterator_range<arg_iterator> gc_transition_args() { + iterator_range<arg_iterator> gc_transition_args() const { return iterator_range<arg_iterator>(gc_transition_args_begin(), gc_transition_args_end()); } /// Number of additional arguments excluding those intended /// for garbage collection. - int getNumTotalVMSArgs() { + int getNumTotalVMSArgs() const { const Value *NumVMSArgs = *gc_transition_args_end(); return cast<ConstantInt>(NumVMSArgs)->getZExtValue(); } - typename CallSiteTy::arg_iterator vm_state_begin() { + typename CallSiteTy::arg_iterator vm_state_begin() const { auto I = gc_transition_args_end() + 1; - assert((StatepointCS.arg_end() - I) >= 0); + assert((getCallSite().arg_end() - I) >= 0); return I; } - typename CallSiteTy::arg_iterator vm_state_end() { + typename CallSiteTy::arg_iterator vm_state_end() const { auto I = vm_state_begin() + getNumTotalVMSArgs(); - assert((StatepointCS.arg_end() - I) >= 0); + assert((getCallSite().arg_end() - I) >= 0); return I; } /// range adapter for vm state arguments - iterator_range<arg_iterator> vm_state_args() { + iterator_range<arg_iterator> vm_state_args() const { return iterator_range<arg_iterator>(vm_state_begin(), vm_state_end()); } - typename CallSiteTy::arg_iterator gc_args_begin() { return vm_state_end(); } - typename CallSiteTy::arg_iterator gc_args_end() { - return StatepointCS.arg_end(); + typename CallSiteTy::arg_iterator gc_args_begin() const { + return vm_state_end(); + } + typename CallSiteTy::arg_iterator gc_args_end() const { + return getCallSite().arg_end(); } /// range adapter for gc arguments - iterator_range<arg_iterator> gc_args() { + iterator_range<arg_iterator> gc_args() const { return iterator_range<arg_iterator>(gc_args_begin(), gc_args_end()); } @@ -198,7 +244,18 @@ public: /// May contain several relocations for the same base/derived pair. /// For example this could happen due to relocations on unwinding /// path of invoke. - std::vector<GCRelocateOperands> getRelocates(); + std::vector<GCRelocateOperands> getRelocates() const; + + /// Get the experimental_gc_result call tied to this statepoint. Can be + /// nullptr if there isn't a gc_result tied to this statepoint. Guaranteed to + /// be a CallInst if non-null. + InstructionTy *getGCResult() const { + for (auto *U : getInstruction()->users()) + if (isGCResult(U)) + return cast<CallInst>(U); + + return nullptr; + } #ifndef NDEBUG /// Asserts if this statepoint is malformed. Common cases for failure @@ -209,8 +266,8 @@ public: "number of arguments to actually callee can't be negative"); // The internal asserts in the iterator accessors do the rest. - (void)call_args_begin(); - (void)call_args_end(); + (void)arg_begin(); + (void)arg_end(); (void)gc_transition_args_begin(); (void)gc_transition_args_end(); (void)vm_state_begin(); @@ -224,9 +281,10 @@ public: /// A specialization of it's base class for read only access /// to a gc.statepoint. class ImmutableStatepoint - : public StatepointBase<const Instruction, const Value, ImmutableCallSite> { - typedef StatepointBase<const Instruction, const Value, ImmutableCallSite> - Base; + : public StatepointBase<const Function, const Instruction, const Value, + ImmutableCallSite> { + typedef StatepointBase<const Function, const Instruction, const Value, + ImmutableCallSite> Base; public: explicit ImmutableStatepoint(const Instruction *I) : Base(I) {} @@ -235,8 +293,9 @@ public: /// A specialization of it's base class for read-write access /// to a gc.statepoint. -class Statepoint : public StatepointBase<Instruction, Value, CallSite> { - typedef StatepointBase<Instruction, Value, CallSite> Base; +class Statepoint + : public StatepointBase<Function, Instruction, Value, CallSite> { + typedef StatepointBase<Function, Instruction, Value, CallSite> Base; public: explicit Statepoint(Instruction *I) : Base(I) {} @@ -313,9 +372,11 @@ public: } }; -template <typename InstructionTy, typename ValueTy, typename CallSiteTy> +template <typename FunTy, typename InstructionTy, typename ValueTy, + typename CallSiteTy> std::vector<GCRelocateOperands> -StatepointBase<InstructionTy, ValueTy, CallSiteTy>::getRelocates() { +StatepointBase<FunTy, InstructionTy, ValueTy, CallSiteTy>::getRelocates() + const { std::vector<GCRelocateOperands> Result; @@ -324,7 +385,7 @@ StatepointBase<InstructionTy, ValueTy, CallSiteTy>::getRelocates() { // Search for relocated pointers. Note that working backwards from the // gc_relocates ensures that we only get pairs which are actually relocated // and used after the statepoint. - for (const User *U : StatepointCS.getInstruction()->users()) + for (const User *U : getInstruction()->users()) if (isGCRelocate(U)) Result.push_back(GCRelocateOperands(U)); @@ -333,7 +394,7 @@ StatepointBase<InstructionTy, ValueTy, CallSiteTy>::getRelocates() { // We need to scan thorough exceptional relocations if it is invoke statepoint LandingPadInst *LandingPad = - cast<InvokeInst>(StatepointCS.getInstruction())->getLandingPadInst(); + cast<InvokeInst>(getInstruction())->getLandingPadInst(); // Search for extract value from landingpad instruction to which // gc relocates will be attached @@ -348,6 +409,6 @@ StatepointBase<InstructionTy, ValueTy, CallSiteTy>::getRelocates() { } return Result; } -} // namespace llvm +} #endif diff --git a/include/llvm/IR/SymbolTableListTraits.h b/include/llvm/IR/SymbolTableListTraits.h index ef69498123fb..0a5149c3d938 100644 --- a/include/llvm/IR/SymbolTableListTraits.h +++ b/include/llvm/IR/SymbolTableListTraits.h @@ -73,6 +73,6 @@ public: static ValueSymbolTable *toPtr(ValueSymbolTable &R) { return &R; } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h index a62604625bd8..6ab0bd0631a0 100644 --- a/include/llvm/IR/Type.h +++ b/include/llvm/IR/Type.h @@ -484,6 +484,6 @@ inline LLVMTypeRef *wrap(Type **Tys) { return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys)); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/TypeFinder.h b/include/llvm/IR/TypeFinder.h index aa50d0e411da..73a63ad0349e 100644 --- a/include/llvm/IR/TypeFinder.h +++ b/include/llvm/IR/TypeFinder.h @@ -74,6 +74,6 @@ private: void incorporateMDNode(const MDNode *V); }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h index 8f87df67057b..160d71b03e7f 100644 --- a/include/llvm/IR/Use.h +++ b/include/llvm/IR/Use.h @@ -168,6 +168,6 @@ template <> struct simplify_type<const Use> { // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef) -} // namespace llvm +} #endif diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h index 41d57703ab01..93614fab5759 100644 --- a/include/llvm/IR/User.h +++ b/include/llvm/IR/User.h @@ -259,6 +259,6 @@ template<> struct simplify_type<User::const_op_iterator> { } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Value.def b/include/llvm/IR/Value.def new file mode 100644 index 000000000000..c2a0639603ed --- /dev/null +++ b/include/llvm/IR/Value.def @@ -0,0 +1,90 @@ +//===-------- llvm/IR/Value.def - File that describes Values ---v-*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains descriptions of the various LLVM values. This is +// used as a central place for enumerating the different values. +// +//===----------------------------------------------------------------------===// + +// NOTE: NO INCLUDE GUARD DESIRED! + +// Provide definitions of macros so that users of this file do not have to +// define everything to use it... +// +#if !(defined HANDLE_GLOBAL_VALUE || defined HANDLE_CONSTANT || \ + defined HANDLE_INSTRUCTION || defined HANDLE_INLINE_ASM_VALUE || \ + defined HANDLE_METADATA_VALUE || defined HANDLE_VALUE || \ + defined HANDLE_CONSTANT_MARKER) +#error "Missing macro definition of HANDLE_VALUE*" +#endif + +#ifndef HANDLE_GLOBAL_VALUE +#define HANDLE_GLOBAL_VALUE(ValueName) HANDLE_CONSTANT(ValueName) +#endif + +#ifndef HANDLE_CONSTANT +#define HANDLE_CONSTANT(ValueName) HANDLE_VALUE(ValueName) +#endif + +#ifndef HANDLE_INSTRUCTION +#define HANDLE_INSTRUCTION(ValueName) HANDLE_VALUE(ValueName) +#endif + +#ifndef HANDLE_INLINE_ASM_VALUE +#define HANDLE_INLINE_ASM_VALUE(ValueName) HANDLE_VALUE(ValueName) +#endif + +#ifndef HANDLE_METADATA_VALUE +#define HANDLE_METADATA_VALUE(ValueName) HANDLE_VALUE(ValueName) +#endif + +#ifndef HANDLE_VALUE +#define HANDLE_VALUE(ValueName) +#endif + +#ifndef HANDLE_CONSTANT_MARKER +#define HANDLE_CONSTANT_MARKER(MarkerName, ValueName) +#endif + +HANDLE_VALUE(Argument) +HANDLE_VALUE(BasicBlock) + +HANDLE_GLOBAL_VALUE(Function) +HANDLE_GLOBAL_VALUE(GlobalAlias) +HANDLE_GLOBAL_VALUE(GlobalVariable) +HANDLE_CONSTANT(UndefValue) +HANDLE_CONSTANT(BlockAddress) +HANDLE_CONSTANT(ConstantExpr) +HANDLE_CONSTANT(ConstantAggregateZero) +HANDLE_CONSTANT(ConstantDataArray) +HANDLE_CONSTANT(ConstantDataVector) +HANDLE_CONSTANT(ConstantInt) +HANDLE_CONSTANT(ConstantFP) +HANDLE_CONSTANT(ConstantArray) +HANDLE_CONSTANT(ConstantStruct) +HANDLE_CONSTANT(ConstantVector) +HANDLE_CONSTANT(ConstantPointerNull) + +HANDLE_METADATA_VALUE(MetadataAsValue) +HANDLE_INLINE_ASM_VALUE(InlineAsm) + +HANDLE_INSTRUCTION(Instruction) +// Enum values starting at InstructionVal are used for Instructions; +// don't add new values here! + +HANDLE_CONSTANT_MARKER(ConstantFirstVal, Function) +HANDLE_CONSTANT_MARKER(ConstantLastVal, ConstantPointerNull) + +#undef HANDLE_GLOBAL_VALUE +#undef HANDLE_CONSTANT +#undef HANDLE_INSTRUCTION +#undef HANDLE_METADATA_VALUE +#undef HANDLE_INLINE_ASM_VALUE +#undef HANDLE_VALUE +#undef HANDLE_CONSTANT_MARKER diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index 6b36ba6debfb..484afc6d232c 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -38,6 +38,7 @@ class InlineAsm; class Instruction; class LLVMContext; class Module; +class ModuleSlotTracker; class StringRef; class Twine; class Type; @@ -199,7 +200,10 @@ public: void dump() const; /// \brief Implement operator<< on Value. + /// @{ void print(raw_ostream &O) const; + void print(raw_ostream &O, ModuleSlotTracker &MST) const; + /// @} /// \brief Print the name of this Value out to the specified raw_ostream. /// @@ -207,8 +211,12 @@ public: /// instruction that generated it. If you specify a Module for context, then /// even constanst get pretty-printed; for example, the type of a null /// pointer is printed symbolically. + /// @{ void printAsOperand(raw_ostream &O, bool PrintType = true, const Module *M = nullptr) const; + void printAsOperand(raw_ostream &O, bool PrintType, + ModuleSlotTracker &MST) const; + /// @} /// \brief All values are typed, get the type of this value. Type *getType() const { return VTy; } @@ -333,32 +341,12 @@ public: /// Value classes SubclassID field. They are used for concrete type /// identification. enum ValueTy { - ArgumentVal, // This is an instance of Argument - BasicBlockVal, // This is an instance of BasicBlock - FunctionVal, // This is an instance of Function - GlobalAliasVal, // This is an instance of GlobalAlias - GlobalVariableVal, // This is an instance of GlobalVariable - UndefValueVal, // This is an instance of UndefValue - BlockAddressVal, // This is an instance of BlockAddress - ConstantExprVal, // This is an instance of ConstantExpr - ConstantAggregateZeroVal, // This is an instance of ConstantAggregateZero - ConstantDataArrayVal, // This is an instance of ConstantDataArray - ConstantDataVectorVal, // This is an instance of ConstantDataVector - ConstantIntVal, // This is an instance of ConstantInt - ConstantFPVal, // This is an instance of ConstantFP - ConstantArrayVal, // This is an instance of ConstantArray - ConstantStructVal, // This is an instance of ConstantStruct - ConstantVectorVal, // This is an instance of ConstantVector - ConstantPointerNullVal, // This is an instance of ConstantPointerNull - MetadataAsValueVal, // This is an instance of MetadataAsValue - InlineAsmVal, // This is an instance of InlineAsm - InstructionVal, // This is an instance of Instruction - // Enum values starting at InstructionVal are used for Instructions; - // don't add new values here! +#define HANDLE_VALUE(Name) Name##Val, +#include "llvm/IR/Value.def" // Markers: - ConstantFirstVal = FunctionVal, - ConstantLastVal = ConstantPointerNullVal +#define HANDLE_CONSTANT_MARKER(Marker, Constant) Marker = Constant##Val, +#include "llvm/IR/Value.def" }; /// \brief Return an ID for the concrete type of this object. @@ -716,6 +704,6 @@ inline LLVMValueRef *wrap(const Value **Vals) { return reinterpret_cast<LLVMValueRef*>(const_cast<Value**>(Vals)); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/ValueHandle.h b/include/llvm/IR/ValueHandle.h index e92aed35c5ac..53fa80a626aa 100644 --- a/include/llvm/IR/ValueHandle.h +++ b/include/llvm/IR/ValueHandle.h @@ -159,11 +159,13 @@ public: // Specialize simplify_type to allow WeakVH to participate in // dyn_cast, isa, etc. -template<> struct simplify_type<WeakVH> { - typedef Value* SimpleType; - static SimpleType getSimplifiedValue(WeakVH &WVH) { - return WVH; - } +template <> struct simplify_type<WeakVH> { + typedef Value *SimpleType; + static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; } +}; +template <> struct simplify_type<const WeakVH> { + typedef Value *SimpleType; + static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; } }; /// \brief Value handle that asserts if the Value is deleted. @@ -380,6 +382,6 @@ public: virtual void allUsesReplacedWith(Value *) {} }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/ValueSymbolTable.h b/include/llvm/IR/ValueSymbolTable.h index 8219f5099690..bf1fade1ccef 100644 --- a/include/llvm/IR/ValueSymbolTable.h +++ b/include/llvm/IR/ValueSymbolTable.h @@ -128,6 +128,6 @@ private: /// @} }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IR/Verifier.h b/include/llvm/IR/Verifier.h index 7da4d97488ad..89039d24195e 100644 --- a/include/llvm/IR/Verifier.h +++ b/include/llvm/IR/Verifier.h @@ -72,6 +72,6 @@ public: static StringRef name() { return "VerifierPass"; } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/IRReader/IRReader.h b/include/llvm/IRReader/IRReader.h index bdaea6d6c0cf..2d9ace0b62a0 100644 --- a/include/llvm/IRReader/IRReader.h +++ b/include/llvm/IRReader/IRReader.h @@ -43,6 +43,6 @@ std::unique_ptr<Module> parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err, /// for it. std::unique_ptr<Module> parseIRFile(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context); -} // namespace llvm +} #endif diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 33ffadb6848c..74fbc0f94b03 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -302,6 +302,6 @@ void initializePlaceSafepointsPass(PassRegistry&); void initializeDwarfEHPreparePass(PassRegistry&); void initializeFloat2IntPass(PassRegistry&); void initializeLoopDistributePass(PassRegistry&); -} // namespace llvm +} #endif diff --git a/include/llvm/LTO/LTOCodeGenerator.h b/include/llvm/LTO/LTOCodeGenerator.h index c079f791c24f..0c46fc048a43 100644 --- a/include/llvm/LTO/LTOCodeGenerator.h +++ b/include/llvm/LTO/LTOCodeGenerator.h @@ -177,5 +177,5 @@ private: bool ShouldInternalize = true; bool ShouldEmbedUselists = false; }; -} // namespace llvm +} #endif diff --git a/include/llvm/LTO/LTOModule.h b/include/llvm/LTO/LTOModule.h index c2eb36220e84..c4e2be627399 100644 --- a/include/llvm/LTO/LTOModule.h +++ b/include/llvm/LTO/LTOModule.h @@ -47,12 +47,11 @@ private: std::unique_ptr<LLVMContext> OwnedContext; + std::string LinkerOpts; + std::unique_ptr<object::IRObjectFile> IRFile; std::unique_ptr<TargetMachine> _target; - StringSet<> _linkeropt_strings; - std::vector<const char *> _deplibs; - std::vector<const char *> _linkeropts; - std::vector<NameAndAttributes> _symbols; + std::vector<NameAndAttributes> _symbols; // _defines and _undefines only needed to disambiguate tentative definitions StringSet<> _defines; @@ -149,28 +148,8 @@ public: return nullptr; } - /// Get the number of dependent libraries - uint32_t getDependentLibraryCount() { - return _deplibs.size(); - } - - /// Get the dependent library at the specified index. - const char *getDependentLibrary(uint32_t index) { - if (index < _deplibs.size()) - return _deplibs[index]; - return nullptr; - } - - /// Get the number of linker options - uint32_t getLinkerOptCount() { - return _linkeropts.size(); - } - - /// Get the linker option at the specified index. - const char *getLinkerOpt(uint32_t index) { - if (index < _linkeropts.size()) - return _linkeropts[index]; - return nullptr; + const char *getLinkerOpts() { + return LinkerOpts.c_str(); } const std::vector<const char*> &getAsmUndefinedRefs() { @@ -224,5 +203,5 @@ private: static LTOModule *makeLTOModule(MemoryBufferRef Buffer, TargetOptions options, std::string &errMsg, LLVMContext *Context); }; -} // namespace llvm +} #endif diff --git a/include/llvm/LibDriver/LibDriver.h b/include/llvm/LibDriver/LibDriver.h index 99c783c95cb6..aaaa7b7d21c3 100644 --- a/include/llvm/LibDriver/LibDriver.h +++ b/include/llvm/LibDriver/LibDriver.h @@ -15,9 +15,11 @@ #ifndef LLVM_LIBDRIVER_LIBDRIVER_H #define LLVM_LIBDRIVER_LIBDRIVER_H +#include "llvm/ADT/ArrayRef.h" + namespace llvm { -int libDriverMain(int argc, const char **argv); +int libDriverMain(llvm::ArrayRef<const char*> ARgs); } diff --git a/include/llvm/LineEditor/LineEditor.h b/include/llvm/LineEditor/LineEditor.h index e644b1990f96..bb106f87ca48 100644 --- a/include/llvm/LineEditor/LineEditor.h +++ b/include/llvm/LineEditor/LineEditor.h @@ -148,6 +148,6 @@ private: std::unique_ptr<const CompleterConcept> Completer; }; -} // namespace llvm +} #endif diff --git a/include/llvm/Linker/Linker.h b/include/llvm/Linker/Linker.h index de23acb7e524..c43b90e9cd26 100644 --- a/include/llvm/Linker/Linker.h +++ b/include/llvm/Linker/Linker.h @@ -90,6 +90,6 @@ private: DiagnosticHandlerFunction DiagnosticHandler; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index 07bba904788a..2bfad2d355b8 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -138,6 +138,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index f72959a5c5a0..9bb0fa63c523 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -39,7 +39,7 @@ enum class EncodingType { X86, /// Windows x86, uses no CFI, just EH tables MIPS = Alpha, }; -} // namespace WinEH +} enum class ExceptionHandling { None, /// No exception support @@ -555,6 +555,6 @@ public: bool shouldUseLogicalShr() const { return UseLogicalShr; } }; -} // namespace llvm +} #endif diff --git a/include/llvm/MC/MCAsmInfoCOFF.h b/include/llvm/MC/MCAsmInfoCOFF.h index 24f03e4c9bad..56444f3c7cf5 100644 --- a/include/llvm/MC/MCAsmInfoCOFF.h +++ b/include/llvm/MC/MCAsmInfoCOFF.h @@ -30,7 +30,7 @@ namespace llvm { protected: explicit MCAsmInfoGNUCOFF(); }; -} // namespace llvm +} #endif // LLVM_MC_MCASMINFOCOFF_H diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h index b4445d10c337..b6c19150c12a 100644 --- a/include/llvm/MC/MCCodeEmitter.h +++ b/include/llvm/MC/MCCodeEmitter.h @@ -41,6 +41,6 @@ public: const MCSubtargetInfo &STI) const = 0; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index 855013a9cbbe..01f694d3b756 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -132,6 +132,6 @@ public: MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS, bool IsLittleEndian); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCExternalSymbolizer.h b/include/llvm/MC/MCExternalSymbolizer.h index a88b32e215e8..2c7d23707c95 100644 --- a/include/llvm/MC/MCExternalSymbolizer.h +++ b/include/llvm/MC/MCExternalSymbolizer.h @@ -53,6 +53,6 @@ public: uint64_t Address) override; }; -} // namespace llvm +} #endif diff --git a/include/llvm/MC/MCFixedLenDisassembler.h b/include/llvm/MC/MCFixedLenDisassembler.h index 9fbdf9c22fba..ad99943df2c3 100644 --- a/include/llvm/MC/MCFixedLenDisassembler.h +++ b/include/llvm/MC/MCFixedLenDisassembler.h @@ -26,7 +26,7 @@ enum DecoderOps { OPC_Fail // OPC_Fail() }; -} // namespace MCD +} // namespace MCDecode } // namespace llvm #endif diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h index c09f55a8ffc4..8ab477c401a1 100644 --- a/include/llvm/MC/MCFixup.h +++ b/include/llvm/MC/MCFixup.h @@ -108,6 +108,6 @@ public: SMLoc getLoc() const { return Loc; } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCFixupKindInfo.h b/include/llvm/MC/MCFixupKindInfo.h index b779781f49bd..58183bd778e6 100644 --- a/include/llvm/MC/MCFixupKindInfo.h +++ b/include/llvm/MC/MCFixupKindInfo.h @@ -38,6 +38,6 @@ struct MCFixupKindInfo { unsigned Flags; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCInstrAnalysis.h b/include/llvm/MC/MCInstrAnalysis.h index a0a68106bc80..8f5159e9e1c8 100644 --- a/include/llvm/MC/MCInstrAnalysis.h +++ b/include/llvm/MC/MCInstrAnalysis.h @@ -66,6 +66,6 @@ public: uint64_t &Target) const; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index fe67e4407672..3209a2ce0408 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -49,7 +49,7 @@ enum OperandType { OPERAND_PCREL = 4, OPERAND_FIRST_TARGET = 5 }; -} // namespace MCOI +} /// \brief This holds information about one operand of a machine instruction, /// indicating the register class for register operands, etc. @@ -128,7 +128,7 @@ enum Flag { InsertSubreg, Convergent }; -} // namespace MCID +} /// \brief Describe properties that are true of each instruction in the target /// description file. This captures information about side effects, register diff --git a/include/llvm/MC/MCInstrInfo.h b/include/llvm/MC/MCInstrInfo.h index d75c4cad1f1a..70c86587b08c 100644 --- a/include/llvm/MC/MCInstrInfo.h +++ b/include/llvm/MC/MCInstrInfo.h @@ -54,6 +54,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCInstrItineraries.h b/include/llvm/MC/MCInstrItineraries.h index a58bd7b4d396..161705de7c4e 100644 --- a/include/llvm/MC/MCInstrItineraries.h +++ b/include/llvm/MC/MCInstrItineraries.h @@ -234,6 +234,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index 10b7905a82de..175d73e72c10 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -264,6 +264,6 @@ MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_pwrite_stream &OS, bool IsLittleEndian); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index ca7fba547dc3..2211673efc31 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -188,6 +188,6 @@ public: /// @} }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 0bf8aa6d899a..71f15b37c331 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -190,6 +190,6 @@ public: void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index c840958fa91e..ac8706d99505 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -197,12 +197,23 @@ public: /// \brief Ensure that we have a valid section set in the streamer. Otherwise, /// report an error and switch to .text. virtual void checkForValidSection() = 0; + + /// \brief Parse an arbitrary expression of a specified parenthesis depth, + /// assuming that the initial '(' characters have already been consumed. + /// + /// \param ParenDepth - Specifies how many trailing expressions outside the + /// current parentheses we have to parse. + /// \param Res - The value of the expression. The result is undefined + /// on error. + /// \return - False on success. + virtual bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res, + SMLoc &EndLoc) = 0; }; /// \brief Create an MCAsmParser instance. MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h index 46f716e68e67..077fd21e073c 100644 --- a/include/llvm/MC/MCParser/MCAsmParserExtension.h +++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -84,6 +84,6 @@ public: /// @} }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCParser/MCAsmParserUtils.h b/include/llvm/MC/MCParser/MCAsmParserUtils.h new file mode 100644 index 000000000000..9834fe96307b --- /dev/null +++ b/include/llvm/MC/MCParser/MCAsmParserUtils.h @@ -0,0 +1,33 @@ +//===------ llvm/MC/MCAsmParserUtils.h - Asm Parser Utilities ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCPARSER_MCASMPARSERUTILS_H +#define LLVM_MC_MCPARSER_MCASMPARSERUTILS_H + +namespace llvm { + +class MCAsmParser; +class MCExpr; +class MCSymbol; +class StringRef; + +namespace MCParserUtils { + +/// Parse a value expression and return whether it can be assigned to a symbol +/// with the given name. +/// +/// On success, returns false and sets the Symbol and Value output parameters. +bool parseAssignmentExpression(StringRef Name, bool allow_redef, + MCAsmParser &Parser, MCSymbol *&Symbol, + const MCExpr *&Value); + +} // namespace MCParserUtils +} // namespace llvm + +#endif diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index 7a41abcbf728..8e25ee18e08d 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -686,6 +686,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCRelocationInfo.h b/include/llvm/MC/MCRelocationInfo.h index 8fc5c9f53a46..40e0217b8d83 100644 --- a/include/llvm/MC/MCRelocationInfo.h +++ b/include/llvm/MC/MCRelocationInfo.h @@ -50,6 +50,6 @@ public: unsigned VariantKind); }; -} // namespace llvm +} #endif diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h index 635eab99be6a..1adfedd2638a 100644 --- a/include/llvm/MC/MCSchedule.h +++ b/include/llvm/MC/MCSchedule.h @@ -245,6 +245,6 @@ struct MCSchedModel { } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 50d8d314ef4e..6b9b8a153845 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -78,7 +78,7 @@ public: MCTargetStreamer(MCStreamer &S); virtual ~MCTargetStreamer(); - const MCStreamer &getStreamer() { return Streamer; } + MCStreamer &getStreamer() { return Streamer; } // Allow a target to add behavior to the EmitLabel of MCStreamer. virtual void emitLabel(MCSymbol *Symbol); diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index 0a23306fa694..b8ad02fbe696 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -160,6 +160,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 0acf6e50ba48..17e6b857cf20 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -14,6 +14,7 @@ #ifndef LLVM_MC_MCSYMBOL_H #define LLVM_MC_MCSYMBOL_H +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringMap.h" #include "llvm/MC/MCAssembler.h" @@ -46,6 +47,15 @@ protected: SymbolKindMachO, }; + /// A symbol can contain an Offset, or Value, or be Common, but never more + /// than one of these. + enum Contents : uint8_t { + SymContentsUnset, + SymContentsOffset, + SymContentsVariable, + SymContentsCommon, + }; + // Special sentinal value for the absolute pseudo section. // // FIXME: Use a PointerInt wrapper for this? @@ -62,10 +72,12 @@ protected: /// /// If this is a fragment, then it gives the fragment this symbol's value is /// relative to, if any. - mutable PointerUnion<MCSection *, MCFragment *> SectionOrFragment; - - /// Value - If non-null, the value for a variable symbol. - const MCExpr *Value; + /// + /// For the 'HasName' integer, this is true if this symbol is named. + /// A named symbol will have a pointer to the name allocated in the bytes + /// immediately prior to the MCSymbol. + mutable PointerIntPair<PointerUnion<MCSection *, MCFragment *>, 1> + SectionOrFragmentAndHasName; /// IsTemporary - True if this is an assembler temporary label, which /// typically does not survive in the .o file's symbol table. Usually @@ -86,11 +98,6 @@ protected: /// This symbol is private extern. mutable unsigned IsPrivateExtern : 1; - /// True if this symbol is named. - /// A named symbol will have a pointer to the name allocated in the bytes - /// immediately prior to the MCSymbol. - unsigned HasName : 1; - /// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is /// unsigned to avoid sign extension and achieve better bitpacking with MSVC. unsigned Kind : 2; @@ -98,6 +105,23 @@ protected: /// True if we have created a relocation that uses this symbol. mutable unsigned IsUsedInReloc : 1; + /// This is actually a Contents enumerator, but is unsigned to avoid sign + /// extension and achieve better bitpacking with MSVC. + unsigned SymbolContents : 2; + + /// The alignment of the symbol, if it is 'common', or -1. + /// + /// The alignment is stored as log2(align) + 1. This allows all values from + /// 0 to 2^31 to be stored which is every power of 2 representable by an + /// unsigned. + static const unsigned NumCommonAlignmentBits = 5; + unsigned CommonAlignLog2 : NumCommonAlignmentBits; + + /// The Flags field is used by object file implementations to store + /// additional per symbol information which is not easily classified. + static const unsigned NumFlagsBits = 16; + mutable uint32_t Flags : NumFlagsBits; + /// Index field, for use by the object file implementation. mutable uint32_t Index = 0; @@ -107,16 +131,10 @@ protected: /// The size of the symbol, if it is 'common'. uint64_t CommonSize; - }; - /// The alignment of the symbol, if it is 'common', or -1. - // - // FIXME: Pack this in with other fields? - unsigned CommonAlign = -1U; - - /// The Flags field is used by object file implementations to store - /// additional per symbol information which is not easily classified. - mutable uint32_t Flags = 0; + /// If non-null, the value for a variable symbol. + const MCExpr *Value; + }; protected: // MCContext creates and uniques these. friend class MCExpr; @@ -132,11 +150,12 @@ protected: // MCContext creates and uniques these. } NameEntryStorageTy; MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary) - : Value(nullptr), IsTemporary(isTemporary), IsRedefinable(false), - IsUsed(false), IsRegistered(false), IsExternal(false), - IsPrivateExtern(false), HasName(!!Name), Kind(Kind), - IsUsedInReloc(false) { + : IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false), + IsRegistered(false), IsExternal(false), IsPrivateExtern(false), + Kind(Kind), IsUsedInReloc(false), SymbolContents(SymContentsUnset), + CommonAlignLog2(0), Flags(0) { Offset = 0; + SectionOrFragmentAndHasName.setInt(!!Name); if (Name) getNameEntryPtr() = Name; } @@ -163,16 +182,17 @@ private: MCSection *getSectionPtr() const { if (MCFragment *F = getFragment()) return F->getParent(); + const auto &SectionOrFragment = SectionOrFragmentAndHasName.getPointer(); assert(!SectionOrFragment.is<MCFragment *>() && "Section or null expected"); MCSection *Section = SectionOrFragment.dyn_cast<MCSection *>(); - if (Section || !Value) + if (Section || !isVariable()) return Section; - return Section = Value->findAssociatedSection(); + return Section = getVariableValue()->findAssociatedSection(); } /// \brief Get a reference to the name field. Requires that we have a name const StringMapEntry<bool> *&getNameEntryPtr() { - assert(HasName && "Name is required"); + assert(SectionOrFragmentAndHasName.getInt() && "Name is required"); NameEntryStorageTy *Name = reinterpret_cast<NameEntryStorageTy *>(this); return (*(Name - 1)).NameEntry; } @@ -183,7 +203,7 @@ private: public: /// getName - Get the symbol name. StringRef getName() const { - if (!HasName) + if (!SectionOrFragmentAndHasName.getInt()) return StringRef(); return getNameEntryPtr()->first(); @@ -212,8 +232,11 @@ public: /// \brief Prepare this symbol to be redefined. void redefineIfPossible() { if (IsRedefinable) { - Value = nullptr; - SectionOrFragment = nullptr; + if (SymbolContents == SymContentsVariable) { + Value = nullptr; + SymbolContents = SymContentsUnset; + } + setUndefined(); IsRedefinable = false; } } @@ -246,13 +269,15 @@ public: /// Mark the symbol as defined in the section \p S. void setSection(MCSection &S) { assert(!isVariable() && "Cannot set section of variable"); - assert(!SectionOrFragment.is<MCFragment *>() && "Section or null expected"); - SectionOrFragment = &S; + assert(!SectionOrFragmentAndHasName.getPointer().is<MCFragment *>() && + "Section or null expected"); + SectionOrFragmentAndHasName.setPointer(&S); } /// Mark the symbol as undefined. void setUndefined() { - SectionOrFragment = nullptr; + SectionOrFragmentAndHasName.setPointer( + PointerUnion<MCSection *, MCFragment *>()); } bool isELF() const { return Kind == SymbolKindELF; } @@ -266,7 +291,9 @@ public: /// @{ /// isVariable - Check if this is a variable symbol. - bool isVariable() const { return Value != nullptr; } + bool isVariable() const { + return SymbolContents == SymContentsVariable; + } /// getVariableValue() - Get the value for variable symbols. const MCExpr *getVariableValue() const { @@ -290,12 +317,17 @@ public: } uint64_t getOffset() const { - assert(!isCommon()); + assert((SymbolContents == SymContentsUnset || + SymbolContents == SymContentsOffset) && + "Cannot get offset for a common/variable symbol"); return Offset; } void setOffset(uint64_t Value) { - assert(!isCommon()); + assert((SymbolContents == SymContentsUnset || + SymbolContents == SymContentsOffset) && + "Cannot set offset for a common/variable symbol"); Offset = Value; + SymbolContents = SymContentsOffset; } /// Return the size of a 'common' symbol. @@ -311,13 +343,20 @@ public: void setCommon(uint64_t Size, unsigned Align) { assert(getOffset() == 0); CommonSize = Size; - CommonAlign = Align; + SymbolContents = SymContentsCommon; + + assert((!Align || isPowerOf2_32(Align)) && + "Alignment must be a power of 2"); + unsigned Log2Align = Log2_32(Align) + 1; + assert(Log2Align < (1U << NumCommonAlignmentBits) && + "Out of range alignment"); + CommonAlignLog2 = Log2Align; } /// Return the alignment of a 'common' symbol. unsigned getCommonAlignment() const { assert(isCommon() && "Not a 'common' symbol!"); - return CommonAlign; + return CommonAlignLog2 ? (1U << (CommonAlignLog2 - 1)) : 0; } /// Declare this symbol as being 'common'. @@ -328,7 +367,7 @@ public: bool declareCommon(uint64_t Size, unsigned Align) { assert(isCommon() || getOffset() == 0); if(isCommon()) { - if(CommonSize != Size || CommonAlign != Align) + if(CommonSize != Size || getCommonAlignment() != Align) return true; } else setCommon(Size, Align); @@ -336,13 +375,15 @@ public: } /// Is this a 'common' symbol. - bool isCommon() const { return CommonAlign != -1U; } + bool isCommon() const { + return SymbolContents == SymContentsCommon; + } MCFragment *getFragment() const { - return SectionOrFragment.dyn_cast<MCFragment *>(); + return SectionOrFragmentAndHasName.getPointer().dyn_cast<MCFragment *>(); } void setFragment(MCFragment *Value) const { - SectionOrFragment = Value; + SectionOrFragmentAndHasName.setPointer(Value); } bool isExternal() const { return IsExternal; } @@ -362,10 +403,14 @@ protected: uint32_t getFlags() const { return Flags; } /// Set the (implementation defined) symbol flags. - void setFlags(uint32_t Value) const { Flags = Value; } + void setFlags(uint32_t Value) const { + assert(Value < (1U << NumFlagsBits) && "Out of range flags"); + Flags = Value; + } /// Modify the flags via a mask void modifyFlags(uint32_t Value, uint32_t Mask) const { + assert(Value < (1U << NumFlagsBits) && "Out of range flags"); Flags = (Flags & ~Mask) | Value; } }; diff --git a/include/llvm/MC/MCSymbolCOFF.h b/include/llvm/MC/MCSymbolCOFF.h index 3b853f788c8d..2172c67981c0 100644 --- a/include/llvm/MC/MCSymbolCOFF.h +++ b/include/llvm/MC/MCSymbolCOFF.h @@ -59,6 +59,6 @@ public: static bool classof(const MCSymbol *S) { return S->isCOFF(); } }; -} // namespace llvm +} #endif diff --git a/include/llvm/MC/MCSymbolELF.h b/include/llvm/MC/MCSymbolELF.h index b0ce3fe158c4..bbcd22e8e7db 100644 --- a/include/llvm/MC/MCSymbolELF.h +++ b/include/llvm/MC/MCSymbolELF.h @@ -49,6 +49,6 @@ public: private: void setIsBindingSet() const; }; -} // namespace llvm +} #endif diff --git a/include/llvm/MC/MCSymbolMachO.h b/include/llvm/MC/MCSymbolMachO.h index a16208088b99..166ae9e755a1 100644 --- a/include/llvm/MC/MCSymbolMachO.h +++ b/include/llvm/MC/MCSymbolMachO.h @@ -118,6 +118,6 @@ public: static bool classof(const MCSymbol *S) { return S->isMachO(); } }; -} // namespace llvm +} #endif diff --git a/include/llvm/MC/MCSymbolizer.h b/include/llvm/MC/MCSymbolizer.h index 41c1b0d897f9..2ef17673f091 100644 --- a/include/llvm/MC/MCSymbolizer.h +++ b/include/llvm/MC/MCSymbolizer.h @@ -80,6 +80,6 @@ public: uint64_t Address) = 0; }; -} // namespace llvm +} #endif diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h index 4ee53adee599..36db3914f017 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -201,6 +201,6 @@ public: virtual void onLabelParsed(MCSymbol *Symbol) { }; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCWin64EH.h b/include/llvm/MC/MCWin64EH.h index f2211d73f60a..0e81a191cd2c 100644 --- a/include/llvm/MC/MCWin64EH.h +++ b/include/llvm/MC/MCWin64EH.h @@ -57,7 +57,7 @@ public: void Emit(MCStreamer &Streamer) const override; void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI) const override; }; -} // namespace Win64EH +} } // end namespace llvm #endif diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h index edf87f5f9cf9..e2e95c7df710 100644 --- a/include/llvm/MC/MCWinCOFFObjectWriter.h +++ b/include/llvm/MC/MCWinCOFFObjectWriter.h @@ -42,6 +42,6 @@ class raw_pwrite_stream; /// \returns The constructed object writer. MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_pwrite_stream &OS); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h index fcca838bbf17..6fbc754f1125 100644 --- a/include/llvm/MC/MCWinCOFFStreamer.h +++ b/include/llvm/MC/MCWinCOFFStreamer.h @@ -75,7 +75,7 @@ protected: private: LLVM_ATTRIBUTE_NORETURN void FatalError(const Twine &Msg) const; }; -} // namespace llvm +} #endif diff --git a/include/llvm/MC/MCWinEH.h b/include/llvm/MC/MCWinEH.h index d22791e239d5..723d7a397c49 100644 --- a/include/llvm/MC/MCWinEH.h +++ b/include/llvm/MC/MCWinEH.h @@ -78,7 +78,7 @@ public: virtual void Emit(MCStreamer &Streamer) const = 0; virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI) const = 0; }; -} // namespace WinEH -} // namespace llvm +} +} #endif diff --git a/include/llvm/MC/MachineLocation.h b/include/llvm/MC/MachineLocation.h index 1c421821ce9d..2a18615eff62 100644 --- a/include/llvm/MC/MachineLocation.h +++ b/include/llvm/MC/MachineLocation.h @@ -78,6 +78,6 @@ inline bool operator!=(const MachineLocation &LHS, const MachineLocation &RHS) { return !(LHS == RHS); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/MC/StringTableBuilder.h b/include/llvm/MC/StringTableBuilder.h index 700a8a6e340d..897d449254ea 100644 --- a/include/llvm/MC/StringTableBuilder.h +++ b/include/llvm/MC/StringTableBuilder.h @@ -62,6 +62,6 @@ private: } }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/MC/YAML.h b/include/llvm/MC/YAML.h index ae8329829a59..383cdc6785fa 100644 --- a/include/llvm/MC/YAML.h +++ b/include/llvm/MC/YAML.h @@ -89,6 +89,6 @@ template <> struct ScalarTraits<BinaryRef> { static StringRef input(StringRef, void *, BinaryRef &); static bool mustQuote(StringRef S) { return needsQuotes(S); } }; -} // namespace yaml -} // namespace llvm +} +} #endif diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index 3a52a9dc9be3..8da6919a4655 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -217,7 +217,7 @@ private: unsigned IsThin : 1; }; -} // namespace object -} // namespace llvm +} +} #endif diff --git a/include/llvm/Object/ArchiveWriter.h b/include/llvm/Object/ArchiveWriter.h index 8a394fa4f44e..1616e46d3e6f 100644 --- a/include/llvm/Object/ArchiveWriter.h +++ b/include/llvm/Object/ArchiveWriter.h @@ -46,6 +46,6 @@ std::pair<StringRef, std::error_code> writeArchive(StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers, bool WriteSymtab); -} // namespace llvm +} #endif diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index 949edf8e7811..a3d6d0d4d428 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -178,7 +178,7 @@ template <typename T> const T* OwningBinary<T>::getBinary() const { } ErrorOr<OwningBinary<Binary>> createBinary(StringRef Path); -} // namespace object -} // namespace llvm +} +} #endif diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index ad657b591fb4..fc605826a8b0 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -249,6 +249,15 @@ struct coff_symbol { typedef coff_symbol<support::ulittle16_t> coff_symbol16; typedef coff_symbol<support::ulittle32_t> coff_symbol32; +// Contains only common parts of coff_symbol16 and coff_symbol32. +struct coff_symbol_generic { + union { + char ShortName[COFF::NameSize]; + StringTableOffset Offset; + } Name; + support::ulittle32_t Value; +}; + class COFFSymbolRef { public: COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS), CS32(nullptr) {} @@ -259,6 +268,12 @@ public: return CS16 ? static_cast<const void *>(CS16) : CS32; } + const coff_symbol_generic *getGeneric() const { + if (CS16) + return reinterpret_cast<const coff_symbol_generic *>(CS16); + return reinterpret_cast<const coff_symbol_generic *>(CS32); + } + friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) { return A.getRawPtr() < B.getRawPtr(); } @@ -493,6 +508,29 @@ struct coff_load_configuration32 { support::ulittle32_t SEHandlerCount; }; +struct coff_load_configuration64 { + support::ulittle32_t Characteristics; + support::ulittle32_t TimeDateStamp; + support::ulittle16_t MajorVersion; + support::ulittle16_t MinorVersion; + support::ulittle32_t GlobalFlagsClear; + support::ulittle32_t GlobalFlagsSet; + support::ulittle32_t CriticalSectionDefaultTimeout; + support::ulittle32_t DeCommitFreeBlockThreshold; + support::ulittle32_t DeCommitTotalFreeThreshold; + support::ulittle32_t LockPrefixTable; + support::ulittle32_t MaximumAllocationSize; + support::ulittle32_t VirtualMemoryThreshold; + support::ulittle32_t ProcessAffinityMask; + support::ulittle32_t ProcessHeapFlags; + support::ulittle16_t CSDVersion; + support::ulittle16_t Reserved; + support::ulittle32_t EditList; + support::ulittle64_t SecurityCookie; + support::ulittle64_t SEHandlerTable; + support::ulittle64_t SEHandlerCount; +}; + struct coff_runtime_function_x64 { support::ulittle32_t BeginAddress; support::ulittle32_t EndAddress; @@ -609,14 +647,13 @@ public: } protected: void moveSymbolNext(DataRefImpl &Symb) const override; - std::error_code getSymbolName(DataRefImpl Symb, - StringRef &Res) const override; + ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override; std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; - uint64_t getSymbolSize(DataRefImpl Symb) const override; + uint64_t getSymbolValue(DataRefImpl Symb) const override; + uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; - std::error_code getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Res) const override; + SymbolRef::Type getSymbolType(DataRefImpl Symb) const override; std::error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const override; void moveSectionNext(DataRefImpl &Sec) const override; @@ -631,21 +668,17 @@ protected: bool isSectionData(DataRefImpl Sec) const override; bool isSectionBSS(DataRefImpl Sec) const override; bool isSectionVirtual(DataRefImpl Sec) const override; - bool sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; - std::error_code getRelocationAddress(DataRefImpl Rel, - uint64_t &Res) const override; - std::error_code getRelocationOffset(DataRefImpl Rel, - uint64_t &Res) const override; + ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const override; + uint64_t getRelocationOffset(DataRefImpl Rel) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; - std::error_code getRelocationType(DataRefImpl Rel, - uint64_t &Res) const override; - std::error_code - getRelocationTypeName(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const override; + uint64_t getRelocationType(DataRefImpl Rel) const override; + void getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl<char> &Result) const override; + public: COFFObjectFile(MemoryBufferRef Object, std::error_code &EC); basic_symbol_iterator symbol_begin_impl() const override; @@ -657,6 +690,8 @@ public: COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const; COFFSymbolRef getCOFFSymbol(const SymbolRef &Symbol) const; const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const; + unsigned getSectionID(SectionRef Sec) const; + unsigned getSymbolSectionID(SymbolRef Sym) const; uint8_t getBytesInAddress() const override; StringRef getFileFormatName() const override; @@ -720,6 +755,8 @@ public: return std::error_code(); } std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const; + std::error_code getSymbolName(const coff_symbol_generic *Symbol, + StringRef &Res) const; ArrayRef<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol) const; @@ -731,6 +768,9 @@ public: llvm_unreachable("null symbol table pointer!"); } + iterator_range<const coff_relocation *> + getRelocations(const coff_section *Sec) const; + std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const; uint64_t getSectionSize(const coff_section *Sec) const; std::error_code getSectionContents(const coff_section *Sec, diff --git a/include/llvm/Object/COFFYAML.h b/include/llvm/Object/COFFYAML.h index 5ba3db3e679d..12a25223bd37 100644 --- a/include/llvm/Object/COFFYAML.h +++ b/include/llvm/Object/COFFYAML.h @@ -37,7 +37,7 @@ inline DLLCharacteristics operator|(DLLCharacteristics a, uint16_t Ret = static_cast<uint16_t>(a) | static_cast<uint16_t>(b); return static_cast<DLLCharacteristics>(Ret); } -} // namespace COFF +} // The structure of the yaml files is not an exact 1:1 match to COFF. In order // to use yaml::IO, we use these structures which are closer to the source. @@ -87,8 +87,8 @@ namespace COFFYAML { std::vector<Symbol> Symbols; Object(); }; -} // namespace COFFYAML -} // namespace llvm +} +} LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Section) LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Symbol) diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index e87737dcce7a..3b0c548ffe15 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -143,8 +143,7 @@ public: typedef iterator_range<Elf_Dyn_Iter> Elf_Dyn_Range; typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter; typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter; - typedef ELFEntityIterator<const Elf_Shdr> Elf_Shdr_Iter; - typedef iterator_range<Elf_Shdr_Iter> Elf_Shdr_Range; + typedef iterator_range<const Elf_Shdr *> Elf_Shdr_Range; /// \brief Archive files are 2 byte aligned, so we need this for /// PointerIntPair to work. @@ -158,74 +157,7 @@ public: enum { NumLowBitsAvailable = 1 }; }; - class Elf_Sym_Iter { - public: - typedef ptrdiff_t difference_type; - typedef const Elf_Sym value_type; - typedef std::random_access_iterator_tag iterator_category; - typedef value_type &reference; - typedef value_type *pointer; - - /// \brief Default construct iterator. - Elf_Sym_Iter() : EntitySize(0), Current(0, false) {} - Elf_Sym_Iter(uintX_t EntSize, const char *Start, bool IsDynamic) - : EntitySize(EntSize), Current(Start, IsDynamic) {} - - reference operator*() { - assert(Current.getPointer() && - "Attempted to dereference an invalid iterator!"); - return *reinterpret_cast<pointer>(Current.getPointer()); - } - - pointer operator->() { - assert(Current.getPointer() && - "Attempted to dereference an invalid iterator!"); - return reinterpret_cast<pointer>(Current.getPointer()); - } - - bool operator==(const Elf_Sym_Iter &Other) { - return Current == Other.Current; - } - - bool operator!=(const Elf_Sym_Iter &Other) { return !(*this == Other); } - - Elf_Sym_Iter &operator++() { - assert(Current.getPointer() && - "Attempted to increment an invalid iterator!"); - Current.setPointer(Current.getPointer() + EntitySize); - return *this; - } - - Elf_Sym_Iter operator++(int) { - Elf_Sym_Iter Tmp = *this; - ++*this; - return Tmp; - } - - Elf_Sym_Iter operator+(difference_type Dist) { - assert(Current.getPointer() && - "Attempted to increment an invalid iterator!"); - Current.setPointer(Current.getPointer() + EntitySize * Dist); - return *this; - } - - difference_type operator-(const Elf_Sym_Iter &Other) const { - assert(EntitySize == Other.EntitySize && - "Subtracting iterators of different EntitySize!"); - return (Current.getPointer() - Other.Current.getPointer()) / EntitySize; - } - - const char *get() const { return Current.getPointer(); } - - bool isDynamic() const { return Current.getInt(); } - - uintX_t getEntSize() const { return EntitySize; } - - private: - uintX_t EntitySize; - PointerIntPair<const char *, 1, bool, - ArchivePointerTypeTraits<const char> > Current; - }; + typedef iterator_range<const Elf_Sym *> Elf_Sym_Range; private: typedef SmallVector<const Elf_Shdr *, 2> Sections_t; @@ -238,17 +170,19 @@ private: } const Elf_Ehdr *Header; - const Elf_Shdr *SectionHeaderTable; - const Elf_Shdr *dot_shstrtab_sec; // Section header string table. - const Elf_Shdr *dot_strtab_sec; // Symbol header string table. - const Elf_Shdr *dot_symtab_sec; // Symbol table section. - - const Elf_Shdr *SymbolTableSectionHeaderIndex; + const Elf_Shdr *SectionHeaderTable = nullptr; + StringRef DotShstrtab; // Section header string table. + StringRef DotStrtab; // Symbol header string table. + const Elf_Shdr *dot_symtab_sec = nullptr; // Symbol table section. + StringRef DynSymStrTab; // Dynnamic symbol string table. + const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section. + + const Elf_Shdr *SymbolTableSectionHeaderIndex = nullptr; DenseMap<const Elf_Sym *, ELF::Elf64_Word> ExtendedSymbolTable; - const Elf_Shdr *dot_gnu_version_sec; // .gnu.version - const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r - const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d + const Elf_Shdr *dot_gnu_version_sec = nullptr; // .gnu.version + const Elf_Shdr *dot_gnu_version_r_sec = nullptr; // .gnu.version_r + const Elf_Shdr *dot_gnu_version_d_sec = nullptr; // .gnu.version_d /// \brief Represents a region described by entries in the .dynamic table. struct DynRegionInfo { @@ -263,12 +197,11 @@ private: DynRegionInfo DynamicRegion; DynRegionInfo DynHashRegion; - DynRegionInfo DynStrRegion; - DynRegionInfo DynSymRegion; + DynRegionInfo DynRelaRegion; // Pointer to SONAME entry in dynamic string table // This is set the first time getLoadName is called. - mutable const char *dt_soname; + mutable const char *dt_soname = nullptr; // Records for each version index the corresponding Verdef or Vernaux entry. // This is filled the first time LoadVersionMap() is called. @@ -301,8 +234,11 @@ public: const T *getEntry(uint32_t Section, uint32_t Entry) const; template <typename T> const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const; - const char *getString(uint32_t section, uint32_t offset) const; - const char *getString(const Elf_Shdr *section, uint32_t offset) const; + + const Elf_Shdr *getDotSymtabSec() const { return dot_symtab_sec; } + const Elf_Shdr *getDotDynSymSec() const { return DotDynSymSec; } + + ErrorOr<StringRef> getStringTable(const Elf_Shdr *Section) const; const char *getDynamicString(uintX_t Offset) const; ErrorOr<StringRef> getSymbolVersion(const Elf_Shdr *section, const Elf_Sym *Symb, @@ -331,55 +267,77 @@ public: Header->getDataEncoding() == ELF::ELFDATA2LSB; } - Elf_Shdr_Iter begin_sections() const; - Elf_Shdr_Iter end_sections() const; + const Elf_Shdr *section_begin() const; + const Elf_Shdr *section_end() const; Elf_Shdr_Range sections() const { - return make_range(begin_sections(), end_sections()); + return make_range(section_begin(), section_end()); } - Elf_Sym_Iter begin_symbols() const; - Elf_Sym_Iter end_symbols() const; + const Elf_Sym *symbol_begin() const; + const Elf_Sym *symbol_end() const; + Elf_Sym_Range symbols() const { + return make_range(symbol_begin(), symbol_end()); + } - Elf_Dyn_Iter begin_dynamic_table() const; + Elf_Dyn_Iter dynamic_table_begin() const; /// \param NULLEnd use one past the first DT_NULL entry as the end instead of /// the section size. - Elf_Dyn_Iter end_dynamic_table(bool NULLEnd = false) const; + Elf_Dyn_Iter dynamic_table_end(bool NULLEnd = false) const; Elf_Dyn_Range dynamic_table(bool NULLEnd = false) const { - return make_range(begin_dynamic_table(), end_dynamic_table(NULLEnd)); + return make_range(dynamic_table_begin(), dynamic_table_end(NULLEnd)); + } + + const Elf_Sym *dynamic_symbol_begin() const { + if (!DotDynSymSec) + return nullptr; + if (DotDynSymSec->sh_entsize != sizeof(Elf_Sym)) + report_fatal_error("Invalid symbol size"); + return reinterpret_cast<const Elf_Sym *>(base() + DotDynSymSec->sh_offset); + } + + const Elf_Sym *dynamic_symbol_end() const { + if (!DotDynSymSec) + return nullptr; + return reinterpret_cast<const Elf_Sym *>(base() + DotDynSymSec->sh_offset + + DotDynSymSec->sh_size); } - Elf_Sym_Iter begin_dynamic_symbols() const { - if (DynSymRegion.Addr) - return Elf_Sym_Iter(DynSymRegion.EntSize, (const char *)DynSymRegion.Addr, - true); - return Elf_Sym_Iter(0, nullptr, true); + Elf_Sym_Range dynamic_symbols() const { + return make_range(dynamic_symbol_begin(), dynamic_symbol_end()); } - Elf_Sym_Iter end_dynamic_symbols() const { - if (DynSymRegion.Addr) - return Elf_Sym_Iter(DynSymRegion.EntSize, - (const char *)DynSymRegion.Addr + DynSymRegion.Size, - true); - return Elf_Sym_Iter(0, nullptr, true); + Elf_Rela_Iter dyn_rela_begin() const { + if (DynRelaRegion.Addr) + return Elf_Rela_Iter(DynRelaRegion.EntSize, + (const char *)DynRelaRegion.Addr); + return Elf_Rela_Iter(0, nullptr); } - Elf_Rela_Iter begin_rela(const Elf_Shdr *sec) const { + Elf_Rela_Iter dyn_rela_end() const { + if (DynRelaRegion.Addr) + return Elf_Rela_Iter( + DynRelaRegion.EntSize, + (const char *)DynRelaRegion.Addr + DynRelaRegion.Size); + return Elf_Rela_Iter(0, nullptr); + } + + Elf_Rela_Iter rela_begin(const Elf_Shdr *sec) const { return Elf_Rela_Iter(sec->sh_entsize, (const char *)(base() + sec->sh_offset)); } - Elf_Rela_Iter end_rela(const Elf_Shdr *sec) const { + Elf_Rela_Iter rela_end(const Elf_Shdr *sec) const { return Elf_Rela_Iter( sec->sh_entsize, (const char *)(base() + sec->sh_offset + sec->sh_size)); } - Elf_Rel_Iter begin_rel(const Elf_Shdr *sec) const { + Elf_Rel_Iter rel_begin(const Elf_Shdr *sec) const { return Elf_Rel_Iter(sec->sh_entsize, (const char *)(base() + sec->sh_offset)); } - Elf_Rel_Iter end_rel(const Elf_Shdr *sec) const { + Elf_Rel_Iter rel_end(const Elf_Shdr *sec) const { return Elf_Rel_Iter(sec->sh_entsize, (const char *)(base() + sec->sh_offset + sec->sh_size)); } @@ -387,12 +345,12 @@ public: /// \brief Iterate over program header table. typedef ELFEntityIterator<const Elf_Phdr> Elf_Phdr_Iter; - Elf_Phdr_Iter begin_program_headers() const { + Elf_Phdr_Iter program_header_begin() const { return Elf_Phdr_Iter(Header->e_phentsize, (const char*)base() + Header->e_phoff); } - Elf_Phdr_Iter end_program_headers() const { + Elf_Phdr_Iter program_header_end() const { return Elf_Phdr_Iter(Header->e_phentsize, (const char*)base() + Header->e_phoff + @@ -401,24 +359,17 @@ public: uint64_t getNumSections() const; uintX_t getStringTableIndex() const; - ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const; + ELF::Elf64_Word getExtendedSymbolTableIndex(const Elf_Sym *symb) const; const Elf_Ehdr *getHeader() const { return Header; } - const Elf_Shdr *getSection(const Elf_Sym *symb) const; - const Elf_Shdr *getSection(uint32_t Index) const; + ErrorOr<const Elf_Shdr *> getSection(const Elf_Sym *symb) const; + ErrorOr<const Elf_Shdr *> getSection(uint32_t Index) const; const Elf_Sym *getSymbol(uint32_t index) const; - ErrorOr<StringRef> getSymbolName(Elf_Sym_Iter Sym) const; + ErrorOr<StringRef> getStaticSymbolName(const Elf_Sym *Symb) const; + ErrorOr<StringRef> getDynamicSymbolName(const Elf_Sym *Symb) const; + ErrorOr<StringRef> getSymbolName(const Elf_Sym *Symb, bool IsDynamic) const; - /// \brief Get the name of \p Symb. - /// \param SymTab The symbol table section \p Symb is contained in. - /// \param Symb The symbol to get the name of. - /// - /// \p SymTab is used to lookup the string table to use to get the symbol's - /// name. - ErrorOr<StringRef> getSymbolName(const Elf_Shdr *SymTab, - const Elf_Sym *Symb) const; ErrorOr<StringRef> getSectionName(const Elf_Shdr *Section) const; - uint64_t getSymbolIndex(const Elf_Sym *sym) const; ErrorOr<ArrayRef<uint8_t> > getSectionContents(const Elf_Shdr *Sec) const; StringRef getLoadName() const; }; @@ -490,7 +441,7 @@ void ELFFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const { template <class ELFT> void ELFFile<ELFT>::LoadVersionMap() const { // If there is no dynamic symtab or version table, there is nothing to do. - if (!DynSymRegion.Addr || !dot_gnu_version_sec) + if (!DotDynSymSec || !dot_gnu_version_sec) return; // Has the VersionMap already been loaded? @@ -510,18 +461,19 @@ void ELFFile<ELFT>::LoadVersionMap() const { } template <class ELFT> -ELF::Elf64_Word ELFFile<ELFT>::getSymbolTableIndex(const Elf_Sym *symb) const { - if (symb->st_shndx == ELF::SHN_XINDEX) - return ExtendedSymbolTable.lookup(symb); - return symb->st_shndx; +ELF::Elf64_Word +ELFFile<ELFT>::getExtendedSymbolTableIndex(const Elf_Sym *symb) const { + assert(symb->st_shndx == ELF::SHN_XINDEX); + return ExtendedSymbolTable.lookup(symb); } template <class ELFT> -const typename ELFFile<ELFT>::Elf_Shdr * +ErrorOr<const typename ELFFile<ELFT>::Elf_Shdr *> ELFFile<ELFT>::getSection(const Elf_Sym *symb) const { - if (symb->st_shndx == ELF::SHN_XINDEX) + uint32_t Index = symb->st_shndx; + if (Index == ELF::SHN_XINDEX) return getSection(ExtendedSymbolTable.lookup(symb)); - if (symb->st_shndx >= ELF::SHN_LORESERVE) + if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE) return nullptr; return getSection(symb->st_shndx); } @@ -529,7 +481,7 @@ ELFFile<ELFT>::getSection(const Elf_Sym *symb) const { template <class ELFT> const typename ELFFile<ELFT>::Elf_Sym * ELFFile<ELFT>::getSymbol(uint32_t Index) const { - return &*(begin_symbols() + Index); + return &*(symbol_begin() + Index); } template <class ELFT> @@ -584,20 +536,14 @@ std::pair<const typename ELFFile<ELFT>::Elf_Shdr *, ELFFile<ELFT>::getRelocationSymbol(const Elf_Shdr *Sec, const RelT *Rel) const { if (!Sec->sh_link) return std::make_pair(nullptr, nullptr); - const Elf_Shdr *SymTable = getSection(Sec->sh_link); + ErrorOr<const Elf_Shdr *> SymTableOrErr = getSection(Sec->sh_link); + if (std::error_code EC = SymTableOrErr.getError()) + report_fatal_error(EC.message()); + const Elf_Shdr *SymTable = *SymTableOrErr; return std::make_pair( SymTable, getEntry<Elf_Sym>(SymTable, Rel->getSymbol(isMips64EL()))); } -// Verify that the last byte in the string table in a null. -template <class ELFT> -void ELFFile<ELFT>::VerifyStrTab(const Elf_Shdr *sh) const { - const char *strtab = (const char *)base() + sh->sh_offset; - if (strtab[sh->sh_size - 1] != 0) - // FIXME: Proper error handling. - report_fatal_error("String table must end with a null terminator!"); -} - template <class ELFT> uint64_t ELFFile<ELFT>::getNumSections() const { assert(Header && "Header not initialized!"); @@ -621,11 +567,7 @@ typename ELFFile<ELFT>::uintX_t ELFFile<ELFT>::getStringTableIndex() const { template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) - : Buf(Object), SectionHeaderTable(nullptr), dot_shstrtab_sec(nullptr), - dot_strtab_sec(nullptr), dot_symtab_sec(nullptr), - SymbolTableSectionHeaderIndex(nullptr), dot_gnu_version_sec(nullptr), - dot_gnu_version_r_sec(nullptr), dot_gnu_version_d_sec(nullptr), - dt_soname(nullptr) { + : Buf(Object) { const uint64_t FileSize = Buf.size(); if (sizeof(Elf_Ehdr) > FileSize) { @@ -670,28 +612,35 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) } SymbolTableSectionHeaderIndex = &Sec; break; - case ELF::SHT_SYMTAB: + case ELF::SHT_SYMTAB: { if (dot_symtab_sec) { // More than one .symtab! EC = object_error::parse_failed; return; } dot_symtab_sec = &Sec; - dot_strtab_sec = getSection(Sec.sh_link); - break; + ErrorOr<const Elf_Shdr *> SectionOrErr = getSection(Sec.sh_link); + if ((EC = SectionOrErr.getError())) + return; + ErrorOr<StringRef> SymtabOrErr = getStringTable(*SectionOrErr); + if ((EC = SymtabOrErr.getError())) + return; + DotStrtab = *SymtabOrErr; + } break; case ELF::SHT_DYNSYM: { - if (DynSymRegion.Addr) { + if (DotDynSymSec) { // More than one .dynsym! EC = object_error::parse_failed; return; } - DynSymRegion.Addr = base() + Sec.sh_offset; - DynSymRegion.Size = Sec.sh_size; - DynSymRegion.EntSize = Sec.sh_entsize; - const Elf_Shdr *DynStr = getSection(Sec.sh_link); - DynStrRegion.Addr = base() + DynStr->sh_offset; - DynStrRegion.Size = DynStr->sh_size; - DynStrRegion.EntSize = DynStr->sh_entsize; + DotDynSymSec = &Sec; + ErrorOr<const Elf_Shdr *> SectionOrErr = getSection(Sec.sh_link); + if ((EC = SectionOrErr.getError())) + return; + ErrorOr<StringRef> SymtabOrErr = getStringTable(*SectionOrErr); + if ((EC = SymtabOrErr.getError())) + return; + DynSymStrTab = *SymtabOrErr; break; } case ELF::SHT_DYNAMIC: @@ -732,27 +681,29 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) } // Get string table sections. - dot_shstrtab_sec = getSection(getStringTableIndex()); - if (dot_shstrtab_sec) { - // Verify that the last byte in the string table in a null. - VerifyStrTab(dot_shstrtab_sec); - } + ErrorOr<const Elf_Shdr *> StrTabSecOrErr = getSection(getStringTableIndex()); + if ((EC = StrTabSecOrErr.getError())) + return; + + ErrorOr<StringRef> SymtabOrErr = getStringTable(*StrTabSecOrErr); + if ((EC = SymtabOrErr.getError())) + return; + DotShstrtab = *SymtabOrErr; // Build symbol name side-mapping if there is one. if (SymbolTableSectionHeaderIndex) { const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() + SymbolTableSectionHeaderIndex->sh_offset); - for (Elf_Sym_Iter SI = begin_symbols(), SE = end_symbols(); SI != SE; - ++SI) { + for (const Elf_Sym &S : symbols()) { if (*ShndxTable != ELF::SHN_UNDEF) - ExtendedSymbolTable[&*SI] = *ShndxTable; + ExtendedSymbolTable[&S] = *ShndxTable; ++ShndxTable; } } // Scan program headers. - for (Elf_Phdr_Iter PhdrI = begin_program_headers(), - PhdrE = end_program_headers(); + for (Elf_Phdr_Iter PhdrI = program_header_begin(), + PhdrE = program_header_end(); PhdrI != PhdrE; ++PhdrI) { if (PhdrI->p_type == ELF::PT_DYNAMIC) { DynamicRegion.Addr = base() + PhdrI->p_offset; @@ -762,55 +713,74 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) } } - EC = std::error_code(); -} + // Scan dynamic table. + for (Elf_Dyn_Iter DynI = dynamic_table_begin(), DynE = dynamic_table_end(); + DynI != DynE; ++DynI) { + switch (DynI->d_tag) { + case ELF::DT_RELA: { + uint64_t VBase = 0; + const uint8_t *FBase = nullptr; + for (Elf_Phdr_Iter PhdrI = program_header_begin(), + PhdrE = program_header_end(); + PhdrI != PhdrE; ++PhdrI) { + if (PhdrI->p_type != ELF::PT_LOAD) + continue; + if (DynI->getPtr() >= PhdrI->p_vaddr && + DynI->getPtr() < PhdrI->p_vaddr + PhdrI->p_memsz) { + VBase = PhdrI->p_vaddr; + FBase = base() + PhdrI->p_offset; + break; + } + } + if (!VBase) + return; + DynRelaRegion.Addr = FBase + DynI->getPtr() - VBase; + break; + } + case ELF::DT_RELASZ: + DynRelaRegion.Size = DynI->getVal(); + break; + case ELF::DT_RELAENT: + DynRelaRegion.EntSize = DynI->getVal(); + } + } -// Get the symbol table index in the symtab section given a symbol -template <class ELFT> -uint64_t ELFFile<ELFT>::getSymbolIndex(const Elf_Sym *Sym) const { - uintptr_t SymLoc = uintptr_t(Sym); - uintptr_t SymTabLoc = uintptr_t(base() + dot_symtab_sec->sh_offset); - assert(SymLoc > SymTabLoc && "Symbol not in symbol table!"); - uint64_t SymOffset = SymLoc - SymTabLoc; - assert(SymOffset % dot_symtab_sec->sh_entsize == 0 && - "Symbol not multiple of symbol size!"); - return SymOffset / dot_symtab_sec->sh_entsize; + EC = std::error_code(); } template <class ELFT> -typename ELFFile<ELFT>::Elf_Shdr_Iter ELFFile<ELFT>::begin_sections() const { - return Elf_Shdr_Iter(Header->e_shentsize, - (const char *)base() + Header->e_shoff); +const typename ELFFile<ELFT>::Elf_Shdr *ELFFile<ELFT>::section_begin() const { + if (Header->e_shentsize != sizeof(Elf_Shdr)) + report_fatal_error( + "Invalid section header entry size (e_shentsize) in ELF header"); + return reinterpret_cast<const Elf_Shdr *>(base() + Header->e_shoff); } template <class ELFT> -typename ELFFile<ELFT>::Elf_Shdr_Iter ELFFile<ELFT>::end_sections() const { - return Elf_Shdr_Iter(Header->e_shentsize, - (const char *)base() + Header->e_shoff + - (getNumSections() * Header->e_shentsize)); +const typename ELFFile<ELFT>::Elf_Shdr *ELFFile<ELFT>::section_end() const { + return section_begin() + getNumSections(); } template <class ELFT> -typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::begin_symbols() const { +const typename ELFFile<ELFT>::Elf_Sym *ELFFile<ELFT>::symbol_begin() const { if (!dot_symtab_sec) - return Elf_Sym_Iter(0, nullptr, false); - return Elf_Sym_Iter(dot_symtab_sec->sh_entsize, - (const char *)base() + dot_symtab_sec->sh_offset, false); + return nullptr; + if (dot_symtab_sec->sh_entsize != sizeof(Elf_Sym)) + report_fatal_error("Invalid symbol size"); + return reinterpret_cast<const Elf_Sym *>(base() + dot_symtab_sec->sh_offset); } template <class ELFT> -typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::end_symbols() const { +const typename ELFFile<ELFT>::Elf_Sym *ELFFile<ELFT>::symbol_end() const { if (!dot_symtab_sec) - return Elf_Sym_Iter(0, nullptr, false); - return Elf_Sym_Iter(dot_symtab_sec->sh_entsize, - (const char *)base() + dot_symtab_sec->sh_offset + - dot_symtab_sec->sh_size, - false); + return nullptr; + return reinterpret_cast<const Elf_Sym *>(base() + dot_symtab_sec->sh_offset + + dot_symtab_sec->sh_size); } template <class ELFT> typename ELFFile<ELFT>::Elf_Dyn_Iter -ELFFile<ELFT>::begin_dynamic_table() const { +ELFFile<ELFT>::dynamic_table_begin() const { if (DynamicRegion.Addr) return Elf_Dyn_Iter(DynamicRegion.EntSize, (const char *)DynamicRegion.Addr); @@ -819,14 +789,14 @@ ELFFile<ELFT>::begin_dynamic_table() const { template <class ELFT> typename ELFFile<ELFT>::Elf_Dyn_Iter -ELFFile<ELFT>::end_dynamic_table(bool NULLEnd) const { +ELFFile<ELFT>::dynamic_table_end(bool NULLEnd) const { if (!DynamicRegion.Addr) return Elf_Dyn_Iter(0, nullptr); Elf_Dyn_Iter Ret(DynamicRegion.EntSize, (const char *)DynamicRegion.Addr + DynamicRegion.Size); if (NULLEnd) { - Elf_Dyn_Iter Start = begin_dynamic_table(); + Elf_Dyn_Iter Start = dynamic_table_begin(); while (Start != Ret && Start->getTag() != ELF::DT_NULL) ++Start; @@ -855,7 +825,10 @@ StringRef ELFFile<ELFT>::getLoadName() const { template <class ELFT> template <typename T> const T *ELFFile<ELFT>::getEntry(uint32_t Section, uint32_t Entry) const { - return getEntry<T>(getSection(Section), Entry); + ErrorOr<const Elf_Shdr *> Sec = getSection(Section); + if (std::error_code EC = Sec.getError()) + report_fatal_error(EC.message()); + return getEntry<T>(*Sec, Entry); } template <class ELFT> @@ -867,82 +840,85 @@ const T *ELFFile<ELFT>::getEntry(const Elf_Shdr *Section, } template <class ELFT> -const typename ELFFile<ELFT>::Elf_Shdr * -ELFFile<ELFT>::getSection(uint32_t index) const { - if (index == 0) - return nullptr; - if (!SectionHeaderTable || index >= getNumSections()) - // FIXME: Proper error handling. - report_fatal_error("Invalid section index!"); +ErrorOr<const typename ELFFile<ELFT>::Elf_Shdr *> +ELFFile<ELFT>::getSection(uint32_t Index) const { + assert(SectionHeaderTable && "SectionHeaderTable not initialized!"); + if (Index >= getNumSections()) + return object_error::invalid_section_index; return reinterpret_cast<const Elf_Shdr *>( - reinterpret_cast<const char *>(SectionHeaderTable) - + (index * Header->e_shentsize)); + reinterpret_cast<const char *>(SectionHeaderTable) + + (Index * Header->e_shentsize)); } template <class ELFT> -const char *ELFFile<ELFT>::getString(uint32_t section, - ELF::Elf32_Word offset) const { - return getString(getSection(section), offset); -} - -template <class ELFT> -const char *ELFFile<ELFT>::getString(const Elf_Shdr *section, - ELF::Elf32_Word offset) const { - assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!"); - if (offset >= section->sh_size) - // FIXME: Proper error handling. - report_fatal_error("Symbol name offset outside of string table!"); - return (const char *)base() + section->sh_offset + offset; +ErrorOr<StringRef> +ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const { + if (Section->sh_type != ELF::SHT_STRTAB) + return object_error::parse_failed; + uint64_t Offset = Section->sh_offset; + uint64_t Size = Section->sh_size; + if (Offset + Size > Buf.size()) + return object_error::parse_failed; + StringRef Data((const char *)base() + Section->sh_offset, Size); + if (Data[Size - 1] != '\0') + return object_error::string_table_non_null_end; + return Data; } template <class ELFT> const char *ELFFile<ELFT>::getDynamicString(uintX_t Offset) const { - if (!DynStrRegion.Addr || Offset >= DynStrRegion.Size) + if (!DotDynSymSec || Offset >= DynSymStrTab.size()) return nullptr; - return (const char *)DynStrRegion.Addr + Offset; + return (const char *)DynSymStrTab.begin() + Offset; } template <class ELFT> -ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(Elf_Sym_Iter Sym) const { - if (!Sym.isDynamic()) - return getSymbolName(dot_symtab_sec, &*Sym); - - if (!DynStrRegion.Addr || Sym->st_name >= DynStrRegion.Size) - return object_error::parse_failed; - return StringRef(getDynamicString(Sym->st_name)); +ErrorOr<StringRef> +ELFFile<ELFT>::getStaticSymbolName(const Elf_Sym *Symb) const { + return Symb->getName(DotStrtab); } template <class ELFT> -ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(const Elf_Shdr *Section, - const Elf_Sym *Symb) const { - if (Symb->st_name == 0) - return StringRef(""); +ErrorOr<StringRef> +ELFFile<ELFT>::getDynamicSymbolName(const Elf_Sym *Symb) const { + return StringRef(getDynamicString(Symb->st_name)); +} - const Elf_Shdr *StrTab = getSection(Section->sh_link); - if (Symb->st_name >= StrTab->sh_size) - return object_error::parse_failed; - return StringRef(getString(StrTab, Symb->st_name)); +template <class ELFT> +ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(const Elf_Sym *Symb, + bool IsDynamic) const { + if (IsDynamic) + return getDynamicSymbolName(Symb); + return getStaticSymbolName(Symb); } template <class ELFT> ErrorOr<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section) const { - if (Section->sh_name >= dot_shstrtab_sec->sh_size) + uint32_t Offset = Section->sh_name; + if (Offset >= DotShstrtab.size()) return object_error::parse_failed; - return StringRef(getString(dot_shstrtab_sec, Section->sh_name)); + return StringRef(DotShstrtab.data() + Offset); } template <class ELFT> ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section, const Elf_Sym *symb, bool &IsDefault) const { + StringRef StrTab; + if (section) { + ErrorOr<StringRef> StrTabOrErr = getStringTable(section); + if (std::error_code EC = StrTabOrErr.getError()) + return EC; + StrTab = *StrTabOrErr; + } // Handle non-dynamic symbols. - if (section != DynSymRegion.Addr && section != nullptr) { + if (section != DotDynSymSec && section != nullptr) { // Non-dynamic symbols can have versions in their names // A name of the form 'foo@V1' indicates version 'V1', non-default. // A name of the form 'foo@@V2' indicates version 'V2', default version. - ErrorOr<StringRef> SymName = getSymbolName(section, symb); + ErrorOr<StringRef> SymName = symb->getName(StrTab); if (!SymName) return SymName; StringRef Name = *SymName; @@ -969,8 +945,10 @@ ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section, } // Determine the position in the symbol table of this entry. - size_t entry_index = ((const char *)symb - (const char *)DynSymRegion.Addr) / - DynSymRegion.EntSize; + size_t entry_index = + (reinterpret_cast<uintptr_t>(symb) - DotDynSymSec->sh_offset - + reinterpret_cast<uintptr_t>(base())) / + sizeof(Elf_Sym); // Get the corresponding version index entry const Elf_Versym *vs = getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index); @@ -1005,7 +983,7 @@ ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section, IsDefault = false; } - if (name_offset >= DynStrRegion.Size) + if (name_offset >= DynSymStrTab.size()) return object_error::parse_failed; return StringRef(getDynamicString(name_offset)); } diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 7fc56adff1df..5b9b113a2f0b 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -35,27 +35,148 @@ namespace llvm { namespace object { +class elf_symbol_iterator; +class ELFSymbolRef; +class ELFRelocationRef; + class ELFObjectFileBase : public ObjectFile { + friend class ELFSymbolRef; + friend class ELFSectionRef; + friend class ELFRelocationRef; + protected: ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source); -public: - virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0; + virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; + virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0; + virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0; - // FIXME: This is a bit of a hack. Every caller should know if it expecting - // and addend or not. - virtual bool hasRelocationAddend(DataRefImpl Rel) const = 0; + virtual uint32_t getSectionType(DataRefImpl Sec) const = 0; + virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0; - virtual std::pair<symbol_iterator, symbol_iterator> - getELFDynamicSymbolIterators() const = 0; + virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0; +public: - virtual uint64_t getSectionFlags(SectionRef Sec) const = 0; - virtual uint32_t getSectionType(SectionRef Sec) const = 0; + typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range; + virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0; + + elf_symbol_iterator_range symbols() const; static inline bool classof(const Binary *v) { return v->isELF(); } }; +class ELFSectionRef : public SectionRef { +public: + ELFSectionRef(const SectionRef &B) : SectionRef(B) { + assert(isa<ELFObjectFileBase>(SectionRef::getObject())); + } + + const ELFObjectFileBase *getObject() const { + return cast<ELFObjectFileBase>(SectionRef::getObject()); + } + + uint32_t getType() const { + return getObject()->getSectionType(getRawDataRefImpl()); + } + + uint64_t getFlags() const { + return getObject()->getSectionFlags(getRawDataRefImpl()); + } +}; + +class elf_section_iterator : public section_iterator { +public: + elf_section_iterator(const section_iterator &B) : section_iterator(B) { + assert(isa<ELFObjectFileBase>(B->getObject())); + } + + const ELFSectionRef *operator->() const { + return static_cast<const ELFSectionRef *>(section_iterator::operator->()); + } + + const ELFSectionRef &operator*() const { + return static_cast<const ELFSectionRef &>(section_iterator::operator*()); + } +}; + +class ELFSymbolRef : public SymbolRef { +public: + ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) { + assert(isa<ELFObjectFileBase>(SymbolRef::getObject())); + } + + const ELFObjectFileBase *getObject() const { + return cast<ELFObjectFileBase>(BasicSymbolRef::getObject()); + } + + uint64_t getSize() const { + return getObject()->getSymbolSize(getRawDataRefImpl()); + } + + uint8_t getOther() const { + return getObject()->getSymbolOther(getRawDataRefImpl()); + } + + uint8_t getELFType() const { + return getObject()->getSymbolELFType(getRawDataRefImpl()); + } +}; + +class elf_symbol_iterator : public symbol_iterator { +public: + elf_symbol_iterator(const basic_symbol_iterator &B) + : symbol_iterator(SymbolRef(B->getRawDataRefImpl(), + cast<ELFObjectFileBase>(B->getObject()))) {} + + const ELFSymbolRef *operator->() const { + return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->()); + } + + const ELFSymbolRef &operator*() const { + return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*()); + } +}; + +class ELFRelocationRef : public RelocationRef { +public: + ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) { + assert(isa<ELFObjectFileBase>(RelocationRef::getObject())); + } + + const ELFObjectFileBase *getObject() const { + return cast<ELFObjectFileBase>(RelocationRef::getObject()); + } + + ErrorOr<int64_t> getAddend() const { + return getObject()->getRelocationAddend(getRawDataRefImpl()); + } +}; + +class elf_relocation_iterator : public relocation_iterator { +public: + elf_relocation_iterator(const relocation_iterator &B) + : relocation_iterator(RelocationRef( + B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {} + + const ELFRelocationRef *operator->() const { + return static_cast<const ELFRelocationRef *>( + relocation_iterator::operator->()); + } + + const ELFRelocationRef &operator*() const { + return static_cast<const ELFRelocationRef &>( + relocation_iterator::operator*()); + } +}; + +inline ELFObjectFileBase::elf_symbol_iterator_range +ELFObjectFileBase::symbols() const { + return elf_symbol_iterator_range(symbol_begin(), symbol_end()); +} + template <class ELFT> class ELFObjectFile : public ELFObjectFileBase { + uint64_t getSymbolSize(DataRefImpl Sym) const override; + public: LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) @@ -68,24 +189,22 @@ public: typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela; typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; - typedef typename ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter; - typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter; typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter; protected: ELFFile<ELFT> EF; void moveSymbolNext(DataRefImpl &Symb) const override; - std::error_code getSymbolName(DataRefImpl Symb, - StringRef &Res) const override; + ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override; std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; + uint64_t getSymbolValue(DataRefImpl Symb) const override; uint32_t getSymbolAlignment(DataRefImpl Symb) const override; - uint64_t getSymbolSize(DataRefImpl Symb) const override; + uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; - std::error_code getSymbolOther(DataRefImpl Symb, uint8_t &Res) const override; - std::error_code getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Res) const override; + uint8_t getSymbolOther(DataRefImpl Symb) const override; + uint8_t getSymbolELFType(DataRefImpl Symb) const override; + SymbolRef::Type getSymbolType(DataRefImpl Symb) const override; section_iterator getSymbolSection(const Elf_Sym *Symb) const; std::error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const override; @@ -102,62 +221,55 @@ protected: bool isSectionData(DataRefImpl Sec) const override; bool isSectionBSS(DataRefImpl Sec) const override; bool isSectionVirtual(DataRefImpl Sec) const override; - bool sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; section_iterator getRelocatedSection(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; - std::error_code getRelocationAddress(DataRefImpl Rel, - uint64_t &Res) const override; - std::error_code getRelocationOffset(DataRefImpl Rel, - uint64_t &Res) const override; + ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const override; + uint64_t getRelocationOffset(DataRefImpl Rel) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; - std::error_code getRelocationType(DataRefImpl Rel, - uint64_t &Res) const override; - std::error_code - getRelocationTypeName(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const override; + uint64_t getRelocationType(DataRefImpl Rel) const override; + void getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl<char> &Result) const override; + uint32_t getSectionType(DataRefImpl Sec) const override; + uint64_t getSectionFlags(DataRefImpl Sec) const override; uint64_t getROffset(DataRefImpl Rel) const; StringRef getRelocationTypeName(uint32_t Type) const; /// \brief Get the relocation section that contains \a Rel. const Elf_Shdr *getRelSection(DataRefImpl Rel) const { - return EF.getSection(Rel.d.a); + return *EF.getSection(Rel.d.a); } - const Elf_Rel *getRel(DataRefImpl Rel) const; - const Elf_Rela *getRela(DataRefImpl Rela) const; - - Elf_Sym_Iter toELFSymIter(DataRefImpl Symb) const { - bool IsDynamic = Symb.p & 1; - if (IsDynamic) - return Elf_Sym_Iter( - EF.begin_dynamic_symbols().getEntSize(), - reinterpret_cast<const char *>(Symb.p & ~uintptr_t(1)), IsDynamic); - return Elf_Sym_Iter(EF.begin_symbols().getEntSize(), - reinterpret_cast<const char *>(Symb.p), IsDynamic); + const Elf_Sym *toELFSymIter(DataRefImpl Sym) const { + return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b); } - DataRefImpl toDRI(Elf_Sym_Iter Symb) const { + DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const { DataRefImpl DRI; - DRI.p = reinterpret_cast<uintptr_t>(Symb.get()) | - static_cast<uintptr_t>(Symb.isDynamic()); - return DRI; - } + if (!SymTable) { + DRI.d.a = 0; + DRI.d.b = 0; + return DRI; + } + assert(SymTable->sh_type == ELF::SHT_SYMTAB || + SymTable->sh_type == ELF::SHT_DYNSYM); - Elf_Shdr_Iter toELFShdrIter(DataRefImpl Sec) const { - return Elf_Shdr_Iter(EF.getHeader()->e_shentsize, - reinterpret_cast<const char *>(Sec.p)); - } + uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin()); + unsigned SymTableIndex = + (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr); - DataRefImpl toDRI(Elf_Shdr_Iter Sec) const { - DataRefImpl DRI; - DRI.p = reinterpret_cast<uintptr_t>(Sec.get()); + DRI.d.a = SymTableIndex; + DRI.d.b = SymbolNum; return DRI; } + const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const { + return reinterpret_cast<const Elf_Shdr *>(Sec.p); + } + DataRefImpl toDRI(const Elf_Shdr *Sec) const { DataRefImpl DRI; DRI.p = reinterpret_cast<uintptr_t>(Sec); @@ -197,22 +309,21 @@ protected: public: ELFObjectFile(MemoryBufferRef Object, std::error_code &EC); + const Elf_Rel *getRel(DataRefImpl Rel) const; + const Elf_Rela *getRela(DataRefImpl Rela) const; + const Elf_Sym *getSymbol(DataRefImpl Symb) const; basic_symbol_iterator symbol_begin_impl() const override; basic_symbol_iterator symbol_end_impl() const override; - symbol_iterator dynamic_symbol_begin() const; - symbol_iterator dynamic_symbol_end() const; + elf_symbol_iterator dynamic_symbol_begin() const; + elf_symbol_iterator dynamic_symbol_end() const; section_iterator section_begin() const override; section_iterator section_end() const override; ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const override; - bool hasRelocationAddend(DataRefImpl Rel) const override; - - uint64_t getSectionFlags(SectionRef Sec) const override; - uint32_t getSectionType(SectionRef Sec) const override; uint8_t getBytesInAddress() const override; StringRef getFileFormatName() const override; @@ -232,8 +343,7 @@ public: ELFT::Is64Bits); } - std::pair<symbol_iterator, symbol_iterator> - getELFDynamicSymbolIterators() const override; + elf_symbol_iterator_range getDynamicSymbolIterators() const override; bool isRelocatableObject() const override; }; @@ -244,59 +354,71 @@ typedef ELFObjectFile<ELFType<support::big, false>> ELF32BEObjectFile; typedef ELFObjectFile<ELFType<support::big, true>> ELF64BEObjectFile; template <class ELFT> -void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Symb) const { - Symb = toDRI(++toELFSymIter(Symb)); +void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const { + ++Sym.d.b; } template <class ELFT> -std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb, - StringRef &Result) const { - ErrorOr<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb)); - if (!Name) - return Name.getError(); - Result = *Name; - return std::error_code(); +ErrorOr<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const { + const Elf_Sym *ESym = toELFSymIter(Sym); + const Elf_Shdr *SymTableSec = *EF.getSection(Sym.d.a); + const Elf_Shdr *StringTableSec = *EF.getSection(SymTableSec->sh_link); + StringRef SymTable = *EF.getStringTable(StringTableSec); + return ESym->getName(SymTable); } template <class ELFT> -uint64_t ELFObjectFile<ELFT>::getSectionFlags(SectionRef Sec) const { - DataRefImpl DRI = Sec.getRawDataRefImpl(); - return toELFShdrIter(DRI)->sh_flags; +uint64_t ELFObjectFile<ELFT>::getSectionFlags(DataRefImpl Sec) const { + return toELFShdrIter(Sec)->sh_flags; } template <class ELFT> -uint32_t ELFObjectFile<ELFT>::getSectionType(SectionRef Sec) const { - DataRefImpl DRI = Sec.getRawDataRefImpl(); - return toELFShdrIter(DRI)->sh_type; +uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const { + return toELFShdrIter(Sec)->sh_type; } template <class ELFT> -std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, - uint64_t &Result) const { +uint64_t ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb) const { const Elf_Sym *ESym = getSymbol(Symb); - switch (EF.getSymbolTableIndex(ESym)) { + switch (ESym->st_shndx) { case ELF::SHN_COMMON: case ELF::SHN_UNDEF: - Result = UnknownAddressOrSize; - return std::error_code(); + return UnknownAddress; case ELF::SHN_ABS: - Result = ESym->st_value; - return std::error_code(); - default: - break; + return ESym->st_value; } const Elf_Ehdr *Header = EF.getHeader(); - Result = ESym->st_value; + uint64_t Ret = ESym->st_value; // Clear the ARM/Thumb or microMIPS indicator flag. if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) && ESym->getType() == ELF::STT_FUNC) - Result &= ~1; + Ret &= ~1; + + return Ret; +} + +template <class ELFT> +std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, + uint64_t &Result) const { + Result = getSymbolValue(Symb); + const Elf_Sym *ESym = getSymbol(Symb); + switch (ESym->st_shndx) { + case ELF::SHN_COMMON: + case ELF::SHN_UNDEF: + case ELF::SHN_ABS: + return std::error_code(); + } + + const Elf_Ehdr *Header = EF.getHeader(); if (Header->e_type == ELF::ET_REL) { - const typename ELFFile<ELFT>::Elf_Shdr * Section = EF.getSection(ESym); - if (Section != nullptr) + ErrorOr<const Elf_Shdr *> SectionOrErr = EF.getSection(ESym); + if (std::error_code EC = SectionOrErr.getError()) + return EC; + const Elf_Shdr *Section = *SectionOrErr; + if (Section) Result += Section->sh_addr; } @@ -305,59 +427,57 @@ std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, template <class ELFT> uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const { - Elf_Sym_Iter Sym = toELFSymIter(Symb); + const Elf_Sym *Sym = toELFSymIter(Symb); if (Sym->st_shndx == ELF::SHN_COMMON) return Sym->st_value; return 0; } template <class ELFT> -uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb) const { +uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const { + return toELFSymIter(Sym)->st_size; +} + +template <class ELFT> +uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const { return toELFSymIter(Symb)->st_size; } template <class ELFT> -std::error_code ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb, - uint8_t &Result) const { - Result = toELFSymIter(Symb)->st_other; - return std::error_code(); +uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const { + return toELFSymIter(Symb)->st_other; } template <class ELFT> -std::error_code -ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Result) const { +uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const { + return toELFSymIter(Symb)->getType(); +} + +template <class ELFT> +SymbolRef::Type ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const { const Elf_Sym *ESym = getSymbol(Symb); switch (ESym->getType()) { case ELF::STT_NOTYPE: - Result = SymbolRef::ST_Unknown; - break; + return SymbolRef::ST_Unknown; case ELF::STT_SECTION: - Result = SymbolRef::ST_Debug; - break; + return SymbolRef::ST_Debug; case ELF::STT_FILE: - Result = SymbolRef::ST_File; - break; + return SymbolRef::ST_File; case ELF::STT_FUNC: - Result = SymbolRef::ST_Function; - break; + return SymbolRef::ST_Function; case ELF::STT_OBJECT: case ELF::STT_COMMON: case ELF::STT_TLS: - Result = SymbolRef::ST_Data; - break; + return SymbolRef::ST_Data; default: - Result = SymbolRef::ST_Other; - break; + return SymbolRef::ST_Other; } - return std::error_code(); } template <class ELFT> -uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const { - Elf_Sym_Iter EIter = toELFSymIter(Symb); - const Elf_Sym *ESym = &*EIter; +uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const { + const Elf_Sym *ESym = toELFSymIter(Sym); uint32_t Result = SymbolRef::SF_None; @@ -371,14 +491,22 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const { Result |= SymbolRef::SF_Absolute; if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION || - EIter == EF.begin_symbols() || EIter == EF.begin_dynamic_symbols()) + ESym == EF.symbol_begin() || ESym == EF.dynamic_symbol_begin()) Result |= SymbolRef::SF_FormatSpecific; - if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF) + if (EF.getHeader()->e_machine == ELF::EM_ARM) { + if (ErrorOr<StringRef> NameOrErr = getSymbolName(Sym)) { + StringRef Name = *NameOrErr; + if (Name.startswith("$d") || Name.startswith("$t") || + Name.startswith("$a")) + Result |= SymbolRef::SF_FormatSpecific; + } + } + + if (ESym->st_shndx == ELF::SHN_UNDEF) Result |= SymbolRef::SF_Undefined; - if (ESym->getType() == ELF::STT_COMMON || - EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON) + if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON) Result |= SymbolRef::SF_Common; if (isExportedToOtherDSO(ESym)) @@ -393,14 +521,17 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const { template <class ELFT> section_iterator ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym) const { - const Elf_Shdr *ESec = EF.getSection(ESym); + ErrorOr<const Elf_Shdr *> ESecOrErr = EF.getSection(ESym); + if (std::error_code EC = ESecOrErr.getError()) + report_fatal_error(EC.message()); + + const Elf_Shdr *ESec = *ESecOrErr; if (!ESec) return section_end(); - else { - DataRefImpl Sec; - Sec.p = reinterpret_cast<intptr_t>(ESec); - return section_iterator(SectionRef(Sec, this)); - } + + DataRefImpl Sec; + Sec.p = reinterpret_cast<intptr_t>(ESec); + return section_iterator(SectionRef(Sec, this)); } template <class ELFT> @@ -413,7 +544,8 @@ ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, template <class ELFT> void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const { - Sec = toDRI(++toELFShdrIter(Sec)); + const Elf_Shdr *ESec = toELFShdrIter(Sec); + Sec = toDRI(++ESec); } template <class ELFT> @@ -440,7 +572,7 @@ template <class ELFT> std::error_code ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec, StringRef &Result) const { - Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); + const Elf_Shdr *EShdr = toELFShdrIter(Sec); Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size); return std::error_code(); } @@ -457,14 +589,14 @@ bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const { template <class ELFT> bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const { - Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); + const Elf_Shdr *EShdr = toELFShdrIter(Sec); return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && EShdr->sh_type == ELF::SHT_PROGBITS; } template <class ELFT> bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const { - Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); + const Elf_Shdr *EShdr = toELFShdrIter(Sec); return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && EShdr->sh_type == ELF::SHT_NOBITS; } @@ -475,38 +607,40 @@ bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const { } template <class ELFT> -bool ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec, - DataRefImpl Symb) const { - Elf_Sym_Iter ESym = toELFSymIter(Symb); - - uintX_t Index = ESym->st_shndx; - bool Reserved = Index >= ELF::SHN_LORESERVE && Index <= ELF::SHN_HIRESERVE; - - return !Reserved && (&*toELFShdrIter(Sec) == EF.getSection(ESym->st_shndx)); -} - -template <class ELFT> relocation_iterator ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const { DataRefImpl RelData; - uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get()); + uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin()); RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize; RelData.d.b = 0; + + const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p); + if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL) + return relocation_iterator(RelocationRef(RelData, this)); + + const Elf_Shdr *RelSec = getRelSection(RelData); + ErrorOr<const Elf_Shdr *> SymSecOrErr = EF.getSection(RelSec->sh_link); + if (std::error_code EC = SymSecOrErr.getError()) + report_fatal_error(EC.message()); + const Elf_Shdr *SymSec = *SymSecOrErr; + uint32_t SymSecType = SymSec->sh_type; + if (SymSecType != ELF::SHT_SYMTAB && SymSecType != ELF::SHT_DYNSYM) + report_fatal_error("Invalid symbol table section type!"); + if (SymSecType == ELF::SHT_DYNSYM) + RelData.d.b = 1; + return relocation_iterator(RelocationRef(RelData, this)); } template <class ELFT> relocation_iterator ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const { - DataRefImpl RelData; - uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get()); const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p); - RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize; + relocation_iterator Begin = section_rel_begin(Sec); if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL) - RelData.d.b = 0; - else - RelData.d.b = S->sh_size / S->sh_entsize; - + return Begin; + DataRefImpl RelData = Begin->getRawDataRefImpl(); + RelData.d.b += (S->sh_size / S->sh_entsize) << 1; return relocation_iterator(RelocationRef(RelData, this)); } @@ -516,19 +650,21 @@ ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const { if (EF.getHeader()->e_type != ELF::ET_REL) return section_end(); - Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); + const Elf_Shdr *EShdr = toELFShdrIter(Sec); uintX_t Type = EShdr->sh_type; if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA) return section_end(); - const Elf_Shdr *R = EF.getSection(EShdr->sh_info); - return section_iterator(SectionRef(toDRI(R), this)); + ErrorOr<const Elf_Shdr *> R = EF.getSection(EShdr->sh_info); + if (std::error_code EC = R.getError()) + report_fatal_error(EC.message()); + return section_iterator(SectionRef(toDRI(*R), this)); } // Relocations template <class ELFT> void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const { - ++Rel.d.b; + Rel.d.b += 2; } template <class ELFT> @@ -536,96 +672,62 @@ symbol_iterator ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const { uint32_t symbolIdx; const Elf_Shdr *sec = getRelSection(Rel); - switch (sec->sh_type) { - default: - report_fatal_error("Invalid section type in Rel!"); - case ELF::SHT_REL: { + if (sec->sh_type == ELF::SHT_REL) symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL()); - break; - } - case ELF::SHT_RELA: { + else symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL()); - break; - } - } if (!symbolIdx) return symbol_end(); - const Elf_Shdr *SymSec = EF.getSection(sec->sh_link); - + bool IsDyn = Rel.d.b & 1; DataRefImpl SymbolData; - switch (SymSec->sh_type) { - default: - report_fatal_error("Invalid symbol table section type!"); - case ELF::SHT_SYMTAB: - SymbolData = toDRI(EF.begin_symbols() + symbolIdx); - break; - case ELF::SHT_DYNSYM: - SymbolData = toDRI(EF.begin_dynamic_symbols() + symbolIdx); - break; - } - + if (IsDyn) + SymbolData = toDRI(EF.getDotDynSymSec(), symbolIdx); + else + SymbolData = toDRI(EF.getDotSymtabSec(), symbolIdx); return symbol_iterator(SymbolRef(SymbolData, this)); } template <class ELFT> -std::error_code -ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, - uint64_t &Result) const { +ErrorOr<uint64_t> +ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel) const { uint64_t ROffset = getROffset(Rel); const Elf_Ehdr *Header = EF.getHeader(); if (Header->e_type == ELF::ET_REL) { const Elf_Shdr *RelocationSec = getRelSection(Rel); - const Elf_Shdr *RelocatedSec = EF.getSection(RelocationSec->sh_info); - Result = ROffset + RelocatedSec->sh_addr; - } else { - Result = ROffset; + ErrorOr<const Elf_Shdr *> RelocatedSec = + EF.getSection(RelocationSec->sh_info); + if (std::error_code EC = RelocatedSec.getError()) + return EC; + return ROffset + (*RelocatedSec)->sh_addr; } - - return std::error_code(); + return ROffset; } template <class ELFT> -std::error_code -ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel, - uint64_t &Result) const { +uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const { assert(EF.getHeader()->e_type == ELF::ET_REL && "Only relocatable object files have relocation offsets"); - Result = getROffset(Rel); - return std::error_code(); + return getROffset(Rel); } template <class ELFT> uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const { const Elf_Shdr *sec = getRelSection(Rel); - switch (sec->sh_type) { - default: - report_fatal_error("Invalid section type in Rel!"); - case ELF::SHT_REL: + if (sec->sh_type == ELF::SHT_REL) return getRel(Rel)->r_offset; - case ELF::SHT_RELA: - return getRela(Rel)->r_offset; - } + + return getRela(Rel)->r_offset; } template <class ELFT> -std::error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel, - uint64_t &Result) const { +uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const { const Elf_Shdr *sec = getRelSection(Rel); - switch (sec->sh_type) { - default: - report_fatal_error("Invalid section type in Rel!"); - case ELF::SHT_REL: { - Result = getRel(Rel)->getType(EF.isMips64EL()); - break; - } - case ELF::SHT_RELA: { - Result = getRela(Rel)->getType(EF.isMips64EL()); - break; - } - } - return std::error_code(); + if (sec->sh_type == ELF::SHT_REL) + return getRel(Rel)->getType(EF.isMips64EL()); + else + return getRela(Rel)->getType(EF.isMips64EL()); } template <class ELFT> @@ -634,25 +736,10 @@ StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const { } template <class ELFT> -std::error_code ELFObjectFile<ELFT>::getRelocationTypeName( +void ELFObjectFile<ELFT>::getRelocationTypeName( DataRefImpl Rel, SmallVectorImpl<char> &Result) const { - const Elf_Shdr *sec = getRelSection(Rel); - uint32_t type; - switch (sec->sh_type) { - default: - return object_error::parse_failed; - case ELF::SHT_REL: { - type = getRel(Rel)->getType(EF.isMips64EL()); - break; - } - case ELF::SHT_RELA: { - type = getRela(Rel)->getType(EF.isMips64EL()); - break; - } - } - + uint32_t type = getRelocationType(Rel); EF.getRelocationTypeName(type, Result); - return std::error_code(); } template <class ELFT> @@ -664,11 +751,6 @@ ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const { } template <class ELFT> -bool ELFObjectFile<ELFT>::hasRelocationAddend(DataRefImpl Rel) const { - return getRelSection(Rel)->sh_type == ELF::SHT_RELA; -} - -template <class ELFT> const typename ELFFile<ELFT>::Elf_Sym * ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const { return &*toELFSymIter(Symb); @@ -677,13 +759,15 @@ ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const { template <class ELFT> const typename ELFObjectFile<ELFT>::Elf_Rel * ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const { - return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b); + assert(getRelSection(Rel)->sh_type == ELF::SHT_REL); + return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b >> 1); } template <class ELFT> const typename ELFObjectFile<ELFT>::Elf_Rela * ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { - return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b); + assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA); + return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b >> 1); } template <class ELFT> @@ -697,38 +781,46 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC) template <class ELFT> basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const { - return basic_symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this)); + DataRefImpl Sym = toDRI(EF.getDotSymtabSec(), 0); + return basic_symbol_iterator(SymbolRef(Sym, this)); } template <class ELFT> basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const { - return basic_symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this)); + const Elf_Shdr *SymTab = EF.getDotSymtabSec(); + if (!SymTab) + return symbol_begin_impl(); + DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym)); + return basic_symbol_iterator(SymbolRef(Sym, this)); } template <class ELFT> -symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const { - return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this)); +elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const { + DataRefImpl Sym = toDRI(EF.getDotDynSymSec(), 0); + return symbol_iterator(SymbolRef(Sym, this)); } template <class ELFT> -symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const { - return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this)); +elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const { + const Elf_Shdr *SymTab = EF.getDotDynSymSec(); + DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym)); + return basic_symbol_iterator(SymbolRef(Sym, this)); } template <class ELFT> section_iterator ELFObjectFile<ELFT>::section_begin() const { - return section_iterator(SectionRef(toDRI(EF.begin_sections()), this)); + return section_iterator(SectionRef(toDRI(EF.section_begin()), this)); } template <class ELFT> section_iterator ELFObjectFile<ELFT>::section_end() const { - return section_iterator(SectionRef(toDRI(EF.end_sections()), this)); + return section_iterator(SectionRef(toDRI(EF.section_end()), this)); } template <class ELFT> StringRef ELFObjectFile<ELFT>::getLoadName() const { - Elf_Dyn_Iter DI = EF.begin_dynamic_table(); - Elf_Dyn_Iter DE = EF.end_dynamic_table(); + Elf_Dyn_Iter DI = EF.dynamic_table_begin(); + Elf_Dyn_Iter DE = EF.dynamic_table_end(); while (DI != DE && DI->getTag() != ELF::DT_SONAME) ++DI; @@ -834,21 +926,16 @@ unsigned ELFObjectFile<ELFT>::getArch() const { } template <class ELFT> -std::pair<symbol_iterator, symbol_iterator> -ELFObjectFile<ELFT>::getELFDynamicSymbolIterators() const { - return std::make_pair(dynamic_symbol_begin(), dynamic_symbol_end()); +ELFObjectFileBase::elf_symbol_iterator_range +ELFObjectFile<ELFT>::getDynamicSymbolIterators() const { + return make_range(dynamic_symbol_begin(), dynamic_symbol_end()); } template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const { return EF.getHeader()->e_type == ELF::ET_REL; } -inline std::pair<symbol_iterator, symbol_iterator> -getELFDynamicSymbolIterators(const SymbolicFile *Obj) { - return cast<ELFObjectFileBase>(Obj)->getELFDynamicSymbolIterators(); } - -} // namespace object -} // namespace llvm +} #endif diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h index 2eda0c179f10..63e13909ae5c 100644 --- a/include/llvm/Object/ELFTypes.h +++ b/include/llvm/Object/ELFTypes.h @@ -10,9 +10,11 @@ #ifndef LLVM_OBJECT_ELFTYPES_H #define LLVM_OBJECT_ELFTYPES_H +#include "llvm/Object/Error.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/ErrorOr.h" namespace llvm { namespace object { @@ -24,6 +26,11 @@ template <endianness target_endianness, bool is64Bits> struct ELFType { static const bool Is64Bits = is64Bits; }; +typedef ELFType<support::little, false> ELF32LE; +typedef ELFType<support::big, false> ELF32BE; +typedef ELFType<support::little, true> ELF64LE; +typedef ELFType<support::big, true> ELF64BE; + // Use an alignment of 2 for the typedefs since that is the worst case for // ELF files in archives. @@ -197,8 +204,21 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> { return st_shndx >= ELF::SHN_LORESERVE; } bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; } + bool isExternal() const { + return getBinding() != ELF::STB_LOCAL; + } + + ErrorOr<StringRef> getName(StringRef StrTab) const; }; +template <class ELFT> +ErrorOr<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const { + uint32_t Offset = this->st_name; + if (Offset >= StrTab.size()) + return object_error::parse_failed; + return StringRef(StrTab.data() + Offset); +} + /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section /// (.gnu.version). This structure is identical for ELF32 and ELF64. template <class ELFT> @@ -293,14 +313,14 @@ struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> { using Elf_Dyn_Base<ELFT>::d_un; int64_t getTag() const { return d_tag; } uint64_t getVal() const { return d_un.d_val; } - uint64_t getPtr() const { return d_un.ptr; } + uint64_t getPtr() const { return d_un.d_ptr; } }; // Elf_Rel: Elf Relocation -template <class ELFT, bool isRela> struct Elf_Rel_Base; +template <class ELFT, bool isRela> struct Elf_Rel_Impl; template <endianness TargetEndianness> -struct Elf_Rel_Base<ELFType<TargetEndianness, false>, false> { +struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> { LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Word r_info; // Symbol table index and type of relocation to apply @@ -313,64 +333,46 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, false>, false> { assert(!IsMips64EL); r_info = R; } -}; - -template <endianness TargetEndianness> -struct Elf_Rel_Base<ELFType<TargetEndianness, true>, false> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) - Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) - Elf_Xword r_info; // Symbol table index and type of relocation to apply - uint64_t getRInfo(bool isMips64EL) const { - uint64_t t = r_info; - if (!isMips64EL) - return t; - // Mips64 little endian has a "special" encoding of r_info. Instead of one - // 64 bit little endian number, it is a little endian 32 bit number followed - // by a 32 bit big endian number. - return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | - ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); + // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, + // and ELF32_R_INFO macros defined in the ELF specification: + uint32_t getSymbol(bool isMips64EL) const { + return this->getRInfo(isMips64EL) >> 8; } - void setRInfo(uint64_t R, bool IsMips64EL) { - if (IsMips64EL) - r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) | - ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56); - else - r_info = R; + unsigned char getType(bool isMips64EL) const { + return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff); + } + void setSymbol(uint32_t s, bool IsMips64EL) { + setSymbolAndType(s, getType(), IsMips64EL); + } + void setType(unsigned char t, bool IsMips64EL) { + setSymbolAndType(getSymbol(), t, IsMips64EL); + } + void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) { + this->setRInfo((s << 8) + t, IsMips64EL); } }; template <endianness TargetEndianness> -struct Elf_Rel_Base<ELFType<TargetEndianness, false>, true> { +struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, true> + : public Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> { LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) - Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) - Elf_Word r_info; // Symbol table index and type of relocation to apply Elf_Sword r_addend; // Compute value for relocatable field by adding this - - uint32_t getRInfo(bool isMips64EL) const { - assert(!isMips64EL); - return r_info; - } - void setRInfo(uint32_t R, bool IsMips64EL) { - assert(!IsMips64EL); - r_info = R; - } }; template <endianness TargetEndianness> -struct Elf_Rel_Base<ELFType<TargetEndianness, true>, true> { +struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> { LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) - Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) - Elf_Xword r_info; // Symbol table index and type of relocation to apply - Elf_Sxword r_addend; // Compute value for relocatable field by adding this. + Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) + Elf_Xword r_info; // Symbol table index and type of relocation to apply uint64_t getRInfo(bool isMips64EL) const { - // Mips64 little endian has a "special" encoding of r_info. Instead of one - // 64 bit little endian number, it is a little endian 32 bit number followed - // by a 32 bit big endian number. uint64_t t = r_info; if (!isMips64EL) return t; + // Mips64 little endian has a "special" encoding of r_info. Instead of one + // 64 bit little endian number, it is a little endian 32 bit number followed + // by a 32 bit big endian number. return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); } @@ -381,14 +383,6 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, true>, true> { else r_info = R; } -}; - -template <class ELFT, bool isRela> struct Elf_Rel_Impl; - -template <endianness TargetEndianness, bool isRela> -struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, isRela> - : Elf_Rel_Base<ELFType<TargetEndianness, true>, isRela> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, // and ELF64_R_INFO macros defined in the ELF specification: @@ -409,28 +403,11 @@ struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, isRela> } }; -template <endianness TargetEndianness, bool isRela> -struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, isRela> - : Elf_Rel_Base<ELFType<TargetEndianness, false>, isRela> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) - - // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, - // and ELF32_R_INFO macros defined in the ELF specification: - uint32_t getSymbol(bool isMips64EL) const { - return this->getRInfo(isMips64EL) >> 8; - } - unsigned char getType(bool isMips64EL) const { - return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff); - } - void setSymbol(uint32_t s, bool IsMips64EL) { - setSymbolAndType(s, getType(), IsMips64EL); - } - void setType(unsigned char t, bool IsMips64EL) { - setSymbolAndType(getSymbol(), t, IsMips64EL); - } - void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) { - this->setRInfo((s << 8) + t, IsMips64EL); - } +template <endianness TargetEndianness> +struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, true> + : public Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) + Elf_Sxword r_addend; // Compute value for relocatable field by adding this. }; template <class ELFT> diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h index c9db1b80b916..aa320bb51a46 100644 --- a/include/llvm/Object/Error.h +++ b/include/llvm/Object/Error.h @@ -27,6 +27,8 @@ enum class object_error { invalid_file_type, parse_failed, unexpected_eof, + string_table_non_null_end, + invalid_section_index, bitcode_section_not_found, macho_small_load_command, macho_load_segment_too_many_sections, diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h index f7135706cc4e..ef655287c34c 100644 --- a/include/llvm/Object/IRObjectFile.h +++ b/include/llvm/Object/IRObjectFile.h @@ -68,7 +68,7 @@ public: static ErrorOr<std::unique_ptr<IRObjectFile>> create(MemoryBufferRef Object, LLVMContext &Context); }; -} // namespace object -} // namespace llvm +} +} #endif diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 4350a759f153..f4edfd057303 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -197,8 +197,9 @@ public: std::error_code &EC); void moveSymbolNext(DataRefImpl &Symb) const override; - std::error_code getSymbolName(DataRefImpl Symb, - StringRef &Res) const override; + + uint64_t getNValue(DataRefImpl Sym) const; + ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override; // MachO specific. std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const; @@ -206,13 +207,15 @@ public: std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; + uint64_t getSymbolValue(DataRefImpl Symb) const override; uint32_t getSymbolAlignment(DataRefImpl Symb) const override; - uint64_t getSymbolSize(DataRefImpl Symb) const override; - std::error_code getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Res) const override; + uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; + SymbolRef::Type getSymbolType(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; std::error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const override; + unsigned getSymbolSectionID(SymbolRef Symb) const; + unsigned getSectionID(SectionRef Sec) const; void moveSectionNext(DataRefImpl &Sec) const override; std::error_code getSectionName(DataRefImpl Sec, @@ -226,24 +229,17 @@ public: bool isSectionData(DataRefImpl Sec) const override; bool isSectionBSS(DataRefImpl Sec) const override; bool isSectionVirtual(DataRefImpl Sec) const override; - bool sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; - std::error_code getRelocationAddress(DataRefImpl Rel, - uint64_t &Res) const override; - std::error_code getRelocationOffset(DataRefImpl Rel, - uint64_t &Res) const override; + ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const override; + uint64_t getRelocationOffset(DataRefImpl Rel) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; section_iterator getRelocationSection(DataRefImpl Rel) const; - std::error_code getRelocationType(DataRefImpl Rel, - uint64_t &Res) const override; - std::error_code - getRelocationTypeName(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const override; - std::error_code getRelocationHidden(DataRefImpl Rel, - bool &Result) const override; + uint64_t getRelocationType(DataRefImpl Rel) const override; + void getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl<char> &Result) const override; uint8_t getRelocationLength(DataRefImpl Rel) const; // MachO specific. @@ -503,8 +499,8 @@ inline const ObjectFile *DiceRef::getObjectFile() const { return OwningObject; } -} // namespace object -} // namespace llvm +} +} #endif diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h index ebc8b906691a..a11d381a700a 100644 --- a/include/llvm/Object/MachOUniversal.h +++ b/include/llvm/Object/MachOUniversal.h @@ -109,10 +109,10 @@ public: } ErrorOr<std::unique_ptr<MachOObjectFile>> - getObjectForArch(Triple::ArchType Arch) const; + getObjectForArch(StringRef ArchName) const; }; -} // namespace object -} // namespace llvm +} +} #endif diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index e00fe0ed0a2a..62eab1066be5 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -35,8 +35,8 @@ class symbol_iterator; class SectionRef; typedef content_iterator<SectionRef> section_iterator; -/// RelocationRef - This is a value type class that represents a single -/// relocation in the list of relocations in the object file. +/// This is a value type class that represents a single relocation in the list +/// of relocations in the object file. class RelocationRef { DataRefImpl RelocationPimpl; const ObjectFile *OwningObject; @@ -50,29 +50,23 @@ public: void moveNext(); - std::error_code getAddress(uint64_t &Result) const; - std::error_code getOffset(uint64_t &Result) const; + ErrorOr<uint64_t> getAddress() const; + uint64_t getOffset() const; symbol_iterator getSymbol() const; - std::error_code getType(uint64_t &Result) const; - - /// @brief Indicates whether this relocation should hidden when listing - /// relocations, usually because it is the trailing part of a multipart - /// relocation that will be printed as part of the leading relocation. - std::error_code getHidden(bool &Result) const; + uint64_t getType() const; /// @brief Get a string that represents the type of this relocation. /// /// This is for display purposes only. - std::error_code getTypeName(SmallVectorImpl<char> &Result) const; - + void getTypeName(SmallVectorImpl<char> &Result) const; DataRefImpl getRawDataRefImpl() const; - const ObjectFile *getObjectFile() const; + const ObjectFile *getObject() const; }; typedef content_iterator<RelocationRef> relocation_iterator; -/// SectionRef - This is a value type class that represents a single section in -/// the list of sections in the object file. +/// This is a value type class that represents a single section in the list of +/// sections in the object file. class SectionRef { friend class SymbolRef; DataRefImpl SectionPimpl; @@ -116,8 +110,8 @@ public: const ObjectFile *getObject() const; }; -/// SymbolRef - This is a value type class that represents a single symbol in -/// the list of symbols in the object file. +/// This is a value type class that represents a single symbol in the list of +/// symbols in the object file. class SymbolRef : public BasicSymbolRef { friend class SectionRef; @@ -134,16 +128,23 @@ public: }; SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); + SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) { + assert(isa<ObjectFile>(BasicSymbolRef::getObject())); + } - std::error_code getName(StringRef &Result) const; + ErrorOr<StringRef> getName() const; /// Returns the symbol virtual address (i.e. address at which it will be /// mapped). std::error_code getAddress(uint64_t &Result) const; + + /// Return the value of the symbol depending on the object this can be an + /// offset or a virtual address. + uint64_t getValue() const; + /// @brief Get the alignment of this symbol as the actual value (not log 2). uint32_t getAlignment() const; - uint64_t getSize() const; - std::error_code getType(SymbolRef::Type &Result) const; - std::error_code getOther(uint8_t &Result) const; + uint64_t getCommonSize() const; + SymbolRef::Type getType() const; /// @brief Get section this symbol is defined in reference to. Result is /// end_sections() if it is undefined or is an absolute symbol. @@ -170,9 +171,9 @@ public: } }; -/// ObjectFile - This class is the base class for all object file types. -/// Concrete instances of this object are created by createObjectFile, which -/// figures out which type to create. +/// This class is the base class for all object file types. Concrete instances +/// of this object are created by createObjectFile, which figures out which type +/// to create. class ObjectFile : public SymbolicFile { virtual void anchor(); ObjectFile() = delete; @@ -194,22 +195,17 @@ protected: // Implementations assume that the DataRefImpl is valid and has not been // modified externally. It's UB otherwise. friend class SymbolRef; - virtual std::error_code getSymbolName(DataRefImpl Symb, - StringRef &Res) const = 0; + virtual ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const = 0; std::error_code printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override; virtual std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0; + virtual uint64_t getSymbolValue(DataRefImpl Symb) const = 0; virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const; - virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; - virtual std::error_code getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Res) const = 0; + virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0; + virtual SymbolRef::Type getSymbolType(DataRefImpl Symb) const = 0; virtual std::error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const = 0; - virtual std::error_code getSymbolOther(DataRefImpl Symb, - uint8_t &Res) const { - return object_error::invalid_file_type; - } // Same as above for SectionRef. friend class SectionRef; @@ -226,8 +222,6 @@ protected: virtual bool isSectionBSS(DataRefImpl Sec) const = 0; // A section is 'virtual' if its contents aren't present in the object image. virtual bool isSectionVirtual(DataRefImpl Sec) const = 0; - virtual bool sectionContainsSymbol(DataRefImpl Sec, - DataRefImpl Symb) const = 0; virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0; virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0; virtual section_iterator getRelocatedSection(DataRefImpl Sec) const; @@ -235,23 +229,19 @@ protected: // Same as above for RelocationRef. friend class RelocationRef; virtual void moveRelocationNext(DataRefImpl &Rel) const = 0; - virtual std::error_code getRelocationAddress(DataRefImpl Rel, - uint64_t &Res) const = 0; - virtual std::error_code getRelocationOffset(DataRefImpl Rel, - uint64_t &Res) const = 0; + virtual ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const = 0; + virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0; virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0; - virtual std::error_code getRelocationType(DataRefImpl Rel, - uint64_t &Res) const = 0; - virtual std::error_code - getRelocationTypeName(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const = 0; - virtual std::error_code getRelocationHidden(DataRefImpl Rel, - bool &Result) const { - Result = false; - return std::error_code(); - } + virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0; + virtual void getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl<char> &Result) const = 0; public: + uint64_t getCommonSymbolSize(DataRefImpl Symb) const { + assert(getSymbolFlags(Symb) & SymbolRef::SF_Common); + return getCommonSymbolSizeImpl(Symb); + } + typedef iterator_range<symbol_iterator> symbol_iterator_range; symbol_iterator_range symbols() const { return symbol_iterator_range(symbol_begin(), symbol_end()); @@ -314,32 +304,32 @@ public: inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner) : BasicSymbolRef(SymbolP, Owner) {} -inline std::error_code SymbolRef::getName(StringRef &Result) const { - return getObject()->getSymbolName(getRawDataRefImpl(), Result); +inline ErrorOr<StringRef> SymbolRef::getName() const { + return getObject()->getSymbolName(getRawDataRefImpl()); } inline std::error_code SymbolRef::getAddress(uint64_t &Result) const { return getObject()->getSymbolAddress(getRawDataRefImpl(), Result); } +inline uint64_t SymbolRef::getValue() const { + return getObject()->getSymbolValue(getRawDataRefImpl()); +} + inline uint32_t SymbolRef::getAlignment() const { return getObject()->getSymbolAlignment(getRawDataRefImpl()); } -inline uint64_t SymbolRef::getSize() const { - return getObject()->getSymbolSize(getRawDataRefImpl()); +inline uint64_t SymbolRef::getCommonSize() const { + return getObject()->getCommonSymbolSize(getRawDataRefImpl()); } inline std::error_code SymbolRef::getSection(section_iterator &Result) const { return getObject()->getSymbolSection(getRawDataRefImpl(), Result); } -inline std::error_code SymbolRef::getType(SymbolRef::Type &Result) const { - return getObject()->getSymbolType(getRawDataRefImpl(), Result); -} - -inline std::error_code SymbolRef::getOther(uint8_t &Result) const { - return getObject()->getSymbolOther(getRawDataRefImpl(), Result); +inline SymbolRef::Type SymbolRef::getType() const { + return getObject()->getSymbolType(getRawDataRefImpl()); } inline const ObjectFile *SymbolRef::getObject() const { @@ -406,11 +396,6 @@ inline bool SectionRef::isVirtual() const { return OwningObject->isSectionVirtual(SectionPimpl); } -inline bool SectionRef::containsSymbol(SymbolRef S) const { - return OwningObject->sectionContainsSymbol(SectionPimpl, - S.getRawDataRefImpl()); -} - inline relocation_iterator SectionRef::relocation_begin() const { return OwningObject->section_rel_begin(SectionPimpl); } @@ -445,36 +430,31 @@ inline void RelocationRef::moveNext() { return OwningObject->moveRelocationNext(RelocationPimpl); } -inline std::error_code RelocationRef::getAddress(uint64_t &Result) const { - return OwningObject->getRelocationAddress(RelocationPimpl, Result); +inline ErrorOr<uint64_t> RelocationRef::getAddress() const { + return OwningObject->getRelocationAddress(RelocationPimpl); } -inline std::error_code RelocationRef::getOffset(uint64_t &Result) const { - return OwningObject->getRelocationOffset(RelocationPimpl, Result); +inline uint64_t RelocationRef::getOffset() const { + return OwningObject->getRelocationOffset(RelocationPimpl); } inline symbol_iterator RelocationRef::getSymbol() const { return OwningObject->getRelocationSymbol(RelocationPimpl); } -inline std::error_code RelocationRef::getType(uint64_t &Result) const { - return OwningObject->getRelocationType(RelocationPimpl, Result); +inline uint64_t RelocationRef::getType() const { + return OwningObject->getRelocationType(RelocationPimpl); } -inline std::error_code -RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const { +inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const { return OwningObject->getRelocationTypeName(RelocationPimpl, Result); } -inline std::error_code RelocationRef::getHidden(bool &Result) const { - return OwningObject->getRelocationHidden(RelocationPimpl, Result); -} - inline DataRefImpl RelocationRef::getRawDataRefImpl() const { return RelocationPimpl; } -inline const ObjectFile *RelocationRef::getObjectFile() const { +inline const ObjectFile *RelocationRef::getObject() const { return OwningObject; } diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index f80ee0a8a7a2..950e2ed0e338 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -240,16 +240,14 @@ private: } int64_t getELFAddend(RelocationRef R) { - const auto *Obj = cast<ELFObjectFileBase>(R.getObjectFile()); - DataRefImpl DRI = R.getRawDataRefImpl(); - ErrorOr<int64_t> AddendOrErr = Obj->getRelocationAddend(DRI); + ErrorOr<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend(); if (std::error_code EC = AddendOrErr.getError()) report_fatal_error(EC.message()); return *AddendOrErr; } uint8_t getLengthMachO64(RelocationRef R) { - const MachOObjectFile *Obj = cast<MachOObjectFile>(R.getObjectFile()); + const MachOObjectFile *Obj = cast<MachOObjectFile>(R.getObject()); return Obj->getRelocationLength(R.getRawDataRefImpl()); } @@ -267,8 +265,7 @@ private: } RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value) { - uint64_t Address; - R.getOffset(Address); + uint64_t Address = R.getOffset(); return RelocToApply(Value - Address, 4); } @@ -282,8 +279,7 @@ private: } RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value) { int64_t Addend = getELFAddend(R); - uint64_t Address; - R.getOffset(Address); + uint64_t Address = R.getOffset(); return RelocToApply(Value + Addend - Address, 4); } RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) { @@ -412,6 +408,6 @@ private: } }; -} // namespace object -} // namespace llvm +} +} #endif diff --git a/include/llvm/Object/StackMapParser.h b/include/llvm/Object/StackMapParser.h new file mode 100644 index 000000000000..276eab6c294e --- /dev/null +++ b/include/llvm/Object/StackMapParser.h @@ -0,0 +1,442 @@ +//===-------- StackMapParser.h - StackMap Parsing Support -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_STACKMAPPARSER_H +#define LLVM_CODEGEN_STACKMAPPARSER_H + +#include "llvm/Support/Debug.h" +#include "llvm/Support/Endian.h" +#include <map> +#include <vector> + +namespace llvm { + +template <support::endianness Endianness> +class StackMapV1Parser { +public: + + template <typename AccessorT> + class AccessorIterator { + public: + + AccessorIterator(AccessorT A) : A(A) {} + AccessorIterator& operator++() { A = A.next(); return *this; } + AccessorIterator operator++(int) { + auto tmp = *this; + ++*this; + return tmp; + } + + bool operator==(const AccessorIterator &Other) { + return A.P == Other.A.P; + } + + bool operator!=(const AccessorIterator &Other) { return !(*this == Other); } + + AccessorT& operator*() { return A; } + AccessorT* operator->() { return &A; } + + private: + AccessorT A; + }; + + /// Accessor for function records. + class FunctionAccessor { + friend class StackMapV1Parser; + public: + + /// Get the function address. + uint64_t getFunctionAddress() const { + return read<uint64_t>(P); + } + + /// Get the function's stack size. + uint32_t getStackSize() const { + return read<uint64_t>(P + sizeof(uint64_t)); + } + + private: + FunctionAccessor(const uint8_t *P) : P(P) {} + + const static int FunctionAccessorSize = 2 * sizeof(uint64_t); + + FunctionAccessor next() const { + return FunctionAccessor(P + FunctionAccessorSize); + } + + const uint8_t *P; + }; + + /// Accessor for constants. + class ConstantAccessor { + friend class StackMapV1Parser; + public: + + /// Return the value of this constant. + uint64_t getValue() const { return read<uint64_t>(P); } + + private: + + ConstantAccessor(const uint8_t *P) : P(P) {} + + const static int ConstantAccessorSize = sizeof(uint64_t); + + ConstantAccessor next() const { + return ConstantAccessor(P + ConstantAccessorSize); + } + + const uint8_t *P; + }; + + // Forward-declare RecordAccessor so we can friend it below. + class RecordAccessor; + + enum class LocationKind : uint8_t { + Register = 1, Direct = 2, Indirect = 3, Constant = 4, ConstantIndex = 5 + }; + + + /// Accessor for location records. + class LocationAccessor { + friend class StackMapV1Parser; + friend class RecordAccessor; + public: + + /// Get the Kind for this location. + LocationKind getKind() const { + return LocationKind(P[KindOffset]); + } + + /// Get the Dwarf register number for this location. + uint16_t getDwarfRegNum() const { + return read<uint16_t>(P + DwarfRegNumOffset); + } + + /// Get the small-constant for this location. (Kind must be Constant). + uint32_t getSmallConstant() const { + assert(getKind() == LocationKind::Constant && "Not a small constant."); + return read<uint32_t>(P + SmallConstantOffset); + } + + /// Get the constant-index for this location. (Kind must be ConstantIndex). + uint32_t getConstantIndex() const { + assert(getKind() == LocationKind::ConstantIndex && + "Not a constant-index."); + return read<uint32_t>(P + SmallConstantOffset); + } + + /// Get the offset for this location. (Kind must be Direct or Indirect). + int32_t getOffset() const { + assert((getKind() == LocationKind::Direct || + getKind() == LocationKind::Indirect) && + "Not direct or indirect."); + return read<int32_t>(P + SmallConstantOffset); + } + + private: + + LocationAccessor(const uint8_t *P) : P(P) {} + + LocationAccessor next() const { + return LocationAccessor(P + LocationAccessorSize); + } + + static const int KindOffset = 0; + static const int DwarfRegNumOffset = KindOffset + sizeof(uint16_t); + static const int SmallConstantOffset = DwarfRegNumOffset + sizeof(uint16_t); + static const int LocationAccessorSize = sizeof(uint64_t); + + const uint8_t *P; + }; + + /// Accessor for stackmap live-out fields. + class LiveOutAccessor { + friend class StackMapV1Parser; + friend class RecordAccessor; + public: + + /// Get the Dwarf register number for this live-out. + uint16_t getDwarfRegNum() const { + return read<uint16_t>(P + DwarfRegNumOffset); + } + + /// Get the size in bytes of live [sub]register. + unsigned getSizeInBytes() const { + return read<uint8_t>(P + SizeOffset); + } + + private: + + LiveOutAccessor(const uint8_t *P) : P(P) {} + + LiveOutAccessor next() const { + return LiveOutAccessor(P + LiveOutAccessorSize); + } + + static const int DwarfRegNumOffset = 0; + static const int SizeOffset = + DwarfRegNumOffset + sizeof(uint16_t) + sizeof(uint8_t); + static const int LiveOutAccessorSize = sizeof(uint32_t); + + const uint8_t *P; + }; + + /// Accessor for stackmap records. + class RecordAccessor { + friend class StackMapV1Parser; + public: + + typedef AccessorIterator<LocationAccessor> location_iterator; + typedef AccessorIterator<LiveOutAccessor> liveout_iterator; + + /// Get the patchpoint/stackmap ID for this record. + uint64_t getID() const { + return read<uint64_t>(P + PatchpointIDOffset); + } + + /// Get the instruction offset (from the start of the containing function) + /// for this record. + uint32_t getInstructionOffset() const { + return read<uint32_t>(P + InstructionOffsetOffset); + } + + /// Get the number of locations contained in this record. + uint16_t getNumLocations() const { + return read<uint16_t>(P + NumLocationsOffset); + } + + /// Get the location with the given index. + LocationAccessor getLocation(unsigned LocationIndex) const { + unsigned LocationOffset = + LocationListOffset + LocationIndex * LocationSize; + return LocationAccessor(P + LocationOffset); + } + + /// Begin iterator for locations. + location_iterator location_begin() const { + return location_iterator(getLocation(0)); + } + + /// End iterator for locations. + location_iterator location_end() const { + return location_iterator(getLocation(getNumLocations())); + } + + /// Iterator range for locations. + iterator_range<location_iterator> locations() const { + return make_range(location_begin(), location_end()); + } + + /// Get the number of liveouts contained in this record. + uint16_t getNumLiveOuts() const { + return read<uint16_t>(P + getNumLiveOutsOffset()); + } + + /// Get the live-out with the given index. + LiveOutAccessor getLiveOut(unsigned LiveOutIndex) const { + unsigned LiveOutOffset = + getNumLiveOutsOffset() + sizeof(uint16_t) + LiveOutIndex * LiveOutSize; + return LiveOutAccessor(P + LiveOutOffset); + } + + /// Begin iterator for live-outs. + liveout_iterator liveouts_begin() const { + return liveout_iterator(getLiveOut(0)); + } + + + /// End iterator for live-outs. + liveout_iterator liveouts_end() const { + return liveout_iterator(getLiveOut(getNumLiveOuts())); + } + + /// Iterator range for live-outs. + iterator_range<liveout_iterator> liveouts() const { + return make_range(liveouts_begin(), liveouts_end()); + } + + private: + + RecordAccessor(const uint8_t *P) : P(P) {} + + unsigned getNumLiveOutsOffset() const { + return LocationListOffset + LocationSize * getNumLocations() + + sizeof(uint16_t); + } + + unsigned getSizeInBytes() const { + unsigned RecordSize = + getNumLiveOutsOffset() + sizeof(uint16_t) + getNumLiveOuts() * LiveOutSize; + return (RecordSize + 7) & ~0x7; + } + + RecordAccessor next() const { + return RecordAccessor(P + getSizeInBytes()); + } + + static const unsigned PatchpointIDOffset = 0; + static const unsigned InstructionOffsetOffset = + PatchpointIDOffset + sizeof(uint64_t); + static const unsigned NumLocationsOffset = + InstructionOffsetOffset + sizeof(uint32_t) + sizeof(uint16_t); + static const unsigned LocationListOffset = + NumLocationsOffset + sizeof(uint16_t); + static const unsigned LocationSize = sizeof(uint64_t); + static const unsigned LiveOutSize = sizeof(uint32_t); + + const uint8_t *P; + }; + + /// Construct a parser for a version-1 stackmap. StackMap data will be read + /// from the given array. + StackMapV1Parser(ArrayRef<uint8_t> StackMapSection) + : StackMapSection(StackMapSection) { + ConstantsListOffset = FunctionListOffset + getNumFunctions() * FunctionSize; + + assert(StackMapSection[0] == 1 && + "StackMapV1Parser can only parse version 1 stackmaps"); + + unsigned CurrentRecordOffset = + ConstantsListOffset + getNumConstants() * ConstantSize; + + for (unsigned I = 0, E = getNumRecords(); I != E; ++I) { + StackMapRecordOffsets.push_back(CurrentRecordOffset); + CurrentRecordOffset += + RecordAccessor(&StackMapSection[CurrentRecordOffset]).getSizeInBytes(); + } + } + + typedef AccessorIterator<FunctionAccessor> function_iterator; + typedef AccessorIterator<ConstantAccessor> constant_iterator; + typedef AccessorIterator<RecordAccessor> record_iterator; + + /// Get the version number of this stackmap. (Always returns 1). + unsigned getVersion() const { return 1; } + + /// Get the number of functions in the stack map. + uint32_t getNumFunctions() const { + return read<uint32_t>(&StackMapSection[NumFunctionsOffset]); + } + + /// Get the number of large constants in the stack map. + uint32_t getNumConstants() const { + return read<uint32_t>(&StackMapSection[NumConstantsOffset]); + } + + /// Get the number of stackmap records in the stackmap. + uint32_t getNumRecords() const { + return read<uint32_t>(&StackMapSection[NumRecordsOffset]); + } + + /// Return an FunctionAccessor for the given function index. + FunctionAccessor getFunction(unsigned FunctionIndex) const { + return FunctionAccessor(StackMapSection.data() + + getFunctionOffset(FunctionIndex)); + } + + /// Begin iterator for functions. + function_iterator functions_begin() const { + return function_iterator(getFunction(0)); + } + + /// End iterator for functions. + function_iterator functions_end() const { + return function_iterator( + FunctionAccessor(StackMapSection.data() + + getFunctionOffset(getNumFunctions()))); + } + + /// Iterator range for functions. + iterator_range<function_iterator> functions() const { + return make_range(functions_begin(), functions_end()); + } + + /// Return the large constant at the given index. + ConstantAccessor getConstant(unsigned ConstantIndex) const { + return ConstantAccessor(StackMapSection.data() + + getConstantOffset(ConstantIndex)); + } + + /// Begin iterator for constants. + constant_iterator constants_begin() const { + return constant_iterator(getConstant(0)); + } + + /// End iterator for constants. + constant_iterator constants_end() const { + return constant_iterator( + ConstantAccessor(StackMapSection.data() + + getConstantOffset(getNumConstants()))); + } + + /// Iterator range for constants. + iterator_range<constant_iterator> constants() const { + return make_range(constants_begin(), constants_end()); + } + + /// Return a RecordAccessor for the given record index. + RecordAccessor getRecord(unsigned RecordIndex) const { + std::size_t RecordOffset = StackMapRecordOffsets[RecordIndex]; + return RecordAccessor(StackMapSection.data() + RecordOffset); + } + + /// Begin iterator for records. + record_iterator records_begin() const { + if (getNumRecords() == 0) + return record_iterator(RecordAccessor(nullptr)); + return record_iterator(getRecord(0)); + } + + /// End iterator for records. + record_iterator records_end() const { + // Records need to be handled specially, since we cache the start addresses + // for them: We can't just compute the 1-past-the-end address, we have to + // look at the last record and use the 'next' method. + if (getNumRecords() == 0) + return record_iterator(RecordAccessor(nullptr)); + return record_iterator(getRecord(getNumRecords() - 1).next()); + } + + /// Iterator range for records. + iterator_range<record_iterator> records() const { + return make_range(records_begin(), records_end()); + } + +private: + + template <typename T> + static T read(const uint8_t *P) { + return support::endian::read<T, Endianness, 1>(P); + } + + static const unsigned HeaderOffset = 0; + static const unsigned NumFunctionsOffset = HeaderOffset + sizeof(uint32_t); + static const unsigned NumConstantsOffset = NumFunctionsOffset + sizeof(uint32_t); + static const unsigned NumRecordsOffset = NumConstantsOffset + sizeof(uint32_t); + static const unsigned FunctionListOffset = NumRecordsOffset + sizeof(uint32_t); + + static const unsigned FunctionSize = 2 * sizeof(uint64_t); + static const unsigned ConstantSize = sizeof(uint64_t); + + std::size_t getFunctionOffset(unsigned FunctionIndex) const { + return FunctionListOffset + FunctionIndex * FunctionSize; + } + + std::size_t getConstantOffset(unsigned ConstantIndex) const { + return ConstantsListOffset + ConstantIndex * ConstantSize; + } + + ArrayRef<uint8_t> StackMapSection; + unsigned ConstantsListOffset; + std::vector<unsigned> StackMapRecordOffsets; +}; + +} + +#endif diff --git a/include/llvm/Object/SymbolSize.h b/include/llvm/Object/SymbolSize.h new file mode 100644 index 000000000000..f2ce70f4208d --- /dev/null +++ b/include/llvm/Object/SymbolSize.h @@ -0,0 +1,23 @@ +//===- SymbolSize.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_SYMBOLSIZE_H +#define LLVM_OBJECT_SYMBOLSIZE_H + +#include "llvm/Object/ObjectFile.h" + +namespace llvm { +namespace object { +std::vector<std::pair<SymbolRef, uint64_t>> +computeSymbolSizes(const ObjectFile &O); +} +} // namespace llvm + +#endif diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h index bf465997838f..3a3823159c92 100644 --- a/include/llvm/Object/SymbolicFile.h +++ b/include/llvm/Object/SymbolicFile.h @@ -115,7 +115,7 @@ public: typedef content_iterator<BasicSymbolRef> basic_symbol_iterator; -const uint64_t UnknownAddressOrSize = ~0ULL; +const uint64_t UnknownAddress = ~0ULL; class SymbolicFile : public Binary { public: @@ -195,7 +195,7 @@ inline const SymbolicFile *BasicSymbolRef::getObject() const { return OwningObject; } -} // namespace object -} // namespace llvm +} +} #endif diff --git a/include/llvm/Option/Arg.h b/include/llvm/Option/Arg.h index 5f6941a53d0c..e1b72b6267cf 100644 --- a/include/llvm/Option/Arg.h +++ b/include/llvm/Option/Arg.h @@ -93,9 +93,8 @@ public: return Values[N]; } - SmallVectorImpl<const char*> &getValues() { - return Values; - } + SmallVectorImpl<const char *> &getValues() { return Values; } + const SmallVectorImpl<const char *> &getValues() const { return Values; } bool containsValue(StringRef Value) const { for (unsigned i = 0, e = getNumValues(); i != e; ++i) diff --git a/include/llvm/Option/ArgList.h b/include/llvm/Option/ArgList.h index 23b04513178c..ef4005761b75 100644 --- a/include/llvm/Option/ArgList.h +++ b/include/llvm/Option/ArgList.h @@ -14,6 +14,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" +#include "llvm/Option/Arg.h" #include "llvm/Option/OptSpecifier.h" #include "llvm/Option/Option.h" #include <list> @@ -23,7 +24,6 @@ namespace llvm { namespace opt { -class Arg; class ArgList; class Option; @@ -92,10 +92,6 @@ public: /// check for the presence of Arg instances for a particular Option /// and to iterate over groups of arguments. class ArgList { -private: - ArgList(const ArgList &) = delete; - void operator=(const ArgList &) = delete; - public: typedef SmallVector<Arg*, 16> arglist_type; typedef arglist_type::iterator iterator; @@ -108,12 +104,23 @@ private: arglist_type Args; protected: - // Default ctor provided explicitly as it is not provided implicitly due to - // the presence of the (deleted) copy ctor above. - ArgList() { } - // Virtual to provide a vtable anchor and because -Wnon-virtua-dtor warns, not - // because this type is ever actually destroyed polymorphically. - virtual ~ArgList(); + // Make the default special members protected so they won't be used to slice + // derived objects, but can still be used by derived objects to implement + // their own special members. + ArgList() = default; + // Explicit move operations to ensure the container is cleared post-move + // otherwise it could lead to a double-delete in the case of moving of an + // InputArgList which deletes the contents of the container. If we could fix + // up the ownership here (delegate storage/ownership to the derived class so + // it can be a container of unique_ptr) this would be simpler. + ArgList(ArgList &&RHS) : Args(std::move(RHS.Args)) { RHS.Args.clear(); } + ArgList &operator=(ArgList &&RHS) { + Args = std::move(RHS.Args); + RHS.Args.clear(); + return *this; + } + // Protect the dtor to ensure this type is never destroyed polymorphically. + ~ArgList() = default; public: @@ -299,7 +306,7 @@ public: /// @} }; -class InputArgList : public ArgList { +class InputArgList final : public ArgList { private: /// List of argument strings used by the contained Args. /// @@ -318,9 +325,24 @@ private: /// The number of original input argument strings. unsigned NumInputArgStrings; + /// Release allocated arguments. + void releaseMemory(); + public: InputArgList(const char* const *ArgBegin, const char* const *ArgEnd); - ~InputArgList() override; + InputArgList(InputArgList &&RHS) + : ArgList(std::move(RHS)), ArgStrings(std::move(RHS.ArgStrings)), + SynthesizedStrings(std::move(RHS.SynthesizedStrings)), + NumInputArgStrings(RHS.NumInputArgStrings) {} + InputArgList &operator=(InputArgList &&RHS) { + releaseMemory(); + ArgList::operator=(std::move(RHS)); + ArgStrings = std::move(RHS.ArgStrings); + SynthesizedStrings = std::move(RHS.SynthesizedStrings); + NumInputArgStrings = RHS.NumInputArgStrings; + return *this; + } + ~InputArgList() { releaseMemory(); } const char *getArgString(unsigned Index) const override { return ArgStrings[Index]; @@ -346,7 +368,7 @@ public: /// DerivedArgList - An ordered collection of driver arguments, /// whose storage may be in another argument list. -class DerivedArgList : public ArgList { +class DerivedArgList final : public ArgList { const InputArgList &BaseArgs; /// The list of arguments we synthesized. @@ -355,7 +377,6 @@ class DerivedArgList : public ArgList { public: /// Construct a new derived arg list from \p BaseArgs. DerivedArgList(const InputArgList &BaseArgs); - ~DerivedArgList() override; const char *getArgString(unsigned Index) const override { return BaseArgs.getArgString(Index); diff --git a/include/llvm/Option/OptSpecifier.h b/include/llvm/Option/OptSpecifier.h index f9b121e352db..0b2aaaec3afc 100644 --- a/include/llvm/Option/OptSpecifier.h +++ b/include/llvm/Option/OptSpecifier.h @@ -35,7 +35,7 @@ namespace opt { bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); } bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); } }; -} // namespace opt -} // namespace llvm +} +} #endif diff --git a/include/llvm/Option/OptTable.h b/include/llvm/Option/OptTable.h index a7ff46919cd6..96f51cf3317d 100644 --- a/include/llvm/Option/OptTable.h +++ b/include/llvm/Option/OptTable.h @@ -10,6 +10,7 @@ #ifndef LLVM_OPTION_OPTTABLE_H #define LLVM_OPTION_OPTTABLE_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/Option/OptSpecifier.h" @@ -141,8 +142,6 @@ public: /// The only error that can occur in this routine is if an argument is /// missing values; in this case \p MissingArgCount will be non-zero. /// - /// \param ArgBegin - The beginning of the argument vector. - /// \param ArgEnd - The end of the argument vector. /// \param MissingArgIndex - On error, the index of the option which could /// not be parsed. /// \param MissingArgCount - On error, the number of missing options. @@ -152,12 +151,9 @@ public: /// is the default and means exclude nothing. /// \return An InputArgList; on error this will contain all the options /// which could be parsed. - InputArgList *ParseArgs(const char* const *ArgBegin, - const char* const *ArgEnd, - unsigned &MissingArgIndex, - unsigned &MissingArgCount, - unsigned FlagsToInclude = 0, - unsigned FlagsToExclude = 0) const; + InputArgList ParseArgs(ArrayRef<const char *> Args, unsigned &MissingArgIndex, + unsigned &MissingArgCount, unsigned FlagsToInclude = 0, + unsigned FlagsToExclude = 0) const; /// \brief Render the help text for an option table. /// diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index ccd6f2728230..3c4d838a4652 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -369,7 +369,7 @@ protected: /// @brief This is the storage for the -time-passes option. extern bool TimePassesIsEnabled; -} // namespace llvm +} // End llvm namespace // Include support files that contain important APIs commonly used by Passes, // but that we want to separate out to make it easier to read the header files. diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h index d356097d0b94..0b318fc8fb07 100644 --- a/include/llvm/PassAnalysisSupport.h +++ b/include/llvm/PassAnalysisSupport.h @@ -27,28 +27,27 @@ namespace llvm { //===----------------------------------------------------------------------===// -// AnalysisUsage - Represent the analysis usage information of a pass. This -// tracks analyses that the pass REQUIRES (must be available when the pass -// runs), REQUIRES TRANSITIVE (must be available throughout the lifetime of the -// pass), and analyses that the pass PRESERVES (the pass does not invalidate the -// results of these analyses). This information is provided by a pass to the -// Pass infrastructure through the getAnalysisUsage virtual function. -// +/// Represent the analysis usage information of a pass. This tracks analyses +/// that the pass REQUIRES (must be available when the pass runs), REQUIRES +/// TRANSITIVE (must be available throughout the lifetime of the pass), and +/// analyses that the pass PRESERVES (the pass does not invalidate the results +/// of these analyses). This information is provided by a pass to the Pass +/// infrastructure through the getAnalysisUsage virtual function. +/// class AnalysisUsage { public: typedef SmallVector<AnalysisID, 32> VectorType; private: - // Sets of analyses required and preserved by a pass + /// Sets of analyses required and preserved by a pass VectorType Required, RequiredTransitive, Preserved; bool PreservesAll; public: AnalysisUsage() : PreservesAll(false) {} - // addRequired - Add the specified ID to the required set of the usage info - // for a pass. - // + ///@{ + /// Add the specified ID to the required set of the usage info for a pass. AnalysisUsage &addRequiredID(const void *ID); AnalysisUsage &addRequiredID(char &ID); template<class PassClass> @@ -61,10 +60,10 @@ public: AnalysisUsage &addRequiredTransitive() { return addRequiredTransitiveID(PassClass::ID); } + ///@} - // addPreserved - Add the specified ID to the set of analyses preserved by - // this pass - // + ///@{ + /// Add the specified ID to the set of analyses preserved by this pass. AnalysisUsage &addPreservedID(const void *ID) { Preserved.push_back(ID); return *this; @@ -73,29 +72,28 @@ public: Preserved.push_back(&ID); return *this; } + ///@} - // addPreserved - Add the specified Pass class to the set of analyses - // preserved by this pass. - // + /// Add the specified Pass class to the set of analyses preserved by this pass. template<class PassClass> AnalysisUsage &addPreserved() { Preserved.push_back(&PassClass::ID); return *this; } - // addPreserved - Add the Pass with the specified argument string to the set - // of analyses preserved by this pass. If no such Pass exists, do nothing. - // This can be useful when a pass is trivially preserved, but may not be - // linked in. Be careful about spelling! - // + /// Add the Pass with the specified argument string to the set of analyses + /// preserved by this pass. If no such Pass exists, do nothing. This can be + /// useful when a pass is trivially preserved, but may not be linked in. Be + /// careful about spelling! AnalysisUsage &addPreserved(StringRef Arg); - // setPreservesAll - Set by analyses that do not transform their input at all + /// Set by analyses that do not transform their input at all void setPreservesAll() { PreservesAll = true; } + + /// Determine whether a pass said it does not transform its input at all bool getPreservesAll() const { return PreservesAll; } - /// setPreservesCFG - This function should be called by the pass, iff they do - /// not: + /// This function should be called by the pass, iff they do not: /// /// 1. Add or remove basic blocks from the function /// 2. Modify terminator instructions in any way. @@ -113,10 +111,10 @@ public: }; //===----------------------------------------------------------------------===// -// AnalysisResolver - Simple interface used by Pass objects to pull all -// analysis information out of pass manager that is responsible to manage -// the pass. -// +/// AnalysisResolver - Simple interface used by Pass objects to pull all +/// analysis information out of pass manager that is responsible to manage +/// the pass. +/// class PMDataManager; class AnalysisResolver { private: @@ -124,10 +122,10 @@ private: public: explicit AnalysisResolver(PMDataManager &P) : PM(P) { } - + inline PMDataManager &getPMDataManager() { return PM; } - // Find pass that is implementing PI. + /// Find pass that is implementing PI. Pass *findImplPass(AnalysisID PI) { Pass *ResultPass = nullptr; for (unsigned i = 0; i < AnalysisImpls.size() ; ++i) { @@ -139,7 +137,7 @@ public: return ResultPass; } - // Find pass that is implementing PI. Initialize pass for Function F. + /// Find pass that is implementing PI. Initialize pass for Function F. Pass *findImplPass(Pass *P, AnalysisID PI, Function &F); void addAnalysisImplsPair(AnalysisID PI, Pass *P) { @@ -149,21 +147,20 @@ public: AnalysisImpls.push_back(pir); } - /// clearAnalysisImpls - Clear cache that is used to connect a pass to the - /// the analysis (PassInfo). + /// Clear cache that is used to connect a pass to the the analysis (PassInfo). void clearAnalysisImpls() { AnalysisImpls.clear(); } - // getAnalysisIfAvailable - Return analysis result or null if it doesn't exist + /// Return analysis result or null if it doesn't exist. Pass *getAnalysisIfAvailable(AnalysisID ID, bool Direction) const; private: - // AnalysisImpls - This keeps track of which passes implements the interfaces - // that are required by the current pass (to implement getAnalysis()). + /// This keeps track of which passes implements the interfaces that are + /// required by the current pass (to implement getAnalysis()). std::vector<std::pair<AnalysisID, Pass*> > AnalysisImpls; - // PassManager that is used to resolve analysis info + /// PassManager that is used to resolve analysis info PMDataManager &PM; }; @@ -240,7 +237,7 @@ AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F) { // vector. Pass *ResultPass = Resolver->findImplPass(this, PI, F); assert(ResultPass && "Unable to find requested analysis info"); - + // Because the AnalysisType may not be a subclass of pass (for // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially // adjust the return pointer (because the class may multiply inherit, once @@ -248,6 +245,6 @@ AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F) { return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/PassInfo.h b/include/llvm/PassInfo.h index 6a2f942bbca7..d10761831b3a 100644 --- a/include/llvm/PassInfo.h +++ b/include/llvm/PassInfo.h @@ -142,6 +142,6 @@ private: PassInfo(const PassInfo &) = delete; }; -} // namespace llvm +} #endif diff --git a/include/llvm/PassRegistry.h b/include/llvm/PassRegistry.h index 0d2cd24e81a6..8c28ef5e7e61 100644 --- a/include/llvm/PassRegistry.h +++ b/include/llvm/PassRegistry.h @@ -95,6 +95,6 @@ public: // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassRegistry, LLVMPassRegistryRef) -} // namespace llvm +} #endif diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index af1a195dfd8c..6cb6516412e8 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -245,6 +245,6 @@ struct PassRegistrationListener { }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Passes/PassBuilder.h b/include/llvm/Passes/PassBuilder.h index bbf80f8ca4bf..1e605e374178 100644 --- a/include/llvm/Passes/PassBuilder.h +++ b/include/llvm/Passes/PassBuilder.h @@ -100,6 +100,6 @@ private: bool VerifyEachPass, bool DebugLogging); }; -} // namespace llvm +} #endif diff --git a/include/llvm/ProfileData/CoverageMapping.h b/include/llvm/ProfileData/CoverageMapping.h index 94e655c3edcb..3488e793d84f 100644 --- a/include/llvm/ProfileData/CoverageMapping.h +++ b/include/llvm/ProfileData/CoverageMapping.h @@ -410,7 +410,7 @@ public: /// \brief Load the coverage mapping from the given files. static ErrorOr<std::unique_ptr<CoverageMapping>> load(StringRef ObjectFilename, StringRef ProfileFilename, - Triple::ArchType Arch = Triple::ArchType::UnknownArch); + StringRef Arch = StringRef()); /// \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 020edbd3e6c1..38fb4680476b 100644 --- a/include/llvm/ProfileData/CoverageMappingReader.h +++ b/include/llvm/ProfileData/CoverageMappingReader.h @@ -171,7 +171,7 @@ private: public: static ErrorOr<std::unique_ptr<BinaryCoverageReader>> create(std::unique_ptr<MemoryBuffer> &ObjectBuffer, - Triple::ArchType Arch = Triple::ArchType::UnknownArch); + StringRef Arch); std::error_code readNextRecord(CoverageMappingRecord &Record) override; }; diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h index eafb76886c83..77055ba87268 100644 --- a/include/llvm/ProfileData/InstrProf.h +++ b/include/llvm/ProfileData/InstrProf.h @@ -16,7 +16,10 @@ #ifndef LLVM_PROFILEDATA_INSTRPROF_H_ #define LLVM_PROFILEDATA_INSTRPROF_H_ +#include "llvm/ADT/StringRef.h" +#include <cstdint> #include <system_error> +#include <vector> namespace llvm { const std::error_category &instrprof_category(); @@ -41,6 +44,16 @@ inline std::error_code make_error_code(instrprof_error E) { return std::error_code(static_cast<int>(E), instrprof_category()); } +/// Profiling information for a single function. +struct InstrProfRecord { + InstrProfRecord() {} + InstrProfRecord(StringRef Name, uint64_t Hash, std::vector<uint64_t> Counts) + : Name(Name), Hash(Hash), Counts(std::move(Counts)) {} + StringRef Name; + uint64_t Hash; + std::vector<uint64_t> Counts; +}; + } // end namespace llvm namespace std { diff --git a/include/llvm/ProfileData/InstrProfReader.h b/include/llvm/ProfileData/InstrProfReader.h index 63a6ac671f2b..f937e7d08d54 100644 --- a/include/llvm/ProfileData/InstrProfReader.h +++ b/include/llvm/ProfileData/InstrProfReader.h @@ -29,16 +29,6 @@ namespace llvm { class InstrProfReader; -/// Profiling information for a single function. -struct InstrProfRecord { - InstrProfRecord() {} - InstrProfRecord(StringRef Name, uint64_t Hash, ArrayRef<uint64_t> Counts) - : Name(Name), Hash(Hash), Counts(Counts) {} - StringRef Name; - uint64_t Hash; - ArrayRef<uint64_t> Counts; -}; - /// A file format agnostic iterator over profiling data. class InstrProfIterator : public std::iterator<std::input_iterator_tag, InstrProfRecord> { @@ -114,8 +104,6 @@ private: std::unique_ptr<MemoryBuffer> DataBuffer; /// Iterator over the profile data. line_iterator Line; - /// The current set of counter values. - std::vector<uint64_t> Counts; TextInstrProfReader(const TextInstrProfReader &) = delete; TextInstrProfReader &operator=(const TextInstrProfReader &) = delete; @@ -141,8 +129,6 @@ class RawInstrProfReader : public InstrProfReader { private: /// The profile data file contents. std::unique_ptr<MemoryBuffer> DataBuffer; - /// The current set of counter values. - std::vector<uint64_t> Counts; struct ProfileData { const uint32_t NameSize; const uint32_t NumCounters; @@ -206,17 +192,16 @@ enum class HashT : uint32_t; /// Trait for lookups into the on-disk hash table for the binary instrprof /// format. class InstrProfLookupTrait { - std::vector<uint64_t> DataBuffer; + std::vector<InstrProfRecord> DataBuffer; IndexedInstrProf::HashT HashType; + unsigned FormatVersion; + public: - InstrProfLookupTrait(IndexedInstrProf::HashT HashType) : HashType(HashType) {} + InstrProfLookupTrait(IndexedInstrProf::HashT HashType, unsigned FormatVersion) + : HashType(HashType), FormatVersion(FormatVersion) {} + + typedef ArrayRef<InstrProfRecord> data_type; - struct data_type { - data_type(StringRef Name, ArrayRef<uint64_t> Data) - : Name(Name), Data(Data) {} - StringRef Name; - ArrayRef<uint64_t> Data; - }; typedef StringRef internal_key_type; typedef StringRef external_key_type; typedef uint64_t hash_value_type; @@ -239,22 +224,9 @@ public: return StringRef((const char *)D, N); } - data_type ReadData(StringRef K, const unsigned char *D, offset_type N) { - DataBuffer.clear(); - if (N % sizeof(uint64_t)) - // The data is corrupt, don't try to read it. - return data_type("", DataBuffer); - - using namespace support; - // We just treat the data as opaque here. It's simpler to handle in - // IndexedInstrProfReader. - unsigned NumEntries = N / sizeof(uint64_t); - DataBuffer.reserve(NumEntries); - for (unsigned I = 0; I < NumEntries; ++I) - DataBuffer.push_back(endian::readNext<uint64_t, little, unaligned>(D)); - return data_type(K, DataBuffer); - } + data_type ReadData(StringRef K, const unsigned char *D, offset_type N); }; + typedef OnDiskIterableChainedHashTable<InstrProfLookupTrait> InstrProfReaderIndex; @@ -267,8 +239,6 @@ private: std::unique_ptr<InstrProfReaderIndex> Index; /// Iterator over the profile data. InstrProfReaderIndex::data_iterator RecordIterator; - /// Offset into our current data set. - size_t CurrentOffset; /// The file format version of the profile data. uint64_t FormatVersion; /// The maximal execution count among all functions. @@ -278,7 +248,7 @@ private: IndexedInstrProfReader &operator=(const IndexedInstrProfReader &) = delete; public: IndexedInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer) - : DataBuffer(std::move(DataBuffer)), Index(nullptr), CurrentOffset(0) {} + : DataBuffer(std::move(DataBuffer)), Index(nullptr) {} /// Return true if the given buffer is in an indexed instrprof format. static bool hasFormat(const MemoryBuffer &DataBuffer); diff --git a/include/llvm/Support/ARMEHABI.h b/include/llvm/Support/ARMEHABI.h index db045a8a3efa..9b052df0a908 100644 --- a/include/llvm/Support/ARMEHABI.h +++ b/include/llvm/Support/ARMEHABI.h @@ -127,8 +127,8 @@ namespace EHABI { NUM_PERSONALITY_INDEX }; -} // namespace EHABI -} // namespace ARM -} // namespace llvm +} +} +} #endif diff --git a/include/llvm/Support/ARMWinEH.h b/include/llvm/Support/ARMWinEH.h index 0b379032c200..1463629f45dc 100644 --- a/include/llvm/Support/ARMWinEH.h +++ b/include/llvm/Support/ARMWinEH.h @@ -375,8 +375,8 @@ struct ExceptionDataRecord { inline size_t HeaderWords(const ExceptionDataRecord &XR) { return (XR.Data[0] & 0xff800000) ? 1 : 2; } -} // namespace WinEH -} // namespace ARM -} // namespace llvm +} +} +} #endif diff --git a/include/llvm/Support/ArrayRecycler.h b/include/llvm/Support/ArrayRecycler.h index 5907c79db2be..36f644af2880 100644 --- a/include/llvm/Support/ArrayRecycler.h +++ b/include/llvm/Support/ArrayRecycler.h @@ -138,6 +138,6 @@ public: } }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/Support/Atomic.h b/include/llvm/Support/Atomic.h index a3cec47563b8..9ec23e827023 100644 --- a/include/llvm/Support/Atomic.h +++ b/include/llvm/Support/Atomic.h @@ -33,7 +33,7 @@ namespace llvm { cas_flag AtomicAdd(volatile cas_flag* ptr, cas_flag val); cas_flag AtomicMul(volatile cas_flag* ptr, cas_flag val); cas_flag AtomicDiv(volatile cas_flag* ptr, cas_flag val); - } // namespace sys -} // namespace llvm + } +} #endif diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h index 20b2782ad61a..4304a253b287 100644 --- a/include/llvm/Support/BlockFrequency.h +++ b/include/llvm/Support/BlockFrequency.h @@ -69,6 +69,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h index df89d2dd4da9..a6429dd22a3b 100644 --- a/include/llvm/Support/BranchProbability.h +++ b/include/llvm/Support/BranchProbability.h @@ -84,6 +84,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, const BranchProbability &Prob) { return Prob.print(OS); } -} // namespace llvm +} #endif diff --git a/include/llvm/Support/COM.h b/include/llvm/Support/COM.h index 45559b0ec149..a2d5a7a68ba9 100644 --- a/include/llvm/Support/COM.h +++ b/include/llvm/Support/COM.h @@ -30,7 +30,7 @@ private: InitializeCOMRAII(const InitializeCOMRAII &) = delete; void operator=(const InitializeCOMRAII &) = delete; }; -} // namespace sys -} // namespace llvm +} +} #endif diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index e84676abc779..6ba5efa47554 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -321,6 +321,6 @@ dyn_cast_or_null(Y *Val) { return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Support/CodeGen.h b/include/llvm/Support/CodeGen.h index 1eca5681e449..243f2dd7498c 100644 --- a/include/llvm/Support/CodeGen.h +++ b/include/llvm/Support/CodeGen.h @@ -90,6 +90,6 @@ namespace llvm { } llvm_unreachable("Bad CodeModel!"); } -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h index 13aff7a37b7a..c08c3c1f0d21 100644 --- a/include/llvm/Support/CrashRecoveryContext.h +++ b/include/llvm/Support/CrashRecoveryContext.h @@ -199,6 +199,6 @@ public: cleanup = 0; } }; -} // namespace llvm +} #endif diff --git a/include/llvm/Support/DOTGraphTraits.h b/include/llvm/Support/DOTGraphTraits.h index 3d21129066ec..95e37c01d7d5 100644 --- a/include/llvm/Support/DOTGraphTraits.h +++ b/include/llvm/Support/DOTGraphTraits.h @@ -161,6 +161,6 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits { DOTGraphTraits (bool simple=false) : DefaultDOTGraphTraits (simple) {} }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Support/DataStream.h b/include/llvm/Support/DataStream.h index 9a4daec1e9cc..a544316f430d 100644 --- a/include/llvm/Support/DataStream.h +++ b/include/llvm/Support/DataStream.h @@ -33,6 +33,6 @@ public: std::unique_ptr<DataStreamer> getDataFileStreamer(const std::string &Filename, std::string *Err); -} // namespace llvm +} #endif // LLVM_SUPPORT_DATASTREAM_H_ diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h index 2f3fe77f0e50..fff4f986a6c0 100644 --- a/include/llvm/Support/Debug.h +++ b/include/llvm/Support/Debug.h @@ -91,6 +91,6 @@ raw_ostream &dbgs(); // #define DEBUG(X) DEBUG_WITH_TYPE(DEBUG_TYPE, X) -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index c3d94d19f919..17e9c1540a41 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -239,6 +239,11 @@ enum Attribute : uint16_t { DW_AT_GNU_pubnames = 0x2134, DW_AT_GNU_pubtypes = 0x2135, + // LLVM project extensions. + DW_AT_LLVM_include_path = 0x3e00, + DW_AT_LLVM_config_macros = 0x3e01, + DW_AT_LLVM_isysroot = 0x3e02, + // Apple extensions. DW_AT_APPLE_optimized = 0x3fe1, DW_AT_APPLE_flags = 0x3fe2, diff --git a/include/llvm/Support/DynamicLibrary.h b/include/llvm/Support/DynamicLibrary.h index d6ff9043c46a..a7d22212dbdb 100644 --- a/include/llvm/Support/DynamicLibrary.h +++ b/include/llvm/Support/DynamicLibrary.h @@ -99,7 +99,7 @@ namespace sys { static void AddSymbol(StringRef symbolName, void *symbolValue); }; -} // namespace sys -} // namespace llvm +} // End sys namespace +} // End llvm namespace #endif diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index e23fcbb5eb8c..94a4bfb22025 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -308,7 +308,8 @@ enum { EM_COGE = 216, // Cognitive Smart Memory Processor EM_COOL = 217, // iCelero CoolEngine EM_NORC = 218, // Nanoradio Optimized RISC - EM_CSR_KALIMBA = 219 // CSR Kalimba architecture family + EM_CSR_KALIMBA = 219, // CSR Kalimba architecture family + EM_AMDGPU = 224 // AMD GPU architecture }; // Object file classes. @@ -346,6 +347,7 @@ enum { ELFOSABI_FENIXOS = 16, // FenixOS ELFOSABI_CLOUDABI = 17, // Nuxi CloudABI ELFOSABI_C6000_ELFABI = 64, // Bare-metal TMS320C6000 + ELFOSABI_AMDGPU_HSA = 64, // AMD HSA runtime ELFOSABI_C6000_LINUX = 65, // Linux TMS320C6000 ELFOSABI_ARM = 97, // ARM ELFOSABI_STANDALONE = 255 // Standalone (embedded) application @@ -822,9 +824,9 @@ enum { STT_FILE = 4, // Local, absolute symbol that refers to a file STT_COMMON = 5, // An uninitialized common block STT_TLS = 6, // Thread local data object - STT_LOOS = 7, // Lowest operating system-specific symbol type - STT_HIOS = 8, // Highest operating system-specific symbol type STT_GNU_IFUNC = 10, // GNU indirect function + STT_LOOS = 10, // Lowest operating system-specific symbol type + STT_HIOS = 12, // Highest operating system-specific symbol type STT_LOPROC = 13, // Lowest processor-specific symbol type STT_HIPROC = 15 // Highest processor-specific symbol type }; diff --git a/include/llvm/Support/Errc.h b/include/llvm/Support/Errc.h index 7efca026d1e4..80bfe2ac2ee5 100644 --- a/include/llvm/Support/Errc.h +++ b/include/llvm/Support/Errc.h @@ -78,7 +78,7 @@ enum class errc { inline std::error_code make_error_code(errc E) { return std::error_code(static_cast<int>(E), std::generic_category()); } -} // namespace llvm +} namespace std { template <> struct is_error_code_enum<llvm::errc> : std::true_type {}; diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h index 427d8ea2c570..9afd52d1abc7 100644 --- a/include/llvm/Support/ErrorHandling.h +++ b/include/llvm/Support/ErrorHandling.h @@ -84,7 +84,7 @@ namespace llvm { LLVM_ATTRIBUTE_NORETURN void llvm_unreachable_internal(const char *msg=nullptr, const char *file=nullptr, unsigned line=0); -} // namespace llvm +} /// Marks that the current location is not supposed to be reachable. /// In !NDEBUG builds, prints the message and location info to stderr. diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index 5a857e41b95a..a736c324f8aa 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -724,7 +724,7 @@ namespace detail { intptr_t IterationHandle; directory_entry CurrentEntry; }; -} // namespace detail +} /// directory_iterator - Iterates through the entries in path. There is no /// operator++ because we need an error_code. If it's really needed we can make @@ -786,7 +786,7 @@ namespace detail { uint16_t Level; bool HasNoPushRequest; }; -} // namespace detail +} /// recursive_directory_iterator - Same as directory_iterator except for it /// recurses down into child directories. diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h index 8a790dece225..2ee2c60b9964 100644 --- a/include/llvm/Support/FileUtilities.h +++ b/include/llvm/Support/FileUtilities.h @@ -73,6 +73,6 @@ namespace llvm { /// will not be removed when the object is destroyed. void releaseFile() { DeleteIt = false; } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h index 145d8984a418..4a135cd23174 100644 --- a/include/llvm/Support/FormattedStream.h +++ b/include/llvm/Support/FormattedStream.h @@ -156,7 +156,7 @@ formatted_raw_ostream &ferrs(); /// debug output. Use it like: fdbgs() << "foo" << "bar"; formatted_raw_ostream &fdbgs(); -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h index 138b9dbe0a37..c2e34bd3eaeb 100644 --- a/include/llvm/Support/GCOV.h +++ b/include/llvm/Support/GCOV.h @@ -435,6 +435,6 @@ private: FileCoverageList FileCoverages; FuncCoverageMap FuncCoverages; }; -} // namespace llvm +} #endif diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h index cd59f82eea72..63678bb98bb1 100644 --- a/include/llvm/Support/GenericDomTree.h +++ b/include/llvm/Support/GenericDomTree.h @@ -772,6 +772,6 @@ bool DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, getNode(const_cast<NodeT *>(B))); } -} // namespace llvm +} #endif diff --git a/include/llvm/Support/GenericDomTreeConstruction.h b/include/llvm/Support/GenericDomTreeConstruction.h index 76e3cc8af40c..7c065f939256 100644 --- a/include/llvm/Support/GenericDomTreeConstruction.h +++ b/include/llvm/Support/GenericDomTreeConstruction.h @@ -288,6 +288,6 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT, DT.updateDFSNumbers(); } -} // namespace llvm +} #endif diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h index 04b40848cb76..b1af3d7c2632 100644 --- a/include/llvm/Support/GraphWriter.h +++ b/include/llvm/Support/GraphWriter.h @@ -353,9 +353,9 @@ void ViewGraph(const GraphType &G, const Twine &Name, if (Filename.empty()) return; - DisplayGraph(Filename, true, Program); + DisplayGraph(Filename, false, Program); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Support/Host.h b/include/llvm/Support/Host.h index f2519df41aa2..8f4bf3c1ba56 100644 --- a/include/llvm/Support/Host.h +++ b/include/llvm/Support/Host.h @@ -68,7 +68,7 @@ namespace sys { /// /// \return - True on success. bool getHostCPUFeatures(StringMap<bool> &Features); -} // namespace sys -} // namespace llvm +} +} #endif diff --git a/include/llvm/Support/LineIterator.h b/include/llvm/Support/LineIterator.h index d0f7d30a7076..9d4cd3bd4c6d 100644 --- a/include/llvm/Support/LineIterator.h +++ b/include/llvm/Support/LineIterator.h @@ -83,6 +83,6 @@ private: /// \brief Advance the iterator to the next line. void advance(); }; -} // namespace llvm +} #endif diff --git a/include/llvm/Support/MD5.h b/include/llvm/Support/MD5.h index 8658c8ef5c24..f6e1e92c9fa8 100644 --- a/include/llvm/Support/MD5.h +++ b/include/llvm/Support/MD5.h @@ -65,6 +65,6 @@ private: const uint8_t *body(ArrayRef<uint8_t> Data); }; -} // namespace llvm +} #endif diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h index 1187e055aadd..addd34e704bc 100644 --- a/include/llvm/Support/ManagedStatic.h +++ b/include/llvm/Support/ManagedStatic.h @@ -106,6 +106,6 @@ struct llvm_shutdown_obj { ~llvm_shutdown_obj() { llvm_shutdown(); } }; -} // namespace llvm +} #endif diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index 7c63aaa06998..2cf7e0e5d0b3 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -642,6 +642,6 @@ inline int64_t SignExtend64(uint64_t X, unsigned B) { } extern const float huge_valf; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h index 6abb17aff8c6..b4305cb697d0 100644 --- a/include/llvm/Support/Memory.h +++ b/include/llvm/Support/Memory.h @@ -155,7 +155,7 @@ namespace sys { /// as writable. static bool setRangeWritable(const void *Addr, size_t Size); }; -} // namespace sys -} // namespace llvm +} +} #endif diff --git a/include/llvm/Support/MemoryObject.h b/include/llvm/Support/MemoryObject.h index deff6c1c667f..e0c8749da346 100644 --- a/include/llvm/Support/MemoryObject.h +++ b/include/llvm/Support/MemoryObject.h @@ -63,6 +63,6 @@ public: virtual bool isValidAddress(uint64_t address) const = 0; }; -} // namespace llvm +} #endif diff --git a/include/llvm/Support/MipsABIFlags.h b/include/llvm/Support/MipsABIFlags.h index 8740823dac42..93f6b416ba88 100644 --- a/include/llvm/Support/MipsABIFlags.h +++ b/include/llvm/Support/MipsABIFlags.h @@ -96,7 +96,7 @@ enum Val_GNU_MIPS_ABI_MSA { Val_GNU_MIPS_ABI_MSA_ANY = 0, // not tagged Val_GNU_MIPS_ABI_MSA_128 = 1 // 128-bit MSA }; -} // namespace Mips -} // namespace llvm +} +} #endif diff --git a/include/llvm/Support/Mutex.h b/include/llvm/Support/Mutex.h index 47f0ab6d5c6f..0f4e61af4439 100644 --- a/include/llvm/Support/Mutex.h +++ b/include/llvm/Support/Mutex.h @@ -152,7 +152,7 @@ namespace llvm }; typedef SmartScopedLock<false> ScopedLock; - } // namespace sys -} // namespace llvm + } +} #endif diff --git a/include/llvm/Support/MutexGuard.h b/include/llvm/Support/MutexGuard.h index ea5861761acd..07b64b611960 100644 --- a/include/llvm/Support/MutexGuard.h +++ b/include/llvm/Support/MutexGuard.h @@ -36,6 +36,6 @@ namespace llvm { /// is held. bool holds(const sys::Mutex& lock) const { return &M == &lock; } }; -} // namespace llvm +} #endif // LLVM_SUPPORT_MUTEXGUARD_H diff --git a/include/llvm/Support/PluginLoader.h b/include/llvm/Support/PluginLoader.h index da4324e6c13f..bdbb134b28eb 100644 --- a/include/llvm/Support/PluginLoader.h +++ b/include/llvm/Support/PluginLoader.h @@ -32,6 +32,6 @@ namespace llvm { LoadOpt("load", cl::ZeroOrMore, cl::value_desc("pluginfilename"), cl::desc("Load the specified plugin")); #endif -} // namespace llvm +} #endif diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h index 089894cf9020..cfdd06c62f33 100644 --- a/include/llvm/Support/Process.h +++ b/include/llvm/Support/Process.h @@ -184,7 +184,7 @@ public: static unsigned GetRandomNumber(); }; -} // namespace sys -} // namespace llvm +} +} #endif diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h index 5f1bc12601b1..b89a0f73ec68 100644 --- a/include/llvm/Support/Program.h +++ b/include/llvm/Support/Program.h @@ -187,7 +187,7 @@ struct ProcessInfo { ///< string is non-empty upon return an error occurred while invoking the ///< program. ); - } // namespace sys -} // namespace llvm + } +} #endif diff --git a/include/llvm/Support/RWMutex.h b/include/llvm/Support/RWMutex.h index 5299708c6a6a..4be931337765 100644 --- a/include/llvm/Support/RWMutex.h +++ b/include/llvm/Support/RWMutex.h @@ -171,7 +171,7 @@ namespace llvm } }; typedef SmartScopedWriter<false> ScopedWriter; - } // namespace sys -} // namespace llvm + } +} #endif diff --git a/include/llvm/Support/RandomNumberGenerator.h b/include/llvm/Support/RandomNumberGenerator.h index 316778b00e5e..7446558f0c88 100644 --- a/include/llvm/Support/RandomNumberGenerator.h +++ b/include/llvm/Support/RandomNumberGenerator.h @@ -53,6 +53,6 @@ private: friend class Module; }; -} // namespace llvm +} #endif diff --git a/include/llvm/Support/Recycler.h b/include/llvm/Support/Recycler.h index a909b9d57376..e97f36a735fd 100644 --- a/include/llvm/Support/Recycler.h +++ b/include/llvm/Support/Recycler.h @@ -123,6 +123,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/include/llvm/Support/RecyclingAllocator.h b/include/llvm/Support/RecyclingAllocator.h index fded4edcad44..001d1cf7c3df 100644 --- a/include/llvm/Support/RecyclingAllocator.h +++ b/include/llvm/Support/RecyclingAllocator.h @@ -57,7 +57,7 @@ public: } }; -} // namespace llvm +} template<class AllocatorType, class T, size_t Size, size_t Align> inline void *operator new(size_t size, diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h index 15f20a668ae5..31b35ed0cad6 100644 --- a/include/llvm/Support/Regex.h +++ b/include/llvm/Support/Regex.h @@ -100,6 +100,6 @@ namespace llvm { struct llvm_regex *preg; int error; }; -} // namespace llvm +} #endif // LLVM_SUPPORT_REGEX_H diff --git a/include/llvm/Support/Registry.h b/include/llvm/Support/Registry.h index 7eb1090a393b..95c4e96f7f29 100644 --- a/include/llvm/Support/Registry.h +++ b/include/llvm/Support/Registry.h @@ -228,6 +228,6 @@ namespace llvm { template <typename T, typename U> typename Registry<T,U>::listener *Registry<T,U>::ListenerTail; -} // namespace llvm +} #endif diff --git a/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h index 0cb421bcf32b..7e165d7f3a42 100644 --- a/include/llvm/Support/Signals.h +++ b/include/llvm/Support/Signals.h @@ -62,7 +62,7 @@ namespace sys { /// different thread on some platforms. /// @brief Register a function to be called when ctrl-c is pressed. void SetInterruptFunction(void (*IF)()); -} // namespace sys -} // namespace llvm +} // End sys namespace +} // End llvm namespace #endif diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index 5eef9a075c46..1f8b1a01865f 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -280,6 +280,6 @@ public: bool ShowKindLabel = true) const; }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/Support/StreamingMemoryObject.h b/include/llvm/Support/StreamingMemoryObject.h index fe0cc7e71f97..7cb6438d1342 100644 --- a/include/llvm/Support/StreamingMemoryObject.h +++ b/include/llvm/Support/StreamingMemoryObject.h @@ -89,5 +89,5 @@ private: MemoryObject *getNonStreamedMemoryObject( const unsigned char *Start, const unsigned char *End); -} // namespace llvm +} #endif // STREAMINGMEMORYOBJECT_H_ diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h index 3aa826b5ae9f..2ec0c3b76c11 100644 --- a/include/llvm/Support/StringPool.h +++ b/include/llvm/Support/StringPool.h @@ -133,6 +133,6 @@ namespace llvm { inline bool operator!=(const PooledStringPtr &That) const { return S != That.S; } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Support/StringSaver.h b/include/llvm/Support/StringSaver.h index c7a2e8f48e86..f3853ee91570 100644 --- a/include/llvm/Support/StringSaver.h +++ b/include/llvm/Support/StringSaver.h @@ -38,5 +38,5 @@ class BumpPtrStringSaver final : public StringSaver { public: BumpPtrStringSaver(BumpPtrAllocator &Alloc) : StringSaver(Alloc) {} }; -} // namespace llvm +} #endif diff --git a/include/llvm/Support/SystemUtils.h b/include/llvm/Support/SystemUtils.h index f8c5dc85a5e9..2997b1b0c9cf 100644 --- a/include/llvm/Support/SystemUtils.h +++ b/include/llvm/Support/SystemUtils.h @@ -27,6 +27,6 @@ bool CheckBitcodeOutputToConsole( bool print_warning = true ///< Control whether warnings are printed ); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Support/TargetParser.h b/include/llvm/Support/TargetParser.h index 777ee2075d61..dab724895e86 100644 --- a/include/llvm/Support/TargetParser.h +++ b/include/llvm/Support/TargetParser.h @@ -36,7 +36,11 @@ namespace ARM { FK_VFP, FK_VFPV2, FK_VFPV3, + FK_VFPV3_FP16, FK_VFPV3_D16, + FK_VFPV3_D16_FP16, + FK_VFPV3XD, + FK_VFPV3XD_FP16, FK_VFPV4, FK_VFPV4_D16, FK_FPV4_SP_D16, @@ -44,6 +48,7 @@ namespace ARM { FK_FPV5_SP_D16, FK_FP_ARMV8, FK_NEON, + FK_NEON_FP16, FK_NEON_VFPV4, FK_NEON_FP_ARMV8, FK_CRYPTO_NEON_FP_ARMV8, @@ -51,6 +56,16 @@ namespace ARM { FK_LAST }; + // FPU Version + enum FPUVersion { + FV_NONE = 0, + FV_VFPV2, + FV_VFPV3, + FV_VFPV3_FP16, + FV_VFPV4, + FV_VFPV5 + }; + // An FPU name implies one of three levels of Neon support: enum NeonSupportLevel { NS_None = 0, ///< No Neon diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index 1c11ef31f82c..d2e8b95d74f3 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -1178,6 +1178,6 @@ private: return new MCCodeEmitterImpl(); } }; -} // namespace llvm +} #endif diff --git a/include/llvm/Support/TargetSelect.h b/include/llvm/Support/TargetSelect.h index 96ecf0b5e5c6..a86e953f00ea 100644 --- a/include/llvm/Support/TargetSelect.h +++ b/include/llvm/Support/TargetSelect.h @@ -161,6 +161,6 @@ namespace llvm { #endif } -} // namespace llvm +} #endif diff --git a/include/llvm/Support/ThreadLocal.h b/include/llvm/Support/ThreadLocal.h index db61f5c17b96..427a67e2a96d 100644 --- a/include/llvm/Support/ThreadLocal.h +++ b/include/llvm/Support/ThreadLocal.h @@ -57,7 +57,7 @@ namespace llvm { // erase - Removes the pointer associated with the current thread. void erase() { removeInstance(); } }; - } // namespace sys -} // namespace llvm + } +} #endif diff --git a/include/llvm/Support/Threading.h b/include/llvm/Support/Threading.h index 365fb9ee9b8e..3cca1d6a9913 100644 --- a/include/llvm/Support/Threading.h +++ b/include/llvm/Support/Threading.h @@ -34,6 +34,6 @@ namespace llvm { /// the thread stack. void llvm_execute_on_thread(void (*UserFn)(void*), void *UserData, unsigned RequestedStackSize = 0); -} // namespace llvm +} #endif diff --git a/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h index a9efb1b9f78e..6bca58b6bc20 100644 --- a/include/llvm/Support/TimeValue.h +++ b/include/llvm/Support/TimeValue.h @@ -380,7 +380,7 @@ inline TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2) { return difference; } -} // namespace sys -} // namespace llvm +} +} #endif diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h index 56fbcccc5cd9..2cd30e2aaf32 100644 --- a/include/llvm/Support/Timer.h +++ b/include/llvm/Support/Timer.h @@ -184,6 +184,6 @@ private: void PrintQueuedTimers(raw_ostream &OS); }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Support/ToolOutputFile.h b/include/llvm/Support/ToolOutputFile.h index e7a65456e3de..1be26c2cb58b 100644 --- a/include/llvm/Support/ToolOutputFile.h +++ b/include/llvm/Support/ToolOutputFile.h @@ -58,6 +58,6 @@ public: void keep() { Installer.Keep = true; } }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/Support/UniqueLock.h b/include/llvm/Support/UniqueLock.h index c5f37a7b8ce0..529284d3868b 100644 --- a/include/llvm/Support/UniqueLock.h +++ b/include/llvm/Support/UniqueLock.h @@ -62,6 +62,6 @@ namespace llvm { bool owns_lock() { return locked; } }; -} // namespace llvm +} #endif // LLVM_SUPPORT_UNIQUE_LOCK_H diff --git a/include/llvm/Support/Valgrind.h b/include/llvm/Support/Valgrind.h index 7eabca93d6b4..cebf75c49c19 100644 --- a/include/llvm/Support/Valgrind.h +++ b/include/llvm/Support/Valgrind.h @@ -67,7 +67,7 @@ namespace sys { #define TsanIgnoreWritesBegin() #define TsanIgnoreWritesEnd() #endif -} // namespace sys -} // namespace llvm +} +} #endif diff --git a/include/llvm/Support/Watchdog.h b/include/llvm/Support/Watchdog.h index 5642ae2e2322..01e1d926eb95 100644 --- a/include/llvm/Support/Watchdog.h +++ b/include/llvm/Support/Watchdog.h @@ -32,7 +32,7 @@ namespace llvm { Watchdog(const Watchdog &other) = delete; Watchdog &operator=(const Watchdog &other) = delete; }; - } // namespace sys -} // namespace llvm + } +} #endif diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h index 89d6421e1e33..19f9c2c4b155 100644 --- a/include/llvm/Support/circular_raw_ostream.h +++ b/include/llvm/Support/circular_raw_ostream.h @@ -152,7 +152,7 @@ namespace llvm delete TheStream; } }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h index c13e7792821b..a983aeb90879 100644 --- a/include/llvm/Support/raw_os_ostream.h +++ b/include/llvm/Support/raw_os_ostream.h @@ -37,6 +37,6 @@ public: ~raw_os_ostream() override; }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 4b4f933aa017..b59317112c44 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -545,6 +545,6 @@ public: ~buffer_ostream() { OS << str(); } }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h index 6e2e202b0f2d..45465aea004b 100644 --- a/include/llvm/Support/type_traits.h +++ b/include/llvm/Support/type_traits.h @@ -91,7 +91,7 @@ struct add_const_past_pointer< typedef const typename std::remove_pointer<T>::type *type; }; -} // namespace llvm +} #ifdef LLVM_DEFINED_HAS_FEATURE #undef __has_feature diff --git a/include/llvm/TableGen/Error.h b/include/llvm/TableGen/Error.h index 2ecc9d26792c..3df658df8809 100644 --- a/include/llvm/TableGen/Error.h +++ b/include/llvm/TableGen/Error.h @@ -34,6 +34,6 @@ LLVM_ATTRIBUTE_NORETURN void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, extern SourceMgr SrcMgr; extern unsigned ErrorsPrinted; -} // namespace llvm +} // end namespace "llvm" #endif diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index c5a43018d667..717a2a4ba62a 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -1161,7 +1161,7 @@ class Record { // Tracks Record instances. Not owned by Record. RecordKeeper &TrackedRecords; - DefInit *TheInit; + std::unique_ptr<DefInit> TheInit; bool IsAnonymous; // Class-instance values can be used by other defs. For example, Struct<i> @@ -1184,8 +1184,7 @@ public: explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records, bool Anonymous = false) : ID(LastID++), Name(N), Locs(locs.begin(), locs.end()), - TrackedRecords(records), TheInit(nullptr), IsAnonymous(Anonymous), - ResolveFirst(false) { + TrackedRecords(records), IsAnonymous(Anonymous), ResolveFirst(false) { init(); } explicit Record(const std::string &N, ArrayRef<SMLoc> locs, @@ -1194,12 +1193,13 @@ public: // When copy-constructing a Record, we must still guarantee a globally unique - // ID number. All other fields can be copied normally. + // ID number. Don't copy TheInit either since it's owned by the original + // record. All other fields can be copied normally. Record(const Record &O) : ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs), Values(O.Values), SuperClasses(O.SuperClasses), SuperClassRanges(O.SuperClassRanges), TrackedRecords(O.TrackedRecords), - TheInit(O.TheInit), IsAnonymous(O.IsAnonymous), + IsAnonymous(O.IsAnonymous), ResolveFirst(O.ResolveFirst) { } static unsigned getNewUID() { return LastID++; } @@ -1589,6 +1589,6 @@ Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass, Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass, const std::string &Name, const std::string &Scoper); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/TableGen/StringMatcher.h b/include/llvm/TableGen/StringMatcher.h index 5a77f5ee3d29..b43877910834 100644 --- a/include/llvm/TableGen/StringMatcher.h +++ b/include/llvm/TableGen/StringMatcher.h @@ -49,6 +49,6 @@ private: unsigned CharNo, unsigned IndentCount) const; }; -} // namespace llvm +} // end llvm namespace. #endif diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h index 11a2cfdf815b..9d4e7a04d905 100644 --- a/include/llvm/Target/TargetCallingConv.h +++ b/include/llvm/Target/TargetCallingConv.h @@ -190,8 +190,8 @@ namespace ISD { ArgVT = argvt; } }; -} // namespace ISD +} -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h index 2e8fe217fd12..0e317247a59f 100644 --- a/include/llvm/Target/TargetFrameLowering.h +++ b/include/llvm/Target/TargetFrameLowering.h @@ -283,6 +283,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index ec7aef3e5aa0..8b314f454b18 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -1270,6 +1270,6 @@ private: unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Target/TargetIntrinsicInfo.h b/include/llvm/Target/TargetIntrinsicInfo.h index 373295930288..c630f5b12a15 100644 --- a/include/llvm/Target/TargetIntrinsicInfo.h +++ b/include/llvm/Target/TargetIntrinsicInfo.h @@ -60,6 +60,6 @@ public: unsigned numTys = 0) const = 0; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index a536e004c0ea..277487fee6bc 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1235,11 +1235,10 @@ protected: HasExtractBitsInsn = hasExtractInsn; } - /// Tells the code generator not to expand sequence of operations into a - /// separate sequences that increases the amount of flow control. - void setJumpIsExpensive(bool isExpensive = true) { - JumpIsExpensive = isExpensive; - } + /// Tells the code generator not to expand logic operations on comparison + /// predicates into separate sequences that increase the amount of flow + /// control. + void setJumpIsExpensive(bool isExpensive = true); /// Tells the code generator that integer divide is expensive, and if /// possible, should be replaced by an alternate sequence of instructions not @@ -1597,6 +1596,35 @@ public: return false; } + /// \brief Get the maximum supported factor for interleaved memory accesses. + /// Default to be the minimum interleave factor: 2. + virtual unsigned getMaxSupportedInterleaveFactor() const { return 2; } + + /// \brief Lower an interleaved load to target specific intrinsics. Return + /// true on success. + /// + /// \p LI is the vector load instruction. + /// \p Shuffles is the shufflevector list to DE-interleave the loaded vector. + /// \p Indices is the corresponding indices for each shufflevector. + /// \p Factor is the interleave factor. + virtual bool lowerInterleavedLoad(LoadInst *LI, + ArrayRef<ShuffleVectorInst *> Shuffles, + ArrayRef<unsigned> Indices, + unsigned Factor) const { + return false; + } + + /// \brief Lower an interleaved store to target specific intrinsics. Return + /// true on success. + /// + /// \p SI is the vector store instruction. + /// \p SVI is the shufflevector to RE-interleave the stored vector. + /// \p Factor is the interleave factor. + virtual bool lowerInterleavedStore(StoreInst *SI, ShuffleVectorInst *SVI, + unsigned Factor) const { + return false; + } + /// Return true if zero-extending the specific node Val to type VT2 is free /// (either because it's implicitly zero-extended such as ARM ldrb / ldrh or /// because it's folded such as X86 zero-extending loads). @@ -2689,8 +2717,6 @@ public: //===--------------------------------------------------------------------===// // Div utility functions // - SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, SDLoc dl, - SelectionDAG &DAG) const; SDValue BuildSDIV(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, bool IsAfterLegalization, std::vector<SDNode *> *Created) const; @@ -2801,6 +2827,6 @@ void GetReturnInfo(Type* ReturnType, AttributeSet attr, SmallVectorImpl<ISD::OutputArg> &Outs, const TargetLowering &TLI); -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 2a17bd200f4d..5b626c244ba0 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -64,12 +64,6 @@ public: const TargetMachine &TM, const MCSymbol *Sym) const; - /// Extract the dependent library name from a linker option string. Returns - /// StringRef() if the option does not specify a library. - virtual StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const { - return StringRef(); - } - /// Emit the module flags that the platform cares about. virtual void emitModuleFlags(MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> Flags, @@ -188,6 +182,9 @@ public: return nullptr; } + virtual void emitLinkerFlagsForGlobal(raw_ostream &OS, const GlobalValue *GV, + const Mangler &Mang) const {} + protected: virtual MCSection *SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler &Mang, diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 768157549043..64a923b80edf 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -273,6 +273,6 @@ public: bool DisableVerify = true) override; }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index f27411e47412..d52cb60cf108 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -72,7 +72,7 @@ namespace llvm { UseInitArray(false), DisableIntegratedAS(false), CompressDebugSections(false), FunctionSections(false), DataSections(false), UniqueSectionNames(true), TrapUnreachable(false), - TrapFuncName(), FloatABIType(FloatABI::Default), + FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard), Reciprocals(TargetRecip()), JTType(JumpTable::Single), ThreadModel(ThreadModel::POSIX) {} @@ -172,12 +172,6 @@ namespace llvm { /// Emit target-specific trap instruction for 'unreachable' IR instructions. unsigned TrapUnreachable : 1; - /// getTrapFunctionName - If this returns a non-empty string, this means - /// isel should lower Intrinsic::trap to a call to the specified function - /// name instead of an ISD::TRAP node. - std::string TrapFuncName; - StringRef getTrapFunctionName() const; - /// FloatABIType - This setting is set by -float-abi=xxx option is specfied /// on the command line. This setting may either be Default, Soft, or Hard. /// Default selects the target's default behavior. Soft selects the ABI for @@ -237,7 +231,6 @@ inline bool operator==(const TargetOptions &LHS, ARE_EQUAL(PositionIndependentExecutable) && ARE_EQUAL(UseInitArray) && ARE_EQUAL(TrapUnreachable) && - ARE_EQUAL(TrapFuncName) && ARE_EQUAL(FloatABIType) && ARE_EQUAL(AllowFPOpFusion) && ARE_EQUAL(Reciprocals) && @@ -252,6 +245,6 @@ inline bool operator!=(const TargetOptions &LHS, return !(LHS == RHS); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Target/TargetRecip.h b/include/llvm/Target/TargetRecip.h index c3beb40fca00..4cc3672d758d 100644 --- a/include/llvm/Target/TargetRecip.h +++ b/include/llvm/Target/TargetRecip.h @@ -68,6 +68,6 @@ private: void parseIndividualParams(const std::vector<std::string> &Args); }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 1377b38799b6..0ee936a76211 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -469,6 +469,10 @@ public: return nullptr; } + /// Return all the call-preserved register masks defined for this target. + virtual ArrayRef<const uint32_t *> getRegMasks() const = 0; + virtual ArrayRef<const char *> getRegMaskNames() const = 0; + /// getReservedRegs - Returns a bitset indexed by physical register number /// indicating if a register is a special register that has particular uses /// and should be considered unavailable at all times, e.g. SP, RA. This is @@ -998,6 +1002,6 @@ static inline raw_ostream &operator<<(raw_ostream &OS, return OS; } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 7a788cef0237..4abbe3793995 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -341,6 +341,7 @@ def externalsym : SDNode<"ISD::ExternalSymbol", SDTPtrLeaf, [], "ExternalSymbolSDNode">; def texternalsym: SDNode<"ISD::TargetExternalSymbol", SDTPtrLeaf, [], "ExternalSymbolSDNode">; +def mcsym: SDNode<"ISD::MCSymbol", SDTPtrLeaf, [], "MCSymbolSDNode">; def blockaddress : SDNode<"ISD::BlockAddress", SDTPtrLeaf, [], "BlockAddressSDNode">; def tblockaddress: SDNode<"ISD::TargetBlockAddress", SDTPtrLeaf, [], diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h index c3343caedd18..bacdd950705b 100644 --- a/include/llvm/Target/TargetSelectionDAGInfo.h +++ b/include/llvm/Target/TargetSelectionDAGInfo.h @@ -163,6 +163,6 @@ public: } }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h index 640e1123e928..e42c56add7b1 100644 --- a/include/llvm/Target/TargetSubtargetInfo.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -178,6 +178,6 @@ public: virtual bool enableSubRegLiveness() const { return false; } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h index 59cd921820a2..fbd999cbc946 100644 --- a/include/llvm/Transforms/IPO.h +++ b/include/llvm/Transforms/IPO.h @@ -203,6 +203,6 @@ ModulePass *createBarrierNoopPass(); /// to bitsets. ModulePass *createLowerBitSetsPass(); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h index 4abb92d21537..6a644ad4a63b 100644 --- a/include/llvm/Transforms/IPO/InlinerPass.h +++ b/include/llvm/Transforms/IPO/InlinerPass.h @@ -86,6 +86,6 @@ private: bool shouldInline(CallSite CS); }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/InstCombine/InstCombine.h b/include/llvm/Transforms/InstCombine/InstCombine.h index cfb31569f13e..f48ec13107bc 100644 --- a/include/llvm/Transforms/InstCombine/InstCombine.h +++ b/include/llvm/Transforms/InstCombine/InstCombine.h @@ -41,6 +41,6 @@ public: PreservedAnalyses run(Function &F, AnalysisManager<Function> *AM); }; -} // namespace llvm +} #endif diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index 4447d0da900c..250e3893cb15 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -136,6 +136,6 @@ FunctionPass *createBoundsCheckingPass(); /// protect against stack-based overflow vulnerabilities. FunctionPass *createSafeStackPass(); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/ObjCARC.h b/include/llvm/Transforms/ObjCARC.h index 367cdf6e47c7..1897adc2ffbf 100644 --- a/include/llvm/Transforms/ObjCARC.h +++ b/include/llvm/Transforms/ObjCARC.h @@ -43,6 +43,6 @@ Pass *createObjCARCContractPass(); // Pass *createObjCARCOptPass(); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index 99fff376ecd1..4676c95d7cd4 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -486,6 +486,6 @@ FunctionPass *createNaryReassociatePass(); // FunctionPass *createLoopDistributePass(); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Scalar/EarlyCSE.h b/include/llvm/Transforms/Scalar/EarlyCSE.h index 5cd4a69cafab..e3dd3c050df6 100644 --- a/include/llvm/Transforms/Scalar/EarlyCSE.h +++ b/include/llvm/Transforms/Scalar/EarlyCSE.h @@ -34,6 +34,6 @@ public: PreservedAnalyses run(Function &F, AnalysisManager<Function> *AM); }; -} // namespace llvm +} #endif diff --git a/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h b/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h index ce3674267b66..40283203f3a3 100644 --- a/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h +++ b/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h @@ -35,6 +35,6 @@ public: PreservedAnalyses run(Function &F); }; -} // namespace llvm +} #endif diff --git a/include/llvm/Transforms/Scalar/SimplifyCFG.h b/include/llvm/Transforms/Scalar/SimplifyCFG.h index d8b638de70f4..ef28e0f78a4c 100644 --- a/include/llvm/Transforms/Scalar/SimplifyCFG.h +++ b/include/llvm/Transforms/Scalar/SimplifyCFG.h @@ -41,6 +41,6 @@ public: PreservedAnalyses run(Function &F, AnalysisManager<Function> *AM); }; -} // namespace llvm +} #endif diff --git a/include/llvm/Transforms/Utils/ASanStackFrameLayout.h b/include/llvm/Transforms/Utils/ASanStackFrameLayout.h index 7f6a264b29de..4e4f02c84ece 100644 --- a/include/llvm/Transforms/Utils/ASanStackFrameLayout.h +++ b/include/llvm/Transforms/Utils/ASanStackFrameLayout.h @@ -59,6 +59,6 @@ void ComputeASanStackFrameLayout( // The result is put here. ASanStackFrameLayout *Layout); -} // namespace llvm +} // llvm namespace #endif // LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h index 3004f9eba5ae..9b919b62ee41 100644 --- a/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -64,14 +64,16 @@ void ReplaceInstWithValue(BasicBlock::InstListType &BIL, BasicBlock::iterator &BI, Value *V); // ReplaceInstWithInst - Replace the instruction specified by BI with the -// instruction specified by I. The original instruction is deleted and BI is +// instruction specified by I. Copies DebugLoc from BI to I, if I doesn't +// already have a DebugLoc. The original instruction is deleted and BI is // updated to point to the new instruction. // void ReplaceInstWithInst(BasicBlock::InstListType &BIL, BasicBlock::iterator &BI, Instruction *I); // ReplaceInstWithInst - Replace the instruction specified by From with the -// instruction specified by To. +// instruction specified by To. Copies DebugLoc from BI to I, if I doesn't +// already have a DebugLoc. // void ReplaceInstWithInst(Instruction *From, Instruction *To); @@ -308,6 +310,6 @@ void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore, /// entered if the condition is false. Value *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue, BasicBlock *&IfFalse); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h index 508122949b6b..879f295caf0c 100644 --- a/include/llvm/Transforms/Utils/BuildLibCalls.h +++ b/include/llvm/Transforms/Utils/BuildLibCalls.h @@ -111,6 +111,6 @@ namespace llvm { /// 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 &DL, const TargetLibraryInfo *TLI); -} // namespace llvm +} #endif diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index 9ba6bea499f6..cb187ec103d0 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -233,6 +233,6 @@ bool InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI, bool InsertLifetime = true); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/CodeExtractor.h b/include/llvm/Transforms/Utils/CodeExtractor.h index c3c2f3e793ac..3a96d955cac2 100644 --- a/include/llvm/Transforms/Utils/CodeExtractor.h +++ b/include/llvm/Transforms/Utils/CodeExtractor.h @@ -121,6 +121,6 @@ namespace llvm { ValueSet &inputs, ValueSet &outputs); }; -} // namespace llvm +} #endif diff --git a/include/llvm/Transforms/Utils/CtorUtils.h b/include/llvm/Transforms/Utils/CtorUtils.h index 1213324af19f..63e564dcb87a 100644 --- a/include/llvm/Transforms/Utils/CtorUtils.h +++ b/include/llvm/Transforms/Utils/CtorUtils.h @@ -27,6 +27,6 @@ class Module; bool optimizeGlobalCtorsList(Module &M, function_ref<bool(Function *)> ShouldRemove); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/GlobalStatus.h b/include/llvm/Transforms/Utils/GlobalStatus.h index 658449c9fab1..c36609508808 100644 --- a/include/llvm/Transforms/Utils/GlobalStatus.h +++ b/include/llvm/Transforms/Utils/GlobalStatus.h @@ -77,6 +77,6 @@ struct GlobalStatus { GlobalStatus(); }; -} // namespace llvm +} #endif diff --git a/include/llvm/Transforms/Utils/IntegerDivision.h b/include/llvm/Transforms/Utils/IntegerDivision.h index 5ba6685fdc69..0ec3321b9cf8 100644 --- a/include/llvm/Transforms/Utils/IntegerDivision.h +++ b/include/llvm/Transforms/Utils/IntegerDivision.h @@ -68,6 +68,6 @@ namespace llvm { /// @brief Replace Rem with generated code. bool expandDivisionUpTo64Bits(BinaryOperator *Div); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 1063f5fa9f07..a1bb367ac7b6 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -291,6 +291,6 @@ void combineMetadata(Instruction *K, const Instruction *J, ArrayRef<unsigned> Kn /// the given edge. Returns the number of replacements made. unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT, const BasicBlockEdge &Edge); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h index 3aa40cfaa25a..15747bc7f1ac 100644 --- a/include/llvm/Transforms/Utils/LoopUtils.h +++ b/include/llvm/Transforms/Utils/LoopUtils.h @@ -263,6 +263,6 @@ void computeLICMSafetyInfo(LICMSafetyInfo *, Loop *); /// variable. Returns true if this is an induction PHI along with the step /// value. bool isInductionPHI(PHINode *, ScalarEvolution *, ConstantInt *&); -} // namespace llvm +} #endif diff --git a/include/llvm/Transforms/Utils/ModuleUtils.h b/include/llvm/Transforms/Utils/ModuleUtils.h index 120d14ab87bb..622265bae143 100644 --- a/include/llvm/Transforms/Utils/ModuleUtils.h +++ b/include/llvm/Transforms/Utils/ModuleUtils.h @@ -57,6 +57,6 @@ Function *checkSanitizerInterfaceFunction(Constant *FuncOrBitcast); std::pair<Function *, Function *> createSanitizerCtorAndInitFunctions( Module &M, StringRef CtorName, StringRef InitName, ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs); -} // namespace llvm +} // End llvm namespace #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H diff --git a/include/llvm/Transforms/Utils/PromoteMemToReg.h b/include/llvm/Transforms/Utils/PromoteMemToReg.h index 6c3d2ea9b439..d0602bf47c92 100644 --- a/include/llvm/Transforms/Utils/PromoteMemToReg.h +++ b/include/llvm/Transforms/Utils/PromoteMemToReg.h @@ -45,6 +45,6 @@ void PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT, AliasSetTracker *AST = nullptr, AssumptionCache *AC = nullptr); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h index 5179d587176f..1c7b2c587a36 100644 --- a/include/llvm/Transforms/Utils/SSAUpdater.h +++ b/include/llvm/Transforms/Utils/SSAUpdater.h @@ -173,6 +173,6 @@ public: } }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/SSAUpdaterImpl.h b/include/llvm/Transforms/Utils/SSAUpdaterImpl.h index 1b9cb48a83c6..ed0841c46c27 100644 --- a/include/llvm/Transforms/Utils/SSAUpdaterImpl.h +++ b/include/llvm/Transforms/Utils/SSAUpdaterImpl.h @@ -455,6 +455,6 @@ public: #undef DEBUG_TYPE // "ssaupdater" -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h index d7c8338bafb5..41159603aae5 100644 --- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -166,6 +166,6 @@ private: /// function by checking for an existing function with name FuncName + f bool hasFloatVersion(StringRef FuncName); }; -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/SymbolRewriter.h b/include/llvm/Transforms/Utils/SymbolRewriter.h index d79835857873..5ccee98f97e7 100644 --- a/include/llvm/Transforms/Utils/SymbolRewriter.h +++ b/include/llvm/Transforms/Utils/SymbolRewriter.h @@ -108,7 +108,7 @@ private: yaml::MappingNode *V, RewriteDescriptorList *DL); }; -} // namespace SymbolRewriter +} template <> struct ilist_traits<SymbolRewriter::RewriteDescriptor> @@ -147,6 +147,6 @@ public: ModulePass *createRewriteSymbolsPass(); ModulePass *createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &); -} // namespace llvm +} #endif diff --git a/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h index b19c6fab70e5..550292f6b7a3 100644 --- a/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h +++ b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h @@ -47,6 +47,6 @@ public: Pass *createUnifyFunctionExitNodesPass(); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/UnrollLoop.h b/include/llvm/Transforms/Utils/UnrollLoop.h index ba5866876e7a..7f2cf8d7f59e 100644 --- a/include/llvm/Transforms/Utils/UnrollLoop.h +++ b/include/llvm/Transforms/Utils/UnrollLoop.h @@ -37,6 +37,6 @@ bool UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LPPassManager *LPM); MDNode *GetUnrollMetadata(MDNode *LoopID, StringRef Name); -} // namespace llvm +} #endif diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h index 737ad4f7ed80..047ab818711b 100644 --- a/include/llvm/Transforms/Utils/ValueMapper.h +++ b/include/llvm/Transforms/Utils/ValueMapper.h @@ -96,6 +96,6 @@ namespace llvm { Materializer)); } -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/VectorUtils.h b/include/llvm/Transforms/Utils/VectorUtils.h deleted file mode 100644 index 6a35247950d3..000000000000 --- a/include/llvm/Transforms/Utils/VectorUtils.h +++ /dev/null @@ -1,205 +0,0 @@ -//===- llvm/Transforms/Utils/VectorUtils.h - Vector utilities -*- 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 some vectorizer utilities. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TRANSFORMS_UTILS_VECTORUTILS_H -#define LLVM_TRANSFORMS_UTILS_VECTORUTILS_H - -#include "llvm/Analysis/TargetLibraryInfo.h" -#include "llvm/IR/IntrinsicInst.h" -#include "llvm/IR/Intrinsics.h" - -namespace llvm { - -/// \brief Identify if the intrinsic is trivially vectorizable. -/// -/// This method returns true if the intrinsic's argument types are all -/// scalars for the scalar form of the intrinsic and all vectors for -/// the vector form of the intrinsic. -static inline bool isTriviallyVectorizable(Intrinsic::ID ID) { - switch (ID) { - case Intrinsic::sqrt: - case Intrinsic::sin: - case Intrinsic::cos: - case Intrinsic::exp: - case Intrinsic::exp2: - case Intrinsic::log: - case Intrinsic::log10: - case Intrinsic::log2: - case Intrinsic::fabs: - case Intrinsic::minnum: - case Intrinsic::maxnum: - case Intrinsic::copysign: - case Intrinsic::floor: - case Intrinsic::ceil: - case Intrinsic::trunc: - case Intrinsic::rint: - case Intrinsic::nearbyint: - case Intrinsic::round: - case Intrinsic::bswap: - case Intrinsic::ctpop: - case Intrinsic::pow: - case Intrinsic::fma: - case Intrinsic::fmuladd: - case Intrinsic::ctlz: - case Intrinsic::cttz: - case Intrinsic::powi: - return true; - default: - return false; - } -} - -static inline bool hasVectorInstrinsicScalarOpd(Intrinsic::ID ID, - unsigned ScalarOpdIdx) { - switch (ID) { - case Intrinsic::ctlz: - case Intrinsic::cttz: - case Intrinsic::powi: - return (ScalarOpdIdx == 1); - default: - return false; - } -} - -static Intrinsic::ID checkUnaryFloatSignature(const CallInst &I, - Intrinsic::ID ValidIntrinsicID) { - if (I.getNumArgOperands() != 1 || - !I.getArgOperand(0)->getType()->isFloatingPointTy() || - I.getType() != I.getArgOperand(0)->getType() || - !I.onlyReadsMemory()) - return Intrinsic::not_intrinsic; - - return ValidIntrinsicID; -} - -static Intrinsic::ID checkBinaryFloatSignature(const CallInst &I, - Intrinsic::ID ValidIntrinsicID) { - if (I.getNumArgOperands() != 2 || - !I.getArgOperand(0)->getType()->isFloatingPointTy() || - !I.getArgOperand(1)->getType()->isFloatingPointTy() || - I.getType() != I.getArgOperand(0)->getType() || - I.getType() != I.getArgOperand(1)->getType() || - !I.onlyReadsMemory()) - return Intrinsic::not_intrinsic; - - return ValidIntrinsicID; -} - -static Intrinsic::ID -getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI) { - // If we have an intrinsic call, check if it is trivially vectorizable. - if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) { - Intrinsic::ID ID = II->getIntrinsicID(); - if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start || - ID == Intrinsic::lifetime_end || ID == Intrinsic::assume) - return ID; - else - return Intrinsic::not_intrinsic; - } - - if (!TLI) - return Intrinsic::not_intrinsic; - - LibFunc::Func Func; - Function *F = CI->getCalledFunction(); - // We're going to make assumptions on the semantics of the functions, check - // that the target knows that it's available in this environment and it does - // not have local linkage. - if (!F || F->hasLocalLinkage() || !TLI->getLibFunc(F->getName(), Func)) - return Intrinsic::not_intrinsic; - - // Otherwise check if we have a call to a function that can be turned into a - // vector intrinsic. - switch (Func) { - default: - break; - case LibFunc::sin: - case LibFunc::sinf: - case LibFunc::sinl: - return checkUnaryFloatSignature(*CI, Intrinsic::sin); - case LibFunc::cos: - case LibFunc::cosf: - case LibFunc::cosl: - return checkUnaryFloatSignature(*CI, Intrinsic::cos); - case LibFunc::exp: - case LibFunc::expf: - case LibFunc::expl: - return checkUnaryFloatSignature(*CI, Intrinsic::exp); - case LibFunc::exp2: - case LibFunc::exp2f: - case LibFunc::exp2l: - return checkUnaryFloatSignature(*CI, Intrinsic::exp2); - case LibFunc::log: - case LibFunc::logf: - case LibFunc::logl: - return checkUnaryFloatSignature(*CI, Intrinsic::log); - case LibFunc::log10: - case LibFunc::log10f: - case LibFunc::log10l: - return checkUnaryFloatSignature(*CI, Intrinsic::log10); - case LibFunc::log2: - case LibFunc::log2f: - case LibFunc::log2l: - return checkUnaryFloatSignature(*CI, Intrinsic::log2); - case LibFunc::fabs: - case LibFunc::fabsf: - case LibFunc::fabsl: - return checkUnaryFloatSignature(*CI, Intrinsic::fabs); - case LibFunc::fmin: - case LibFunc::fminf: - case LibFunc::fminl: - return checkBinaryFloatSignature(*CI, Intrinsic::minnum); - case LibFunc::fmax: - case LibFunc::fmaxf: - case LibFunc::fmaxl: - return checkBinaryFloatSignature(*CI, Intrinsic::maxnum); - case LibFunc::copysign: - case LibFunc::copysignf: - case LibFunc::copysignl: - return checkBinaryFloatSignature(*CI, Intrinsic::copysign); - case LibFunc::floor: - case LibFunc::floorf: - case LibFunc::floorl: - return checkUnaryFloatSignature(*CI, Intrinsic::floor); - case LibFunc::ceil: - case LibFunc::ceilf: - case LibFunc::ceill: - return checkUnaryFloatSignature(*CI, Intrinsic::ceil); - case LibFunc::trunc: - case LibFunc::truncf: - case LibFunc::truncl: - return checkUnaryFloatSignature(*CI, Intrinsic::trunc); - case LibFunc::rint: - case LibFunc::rintf: - case LibFunc::rintl: - return checkUnaryFloatSignature(*CI, Intrinsic::rint); - case LibFunc::nearbyint: - case LibFunc::nearbyintf: - case LibFunc::nearbyintl: - return checkUnaryFloatSignature(*CI, Intrinsic::nearbyint); - case LibFunc::round: - case LibFunc::roundf: - case LibFunc::roundl: - return checkUnaryFloatSignature(*CI, Intrinsic::round); - case LibFunc::pow: - case LibFunc::powf: - case LibFunc::powl: - return checkBinaryFloatSignature(*CI, Intrinsic::pow); - } - - return Intrinsic::not_intrinsic; -} - -} // namespace llvm - -#endif diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h index aab2790c0ab1..aec3993d68fc 100644 --- a/include/llvm/Transforms/Vectorize.h +++ b/include/llvm/Transforms/Vectorize.h @@ -139,6 +139,6 @@ Pass *createSLPVectorizerPass(); bool vectorizeBasicBlock(Pass *P, BasicBlock &BB, const VectorizeConfig &C = VectorizeConfig()); -} // namespace llvm +} // End llvm namespace #endif diff --git a/include/llvm/module.modulemap b/include/llvm/module.modulemap index a9e6daf4977e..dcc5ce1059ff 100644 --- a/include/llvm/module.modulemap +++ b/include/llvm/module.modulemap @@ -124,6 +124,7 @@ module LLVM_IR { textual header "IR/DebugInfoFlags.def" textual header "IR/Instruction.def" textual header "IR/Metadata.def" + textual header "IR/Value.def" } module LLVM_IRReader { requires cplusplus umbrella "IRReader" module * { export * } } |