aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
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/lib/Bitcode/Writer/ValueEnumerator.cpp
parent79cb643b201bfa1acba9a1afef7395f3be3f60e6 (diff)
downloadllvm-a1feff7024b552b579f302fea0030aaaa14624b3.zip
llvm-a1feff7024b552b579f302fea0030aaaa14624b3.tar.gz
llvm-a1feff7024b552b579f302fea0030aaaa14624b3.tar.bz2
[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/Bitcode/Writer/ValueEnumerator.cpp')
-rw-r--r--llvm/lib/Bitcode/Writer/ValueEnumerator.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
index 91b523f..ff87052 100644
--- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -86,6 +86,9 @@ static OrderMap orderModule(const Module &M) {
for (const GlobalAlias &A : M.aliases())
if (!isa<GlobalValue>(A.getAliasee()))
orderValue(A.getAliasee(), OM);
+ for (const GlobalIFunc &I : M.ifuncs())
+ if (!isa<GlobalValue>(I.getResolver()))
+ orderValue(I.getResolver(), OM);
for (const Function &F : M) {
for (const Use &U : F.operands())
if (!isa<GlobalValue>(U.get()))
@@ -105,6 +108,8 @@ static OrderMap orderModule(const Module &M) {
orderValue(&F, OM);
for (const GlobalAlias &A : M.aliases())
orderValue(&A, OM);
+ for (const GlobalIFunc &I : M.ifuncs())
+ orderValue(&I, OM);
for (const GlobalVariable &G : M.globals())
orderValue(&G, OM);
OM.LastGlobalValueID = OM.size();
@@ -261,11 +266,15 @@ static UseListOrderStack predictUseListOrder(const Module &M) {
predictValueUseListOrder(&F, nullptr, OM, Stack);
for (const GlobalAlias &A : M.aliases())
predictValueUseListOrder(&A, nullptr, OM, Stack);
+ for (const GlobalIFunc &I : M.ifuncs())
+ predictValueUseListOrder(&I, nullptr, OM, Stack);
for (const GlobalVariable &G : M.globals())
if (G.hasInitializer())
predictValueUseListOrder(G.getInitializer(), nullptr, OM, Stack);
for (const GlobalAlias &A : M.aliases())
predictValueUseListOrder(A.getAliasee(), nullptr, OM, Stack);
+ for (const GlobalIFunc &I : M.ifuncs())
+ predictValueUseListOrder(I.getResolver(), nullptr, OM, Stack);
for (const Function &F : M) {
for (const Use &U : F.operands())
predictValueUseListOrder(U.get(), nullptr, OM, Stack);
@@ -298,6 +307,10 @@ ValueEnumerator::ValueEnumerator(const Module &M,
for (const GlobalAlias &GA : M.aliases())
EnumerateValue(&GA);
+ // Enumerate the ifuncs.
+ for (const GlobalIFunc &GIF : M.ifuncs())
+ EnumerateValue(&GIF);
+
// Remember what is the cutoff between globalvalue's and other constants.
unsigned FirstConstant = Values.size();
@@ -310,6 +323,10 @@ ValueEnumerator::ValueEnumerator(const Module &M,
for (const GlobalAlias &GA : M.aliases())
EnumerateValue(GA.getAliasee());
+ // Enumerate the ifunc resolvers.
+ for (const GlobalIFunc &GIF : M.ifuncs())
+ EnumerateValue(GIF.getResolver());
+
// Enumerate any optional Function data.
for (const Function &F : M)
for (const Use &U : F.operands())