Alex Bradbury via llvm-dev
2017-Dec-21 08:32 UTC
[llvm-dev] How to implement lowerReturn for poring GlobalISel to RISCV?
On 21 December 2017 at 05:03, Leslie Zhai <lesliezhai at llvm.org.cn> wrote:> Hi LLVM developers, > > Thank Daniel Sanders, Aditya Nandakumar and Justin Bogner's Tutorial[1]: > Head First into GlobalISel about how to port, and Aditya took BPF target as > a simple instance: > > > bool BPFCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, > const Value *Val, unsigned VReg) const { > assert(!Val == !VReg && "Return value without a vreg"); > MIRBuilder.buildInstr(BPF::RET); > return true; > } > > > But how to implement it for RISCV target? > https://github.com/xiangzhai/llvm/commit/c49146edbbf655e97727e22e4a87a020fb8da6e5 > > Because there are separate trap return instructions[2] per privilege level: > MRET, SRET, and URET. MRET is always provided, while SRET must be provided > if supervisor mode is supported. URET is only provided if user-mode traps > are supported. and David added RISCV privileged instructionsit[3], then > merged into upstream, it might be more complex than ARM[4] please give me > some hint, thanks a lot!Hi Leslie. Although it's useful to think ahead, I'd really recommend to try to incrementally build up support as was done in my RISC-V SelectionDAGISel implementation and the GlobalISel tutorials. An initial milestone might be generating a return from a void function, then a function with a simple addition in its body and so on. The code generator doesn't need to generate MRET/SRET/URET instructions. Typically these will just be used in hand-written assembly (you can find examples of usage in https://github.com/riscv/riscv-pk for instance). It might make sense in the future to define a function attribute for interrupt handlers much like Mips (https://gcc.gnu.org/onlinedocs/gcc/MIPS-Function-Attributes.html), but that would require co-ordination with the GCC developers. So the good news is that return lowering should be much simpler than you're currently thinking. Best, Alex
Leslie Zhai via llvm-dev
2017-Dec-21 09:05 UTC
[llvm-dev] How to implement lowerReturn for poring GlobalISel to RISCV?
Hi Alex, Thanks for your teaching! I only implemented GlobalISel skeleton for RISCV target, built with no errors, is it suitable to review code now as Initial porting or wait for more APIs (for example: lowerReturn, getStackAddress) implemented? I use `a return from a void function` testcase: define void @f() { ret void } $ llc -global-isel -march=riscv32 -stop-after=irtranslator return.ll -o return.mir ... savePoint: '' restorePoint: '' fixedStack: stack: constants: body: | bb.1 (%ir-block.0): MRET ... But I think it is not correct, so please teach me how to implement `return lowering` in a simple way, thanks! PS: as you suggested I built RISCV GNU toolchain using upstream repository: $ /opt/riscv-gnu-git/bin/riscv32-unknown-elf-gcc -O0 -Wall -c return.c -o return-riscv32-gnu.o ^-- return.c is equivalent to above LLVM IR testcase $ /opt/riscv-gnu-git/bin/riscv32-unknown-elf-objdump -d return-riscv32-gnu.o return-riscv32-gnu.o: file format elf32-littleriscv Disassembly of section .text: 00000000 <f>: 0: ff010113 addi sp,sp,-16 4: 00812623 sw s0,12(sp) 8: 01010413 addi s0,sp,16 c: 00000013 nop 10: 00c12403 lw s0,12(sp) 14: 01010113 addi sp,sp,16 18: 00008067 ret And I merged master branch, is it ok? or use other branch? $ /opt/riscv-gnu-git/bin/riscv32-unknown-elf-gcc -v Using built-in specs. COLLECT_GCC=/opt/riscv-gnu-git/bin/riscv32-unknown-elf-gcc COLLECT_LTO_WRAPPER=/opt/riscv-gnu-git/libexec/gcc/riscv32-unknown-elf/8.0.0/lto-wrapper Target: riscv32-unknown-elf Configured with: ../configure --target=riscv32-unknown-elf --enable-languages=c --disable-shared --disable-threads --disable-multilib --disable-gdb --disable-libssp --with-newlib --with-arch=rv32ima --with-abi=ilp32 --prefix=/opt/riscv-gnu-git Thread model: single gcc version 8.0.0 20171215 (experimental) (GCC) 在 2017年12月21日 16:32, Alex Bradbury 写道:> On 21 December 2017 at 05:03, Leslie Zhai <lesliezhai at llvm.org.cn> wrote: >> Hi LLVM developers, >> >> Thank Daniel Sanders, Aditya Nandakumar and Justin Bogner's Tutorial[1]: >> Head First into GlobalISel about how to port, and Aditya took BPF target as >> a simple instance: >> >> >> bool BPFCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, >> const Value *Val, unsigned VReg) const { >> assert(!Val == !VReg && "Return value without a vreg"); >> MIRBuilder.buildInstr(BPF::RET); >> return true; >> } >> >> >> But how to implement it for RISCV target? >> https://github.com/xiangzhai/llvm/commit/c49146edbbf655e97727e22e4a87a020fb8da6e5 >> >> Because there are separate trap return instructions[2] per privilege level: >> MRET, SRET, and URET. MRET is always provided, while SRET must be provided >> if supervisor mode is supported. URET is only provided if user-mode traps >> are supported. and David added RISCV privileged instructionsit[3], then >> merged into upstream, it might be more complex than ARM[4] please give me >> some hint, thanks a lot! > Hi Leslie. Although it's useful to think ahead, I'd really recommend > to try to incrementally build up support as was done in my RISC-V > SelectionDAGISel implementation and the GlobalISel tutorials. An > initial milestone might be generating a return from a void function, > then a function with a simple addition in its body and so on. > > The code generator doesn't need to generate MRET/SRET/URET > instructions. Typically these will just be used in hand-written > assembly (you can find examples of usage in > https://github.com/riscv/riscv-pk for instance). It might make sense > in the future to define a function attribute for interrupt handlers > much like Mips (https://gcc.gnu.org/onlinedocs/gcc/MIPS-Function-Attributes.html), > but that would require co-ordination with the GCC developers. > > So the good news is that return lowering should be much simpler than > you're currently thinking. > > Best, > > Alex-- Regards, Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/
Leslie Zhai via llvm-dev
2017-Dec-21 09:26 UTC
[llvm-dev] How to implement lowerReturn for poring GlobalISel to RISCV?
在 2017年12月21日 16:32, Alex Bradbury 写道:> On 21 December 2017 at 05:03, Leslie Zhai <lesliezhai at llvm.org.cn> wrote: >> Hi LLVM developers, >> >> Thank Daniel Sanders, Aditya Nandakumar and Justin Bogner's Tutorial[1]: >> Head First into GlobalISel about how to port, and Aditya took BPF target as >> a simple instance: >> >> >> bool BPFCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, >> const Value *Val, unsigned VReg) const { >> assert(!Val == !VReg && "Return value without a vreg"); >> MIRBuilder.buildInstr(BPF::RET); >> return true; >> } >> >> >> But how to implement it for RISCV target? >> https://github.com/xiangzhai/llvm/commit/c49146edbbf655e97727e22e4a87a020fb8da6e5 >> >> Because there are separate trap return instructions[2] per privilege level: >> MRET, SRET, and URET. MRET is always provided, while SRET must be provided >> if supervisor mode is supported. URET is only provided if user-mode traps >> are supported. and David added RISCV privileged instructionsit[3], then >> merged into upstream, it might be more complex than ARM[4] please give me >> some hint, thanks a lot! > Hi Leslie. Although it's useful to think ahead, I'd really recommend > to try to incrementally build up support as was done in my RISC-V > SelectionDAGISel implementation and the GlobalISel tutorials. An > initial milestone might be generating a return from a void function, > then a function with a simple addition in its body and so on. > > The code generator doesn't need to generate MRET/SRET/URET > instructions. Typically these will just be used in hand-written > assembly (you can find examples of usage in > https://github.com/riscv/riscv-pk for instance). It might make sense > in the future to define a function attribute for interrupt handlers > much like Mips (https://gcc.gnu.org/onlinedocs/gcc/MIPS-Function-Attributes.html), > but that would require co-ordination with the GCC developers. > > So the good news is that return lowering should be much simpler than > you're currently thinking.Implemented lowerReturn in simple way https://github.com/xiangzhai/llvm/commit/0adf9aa558dd452f8e5bffa3f5b127c58f9d3a43 And compared with GNU toolchain: return-riscv32-gnu.o: file format elf32-littleriscv Disassembly of section .text: 00000000 <f>: 0: ff010113 addi sp,sp,-16 4: 00812623 sw s0,12(sp) 8: 01010413 addi s0,sp,16 c: 00000013 nop 10: 00c12403 lw s0,12(sp) 14: 01010113 addi sp,sp,16 18: 00008067 ret return-riscv32-llvm.o: file format elf32-littleriscv Disassembly of section .text: 00000000 <f>: 0: ff010113 addi sp,sp,-16 4: 00112623 sw ra,12(sp) 8: 00812423 sw s0,8(sp) c: 01010413 addi s0,sp,16 10: 00812403 lw s0,8(sp) 14: 00c12083 lw ra,12(sp) 18: 01010113 addi sp,sp,16 1c: 00008067 ret Thanks for your hint :)> > Best, > > Alex-- Regards, Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/