diff options
Diffstat (limited to 'llvm/include')
56 files changed, 776 insertions, 480 deletions
diff --git a/llvm/include/llvm/ADT/ArrayRef.h b/llvm/include/llvm/ADT/ArrayRef.h index ff8bdb8..fb91690 100644 --- a/llvm/include/llvm/ADT/ArrayRef.h +++ b/llvm/include/llvm/ADT/ArrayRef.h @@ -317,10 +317,6 @@ namespace llvm { /// Construct an empty MutableArrayRef. /*implicit*/ MutableArrayRef() = default; - /// Construct an empty MutableArrayRef from std::nullopt. - /*implicit*/ LLVM_DEPRECATED("Use {} or MutableArrayRef<T>() instead", "{}") - MutableArrayRef(std::nullopt_t) : ArrayRef<T>() {} - /// Construct a MutableArrayRef from a single element. /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {} diff --git a/llvm/include/llvm/ADT/DenseMapInfo.h b/llvm/include/llvm/ADT/DenseMapInfo.h index b850223..9d8fd89 100644 --- a/llvm/include/llvm/ADT/DenseMapInfo.h +++ b/llvm/include/llvm/ADT/DenseMapInfo.h @@ -51,10 +51,10 @@ inline unsigned combineHashValue(unsigned a, unsigned b) { /// just be `void`. template<typename T, typename Enable = void> struct DenseMapInfo { - //static inline T getEmptyKey(); - //static inline T getTombstoneKey(); - //static unsigned getHashValue(const T &Val); - //static bool isEqual(const T &LHS, const T &RHS); + // static constexpr T getEmptyKey(); + // static constexpr T getTombstoneKey(); + // static unsigned getHashValue(const T &Val); + // static bool isEqual(const T &LHS, const T &RHS); }; // Provide DenseMapInfo for all pointers. Come up with sentinel pointer values @@ -70,13 +70,13 @@ struct DenseMapInfo<T*> { // "Log2MaxAlign bits of alignment"); static constexpr uintptr_t Log2MaxAlign = 12; - static inline T* getEmptyKey() { + static constexpr T *getEmptyKey() { uintptr_t Val = static_cast<uintptr_t>(-1); Val <<= Log2MaxAlign; return reinterpret_cast<T*>(Val); } - static inline T* getTombstoneKey() { + static constexpr T *getTombstoneKey() { uintptr_t Val = static_cast<uintptr_t>(-2); Val <<= Log2MaxAlign; return reinterpret_cast<T*>(Val); @@ -92,8 +92,8 @@ struct DenseMapInfo<T*> { // Provide DenseMapInfo for chars. template<> struct DenseMapInfo<char> { - static inline char getEmptyKey() { return ~0; } - static inline char getTombstoneKey() { return ~0 - 1; } + static constexpr char getEmptyKey() { return ~0; } + static constexpr char getTombstoneKey() { return ~0 - 1; } static unsigned getHashValue(const char& Val) { return Val * 37U; } static bool isEqual(const char &LHS, const char &RHS) { @@ -103,8 +103,8 @@ template<> struct DenseMapInfo<char> { // Provide DenseMapInfo for unsigned chars. template <> struct DenseMapInfo<unsigned char> { - static inline unsigned char getEmptyKey() { return ~0; } - static inline unsigned char getTombstoneKey() { return ~0 - 1; } + static constexpr unsigned char getEmptyKey() { return ~0; } + static constexpr unsigned char getTombstoneKey() { return ~0 - 1; } static unsigned getHashValue(const unsigned char &Val) { return Val * 37U; } static bool isEqual(const unsigned char &LHS, const unsigned char &RHS) { @@ -114,8 +114,8 @@ template <> struct DenseMapInfo<unsigned char> { // Provide DenseMapInfo for unsigned shorts. template <> struct DenseMapInfo<unsigned short> { - static inline unsigned short getEmptyKey() { return 0xFFFF; } - static inline unsigned short getTombstoneKey() { return 0xFFFF - 1; } + static constexpr unsigned short getEmptyKey() { return 0xFFFF; } + static constexpr unsigned short getTombstoneKey() { return 0xFFFF - 1; } static unsigned getHashValue(const unsigned short &Val) { return Val * 37U; } static bool isEqual(const unsigned short &LHS, const unsigned short &RHS) { @@ -125,8 +125,8 @@ template <> struct DenseMapInfo<unsigned short> { // Provide DenseMapInfo for unsigned ints. template<> struct DenseMapInfo<unsigned> { - static inline unsigned getEmptyKey() { return ~0U; } - static inline unsigned getTombstoneKey() { return ~0U - 1; } + static constexpr unsigned getEmptyKey() { return ~0U; } + static constexpr unsigned getTombstoneKey() { return ~0U - 1; } static unsigned getHashValue(const unsigned& Val) { return Val * 37U; } static bool isEqual(const unsigned& LHS, const unsigned& RHS) { @@ -136,8 +136,8 @@ template<> struct DenseMapInfo<unsigned> { // Provide DenseMapInfo for unsigned longs. template<> struct DenseMapInfo<unsigned long> { - static inline unsigned long getEmptyKey() { return ~0UL; } - static inline unsigned long getTombstoneKey() { return ~0UL - 1L; } + static constexpr unsigned long getEmptyKey() { return ~0UL; } + static constexpr unsigned long getTombstoneKey() { return ~0UL - 1L; } static unsigned getHashValue(const unsigned long& Val) { if constexpr (sizeof(Val) == 4) @@ -153,8 +153,8 @@ template<> struct DenseMapInfo<unsigned long> { // Provide DenseMapInfo for unsigned long longs. template<> struct DenseMapInfo<unsigned long long> { - static inline unsigned long long getEmptyKey() { return ~0ULL; } - static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; } + static constexpr unsigned long long getEmptyKey() { return ~0ULL; } + static constexpr unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; } static unsigned getHashValue(const unsigned long long& Val) { return densemap::detail::mix(Val); @@ -168,16 +168,16 @@ template<> struct DenseMapInfo<unsigned long long> { // Provide DenseMapInfo for shorts. template <> struct DenseMapInfo<short> { - static inline short getEmptyKey() { return 0x7FFF; } - static inline short getTombstoneKey() { return -0x7FFF - 1; } + static constexpr short getEmptyKey() { return 0x7FFF; } + static constexpr short getTombstoneKey() { return -0x7FFF - 1; } static unsigned getHashValue(const short &Val) { return Val * 37U; } static bool isEqual(const short &LHS, const short &RHS) { return LHS == RHS; } }; // Provide DenseMapInfo for ints. template<> struct DenseMapInfo<int> { - static inline int getEmptyKey() { return 0x7fffffff; } - static inline int getTombstoneKey() { return -0x7fffffff - 1; } + static constexpr int getEmptyKey() { return 0x7fffffff; } + static constexpr int getTombstoneKey() { return -0x7fffffff - 1; } static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); } static bool isEqual(const int& LHS, const int& RHS) { @@ -187,11 +187,11 @@ template<> struct DenseMapInfo<int> { // Provide DenseMapInfo for longs. template<> struct DenseMapInfo<long> { - static inline long getEmptyKey() { + static constexpr long getEmptyKey() { return (1UL << (sizeof(long) * 8 - 1)) - 1UL; } - static inline long getTombstoneKey() { return getEmptyKey() - 1L; } + static constexpr long getTombstoneKey() { return getEmptyKey() - 1L; } static unsigned getHashValue(const long& Val) { return (unsigned)(Val * 37UL); @@ -204,8 +204,10 @@ template<> struct DenseMapInfo<long> { // Provide DenseMapInfo for long longs. template<> struct DenseMapInfo<long long> { - static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; } - static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; } + static constexpr long long getEmptyKey() { return 0x7fffffffffffffffLL; } + static constexpr long long getTombstoneKey() { + return -0x7fffffffffffffffLL - 1; + } static unsigned getHashValue(const long long& Val) { return (unsigned)(Val * 37ULL); @@ -224,12 +226,12 @@ struct DenseMapInfo<std::pair<T, U>> { using FirstInfo = DenseMapInfo<T>; using SecondInfo = DenseMapInfo<U>; - static inline Pair getEmptyKey() { + static constexpr Pair getEmptyKey() { return std::make_pair(FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()); } - static inline Pair getTombstoneKey() { + static constexpr Pair getTombstoneKey() { return std::make_pair(FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()); } @@ -257,11 +259,11 @@ struct DenseMapInfo<std::pair<T, U>> { template <typename... Ts> struct DenseMapInfo<std::tuple<Ts...>> { using Tuple = std::tuple<Ts...>; - static inline Tuple getEmptyKey() { + static constexpr Tuple getEmptyKey() { return Tuple(DenseMapInfo<Ts>::getEmptyKey()...); } - static inline Tuple getTombstoneKey() { + static constexpr Tuple getTombstoneKey() { return Tuple(DenseMapInfo<Ts>::getTombstoneKey()...); } @@ -309,10 +311,22 @@ struct DenseMapInfo<Enum, std::enable_if_t<std::is_enum_v<Enum>>> { using UnderlyingType = std::underlying_type_t<Enum>; using Info = DenseMapInfo<UnderlyingType>; - static Enum getEmptyKey() { return static_cast<Enum>(Info::getEmptyKey()); } + // If an enum does not have a "fixed" underlying type, it may be UB to cast + // some values of the underlying type to the enum. We use an "extra" constexpr + // local to ensure that such UB would trigger "static assertion expression is + // not an integral constant expression", rather than runtime UB. + // + // If you hit this error, you can fix by switching to `enum class`, or adding + // an explicit underlying type (e.g. `enum X : int`) to the enum's definition. + + static constexpr Enum getEmptyKey() { + constexpr Enum V = static_cast<Enum>(Info::getEmptyKey()); + return V; + } - static Enum getTombstoneKey() { - return static_cast<Enum>(Info::getTombstoneKey()); + static constexpr Enum getTombstoneKey() { + constexpr Enum V = static_cast<Enum>(Info::getTombstoneKey()); + return V; } static unsigned getHashValue(const Enum &Val) { @@ -326,9 +340,11 @@ template <typename T> struct DenseMapInfo<std::optional<T>> { using Optional = std::optional<T>; using Info = DenseMapInfo<T>; - static inline Optional getEmptyKey() { return {Info::getEmptyKey()}; } + static constexpr Optional getEmptyKey() { return {Info::getEmptyKey()}; } - static inline Optional getTombstoneKey() { return {Info::getTombstoneKey()}; } + static constexpr Optional getTombstoneKey() { + return {Info::getTombstoneKey()}; + } static unsigned getHashValue(const Optional &OptionalVal) { return detail::combineHashValue( diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h index 9e2dc1a..956dcbc 100644 --- a/llvm/include/llvm/Analysis/DXILResource.h +++ b/llvm/include/llvm/Analysis/DXILResource.h @@ -359,6 +359,8 @@ public: std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size); } bool overlapsWith(const ResourceBinding &RHS) const { + if (Size == UINT32_MAX) + return LowerBound < RHS.LowerBound; return Space == RHS.Space && LowerBound + Size - 1 >= RHS.LowerBound; } }; diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h index 09e3945..bff7707 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h +++ b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h @@ -160,6 +160,12 @@ m_scev_ZExt(const Op0_t &Op0) { return m_scev_Unary<SCEVZeroExtendExpr>(Op0); } +template <typename Op0_t> +inline SCEVUnaryExpr_match<SCEVPtrToIntExpr, Op0_t> +m_scev_PtrToInt(const Op0_t &Op0) { + return SCEVUnaryExpr_match<SCEVPtrToIntExpr, Op0_t>(Op0); +} + /// Match a binary SCEV. template <typename SCEVTy, typename Op0_t, typename Op1_t> struct SCEVBinaryExpr_match { diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h index 1d7c414..1fcedcd 100644 --- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -1985,11 +1985,6 @@ public: cast<VectorType>(Args[0]->getType()), {}, CostKind, Index, cast<VectorType>(Args[1]->getType())); } - case Intrinsic::vector_reverse: { - return thisT()->getShuffleCost(TTI::SK_Reverse, cast<VectorType>(RetTy), - cast<VectorType>(Args[0]->getType()), {}, - CostKind, 0, cast<VectorType>(RetTy)); - } case Intrinsic::vector_splice: { unsigned Index = cast<ConstantInt>(Args[2])->getZExtValue(); return thisT()->getShuffleCost(TTI::SK_Splice, cast<VectorType>(RetTy), @@ -2458,6 +2453,10 @@ public: thisT()->getArithmeticInstrCost(BinaryOperator::And, RetTy, CostKind); return Cost; } + case Intrinsic::vector_reverse: + return thisT()->getShuffleCost(TTI::SK_Reverse, cast<VectorType>(RetTy), + cast<VectorType>(ICA.getArgTypes()[0]), {}, + CostKind, 0, cast<VectorType>(RetTy)); case Intrinsic::get_active_lane_mask: { Type *ArgTy = ICA.getArgTypes()[0]; EVT ResVT = getTLI()->getValueType(DL, RetTy, true); diff --git a/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h b/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h index c22f9d4..c70413d 100644 --- a/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h +++ b/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h @@ -15,19 +15,17 @@ #define LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H #include "llvm/IR/BuiltinGCs.h" -#include <cstdlib> +#include "llvm/Support/AlwaysTrue.h" namespace { struct ForceAsmWriterLinking { ForceAsmWriterLinking() { // We must reference the plug-ins in such a way that compilers will not // delete it all as dead code, even with whole program optimization, - // yet is effectively a NO-OP. As the compiler isn't smart enough - // to know that getenv() never returns -1, this will do the job. - // This is so that globals in the translation units where these functions - // are defined are forced to be initialized, populating various - // registries. - if (std::getenv("bar") != (char*) -1) + // yet is effectively a NO-OP. This is so that globals in the translation + // units where these functions are defined are forced to be initialized, + // populating various registries. + if (llvm::getNonFoldableAlwaysTrue()) return; llvm::linkOcamlGCPrinter(); diff --git a/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h b/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h index 6f56682..f0a01d2 100644 --- a/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h +++ b/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h @@ -16,20 +16,18 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/SchedulerRegistry.h" +#include "llvm/Support/AlwaysTrue.h" #include "llvm/Target/TargetMachine.h" -#include <cstdlib> namespace { struct ForceCodegenLinking { ForceCodegenLinking() { // We must reference the passes in such a way that compilers will not // delete it all as dead code, even with whole program optimization, - // yet is effectively a NO-OP. As the compiler isn't smart enough - // to know that getenv() never returns -1, this will do the job. - // This is so that globals in the translation units where these functions - // are defined are forced to be initialized, populating various - // registries. - if (std::getenv("bar") != (char*) -1) + // yet is effectively a NO-OP. This is so that globals in the translation + // units where these functions are defined are forced to be initialized, + // populating various registries. + if (llvm::getNonFoldableAlwaysTrue()) return; (void) llvm::createFastRegisterAllocator(); diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h index 714285e..095a40e 100644 --- a/llvm/include/llvm/CodeGen/Passes.h +++ b/llvm/include/llvm/CodeGen/Passes.h @@ -438,10 +438,6 @@ LLVM_ABI extern char &UnpackMachineBundlesID; LLVM_ABI FunctionPass * createUnpackMachineBundles(std::function<bool(const MachineFunction &)> Ftor); -/// FinalizeMachineBundles - This pass finalize machine instruction -/// bundles (created earlier, e.g. during pre-RA scheduling). -LLVM_ABI extern char &FinalizeMachineBundlesID; - /// StackMapLiveness - This pass analyses the register live-out set of /// stackmap/patchpoint intrinsics and attaches the calculated information to /// the intrinsic for later emission to the StackMap. diff --git a/llvm/include/llvm/Config/abi-breaking.h.cmake b/llvm/include/llvm/Config/abi-breaking.h.cmake index 2d27e02..330f360 100644 --- a/llvm/include/llvm/Config/abi-breaking.h.cmake +++ b/llvm/include/llvm/Config/abi-breaking.h.cmake @@ -12,12 +12,41 @@ #ifndef LLVM_ABI_BREAKING_CHECKS_H #define LLVM_ABI_BREAKING_CHECKS_H +// llvm-config.h is required for LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS +#include "llvm/Config/llvm-config.h" + /* Define to enable checks that alter the LLVM C++ ABI */ #cmakedefine01 LLVM_ENABLE_ABI_BREAKING_CHECKS /* Define to enable reverse iteration of unordered llvm containers */ #cmakedefine01 LLVM_ENABLE_REVERSE_ITERATION +#if !defined(__has_attribute) +#define __has_attribute(attribute) 0 +#endif + +// Properly annotate EnableABIBreakingChecks or DisableABIBreakingChecks for +// export from shared library. +// TODO(https://github.com/llvm/llvm-project/issues/145406): eliminate need for +// two preprocessor definitions to gate LLVM_ABI macro definitions. +#if defined(LLVM_BUILD_STATIC) || !defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) +#define ABI_BREAKING_EXPORT_ABI +#else +#if defined(_WIN32) +#if defined(LLVM_EXPORTS) +#define ABI_BREAKING_EXPORT_ABI __declspec(dllexport) +#else +#define ABI_BREAKING_EXPORT_ABI __declspec(dllimport) +#endif +#else +#if __has_attribute(visibility) +#define ABI_BREAKING_EXPORT_ABI __attribute__((__visibility__("default"))) +#else +#define ABI_BREAKING_EXPORT_ABI +#endif +#endif +#endif + /* Allow selectively disabling link-time mismatch checking so that header-only ADT content from LLVM can be used without linking libSupport. */ #if !defined(LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING) || !LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING @@ -43,12 +72,12 @@ #endif namespace llvm { #if LLVM_ENABLE_ABI_BREAKING_CHECKS -extern int EnableABIBreakingChecks; +ABI_BREAKING_EXPORT_ABI extern int EnableABIBreakingChecks; LLVM_HIDDEN_VISIBILITY __attribute__((weak)) int *VerifyEnableABIBreakingChecks = &EnableABIBreakingChecks; #else -extern int DisableABIBreakingChecks; +ABI_BREAKING_EXPORT_ABI extern int DisableABIBreakingChecks; LLVM_HIDDEN_VISIBILITY __attribute__((weak)) int *VerifyDisableABIBreakingChecks = &DisableABIBreakingChecks; diff --git a/llvm/include/llvm/Config/llvm-config.h.cmake b/llvm/include/llvm/Config/llvm-config.h.cmake index a683229..39136bc 100644 --- a/llvm/include/llvm/Config/llvm-config.h.cmake +++ b/llvm/include/llvm/Config/llvm-config.h.cmake @@ -101,6 +101,9 @@ /* Define if LLVM is using tflite */ #cmakedefine LLVM_HAVE_TFLITE +/* Define if we want to check profile consistency in lit tests */ +#cmakedefine LLVM_ENABLE_PROFCHECK + /* Define to 1 if you have the <sysexits.h> header file. */ #cmakedefine HAVE_SYSEXITS_H ${HAVE_SYSEXITS_H} diff --git a/llvm/include/llvm/Demangle/Demangle.h b/llvm/include/llvm/Demangle/Demangle.h index 21e7457..d9b08b2 100644 --- a/llvm/include/llvm/Demangle/Demangle.h +++ b/llvm/include/llvm/Demangle/Demangle.h @@ -9,6 +9,7 @@ #ifndef LLVM_DEMANGLE_DEMANGLE_H #define LLVM_DEMANGLE_DEMANGLE_H +#include "DemangleConfig.h" #include <cstddef> #include <optional> #include <string> @@ -33,7 +34,8 @@ enum : int { /// Returns a non-NULL pointer to a NUL-terminated C style string /// that should be explicitly freed, if successful. Otherwise, may return /// nullptr if mangled_name is not a valid mangling or is nullptr. -char *itaniumDemangle(std::string_view mangled_name, bool ParseParams = true); +DEMANGLE_ABI char *itaniumDemangle(std::string_view mangled_name, + bool ParseParams = true); enum MSDemangleFlags { MSDF_None = 0, @@ -52,87 +54,90 @@ enum MSDemangleFlags { /// bytes of the input string were consumed. /// status receives one of the demangle_ enum entries above if it's not nullptr. /// Flags controls various details of the demangled representation. -char *microsoftDemangle(std::string_view mangled_name, size_t *n_read, - int *status, MSDemangleFlags Flags = MSDF_None); +DEMANGLE_ABI char *microsoftDemangle(std::string_view mangled_name, + size_t *n_read, int *status, + MSDemangleFlags Flags = MSDF_None); -std::optional<size_t> +DEMANGLE_ABI std::optional<size_t> getArm64ECInsertionPointInMangledName(std::string_view MangledName); // Demangles a Rust v0 mangled symbol. -char *rustDemangle(std::string_view MangledName); +DEMANGLE_ABI char *rustDemangle(std::string_view MangledName); // Demangles a D mangled symbol. -char *dlangDemangle(std::string_view MangledName); +DEMANGLE_ABI char *dlangDemangle(std::string_view MangledName); /// Attempt to demangle a string using different demangling schemes. /// The function uses heuristics to determine which demangling scheme to use. /// \param MangledName - reference to string to demangle. /// \returns - the demangled string, or a copy of the input string if no /// demangling occurred. -std::string demangle(std::string_view MangledName); +DEMANGLE_ABI std::string demangle(std::string_view MangledName); -bool nonMicrosoftDemangle(std::string_view MangledName, std::string &Result, - bool CanHaveLeadingDot = true, - bool ParseParams = true); +DEMANGLE_ABI bool nonMicrosoftDemangle(std::string_view MangledName, + std::string &Result, + bool CanHaveLeadingDot = true, + bool ParseParams = true); /// "Partial" demangler. This supports demangling a string into an AST /// (typically an intermediate stage in itaniumDemangle) and querying certain /// properties or partially printing the demangled name. struct ItaniumPartialDemangler { - ItaniumPartialDemangler(); + DEMANGLE_ABI ItaniumPartialDemangler(); - ItaniumPartialDemangler(ItaniumPartialDemangler &&Other); - ItaniumPartialDemangler &operator=(ItaniumPartialDemangler &&Other); + DEMANGLE_ABI ItaniumPartialDemangler(ItaniumPartialDemangler &&Other); + DEMANGLE_ABI ItaniumPartialDemangler & + operator=(ItaniumPartialDemangler &&Other); /// Demangle into an AST. Subsequent calls to the rest of the member functions /// implicitly operate on the AST this produces. /// \return true on error, false otherwise - bool partialDemangle(const char *MangledName); + DEMANGLE_ABI bool partialDemangle(const char *MangledName); /// Just print the entire mangled name into Buf. Buf and N behave like the /// second and third parameters to __cxa_demangle. - char *finishDemangle(char *Buf, size_t *N) const; + DEMANGLE_ABI char *finishDemangle(char *Buf, size_t *N) const; /// See \ref finishDemangle /// /// \param[in] OB A llvm::itanium_demangle::OutputBuffer that the demangled /// name will be printed into. /// - char *finishDemangle(void *OB) const; + DEMANGLE_ABI char *finishDemangle(void *OB) const; /// Get the base name of a function. This doesn't include trailing template /// arguments, ie for "a::b<int>" this function returns "b". - char *getFunctionBaseName(char *Buf, size_t *N) const; + DEMANGLE_ABI char *getFunctionBaseName(char *Buf, size_t *N) const; /// Get the context name for a function. For "a::b::c", this function returns /// "a::b". - char *getFunctionDeclContextName(char *Buf, size_t *N) const; + DEMANGLE_ABI char *getFunctionDeclContextName(char *Buf, size_t *N) const; /// Get the entire name of this function. - char *getFunctionName(char *Buf, size_t *N) const; + DEMANGLE_ABI char *getFunctionName(char *Buf, size_t *N) const; /// Get the parameters for this function. - char *getFunctionParameters(char *Buf, size_t *N) const; - char *getFunctionReturnType(char *Buf, size_t *N) const; + DEMANGLE_ABI char *getFunctionParameters(char *Buf, size_t *N) const; + DEMANGLE_ABI char *getFunctionReturnType(char *Buf, size_t *N) const; /// If this function has any cv or reference qualifiers. These imply that /// the function is a non-static member function. - bool hasFunctionQualifiers() const; + DEMANGLE_ABI bool hasFunctionQualifiers() const; /// If this symbol describes a constructor or destructor. - bool isCtorOrDtor() const; + DEMANGLE_ABI bool isCtorOrDtor() const; /// If this symbol describes a function. - bool isFunction() const; + DEMANGLE_ABI bool isFunction() const; /// If this symbol describes a variable. - bool isData() const; + DEMANGLE_ABI bool isData() const; /// If this symbol is a <special-name>. These are generally implicitly /// generated by the implementation, such as vtables and typeinfo names. - bool isSpecialName() const; + DEMANGLE_ABI bool isSpecialName() const; - ~ItaniumPartialDemangler(); + DEMANGLE_ABI ~ItaniumPartialDemangler(); private: void *RootNode; diff --git a/llvm/include/llvm/Demangle/DemangleConfig.h b/llvm/include/llvm/Demangle/DemangleConfig.h index 30f72ff..7ee23a4 100644 --- a/llvm/include/llvm/Demangle/DemangleConfig.h +++ b/llvm/include/llvm/Demangle/DemangleConfig.h @@ -94,4 +94,24 @@ #define DEMANGLE_NAMESPACE_BEGIN namespace llvm { namespace itanium_demangle { #define DEMANGLE_NAMESPACE_END } } +/// DEMANGLE_ABI is the export/visibility macro used to mark symbols delcared in +/// llvm/Demangle as exported when built as a shared library. +#if defined(LLVM_BUILD_STATIC) || !defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) +#define DEMANGLE_ABI +#else +#if defined(_WIN32) +#if defined(LLVM_EXPORTS) +#define DEMANGLE_ABI __declspec(dllexport) +#else +#define DEMANGLE_ABI __declspec(dllimport) +#endif +#else +#if __has_attribute(visibility) +#define DEMANGLE_ABI __attribute__((__visibility__("default"))) +#else +#define DEMANGLE_ABI +#endif +#endif +#endif + #endif diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h index 5533652..62d427c 100644 --- a/llvm/include/llvm/Demangle/ItaniumDemangle.h +++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -3049,7 +3049,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser { Node *parse(bool ParseParams = true); }; -const char* parse_discriminator(const char* first, const char* last); +DEMANGLE_ABI const char *parse_discriminator(const char *first, + const char *last); // <name> ::= <nested-name> // N // ::= <local-name> # See Scope Encoding below // Z diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangle.h b/llvm/include/llvm/Demangle/MicrosoftDemangle.h index b9a25e3..a2af875 100644 --- a/llvm/include/llvm/Demangle/MicrosoftDemangle.h +++ b/llvm/include/llvm/Demangle/MicrosoftDemangle.h @@ -10,6 +10,7 @@ #define LLVM_DEMANGLE_MICROSOFTDEMANGLE_H #include "llvm/Demangle/Demangle.h" +#include "llvm/Demangle/DemangleConfig.h" #include "llvm/Demangle/MicrosoftDemangleNodes.h" #include <cassert> @@ -151,14 +152,14 @@ public: // You are supposed to call parse() first and then check if error is true. If // it is false, call output() to write the formatted name to the given stream. - SymbolNode *parse(std::string_view &MangledName); + DEMANGLE_ABI SymbolNode *parse(std::string_view &MangledName); - TagTypeNode *parseTagUniqueName(std::string_view &MangledName); + DEMANGLE_ABI TagTypeNode *parseTagUniqueName(std::string_view &MangledName); // True if an error occurred. bool Error = false; - void dumpBackReferences(); + DEMANGLE_ABI void dumpBackReferences(); private: SymbolNode *demangleEncodedSymbol(std::string_view &MangledName, diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h index a9cfe72..155cfe8 100644 --- a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h +++ b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h @@ -13,6 +13,7 @@ #ifndef LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H #define LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H +#include "DemangleConfig.h" #include <array> #include <cstdint> #include <string> @@ -281,7 +282,7 @@ struct Node { virtual void output(OutputBuffer &OB, OutputFlags Flags) const = 0; - std::string toString(OutputFlags Flags = OF_Default) const; + DEMANGLE_ABI std::string toString(OutputFlags Flags = OF_Default) const; private: NodeKind Kind; @@ -332,7 +333,7 @@ struct TypeNode : public Node { Qualifiers Quals = Q_None; }; -struct PrimitiveTypeNode : public TypeNode { +struct DEMANGLE_ABI PrimitiveTypeNode : public TypeNode { explicit PrimitiveTypeNode(PrimitiveKind K) : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {} @@ -346,7 +347,7 @@ struct PrimitiveTypeNode : public TypeNode { PrimitiveKind PrimKind; }; -struct FunctionSignatureNode : public TypeNode { +struct DEMANGLE_ABI FunctionSignatureNode : public TypeNode { explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {} FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {} @@ -394,10 +395,11 @@ struct IdentifierNode : public Node { NodeArrayNode *TemplateParams = nullptr; protected: - void outputTemplateParameters(OutputBuffer &OB, OutputFlags Flags) const; + DEMANGLE_ABI void outputTemplateParameters(OutputBuffer &OB, + OutputFlags Flags) const; }; -struct VcallThunkIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI VcallThunkIdentifierNode : public IdentifierNode { VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -409,7 +411,7 @@ struct VcallThunkIdentifierNode : public IdentifierNode { uint64_t OffsetInVTable = 0; }; -struct DynamicStructorIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI DynamicStructorIdentifierNode : public IdentifierNode { DynamicStructorIdentifierNode() : IdentifierNode(NodeKind::DynamicStructorIdentifier) {} @@ -424,7 +426,7 @@ struct DynamicStructorIdentifierNode : public IdentifierNode { bool IsDestructor = false; }; -struct NamedIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI NamedIdentifierNode : public IdentifierNode { NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -436,7 +438,7 @@ struct NamedIdentifierNode : public IdentifierNode { std::string_view Name; }; -struct IntrinsicFunctionIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI IntrinsicFunctionIdentifierNode : public IdentifierNode { explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator) : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier), Operator(Operator) {} @@ -450,7 +452,7 @@ struct IntrinsicFunctionIdentifierNode : public IdentifierNode { IntrinsicFunctionKind Operator; }; -struct LiteralOperatorIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI LiteralOperatorIdentifierNode : public IdentifierNode { LiteralOperatorIdentifierNode() : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {} @@ -463,7 +465,7 @@ struct LiteralOperatorIdentifierNode : public IdentifierNode { std::string_view Name; }; -struct LocalStaticGuardIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI LocalStaticGuardIdentifierNode : public IdentifierNode { LocalStaticGuardIdentifierNode() : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {} @@ -477,7 +479,7 @@ struct LocalStaticGuardIdentifierNode : public IdentifierNode { uint32_t ScopeIndex = 0; }; -struct ConversionOperatorIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI ConversionOperatorIdentifierNode : public IdentifierNode { ConversionOperatorIdentifierNode() : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {} @@ -491,7 +493,7 @@ struct ConversionOperatorIdentifierNode : public IdentifierNode { TypeNode *TargetType = nullptr; }; -struct StructorIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI StructorIdentifierNode : public IdentifierNode { StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {} explicit StructorIdentifierNode(bool IsDestructor) : IdentifierNode(NodeKind::StructorIdentifier), @@ -508,7 +510,7 @@ struct StructorIdentifierNode : public IdentifierNode { bool IsDestructor = false; }; -struct ThunkSignatureNode : public FunctionSignatureNode { +struct DEMANGLE_ABI ThunkSignatureNode : public FunctionSignatureNode { ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {} void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; @@ -528,7 +530,7 @@ struct ThunkSignatureNode : public FunctionSignatureNode { ThisAdjustor ThisAdjust; }; -struct PointerTypeNode : public TypeNode { +struct DEMANGLE_ABI PointerTypeNode : public TypeNode { PointerTypeNode() : TypeNode(NodeKind::PointerType) {} void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; void outputPost(OutputBuffer &OB, OutputFlags Flags) const override; @@ -550,7 +552,7 @@ struct PointerTypeNode : public TypeNode { TypeNode *Pointee = nullptr; }; -struct TagTypeNode : public TypeNode { +struct DEMANGLE_ABI TagTypeNode : public TypeNode { explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {} void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; @@ -562,7 +564,7 @@ struct TagTypeNode : public TypeNode { TagKind Tag; }; -struct ArrayTypeNode : public TypeNode { +struct DEMANGLE_ABI ArrayTypeNode : public TypeNode { ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {} void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; @@ -591,7 +593,7 @@ struct IntrinsicNode : public TypeNode { } }; -struct CustomTypeNode : public TypeNode { +struct DEMANGLE_ABI CustomTypeNode : public TypeNode { CustomTypeNode() : TypeNode(NodeKind::Custom) {} void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; @@ -602,7 +604,7 @@ struct CustomTypeNode : public TypeNode { IdentifierNode *Identifier = nullptr; }; -struct NodeArrayNode : public Node { +struct DEMANGLE_ABI NodeArrayNode : public Node { NodeArrayNode() : Node(NodeKind::NodeArray) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -618,7 +620,7 @@ struct NodeArrayNode : public Node { size_t Count = 0; }; -struct QualifiedNameNode : public Node { +struct DEMANGLE_ABI QualifiedNameNode : public Node { QualifiedNameNode() : Node(NodeKind::QualifiedName) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -635,7 +637,7 @@ struct QualifiedNameNode : public Node { } }; -struct TemplateParameterReferenceNode : public Node { +struct DEMANGLE_ABI TemplateParameterReferenceNode : public Node { TemplateParameterReferenceNode() : Node(NodeKind::TemplateParameterReference) {} @@ -653,7 +655,7 @@ struct TemplateParameterReferenceNode : public Node { bool IsMemberPointer = false; }; -struct IntegerLiteralNode : public Node { +struct DEMANGLE_ABI IntegerLiteralNode : public Node { IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {} IntegerLiteralNode(uint64_t Value, bool IsNegative) : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {} @@ -668,7 +670,7 @@ struct IntegerLiteralNode : public Node { bool IsNegative = false; }; -struct RttiBaseClassDescriptorNode : public IdentifierNode { +struct DEMANGLE_ABI RttiBaseClassDescriptorNode : public IdentifierNode { RttiBaseClassDescriptorNode() : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {} @@ -684,7 +686,7 @@ struct RttiBaseClassDescriptorNode : public IdentifierNode { uint32_t Flags = 0; }; -struct SymbolNode : public Node { +struct DEMANGLE_ABI SymbolNode : public Node { explicit SymbolNode(NodeKind K) : Node(K) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -696,7 +698,7 @@ struct SymbolNode : public Node { QualifiedNameNode *Name = nullptr; }; -struct SpecialTableSymbolNode : public SymbolNode { +struct DEMANGLE_ABI SpecialTableSymbolNode : public SymbolNode { explicit SpecialTableSymbolNode() : SymbolNode(NodeKind::SpecialTableSymbol) {} @@ -710,7 +712,7 @@ struct SpecialTableSymbolNode : public SymbolNode { Qualifiers Quals = Qualifiers::Q_None; }; -struct LocalStaticGuardVariableNode : public SymbolNode { +struct DEMANGLE_ABI LocalStaticGuardVariableNode : public SymbolNode { LocalStaticGuardVariableNode() : SymbolNode(NodeKind::LocalStaticGuardVariable) {} @@ -723,7 +725,7 @@ struct LocalStaticGuardVariableNode : public SymbolNode { bool IsVisible = false; }; -struct EncodedStringLiteralNode : public SymbolNode { +struct DEMANGLE_ABI EncodedStringLiteralNode : public SymbolNode { EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -737,7 +739,7 @@ struct EncodedStringLiteralNode : public SymbolNode { CharKind Char = CharKind::Char; }; -struct VariableSymbolNode : public SymbolNode { +struct DEMANGLE_ABI VariableSymbolNode : public SymbolNode { VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -750,7 +752,7 @@ struct VariableSymbolNode : public SymbolNode { TypeNode *Type = nullptr; }; -struct FunctionSymbolNode : public SymbolNode { +struct DEMANGLE_ABI FunctionSymbolNode : public SymbolNode { FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -762,7 +764,7 @@ struct FunctionSymbolNode : public SymbolNode { FunctionSignatureNode *Signature = nullptr; }; -struct PointerAuthQualifierNode : public Node { +struct DEMANGLE_ABI PointerAuthQualifierNode : public Node { PointerAuthQualifierNode() : Node(NodeKind::PointerAuthQualifier) {} // __ptrauth takes three arguments: diff --git a/llvm/include/llvm/ExecutionEngine/MCJIT.h b/llvm/include/llvm/ExecutionEngine/MCJIT.h index c836c06..1e035c0 100644 --- a/llvm/include/llvm/ExecutionEngine/MCJIT.h +++ b/llvm/include/llvm/ExecutionEngine/MCJIT.h @@ -15,8 +15,8 @@ #define LLVM_EXECUTIONENGINE_MCJIT_H #include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/Support/AlwaysTrue.h" #include "llvm/Support/Compiler.h" -#include <cstdlib> extern "C" LLVM_ABI void LLVMLinkInMCJIT(); @@ -24,13 +24,11 @@ namespace { struct ForceMCJITLinking { ForceMCJITLinking() { // We must reference MCJIT in such a way that compilers will not - // delete it all as dead code, even with whole program optimization, - // yet is effectively a NO-OP. As the compiler isn't smart enough - // to know that getenv() never returns -1, this will do the job. - // This is so that globals in the translation units where these functions - // are defined are forced to be initialized, populating various - // registries. - if (std::getenv("bar") != (char*) -1) + // delete it all as dead code, even with whole program optimization, yet + // is effectively a NO-OP. This is so that globals in the translation + // units where these functions are defined are forced to be initialized, + // populating various registries. + if (llvm::getNonFoldableAlwaysTrue()) return; LLVMLinkInMCJIT(); diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureMetadata.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureMetadata.h index 0aa122f..6fa51ed 100644 --- a/llvm/include/llvm/Frontend/HLSL/RootSignatureMetadata.h +++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureMetadata.h @@ -15,6 +15,8 @@ #define LLVM_FRONTEND_HLSL_ROOTSIGNATUREMETADATA_H #include "llvm/Frontend/HLSL/HLSLRootSignature.h" +#include "llvm/IR/Constants.h" +#include "llvm/MC/DXContainerRootSignature.h" namespace llvm { class LLVMContext; @@ -49,6 +51,48 @@ private: SmallVector<Metadata *> GeneratedMetadata; }; +enum class RootSignatureElementKind { + Error = 0, + RootFlags = 1, + RootConstants = 2, + SRV = 3, + UAV = 4, + CBV = 5, + DescriptorTable = 6, + StaticSamplers = 7 +}; + +class MetadataParser { +public: + MetadataParser(MDNode *Root) : Root(Root) {} + + LLVM_ABI bool ParseRootSignature(LLVMContext *Ctx, + mcdxbc::RootSignatureDesc &RSD); + +private: + bool parseRootFlags(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD, + MDNode *RootFlagNode); + bool parseRootConstants(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD, + MDNode *RootConstantNode); + bool parseRootDescriptors(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD, + MDNode *RootDescriptorNode, + RootSignatureElementKind ElementKind); + bool parseDescriptorRange(LLVMContext *Ctx, mcdxbc::DescriptorTable &Table, + MDNode *RangeDescriptorNode); + bool parseDescriptorTable(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD, + MDNode *DescriptorTableNode); + bool parseRootSignatureElement(LLVMContext *Ctx, + mcdxbc::RootSignatureDesc &RSD, + MDNode *Element); + bool parseStaticSampler(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD, + MDNode *StaticSamplerNode); + + bool validateRootSignature(LLVMContext *Ctx, + const llvm::mcdxbc::RootSignatureDesc &RSD); + + MDNode *Root; +}; + } // namespace rootsig } // namespace hlsl } // namespace llvm diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h index 862be04..5f7225e 100644 --- a/llvm/include/llvm/IR/DiagnosticInfo.h +++ b/llvm/include/llvm/IR/DiagnosticInfo.h @@ -68,6 +68,7 @@ enum DiagnosticKind { DK_StackSize, DK_Linker, DK_Lowering, + DK_LegalizationFailure, DK_DebugMetadataVersion, DK_DebugMetadataInvalid, DK_Instrumentation, @@ -383,6 +384,30 @@ private: DiagnosticLocation Loc; }; +class LLVM_ABI DiagnosticInfoLegalizationFailure + : public DiagnosticInfoWithLocationBase { +private: + /// Message to be reported. + const Twine &MsgStr; + +public: + DiagnosticInfoLegalizationFailure(const Twine &MsgStr LLVM_LIFETIME_BOUND, + const Function &Fn, + const DiagnosticLocation &Loc, + DiagnosticSeverity Severity = DS_Error) + : DiagnosticInfoWithLocationBase(DK_LegalizationFailure, Severity, Fn, + Loc), + MsgStr(MsgStr) {} + + const Twine &getMsgStr() const { return MsgStr; } + + void print(DiagnosticPrinter &DP) const override; + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_LegalizationFailure; + } +}; + class LLVM_ABI DiagnosticInfoGenericWithLoc : public DiagnosticInfoWithLocationBase { private: diff --git a/llvm/include/llvm/IR/IntrinsicsAMDGPU.td b/llvm/include/llvm/IR/IntrinsicsAMDGPU.td index 8bfa345..3a7db6d 100644 --- a/llvm/include/llvm/IR/IntrinsicsAMDGPU.td +++ b/llvm/include/llvm/IR/IntrinsicsAMDGPU.td @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +def flat_ptr_ty : LLVMQualPointerType<0>; def global_ptr_ty : LLVMQualPointerType<1>; def local_ptr_ty : LLVMQualPointerType<3>; @@ -3045,6 +3046,24 @@ def int_amdgcn_ds_bpermute_fi_b32 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrConvergent, IntrWillReturn, IntrNoCallback, IntrNoFree]>; +def int_amdgcn_flat_prefetch : ClangBuiltin<"__builtin_amdgcn_flat_prefetch">, + Intrinsic<[], + [llvm_ptr_ty, // Pointer + llvm_i32_ty], // cachepolicy(imm), bits [0-2] = th, bits [3-4] = scope + [IntrInaccessibleMemOrArgMemOnly, IntrWillReturn, NoCapture<ArgIndex<0>>, + IntrNoCallback, IntrNoFree, ImmArg<ArgIndex<1>>], + "", [SDNPMemOperand] + >; + +def int_amdgcn_global_prefetch : ClangBuiltin<"__builtin_amdgcn_global_prefetch">, + Intrinsic<[], + [LLVMQualPointerType<1>, // Pointer + llvm_i32_ty], // cachepolicy(imm), bits [0-2] = th, bits [3-4] = scope + [IntrInaccessibleMemOrArgMemOnly, IntrWillReturn, NoCapture<ArgIndex<0>>, + IntrNoCallback, IntrNoFree, ImmArg<ArgIndex<1>>], + "", [SDNPMemOperand] + >; + //===----------------------------------------------------------------------===// // Deep learning intrinsics. //===----------------------------------------------------------------------===// @@ -3828,6 +3847,26 @@ def int_amdgcn_tensor_load_to_lds_d2 : def int_amdgcn_tensor_store_from_lds_d2 : ClangBuiltin<"__builtin_amdgcn_tensor_store_from_lds_d2">, AMDGPUTensorLoadStoreD2; +class AMDGPULoadMonitor<LLVMType ptr_ty>: + Intrinsic< + [llvm_any_ty], + [ptr_ty, + llvm_i32_ty], // gfx12+ cachepolicy: + // bits [0-2] = th + // bits [3-4] = scope + [IntrArgMemOnly, IntrReadMem, ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>, ImmArg<ArgIndex<1>>, + IntrWillReturn, IntrConvergent, IntrNoCallback, IntrNoFree], + "", + [SDNPMemOperand] + >; + +def int_amdgcn_flat_load_monitor_b32 : AMDGPULoadMonitor<flat_ptr_ty>; +def int_amdgcn_flat_load_monitor_b64 : AMDGPULoadMonitor<flat_ptr_ty>; +def int_amdgcn_flat_load_monitor_b128 : AMDGPULoadMonitor<flat_ptr_ty>; +def int_amdgcn_global_load_monitor_b32 : AMDGPULoadMonitor<global_ptr_ty>; +def int_amdgcn_global_load_monitor_b64 : AMDGPULoadMonitor<global_ptr_ty>; +def int_amdgcn_global_load_monitor_b128 : AMDGPULoadMonitor<global_ptr_ty>; + /// Emit an addrspacecast without null pointer checking. /// Should only be inserted by a pass based on analysis of an addrspacecast's src. def int_amdgcn_addrspacecast_nonnull : DefaultAttrsIntrinsic< diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 2e231cf..31801da 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -119,7 +119,6 @@ LLVM_ABI void initializeExpandVariadicsPass(PassRegistry &); LLVM_ABI void initializeExternalAAWrapperPassPass(PassRegistry &); LLVM_ABI void initializeFEntryInserterLegacyPass(PassRegistry &); LLVM_ABI void initializeFinalizeISelPass(PassRegistry &); -LLVM_ABI void initializeFinalizeMachineBundlesPass(PassRegistry &); LLVM_ABI void initializeFixIrreduciblePass(PassRegistry &); LLVM_ABI void initializeFixupStatepointCallerSavedLegacyPass(PassRegistry &); LLVM_ABI void initializeFlattenCFGLegacyPassPass(PassRegistry &); diff --git a/llvm/include/llvm/LinkAllIR.h b/llvm/include/llvm/LinkAllIR.h index ceed784..894a8dd 100644 --- a/llvm/include/llvm/LinkAllIR.h +++ b/llvm/include/llvm/LinkAllIR.h @@ -21,6 +21,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" +#include "llvm/Support/AlwaysTrue.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Memory.h" @@ -29,19 +30,16 @@ #include "llvm/Support/Process.h" #include "llvm/Support/Program.h" #include "llvm/Support/Signals.h" -#include <cstdlib> namespace { struct ForceVMCoreLinking { ForceVMCoreLinking() { // We must reference VMCore in such a way that compilers will not - // delete it all as dead code, even with whole program optimization, - // yet is effectively a NO-OP. As the compiler isn't smart enough - // to know that getenv() never returns -1, this will do the job. + // delete it all as dead code, even with whole program optimization. // This is so that globals in the translation units where these functions // are defined are forced to be initialized, populating various // registries. - if (std::getenv("bar") != (char*) -1) + if (llvm::getNonFoldableAlwaysTrue()) return; llvm::LLVMContext Context; (void)new llvm::Module("", Context); diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h index bae7f0d..f82a439 100644 --- a/llvm/include/llvm/LinkAllPasses.h +++ b/llvm/include/llvm/LinkAllPasses.h @@ -34,6 +34,7 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRPrintingPasses.h" +#include "llvm/Support/AlwaysTrue.h" #include "llvm/Support/Valgrind.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" @@ -54,14 +55,12 @@ class Triple; namespace { struct ForcePassLinking { ForcePassLinking() { - // We must reference the passes in such a way that compilers will not - // delete it all as dead code, even with whole program optimization, - // yet is effectively a NO-OP. As the compiler isn't smart enough - // to know that getenv() never returns -1, this will do the job. - // This is so that globals in the translation units where these functions - // are defined are forced to be initialized, populating various - // registries. - if (std::getenv("bar") != (char *)-1) + // We must reference the passes in such a way that compilers will not delete + // it all as dead code, even with whole program optimization, yet is + // effectively a NO-OP. This is so that globals in the translation units + // where these functions are defined are forced to be initialized, + // populating various registries. + if (llvm::getNonFoldableAlwaysTrue()) return; (void)llvm::createAtomicExpandLegacyPass(); diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h index 4b6b42f..14a2429 100644 --- a/llvm/include/llvm/MC/DXContainerRootSignature.h +++ b/llvm/include/llvm/MC/DXContainerRootSignature.h @@ -6,6 +6,9 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_MC_DXCONTAINERROOTSIGNATURE_H +#define LLVM_MC_DXCONTAINERROOTSIGNATURE_H + #include "llvm/BinaryFormat/DXContainer.h" #include <cstdint> #include <limits> @@ -116,3 +119,5 @@ struct RootSignatureDesc { }; } // namespace mcdxbc } // namespace llvm + +#endif // LLVM_MC_DXCONTAINERROOTSIGNATURE_H diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h index 71da048..6c12cd3 100644 --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -35,6 +35,7 @@ class MCStreamer; class MCSubtargetInfo; class MCSymbol; class MCValue; +class Triple; class raw_ostream; namespace WinEH { @@ -485,6 +486,9 @@ public: /// syntactically correct. virtual bool isValidUnquotedName(StringRef Name) const; + virtual void printSwitchToSection(const MCSection &, uint32_t Subsection, + const Triple &, raw_ostream &) const {} + /// Return true if the .section directive should be omitted when /// emitting \p SectionName. For example: /// @@ -494,6 +498,10 @@ public: /// returns true => .text virtual bool shouldOmitSectionDirective(StringRef SectionName) const; + // Return true if a .align directive should use "optimized nops" to fill + // instead of 0s. + virtual bool useCodeAlign(const MCSection &Sec) const { return false; } + bool usesSunStyleELFSectionSwitchSyntax() const { return SunStyleELFSectionSwitchSyntax; } diff --git a/llvm/include/llvm/MC/MCAsmInfoCOFF.h b/llvm/include/llvm/MC/MCAsmInfoCOFF.h index 1dfb475..dc7832c 100644 --- a/llvm/include/llvm/MC/MCAsmInfoCOFF.h +++ b/llvm/include/llvm/MC/MCAsmInfoCOFF.h @@ -15,6 +15,9 @@ namespace llvm { class MCAsmInfoCOFF : public MCAsmInfo { virtual void anchor(); + void printSwitchToSection(const MCSection &, uint32_t, const Triple &, + raw_ostream &) const final; + bool useCodeAlign(const MCSection &Sec) const final; protected: explicit MCAsmInfoCOFF(); diff --git a/llvm/include/llvm/MC/MCAsmInfoDarwin.h b/llvm/include/llvm/MC/MCAsmInfoDarwin.h index 4ca62b3..12bc3e9 100644 --- a/llvm/include/llvm/MC/MCAsmInfoDarwin.h +++ b/llvm/include/llvm/MC/MCAsmInfoDarwin.h @@ -21,6 +21,9 @@ namespace llvm { class MCAsmInfoDarwin : public MCAsmInfo { public: explicit MCAsmInfoDarwin(); + void printSwitchToSection(const MCSection &, uint32_t, const Triple &, + raw_ostream &) const final; + bool useCodeAlign(const MCSection &Sec) const final; /// True if the section is atomized using the symbols in it. /// This is false if the section is atomized based on its contents (MachO' __TEXT,__cstring for diff --git a/llvm/include/llvm/MC/MCAsmInfoELF.h b/llvm/include/llvm/MC/MCAsmInfoELF.h index 408d4df..c05e4ad 100644 --- a/llvm/include/llvm/MC/MCAsmInfoELF.h +++ b/llvm/include/llvm/MC/MCAsmInfoELF.h @@ -16,6 +16,9 @@ namespace llvm { class MCAsmInfoELF : public MCAsmInfo { virtual void anchor(); MCSection *getNonexecutableStackSection(MCContext &Ctx) const final; + void printSwitchToSection(const MCSection &, uint32_t, const Triple &, + raw_ostream &) const final; + bool useCodeAlign(const MCSection &Sec) const final; protected: MCAsmInfoELF(); diff --git a/llvm/include/llvm/MC/MCAsmInfoGOFF.h b/llvm/include/llvm/MC/MCAsmInfoGOFF.h index 1f3b263..e62d2ae 100644 --- a/llvm/include/llvm/MC/MCAsmInfoGOFF.h +++ b/llvm/include/llvm/MC/MCAsmInfoGOFF.h @@ -19,7 +19,8 @@ namespace llvm { class MCAsmInfoGOFF : public MCAsmInfo { - virtual void anchor(); + void printSwitchToSection(const MCSection &, uint32_t, const Triple &, + raw_ostream &) const final; protected: MCAsmInfoGOFF(); diff --git a/llvm/include/llvm/MC/MCAsmInfoWasm.h b/llvm/include/llvm/MC/MCAsmInfoWasm.h index 3afc610..d98de6c 100644 --- a/llvm/include/llvm/MC/MCAsmInfoWasm.h +++ b/llvm/include/llvm/MC/MCAsmInfoWasm.h @@ -13,7 +13,8 @@ namespace llvm { class MCAsmInfoWasm : public MCAsmInfo { - virtual void anchor(); + void printSwitchToSection(const MCSection &, uint32_t, const Triple &, + raw_ostream &) const final; protected: MCAsmInfoWasm(); diff --git a/llvm/include/llvm/MC/MCAsmInfoXCOFF.h b/llvm/include/llvm/MC/MCAsmInfoXCOFF.h index 5483899..fd1ae82 100644 --- a/llvm/include/llvm/MC/MCAsmInfoXCOFF.h +++ b/llvm/include/llvm/MC/MCAsmInfoXCOFF.h @@ -14,10 +14,11 @@ namespace llvm { class MCAsmInfoXCOFF : public MCAsmInfo { - virtual void anchor(); - protected: MCAsmInfoXCOFF(); + void printSwitchToSection(const MCSection &, uint32_t, const Triple &, + raw_ostream &) const final; + bool useCodeAlign(const MCSection &Sec) const final; public: // Return true only when C is an acceptable character inside a diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h index c137f61..ddac161 100644 --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -333,8 +333,6 @@ private: void reportCommon(SMLoc Loc, std::function<void(SMDiagnostic &, const SourceMgr *)>); - MCFragment *allocInitialFragment(MCSection &Sec); - MCSymbolTableEntry &getSymbolTableEntry(StringRef Name); MCSymbol *createSymbolImpl(const MCSymbolTableEntry *Name, bool IsTemporary); diff --git a/llvm/include/llvm/MC/MCMachObjectWriter.h b/llvm/include/llvm/MC/MCMachObjectWriter.h index 51e4df5..170e2e7 100644 --- a/llvm/include/llvm/MC/MCMachObjectWriter.h +++ b/llvm/include/llvm/MC/MCMachObjectWriter.h @@ -16,7 +16,7 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCObjectWriter.h" -#include "llvm/MC/MCSection.h" +#include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/StringTableBuilder.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/EndianStream.h" @@ -276,7 +276,7 @@ public: uint64_t SectionDataSize, uint32_t MaxProt, uint32_t InitProt); - void writeSection(const MCAssembler &Asm, const MCSection &Sec, + void writeSection(const MCAssembler &Asm, const MCSectionMachO &Sec, uint64_t VMAddr, uint64_t FileOffset, unsigned Flags, uint64_t RelocationsStart, unsigned NumRelocations); diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h index 2ceeba2..bbbee15 100644 --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -40,6 +40,7 @@ class MCObjectStreamer : public MCStreamer { std::unique_ptr<MCAssembler> Assembler; bool EmitEHFrame; bool EmitDebugFrame; + bool EmitSFrame; struct PendingAssignment { MCSymbol *Symbol; @@ -70,7 +71,7 @@ public: void emitFrames(MCAsmBackend *MAB); MCSymbol *emitCFILabel() override; - void emitCFISections(bool EH, bool Debug) override; + void emitCFISections(bool EH, bool Debug, bool SFrame) override; public: void visitUsedSymbol(const MCSymbol &Sym) override; @@ -101,7 +102,6 @@ public: void emitSLEB128Value(const MCExpr *Value) override; void emitWeakReference(MCSymbol *Alias, const MCSymbol *Target) override; void changeSection(MCSection *Section, uint32_t Subsection = 0) override; - void switchSectionNoPrint(MCSection *Section) override; void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; /// Emit an instruction to a special fragment, because this instruction diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h index 87a8349..7989310 100644 --- a/llvm/include/llvm/MC/MCSection.h +++ b/llvm/include/llvm/MC/MCSection.h @@ -39,147 +39,6 @@ class MCSubtargetInfo; class raw_ostream; class Triple; -/// Instances of this class represent a uniqued identifier for a section in the -/// current translation unit. The MCContext class uniques and creates these. -class LLVM_ABI MCSection { -public: - friend MCAssembler; - friend MCObjectStreamer; - friend class MCFragment; - static constexpr unsigned NonUniqueID = ~0U; - - enum SectionVariant { - SV_COFF = 0, - SV_ELF, - SV_GOFF, - SV_MachO, - SV_Wasm, - SV_XCOFF, - SV_SPIRV, - SV_DXContainer, - }; - - struct iterator { - MCFragment *F = nullptr; - iterator() = default; - explicit iterator(MCFragment *F) : F(F) {} - MCFragment &operator*() const { return *F; } - bool operator==(const iterator &O) const { return F == O.F; } - bool operator!=(const iterator &O) const { return F != O.F; } - iterator &operator++(); - }; - - struct FragList { - MCFragment *Head = nullptr; - MCFragment *Tail = nullptr; - }; - -private: - // At parse time, this holds the fragment list of the current subsection. At - // layout time, this holds the concatenated fragment lists of all subsections. - FragList *CurFragList; - MCSymbol *Begin; - MCSymbol *End = nullptr; - /// The alignment requirement of this section. - Align Alignment; - /// The section index in the assemblers section list. - unsigned Ordinal = 0; - - /// Whether this section has had instructions emitted into it. - bool HasInstructions : 1; - - bool IsRegistered : 1; - - bool IsText : 1; - bool IsBss : 1; - - /// Whether the section contains linker-relaxable fragments. If true, the - /// offset between two locations may not be fully resolved. - bool LinkerRelaxable : 1; - - // Mapping from subsection number to fragment list. At layout time, the - // subsection 0 list is replaced with concatenated fragments from all - // subsections. - SmallVector<std::pair<unsigned, FragList>, 1> Subsections; - - // Content and fixup storage for fragments - SmallVector<char, 0> ContentStorage; - SmallVector<MCFixup, 0> FixupStorage; - SmallVector<MCOperand, 0> MCOperandStorage; - -protected: - // TODO Make Name private when possible. - StringRef Name; - SectionVariant Variant; - - MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsBss, - MCSymbol *Begin); - // Protected non-virtual dtor prevents destroy through a base class pointer. - ~MCSection() {} - -public: - MCSection(const MCSection &) = delete; - MCSection &operator=(const MCSection &) = delete; - - StringRef getName() const { return Name; } - bool isText() const { return IsText; } - - SectionVariant getVariant() const { return Variant; } - - MCSymbol *getBeginSymbol() { return Begin; } - const MCSymbol *getBeginSymbol() const { - return const_cast<MCSection *>(this)->getBeginSymbol(); - } - void setBeginSymbol(MCSymbol *Sym) { - assert(!Begin); - Begin = Sym; - } - MCSymbol *getEndSymbol(MCContext &Ctx); - bool hasEnded() const; - - Align getAlign() const { return Alignment; } - void setAlignment(Align Value) { Alignment = Value; } - - /// Makes sure that Alignment is at least MinAlignment. - void ensureMinAlignment(Align MinAlignment) { - if (Alignment < MinAlignment) - Alignment = MinAlignment; - } - - unsigned getOrdinal() const { return Ordinal; } - void setOrdinal(unsigned Value) { Ordinal = Value; } - - bool hasInstructions() const { return HasInstructions; } - void setHasInstructions(bool Value) { HasInstructions = Value; } - - bool isRegistered() const { return IsRegistered; } - void setIsRegistered(bool Value) { IsRegistered = Value; } - - bool isLinkerRelaxable() const { return LinkerRelaxable; } - void setLinkerRelaxable() { LinkerRelaxable = true; } - - MCFragment &getDummyFragment() { return *Subsections[0].second.Head; } - - FragList *curFragList() const { return CurFragList; } - iterator begin() const { return iterator(CurFragList->Head); } - iterator end() const { return {}; } - - void dump(DenseMap<const MCFragment *, SmallVector<const MCSymbol *, 0>> - *FragToSyms = nullptr) const; - - virtual void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, - raw_ostream &OS, - uint32_t Subsection) const = 0; - - /// Return true if a .align directive should use "optimized nops" to fill - /// instead of 0s. - virtual bool useCodeAlign() const = 0; - - /// Check whether this section is "virtual", that is has no actual object - /// file contents. - bool isBssSection() const { return IsBss; } -}; - // Represents a contiguous piece of code or data within a section. Its size is // determined by MCAssembler::layout. All subclasses must have trivial // destructors. @@ -348,19 +207,8 @@ public: // Get a SmallVector reference. The caller should call doneAppending to update // `ContentEnd`. - SmallVectorImpl<char> &getContentsForAppending() { - SmallVectorImpl<char> &S = getParent()->ContentStorage; - if (LLVM_UNLIKELY(ContentEnd != S.size())) { - // Move the elements to the end. Reserve space to avoid invalidating - // S.begin()+I for `append`. - auto Size = ContentEnd - ContentStart; - auto I = std::exchange(ContentStart, S.size()); - S.reserve(S.size() + Size); - S.append(S.begin() + I, S.begin() + I + Size); - } - return S; - } - void doneAppending() { ContentEnd = getParent()->ContentStorage.size(); } + SmallVectorImpl<char> &getContentsForAppending(); + void doneAppending(); void appendContents(ArrayRef<char> Contents) { getContentsForAppending().append(Contents.begin(), Contents.end()); doneAppending(); @@ -369,25 +217,13 @@ public: getContentsForAppending().append(Num, Elt); doneAppending(); } - MutableArrayRef<char> getContents() { - return MutableArrayRef(getParent()->ContentStorage) - .slice(ContentStart, ContentEnd - ContentStart); - } - ArrayRef<char> getContents() const { - return ArrayRef(getParent()->ContentStorage) - .slice(ContentStart, ContentEnd - ContentStart); - } + MutableArrayRef<char> getContents(); + ArrayRef<char> getContents() const; void setVarContents(ArrayRef<char> Contents); void clearVarContents() { setVarContents({}); } - MutableArrayRef<char> getVarContents() { - return MutableArrayRef(getParent()->ContentStorage) - .slice(VarContentStart, VarContentEnd - VarContentStart); - } - ArrayRef<char> getVarContents() const { - return ArrayRef(getParent()->ContentStorage) - .slice(VarContentStart, VarContentEnd - VarContentStart); - } + MutableArrayRef<char> getVarContents(); + ArrayRef<char> getVarContents() const; size_t getFixedSize() const { return ContentEnd - ContentStart; } size_t getVarSize() const { return VarContentEnd - VarContentStart; } @@ -400,59 +236,24 @@ public: void clearFixups() { FixupEnd = FixupStart; } LLVM_ABI void addFixup(MCFixup Fixup); LLVM_ABI void appendFixups(ArrayRef<MCFixup> Fixups); - MutableArrayRef<MCFixup> getFixups() { - return MutableArrayRef(getParent()->FixupStorage) - .slice(FixupStart, FixupEnd - FixupStart); - } - ArrayRef<MCFixup> getFixups() const { - return ArrayRef(getParent()->FixupStorage) - .slice(FixupStart, FixupEnd - FixupStart); - } + MutableArrayRef<MCFixup> getFixups(); + ArrayRef<MCFixup> getFixups() const; // Source fixup offsets are relative to the variable part's start. // Stored fixup offsets are relative to the fixed part's start. void setVarFixups(ArrayRef<MCFixup> Fixups); void clearVarFixups() { setVarFixups({}); } - MutableArrayRef<MCFixup> getVarFixups() { - return MutableArrayRef(getParent()->FixupStorage) - .slice(VarFixupStart, VarFixupEnd - VarFixupStart); - } - ArrayRef<MCFixup> getVarFixups() const { - return ArrayRef(getParent()->FixupStorage) - .slice(VarFixupStart, VarFixupEnd - VarFixupStart); - } + MutableArrayRef<MCFixup> getVarFixups(); + ArrayRef<MCFixup> getVarFixups() const; //== FT_Relaxable functions unsigned getOpcode() const { assert(Kind == FT_Relaxable); return u.relax.Opcode; } - ArrayRef<MCOperand> getOperands() const { - assert(Kind == FT_Relaxable); - return MutableArrayRef(getParent()->MCOperandStorage) - .slice(u.relax.OperandStart, u.relax.OperandSize); - } - MCInst getInst() const { - assert(Kind == FT_Relaxable); - MCInst Inst; - Inst.setOpcode(u.relax.Opcode); - Inst.setFlags(u.relax.Flags); - Inst.setOperands(ArrayRef(getParent()->MCOperandStorage) - .slice(u.relax.OperandStart, u.relax.OperandSize)); - return Inst; - } - void setInst(const MCInst &Inst) { - assert(Kind == FT_Relaxable); - u.relax.Opcode = Inst.getOpcode(); - u.relax.Flags = Inst.getFlags(); - auto &S = getParent()->MCOperandStorage; - if (Inst.getNumOperands() > u.relax.OperandSize) { - u.relax.OperandStart = S.size(); - S.resize_for_overwrite(S.size() + Inst.getNumOperands()); - } - u.relax.OperandSize = Inst.getNumOperands(); - llvm::copy(Inst, S.begin() + u.relax.OperandStart); - } + ArrayRef<MCOperand> getOperands() const; + MCInst getInst() const; + void setInst(const MCInst &Inst); //== FT_Align functions void makeAlign(Align Alignment, int64_t Fill, uint8_t FillLen, @@ -730,6 +531,207 @@ public: } }; +/// Instances of this class represent a uniqued identifier for a section in the +/// current translation unit. The MCContext class uniques and creates these. +class LLVM_ABI MCSection { +public: + friend MCAssembler; + friend MCObjectStreamer; + friend class MCFragment; + static constexpr unsigned NonUniqueID = ~0U; + + struct iterator { + MCFragment *F = nullptr; + iterator() = default; + explicit iterator(MCFragment *F) : F(F) {} + MCFragment &operator*() const { return *F; } + bool operator==(const iterator &O) const { return F == O.F; } + bool operator!=(const iterator &O) const { return F != O.F; } + iterator &operator++(); + }; + + struct FragList { + MCFragment *Head = nullptr; + MCFragment *Tail = nullptr; + }; + +private: + // At parse time, this holds the fragment list of the current subsection. At + // layout time, this holds the concatenated fragment lists of all subsections. + FragList *CurFragList; + // In many object file formats, this denotes the section symbol. In Mach-O, + // this denotes an optional temporary label at the section start. + MCSymbol *Begin; + MCSymbol *End = nullptr; + /// The alignment requirement of this section. + Align Alignment; + /// The section index in the assemblers section list. + unsigned Ordinal = 0; + + /// Whether this section has had instructions emitted into it. + bool HasInstructions : 1; + + bool IsRegistered : 1; + + bool IsText : 1; + bool IsBss : 1; + + /// Whether the section contains linker-relaxable fragments. If true, the + /// offset between two locations may not be fully resolved. + bool LinkerRelaxable : 1; + + MCFragment DummyFragment; + + // Mapping from subsection number to fragment list. At layout time, the + // subsection 0 list is replaced with concatenated fragments from all + // subsections. + SmallVector<std::pair<unsigned, FragList>, 1> Subsections; + + // Content and fixup storage for fragments + SmallVector<char, 0> ContentStorage; + SmallVector<MCFixup, 0> FixupStorage; + SmallVector<MCOperand, 0> MCOperandStorage; + +protected: + // TODO Make Name private when possible. + StringRef Name; + + MCSection(StringRef Name, bool IsText, bool IsBss, MCSymbol *Begin); + +public: + MCSection(const MCSection &) = delete; + MCSection &operator=(const MCSection &) = delete; + + StringRef getName() const { return Name; } + bool isText() const { return IsText; } + + MCSymbol *getBeginSymbol() { return Begin; } + const MCSymbol *getBeginSymbol() const { + return const_cast<MCSection *>(this)->getBeginSymbol(); + } + void setBeginSymbol(MCSymbol *Sym) { + assert(!Begin); + Begin = Sym; + } + MCSymbol *getEndSymbol(MCContext &Ctx); + bool hasEnded() const; + + Align getAlign() const { return Alignment; } + void setAlignment(Align Value) { Alignment = Value; } + + /// Makes sure that Alignment is at least MinAlignment. + void ensureMinAlignment(Align MinAlignment) { + if (Alignment < MinAlignment) + Alignment = MinAlignment; + } + + unsigned getOrdinal() const { return Ordinal; } + void setOrdinal(unsigned Value) { Ordinal = Value; } + + bool hasInstructions() const { return HasInstructions; } + void setHasInstructions(bool Value) { HasInstructions = Value; } + + bool isRegistered() const { return IsRegistered; } + void setIsRegistered(bool Value) { IsRegistered = Value; } + + bool isLinkerRelaxable() const { return LinkerRelaxable; } + void setLinkerRelaxable() { LinkerRelaxable = true; } + + MCFragment &getDummyFragment() { return DummyFragment; } + + FragList *curFragList() const { return CurFragList; } + iterator begin() const { return iterator(CurFragList->Head); } + iterator end() const { return {}; } + + void dump(DenseMap<const MCFragment *, SmallVector<const MCSymbol *, 0>> + *FragToSyms = nullptr) const; + + /// Check whether this section is "virtual", that is has no actual object + /// file contents. + bool isBssSection() const { return IsBss; } +}; + +inline SmallVectorImpl<char> &MCFragment::getContentsForAppending() { + SmallVectorImpl<char> &S = getParent()->ContentStorage; + if (LLVM_UNLIKELY(ContentEnd != S.size())) { + // Move the elements to the end. Reserve space to avoid invalidating + // S.begin()+I for `append`. + auto Size = ContentEnd - ContentStart; + auto I = std::exchange(ContentStart, S.size()); + S.reserve(S.size() + Size); + S.append(S.begin() + I, S.begin() + I + Size); + } + return S; +} +inline void MCFragment::doneAppending() { + ContentEnd = getParent()->ContentStorage.size(); +} +inline MutableArrayRef<char> MCFragment::getContents() { + return MutableArrayRef(getParent()->ContentStorage) + .slice(ContentStart, ContentEnd - ContentStart); +} +inline ArrayRef<char> MCFragment::getContents() const { + return ArrayRef(getParent()->ContentStorage) + .slice(ContentStart, ContentEnd - ContentStart); +} + +inline MutableArrayRef<char> MCFragment::getVarContents() { + return MutableArrayRef(getParent()->ContentStorage) + .slice(VarContentStart, VarContentEnd - VarContentStart); +} +inline ArrayRef<char> MCFragment::getVarContents() const { + return ArrayRef(getParent()->ContentStorage) + .slice(VarContentStart, VarContentEnd - VarContentStart); +} + +//== Fixup-related functions manage parent's storage using FixupStart and +// FixupSize. +inline MutableArrayRef<MCFixup> MCFragment::getFixups() { + return MutableArrayRef(getParent()->FixupStorage) + .slice(FixupStart, FixupEnd - FixupStart); +} +inline ArrayRef<MCFixup> MCFragment::getFixups() const { + return ArrayRef(getParent()->FixupStorage) + .slice(FixupStart, FixupEnd - FixupStart); +} + +inline MutableArrayRef<MCFixup> MCFragment::getVarFixups() { + return MutableArrayRef(getParent()->FixupStorage) + .slice(VarFixupStart, VarFixupEnd - VarFixupStart); +} +inline ArrayRef<MCFixup> MCFragment::getVarFixups() const { + return ArrayRef(getParent()->FixupStorage) + .slice(VarFixupStart, VarFixupEnd - VarFixupStart); +} + +//== FT_Relaxable functions +inline ArrayRef<MCOperand> MCFragment::getOperands() const { + assert(Kind == FT_Relaxable); + return MutableArrayRef(getParent()->MCOperandStorage) + .slice(u.relax.OperandStart, u.relax.OperandSize); +} +inline MCInst MCFragment::getInst() const { + assert(Kind == FT_Relaxable); + MCInst Inst; + Inst.setOpcode(u.relax.Opcode); + Inst.setFlags(u.relax.Flags); + Inst.setOperands(ArrayRef(getParent()->MCOperandStorage) + .slice(u.relax.OperandStart, u.relax.OperandSize)); + return Inst; +} +inline void MCFragment::setInst(const MCInst &Inst) { + assert(Kind == FT_Relaxable); + u.relax.Opcode = Inst.getOpcode(); + u.relax.Flags = Inst.getFlags(); + auto &S = getParent()->MCOperandStorage; + if (Inst.getNumOperands() > u.relax.OperandSize) { + u.relax.OperandStart = S.size(); + S.resize_for_overwrite(S.size() + Inst.getNumOperands()); + } + u.relax.OperandSize = Inst.getNumOperands(); + llvm::copy(Inst, S.begin() + u.relax.OperandStart); +} + inline MCSection::iterator &MCSection::iterator::operator++() { F = F->Next; return *this; diff --git a/llvm/include/llvm/MC/MCSectionCOFF.h b/llvm/include/llvm/MC/MCSectionCOFF.h index f979413a..71efc41 100644 --- a/llvm/include/llvm/MC/MCSectionCOFF.h +++ b/llvm/include/llvm/MC/MCSectionCOFF.h @@ -51,11 +51,12 @@ class MCSectionCOFF final : public MCSection { private: friend class MCContext; + friend class MCAsmInfoCOFF; // The storage of Name is owned by MCContext's COFFUniquingMap. MCSectionCOFF(StringRef Name, unsigned Characteristics, MCSymbol *COMDATSymbol, int Selection, unsigned UniqueID, MCSymbol *Begin) - : MCSection(SV_COFF, Name, Characteristics & COFF::IMAGE_SCN_CNT_CODE, + : MCSection(Name, Characteristics & COFF::IMAGE_SCN_CNT_CODE, Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA, Begin), Characteristics(Characteristics), COMDATSymbol(COMDATSymbol), @@ -67,7 +68,7 @@ private: public: /// Decides whether a '.section' directive should be printed before the /// section name - bool shouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; + bool shouldOmitSectionDirective(StringRef Name) const; unsigned getCharacteristics() const { return Characteristics; } MCSymbol *getCOMDATSymbol() const { return COMDATSymbol; } @@ -78,11 +79,6 @@ public: bool isUnique() const { return UniqueID != NonUniqueID; } unsigned getUniqueID() const { return UniqueID; } - void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, - raw_ostream &OS, - uint32_t Subsection) const override; - bool useCodeAlign() const override; - unsigned getOrAssignWinCFISectionID(unsigned *NextID) const { if (WinCFISectionID == ~0U) WinCFISectionID = (*NextID)++; @@ -92,8 +88,6 @@ public: static bool isImplicitlyDiscardable(StringRef Name) { return Name.starts_with(".debug"); } - - static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; } }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCSectionDXContainer.h b/llvm/include/llvm/MC/MCSectionDXContainer.h index 723b477..7d8e0c5 100644 --- a/llvm/include/llvm/MC/MCSectionDXContainer.h +++ b/llvm/include/llvm/MC/MCSectionDXContainer.h @@ -24,13 +24,7 @@ class MCSectionDXContainer final : public MCSection { friend class MCContext; MCSectionDXContainer(StringRef Name, SectionKind K, MCSymbol *Begin) - : MCSection(SV_DXContainer, Name, K.isText(), /*IsVirtual=*/false, - Begin) {} - -public: - void printSwitchToSection(const MCAsmInfo &, const Triple &, raw_ostream &, - uint32_t) const override; - bool useCodeAlign() const override { return false; } + : MCSection(Name, K.isText(), /*IsVirtual=*/false, Begin) {} }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCSectionELF.h b/llvm/include/llvm/MC/MCSectionELF.h index 64a4daf..f089dd9 100644 --- a/llvm/include/llvm/MC/MCSectionELF.h +++ b/llvm/include/llvm/MC/MCSectionELF.h @@ -52,14 +52,15 @@ class MCSectionELF final : public MCSection { private: friend class MCContext; + friend class MCAsmInfoELF; // The storage of Name is owned by MCContext's ELFUniquingMap. MCSectionELF(StringRef Name, unsigned type, unsigned flags, unsigned entrySize, const MCSymbolELF *group, bool IsComdat, unsigned UniqueID, MCSymbol *Begin, const MCSymbolELF *LinkedToSym) - : MCSection(SV_ELF, Name, flags & ELF::SHF_EXECINSTR, - type == ELF::SHT_NOBITS, Begin), + : MCSection(Name, flags & ELF::SHF_EXECINSTR, type == ELF::SHT_NOBITS, + Begin), Type(type), Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group, IsComdat), LinkedToSym(LinkedToSym) { assert((!(Flags & ELF::SHF_GROUP) || Group.getPointer()) && @@ -69,10 +70,6 @@ private: } public: - /// Decides whether a '.section' directive should be printed before the - /// section name - bool shouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; - unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } unsigned getEntrySize() const { return EntrySize; } @@ -80,11 +77,6 @@ public: const MCSymbolELF *getGroup() const { return Group.getPointer(); } bool isComdat() const { return Group.getInt(); } - void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, - raw_ostream &OS, - uint32_t Subsection) const override; - bool useCodeAlign() const override; - bool isUnique() const { return UniqueID != NonUniqueID; } unsigned getUniqueID() const { return UniqueID; } @@ -100,10 +92,6 @@ public: std::pair<uint64_t, uint64_t> getOffsets() const { return std::make_pair(StartOffset, EndOffset); } - - static bool classof(const MCSection *S) { - return S->getVariant() == SV_ELF; - } }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h index b166397..2136148 100644 --- a/llvm/include/llvm/MC/MCSectionGOFF.h +++ b/llvm/include/llvm/MC/MCSectionGOFF.h @@ -52,36 +52,28 @@ class LLVM_ABI MCSectionGOFF final : public MCSection { mutable unsigned Emitted : 1; friend class MCContext; + friend class MCAsmInfoGOFF; friend class MCSymbolGOFF; MCSectionGOFF(StringRef Name, SectionKind K, bool IsVirtual, GOFF::SDAttr SDAttributes, MCSectionGOFF *Parent) - : MCSection(SV_GOFF, Name, K.isText(), IsVirtual, nullptr), - Parent(Parent), SDAttributes(SDAttributes), - SymbolType(GOFF::ESD_ST_SectionDefinition), IsBSS(K.isBSS()), - RequiresNonZeroLength(0), Emitted(0) {} + : MCSection(Name, K.isText(), IsVirtual, nullptr), Parent(Parent), + SDAttributes(SDAttributes), SymbolType(GOFF::ESD_ST_SectionDefinition), + IsBSS(K.isBSS()), RequiresNonZeroLength(0), Emitted(0) {} MCSectionGOFF(StringRef Name, SectionKind K, bool IsVirtual, GOFF::EDAttr EDAttributes, MCSectionGOFF *Parent) - : MCSection(SV_GOFF, Name, K.isText(), IsVirtual, nullptr), - Parent(Parent), EDAttributes(EDAttributes), - SymbolType(GOFF::ESD_ST_ElementDefinition), IsBSS(K.isBSS()), - RequiresNonZeroLength(0), Emitted(0) {} + : MCSection(Name, K.isText(), IsVirtual, nullptr), Parent(Parent), + EDAttributes(EDAttributes), SymbolType(GOFF::ESD_ST_ElementDefinition), + IsBSS(K.isBSS()), RequiresNonZeroLength(0), Emitted(0) {} MCSectionGOFF(StringRef Name, SectionKind K, bool IsVirtual, GOFF::PRAttr PRAttributes, MCSectionGOFF *Parent) - : MCSection(SV_GOFF, Name, K.isText(), IsVirtual, nullptr), - Parent(Parent), PRAttributes(PRAttributes), - SymbolType(GOFF::ESD_ST_PartReference), IsBSS(K.isBSS()), - RequiresNonZeroLength(0), Emitted(0) {} + : MCSection(Name, K.isText(), IsVirtual, nullptr), Parent(Parent), + PRAttributes(PRAttributes), SymbolType(GOFF::ESD_ST_PartReference), + IsBSS(K.isBSS()), RequiresNonZeroLength(0), Emitted(0) {} public: - void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, - raw_ostream &OS, - uint32_t Subsection) const override; - - bool useCodeAlign() const override { return false; } - // Return the parent section. MCSectionGOFF *getParent() const { return Parent; } @@ -123,8 +115,6 @@ public: bool requiresNonZeroLength() const { return RequiresNonZeroLength; } void setName(StringRef SectionName) { Name = SectionName; } - - static bool classof(const MCSection *S) { return S->getVariant() == SV_GOFF; } }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCSectionMachO.h b/llvm/include/llvm/MC/MCSectionMachO.h index 4312175..a65d7e0 100644 --- a/llvm/include/llvm/MC/MCSectionMachO.h +++ b/llvm/include/llvm/MC/MCSectionMachO.h @@ -23,6 +23,8 @@ namespace llvm { /// This represents a section on a Mach-O system (used by Mac OS X). On a Mac /// system, these are also described in /usr/include/mach-o/loader.h. class LLVM_ABI MCSectionMachO final : public MCSection { + friend class MCContext; + friend class MCAsmInfoDarwin; char SegmentName[16]; // Not necessarily null terminated! /// This is the SECTION_TYPE and SECTION_ATTRIBUTES field of a section, drawn @@ -42,7 +44,6 @@ class LLVM_ABI MCSectionMachO final : public MCSection { MCSectionMachO(StringRef Segment, StringRef Section, unsigned TAA, unsigned reserved2, SectionKind K, MCSymbol *Begin); - friend class MCContext; public: StringRef getSegmentName() const { @@ -76,21 +77,12 @@ public: bool &TAAParsed, // Out. unsigned &StubSize); // Out. - void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, - raw_ostream &OS, - uint32_t Subsection) const override; - bool useCodeAlign() const override; - void allocAtoms(); const MCSymbol *getAtom(size_t I) const; void setAtom(size_t I, const MCSymbol *Sym); unsigned getLayoutOrder() const { return LayoutOrder; } void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } - - static bool classof(const MCSection *S) { - return S->getVariant() == SV_MachO; - } }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCSectionSPIRV.h b/llvm/include/llvm/MC/MCSectionSPIRV.h index 091114a..6850965 100644 --- a/llvm/include/llvm/MC/MCSectionSPIRV.h +++ b/llvm/include/llvm/MC/MCSectionSPIRV.h @@ -18,22 +18,13 @@ namespace llvm { -class MCSymbol; - class MCSectionSPIRV final : public MCSection { friend class MCContext; MCSectionSPIRV() - : MCSection(SV_SPIRV, "", /*IsText=*/true, /*IsVirtual=*/false, + : MCSection("", /*IsText=*/true, /*IsVirtual=*/false, /*Begin=*/nullptr) {} // TODO: Add StringRef Name to MCSectionSPIRV. - -public: - ~MCSectionSPIRV() = default; - void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, - raw_ostream &OS, - uint32_t Subsection) const override {} - bool useCodeAlign() const override { return false; } }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCSectionWasm.h b/llvm/include/llvm/MC/MCSectionWasm.h index 4523818..5ec01ed 100644 --- a/llvm/include/llvm/MC/MCSectionWasm.h +++ b/llvm/include/llvm/MC/MCSectionWasm.h @@ -49,26 +49,18 @@ class MCSectionWasm final : public MCSection { // The storage of Name is owned by MCContext's WasmUniquingMap. friend class MCContext; + friend class MCAsmInfoWasm; MCSectionWasm(StringRef Name, SectionKind K, unsigned SegmentFlags, const MCSymbolWasm *Group, unsigned UniqueID, MCSymbol *Begin) - : MCSection(SV_Wasm, Name, K.isText(), /*IsVirtual=*/false, Begin), + : MCSection(Name, K.isText(), /*IsVirtual=*/false, Begin), UniqueID(UniqueID), Group(Group), IsWasmData(K.isReadOnly() || K.isWriteable()), IsMetadata(K.isMetadata()), SegmentFlags(SegmentFlags) {} public: - /// Decides whether a '.section' directive should be printed before the - /// section name - bool shouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; - const MCSymbolWasm *getGroup() const { return Group; } unsigned getSegmentFlags() const { return SegmentFlags; } - void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, - raw_ostream &OS, - uint32_t Subsection) const override; - bool useCodeAlign() const override; - bool isWasmData() const { return IsWasmData; } bool isMetadata() const { return IsMetadata; } @@ -89,7 +81,6 @@ public: assert(isWasmData()); IsPassive = V; } - static bool classof(const MCSection *S) { return S->getVariant() == SV_Wasm; } }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCSectionXCOFF.h b/llvm/include/llvm/MC/MCSectionXCOFF.h index 499df6b5..0571f95 100644 --- a/llvm/include/llvm/MC/MCSectionXCOFF.h +++ b/llvm/include/llvm/MC/MCSectionXCOFF.h @@ -31,6 +31,7 @@ namespace llvm { // implemented yet. class MCSectionXCOFF final : public MCSection { friend class MCContext; + friend class MCAsmInfoXCOFF; std::optional<XCOFF::CsectProperties> CsectProp; MCSymbolXCOFF *const QualName; @@ -46,7 +47,7 @@ class MCSectionXCOFF final : public MCSection { XCOFF::SymbolType ST, SectionKind K, MCSymbolXCOFF *QualName, MCSymbol *Begin, StringRef SymbolTableName, bool MultiSymbolsAllowed) - : MCSection(SV_XCOFF, Name, K.isText(), + : MCSection(Name, K.isText(), /*IsVirtual=*/ST == XCOFF::XTY_CM && SMC != XCOFF::XMC_TD, Begin), CsectProp(XCOFF::CsectProperties(SMC, ST)), QualName(QualName), @@ -77,7 +78,7 @@ class MCSectionXCOFF final : public MCSection { XCOFF::DwarfSectionSubtypeFlags DwarfSubtypeFlags, MCSymbol *Begin, StringRef SymbolTableName, bool MultiSymbolsAllowed) - : MCSection(SV_XCOFF, Name, K.isText(), /*IsVirtual=*/false, Begin), + : MCSection(Name, K.isText(), /*IsVirtual=*/false, Begin), QualName(QualName), SymbolTableName(SymbolTableName), DwarfSubtypeFlags(DwarfSubtypeFlags), MultiSymbolsAllowed(MultiSymbolsAllowed), Kind(K) { @@ -95,10 +96,6 @@ class MCSectionXCOFF final : public MCSection { public: ~MCSectionXCOFF(); - static bool classof(const MCSection *S) { - return S->getVariant() == SV_XCOFF; - } - XCOFF::StorageMappingClass getMappingClass() const { assert(isCsect() && "Only csect section has mapping class property!"); return CsectProp->MappingClass; @@ -115,10 +112,6 @@ public: } MCSymbolXCOFF *getQualNameSymbol() const { return QualName; } - void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, - raw_ostream &OS, - uint32_t Subsection) const override; - bool useCodeAlign() const override; StringRef getSymbolTableName() const { return SymbolTableName; } void setSymbolTableName(StringRef STN) { SymbolTableName = STN; } bool isMultiSymbolsAllowed() const { return MultiSymbolsAllowed; } diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index 4bfc8f9..79c715e 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -438,7 +438,7 @@ public: assert(!CurFrag || CurFrag->getKind() == MCFragment::FT_Data); return CurFrag; } - size_t getCurFragOffset() const { return getCurrentFragment()->Offset; } + size_t getCurFragSize() const { return getCurrentFragment()->getFixedSize(); } /// Save the current and previous section on the section stack. void pushSection() { SectionStack.push_back( @@ -459,7 +459,7 @@ public: bool switchSection(MCSection *Section, const MCExpr *); /// Similar to switchSection, but does not print the section directive. - virtual void switchSectionNoPrint(MCSection *Section); + void switchSectionNoPrint(MCSection *Section); /// Create the default sections and set the initial one. virtual void initSections(bool NoExecStack, const MCSubtargetInfo &STI); @@ -986,7 +986,7 @@ public: const MCSymbol *Lo); virtual MCSymbol *getDwarfLineTableSymbol(unsigned CUID); - virtual void emitCFISections(bool EH, bool Debug); + virtual void emitCFISections(bool EH, bool Debug, bool SFrame); void emitCFIStartProc(bool IsSimple, SMLoc Loc = SMLoc()); void emitCFIEndProc(); virtual void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc = {}); diff --git a/llvm/include/llvm/MC/MCSymbolELF.h b/llvm/include/llvm/MC/MCSymbolELF.h index eba9964..7c271e7 100644 --- a/llvm/include/llvm/MC/MCSymbolELF.h +++ b/llvm/include/llvm/MC/MCSymbolELF.h @@ -13,6 +13,7 @@ namespace llvm { class MCSymbolELF : public MCSymbol { + friend class MCAsmInfoELF; /// An expression describing how to calculate the size of a symbol. If a /// symbol has no size this field will be NULL. const MCExpr *SymbolSize = nullptr; diff --git a/llvm/include/llvm/MC/MCTargetOptions.h b/llvm/include/llvm/MC/MCTargetOptions.h index d95adf9..235d58d 100644 --- a/llvm/include/llvm/MC/MCTargetOptions.h +++ b/llvm/include/llvm/MC/MCTargetOptions.h @@ -102,6 +102,9 @@ public: // functions on Darwins. bool EmitCompactUnwindNonCanonical : 1; + // Whether to emit SFrame unwind sections. + bool EmitSFrameUnwind : 1; + // Whether or not to use full register names on PowerPC. bool PPCUseFullRegisterNames : 1; diff --git a/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h b/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h index b057eff..adfdccd 100644 --- a/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h +++ b/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h @@ -40,6 +40,8 @@ LLVM_ABI EmitDwarfUnwindType getEmitDwarfUnwind(); LLVM_ABI bool getEmitCompactUnwindNonCanonical(); +LLVM_ABI bool getEmitSFrameUnwind(); + LLVM_ABI bool getShowMCInst(); LLVM_ABI bool getFatalWarnings(); diff --git a/llvm/include/llvm/MC/MCXCOFFStreamer.h b/llvm/include/llvm/MC/MCXCOFFStreamer.h index 870d48f..c3bc2ca9 100644 --- a/llvm/include/llvm/MC/MCXCOFFStreamer.h +++ b/llvm/include/llvm/MC/MCXCOFFStreamer.h @@ -22,6 +22,7 @@ public: XCOFFObjectWriter &getWriter(); + void changeSection(MCSection *Section, uint32_t Subsection = 0) override; bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment) override; diff --git a/llvm/include/llvm/Support/AArch64AttributeParser.h b/llvm/include/llvm/Support/AArch64AttributeParser.h index aa82ca1..796dbfd 100644 --- a/llvm/include/llvm/Support/AArch64AttributeParser.h +++ b/llvm/include/llvm/Support/AArch64AttributeParser.h @@ -25,6 +25,17 @@ public: : ELFExtendedAttrParser(nullptr, returnTagsNamesMap()) {} }; +// Used for extracting AArch64 Build Attributes +struct AArch64BuildAttrSubsections { + struct PauthSubSection { + uint64_t TagPlatform = 0; + uint64_t TagSchema = 0; + } Pauth; + uint32_t AndFeatures = 0; +}; + +AArch64BuildAttrSubsections +extractBuildAttributesSubsections(const llvm::AArch64AttributeParser &); } // namespace llvm #endif // LLVM_SUPPORT_AARCH64ATTRIBUTEPARSER_H diff --git a/llvm/include/llvm/Support/AlwaysTrue.h b/llvm/include/llvm/Support/AlwaysTrue.h new file mode 100644 index 0000000..b696856 --- /dev/null +++ b/llvm/include/llvm/Support/AlwaysTrue.h @@ -0,0 +1,25 @@ +//===--- AlwaysTrue.h - Helper for oqaque truthy values --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ALWAYS_TRUE_H +#define LLVM_SUPPORT_ALWAYS_TRUE_H + +#include <cstdlib> + +namespace llvm { +inline bool getNonFoldableAlwaysTrue() { + // Some parts of the codebase require a "constant true value" used as a + // predicate. These cases require that even with LTO and static linking, + // it's not possible for the compiler to fold the value. As compilers + // aren't smart enough to know that getenv() never returns -1, this will do + // the job. + return std::getenv("LLVM_IGNORED_ENV_VAR") != (char *)-1; +} +} // end namespace llvm + +#endif // LLVM_SUPPORT_ALWAYS_TRUE_H diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h index adaa75c..ca725b8 100644 --- a/llvm/include/llvm/Support/CommandLine.h +++ b/llvm/include/llvm/Support/CommandLine.h @@ -1518,11 +1518,18 @@ public: [](const typename ParserClass::parser_data_type &) {}; }; -extern template class opt<unsigned>; -extern template class opt<int>; -extern template class opt<std::string>; -extern template class opt<char>; -extern template class opt<bool>; +#if !(defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) && defined(_MSC_VER)) +// Only instantiate opt<std::string> when not building a Windows DLL. When +// exporting opt<std::string>, MSVC implicitly exports symbols for +// std::basic_string through transitive inheritance via std::string. These +// symbols may appear in clients, leading to duplicate symbol conflicts. +extern template class LLVM_TEMPLATE_ABI opt<std::string>; +#endif + +extern template class LLVM_TEMPLATE_ABI opt<unsigned>; +extern template class LLVM_TEMPLATE_ABI opt<int>; +extern template class LLVM_TEMPLATE_ABI opt<char>; +extern template class LLVM_TEMPLATE_ABI opt<bool>; //===----------------------------------------------------------------------===// // Default storage class definition: external storage. This implementation diff --git a/llvm/include/llvm/Support/DebugLog.h b/llvm/include/llvm/Support/DebugLog.h new file mode 100644 index 0000000..b1b17e3 --- /dev/null +++ b/llvm/include/llvm/Support/DebugLog.h @@ -0,0 +1,88 @@ +//===- llvm/Support/DebugLog.h - Logging like debug output ------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// This file contains macros for logging like debug output. It builds upon the +// support in Debug.h but provides a utility function for common debug output +// style. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_DEBUGLOG_H +#define LLVM_SUPPORT_DEBUGLOG_H + +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { +#ifndef NDEBUG + +// Output with given inputs and trailing newline. E.g., +// LDBG() << "Bitset contains: " << Bitset; +// is equivalent to +// LLVM_DEBUG(dbgs() << DEBUG_TYPE << " [" << __FILE__ << ":" << __LINE__ +// << "] " << "Bitset contains: " << Bitset << "\n"); +#define LDBG() DEBUGLOG_WITH_STREAM_AND_TYPE(llvm::dbgs(), DEBUG_TYPE) + +#if defined(__SHORT_FILE__) +#define DEBUGLOG_WITH_STREAM_AND_TYPE(STREAM, TYPE) \ + for (bool _c = (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE)); _c; \ + _c = false) \ + ::llvm::impl::LogWithNewline(TYPE, __SHORT_FILE__, __LINE__, (STREAM)) +#else +#define DEBUGLOG_WITH_STREAM_AND_TYPE(STREAM, TYPE) \ + for (bool _c = (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE)); _c; \ + _c = false) \ + ::llvm::impl::LogWithNewline(TYPE, __FILE__, __LINE__, (STREAM)) +#endif + +namespace impl { +class LogWithNewline { +public: + LogWithNewline(const char *debug_type, const char *file, int line, + raw_ostream &os) + : os(os) { +#if !defined(__SHORT_FILE__) + file = ::llvm::impl::LogWithNewline::getShortFileName(file); +#endif + if (debug_type) + os << "[" << debug_type << "] "; + os << file << ":" << line << " "; + } + ~LogWithNewline() { os << '\n'; } + template <typename T> raw_ostream &operator<<(const T &t) && { + return os << t; + } + + // Prevent copying, as this class manages newline responsibility and is + // intended for use as a temporary. + LogWithNewline(const LogWithNewline &) = delete; + LogWithNewline &operator=(const LogWithNewline &) = delete; + LogWithNewline &operator=(LogWithNewline &&) = delete; + static constexpr const char *getShortFileName(const char *path) { + // Remove the path prefix from the file name. + const char *filename = path; + for (const char *p = path; *p != '\0'; ++p) { + if (*p == '/' || *p == '\\') { + filename = p + 1; + } + } + return filename; + } + +private: + raw_ostream &os; +}; +} // end namespace impl +#else +// As others in Debug, When compiling without assertions, the -debug-* options +// and all inputs too LDBG() are ignored. +#define LDBG() \ + for (bool _c = false; _c; _c = false) \ + ::llvm::nulls() +#endif +} // end namespace llvm + +#endif // LLVM_SUPPORT_DEBUGLOG_H diff --git a/llvm/include/llvm/Support/ThreadPool.h b/llvm/include/llvm/Support/ThreadPool.h index 9272760..c26681c 100644 --- a/llvm/include/llvm/Support/ThreadPool.h +++ b/llvm/include/llvm/Support/ThreadPool.h @@ -149,10 +149,6 @@ public: /// number of threads! unsigned getMaxConcurrency() const override { return MaxThreadCount; } - // TODO: Remove, misleading legacy name warning! - LLVM_DEPRECATED("Use getMaxConcurrency instead", "getMaxConcurrency") - unsigned getThreadCount() const { return MaxThreadCount; } - /// Returns true if the current thread is a worker thread of this thread pool. bool isWorkerThread() const; @@ -233,10 +229,6 @@ public: /// Returns always 1: there is no concurrency. unsigned getMaxConcurrency() const override { return 1; } - // TODO: Remove, misleading legacy name warning! - LLVM_DEPRECATED("Use getMaxConcurrency instead", "getMaxConcurrency") - unsigned getThreadCount() const { return 1; } - /// Returns true if the current thread is a worker thread of this thread pool. bool isWorkerThread() const; diff --git a/llvm/include/llvm/TextAPI/SymbolSet.h b/llvm/include/llvm/TextAPI/SymbolSet.h index cd30663..a04cb35 100644 --- a/llvm/include/llvm/TextAPI/SymbolSet.h +++ b/llvm/include/llvm/TextAPI/SymbolSet.h @@ -92,6 +92,7 @@ private: public: SymbolSet() = default; + ~SymbolSet(); LLVM_ABI Symbol *addGlobal(EncodeKind Kind, StringRef Name, SymbolFlags Flags, const Target &Targ); size_t size() const { return Symbols.size(); } diff --git a/llvm/include/llvm/Transforms/ObjCARC.h b/llvm/include/llvm/Transforms/ObjCARC.h index c927513..c4b4c4f 100644 --- a/llvm/include/llvm/Transforms/ObjCARC.h +++ b/llvm/include/llvm/Transforms/ObjCARC.h @@ -35,10 +35,6 @@ struct ObjCARCContractPass : public PassInfoMixin<ObjCARCContractPass> { LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -struct ObjCARCAPElimPass : public PassInfoMixin<ObjCARCAPElimPass> { - LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); -}; - struct ObjCARCExpandPass : public PassInfoMixin<ObjCARCExpandPass> { LLVM_ABI PreservedAnalyses run(Function &M, FunctionAnalysisManager &AM); }; diff --git a/llvm/include/llvm/Transforms/Utils/ProfileVerify.h b/llvm/include/llvm/Transforms/Utils/ProfileVerify.h new file mode 100644 index 0000000..7834305 --- /dev/null +++ b/llvm/include/llvm/Transforms/Utils/ProfileVerify.h @@ -0,0 +1,36 @@ +//===- ProfileVerify.h - Verify profile info for testing ----------*-C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Inject profile information, as part of tests, to verify passes don't +// accidentally drop it. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TRANSFORMS_UTILS_PROFILEVERIFY_H +#define LLVM_TRANSFORMS_UTILS_PROFILEVERIFY_H + +#include "llvm/IR/Analysis.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { +/// Inject MD_prof metadata where it's missing. Used for testing that passes +/// don't accidentally drop this metadata. +class ProfileInjectorPass : public PassInfoMixin<ProfileInjectorPass> { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); +}; + +/// Checks that MD_prof is present on every instruction that supports it. Used +/// in conjunction with the ProfileInjectorPass. MD_prof "unknown" is considered +/// valid (i.e. !{!"unknown"}) +class ProfileVerifierPass : public PassInfoMixin<ProfileVerifierPass> { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); +}; + +} // namespace llvm +#endif diff --git a/llvm/include/module.modulemap b/llvm/include/module.modulemap index a4aae08..ac360b2 100644 --- a/llvm/include/module.modulemap +++ b/llvm/include/module.modulemap @@ -78,6 +78,7 @@ module LLVM_BinaryFormat { textual header "llvm/BinaryFormat/DynamicTags.def" textual header "llvm/BinaryFormat/MachO.def" textual header "llvm/BinaryFormat/MinidumpConstants.def" + textual header "llvm/BinaryFormat/SFrameConstants.def" textual header "llvm/BinaryFormat/Swift.def" textual header "llvm/BinaryFormat/ELFRelocs/AArch64.def" textual header "llvm/BinaryFormat/ELFRelocs/AMDGPU.def" |