In this patch, we map mergeable const objects to the read-only section in the same manner as const objects that are not mergeable.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/include/llvm/MC/MCObjectFileInfo.h | ||
---|---|---|
176 ↗ | (On Diff #234065) | Typo: s/pecific/specific/; This comment is misleading though. XCOFF does not define such sections, and the linker does not indicate it has support for the implied merging functionality. |
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | ||
1882 | This code is in an XCOFF-specific function. Is there a case where the pointer remains null? If there is, I suggest to test that case. If there isn't, I suggest to assert that the pointer is non-null instead of doing a null check. This comment also applies to the next handful of lines. | |
1891 | If we believe that there should be special mergeable const sections, then we should assert here that we have handled all mergeable const section variants (in case additional ones are added in the future). | |
llvm/test/CodeGen/PowerPC/aix-xcoff-mergeable-const.ll | ||
2 | Period at the end of the sentence. |
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | ||
---|---|---|
1891 | Questions regarding the design
For the same C source typedef struct { unsigned short id; unsigned char options; } Merge_cnst4; int main() { Merge_cnst4 const cnst4 = { .id = 123}; } Looks like GCC and xlc are able to just store the data member directly without making csects, which is more efficient. I guess clang's FE could generate better IR later to match that? |
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | ||
---|---|---|
1870 | As @jasonliu mentioned, there is not much precedent for this in the context of AIX. What is the rationale for not using the normal read-only data section? | |
1882 | !Kind.isMergeableConst() is always true here now. There should be no need to check that here. | |
llvm/test/CodeGen/PowerPC/aix-xcoff-mergeable-const.ll | ||
2 | This is also testing the object file generation? | |
3 | Should the assembly path be tested for 64-bit as well? | |
4 | Why pwr9? | |
6 | There's two spaces after the colon here (but one space after the colon on the previous lines). | |
13 | The highest-alignment-first ordering here is less interesting than the reverse order in terms of how padding is generated. | |
95 | Shouldn't this be based on Index? |
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | ||
---|---|---|
1870 | I implemented the Mergeable const as gcc did. .csect _mergeableconst.ro_[RO],4 .align 3 cnst32: .long 1073741824 .long 50 .space 24 .globl cnst16 .align 3 cnst16: .long 1073741824 .long 22 .space 8 .globl cnst8 .align 2 cnst8: .long 1073741832 .space 4 .globl cnst4 .align 1 cnst4: .short 16392 .space 2 .csect .text[PR] _section_.text: .csect .data[RW],4 .long _section_.text
.csect cnst32{RO}, 3 .long 0x40000000 # "@\0\0\0" .long 0x00000032 # "\0\0\0002" .long 0x00000000 # "\0\0\0\0" .long 0x00000000 # "\0\0\0\0" .long 0x00000000 # "\0\0\0\0" .long 0x00000000 # "\0\0\0\0" .long 0x00000000 # "\0\0\0\0" .long 0x00000000 # "\0\0\0\0" .csect cnst16{RO}, 3 .long 0x40000000 # "@\0\0\0" .long 0x00000016 # "\0\0\0\026" .long 0x00000000 # "\0\0\0\0" .long 0x00000000 # "\0\0\0\0" .csect cnst8{RO}, 3 .long 0x40000008 # "@\0\0\b" .long 0x00000000 # "\0\0\0\0" .csect cnst4{RO} .long 0x40080000 # "@\b\0\0" | |
1882 | yes, we already deal with Kind.isMergeableConst() before the condition. I will delete it. | |
llvm/test/CodeGen/PowerPC/aix-xcoff-mergeable-const.ll | ||
3 | added | |
4 | changed to pwr4 | |
6 | changed |
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | ||
---|---|---|
1870 | In the assembly you list, the naming of the labels (for the GCC case) or csects (for the XL case) is suspect (they are indicative of declared variables). Declared variables are not mergeable in the general sense. It is observed that GCC on AIX uses .ro and .rw as suffixes for read-only sections; however, the naming does not seem to indicate "mergeable" as a factor. | |
llvm/test/CodeGen/PowerPC/aix-xcoff-mergeable-const.ll | ||
3 | I believe we always use all-caps for XCOFF. |
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | ||
---|---|---|
1870 | yes, you are correct, the for gcc and xlc in the aix , I used the source code as typedef struct { typedef struct { typedef struct { typedef struct { int main() { if I uncomment the int main() { , gcc and xlc will not generate any csect for the cnst32 ,cnst16,cnst8. cnst32 or they also do not put the value in any csect. it put the value in the text asm instruction directly. | |
1870 | and in the linux , the llvm put the mergeabe const in the readonly as .csect .rodata.cst[RO] .align 4 .L__const.main.cnst32: .llong 4611686018427387954 # 0x4000000000000032 .long 0 # 0x0 .space 4 .llong 0 # 0x0 .long 0 # 0x0 .space 4 .align 3 .L__const.main.cnst16: .llong 4611686018427387926 # 0x4000000000000016 .long 0 # 0x0 .space 4 .align 3 .L__const.main.cnst8: .long 1073741832 # 0x40000008 .long 0 # 0x0 .align 3 .L__const.main.cnst4: .short 16392 # 0x4008 .byte 0 # 0x0 .space 1 it also put the merge const in the a new .csect .rodata.cst[RO] . |
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | ||
---|---|---|
1870 | The description of the Linux behaviour seems strange to me. I would expect a .section directive. In any case, it seems we have established that neither XL nor GCC on AIX produce special mergeable-const sections. We should either create the sections as LLVM does for ELF (knowing that it really does not do any merging), or we should just treat the object as being plain read-only). For the strings, we went with the create-like-for-ELF route for now (which has no negative effect that I know of). For the mergeable-const cases, it seems we save on a sizeable amount of code if we just treat them as plain read-only. |
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | ||
---|---|---|
1870 | Sorry. post the wrong information for the linux elf. it should be .type .L__const.main.cnst32,@object # @__const.main.cnst32 .section .rodata.cst32,"aM",@progbits,32 .p2align 4 .L__const.main.cnst32: .long 1073741824 # 0x4000000000000032 .long 50 .long 0 # 0x0 .space 4 .long 0 # 0x0 .long 0 .long 0 # 0x0 .space 4 .size .L__const.main.cnst32, 32 .type .L__const.main.cnst16,@object # @__const.main.cnst16 .section .rodata.cst16,"aM",@progbits,16 .p2align 3 .L__const.main.cnst16: .long 1073741824 # 0x4000000000000016 .long 22 .long 0 # 0x0 .space 4 .size .L__const.main.cnst16, 16 .type .L__const.main.cnst8,@object # @__const.main.cnst8 .section .rodata.cst8,"aM",@progbits,8 .p2align 3 .L__const.main.cnst8: .long 1073741832 # 0x40000008 .long 0 # 0x0 .size .L__const.main.cnst8, 8 .type .L__const.main.cnst4,@object # @__const.main.cnst4 .section .rodata.cst4,"aM",@progbits,4 .p2align 3 .L__const.main.cnst4: .short 16392 # 0x4008 .byte 0 # 0x0 .space 1 .size .L__const.main.cnst4, 4 .section ".note.GNU-stack","",@progbits |
LGTM.
llvm/test/CodeGen/PowerPC/aix-xcoff-mergeable-const.ll | ||
---|---|---|
27 | I can't say that I fully understand the choice of alignment values, but they are reasonable. |
As @jasonliu mentioned, there is not much precedent for this in the context of AIX. What is the rationale for not using the normal read-only data section?