diff options
Diffstat (limited to 'include/llvm/IR/Module.h')
| -rw-r--r-- | include/llvm/IR/Module.h | 214 |
1 files changed, 202 insertions, 12 deletions
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index 942f68543cb6..632b27e2d0dd 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -15,12 +15,12 @@ #ifndef LLVM_IR_MODULE_H #define LLVM_IR_MODULE_H -#include "llvm/ADT/Optional.h" #include "llvm/ADT/iterator_range.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/Support/CBindingWrapping.h" @@ -29,11 +29,13 @@ #include <system_error> namespace llvm { +template <typename T> class Optional; class FunctionType; class GVMaterializer; class LLVMContext; class RandomNumberGenerator; class StructType; +template <class PtrType> class SmallPtrSetImpl; template<> struct ilist_traits<NamedMDNode> : public ilist_default_traits<NamedMDNode> { @@ -75,6 +77,8 @@ public: typedef SymbolTableList<Function> FunctionListType; /// The type for the list of aliases. typedef SymbolTableList<GlobalAlias> AliasListType; + /// The type for the list of ifuncs. + typedef SymbolTableList<GlobalIFunc> IFuncListType; /// The type for the list of named metadata. typedef ilist<NamedMDNode> NamedMDListType; /// The type of the comdat "symbol" table. @@ -100,6 +104,11 @@ public: /// The Global Alias constant iterator typedef AliasListType::const_iterator const_alias_iterator; + /// The Global IFunc iterators. + typedef IFuncListType::iterator ifunc_iterator; + /// The Global IFunc constant iterator + typedef IFuncListType::const_iterator const_ifunc_iterator; + /// The named metadata iterators. typedef NamedMDListType::iterator named_metadata_iterator; /// The named metadata constant iterators. @@ -163,6 +172,7 @@ private: 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 @@ -170,6 +180,8 @@ private: std::unique_ptr<GVMaterializer> 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. @@ -195,6 +207,12 @@ public: /// @returns the module identifier as a string const std::string &getModuleIdentifier() const { return ModuleID; } + /// 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; } + /// \brief Get a short "name" for the module. /// /// This is useful for debugging or logging. It is essentially a convenience @@ -240,6 +258,9 @@ public: /// 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); @@ -251,8 +272,7 @@ public: /// A trailing newline is added if the input doesn't have one. void setModuleInlineAsm(StringRef Asm) { GlobalScopeAsm = Asm; - if (!GlobalScopeAsm.empty() && - GlobalScopeAsm[GlobalScopeAsm.size()-1] != '\n') + if (!GlobalScopeAsm.empty() && GlobalScopeAsm.back() != '\n') GlobalScopeAsm += '\n'; } @@ -260,8 +280,7 @@ public: /// A trailing newline is added if the input doesn't have one. void appendModuleInlineAsm(StringRef Asm) { GlobalScopeAsm += Asm; - if (!GlobalScopeAsm.empty() && - GlobalScopeAsm[GlobalScopeAsm.size()-1] != '\n') + if (!GlobalScopeAsm.empty() && GlobalScopeAsm.back() != '\n') GlobalScopeAsm += '\n'; } @@ -375,6 +394,15 @@ public: 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 /// @{ @@ -477,6 +505,13 @@ public: 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. @@ -551,9 +586,96 @@ public: } /// @} -/// @name Named Metadata Iteration +/// @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<ifunc_iterator> ifuncs() { + return make_range(ifunc_begin(), ifunc_end()); + } + iterator_range<const_ifunc_iterator> ifuncs() const { + return make_range(ifunc_begin(), ifunc_end()); + } + +/// @} +/// @name Convenience iterators /// @{ + template <bool IsConst> class global_object_iterator_t { + friend Module; + + typename std::conditional<IsConst, const_iterator, iterator>::type + function_i, + function_e; + typename std::conditional<IsConst, const_global_iterator, + global_iterator>::type global_i; + + typedef + typename std::conditional<IsConst, const Module, Module>::type ModuleTy; + + global_object_iterator_t(ModuleTy &M) + : function_i(M.begin()), function_e(M.end()), + global_i(M.global_begin()) {} + global_object_iterator_t(ModuleTy &M, int) + : function_i(M.end()), function_e(M.end()), global_i(M.global_end()) {} + + public: + global_object_iterator_t &operator++() { + if (function_i != function_e) + ++function_i; + else + ++global_i; + return *this; + } + + typename std::conditional<IsConst, const GlobalObject, GlobalObject>::type & + operator*() const { + if (function_i != function_e) + return *function_i; + else + return *global_i; + } + + bool operator!=(const global_object_iterator_t &other) const { + return function_i != other.function_i || global_i != other.global_i; + } + }; + + typedef global_object_iterator_t</*IsConst=*/false> global_object_iterator; + typedef global_object_iterator_t</*IsConst=*/true> + const_global_object_iterator; + + global_object_iterator global_object_begin() { + return global_object_iterator(*this); + } + global_object_iterator global_object_end() { + return global_object_iterator(*this, 0); + } + + const_global_object_iterator global_object_begin() const { + return const_global_object_iterator(*this); + } + const_global_object_iterator global_object_end() const { + return const_global_object_iterator(*this, 0); + } + + iterator_range<global_object_iterator> global_objects() { + return make_range(global_object_begin(), global_object_end()); + } + iterator_range<const_global_object_iterator> global_objects() const { + return make_range(global_object_begin(), global_object_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(); @@ -574,6 +696,58 @@ public: 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<std::input_iterator_tag, DICompileUnit *> { + 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_iterator> 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 @@ -583,7 +757,6 @@ public: /// be called where all uses of the LLVMContext are understood. void dropTriviallyDeadConstantArrays(); -/// @} /// @name Utility functions for printing and dumping Module objects /// @{ @@ -628,17 +801,34 @@ public: void setPICLevel(PICLevel::Level PL); /// @} - /// @name Utility functions for querying and setting PGO counts +/// @} +/// @name Utility functions for querying and setting PIE level +/// @{ + + /// \brief Returns the PIE level (small or large model) + PIELevel::Level getPIELevel() const; + + /// \brief Set the PIE level (small or large model) + void setPIELevel(PIELevel::Level PL); +/// @} + + /// @name Utility functions for querying and setting PGO summary /// @{ - /// \brief Set maximum function count in PGO mode - void setMaximumFunctionCount(uint64_t); + /// \brief Attach profile summary metadata to this module. + void setProfileSummary(Metadata *M); - /// \brief Returns maximum function count in PGO mode - Optional<uint64_t> getMaximumFunctionCount(); + /// \brief Returns profile summary metadata + Metadata *getProfileSummary(); /// @} }; +/// \brief 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<GlobalValue *> &Set, + bool CompilerUsed); + /// An raw_ostream inserter for modules. inline raw_ostream &operator<<(raw_ostream &O, const Module &M) { M.print(O, nullptr); |
