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/Bitcode/Writer | |
| 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/Bitcode/Writer')
| -rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 17 |
2 files changed, 29 insertions, 0 deletions
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index cbaaea8bbc6..23cd0888726 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -809,6 +809,18 @@ static uint64_t WriteModuleInfo(const Module *M, const ValueEnumerator &VE, Vals.clear(); } + // Emit the ifunc information. + for (const GlobalIFunc &I : M->ifuncs()) { + // IFUNC: [ifunc type, address space, resolver val#, linkage, visibility] + Vals.push_back(VE.getTypeID(I.getValueType())); + Vals.push_back(I.getType()->getAddressSpace()); + Vals.push_back(VE.getValueID(I.getResolver())); + Vals.push_back(getEncodedLinkage(I)); + Vals.push_back(getEncodedVisibility(I)); + Stream.EmitRecord(bitc::MODULE_CODE_IFUNC, Vals); + Vals.clear(); + } + // Emit the module's source file name. { StringEncoding Bits = getStringEncoding(M->getSourceFileName().data(), diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 91b523f05bc..ff87052c4ef 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()) |

