-
Notifications
You must be signed in to change notification settings - Fork 15.3k
XCOFF associated metadata #159096
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
XCOFF associated metadata #159096
Changes from all commits
84383e7
1885813
dc7b01a
6e570a5
fbdc254
7196fc4
26a6684
3617a36
c574fb2
e78226e
325741a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -769,6 +769,31 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) { | |
| DL.getIntPtrType(GO->getType()), | ||
| RangeLikeMetadataKind::AbsoluteSymbol); | ||
| } | ||
|
|
||
| if (GO->hasMetadata(LLVMContext::MD_implicit_ref)) { | ||
| Check(!GO->isDeclaration(), | ||
| "ref metadata must not be placed on a declaration", GO); | ||
|
|
||
| SmallVector<MDNode *> MDs; | ||
| GO->getMetadata(LLVMContext::MD_implicit_ref, MDs); | ||
| for (const MDNode *MD : MDs) { | ||
| Check(MD->getNumOperands() == 1, "ref metadata must have one operand", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since we're allowed to have multiple rather than https://llvm.org/docs/LangRef.html#callees-metadata does that.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One difference with the callees metadata though is it is added in one place and never modified afterwards. For this metadata it is possible you could have 2 different features that require implicit references to be added. In that case would you have to get the existing array of refs, duplicate and append to it, then create a new metadata node with that array? Or are you suggesting we support both arrays of refs, and multiple individual refs as well? I'm not sure I'm particularly fond of either approach.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
yes you cannot mutate an existing node, so you'll have to create a new one, but that's not too much work as we constantly create new IR and throw old one in LLVM, and it will not happen often.
No, not both because that would complicate the handling on the consumer side. |
||
| &GV, MD); | ||
| const Metadata *Op = MD->getOperand(0).get(); | ||
| const auto *VM = dyn_cast_or_null<ValueAsMetadata>(Op); | ||
| Check(VM, "ref metadata must be ValueAsMetadata", GO, MD); | ||
| if (VM) { | ||
| Check(isa<PointerType>(VM->getValue()->getType()), | ||
| "ref value must be pointer typed", GV, MD); | ||
|
|
||
| const Value *Stripped = VM->getValue()->stripPointerCastsAndAliases(); | ||
| Check(isa<GlobalObject>(Stripped) || isa<Constant>(Stripped), | ||
| "ref metadata must point to a GlobalObject", GO, Stripped); | ||
| Check(Stripped != GO, "values should not reference themselves", GO, | ||
| MD); | ||
| } | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LangRef says the metadata can only be applied to a definition. If that's correct, the verifier should be enforcing it as well. |
||
| } | ||
|
|
||
| Check(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| ; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s | \ | ||
| ; RUN: FileCheck %s -check-prefixes=NOFSECTS,CHECK | ||
|
|
||
| ; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff --function-sections < %s | \ | ||
| ; RUN: FileCheck %s -check-prefixes=FSECTS,CHECK | ||
|
|
||
| ; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -filetype=obj -o %t.o < %s | ||
| ; RUN: llvm-objdump -D -r --symbol-description %t.o | FileCheck -check-prefix=OBJ %s | ||
|
|
||
| ; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff --function-sections -filetype=obj -o %t.o < %s | ||
| ; RUN: llvm-objdump -D -r --symbol-description %t.o | FileCheck -check-prefix=FSECTOBJ %s | ||
|
|
||
| @a = global i32 1 | ||
| @b = global i32 2 | ||
| @c = global i32 3 | ||
|
|
||
| define i32 @foo() !implicit.ref !0 { | ||
| ret i32 0 | ||
| } | ||
|
|
||
| define i32 @bar() !implicit.ref !1 !implicit.ref !2 { | ||
| ret i32 0 | ||
| } | ||
|
|
||
| !0 = !{ptr @a} | ||
| !1 = !{ptr @b} | ||
| !2 = !{ptr @c} | ||
|
|
||
| ; NOFSECTS: .foo: | ||
| ; FSECTS: .csect .foo[PR] | ||
| ; CHECK: .ref a[RW] | ||
|
|
||
| ; NOFSECTS: .bar: | ||
| ; FSECTS: .csect .bar[PR] | ||
| ; CHECK: .ref b[RW] | ||
| ; CHECK: .ref c[RW] | ||
|
|
||
| ; OBJ: Disassembly of section .text: | ||
| ; OBJ: .foo: | ||
| ; OBJ: li 3, 0 | ||
| ; OBJ: R_REF {{.*}} a[RW] | ||
| ; OBJ: R_REF {{.*}} b[RW] | ||
| ; OBJ: R_REF {{.*}} c[RW] | ||
| ; OBJ: blr | ||
| ; OBJ: .bar | ||
|
|
||
| ; FSECTOBJ: .foo[PR]: | ||
| ; FSECTOBJ: li 3, 0 | ||
| ; FSECTOBJ: R_REF {{.*}} a[RW] | ||
| ; FSECTOBJ: blr | ||
| ; FSECTOBJ: .bar[PR]: | ||
| ; FSECTOBJ: li 3, 0 | ||
| ; FSECTOBJ: R_REF {{.*}} b[RW] | ||
| ; FSECTOBJ: R_REF {{.*}} c[RW] | ||
| ; FSECTOBJ: blr |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| ; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we test -fno-data-sections?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need a test for the object file output
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if this MD is to apply to functions and ifuncs, then will need tests for functions now, and I can add ifuncs tests as part of my ifuncs PR. Note: When working on the ifunc PR I encountered an issue (that I'm yet to fix) with -fno-functions-sections -fintegrated-as when emiting
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added textual assembly testing and started working on adding the matching object generation tests. Do you know if the out of order relocations in an issue for function as well?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
yes, if you generate a The bug in the object gen is that it puts the relocation at the start of whatever csect the function is in, instead of (I imagine) the current offset. You can probably reproduce with -ffunction-sections if you call emitXCOFFRefDirective while in the middle of a function body generation, and there's been prior relocations emitted in that function. |
||
| ; RUN: llc -data-sections=false -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck -check-prefix=NODATA %s | ||
|
|
||
| ; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -filetype=obj -o %t.o < %s | ||
| ; RUN: llvm-objdump -D -r --symbol-description %t.o | FileCheck -check-prefix=OBJ %s | ||
|
|
||
| ; RUN: llc -data-sections=false -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -filetype=obj -o %t.o < %s | ||
| ; RUN: llvm-objdump -D -r --symbol-description %t.o | FileCheck -check-prefix=OBJ-NODATA %s | ||
|
|
||
| @a = global i32 1 | ||
| @b = global i32 2 | ||
| @c = global i32 3, section "custom_section_c" | ||
| @d = global i32 4, !implicit.ref !0 | ||
| @e = constant i32 5, !implicit.ref !1, !implicit.ref!2 | ||
| @f = global i32 6, section "custom_section_f", !implicit.ref !1 | ||
|
|
||
|
|
||
| !0 = !{ptr @a} | ||
| !1 = !{ptr @b} | ||
| !2 = !{ptr @c} | ||
|
|
||
| ; CHECK: .csect d[RW] | ||
| ; CHECK: .ref a[RW] | ||
|
|
||
| ; CHECK: .csect e[RO] | ||
| ; CHECK: .ref b[RW] | ||
| ; CHECK: .ref c | ||
|
|
||
| ; CHECK: .csect custom_section_f[RW] | ||
| ; CHECK: .ref b[RW] | ||
|
|
||
| ; NODATA: .csect .data[RW] | ||
| ; NODATA-NOT: .csect | ||
| ; NODATA: .globl a | ||
| ; NODATA-NOT: .csect | ||
| ; NODATA: .globl b | ||
| ; NODATA: .csect custom_section_c[RW] | ||
| ; NODATA: .globl c | ||
| ; NODATA: .csect .data[RW] | ||
| ; NODATA: .ref a | ||
| ; NODATA: .globl d | ||
| ; NODATA: .csect .rodata[RO] | ||
| ; NODATA: .ref b | ||
| ; NODATA: .ref c | ||
| ; NODATA: .globl e | ||
| ; NODATA: .csect custom_section_f[RW] | ||
| ; NODATA: .ref b | ||
| ; NODATA: .globl f | ||
|
|
||
| ; OBJ: Disassembly of section .text: | ||
|
|
||
| ; OBJ: e[RO]: | ||
| ; OBJ: R_REF {{.*}} b[RW] | ||
| ; OBJ: R_REF {{.*}} c | ||
|
|
||
| ; OBJ: Disassembly of section .data: | ||
| ; OBJ: a[RW]: | ||
| ; OBJ: b[RW]: | ||
| ; OBJ: c: | ||
| ; OBJ: d[RW]: | ||
| ; OBJ: R_REF {{.*}} a[RW] | ||
| ; OBJ: f: | ||
| ; OBJ: R_REF {{.*}} b[RW] | ||
|
|
||
| ; OBJ-NODATA: Disassembly of section .text: | ||
| ; OBJ-NODATA: e: | ||
| ; OBJ-NODATA: R_REF {{.*}} b | ||
| ; OBJ-NODATA: R_REF {{.*}} c | ||
|
|
||
| ; OBJ-NODATA: Disassembly of section .data: | ||
| ; OBJ-NODATA: a: | ||
| ; OBJ-NODATA: R_REF {{.*}} a | ||
| ; OBJ-NODATA: b: | ||
| ; OBJ-NODATA: d: | ||
| ; OBJ-NODATA: c: | ||
| ; OBJ-NODATA: f: | ||
| ; OBJ-NODATA: R_REF {{.*}} b | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| ; RUN: opt -passes="ipsccp<func-spec>" -S -force-specialization < %s 2>&1 | FileCheck %s | ||
|
|
||
| @a = global i32 1 | ||
|
|
||
| define i64 @main(i64 %x, i1 %flag) { | ||
| entry: | ||
| br i1 %flag, label %plus, label %minus | ||
|
|
||
| plus: | ||
| %tmp0 = call i64 @compute(i64 %x, ptr @plus) | ||
| br label %merge | ||
|
|
||
| minus: | ||
| %tmp1 = call i64 @compute(i64 %x, ptr @minus) | ||
| br label %merge | ||
|
|
||
| merge: | ||
| %tmp2 = phi i64 [ %tmp0, %plus ], [ %tmp1, %minus] | ||
| ret i64 %tmp2 | ||
| } | ||
|
|
||
| define internal i64 @compute(i64 %x, ptr %binop) !implicit.ref !0 { | ||
| entry: | ||
| %tmp0 = call i64 %binop(i64 %x) | ||
| ret i64 %tmp0 | ||
| } | ||
|
|
||
| define internal i64 @plus(i64 %x) { | ||
| entry: | ||
| %tmp0 = add i64 %x, 1 | ||
| ret i64 %tmp0 | ||
| } | ||
|
|
||
| define internal i64 @minus(i64 %x) { | ||
| entry: | ||
| %tmp0 = sub i64 %x, 1 | ||
| ret i64 %tmp0 | ||
| } | ||
|
|
||
| !0 = !{ptr @a} | ||
|
|
||
| ; CHECK: @compute.specialized.1(i64 %x, ptr %binop) !implicit.ref !0 | ||
| ; CHECK: @compute.specialized.2(i64 %x, ptr %binop) !implicit.ref !0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| ; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s | ||
|
|
||
| @a = global i32 1 | ||
| @b = global i32 2 | ||
| @c = global double 3.141593e+00 | ||
|
|
||
| define i32 @callee1() !implicit.ref !0 { | ||
| ret i32 0 | ||
| } | ||
|
|
||
| define i32 @callee2() !implicit.ref !1 { | ||
| ret i32 1 | ||
| } | ||
|
|
||
| define i32 @callee3() { | ||
| %i = call i32 @callee2() | ||
| ret i32 %i | ||
| } | ||
| ; CHECK: @callee3() !implicit.ref !1 | ||
|
|
||
| define i32 @caller1() { | ||
| %i = call i32 @callee1() | ||
| ret i32 %i | ||
| } | ||
| ; CHECK: @caller1() !implicit.ref !0 | ||
|
|
||
| define i32 @caller2() !implicit.ref !2 { | ||
| %i = call i32 @callee1() | ||
| ret i32 %i | ||
| } | ||
| ; CHECK: @caller2() !implicit.ref !2 !implicit.ref !0 | ||
|
|
||
| define i32 @caller3() { | ||
| %i = call i32 @caller4() | ||
| ret i32 %i | ||
| } | ||
| ; CHECK: @caller3() !implicit.ref !0 !implicit.ref !1 | ||
|
|
||
| define i32 @caller4() { | ||
| %a = call i32 @callee1() | ||
| %b = call i32 @callee2() | ||
| %add = add i32 %a, %b | ||
| ret i32 %add | ||
| } | ||
| ; CHECK: @caller4() !implicit.ref !0 !implicit.ref !1 | ||
|
|
||
| !0 = !{ptr @a} | ||
| !1 = !{ptr @b} | ||
| !2 = !{ptr @c} | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| ; RUN: llvm-as < %s -o /dev/null 2>&1 | ||
|
|
||
| @a = global i32 1 | ||
| @b = global i32 2 | ||
| @c = global i32 3, !implicit.ref !0 | ||
|
|
||
| define i32 @foo() !implicit.ref !1 { | ||
| ret i32 0 | ||
| } | ||
|
|
||
| !0 = !{ptr @a} | ||
| !1 = !{ptr @b} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the metadata propagated from an inlined callee to a caller? Is there a test for that?