llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.8k stars 11.45k forks source link

[PowerPC] [LLD][Compiler] support tail call across modules for ELFv2 #98859

Open chenzheng1030 opened 1 month ago

chenzheng1030 commented 1 month ago

This is from https://github.com/llvm/llvm-project/issues/63214#issuecomment-2128605743 and https://github.com/llvm/llvm-project/issues/63214#issuecomment-2128669372

For ELFv2, tail call optimization should be allowed even across modules. The idea is: (Function A and function B share the TOC; B calls function C which does not share TOC with B.)

1: Changes in the compiler side:

2: Changes in the lld linker side:

llvmbot commented 1 month ago

@llvm/issue-subscribers-backend-powerpc

Author: Chen Zheng (chenzheng1030)

This is from https://github.com/llvm/llvm-project/issues/63214#issuecomment-2128605743 and https://github.com/llvm/llvm-project/issues/63214#issuecomment-2128669372 For ELFv2, tail call optimization should be allowed even across modules. The idea is: (Function A and function B share the TOC; B calls function C which does not share TOC with B.) 1: Changes in the compiler side: - For the call between A and B, use the `st_other === 1` feature to let linker know that when B is called, the caller A needs to restore the TOC although they share the TOC. - From ABI: for `st_other == 1`: The local and global entry points are the same, and r2 should be treated as caller-saved for local and global callers." - inside the compiler, for the call between A and B, we should not use `PPCISD::CALL`, instead `PPCISD::CALL_NOP` should be used to allow the tail call. - B should set `st_other` to 1 - For the tail call between A and B, use the tail call opcode 2: Changes in the lld linker side: - no need for the `nop` after `b` even for the b cross the modules. For now, linker will report an error `call to bar lacks nop, can't restore toc`, see https://github.com/llvm/llvm-project/issues/63214#issuecomment-2217053717 and https://github.com/llvm/llvm-project/issues/63214#issuecomment-2219264350
llvmbot commented 1 month ago

@llvm/issue-subscribers-lld-elf

Author: Chen Zheng (chenzheng1030)

This is from https://github.com/llvm/llvm-project/issues/63214#issuecomment-2128605743 and https://github.com/llvm/llvm-project/issues/63214#issuecomment-2128669372 For ELFv2, tail call optimization should be allowed even across modules. The idea is: (Function A and function B share the TOC; B calls function C which does not share TOC with B.) 1: Changes in the compiler side: - For the call between A and B, use the `st_other === 1` feature to let linker know that when B is called, the caller A needs to restore the TOC although they share the TOC. - From ABI: for `st_other == 1`: The local and global entry points are the same, and r2 should be treated as caller-saved for local and global callers." - inside the compiler, for the call between A and B, we should not use `PPCISD::CALL`, instead `PPCISD::CALL_NOP` should be used to allow the tail call. - B should set `st_other` to 1 - For the tail call between A and B, use the tail call opcode 2: Changes in the lld linker side: - no need for the `nop` after `b` even for the b cross the modules. For now, linker will report an error `call to bar lacks nop, can't restore toc`, see https://github.com/llvm/llvm-project/issues/63214#issuecomment-2217053717 and https://github.com/llvm/llvm-project/issues/63214#issuecomment-2219264350
nemanjai commented 1 month ago

Since we have no control over the GNU and Gold linkers, I think it would be good if you open a bugzilla for those linkers to not complain about the missing nop for the st_other == 1 case since the TOC does not need to be restored. For LLD, we can just implement the necessary change. As you mentioned in your description, the compiler should conservatively emit the nop to appease the linker even though it isn't needed. If we really want to allow the user to avoid the nop, we can implement an option in the compiler to tell it not to emit them - name it something like -mno-ppc-tail-nop.

tpearson-ssc commented 2 weeks ago

Following this with some interest, tired of having to hack up Chromium to get it building on ppc64el (POWER8+, ELF ABI v2 only) :wink: