diff options
Diffstat (limited to 'llvm/include')
-rw-r--r-- | llvm/include/llvm-c/Core.h | 1 | ||||
-rw-r--r-- | llvm/include/llvm/Bitcode/LLVMBitCodes.h | 3 | ||||
-rw-r--r-- | llvm/include/llvm/IR/GlobalIFunc.h | 76 | ||||
-rw-r--r-- | llvm/include/llvm/IR/GlobalIndirectSymbol.h | 3 | ||||
-rw-r--r-- | llvm/include/llvm/IR/GlobalValue.h | 3 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Module.h | 43 | ||||
-rw-r--r-- | llvm/include/llvm/IR/SymbolTableListTraits.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Value.def | 1 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Value.h | 9 | ||||
-rw-r--r-- | llvm/include/llvm/IR/ValueSymbolTable.h | 1 |
10 files changed, 139 insertions, 3 deletions
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index e84726b2d0c..a339ce9c31e 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -256,6 +256,7 @@ typedef enum { LLVMFunctionValueKind, LLVMGlobalAliasValueKind, + LLVMGlobalIFuncValueKind, LLVMGlobalVariableValueKind, LLVMBlockAddressValueKind, LLVMConstantExprValueKind, diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index 0c4cc854cdc..644cfd24b9f 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -110,6 +110,9 @@ enum ModuleCodes { // HASH: [5*i32] MODULE_CODE_HASH = 17, + + // IFUNC: [ifunc value type, addrspace, resolver val#, linkage, visibility] + MODULE_CODE_IFUNC = 18, }; /// PARAMATTR blocks have code for defining a parameter attribute set. diff --git a/llvm/include/llvm/IR/GlobalIFunc.h b/llvm/include/llvm/IR/GlobalIFunc.h new file mode 100644 index 00000000000..57782e0192d --- /dev/null +++ b/llvm/include/llvm/IR/GlobalIFunc.h @@ -0,0 +1,76 @@ +//===-------- llvm/GlobalIFunc.h - GlobalIFunc class ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \brief +/// This file contains the declaration of the GlobalIFunc class, which +/// represents a single indirect function in the IR. Indirect function uses +/// ELF symbol type extension to mark that the address of a declaration should +/// be resolved at runtime by calling a resolver function. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_GLOBALIFUNC_H +#define LLVM_IR_GLOBALIFUNC_H + +#include "llvm/ADT/Twine.h" +#include "llvm/ADT/ilist_node.h" +#include "llvm/IR/GlobalIndirectSymbol.h" + +namespace llvm { + +class Module; + +// Traits class for using GlobalIFunc in symbol table in Module. +template <typename ValueSubClass> class SymbolTableListTraits; + +class GlobalIFunc final : public GlobalIndirectSymbol, + public ilist_node<GlobalIFunc> { + friend class SymbolTableListTraits<GlobalIFunc>; + void operator=(const GlobalIFunc &) = delete; + GlobalIFunc(const GlobalIFunc &) = delete; + + void setParent(Module *parent); + + GlobalIFunc(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, + const Twine &Name, Constant *Resolver, Module *Parent); + +public: + /// If a parent module is specified, the ifunc is automatically inserted into + /// the end of the specified module's ifunc list. + static GlobalIFunc *create(Type *Ty, unsigned AddressSpace, + LinkageTypes Linkage, const Twine &Name, + Constant *Resolver, Module *Parent); + + /// This method unlinks 'this' from the containing module, but does not + /// delete it. + void removeFromParent() final; + + /// This method unlinks 'this' from the containing module and deletes it. + void eraseFromParent() final; + + /// These methods retrieve and set ifunc resolver function. + void setResolver(Constant *Resolver) { + setIndirectSymbol(Resolver); + } + const Constant *getResolver() const { + return getIndirectSymbol(); + } + Constant *getResolver() { + return getIndirectSymbol(); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const Value *V) { + return V->getValueID() == Value::GlobalIFuncVal; + } +}; + +} // End llvm namespace + +#endif diff --git a/llvm/include/llvm/IR/GlobalIndirectSymbol.h b/llvm/include/llvm/IR/GlobalIndirectSymbol.h index db6b661426f..5948d3c1567 100644 --- a/llvm/include/llvm/IR/GlobalIndirectSymbol.h +++ b/llvm/include/llvm/IR/GlobalIndirectSymbol.h @@ -51,7 +51,8 @@ public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { - return V->getValueID() == Value::GlobalAliasVal; + return V->getValueID() == Value::GlobalAliasVal || + V->getValueID() == Value::GlobalIFuncVal; } }; diff --git a/llvm/include/llvm/IR/GlobalValue.h b/llvm/include/llvm/IR/GlobalValue.h index 964d5095f34..14f42e18711 100644 --- a/llvm/include/llvm/IR/GlobalValue.h +++ b/llvm/include/llvm/IR/GlobalValue.h @@ -388,7 +388,8 @@ public: static bool classof(const Value *V) { return V->getValueID() == Value::FunctionVal || V->getValueID() == Value::GlobalVariableVal || - V->getValueID() == Value::GlobalAliasVal; + V->getValueID() == Value::GlobalAliasVal || + V->getValueID() == Value::GlobalIFuncVal; } }; diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index 09cf5318aa4..118a8d19843 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -21,6 +21,7 @@ #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" @@ -75,6 +76,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 +103,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 +171,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 @@ -384,6 +393,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 /// @{ @@ -486,6 +504,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. @@ -560,6 +585,24 @@ public: } /// @} +/// @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 Named Metadata Iteration /// @{ diff --git a/llvm/include/llvm/IR/SymbolTableListTraits.h b/llvm/include/llvm/IR/SymbolTableListTraits.h index 5fc48d10d63..60e04e2f9ec 100644 --- a/llvm/include/llvm/IR/SymbolTableListTraits.h +++ b/llvm/include/llvm/IR/SymbolTableListTraits.h @@ -49,6 +49,7 @@ class Function; class Instruction; class GlobalVariable; class GlobalAlias; +class GlobalIFunc; class Module; #define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT) \ template <> struct SymbolTableListParentType<NODE> { typedef PARENT type; }; @@ -58,6 +59,7 @@ DEFINE_SYMBOL_TABLE_PARENT_TYPE(Argument, Function) DEFINE_SYMBOL_TABLE_PARENT_TYPE(Function, Module) DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalVariable, Module) DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalAlias, Module) +DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalIFunc, Module) #undef DEFINE_SYMBOL_TABLE_PARENT_TYPE template <typename NodeTy> class SymbolTableList; diff --git a/llvm/include/llvm/IR/Value.def b/llvm/include/llvm/IR/Value.def index c5f605ca2f1..48842d7f9cd 100644 --- a/llvm/include/llvm/IR/Value.def +++ b/llvm/include/llvm/IR/Value.def @@ -60,6 +60,7 @@ HANDLE_VALUE(MemoryPhi) HANDLE_GLOBAL_VALUE(Function) HANDLE_GLOBAL_VALUE(GlobalAlias) +HANDLE_GLOBAL_VALUE(GlobalIFunc) HANDLE_GLOBAL_VALUE(GlobalVariable) HANDLE_CONSTANT(BlockAddress) HANDLE_CONSTANT(ConstantExpr) diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h index a632309a63e..13b0c08a807 100644 --- a/llvm/include/llvm/IR/Value.h +++ b/llvm/include/llvm/IR/Value.h @@ -32,6 +32,7 @@ class ConstantAggregate; class DataLayout; class Function; class GlobalAlias; +class GlobalIFunc; class GlobalIndirectSymbol; class GlobalObject; class GlobalValue; @@ -751,9 +752,15 @@ template <> struct isa_impl<GlobalAlias, Value> { } }; +template <> struct isa_impl<GlobalIFunc, Value> { + static inline bool doit(const Value &Val) { + return Val.getValueID() == Value::GlobalIFuncVal; + } +}; + template <> struct isa_impl<GlobalIndirectSymbol, Value> { static inline bool doit(const Value &Val) { - return isa<GlobalAlias>(Val); + return isa<GlobalAlias>(Val) || isa<GlobalIFunc>(Val); } }; diff --git a/llvm/include/llvm/IR/ValueSymbolTable.h b/llvm/include/llvm/IR/ValueSymbolTable.h index 65bd7fc2fec..be1fdbeb4e5 100644 --- a/llvm/include/llvm/IR/ValueSymbolTable.h +++ b/llvm/include/llvm/IR/ValueSymbolTable.h @@ -39,6 +39,7 @@ class ValueSymbolTable { friend class SymbolTableListTraits<Function>; friend class SymbolTableListTraits<GlobalVariable>; friend class SymbolTableListTraits<GlobalAlias>; + friend class SymbolTableListTraits<GlobalIFunc>; /// @name Types /// @{ public: |