summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
authorDmitry Polukhin <dmitry.polukhin@gmail.com>2016-04-07 12:32:19 +0000
committerDmitry Polukhin <dmitry.polukhin@gmail.com>2016-04-07 12:32:19 +0000
commita1feff7024b552b579f302fea0030aaaa14624b3 (patch)
treebc5cbda70333854512705e91da81598e4368a052 /llvm/include
parent79cb643b201bfa1acba9a1afef7395f3be3f60e6 (diff)
downloadbcm5719-llvm-a1feff7024b552b579f302fea0030aaaa14624b3.tar.gz
bcm5719-llvm-a1feff7024b552b579f302fea0030aaaa14624b3.zip
[GCC] Attribute ifunc support in llvm
This patch add support for GCC attribute((ifunc("resolver"))) for targets that use ELF as object file format. In general ifunc is a special kind of function alias with type @gnu_indirect_function. Patch for Clang http://reviews.llvm.org/D15524 Differential Revision: http://reviews.llvm.org/D15525 llvm-svn: 265667
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm-c/Core.h1
-rw-r--r--llvm/include/llvm/Bitcode/LLVMBitCodes.h3
-rw-r--r--llvm/include/llvm/IR/GlobalIFunc.h76
-rw-r--r--llvm/include/llvm/IR/GlobalIndirectSymbol.h3
-rw-r--r--llvm/include/llvm/IR/GlobalValue.h3
-rw-r--r--llvm/include/llvm/IR/Module.h43
-rw-r--r--llvm/include/llvm/IR/SymbolTableListTraits.h2
-rw-r--r--llvm/include/llvm/IR/Value.def1
-rw-r--r--llvm/include/llvm/IR/Value.h9
-rw-r--r--llvm/include/llvm/IR/ValueSymbolTable.h1
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:
OpenPOWER on IntegriCloud