summaryrefslogtreecommitdiff
path: root/include/llvm/IR/Module.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/IR/Module.h')
-rw-r--r--include/llvm/IR/Module.h214
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);