Index: llvm/aaa =================================================================== --- llvm/aaa +++ /dev/null @@ -1,3064 +0,0 @@ -commit 37750fae1175c3615ce0b5198101938c9ffe6145 -Author: Xinmin Tian -Date: Wed Apr 3 18:43:30 2019 -0700 - - IR extensions to support directives - -diff --git a/llvm/include/llvm/IR/CMakeLists.txt b/llvm/include/llvm/IR/CMakeLists.txt -index 830f375..667323d 100644 ---- a/llvm/include/llvm/IR/CMakeLists.txt -+++ b/llvm/include/llvm/IR/CMakeLists.txt -@@ -1,7 +1,12 @@ - set(LLVM_TARGET_DEFINITIONS Attributes.td) - tablegen(LLVM Attributes.inc -gen-attrs) - - set(LLVM_TARGET_DEFINITIONS Intrinsics.td) - tablegen(LLVM IntrinsicEnums.inc -gen-intrinsic-enums) - tablegen(LLVM IntrinsicImpl.inc -gen-intrinsic-impl) - add_public_tablegen_target(intrinsics_gen) -+if (INTEL_COLLAB) -+set(LLVM_TARGET_DEFINITIONS Intel_Directives.td) -+tablegen(LLVM Intel_Directives.gen -gen-directives) -+add_public_tablegen_target(intel_directives_gen) -+endif(INTEL_COLLAB) -diff --git a/llvm/include/llvm/IR/GlobalValue.h b/llvm/include/llvm/IR/GlobalValue.h -index d78ce62..aff50f5 100644 ---- a/llvm/include/llvm/IR/GlobalValue.h -+++ b/llvm/include/llvm/IR/GlobalValue.h -@@ -1,586 +1,612 @@ - //===-- llvm/GlobalValue.h - Class to represent a global value --*- 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 is a common base class of all globally definable objects. As such, - // it is subclassed by GlobalVariable, GlobalAlias and by Function. This is - // used because you can do certain things with these global objects that you - // can't do to anything else. For example, use the address of one as a - // constant. - // - //===----------------------------------------------------------------------===// - - #ifndef LLVM_IR_GLOBALVALUE_H - #define LLVM_IR_GLOBALVALUE_H - - #include "llvm/ADT/StringRef.h" - #include "llvm/ADT/Twine.h" - #include "llvm/IR/Constant.h" - #include "llvm/IR/DerivedTypes.h" - #include "llvm/IR/Value.h" - #include "llvm/Support/Casting.h" - #include "llvm/Support/ErrorHandling.h" - #include "llvm/Support/MD5.h" - #include - #include - #include - - namespace llvm { - - class Comdat; - class ConstantRange; - class Error; - class GlobalObject; - class Module; - - namespace Intrinsic { - enum ID : unsigned; - } // end namespace Intrinsic - - class GlobalValue : public Constant { - public: - /// An enumeration for the kinds of linkage for global values. - enum LinkageTypes { - ExternalLinkage = 0,///< Externally visible function - AvailableExternallyLinkage, ///< Available for inspection, not emission. - LinkOnceAnyLinkage, ///< Keep one copy of function when linking (inline) - LinkOnceODRLinkage, ///< Same, but only replaced by something equivalent. - WeakAnyLinkage, ///< Keep one copy of named function when linking (weak) - WeakODRLinkage, ///< Same, but only replaced by something equivalent. - AppendingLinkage, ///< Special purpose, only applies to global arrays - InternalLinkage, ///< Rename collisions when linking (static functions). - PrivateLinkage, ///< Like Internal, but omit from symbol table. - ExternalWeakLinkage,///< ExternalWeak linkage description. - CommonLinkage ///< Tentative definitions. - }; - - /// An enumeration for the kinds of visibility of global values. - enum VisibilityTypes { - DefaultVisibility = 0, ///< The GV is visible - HiddenVisibility, ///< The GV is hidden - ProtectedVisibility ///< The GV is protected - }; - - /// Storage classes of global values for PE targets. - enum DLLStorageClassTypes { - DefaultStorageClass = 0, - DLLImportStorageClass = 1, ///< Function to be imported from DLL - DLLExportStorageClass = 2 ///< Function to be accessible from DLL. - }; - - protected: - GlobalValue(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, - LinkageTypes Linkage, const Twine &Name, unsigned AddressSpace) - : Constant(PointerType::get(Ty, AddressSpace), VTy, Ops, NumOps), - ValueType(Ty), Visibility(DefaultVisibility), - UnnamedAddrVal(unsigned(UnnamedAddr::None)), - DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal), -+#if INTEL_COLLAB -+ ThreadPrivate(0), TargetDeclare(0), -+#endif // INTEL_COLLAB - HasLLVMReservedName(false), IsDSOLocal(false), IntID((Intrinsic::ID)0U), - Parent(nullptr) { - setLinkage(Linkage); - setName(Name); - } - - Type *ValueType; - -+#if INTEL_COLLAB -+ // INTEL - This needs to be two less than it is in the community version to -+ // account for the ThreadPrivate bit and TargetDeclare bit. See also -+ // the comment at the SubClassData declaration. -+ static const unsigned GlobalValueSubClassDataBits = 15; -+#else - static const unsigned GlobalValueSubClassDataBits = 17; -+#endif // INTEL_COLLAB - - // All bitfields use unsigned as the underlying type so that MSVC will pack - // them. - unsigned Linkage : 4; // The linkage of this global - unsigned Visibility : 2; // The visibility style of this global - unsigned UnnamedAddrVal : 2; // This value's address is not significant - unsigned DllStorageClass : 2; // DLL storage class - - unsigned ThreadLocal : 3; // Is this symbol "Thread Local", if so, what is - // the desired model? -+#if INTEL_COLLAB -+ unsigned ThreadPrivate : 1; // The thread_private attribute indicates -+ // if the global variable is associated -+ // with an OpenMP threadprivate directive -+ // and the threadprivate mode is legacy. -+ unsigned TargetDeclare : 1; // The target declare attribute indicates -+ // if the global variable is associated -+ // with an OpenMP declare target directive. -+#endif // INTEL_COLLAB - - /// True if the function's name starts with "llvm.". This corresponds to the - /// value of Function::isIntrinsic(), which may be true even if - /// Function::intrinsicID() returns Intrinsic::not_intrinsic. - unsigned HasLLVMReservedName : 1; - - /// If true then there is a definition within the same linkage unit and that - /// definition cannot be runtime preempted. - unsigned IsDSOLocal : 1; - - private: - // Give subclasses access to what otherwise would be wasted padding. - // (17 + 4 + 2 + 2 + 2 + 3 + 1 + 1) == 32. - unsigned SubClassData : GlobalValueSubClassDataBits; - - friend class Constant; - - void destroyConstantImpl(); - Value *handleOperandChangeImpl(Value *From, Value *To); - - /// Returns true if the definition of this global may be replaced by a - /// differently optimized variant of the same source level function at link - /// time. - bool mayBeDerefined() const { - switch (getLinkage()) { - case WeakODRLinkage: - case LinkOnceODRLinkage: - case AvailableExternallyLinkage: - return true; - - case WeakAnyLinkage: - case LinkOnceAnyLinkage: - case CommonLinkage: - case ExternalWeakLinkage: - case ExternalLinkage: - case AppendingLinkage: - case InternalLinkage: - case PrivateLinkage: - return isInterposable(); - } - - llvm_unreachable("Fully covered switch above!"); - } - - void maybeSetDsoLocal() { - if (hasLocalLinkage() || - (!hasDefaultVisibility() && !hasExternalWeakLinkage())) - setDSOLocal(true); - } - - protected: - /// The intrinsic ID for this subclass (which must be a Function). - /// - /// This member is defined by this class, but not used for anything. - /// Subclasses can use it to store their intrinsic ID, if they have one. - /// - /// This is stored here to save space in Function on 64-bit hosts. - Intrinsic::ID IntID; - - unsigned getGlobalValueSubClassData() const { - return SubClassData; - } - void setGlobalValueSubClassData(unsigned V) { - assert(V < (1 << GlobalValueSubClassDataBits) && "It will not fit"); - SubClassData = V; - } - - Module *Parent; // The containing module. - - // Used by SymbolTableListTraits. - void setParent(Module *parent) { - Parent = parent; - } - - ~GlobalValue() { - removeDeadConstantUsers(); // remove any dead constants using this. - } - - public: - enum ThreadLocalMode { - NotThreadLocal = 0, - GeneralDynamicTLSModel, - LocalDynamicTLSModel, - InitialExecTLSModel, - LocalExecTLSModel - }; - - GlobalValue(const GlobalValue &) = delete; - - unsigned getAlignment() const; - unsigned getAddressSpace() const; - - enum class UnnamedAddr { - None, - Local, - Global, - }; - - bool hasGlobalUnnamedAddr() const { - return getUnnamedAddr() == UnnamedAddr::Global; - } - - /// Returns true if this value's address is not significant in this module. - /// This attribute is intended to be used only by the code generator and LTO - /// to allow the linker to decide whether the global needs to be in the symbol - /// table. It should probably not be used in optimizations, as the value may - /// have uses outside the module; use hasGlobalUnnamedAddr() instead. - bool hasAtLeastLocalUnnamedAddr() const { - return getUnnamedAddr() != UnnamedAddr::None; - } - - UnnamedAddr getUnnamedAddr() const { - return UnnamedAddr(UnnamedAddrVal); - } - void setUnnamedAddr(UnnamedAddr Val) { UnnamedAddrVal = unsigned(Val); } - - static UnnamedAddr getMinUnnamedAddr(UnnamedAddr A, UnnamedAddr B) { - if (A == UnnamedAddr::None || B == UnnamedAddr::None) - return UnnamedAddr::None; - if (A == UnnamedAddr::Local || B == UnnamedAddr::Local) - return UnnamedAddr::Local; - return UnnamedAddr::Global; - } - - bool hasComdat() const { return getComdat() != nullptr; } - const Comdat *getComdat() const; - Comdat *getComdat() { - return const_cast( - static_cast(this)->getComdat()); - } - - VisibilityTypes getVisibility() const { return VisibilityTypes(Visibility); } - bool hasDefaultVisibility() const { return Visibility == DefaultVisibility; } - bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; } - bool hasProtectedVisibility() const { - return Visibility == ProtectedVisibility; - } - void setVisibility(VisibilityTypes V) { - assert((!hasLocalLinkage() || V == DefaultVisibility) && - "local linkage requires default visibility"); - Visibility = V; - maybeSetDsoLocal(); - } - -+#if INTEL_COLLAB -+ bool isThreadPrivate() const { return ThreadPrivate; } -+ void setThreadPrivate(bool Val) { ThreadPrivate = Val; } -+ -+ bool isTargetDeclare() const { return TargetDeclare; } -+ void setTargetDeclare(bool Val) { TargetDeclare = Val; } -+#endif // INTEL_COLLAB - /// If the value is "Thread Local", its value isn't shared by the threads. - bool isThreadLocal() const { return getThreadLocalMode() != NotThreadLocal; } - void setThreadLocal(bool Val) { - setThreadLocalMode(Val ? GeneralDynamicTLSModel : NotThreadLocal); - } - void setThreadLocalMode(ThreadLocalMode Val) { - assert(Val == NotThreadLocal || getValueID() != Value::FunctionVal); - ThreadLocal = Val; - } - ThreadLocalMode getThreadLocalMode() const { - return static_cast(ThreadLocal); - } - - DLLStorageClassTypes getDLLStorageClass() const { - return DLLStorageClassTypes(DllStorageClass); - } - bool hasDLLImportStorageClass() const { - return DllStorageClass == DLLImportStorageClass; - } - bool hasDLLExportStorageClass() const { - return DllStorageClass == DLLExportStorageClass; - } - void setDLLStorageClass(DLLStorageClassTypes C) { DllStorageClass = C; } - - bool hasSection() const { return !getSection().empty(); } - StringRef getSection() const; - - /// Global values are always pointers. - PointerType *getType() const { return cast(User::getType()); } - - Type *getValueType() const { return ValueType; } - - void setDSOLocal(bool Local) { IsDSOLocal = Local; } - - bool isDSOLocal() const { - return IsDSOLocal; - } - - static LinkageTypes getLinkOnceLinkage(bool ODR) { - return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage; - } - static LinkageTypes getWeakLinkage(bool ODR) { - return ODR ? WeakODRLinkage : WeakAnyLinkage; - } - - static bool isExternalLinkage(LinkageTypes Linkage) { - return Linkage == ExternalLinkage; - } - static bool isAvailableExternallyLinkage(LinkageTypes Linkage) { - return Linkage == AvailableExternallyLinkage; - } - static bool isLinkOnceODRLinkage(LinkageTypes Linkage) { - return Linkage == LinkOnceODRLinkage; - } - static bool isLinkOnceLinkage(LinkageTypes Linkage) { - return Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage; - } - static bool isWeakAnyLinkage(LinkageTypes Linkage) { - return Linkage == WeakAnyLinkage; - } - static bool isWeakODRLinkage(LinkageTypes Linkage) { - return Linkage == WeakODRLinkage; - } - static bool isWeakLinkage(LinkageTypes Linkage) { - return isWeakAnyLinkage(Linkage) || isWeakODRLinkage(Linkage); - } - static bool isAppendingLinkage(LinkageTypes Linkage) { - return Linkage == AppendingLinkage; - } - static bool isInternalLinkage(LinkageTypes Linkage) { - return Linkage == InternalLinkage; - } - static bool isPrivateLinkage(LinkageTypes Linkage) { - return Linkage == PrivateLinkage; - } - static bool isLocalLinkage(LinkageTypes Linkage) { - return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage); - } - static bool isExternalWeakLinkage(LinkageTypes Linkage) { - return Linkage == ExternalWeakLinkage; - } - static bool isCommonLinkage(LinkageTypes Linkage) { - return Linkage == CommonLinkage; - } - static bool isValidDeclarationLinkage(LinkageTypes Linkage) { - return isExternalWeakLinkage(Linkage) || isExternalLinkage(Linkage); - } - - /// Whether the definition of this global may be replaced by something - /// non-equivalent at link time. For example, if a function has weak linkage - /// then the code defining it may be replaced by different code. - static bool isInterposableLinkage(LinkageTypes Linkage) { - switch (Linkage) { - case WeakAnyLinkage: - case LinkOnceAnyLinkage: - case CommonLinkage: - case ExternalWeakLinkage: - return true; - - case AvailableExternallyLinkage: - case LinkOnceODRLinkage: - case WeakODRLinkage: - // The above three cannot be overridden but can be de-refined. - - case ExternalLinkage: - case AppendingLinkage: - case InternalLinkage: - case PrivateLinkage: - return false; - } - llvm_unreachable("Fully covered switch above!"); - } - - /// Whether the definition of this global may be discarded if it is not used - /// in its compilation unit. - static bool isDiscardableIfUnused(LinkageTypes Linkage) { - return isLinkOnceLinkage(Linkage) || isLocalLinkage(Linkage) || - isAvailableExternallyLinkage(Linkage); - } - - /// Whether the definition of this global may be replaced at link time. NB: - /// Using this method outside of the code generators is almost always a - /// mistake: when working at the IR level use isInterposable instead as it - /// knows about ODR semantics. - static bool isWeakForLinker(LinkageTypes Linkage) { - return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage || - Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage || - Linkage == CommonLinkage || Linkage == ExternalWeakLinkage; - } - - /// Return true if the currently visible definition of this global (if any) is - /// exactly the definition we will see at runtime. - /// - /// Non-exact linkage types inhibits most non-inlining IPO, since a - /// differently optimized variant of the same function can have different - /// observable or undefined behavior than in the variant currently visible. - /// For instance, we could have started with - /// - /// void foo(int *v) { - /// int t = 5 / v[0]; - /// (void) t; - /// } - /// - /// and "refined" it to - /// - /// void foo(int *v) { } - /// - /// However, we cannot infer readnone for `foo`, since that would justify - /// DSE'ing a store to `v[0]` across a call to `foo`, which can cause - /// undefined behavior if the linker replaces the actual call destination with - /// the unoptimized `foo`. - /// - /// Inlining is okay across non-exact linkage types as long as they're not - /// interposable (see \c isInterposable), since in such cases the currently - /// visible variant is *a* correct implementation of the original source - /// function; it just isn't the *only* correct implementation. - bool isDefinitionExact() const { - return !mayBeDerefined(); - } - - /// Return true if this global has an exact defintion. - bool hasExactDefinition() const { - // While this computes exactly the same thing as - // isStrongDefinitionForLinker, the intended uses are different. This - // function is intended to help decide if specific inter-procedural - // transforms are correct, while isStrongDefinitionForLinker's intended use - // is in low level code generation. - return !isDeclaration() && isDefinitionExact(); - } - - /// Return true if this global's definition can be substituted with an - /// *arbitrary* definition at link time. We cannot do any IPO or inlinining - /// across interposable call edges, since the callee can be replaced with - /// something arbitrary at link time. - bool isInterposable() const { return isInterposableLinkage(getLinkage()); } - - bool hasExternalLinkage() const { return isExternalLinkage(getLinkage()); } - bool hasAvailableExternallyLinkage() const { - return isAvailableExternallyLinkage(getLinkage()); - } - bool hasLinkOnceLinkage() const { return isLinkOnceLinkage(getLinkage()); } - bool hasLinkOnceODRLinkage() const { - return isLinkOnceODRLinkage(getLinkage()); - } - bool hasWeakLinkage() const { return isWeakLinkage(getLinkage()); } - bool hasWeakAnyLinkage() const { return isWeakAnyLinkage(getLinkage()); } - bool hasWeakODRLinkage() const { return isWeakODRLinkage(getLinkage()); } - bool hasAppendingLinkage() const { return isAppendingLinkage(getLinkage()); } - bool hasInternalLinkage() const { return isInternalLinkage(getLinkage()); } - bool hasPrivateLinkage() const { return isPrivateLinkage(getLinkage()); } - bool hasLocalLinkage() const { return isLocalLinkage(getLinkage()); } - bool hasExternalWeakLinkage() const { - return isExternalWeakLinkage(getLinkage()); - } - bool hasCommonLinkage() const { return isCommonLinkage(getLinkage()); } - bool hasValidDeclarationLinkage() const { - return isValidDeclarationLinkage(getLinkage()); - } - - void setLinkage(LinkageTypes LT) { - if (isLocalLinkage(LT)) - Visibility = DefaultVisibility; - Linkage = LT; - maybeSetDsoLocal(); - } - LinkageTypes getLinkage() const { return LinkageTypes(Linkage); } - - bool isDiscardableIfUnused() const { - return isDiscardableIfUnused(getLinkage()); - } - - bool isWeakForLinker() const { return isWeakForLinker(getLinkage()); } - - protected: - /// Copy all additional attributes (those not needed to create a GlobalValue) - /// from the GlobalValue Src to this one. - void copyAttributesFrom(const GlobalValue *Src); - - public: - /// If the given string begins with the GlobalValue name mangling escape - /// character '\1', drop it. - /// - /// This function applies a specific mangling that is used in PGO profiles, - /// among other things. If you're trying to get a symbol name for an - /// arbitrary GlobalValue, this is not the function you're looking for; see - /// Mangler.h. - static StringRef dropLLVMManglingEscape(StringRef Name) { - if (!Name.empty() && Name[0] == '\1') - return Name.substr(1); - return Name; - } - - /// Return the modified name for a global value suitable to be - /// used as the key for a global lookup (e.g. profile or ThinLTO). - /// The value's original name is \c Name and has linkage of type - /// \c Linkage. The value is defined in module \c FileName. - static std::string getGlobalIdentifier(StringRef Name, - GlobalValue::LinkageTypes Linkage, - StringRef FileName); - - /// Return the modified name for this global value suitable to be - /// used as the key for a global lookup (e.g. profile or ThinLTO). - std::string getGlobalIdentifier() const; - - /// Declare a type to represent a global unique identifier for a global value. - /// This is a 64 bits hash that is used by PGO and ThinLTO to have a compact - /// unique way to identify a symbol. - using GUID = uint64_t; - - /// Return a 64-bit global unique ID constructed from global value name - /// (i.e. returned by getGlobalIdentifier()). - static GUID getGUID(StringRef GlobalName) { return MD5Hash(GlobalName); } - - /// Return a 64-bit global unique ID constructed from global value name - /// (i.e. returned by getGlobalIdentifier()). - GUID getGUID() const { return getGUID(getGlobalIdentifier()); } - - /// @name Materialization - /// Materialization is used to construct functions only as they're needed. - /// This - /// is useful to reduce memory usage in LLVM or parsing work done by the - /// BitcodeReader to load the Module. - /// @{ - - /// If this function's Module is being lazily streamed in functions from disk - /// or some other source, this method can be used to check to see if the - /// function has been read in yet or not. - bool isMaterializable() const; - - /// Make sure this GlobalValue is fully read. - Error materialize(); - - /// @} - - /// Return true if the primary definition of this global value is outside of - /// the current translation unit. - bool isDeclaration() const; - - bool isDeclarationForLinker() const { - if (hasAvailableExternallyLinkage()) - return true; - - return isDeclaration(); - } - - /// Returns true if this global's definition will be the one chosen by the - /// linker. - /// - /// NB! Ideally this should not be used at the IR level at all. If you're - /// interested in optimization constraints implied by the linker's ability to - /// choose an implementation, prefer using \c hasExactDefinition. - bool isStrongDefinitionForLinker() const { - return !(isDeclarationForLinker() || isWeakForLinker()); - } - - // Returns true if the alignment of the value can be unilaterally - // increased. - bool canIncreaseAlignment() const; - - const GlobalObject *getBaseObject() const; - GlobalObject *getBaseObject() { - return const_cast( - static_cast(this)->getBaseObject()); - } - - /// Returns whether this is a reference to an absolute symbol. - bool isAbsoluteSymbolRef() const; - - /// If this is an absolute symbol reference, returns the range of the symbol, - /// otherwise returns None. - Optional getAbsoluteSymbolRange() const; - - /// This method unlinks 'this' from the containing module, but does not delete - /// it. - void removeFromParent(); - - /// This method unlinks 'this' from the containing module and deletes it. - void eraseFromParent(); - - /// Get the module that this global value is contained inside of... - Module *getParent() { return Parent; } - const Module *getParent() const { return Parent; } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static bool classof(const Value *V) { - return V->getValueID() == Value::FunctionVal || - V->getValueID() == Value::GlobalVariableVal || - V->getValueID() == Value::GlobalAliasVal || - V->getValueID() == Value::GlobalIFuncVal; - } - - /// True if GV can be left out of the object symbol table. This is the case - /// for linkonce_odr values whose address is not significant. While legal, it - /// is not normally profitable to omit them from the .o symbol table. Using - /// this analysis makes sense when the information can be passed down to the - /// linker or we are in LTO. - bool canBeOmittedFromSymbolTable() const; - }; - - } // end namespace llvm - - #endif // LLVM_IR_GLOBALVALUE_H -diff --git a/llvm/include/llvm/IR/Intel_Directives.td b/llvm/include/llvm/IR/Intel_Directives.td -new file mode 100644 -index 0000000..960704f ---- /dev/null -+++ b/llvm/include/llvm/IR/Intel_Directives.td -@@ -0,0 +1,254 @@ -+// INTEL_COLLAB -*- tablegen -*- -+//==- Intel_Directives.td - Defines all parallelization and -*- tablegen -*-==// -+// vectorization directives and clauses. -+// -+// Copyright (C) 2016 Intel Corporation. All rights reserved. -+// -+// The information and source code contained herein is the exclusive property -+// of Intel Corporation and may not be disclosed, examined or reproduced in -+// whole or in part without explicit written authorization from the company. -+// -+// ===--------------------------------------------------------------------=== // -+/// -+/// \file -+/// This file defines the classes used to represent parallelization and -+/// vectorization directives and clauses. Each different type of directive and -+/// clause is then instantiated accordingly. TableGen parses these records and -+/// generates enums for both classes, as well as tables which provide an -+/// enum->string and string->enum mapping. The enums and tables are used to -+/// generate Metadata strings that are used as arguments to llvm.directive -+/// intrinsics. These intrinsics are used to mark parallel/vector constructs -+/// and behavior. -+/// -+// ===--------------------------------------------------------------------=== // -+ -+// The Directive class represents all parallel/vector constructs that can be -+// represented within LLVM IR. For example, the "#pragma omp parallel" -+// directive for OpenMP. -+class Directive; -+ -+// The Clause class represents additional information provided to Directives -+// that can be used to control parallel/vector execution. For example, -+// "#pragma omp parallel" could be modified to include the "if (expr)" clause -+// to determine if the region should be executed in parallel or not. -+class Clause; -+ -+// For additional information on the supported Directives and Clauses, please -+// refer to the following documentation. Currently, this file defines only -+// the directives and clauses associated with OpenMP, but will be extended in -+// the future for other parallel/vector programming models and APIs. -+// -+// http://openmp.org/wp/openmp-specifications -+ -+// *** Begin OpenMP Directives *** -+ -+def "DIR.OMP.PARALLEL" : Directive; -+def "DIR.OMP.END.PARALLEL" : Directive; -+ -+def "DIR.OMP.LOOP" : Directive; -+def "DIR.OMP.END.LOOP" : Directive; -+ -+def "DIR.OMP.PARALLEL.LOOP" : Directive; -+def "DIR.OMP.END.PARALLEL.LOOP" : Directive; -+ -+def "DIR.OMP.SECTIONS" : Directive; -+def "DIR.OMP.END.SECTIONS" : Directive; -+ -+def "DIR.OMP.PARALLEL.SECTIONS" : Directive; -+def "DIR.OMP.END.PARALLEL.SECTIONS" : Directive; -+ -+def "DIR.OMP.WORKSHARE" : Directive; -+def "DIR.OMP.END.WORKSHARE" : Directive; -+ -+def "DIR.OMP.PARALLEL.WORKSHARE" : Directive; -+def "DIR.OMP.END.PARALLEL.WORKSHARE" : Directive; -+ -+def "DIR.OMP.SECTION" : Directive; -+def "DIR.OMP.END.SECTION" : Directive; -+ -+def "DIR.OMP.SINGLE" : Directive; -+def "DIR.OMP.END.SINGLE" : Directive; -+ -+def "DIR.OMP.TASK" : Directive; -+def "DIR.OMP.END.TASK" : Directive; -+ -+def "DIR.OMP.MASTER" : Directive; -+def "DIR.OMP.END.MASTER" : Directive; -+ -+def "DIR.OMP.CRITICAL" : Directive; -+def "DIR.OMP.END.CRITICAL" : Directive; -+ -+def "DIR.OMP.BARRIER" : Directive; -+def "DIR.OMP.END.BARRIER" : Directive; -+ -+def "DIR.OMP.TASKWAIT" : Directive; -+def "DIR.OMP.END.TASKWAIT" : Directive; -+ -+def "DIR.OMP.TASKYIELD" : Directive; -+def "DIR.OMP.END.TASKYIELD" : Directive; -+ -+def "DIR.OMP.ATOMIC" : Directive; -+def "DIR.OMP.END.ATOMIC" : Directive; -+ -+def "DIR.OMP.FLUSH" : Directive; -+def "DIR.OMP.END.FLUSH" : Directive; -+ -+def "DIR.OMP.THREADPRIVATE" : Directive; -+ -+def "DIR.OMP.ORDERED" : Directive; -+def "DIR.OMP.END.ORDERED" : Directive; -+ -+def "DIR.OMP.SIMD" : Directive; -+def "DIR.OMP.END.SIMD" : Directive; -+ -+def "DIR.OMP.TASKGROUP" : Directive; -+def "DIR.OMP.END.TASKGROUP" : Directive; -+ -+def "DIR.OMP.TASKLOOP" : Directive; -+def "DIR.OMP.END.TASKLOOP" : Directive; -+ -+def "DIR.OMP.TARGET" : Directive; -+def "DIR.OMP.END.TARGET" : Directive; -+ -+def "DIR.OMP.TARGET.DATA" : Directive; -+def "DIR.OMP.END.TARGET.DATA" : Directive; -+ -+def "DIR.OMP.TARGET.UPDATE" : Directive; -+def "DIR.OMP.END.TARGET.UPDATE" : Directive; -+ -+def "DIR.OMP.TEAMS" : Directive; -+def "DIR.OMP.END.TEAMS" : Directive; -+ -+def "DIR.OMP.DISTRIBUTE" : Directive; -+def "DIR.OMP.END.DISTRIBUTE" : Directive; -+ -+def "DIR.OMP.DISTRIBUTE.PARLOOP" : Directive; -+def "DIR.OMP.END.DISTRIBUTE.PARLOOP" : Directive; -+ -+def "DIR.OMP.TARGET.ENTER.DATA" : Directive; -+def "DIR.OMP.END.TARGET.ENTER.DATA" : Directive; -+ -+def "DIR.OMP.TARGET.EXIT.DATA" : Directive; -+def "DIR.OMP.END.TARGET.EXIT.DATA" : Directive; -+ -+def "DIR.OMP.CANCEL" : Directive; -+def "DIR.OMP.END.CANCEL" : Directive; -+ -+def "DIR.OMP.CANCELLATION.POINT" : Directive; -+def "DIR.OMP.END.CANCELLATION.POINT" : Directive; -+ -+ -+// *** Begin OpenMP Clauses *** -+ -+def "QUAL.OMP.DEFAULT.NONE" : Clause; -+def "QUAL.OMP.DEFAULT.SHARED" : Clause; -+def "QUAL.OMP.DEFAULT.PRIVATE" : Clause; -+def "QUAL.OMP.DEFAULT.FIRSTPRIVATE" : Clause; -+def "QUAL.OMP.MERGEABLE" : Clause; -+def "QUAL.OMP.NOWAIT" : Clause; -+def "QUAL.OMP.NOGROUP" : Clause; -+def "QUAL.OMP.UNTIED" : Clause; -+def "QUAL.OMP.READ" : Clause; -+def "QUAL.OMP.READ.SEQ_CST" : Clause; -+def "QUAL.OMP.WRITE" : Clause; -+def "QUAL.OMP.WRITE.SEQ_CST" : Clause; -+def "QUAL.OMP.UPDATE" : Clause; -+def "QUAL.OMP.UPDATE.SEQ_CST" : Clause; -+def "QUAL.OMP.CAPTURE" : Clause; -+def "QUAL.OMP.CAPTURE.SEQ_CST" : Clause; -+def "QUAL.OMP.PROC.BIND.MASTER" : Clause; -+def "QUAL.OMP.PROC.BIND.CLOSE" : Clause; -+def "QUAL.OMP.PROC.BIND.SPREAD" : Clause; -+def "QUAL.OMP.IF" : Clause; -+def "QUAL.OMP.COLLAPSE" : Clause; -+def "QUAL.OMP.NUM_THREADS" : Clause; -+def "QUAL.OMP.ORDERED" : Clause; -+def "QUAL.OMP.SAFELEN" : Clause; -+def "QUAL.OMP.SIMDLEN" : Clause; -+def "QUAL.OMP.FINAL" : Clause; -+def "QUAL.OMP.GRAINSIZE" : Clause; -+def "QUAL.OMP.NUM_TASKS" : Clause; -+def "QUAL.OMP.PRIORITY" : Clause; -+def "QUAL.OMP.NUM_TEAMS" : Clause; -+def "QUAL.OMP.THREAD_LIMIT" : Clause; -+def "QUAL.OMP.DIST_SCHEDULE.STATIC" : Clause; -+def "QUAL.OMP.SCHEDULE.STATIC" : Clause; -+def "QUAL.OMP.SCHEDULE.DYNAMIC" : Clause; -+def "QUAL.OMP.SCHEDULE.GUIDED" : Clause; -+def "QUAL.OMP.SCHEDULE.AUTO" : Clause; -+def "QUAL.OMP.SCHEDULE.RUNTIME" : Clause; -+def "QUAL.OMP.SHARED" : Clause; -+def "QUAL.OMP.PRIVATE" : Clause; -+def "QUAL.OMP.FIRSTPRIVATE" : Clause; -+def "QUAL.OMP.LASTPRIVATE" : Clause; -+def "QUAL.OMP.COPYIN" : Clause; -+def "QUAL.OMP.COPYPRIVATE" : Clause; -+def "QUAL.OMP.REDUCTION.ADD" : Clause; -+def "QUAL.OMP.REDUCTION.SUB" : Clause; -+def "QUAL.OMP.REDUCTION.MUL" : Clause; -+def "QUAL.OMP.REDUCTION.AND" : Clause; -+def "QUAL.OMP.REDUCTION.OR" : Clause; -+def "QUAL.OMP.REDUCTION.BXOR" : Clause; -+def "QUAL.OMP.REDUCTION.BAND" : Clause; -+def "QUAL.OMP.REDUCTION.BOR" : Clause; -+def "QUAL.OMP.REDUCTION.MAX" : Clause; -+def "QUAL.OMP.REDUCTION.MIN" : Clause; -+def "QUAL.OMP.REDUCTION.UDR" : Clause; -+def "QUAL.OMP.INREDUCTION.ADD" : Clause; -+def "QUAL.OMP.INREDUCTION.SUB" : Clause; -+def "QUAL.OMP.INREDUCTION.MUL" : Clause; -+def "QUAL.OMP.INREDUCTION.AND" : Clause; -+def "QUAL.OMP.INREDUCTION.OR" : Clause; -+def "QUAL.OMP.INREDUCTION.BXOR" : Clause; -+def "QUAL.OMP.INREDUCTION.BAND" : Clause; -+def "QUAL.OMP.INREDUCTION.BOR" : Clause; -+def "QUAL.OMP.INREDUCTION.MAX" : Clause; -+def "QUAL.OMP.INREDUCTION.MIN" : Clause; -+def "QUAL.OMP.INREDUCTION.UDR" : Clause; -+def "QUAL.OMP.TO" : Clause; -+def "QUAL.OMP.FROM" : Clause; -+def "QUAL.OMP.LINEAR" : Clause; -+def "QUAL.OMP.UNIFORM" : Clause; -+def "QUAL.OMP.ALIGNED" : Clause; -+def "QUAL.OMP.FLUSH" : Clause; -+def "QUAL.OMP.THREADPRIVATE" : Clause; -+def "QUAL.OMP.DEVICE" : Clause; -+def "QUAL.OMP.IS_DEVICE_PTR" : Clause; -+def "QUAL.OMP.USE_DEVICE_PTR" : Clause; -+def "QUAL.OMP.DEFAULTMAP.TOFROM.SCALAR" : Clause; -+def "QUAL.OMP.MAP.TO" : Clause; -+def "QUAL.OMP.MAP.FROM" : Clause; -+def "QUAL.OMP.MAP.TOFROM" : Clause; -+def "QUAL.OMP.MAP.ALLOC" : Clause; -+def "QUAL.OMP.MAP.RELEASE" : Clause; -+def "QUAL.OMP.MAP.DELETE" : Clause; -+def "QUAL.OMP.MAP.ALWAYS.TO" : Clause; -+def "QUAL.OMP.MAP.ALWAYS.FROM" : Clause; -+def "QUAL.OMP.MAP.ALWAYS.TOFROM" : Clause; -+def "QUAL.OMP.MAP.ALWAYS.ALLOC" : Clause; -+def "QUAL.OMP.MAP.ALWAYS.RELEASE" : Clause; -+def "QUAL.OMP.MAP.ALWAYS.DELETE" : Clause; -+def "QUAL.OMP.DEPEND.IN" : Clause; -+def "QUAL.OMP.DEPEND.OUT" : Clause; -+def "QUAL.OMP.DEPEND.INOUT" : Clause; -+def "QUAL.OMP.DEPEND.SOURCE" : Clause; -+def "QUAL.OMP.DEPEND.SINK" : Clause; -+def "QUAL.OMP.ORDERED.THREADS" : Clause; -+def "QUAL.OMP.ORDERED.SIMD" : Clause; -+def "QUAL.OMP.CANCEL.PARALLEL" : Clause; -+def "QUAL.OMP.CANCEL.LOOP" : Clause; -+def "QUAL.OMP.CANCEL.SECTIONS" : Clause; -+def "QUAL.OMP.CANCEL.TASKGROUP" : Clause; -+def "QUAL.OMP.HINT" : Clause; -+def "QUAL.OMP.NAME" : Clause; -+ -+// *** Begin Auxiliary Clauses *** -+// These "clauses" don't correspond to actual OpenMP clauses, but are used -+// to carry additional information -+ -+def "QUAL.OMP.NORMALIZED.IV" : Clause; -+def "QUAL.OMP.NORMALIZED.UB" : Clause; -+def "QUAL.OMP.CANCELLATION.POINTS" : Clause; -+def "QUAL.OMP.OFFLOAD.ENTRY.IDX" : Clause; -+ -+// end INTEL_COLLAB -diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td -index b26a26f..33ac71f 100644 ---- a/llvm/include/llvm/IR/Intrinsics.td -+++ b/llvm/include/llvm/IR/Intrinsics.td -@@ -1,1187 +1,1217 @@ - //===- Intrinsics.td - Defines all LLVM intrinsics ---------*- tablegen -*-===// - // - // 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 defines properties of all LLVM intrinsics. - // - //===----------------------------------------------------------------------===// - - include "llvm/CodeGen/ValueTypes.td" - include "llvm/CodeGen/SDNodeProperties.td" - - //===----------------------------------------------------------------------===// - // Properties we keep track of for intrinsics. - //===----------------------------------------------------------------------===// - - class IntrinsicProperty; - - // Intr*Mem - Memory properties. If no property is set, the worst case - // is assumed (it may read and write any memory it can get access to and it may - // have other side effects). - - // IntrNoMem - The intrinsic does not access memory or have any other side - // effects. It may be CSE'd deleted if dead, etc. - def IntrNoMem : IntrinsicProperty; - - // IntrReadMem - This intrinsic only reads from memory. It does not write to - // memory and has no other side effects. Therefore, it cannot be moved across - // potentially aliasing stores. However, it can be reordered otherwise and can - // be deleted if dead. - def IntrReadMem : IntrinsicProperty; - - // IntrWriteMem - This intrinsic only writes to memory, but does not read from - // memory, and has no other side effects. This means dead stores before calls - // to this intrinsics may be removed. - def IntrWriteMem : IntrinsicProperty; - - // IntrArgMemOnly - This intrinsic only accesses memory that its pointer-typed - // argument(s) points to, but may access an unspecified amount. Other than - // reads from and (possibly volatile) writes to memory, it has no side effects. - def IntrArgMemOnly : IntrinsicProperty; - - // IntrInaccessibleMemOnly -- This intrinsic only accesses memory that is not - // accessible by the module being compiled. This is a weaker form of IntrNoMem. - def IntrInaccessibleMemOnly : IntrinsicProperty; - - // IntrInaccessibleMemOrArgMemOnly -- This intrinsic only accesses memory that - // its pointer-typed arguments point to or memory that is not accessible - // by the module being compiled. This is a weaker form of IntrArgMemOnly. - def IntrInaccessibleMemOrArgMemOnly : IntrinsicProperty; - - // Commutative - This intrinsic is commutative: X op Y == Y op X. - def Commutative : IntrinsicProperty; - - // Throws - This intrinsic can throw. - def Throws : IntrinsicProperty; - - // NoCapture - The specified argument pointer is not captured by the intrinsic. - class NoCapture : IntrinsicProperty { - int ArgNo = argNo; - } - - // Returned - The specified argument is always the return value of the - // intrinsic. - class Returned : IntrinsicProperty { - int ArgNo = argNo; - } - - // ImmArg - The specified argument must be an immediate. - class ImmArg : IntrinsicProperty { - int ArgNo = argNo; - } - - // ReadOnly - The specified argument pointer is not written to through the - // pointer by the intrinsic. - class ReadOnly : IntrinsicProperty { - int ArgNo = argNo; - } - - // WriteOnly - The intrinsic does not read memory through the specified - // argument pointer. - class WriteOnly : IntrinsicProperty { - int ArgNo = argNo; - } - - // ReadNone - The specified argument pointer is not dereferenced by the - // intrinsic. - class ReadNone : IntrinsicProperty { - int ArgNo = argNo; - } - - def IntrNoReturn : IntrinsicProperty; - - // IntrCold - Calls to this intrinsic are cold. - // Parallels the cold attribute on LLVM IR functions. - def IntrCold : IntrinsicProperty; - - // IntrNoduplicate - Calls to this intrinsic cannot be duplicated. - // Parallels the noduplicate attribute on LLVM IR functions. - def IntrNoDuplicate : IntrinsicProperty; - - // IntrConvergent - Calls to this intrinsic are convergent and may not be made - // control-dependent on any additional values. - // Parallels the convergent attribute on LLVM IR functions. - def IntrConvergent : IntrinsicProperty; - - // This property indicates that the intrinsic is safe to speculate. - def IntrSpeculatable : IntrinsicProperty; - - // This property can be used to override the 'has no other side effects' - // language of the IntrNoMem, IntrReadMem, IntrWriteMem, and IntrArgMemOnly - // intrinsic properties. By default, intrinsics are assumed to have side - // effects, so this property is only necessary if you have defined one of - // the memory properties listed above. - // For this property, 'side effects' has the same meaning as 'side effects' - // defined by the hasSideEffects property of the TableGen Instruction class. - def IntrHasSideEffects : IntrinsicProperty; - - //===----------------------------------------------------------------------===// - // Types used by intrinsics. - //===----------------------------------------------------------------------===// - - class LLVMType { - ValueType VT = vt; - int isAny = 0; - } - - class LLVMQualPointerType - : LLVMType{ - LLVMType ElTy = elty; - int AddrSpace = addrspace; - } - - class LLVMPointerType - : LLVMQualPointerType; - - class LLVMAnyPointerType - : LLVMType{ - LLVMType ElTy = elty; - - let isAny = 1; - } - - // Match the type of another intrinsic parameter. Number is an index into the - // list of overloaded types for the intrinsic, excluding all the fixed types. - // The Number value must refer to a previously listed type. For example: - // Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_anyfloat_ty, LLVMMatchType<0>]> - // has two overloaded types, the 2nd and 3rd arguments. LLVMMatchType<0> - // refers to the first overloaded type, which is the 2nd argument. - class LLVMMatchType - : LLVMType{ - int Number = num; - } - - // Match the type of another intrinsic parameter that is expected to be based on - // an integral type (i.e. either iN or ), but change the scalar size to - // be twice as wide or half as wide as the other type. This is only useful when - // the intrinsic is overloaded, so the matched type should be declared as iAny. - class LLVMExtendedType : LLVMMatchType; - class LLVMTruncatedType : LLVMMatchType; - - // Match the scalar/vector of another intrinsic parameter but with a different - // element type. Either both are scalars or both are vectors with the same - // number of elements. - class LLVMScalarOrSameVectorWidth - : LLVMMatchType { - ValueType ElTy = elty.VT; - } - - class LLVMPointerTo : LLVMMatchType; - class LLVMPointerToElt : LLVMMatchType; - class LLVMVectorOfAnyPointersToElt : LLVMMatchType; - - // Match the type of another intrinsic parameter that is expected to be a - // vector type, but change the element count to be half as many - class LLVMHalfElementsVectorType : LLVMMatchType; - - def llvm_void_ty : LLVMType; - let isAny = 1 in { - def llvm_any_ty : LLVMType; - def llvm_anyint_ty : LLVMType; - def llvm_anyfloat_ty : LLVMType; - def llvm_anyvector_ty : LLVMType; - } - def llvm_i1_ty : LLVMType; - def llvm_i8_ty : LLVMType; - def llvm_i16_ty : LLVMType; - def llvm_i32_ty : LLVMType; - def llvm_i64_ty : LLVMType; - def llvm_half_ty : LLVMType; - def llvm_float_ty : LLVMType; - def llvm_double_ty : LLVMType; - def llvm_f80_ty : LLVMType; - def llvm_f128_ty : LLVMType; - def llvm_ppcf128_ty : LLVMType; - def llvm_ptr_ty : LLVMPointerType; // i8* - def llvm_ptrptr_ty : LLVMPointerType; // i8** - def llvm_anyptr_ty : LLVMAnyPointerType; // (space)i8* - def llvm_empty_ty : LLVMType; // { } - def llvm_descriptor_ty : LLVMPointerType; // { }* - def llvm_metadata_ty : LLVMType; // !{...} - def llvm_token_ty : LLVMType; // token - - def llvm_x86mmx_ty : LLVMType; - def llvm_ptrx86mmx_ty : LLVMPointerType; // <1 x i64>* - - def llvm_v2i1_ty : LLVMType; // 2 x i1 - def llvm_v4i1_ty : LLVMType; // 4 x i1 - def llvm_v8i1_ty : LLVMType; // 8 x i1 - def llvm_v16i1_ty : LLVMType; // 16 x i1 - def llvm_v32i1_ty : LLVMType; // 32 x i1 - def llvm_v64i1_ty : LLVMType; // 64 x i1 - def llvm_v512i1_ty : LLVMType; // 512 x i1 - def llvm_v1024i1_ty : LLVMType; //1024 x i1 - - def llvm_v1i8_ty : LLVMType; // 1 x i8 - def llvm_v2i8_ty : LLVMType; // 2 x i8 - def llvm_v4i8_ty : LLVMType; // 4 x i8 - def llvm_v8i8_ty : LLVMType; // 8 x i8 - def llvm_v16i8_ty : LLVMType; // 16 x i8 - def llvm_v32i8_ty : LLVMType; // 32 x i8 - def llvm_v64i8_ty : LLVMType; // 64 x i8 - def llvm_v128i8_ty : LLVMType; //128 x i8 - def llvm_v256i8_ty : LLVMType; //256 x i8 - - def llvm_v1i16_ty : LLVMType; // 1 x i16 - def llvm_v2i16_ty : LLVMType; // 2 x i16 - def llvm_v4i16_ty : LLVMType; // 4 x i16 - def llvm_v8i16_ty : LLVMType; // 8 x i16 - def llvm_v16i16_ty : LLVMType; // 16 x i16 - def llvm_v32i16_ty : LLVMType; // 32 x i16 - def llvm_v64i16_ty : LLVMType; // 64 x i16 - def llvm_v128i16_ty : LLVMType; //128 x i16 - - def llvm_v1i32_ty : LLVMType; // 1 x i32 - def llvm_v2i32_ty : LLVMType; // 2 x i32 - def llvm_v4i32_ty : LLVMType; // 4 x i32 - def llvm_v8i32_ty : LLVMType; // 8 x i32 - def llvm_v16i32_ty : LLVMType; // 16 x i32 - def llvm_v32i32_ty : LLVMType; // 32 x i32 - def llvm_v64i32_ty : LLVMType; // 64 x i32 - - def llvm_v1i64_ty : LLVMType; // 1 x i64 - def llvm_v2i64_ty : LLVMType; // 2 x i64 - def llvm_v4i64_ty : LLVMType; // 4 x i64 - def llvm_v8i64_ty : LLVMType; // 8 x i64 - def llvm_v16i64_ty : LLVMType; // 16 x i64 - def llvm_v32i64_ty : LLVMType; // 32 x i64 - - def llvm_v1i128_ty : LLVMType; // 1 x i128 - - def llvm_v2f16_ty : LLVMType; // 2 x half (__fp16) - def llvm_v4f16_ty : LLVMType; // 4 x half (__fp16) - def llvm_v8f16_ty : LLVMType; // 8 x half (__fp16) - def llvm_v1f32_ty : LLVMType; // 1 x float - def llvm_v2f32_ty : LLVMType; // 2 x float - def llvm_v4f32_ty : LLVMType; // 4 x float - def llvm_v8f32_ty : LLVMType; // 8 x float - def llvm_v16f32_ty : LLVMType; // 16 x float - def llvm_v1f64_ty : LLVMType; // 1 x double - def llvm_v2f64_ty : LLVMType; // 2 x double - def llvm_v4f64_ty : LLVMType; // 4 x double - def llvm_v8f64_ty : LLVMType; // 8 x double - - def llvm_vararg_ty : LLVMType; // this means vararg here - - //===----------------------------------------------------------------------===// - // Intrinsic Definitions. - //===----------------------------------------------------------------------===// - - // Intrinsic class - This is used to define one LLVM intrinsic. The name of the - // intrinsic definition should start with "int_", then match the LLVM intrinsic - // name with the "llvm." prefix removed, and all "."s turned into "_"s. For - // example, llvm.bswap.i16 -> int_bswap_i16. - // - // * RetTypes is a list containing the return types expected for the - // intrinsic. - // * ParamTypes is a list containing the parameter types expected for the - // intrinsic. - // * Properties can be set to describe the behavior of the intrinsic. - // - class Intrinsic ret_types, - list param_types = [], - list intr_properties = [], - string name = "", - list sd_properties = []> : SDPatternOperator { - string LLVMName = name; - string TargetPrefix = ""; // Set to a prefix for target-specific intrinsics. - list RetTypes = ret_types; - list ParamTypes = param_types; - list IntrProperties = intr_properties; - let Properties = sd_properties; - - bit isTarget = 0; - } - - /// GCCBuiltin - If this intrinsic exactly corresponds to a GCC builtin, this - /// specifies the name of the builtin. This provides automatic CBE and CFE - /// support. - class GCCBuiltin { - string GCCBuiltinName = name; - } - - class MSBuiltin { - string MSBuiltinName = name; - } - - - //===--------------- Variable Argument Handling Intrinsics ----------------===// - // - - def int_vastart : Intrinsic<[], [llvm_ptr_ty], [], "llvm.va_start">; - def int_vacopy : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], [], - "llvm.va_copy">; - def int_vaend : Intrinsic<[], [llvm_ptr_ty], [], "llvm.va_end">; - - //===------------------- Garbage Collection Intrinsics --------------------===// - // - def int_gcroot : Intrinsic<[], - [llvm_ptrptr_ty, llvm_ptr_ty]>; - def int_gcread : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty, llvm_ptrptr_ty], - [IntrReadMem, IntrArgMemOnly]>; - def int_gcwrite : Intrinsic<[], - [llvm_ptr_ty, llvm_ptr_ty, llvm_ptrptr_ty], - [IntrArgMemOnly, NoCapture<1>, NoCapture<2>]>; - - //===------------------- ObjC ARC runtime Intrinsics --------------------===// - // - // Note these are to support the Objective-C ARC optimizer which wants to - // eliminate retain and releases where possible. - - def int_objc_autorelease : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty]>; - def int_objc_autoreleasePoolPop : Intrinsic<[], [llvm_ptr_ty]>; - def int_objc_autoreleasePoolPush : Intrinsic<[llvm_ptr_ty], []>; - def int_objc_autoreleaseReturnValue : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty]>; - def int_objc_copyWeak : Intrinsic<[], - [llvm_ptrptr_ty, - llvm_ptrptr_ty]>; - def int_objc_destroyWeak : Intrinsic<[], [llvm_ptrptr_ty]>; - def int_objc_initWeak : Intrinsic<[llvm_ptr_ty], - [llvm_ptrptr_ty, - llvm_ptr_ty]>; - def int_objc_loadWeak : Intrinsic<[llvm_ptr_ty], - [llvm_ptrptr_ty]>; - def int_objc_loadWeakRetained : Intrinsic<[llvm_ptr_ty], - [llvm_ptrptr_ty]>; - def int_objc_moveWeak : Intrinsic<[], - [llvm_ptrptr_ty, - llvm_ptrptr_ty]>; - def int_objc_release : Intrinsic<[], [llvm_ptr_ty]>; - def int_objc_retain : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty]>; - def int_objc_retainAutorelease : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty]>; - def int_objc_retainAutoreleaseReturnValue : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty]>; - def int_objc_retainAutoreleasedReturnValue : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty]>; - def int_objc_retainBlock : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty]>; - def int_objc_storeStrong : Intrinsic<[], - [llvm_ptrptr_ty, - llvm_ptr_ty]>; - def int_objc_storeWeak : Intrinsic<[llvm_ptr_ty], - [llvm_ptrptr_ty, - llvm_ptr_ty]>; - def int_objc_clang_arc_use : Intrinsic<[], - [llvm_vararg_ty]>; - def int_objc_unsafeClaimAutoreleasedReturnValue : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty]>; - def int_objc_retainedObject : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty]>; - def int_objc_unretainedObject : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty]>; - def int_objc_unretainedPointer : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty]>; - def int_objc_retain_autorelease : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty]>; - def int_objc_sync_enter : Intrinsic<[llvm_i32_ty], - [llvm_ptr_ty]>; - def int_objc_sync_exit : Intrinsic<[llvm_i32_ty], - [llvm_ptr_ty]>; - def int_objc_arc_annotation_topdown_bbstart : Intrinsic<[], - [llvm_ptrptr_ty, - llvm_ptrptr_ty]>; - def int_objc_arc_annotation_topdown_bbend : Intrinsic<[], - [llvm_ptrptr_ty, - llvm_ptrptr_ty]>; - def int_objc_arc_annotation_bottomup_bbstart : Intrinsic<[], - [llvm_ptrptr_ty, - llvm_ptrptr_ty]>; - def int_objc_arc_annotation_bottomup_bbend : Intrinsic<[], - [llvm_ptrptr_ty, - llvm_ptrptr_ty]>; - - - //===--------------------- Code Generator Intrinsics ----------------------===// - // - def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>; - def int_addressofreturnaddress : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; - def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>; - def int_sponentry : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; - def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty], - [IntrReadMem], "llvm.read_register">; - def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty], - [], "llvm.write_register">; - - // Gets the address of the local variable area. This is typically a copy of the - // stack, frame, or base pointer depending on the type of prologue. - def int_localaddress : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; - - // Escapes local variables to allow access from other functions. - def int_localescape : Intrinsic<[], [llvm_vararg_ty]>; - - // Given a function and the localaddress of a parent frame, returns a pointer - // to an escaped allocation indicated by the index. - def int_localrecover : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrNoMem, ImmArg<2>]>; - - // Given the frame pointer passed into an SEH filter function, returns a - // pointer to the local variable area suitable for use with llvm.localrecover. - def int_eh_recoverfp : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty, llvm_ptr_ty], - [IntrNoMem]>; - - // Note: we treat stacksave/stackrestore as writemem because we don't otherwise - // model their dependencies on allocas. - def int_stacksave : Intrinsic<[llvm_ptr_ty]>, - GCCBuiltin<"__builtin_stack_save">; - def int_stackrestore : Intrinsic<[], [llvm_ptr_ty]>, - GCCBuiltin<"__builtin_stack_restore">; - - def int_get_dynamic_area_offset : Intrinsic<[llvm_anyint_ty]>; - - def int_thread_pointer : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>, - GCCBuiltin<"__builtin_thread_pointer">; - - // IntrInaccessibleMemOrArgMemOnly is a little more pessimistic than strictly - // necessary for prefetch, however it does conveniently prevent the prefetch - // from being reordered overly much with respect to nearby access to the same - // memory while not impeding optimization. - def int_prefetch - : Intrinsic<[], [ llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty ], - [ IntrInaccessibleMemOrArgMemOnly, ReadOnly<0>, NoCapture<0>, - ImmArg<1>, ImmArg<2>]>; - def int_pcmarker : Intrinsic<[], [llvm_i32_ty]>; - - def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>; - - // The assume intrinsic is marked as arbitrarily writing so that proper - // control dependencies will be maintained. - def int_assume : Intrinsic<[], [llvm_i1_ty], []>; - - // Stack Protector Intrinsic - The stackprotector intrinsic writes the stack - // guard to the correct place on the stack frame. - def int_stackprotector : Intrinsic<[], [llvm_ptr_ty, llvm_ptrptr_ty], []>; - def int_stackguard : Intrinsic<[llvm_ptr_ty], [], []>; - - // A counter increment for instrumentation based profiling. - def int_instrprof_increment : Intrinsic<[], - [llvm_ptr_ty, llvm_i64_ty, - llvm_i32_ty, llvm_i32_ty], - []>; - - // A counter increment with step for instrumentation based profiling. - def int_instrprof_increment_step : Intrinsic<[], - [llvm_ptr_ty, llvm_i64_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i64_ty], - []>; - - // A call to profile runtime for value profiling of target expressions - // through instrumentation based profiling. - def int_instrprof_value_profile : Intrinsic<[], - [llvm_ptr_ty, llvm_i64_ty, - llvm_i64_ty, llvm_i32_ty, - llvm_i32_ty], - []>; - - //===------------------- Standard C Library Intrinsics --------------------===// - // - - def int_memcpy : Intrinsic<[], - [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, - llvm_i1_ty], - [IntrArgMemOnly, NoCapture<0>, NoCapture<1>, - WriteOnly<0>, ReadOnly<1>, ImmArg<3>]>; - def int_memmove : Intrinsic<[], - [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, - llvm_i1_ty], - [IntrArgMemOnly, NoCapture<0>, NoCapture<1>, - ReadOnly<1>, ImmArg<3>]>; - def int_memset : Intrinsic<[], - [llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty, - llvm_i1_ty], - [IntrArgMemOnly, NoCapture<0>, WriteOnly<0>, - ImmArg<3>]>; - - // FIXME: Add version of these floating point intrinsics which allow non-default - // rounding modes and FP exception handling. - - let IntrProperties = [IntrNoMem, IntrSpeculatable] in { - def int_fma : Intrinsic<[llvm_anyfloat_ty], - [LLVMMatchType<0>, LLVMMatchType<0>, - LLVMMatchType<0>]>; - def int_fmuladd : Intrinsic<[llvm_anyfloat_ty], - [LLVMMatchType<0>, LLVMMatchType<0>, - LLVMMatchType<0>]>; - - // These functions do not read memory, but are sensitive to the - // rounding mode. LLVM purposely does not model changes to the FP - // environment so they can be treated as readnone. - def int_sqrt : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_powi : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty]>; - def int_sin : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_cos : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_pow : Intrinsic<[llvm_anyfloat_ty], - [LLVMMatchType<0>, LLVMMatchType<0>]>; - def int_log : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_log10: Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_log2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_exp : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_exp2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_fabs : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_copysign : Intrinsic<[llvm_anyfloat_ty], - [LLVMMatchType<0>, LLVMMatchType<0>]>; - def int_floor : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_ceil : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_trunc : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_rint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_nearbyint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_round : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; - def int_canonicalize : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], - [IntrNoMem]>; - } - - def int_minnum : Intrinsic<[llvm_anyfloat_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable, Commutative] - >; - def int_maxnum : Intrinsic<[llvm_anyfloat_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable, Commutative] - >; - def int_minimum : Intrinsic<[llvm_anyfloat_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable, Commutative] - >; - def int_maximum : Intrinsic<[llvm_anyfloat_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable, Commutative] - >; - - // NOTE: these are internal interfaces. - def int_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; - def int_longjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>; - def int_sigsetjmp : Intrinsic<[llvm_i32_ty] , [llvm_ptr_ty, llvm_i32_ty]>; - def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>; - - // Internal interface for object size checking - def int_objectsize : Intrinsic<[llvm_anyint_ty], - [llvm_anyptr_ty, llvm_i1_ty, - llvm_i1_ty, llvm_i1_ty], - [IntrNoMem, IntrSpeculatable, ImmArg<1>, ImmArg<2>, ImmArg<3>]>, - GCCBuiltin<"__builtin_object_size">; - - //===--------------- Constrained Floating Point Intrinsics ----------------===// - // - - let IntrProperties = [IntrInaccessibleMemOnly] in { - def int_experimental_constrained_fadd : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_fsub : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_fmul : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_fdiv : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_frem : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - - def int_experimental_constrained_fma : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - - // These intrinsics are sensitive to the rounding mode so we need constrained - // versions of each of them. When strict rounding and exception control are - // not required the non-constrained versions of these intrinsics should be - // used. - def int_experimental_constrained_sqrt : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_powi : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_i32_ty, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_sin : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_cos : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_pow : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_log : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_log10: Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_log2 : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_exp : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_exp2 : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_rint : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_nearbyint : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_maxnum : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_minnum : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_ceil : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_floor : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_round : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - def int_experimental_constrained_trunc : Intrinsic<[ llvm_anyfloat_ty ], - [ LLVMMatchType<0>, - llvm_metadata_ty, - llvm_metadata_ty ]>; - } - // FIXME: Add intrinsics for fcmp, fptrunc, fpext, fptoui and fptosi. - // FIXME: Add intrinsics for fabs and copysign? - - - //===------------------------- Expect Intrinsics --------------------------===// - // - def int_expect : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>; - - //===-------------------- Bit Manipulation Intrinsics ---------------------===// - // - - // None of these intrinsics accesses memory at all. - let IntrProperties = [IntrNoMem, IntrSpeculatable] in { - def int_bswap: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>; - def int_ctpop: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>; - def int_bitreverse : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>; - def int_fshl : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>; - def int_fshr : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>; - } - - let IntrProperties = [IntrNoMem, IntrSpeculatable, ImmArg<1>] in { - def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>; - def int_cttz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>; - } - - //===------------------------ Debugger Intrinsics -------------------------===// - // - - // None of these intrinsics accesses memory at all...but that doesn't - // mean the optimizers can change them aggressively. Special handling - // needed in a few places. These synthetic intrinsics have no - // side-effects and just mark information about their operands. - let IntrProperties = [IntrNoMem, IntrSpeculatable] in { - def int_dbg_declare : Intrinsic<[], - [llvm_metadata_ty, - llvm_metadata_ty, - llvm_metadata_ty]>; - def int_dbg_value : Intrinsic<[], - [llvm_metadata_ty, - llvm_metadata_ty, - llvm_metadata_ty]>; - def int_dbg_addr : Intrinsic<[], - [llvm_metadata_ty, - llvm_metadata_ty, - llvm_metadata_ty]>; - def int_dbg_label : Intrinsic<[], - [llvm_metadata_ty]>; - } - - //===------------------ Exception Handling Intrinsics----------------------===// - // - - // The result of eh.typeid.for depends on the enclosing function, but inside a - // given function it is 'const' and may be CSE'd etc. - def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>; - - def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>; - def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>; - - // eh.exceptionpointer returns the pointer to the exception caught by - // the given `catchpad`. - def int_eh_exceptionpointer : Intrinsic<[llvm_anyptr_ty], [llvm_token_ty], - [IntrNoMem]>; - - // Gets the exception code from a catchpad token. Only used on some platforms. - def int_eh_exceptioncode : Intrinsic<[llvm_i32_ty], [llvm_token_ty], [IntrNoMem]>; - - // __builtin_unwind_init is an undocumented GCC intrinsic that causes all - // callee-saved registers to be saved and restored (regardless of whether they - // are used) in the calling function. It is used by libgcc_eh. - def int_eh_unwind_init: Intrinsic<[]>, - GCCBuiltin<"__builtin_unwind_init">; - - def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>; - - let IntrProperties = [IntrNoMem] in { - def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; - def int_eh_sjlj_callsite : Intrinsic<[], [llvm_i32_ty]>; - } - def int_eh_sjlj_functioncontext : Intrinsic<[], [llvm_ptr_ty]>; - def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; - def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty], [IntrNoReturn]>; - def int_eh_sjlj_setup_dispatch : Intrinsic<[], []>; - - //===---------------- Generic Variable Attribute Intrinsics----------------===// - // - def int_var_annotation : Intrinsic<[], - [llvm_ptr_ty, llvm_ptr_ty, - llvm_ptr_ty, llvm_i32_ty], - [], "llvm.var.annotation">; - def int_ptr_annotation : Intrinsic<[LLVMAnyPointerType], - [LLVMMatchType<0>, llvm_ptr_ty, llvm_ptr_ty, - llvm_i32_ty], - [], "llvm.ptr.annotation">; - def int_annotation : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, llvm_ptr_ty, - llvm_ptr_ty, llvm_i32_ty], - [], "llvm.annotation">; - - // Annotates the current program point with metadata strings which are emitted - // as CodeView debug info records. This is expensive, as it disables inlining - // and is modelled as having side effects. - def int_codeview_annotation : Intrinsic<[], [llvm_metadata_ty], - [IntrInaccessibleMemOnly, IntrNoDuplicate], - "llvm.codeview.annotation">; - - //===------------------------ Trampoline Intrinsics -----------------------===// - // - def int_init_trampoline : Intrinsic<[], - [llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty], - [IntrArgMemOnly, NoCapture<0>]>, - GCCBuiltin<"__builtin_init_trampoline">; - - def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], - [IntrReadMem, IntrArgMemOnly]>, - GCCBuiltin<"__builtin_adjust_trampoline">; - - //===------------------------ Overflow Intrinsics -------------------------===// - // - - // Expose the carry flag from add operations on two integrals. - def int_sadd_with_overflow : Intrinsic<[llvm_anyint_ty, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable]>; - def int_uadd_with_overflow : Intrinsic<[llvm_anyint_ty, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable]>; - - def int_ssub_with_overflow : Intrinsic<[llvm_anyint_ty, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable]>; - def int_usub_with_overflow : Intrinsic<[llvm_anyint_ty, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable]>; - - def int_smul_with_overflow : Intrinsic<[llvm_anyint_ty, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable]>; - def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable]>; - - //===------------------------- Saturation Arithmetic Intrinsics ---------------------===// - // - def int_sadd_sat : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable, Commutative]>; - def int_uadd_sat : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable, Commutative]>; - def int_ssub_sat : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable]>; - def int_usub_sat : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable]>; - - //===------------------------- Fixed Point Arithmetic Intrinsics ---------------------===// - // - def int_smul_fix : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty], - [IntrNoMem, IntrSpeculatable, Commutative, ImmArg<2>]>; - - def int_umul_fix : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty], - [IntrNoMem, IntrSpeculatable, Commutative, ImmArg<2>]>; - - //===------------------------- Memory Use Markers -------------------------===// - // - def int_lifetime_start : Intrinsic<[], - [llvm_i64_ty, llvm_anyptr_ty], - [IntrArgMemOnly, NoCapture<1>, ImmArg<0>]>; - def int_lifetime_end : Intrinsic<[], - [llvm_i64_ty, llvm_anyptr_ty], - [IntrArgMemOnly, NoCapture<1>, ImmArg<0>]>; - def int_invariant_start : Intrinsic<[llvm_descriptor_ty], - [llvm_i64_ty, llvm_anyptr_ty], - [IntrArgMemOnly, NoCapture<1>, ImmArg<0>]>; - def int_invariant_end : Intrinsic<[], - [llvm_descriptor_ty, llvm_i64_ty, - llvm_anyptr_ty], - [IntrArgMemOnly, NoCapture<2>, ImmArg<1>]>; - - // launder.invariant.group can't be marked with 'readnone' (IntrNoMem), - // because it would cause CSE of two barriers with the same argument. - // Inaccessiblememonly says that the barrier doesn't read the argument, - // but it changes state not accessible to this module. This way - // we can DSE through the barrier because it doesn't read the value - // after store. Although the barrier doesn't modify any memory it - // can't be marked as readonly, because it would be possible to - // CSE 2 barriers with store in between. - // The argument also can't be marked with 'returned' attribute, because - // it would remove barrier. - // Note that it is still experimental, which means that its semantics - // might change in the future. - def int_launder_invariant_group : Intrinsic<[llvm_anyptr_ty], - [LLVMMatchType<0>], - [IntrInaccessibleMemOnly, IntrSpeculatable]>; - - - def int_strip_invariant_group : Intrinsic<[llvm_anyptr_ty], - [LLVMMatchType<0>], - [IntrSpeculatable, IntrNoMem]>; - - //===------------------------ Stackmap Intrinsics -------------------------===// - // - def int_experimental_stackmap : Intrinsic<[], - [llvm_i64_ty, llvm_i32_ty, llvm_vararg_ty], - [Throws]>; - def int_experimental_patchpoint_void : Intrinsic<[], - [llvm_i64_ty, llvm_i32_ty, - llvm_ptr_ty, llvm_i32_ty, - llvm_vararg_ty], - [Throws]>; - def int_experimental_patchpoint_i64 : Intrinsic<[llvm_i64_ty], - [llvm_i64_ty, llvm_i32_ty, - llvm_ptr_ty, llvm_i32_ty, - llvm_vararg_ty], - [Throws]>; - - - //===------------------------ Garbage Collection Intrinsics ---------------===// - // These are documented in docs/Statepoint.rst - - def int_experimental_gc_statepoint : Intrinsic<[llvm_token_ty], - [llvm_i64_ty, llvm_i32_ty, - llvm_anyptr_ty, llvm_i32_ty, - llvm_i32_ty, llvm_vararg_ty], - [Throws, ImmArg<0>, ImmArg<1>, ImmArg<3>, ImmArg<4>]>; - - def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_token_ty], - [IntrReadMem]>; - def int_experimental_gc_relocate : Intrinsic<[llvm_any_ty], - [llvm_token_ty, llvm_i32_ty, llvm_i32_ty], - [IntrReadMem, ImmArg<1>, ImmArg<2>]>; - -+// INTEL_COLLAB -+//===------------------------ Directive Intrinsics ------------------------===// -+// -+def int_directive_region_entry : Intrinsic<[llvm_token_ty], [], []>; -+def int_directive_region_exit : Intrinsic<[], [llvm_token_ty], []>; -+// end INTEL_COLLAB - //===------------------------ Coroutine Intrinsics ---------------===// - // These are documented in docs/Coroutines.rst - - // Coroutine Structure Intrinsics. - - def int_coro_id : Intrinsic<[llvm_token_ty], [llvm_i32_ty, llvm_ptr_ty, - llvm_ptr_ty, llvm_ptr_ty], - [IntrArgMemOnly, IntrReadMem, - ReadNone<1>, ReadOnly<2>, NoCapture<2>]>; - def int_coro_alloc : Intrinsic<[llvm_i1_ty], [llvm_token_ty], []>; - def int_coro_begin : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty], - [WriteOnly<1>]>; - - def int_coro_free : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty], - [IntrReadMem, IntrArgMemOnly, ReadOnly<1>, - NoCapture<1>]>; - def int_coro_end : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_i1_ty], []>; - - def int_coro_frame : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; - def int_coro_noop : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; - def int_coro_size : Intrinsic<[llvm_anyint_ty], [], [IntrNoMem]>; - - def int_coro_save : Intrinsic<[llvm_token_ty], [llvm_ptr_ty], []>; - def int_coro_suspend : Intrinsic<[llvm_i8_ty], [llvm_token_ty, llvm_i1_ty], []>; - - def int_coro_param : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_ptr_ty], - [IntrNoMem, ReadNone<0>, ReadNone<1>]>; - - // Coroutine Manipulation Intrinsics. - - def int_coro_resume : Intrinsic<[], [llvm_ptr_ty], [Throws]>; - def int_coro_destroy : Intrinsic<[], [llvm_ptr_ty], [Throws]>; - def int_coro_done : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty], - [IntrArgMemOnly, ReadOnly<0>, NoCapture<0>]>; - def int_coro_promise : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty, llvm_i32_ty, llvm_i1_ty], - [IntrNoMem, NoCapture<0>]>; - - // Coroutine Lowering Intrinsics. Used internally by coroutine passes. - - def int_coro_subfn_addr : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly, ReadOnly<0>, - NoCapture<0>]>; - - ///===-------------------------- Other Intrinsics --------------------------===// - // - def int_flt_rounds : Intrinsic<[llvm_i32_ty]>, - GCCBuiltin<"__builtin_flt_rounds">; - def int_trap : Intrinsic<[], [], [IntrNoReturn, IntrCold]>, - GCCBuiltin<"__builtin_trap">; - def int_debugtrap : Intrinsic<[]>, - GCCBuiltin<"__builtin_debugtrap">; - - // Support for dynamic deoptimization (or de-specialization) - def int_experimental_deoptimize : Intrinsic<[llvm_any_ty], [llvm_vararg_ty], - [Throws]>; - - // Support for speculative runtime guards - def int_experimental_guard : Intrinsic<[], [llvm_i1_ty, llvm_vararg_ty], - [Throws]>; - - // Supports widenable conditions for guards represented as explicit branches. - def int_experimental_widenable_condition : Intrinsic<[llvm_i1_ty], [], - [IntrInaccessibleMemOnly]>; - - // NOP: calls/invokes to this intrinsic are removed by codegen - def int_donothing : Intrinsic<[], [], [IntrNoMem]>; - - // This instruction has no actual effect, though it is treated by the optimizer - // has having opaque side effects. This may be inserted into loops to ensure - // that they are not removed even if they turn out to be empty, for languages - // which specify that infinite loops must be preserved. - def int_sideeffect : Intrinsic<[], [], [IntrInaccessibleMemOnly]>; - - // Intrisics to support half precision floating point format - let IntrProperties = [IntrNoMem] in { - def int_convert_to_fp16 : Intrinsic<[llvm_i16_ty], [llvm_anyfloat_ty]>; - def int_convert_from_fp16 : Intrinsic<[llvm_anyfloat_ty], [llvm_i16_ty]>; - } - - // Clear cache intrinsic, default to ignore (ie. emit nothing) - // maps to void __clear_cache() on supporting platforms - def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], - [], "llvm.clear_cache">; - - // Intrinsic to detect whether its argument is a constant. - def int_is_constant : Intrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem], "llvm.is.constant">; - - - //===-------------------------- Masked Intrinsics -------------------------===// - // - def int_masked_store : Intrinsic<[], [llvm_anyvector_ty, - LLVMAnyPointerType>, - llvm_i32_ty, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], - [IntrArgMemOnly, ImmArg<2>]>; - - def int_masked_load : Intrinsic<[llvm_anyvector_ty], - [LLVMAnyPointerType>, llvm_i32_ty, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<0>], - [IntrReadMem, IntrArgMemOnly, ImmArg<1>]>; - - def int_masked_gather: Intrinsic<[llvm_anyvector_ty], - [LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, - LLVMMatchType<0>], - [IntrReadMem, ImmArg<1>]>; - - def int_masked_scatter: Intrinsic<[], - [llvm_anyvector_ty, - LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], - [ImmArg<2>]>; - - def int_masked_expandload: Intrinsic<[llvm_anyvector_ty], - [LLVMPointerToElt<0>, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, - LLVMMatchType<0>], - [IntrReadMem]>; - - def int_masked_compressstore: Intrinsic<[], - [llvm_anyvector_ty, - LLVMPointerToElt<0>, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], - [IntrArgMemOnly]>; - - // Test whether a pointer is associated with a type metadata identifier. - def int_type_test : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_metadata_ty], - [IntrNoMem]>; - -+// INTEL_COLLAB -+// These intrinsics will be deprecated. -+// Use int_directive_region_entry/exit instead. -+//===--------------------- Intel Directive Intrinsics ---------------------===// -+ -+def int_intel_directive : Intrinsic<[], [llvm_metadata_ty], -+ [IntrArgMemOnly], -+ "llvm.intel.directive">; -+ -+def int_intel_directive_qual : Intrinsic<[], [llvm_metadata_ty], -+ [IntrArgMemOnly], -+ "llvm.intel.directive.qual">; -+ -+def int_intel_directive_qual_opnd : Intrinsic<[], -+ [llvm_metadata_ty, llvm_any_ty], -+ [IntrArgMemOnly], -+ "llvm.intel.directive.qual.opnd">; -+ -+def int_intel_directive_qual_opndlist : Intrinsic< -+ [], -+ [llvm_metadata_ty, llvm_vararg_ty], -+ [IntrArgMemOnly], -+ "llvm.intel.directive.qual.opndlist">; -+// end INTEL_COLLAB - // Safely loads a function pointer from a virtual table pointer using type metadata. - def int_type_checked_load : Intrinsic<[llvm_ptr_ty, llvm_i1_ty], - [llvm_ptr_ty, llvm_i32_ty, llvm_metadata_ty], - [IntrNoMem]>; - - // Create a branch funnel that implements an indirect call to a limited set of - // callees. This needs to be a musttail call. - def int_icall_branch_funnel : Intrinsic<[], [llvm_vararg_ty], []>; - - def int_load_relative: Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_anyint_ty], - [IntrReadMem, IntrArgMemOnly]>; - - def int_hwasan_check_memaccess : - Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], [IntrInaccessibleMemOnly, ImmArg<2>]>; - - // Xray intrinsics - //===----------------------------------------------------------------------===// - // Custom event logging for x-ray. - // Takes a pointer to a string and the length of the string. - def int_xray_customevent : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], - [NoCapture<0>, ReadOnly<0>, IntrWriteMem]>; - // Typed event logging for x-ray. - // Takes a numeric type tag, a pointer to a string and the length of the string. - def int_xray_typedevent : Intrinsic<[], [llvm_i16_ty, llvm_ptr_ty, llvm_i32_ty], - [NoCapture<1>, ReadOnly<1>, IntrWriteMem]>; - //===----------------------------------------------------------------------===// - - //===------ Memory intrinsics with element-wise atomicity guarantees ------===// - // - - // @llvm.memcpy.element.unordered.atomic.*(dest, src, length, elementsize) - def int_memcpy_element_unordered_atomic - : Intrinsic<[], - [ - llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, llvm_i32_ty - ], - [ - IntrArgMemOnly, NoCapture<0>, NoCapture<1>, WriteOnly<0>, - ReadOnly<1>, ImmArg<3> - ]>; - - // @llvm.memmove.element.unordered.atomic.*(dest, src, length, elementsize) - def int_memmove_element_unordered_atomic - : Intrinsic<[], - [ - llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, llvm_i32_ty - ], - [ - IntrArgMemOnly, NoCapture<0>, NoCapture<1>, WriteOnly<0>, - ReadOnly<1>, ImmArg<3> - ]>; - - // @llvm.memset.element.unordered.atomic.*(dest, value, length, elementsize) - def int_memset_element_unordered_atomic - : Intrinsic<[], [ llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty, llvm_i32_ty ], - [ IntrArgMemOnly, NoCapture<0>, WriteOnly<0>, ImmArg<3> ]>; - - //===------------------------ Reduction Intrinsics ------------------------===// - // - def int_experimental_vector_reduce_fadd : Intrinsic<[llvm_anyfloat_ty], - [llvm_anyfloat_ty, - llvm_anyvector_ty], - [IntrNoMem]>; - def int_experimental_vector_reduce_fmul : Intrinsic<[llvm_anyfloat_ty], - [llvm_anyfloat_ty, - llvm_anyvector_ty], - [IntrNoMem]>; - def int_experimental_vector_reduce_add : Intrinsic<[llvm_anyint_ty], - [llvm_anyvector_ty], - [IntrNoMem]>; - def int_experimental_vector_reduce_mul : Intrinsic<[llvm_anyint_ty], - [llvm_anyvector_ty], - [IntrNoMem]>; - def int_experimental_vector_reduce_and : Intrinsic<[llvm_anyint_ty], - [llvm_anyvector_ty], - [IntrNoMem]>; - def int_experimental_vector_reduce_or : Intrinsic<[llvm_anyint_ty], - [llvm_anyvector_ty], - [IntrNoMem]>; - def int_experimental_vector_reduce_xor : Intrinsic<[llvm_anyint_ty], - [llvm_anyvector_ty], - [IntrNoMem]>; - def int_experimental_vector_reduce_smax : Intrinsic<[llvm_anyint_ty], - [llvm_anyvector_ty], - [IntrNoMem]>; - def int_experimental_vector_reduce_smin : Intrinsic<[llvm_anyint_ty], - [llvm_anyvector_ty], - [IntrNoMem]>; - def int_experimental_vector_reduce_umax : Intrinsic<[llvm_anyint_ty], - [llvm_anyvector_ty], - [IntrNoMem]>; - def int_experimental_vector_reduce_umin : Intrinsic<[llvm_anyint_ty], - [llvm_anyvector_ty], - [IntrNoMem]>; - def int_experimental_vector_reduce_fmax : Intrinsic<[llvm_anyfloat_ty], - [llvm_anyvector_ty], - [IntrNoMem]>; - def int_experimental_vector_reduce_fmin : Intrinsic<[llvm_anyfloat_ty], - [llvm_anyvector_ty], - [IntrNoMem]>; - - //===----- Intrinsics that are used to provide predicate information -----===// - - def int_ssa_copy : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>], - [IntrNoMem, Returned<0>]>; - //===----------------------------------------------------------------------===// - // Target-specific intrinsics - //===----------------------------------------------------------------------===// - - include "llvm/IR/IntrinsicsPowerPC.td" - include "llvm/IR/IntrinsicsX86.td" - include "llvm/IR/IntrinsicsARM.td" - include "llvm/IR/IntrinsicsAArch64.td" - include "llvm/IR/IntrinsicsXCore.td" - include "llvm/IR/IntrinsicsHexagon.td" - include "llvm/IR/IntrinsicsNVVM.td" - include "llvm/IR/IntrinsicsMips.td" - include "llvm/IR/IntrinsicsAMDGPU.td" - include "llvm/IR/IntrinsicsBPF.td" - include "llvm/IR/IntrinsicsSystemZ.td" - include "llvm/IR/IntrinsicsWebAssembly.td" - include "llvm/IR/IntrinsicsRISCV.td" -diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h -index f458680..3ecc0e4 100644 ---- a/llvm/include/llvm/IR/Module.h -+++ b/llvm/include/llvm/IR/Module.h -@@ -1,925 +1,937 @@ - //===- llvm/Module.h - C++ class to represent a VM module -------*- 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 - // - //===----------------------------------------------------------------------===// - // - /// @file - /// Module.h This file contains the declarations for the Module class. - // - //===----------------------------------------------------------------------===// - - #ifndef LLVM_IR_MODULE_H - #define LLVM_IR_MODULE_H - - #include "llvm-c/Types.h" - #include "llvm/ADT/Optional.h" - #include "llvm/ADT/STLExtras.h" - #include "llvm/ADT/StringMap.h" - #include "llvm/ADT/StringRef.h" - #include "llvm/ADT/iterator_range.h" - #include "llvm/IR/Attributes.h" - #include "llvm/IR/Comdat.h" - #include "llvm/IR/DataLayout.h" - #include "llvm/IR/Function.h" - #include "llvm/IR/GlobalAlias.h" - #include "llvm/IR/GlobalIFunc.h" - #include "llvm/IR/GlobalVariable.h" - #include "llvm/IR/Metadata.h" - #include "llvm/IR/ProfileSummary.h" - #include "llvm/IR/SymbolTableListTraits.h" - #include "llvm/Support/CBindingWrapping.h" - #include "llvm/Support/CodeGen.h" - #include - #include - #include - #include - #include - #include - - namespace llvm { - - class Error; - class FunctionType; - class GVMaterializer; - class LLVMContext; - class MemoryBuffer; - class RandomNumberGenerator; - template class SmallPtrSetImpl; - class StructType; - class VersionTuple; - - /// A Module instance is used to store all the information related to an - /// LLVM module. Modules are the top level container of all other LLVM - /// Intermediate Representation (IR) objects. Each module directly contains a - /// list of globals variables, a list of functions, a list of libraries (or - /// other modules) this module depends on, a symbol table, and various data - /// about the target's characteristics. - /// - /// A module maintains a GlobalValRefMap object that is used to hold all - /// constant references to global variables in the module. When a global - /// variable is destroyed, it should have no entries in the GlobalValueRefMap. - /// The main container class for the LLVM Intermediate Representation. - class Module { - /// @name Types And Enumerations - /// @{ - public: - /// The type for the list of global variables. - using GlobalListType = SymbolTableList; - /// The type for the list of functions. - using FunctionListType = SymbolTableList; - /// The type for the list of aliases. - using AliasListType = SymbolTableList; - /// The type for the list of ifuncs. - using IFuncListType = SymbolTableList; - /// The type for the list of named metadata. - using NamedMDListType = ilist; - /// The type of the comdat "symbol" table. - using ComdatSymTabType = StringMap; - - /// The Global Variable iterator. - using global_iterator = GlobalListType::iterator; - /// The Global Variable constant iterator. - using const_global_iterator = GlobalListType::const_iterator; - - /// The Function iterators. - using iterator = FunctionListType::iterator; - /// The Function constant iterator - using const_iterator = FunctionListType::const_iterator; - - /// The Function reverse iterator. - using reverse_iterator = FunctionListType::reverse_iterator; - /// The Function constant reverse iterator. - using const_reverse_iterator = FunctionListType::const_reverse_iterator; - - /// The Global Alias iterators. - using alias_iterator = AliasListType::iterator; - /// The Global Alias constant iterator - using const_alias_iterator = AliasListType::const_iterator; - - /// The Global IFunc iterators. - using ifunc_iterator = IFuncListType::iterator; - /// The Global IFunc constant iterator - using const_ifunc_iterator = IFuncListType::const_iterator; - - /// The named metadata iterators. - using named_metadata_iterator = NamedMDListType::iterator; - /// The named metadata constant iterators. - using const_named_metadata_iterator = NamedMDListType::const_iterator; - - /// This enumeration defines the supported behaviors of module flags. - enum ModFlagBehavior { - /// Emits an error if two values disagree, otherwise the resulting value is - /// that of the operands. - Error = 1, - - /// Emits a warning if two values disagree. The result value will be the - /// operand for the flag from the first module being linked. - Warning = 2, - - /// Adds a requirement that another module flag be present and have a - /// specified value after linking is performed. The value must be a metadata - /// pair, where the first element of the pair is the ID of the module flag - /// to be restricted, and the second element of the pair is the value the - /// module flag should be restricted to. This behavior can be used to - /// restrict the allowable results (via triggering of an error) of linking - /// IDs with the **Override** behavior. - Require = 3, - - /// Uses the specified value, regardless of the behavior or value of the - /// other module. If both modules specify **Override**, but the values - /// differ, an error will be emitted. - Override = 4, - - /// Appends the two values, which are required to be metadata nodes. - Append = 5, - - /// Appends the two values, which are required to be metadata - /// nodes. However, duplicate entries in the second list are dropped - /// during the append operation. - AppendUnique = 6, - - /// Takes the max of the two values, which are required to be integers. - Max = 7, - - // Markers: - ModFlagBehaviorFirstVal = Error, - ModFlagBehaviorLastVal = Max - }; - - /// Checks if Metadata represents a valid ModFlagBehavior, and stores the - /// converted result in MFB. - static bool isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB); - - struct ModuleFlagEntry { - ModFlagBehavior Behavior; - MDString *Key; - Metadata *Val; - - ModuleFlagEntry(ModFlagBehavior B, MDString *K, Metadata *V) - : Behavior(B), Key(K), Val(V) {} - }; - - /// @} - /// @name Member Variables - /// @{ - private: - LLVMContext &Context; ///< The LLVMContext from which types and - ///< constants are allocated. - GlobalListType GlobalList; ///< The Global Variables in the module - FunctionListType FunctionList; ///< The Functions in the module - AliasListType AliasList; ///< The Aliases in the module - IFuncListType IFuncList; ///< The IFuncs in the module - NamedMDListType NamedMDList; ///< The named metadata in the module - std::string GlobalScopeAsm; ///< Inline Asm at global scope. - ValueSymbolTable *ValSymTab; ///< Symbol table for values - ComdatSymTabType ComdatSymTab; ///< Symbol table for COMDATs - std::unique_ptr - OwnedMemoryBuffer; ///< Memory buffer directly owned by this - ///< module, for legacy clients only. - std::unique_ptr - Materializer; ///< Used to materialize GlobalValues - std::string ModuleID; ///< Human readable identifier for the module - std::string SourceFileName; ///< Original source file name for module, - ///< recorded in bitcode. - std::string TargetTriple; ///< Platform target triple Module compiled on - ///< Format: (arch)(sub)-(vendor)-(sys0-(abi) - void *NamedMDSymTab; ///< NamedMDNode names. - DataLayout DL; ///< DataLayout associated with the module - -+#if INTEL_COLLAB -+ std::string TargetDevices; ///< Target devices -+#endif // INTEL_COLLAB - friend class Constant; - - /// @} - /// @name Constructors - /// @{ - public: - /// The Module constructor. Note that there is no default constructor. You - /// must provide a name for the module upon construction. - explicit Module(StringRef ModuleID, LLVMContext& C); - /// The module destructor. This will dropAllReferences. - ~Module(); - - /// @} - /// @name Module Level Accessors - /// @{ - - /// Get the module identifier which is, essentially, the name of the module. - /// @returns the module identifier as a string - const std::string &getModuleIdentifier() const { return ModuleID; } - - /// Returns the number of non-debug IR instructions in the module. - /// This is equivalent to the sum of the IR instruction counts of each - /// function contained in the module. - unsigned getInstructionCount(); - - /// Get the module's original source file name. When compiling from - /// bitcode, this is taken from a bitcode record where it was recorded. - /// For other compiles it is the same as the ModuleID, which would - /// contain the source file name. - const std::string &getSourceFileName() const { return SourceFileName; } - - /// Get a short "name" for the module. - /// - /// This is useful for debugging or logging. It is essentially a convenience - /// wrapper around getModuleIdentifier(). - StringRef getName() const { return ModuleID; } - - /// Get the data layout string for the module's target platform. This is - /// equivalent to getDataLayout()->getStringRepresentation(). - const std::string &getDataLayoutStr() const { - return DL.getStringRepresentation(); - } - - /// Get the data layout for the module's target platform. - const DataLayout &getDataLayout() const; - - /// Get the target triple which is a string describing the target host. - /// @returns a string containing the target triple. - const std::string &getTargetTriple() const { return TargetTriple; } - -+#if INTEL_COLLAB -+ /// Get the target device information which is a comma-separated string -+ /// describing one or more devices. -+ const std::string &getTargetDevices() const { return TargetDevices; } -+#endif // INTEL_COLLAB - /// Get the global data context. - /// @returns LLVMContext - a container for LLVM's global information - LLVMContext &getContext() const { return Context; } - - /// Get any module-scope inline assembly blocks. - /// @returns a string containing the module-scope inline assembly blocks. - const std::string &getModuleInlineAsm() const { return GlobalScopeAsm; } - - /// Get a RandomNumberGenerator salted for use with this module. The - /// RNG can be seeded via -rng-seed= and is salted with the - /// ModuleID and the provided pass salt. The returned RNG should not - /// be shared across threads or passes. - /// - /// A unique RNG per pass ensures a reproducible random stream even - /// when other randomness consuming passes are added or removed. In - /// addition, the random stream will be reproducible across LLVM - /// versions when the pass does not change. - std::unique_ptr createRNG(const Pass* P) const; - - /// Return true if size-info optimization remark is enabled, false - /// otherwise. - bool shouldEmitInstrCountChangedRemark() { - return getContext().getDiagHandlerPtr()->isAnalysisRemarkEnabled( - "size-info"); - } - - /// @} - /// @name Module Level Mutators - /// @{ - - /// Set the module identifier. - void setModuleIdentifier(StringRef ID) { ModuleID = ID; } - - /// Set the module's original source file name. - void setSourceFileName(StringRef Name) { SourceFileName = Name; } - - /// Set the data layout - void setDataLayout(StringRef Desc); - void setDataLayout(const DataLayout &Other); - - /// Set the target triple. - void setTargetTriple(StringRef T) { TargetTriple = T; } - -+#if INTEL_COLLAB -+ /// set the target device information. -+ void setTargetDevices(StringRef T) { TargetDevices = T; } -+#endif // INTEL_COLLAB - /// Set the module-scope inline assembly blocks. - /// A trailing newline is added if the input doesn't have one. - void setModuleInlineAsm(StringRef Asm) { - GlobalScopeAsm = Asm; - if (!GlobalScopeAsm.empty() && GlobalScopeAsm.back() != '\n') - GlobalScopeAsm += '\n'; - } - - /// Append to the module-scope inline assembly blocks. - /// A trailing newline is added if the input doesn't have one. - void appendModuleInlineAsm(StringRef Asm) { - GlobalScopeAsm += Asm; - if (!GlobalScopeAsm.empty() && GlobalScopeAsm.back() != '\n') - GlobalScopeAsm += '\n'; - } - - /// @} - /// @name Generic Value Accessors - /// @{ - - /// Return the global value in the module with the specified name, of - /// arbitrary type. This method returns null if a global with the specified - /// name is not found. - GlobalValue *getNamedValue(StringRef Name) const; - - /// Return a unique non-zero ID for the specified metadata kind. This ID is - /// uniqued across modules in the current LLVMContext. - unsigned getMDKindID(StringRef Name) const; - - /// Populate client supplied SmallVector with the name for custom metadata IDs - /// registered in this LLVMContext. - void getMDKindNames(SmallVectorImpl &Result) const; - - /// Populate client supplied SmallVector with the bundle tags registered in - /// this LLVMContext. The bundle tags are ordered by increasing bundle IDs. - /// \see LLVMContext::getOperandBundleTagID - void getOperandBundleTags(SmallVectorImpl &Result) const; - - /// Return the type with the specified name, or null if there is none by that - /// name. - StructType *getTypeByName(StringRef Name) const; - - std::vector getIdentifiedStructTypes() const; - - /// @} - /// @name Function Accessors - /// @{ - - /// Look up the specified function in the module symbol table. Four - /// possibilities: - /// 1. If it does not exist, add a prototype for the function and return it. - /// 2. Otherwise, if the existing function has the correct prototype, return - /// the existing function. - /// 3. Finally, the function exists but has the wrong prototype: return the - /// function with a constantexpr cast to the right prototype. - /// - /// In all cases, the returned value is a FunctionCallee wrapper around the - /// 'FunctionType *T' passed in, as well as a 'Value*' either of the Function or - /// the bitcast to the function. - FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, - AttributeList AttributeList); - - FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T); - - /// Look up the specified function in the module symbol table. If it does not - /// exist, add a prototype for the function and return it. This function - /// guarantees to return a constant of pointer to the specified function type - /// or a ConstantExpr BitCast of that type if the named function has a - /// different type. This version of the method takes a list of - /// function arguments, which makes it easier for clients to use. - template - FunctionCallee getOrInsertFunction(StringRef Name, - AttributeList AttributeList, Type *RetTy, - ArgsTy... Args) { - SmallVector ArgTys{Args...}; - return getOrInsertFunction(Name, - FunctionType::get(RetTy, ArgTys, false), - AttributeList); - } - - /// Same as above, but without the attributes. - template - FunctionCallee getOrInsertFunction(StringRef Name, Type *RetTy, - ArgsTy... Args) { - return getOrInsertFunction(Name, AttributeList{}, RetTy, Args...); - } - - // Avoid an incorrect ordering that'd otherwise compile incorrectly. - template - FunctionCallee - getOrInsertFunction(StringRef Name, AttributeList AttributeList, - FunctionType *Invalid, ArgsTy... Args) = delete; - - /// Look up the specified function in the module symbol table. If it does not - /// exist, return null. - Function *getFunction(StringRef Name) const; - - /// @} - /// @name Global Variable Accessors - /// @{ - - /// Look up the specified global variable in the module symbol table. If it - /// does not exist, return null. If AllowInternal is set to true, this - /// function will return types that have InternalLinkage. By default, these - /// types are not returned. - GlobalVariable *getGlobalVariable(StringRef Name) const { - return getGlobalVariable(Name, false); - } - - GlobalVariable *getGlobalVariable(StringRef Name, bool AllowInternal) const; - - GlobalVariable *getGlobalVariable(StringRef Name, - bool AllowInternal = false) { - return static_cast(this)->getGlobalVariable(Name, - AllowInternal); - } - - /// Return the global variable in the module with the specified name, of - /// arbitrary type. This method returns null if a global with the specified - /// name is not found. - const GlobalVariable *getNamedGlobal(StringRef Name) const { - return getGlobalVariable(Name, true); - } - GlobalVariable *getNamedGlobal(StringRef Name) { - return const_cast( - static_cast(this)->getNamedGlobal(Name)); - } - - /// Look up the specified global in the module symbol table. - /// If it does not exist, invoke a callback to create a declaration of the - /// global and return it. The global is constantexpr casted to the expected - /// type if necessary. - Constant * - getOrInsertGlobal(StringRef Name, Type *Ty, - function_ref CreateGlobalCallback); - - /// Look up the specified global in the module symbol table. If required, this - /// overload constructs the global variable using its constructor's defaults. - Constant *getOrInsertGlobal(StringRef Name, Type *Ty); - - /// @} - /// @name Global Alias Accessors - /// @{ - - /// Return the global alias in the module with the specified name, of - /// arbitrary type. This method returns null if a global with the specified - /// name is not found. - GlobalAlias *getNamedAlias(StringRef Name) const; - - /// @} - /// @name Global IFunc Accessors - /// @{ - - /// Return the global ifunc in the module with the specified name, of - /// arbitrary type. This method returns null if a global with the specified - /// name is not found. - GlobalIFunc *getNamedIFunc(StringRef Name) const; - - /// @} - /// @name Named Metadata Accessors - /// @{ - - /// Return the first NamedMDNode in the module with the specified name. This - /// method returns null if a NamedMDNode with the specified name is not found. - NamedMDNode *getNamedMetadata(const Twine &Name) const; - - /// Return the named MDNode in the module with the specified name. This method - /// returns a new NamedMDNode if a NamedMDNode with the specified name is not - /// found. - NamedMDNode *getOrInsertNamedMetadata(StringRef Name); - - /// Remove the given NamedMDNode from this module and delete it. - void eraseNamedMetadata(NamedMDNode *NMD); - - /// @} - /// @name Comdat Accessors - /// @{ - - /// Return the Comdat in the module with the specified name. It is created - /// if it didn't already exist. - Comdat *getOrInsertComdat(StringRef Name); - - /// @} - /// @name Module Flags Accessors - /// @{ - - /// Returns the module flags in the provided vector. - void getModuleFlagsMetadata(SmallVectorImpl &Flags) const; - - /// Return the corresponding value if Key appears in module flags, otherwise - /// return null. - Metadata *getModuleFlag(StringRef Key) const; - - /// Returns the NamedMDNode in the module that represents module-level flags. - /// This method returns null if there are no module-level flags. - NamedMDNode *getModuleFlagsMetadata() const; - - /// Returns the NamedMDNode in the module that represents module-level flags. - /// If module-level flags aren't found, it creates the named metadata that - /// contains them. - NamedMDNode *getOrInsertModuleFlagsMetadata(); - - /// Add a module-level flag to the module-level flags metadata. It will create - /// the module-level flags named metadata if it doesn't already exist. - void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, Metadata *Val); - void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, Constant *Val); - void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, uint32_t Val); - void addModuleFlag(MDNode *Node); - - /// @} - /// @name Materialization - /// @{ - - /// Sets the GVMaterializer to GVM. This module must not yet have a - /// Materializer. To reset the materializer for a module that already has one, - /// call materializeAll first. Destroying this module will destroy - /// its materializer without materializing any more GlobalValues. Without - /// destroying the Module, there is no way to detach or destroy a materializer - /// without materializing all the GVs it controls, to avoid leaving orphan - /// unmaterialized GVs. - void setMaterializer(GVMaterializer *GVM); - /// Retrieves the GVMaterializer, if any, for this Module. - GVMaterializer *getMaterializer() const { return Materializer.get(); } - bool isMaterialized() const { return !getMaterializer(); } - - /// Make sure the GlobalValue is fully read. - llvm::Error materialize(GlobalValue *GV); - - /// Make sure all GlobalValues in this Module are fully read and clear the - /// Materializer. - llvm::Error materializeAll(); - - llvm::Error materializeMetadata(); - - /// @} - /// @name Direct access to the globals list, functions list, and symbol table - /// @{ - - /// Get the Module's list of global variables (constant). - const GlobalListType &getGlobalList() const { return GlobalList; } - /// Get the Module's list of global variables. - GlobalListType &getGlobalList() { return GlobalList; } - - static GlobalListType Module::*getSublistAccess(GlobalVariable*) { - return &Module::GlobalList; - } - - /// Get the Module's list of functions (constant). - const FunctionListType &getFunctionList() const { return FunctionList; } - /// Get the Module's list of functions. - FunctionListType &getFunctionList() { return FunctionList; } - static FunctionListType Module::*getSublistAccess(Function*) { - return &Module::FunctionList; - } - - /// Get the Module's list of aliases (constant). - const AliasListType &getAliasList() const { return AliasList; } - /// Get the Module's list of aliases. - AliasListType &getAliasList() { return AliasList; } - - static AliasListType Module::*getSublistAccess(GlobalAlias*) { - return &Module::AliasList; - } - - /// Get the Module's list of ifuncs (constant). - const IFuncListType &getIFuncList() const { return IFuncList; } - /// Get the Module's list of ifuncs. - IFuncListType &getIFuncList() { return IFuncList; } - - static IFuncListType Module::*getSublistAccess(GlobalIFunc*) { - return &Module::IFuncList; - } - - /// Get the Module's list of named metadata (constant). - const NamedMDListType &getNamedMDList() const { return NamedMDList; } - /// Get the Module's list of named metadata. - NamedMDListType &getNamedMDList() { return NamedMDList; } - - static NamedMDListType Module::*getSublistAccess(NamedMDNode*) { - return &Module::NamedMDList; - } - - /// Get the symbol table of global variable and function identifiers - const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; } - /// Get the Module's symbol table of global variable and function identifiers. - ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; } - - /// Get the Module's symbol table for COMDATs (constant). - const ComdatSymTabType &getComdatSymbolTable() const { return ComdatSymTab; } - /// Get the Module's symbol table for COMDATs. - ComdatSymTabType &getComdatSymbolTable() { return ComdatSymTab; } - - /// @} - /// @name Global Variable Iteration - /// @{ - - global_iterator global_begin() { return GlobalList.begin(); } - const_global_iterator global_begin() const { return GlobalList.begin(); } - global_iterator global_end () { return GlobalList.end(); } - const_global_iterator global_end () const { return GlobalList.end(); } - bool global_empty() const { return GlobalList.empty(); } - - iterator_range globals() { - return make_range(global_begin(), global_end()); - } - iterator_range globals() const { - return make_range(global_begin(), global_end()); - } - - /// @} - /// @name Function Iteration - /// @{ - - iterator begin() { return FunctionList.begin(); } - const_iterator begin() const { return FunctionList.begin(); } - iterator end () { return FunctionList.end(); } - const_iterator end () const { return FunctionList.end(); } - reverse_iterator rbegin() { return FunctionList.rbegin(); } - const_reverse_iterator rbegin() const{ return FunctionList.rbegin(); } - reverse_iterator rend() { return FunctionList.rend(); } - const_reverse_iterator rend() const { return FunctionList.rend(); } - size_t size() const { return FunctionList.size(); } - bool empty() const { return FunctionList.empty(); } - - iterator_range functions() { - return make_range(begin(), end()); - } - iterator_range functions() const { - return make_range(begin(), end()); - } - - /// @} - /// @name Alias Iteration - /// @{ - - alias_iterator alias_begin() { return AliasList.begin(); } - const_alias_iterator alias_begin() const { return AliasList.begin(); } - alias_iterator alias_end () { return AliasList.end(); } - const_alias_iterator alias_end () const { return AliasList.end(); } - size_t alias_size () const { return AliasList.size(); } - bool alias_empty() const { return AliasList.empty(); } - - iterator_range aliases() { - return make_range(alias_begin(), alias_end()); - } - iterator_range aliases() const { - return make_range(alias_begin(), alias_end()); - } - - /// @} - /// @name IFunc Iteration - /// @{ - - ifunc_iterator ifunc_begin() { return IFuncList.begin(); } - const_ifunc_iterator ifunc_begin() const { return IFuncList.begin(); } - ifunc_iterator ifunc_end () { return IFuncList.end(); } - const_ifunc_iterator ifunc_end () const { return IFuncList.end(); } - size_t ifunc_size () const { return IFuncList.size(); } - bool ifunc_empty() const { return IFuncList.empty(); } - - iterator_range ifuncs() { - return make_range(ifunc_begin(), ifunc_end()); - } - iterator_range ifuncs() const { - return make_range(ifunc_begin(), ifunc_end()); - } - - /// @} - /// @name Convenience iterators - /// @{ - - using global_object_iterator = - concat_iterator; - using const_global_object_iterator = - concat_iterator; - - iterator_range global_objects() { - return concat(functions(), globals()); - } - iterator_range global_objects() const { - return concat(functions(), globals()); - } - - global_object_iterator global_object_begin() { - return global_objects().begin(); - } - global_object_iterator global_object_end() { return global_objects().end(); } - - const_global_object_iterator global_object_begin() const { - return global_objects().begin(); - } - const_global_object_iterator global_object_end() const { - return global_objects().end(); - } - - using global_value_iterator = - concat_iterator; - using const_global_value_iterator = - concat_iterator; - - iterator_range global_values() { - return concat(functions(), globals(), aliases(), ifuncs()); - } - iterator_range global_values() const { - return concat(functions(), globals(), aliases(), - ifuncs()); - } - - global_value_iterator global_value_begin() { return global_values().begin(); } - global_value_iterator global_value_end() { return global_values().end(); } - - const_global_value_iterator global_value_begin() const { - return global_values().begin(); - } - const_global_value_iterator global_value_end() const { - return global_values().end(); - } - - /// @} - /// @name Named Metadata Iteration - /// @{ - - named_metadata_iterator named_metadata_begin() { return NamedMDList.begin(); } - const_named_metadata_iterator named_metadata_begin() const { - return NamedMDList.begin(); - } - - named_metadata_iterator named_metadata_end() { return NamedMDList.end(); } - const_named_metadata_iterator named_metadata_end() const { - return NamedMDList.end(); - } - - size_t named_metadata_size() const { return NamedMDList.size(); } - bool named_metadata_empty() const { return NamedMDList.empty(); } - - iterator_range named_metadata() { - return make_range(named_metadata_begin(), named_metadata_end()); - } - iterator_range named_metadata() const { - return make_range(named_metadata_begin(), named_metadata_end()); - } - - /// An iterator for DICompileUnits that skips those marked NoDebug. - class debug_compile_units_iterator - : public std::iterator { - NamedMDNode *CUs; - unsigned Idx; - - void SkipNoDebugCUs(); - - public: - explicit debug_compile_units_iterator(NamedMDNode *CUs, unsigned Idx) - : CUs(CUs), Idx(Idx) { - SkipNoDebugCUs(); - } - - debug_compile_units_iterator &operator++() { - ++Idx; - SkipNoDebugCUs(); - return *this; - } - - debug_compile_units_iterator operator++(int) { - debug_compile_units_iterator T(*this); - ++Idx; - return T; - } - - bool operator==(const debug_compile_units_iterator &I) const { - return Idx == I.Idx; - } - - bool operator!=(const debug_compile_units_iterator &I) const { - return Idx != I.Idx; - } - - DICompileUnit *operator*() const; - DICompileUnit *operator->() const; - }; - - debug_compile_units_iterator debug_compile_units_begin() const { - auto *CUs = getNamedMetadata("llvm.dbg.cu"); - return debug_compile_units_iterator(CUs, 0); - } - - debug_compile_units_iterator debug_compile_units_end() const { - auto *CUs = getNamedMetadata("llvm.dbg.cu"); - return debug_compile_units_iterator(CUs, CUs ? CUs->getNumOperands() : 0); - } - - /// Return an iterator for all DICompileUnits listed in this Module's - /// llvm.dbg.cu named metadata node and aren't explicitly marked as - /// NoDebug. - iterator_range debug_compile_units() const { - auto *CUs = getNamedMetadata("llvm.dbg.cu"); - return make_range( - debug_compile_units_iterator(CUs, 0), - debug_compile_units_iterator(CUs, CUs ? CUs->getNumOperands() : 0)); - } - /// @} - - /// Destroy ConstantArrays in LLVMContext if they are not used. - /// ConstantArrays constructed during linking can cause quadratic memory - /// explosion. Releasing all unused constants can cause a 20% LTO compile-time - /// slowdown for a large application. - /// - /// NOTE: Constants are currently owned by LLVMContext. This can then only - /// be called where all uses of the LLVMContext are understood. - void dropTriviallyDeadConstantArrays(); - - /// @name Utility functions for printing and dumping Module objects - /// @{ - - /// Print the module to an output stream with an optional - /// AssemblyAnnotationWriter. If \c ShouldPreserveUseListOrder, then include - /// uselistorder directives so that use-lists can be recreated when reading - /// the assembly. - void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW, - bool ShouldPreserveUseListOrder = false, - bool IsForDebug = false) const; - - /// Dump the module to stderr (for debugging). - void dump() const; - - /// This function causes all the subinstructions to "let go" of all references - /// that they are maintaining. This allows one to 'delete' a whole class at - /// a time, even though there may be circular references... first all - /// references are dropped, and all use counts go to zero. Then everything - /// is delete'd for real. Note that no operations are valid on an object - /// that has "dropped all references", except operator delete. - void dropAllReferences(); - - /// @} - /// @name Utility functions for querying Debug information. - /// @{ - - /// Returns the Number of Register ParametersDwarf Version by checking - /// module flags. - unsigned getNumberRegisterParameters() const; - - /// Returns the Dwarf Version by checking module flags. - unsigned getDwarfVersion() const; - - /// Returns the CodeView Version by checking module flags. - /// Returns zero if not present in module. - unsigned getCodeViewFlag() const; - - /// @} - /// @name Utility functions for querying and setting PIC level - /// @{ - - /// Returns the PIC level (small or large model) - PICLevel::Level getPICLevel() const; - - /// Set the PIC level (small or large model) - void setPICLevel(PICLevel::Level PL); - /// @} - - /// @} - /// @name Utility functions for querying and setting PIE level - /// @{ - - /// Returns the PIE level (small or large model) - PIELevel::Level getPIELevel() const; - - /// Set the PIE level (small or large model) - void setPIELevel(PIELevel::Level PL); - /// @} - - /// @} - /// @name Utility function for querying and setting code model - /// @{ - - /// Returns the code model (tiny, small, kernel, medium or large model) - Optional getCodeModel() const; - - /// Set the code model (tiny, small, kernel, medium or large) - void setCodeModel(CodeModel::Model CL); - /// @} - - /// @name Utility functions for querying and setting PGO summary - /// @{ - - /// Attach profile summary metadata to this module. - void setProfileSummary(Metadata *M, ProfileSummary::Kind Kind); - - /// Returns profile summary metadata. When IsCS is true, use the context - /// sensitive profile summary. - Metadata *getProfileSummary(bool IsCS); - /// @} - - /// Returns true if PLT should be avoided for RTLib calls. - bool getRtLibUseGOT() const; - - /// Set that PLT should be avoid for RTLib calls. - void setRtLibUseGOT(); - - /// @name Utility functions for querying and setting the build SDK version - /// @{ - - /// Attach a build SDK version metadata to this module. - void setSDKVersion(const VersionTuple &V); - - /// Get the build SDK version metadata. - /// - /// An empty version is returned if no such metadata is attached. - VersionTuple getSDKVersion() const; - /// @} - - /// Take ownership of the given memory buffer. - void setOwnedMemoryBuffer(std::unique_ptr MB); - }; - - /// Given "llvm.used" or "llvm.compiler.used" as a global name, collect - /// the initializer elements of that global in Set and return the global itself. - GlobalVariable *collectUsedGlobalVariables(const Module &M, - SmallPtrSetImpl &Set, - bool CompilerUsed); - - /// An raw_ostream inserter for modules. - inline raw_ostream &operator<<(raw_ostream &O, const Module &M) { - M.print(O, nullptr); - return O; - } - - // Create wrappers for C Binding types (see CBindingWrapping.h). - DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef) - - /* LLVMModuleProviderRef exists for historical reasons, but now just holds a - * Module. - */ - inline Module *unwrap(LLVMModuleProviderRef MP) { - return reinterpret_cast(MP); - } - - } // end namespace llvm - - #endif // LLVM_IR_MODULE_H