Skip to content

Commit 74bea4c

Browse files
w2yehiaWael Yehia
andauthored
[IR] enable attaching metadata on ifuncs (llvm#158732)
Teach the IR parser and writer to support metadata on ifuncs, and update documentation. In PR llvm#153049, we have a use case of attaching the `!associated` metadata to an ifunc. Since an ifunc is similar to a function declaration, it seems natural to allow metadata on ifuncs. Currently, the metadata API allows adding Metadata to llvm::GlobalObject, so the in-memory IR allows for metadata on ifuncs, but the IR reader/writer is not aware of that. --------- Co-authored-by: Wael Yehia <[email protected]>
1 parent 69465eb commit 74bea4c

File tree

7 files changed

+42
-3
lines changed

7 files changed

+42
-3
lines changed

llvm/docs/LangRef.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,13 +1022,14 @@ On ELF platforms, IFuncs are resolved by the dynamic linker at load time. On
10221022
Mach-O platforms, they are lowered in terms of ``.symbol_resolver`` functions,
10231023
which lazily resolve the callee the first time they are called.
10241024

1025-
IFunc may have an optional :ref:`linkage type <linkage>` and an optional
1026-
:ref:`visibility style <visibility>`.
1025+
IFunc may have an optional :ref:`linkage type <linkage>`, an optional
1026+
:ref:`visibility style <visibility>`, an option partition, and an optional
1027+
list of attached :ref:`metadata <metadata>`.
10271028

10281029
Syntax::
10291030

10301031
@<Name> = [Linkage] [PreemptionSpecifier] [Visibility] ifunc <IFuncTy>, <ResolverTy>* @<Resolver>
1031-
[, partition "name"]
1032+
[, partition "name"] (, !name !N)*
10321033

10331034

10341035
.. _langref_comdats:

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,9 @@ bool LLParser::parseAliasOrIFunc(const std::string &Name, unsigned NameID,
12581258
GV->setPartition(Lex.getStrVal());
12591259
if (parseToken(lltok::StringConstant, "expected partition string"))
12601260
return true;
1261+
} else if (!IsAlias && Lex.getKind() == lltok::MetadataVar) {
1262+
if (parseGlobalObjectMetadataAttachment(*GI.get()))
1263+
return true;
12611264
} else {
12621265
return tokError("unknown alias or ifunc property!");
12631266
}

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2626,6 +2626,9 @@ void ModuleBitcodeWriter::writeModuleMetadata() {
26262626
for (const Function &F : M)
26272627
if (F.isDeclaration() && F.hasMetadata())
26282628
AddDeclAttachedMetadata(F);
2629+
for (const GlobalIFunc &GI : M.ifuncs())
2630+
if (GI.hasMetadata())
2631+
AddDeclAttachedMetadata(GI);
26292632
// FIXME: Only store metadata for declarations here, and move data for global
26302633
// variable definitions to a separate block (PR28134).
26312634
for (const GlobalVariable &GV : M.globals())

llvm/lib/Bitcode/Writer/ValueEnumerator.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,12 @@ ValueEnumerator::ValueEnumerator(const Module &M,
495495
EnumerateMetadata(&F, Op);
496496
}
497497
}
498+
for (const GlobalIFunc &GIF : M.ifuncs()) {
499+
MDs.clear();
500+
GIF.getAllMetadata(MDs);
501+
for (const auto &I : MDs)
502+
EnumerateMetadata(nullptr, I.second);
503+
}
498504

499505
// Optimize constant ordering.
500506
OptimizeConstants(FirstConstant, Values.size());

llvm/lib/IR/AsmWriter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,7 @@ void SlotTracker::processModule() {
10801080
for (const GlobalIFunc &I : TheModule->ifuncs()) {
10811081
if (!I.hasName())
10821082
CreateModuleSlot(&I);
1083+
processGlobalObjectMetadata(I);
10831084
}
10841085

10851086
// Add metadata used by named metadata.
@@ -4079,6 +4080,11 @@ void AssemblyWriter::printIFunc(const GlobalIFunc *GI) {
40794080
printEscapedString(GI->getPartition(), Out);
40804081
Out << '"';
40814082
}
4083+
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
4084+
GI->getAllMetadata(MDs);
4085+
if (!MDs.empty()) {
4086+
printMetadataAttachments(MDs, ", ");
4087+
}
40824088

40834089
printInfoComment(*GI);
40844090
Out << '\n';

llvm/lib/IR/Verifier.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,18 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) {
999999
}
10001000

10011001
void Verifier::visitGlobalIFunc(const GlobalIFunc &GI) {
1002+
visitGlobalValue(GI);
1003+
1004+
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
1005+
GI.getAllMetadata(MDs);
1006+
for (const auto &I : MDs) {
1007+
CheckDI(I.first != LLVMContext::MD_dbg,
1008+
"an ifunc may not have a !dbg attachment", &GI);
1009+
Check(I.first != LLVMContext::MD_prof,
1010+
"an ifunc may not have a !prof attachment", &GI);
1011+
visitMDNode(*I.second, AreDebugLocsAllowed::No);
1012+
}
1013+
10021014
Check(GlobalIFunc::isValidLinkage(GI.getLinkage()),
10031015
"IFunc should have private, internal, linkonce, weak, linkonce_odr, "
10041016
"weak_odr, or external linkage!",

llvm/test/Assembler/metadata.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
; CHECK-UNMAT: @global = global i32 0, !foo [[M2:![0-9]+]], !foo [[M3:![0-9]+]], !baz [[M3]]
66
@global = global i32 0, !foo !2, !foo !3, !baz !3
77

8+
; CHECK-UNMAT: @ifunc_func = ifunc void (...), ptr @resolver, !foo [[M2]]
9+
@ifunc_func = ifunc void (...), ptr @resolver, !foo !2
10+
11+
define internal ptr @resolver() {
12+
entry:
13+
ret ptr @test
14+
}
15+
816
; CHECK-LABEL: @test
917
; CHECK: ret void, !foo [[M0:![0-9]+]], !bar [[M1:![0-9]+]]
1018
define void @test() !dbg !1 {

0 commit comments

Comments
 (0)