diff options
author | Dmitry Polukhin <dmitry.polukhin@gmail.com> | 2016-04-07 12:32:19 +0000 |
---|---|---|
committer | Dmitry Polukhin <dmitry.polukhin@gmail.com> | 2016-04-07 12:32:19 +0000 |
commit | a1feff7024b552b579f302fea0030aaaa14624b3 (patch) | |
tree | bc5cbda70333854512705e91da81598e4368a052 /llvm/lib/IR/Globals.cpp | |
parent | 79cb643b201bfa1acba9a1afef7395f3be3f60e6 (diff) | |
download | bcm5719-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/lib/IR/Globals.cpp')
-rw-r--r-- | llvm/lib/IR/Globals.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp index a0d59fddfc4..a9702b7af81 100644 --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -145,6 +145,9 @@ Comdat *GlobalValue::getComdat() { return const_cast<GlobalObject *>(GO)->getComdat(); return nullptr; } + // ifunc and its resolver are separate things so don't use resolver comdat. + if (isa<GlobalIFunc>(this)) + return nullptr; return cast<GlobalObject>(this)->getComdat(); } @@ -364,3 +367,34 @@ void GlobalAlias::setAliasee(Constant *Aliasee) { "Alias and aliasee types should match!"); setIndirectSymbol(Aliasee); } + +//===----------------------------------------------------------------------===// +// GlobalIFunc Implementation +//===----------------------------------------------------------------------===// + +GlobalIFunc::GlobalIFunc(Type *Ty, unsigned AddressSpace, LinkageTypes Link, + const Twine &Name, Constant *Resolver, + Module *ParentModule) + : GlobalIndirectSymbol(Ty, Value::GlobalIFuncVal, AddressSpace, Link, Name, + Resolver) { + if (ParentModule) + ParentModule->getIFuncList().push_back(this); +} + +GlobalIFunc *GlobalIFunc::create(Type *Ty, unsigned AddressSpace, + LinkageTypes Link, const Twine &Name, + Constant *Resolver, Module *ParentModule) { + return new GlobalIFunc(Ty, AddressSpace, Link, Name, Resolver, ParentModule); +} + +void GlobalIFunc::setParent(Module *parent) { + Parent = parent; +} + +void GlobalIFunc::removeFromParent() { + getParent()->getIFuncList().remove(getIterator()); +} + +void GlobalIFunc::eraseFromParent() { + getParent()->getIFuncList().erase(getIterator()); +} |