| commit | d2ade4e2440f87b03882074c9aebe75da9840f4c | [log] [tgz] |
|---|---|---|
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | Wed Oct 15 07:09:54 2025 +0200 |
| committer | GitHub <noreply@github.com> | Wed Oct 15 07:09:54 2025 +0200 |
| tree | 219bd1d8c71b9e1ea8a1fdcaab22871b9393ce82 | |
| parent | 5f0d88ffcf4c97c062746e2c4dc4e68d5eab9cbc [diff] | |
| parent | d96167fc9a3e8e412b9933f423ab993336e7ee85 [diff] |
Rollup merge of #146949 - pmur:murp/improve-ppc-inline-asm, r=Amanieu Add vsx register support for ppc inline asm, and implement preserves_flag option This should address the last(?) missing pieces of inline asm for ppc: * Explicit VSX register support. ISA 2.06 (POWER7) added a 64x128b register overlay extending the fpr's to 128b, and unifies them with the vmx (altivec) registers. Implementations details within gcc/llvm percolate up, and require using the `x` template modifier. I have updated the inline asm to implicitly include this for vsx arguments which do not specify it. ~~Support for the gcc codegen backend is still a todo.~~ * Implement the `preserves_flags` option. All ABI's, and all ISAs store their flags in `cr`, and the carry bit lives inside `xer`. The other status registers hold sticky bits or control bits which do not affect branch instructions. There is some interest in the e500 (powerpcspe) port. Architecturally, it has a very different FP ISA, and includes a simd extension called SPR (which is not IBM's cell SPE). Notably, it does not have altivec/fpr/vsx registers. It also has an SPE accumulator register which its ABI marks as volatile, but I am not sure if the compiler uses it.
This is a GCC codegen for rustc, which means it can be loaded by the existing rustc frontend, but benefits from GCC: more architectures are supported and GCC's optimizations are used.
Despite its name, libgccjit can be used for ahead-of-time compilation, as is used here.
The primary goal of this project is to be able to compile Rust code on platforms unsupported by LLVM. A secondary goal is to check if using the gcc backend will provide any run-time speed improvement for the programs compiled using rustc.
Note: This requires a patched libgccjit in order to work. You need to use my fork of gcc which already includes these patches. The default configuration (see below in the Quick start section) will download a libgccjit built in the CI that already contains these patches, so you don't need to build this fork yourself if you use the default configuration.
flex, libmpfr-dev, libgmp-dev, libmpc3, libmpc-devClone and configure the repository:
git clone https://github.com/rust-lang/rustc_codegen_gcc cd rustc_codegen_gcc cp config.example.toml config.toml
Build and test:
./y.sh prepare # downloads and patches sysroot ./y.sh build --sysroot --release # Verify setup with a simple test ./y.sh cargo build --manifest-path tests/hello-world/Cargo.toml # Run full test suite (expect ~100 failing UI tests) ./y.sh test --release
If don't need to test GCC patches you wrote in our GCC fork, then the default configuration should be all you need. You can update the rustc_codegen_gcc without worrying about GCC.
If you wrote a patch for GCC and want to test it without this backend, you will need to do a few more things.
To build it (most of these instructions come from here, so don't hesitate to take a look there if you encounter an issue):
$ git clone https://github.com/rust-lang/gcc $ sudo apt install flex libmpfr-dev libgmp-dev libmpc3 libmpc-dev $ mkdir gcc-build gcc-install $ cd gcc-build $ ../gcc/configure \ --enable-host-shared \ --enable-languages=jit \ --enable-checking=release \ # it enables extra checks which allow to find bugs --disable-bootstrap \ --disable-multilib \ --prefix=$(pwd)/../gcc-install $ make -j4 # You can replace `4` with another number depending on how many cores you have.
If you want to run libgccjit tests, you will need to also enable the C++ language in the configure:
--enable-languages=jit,c++
Then to run libgccjit tests:
$ cd gcc # from the `gcc-build` folder $ make check-jit # To run one specific test: $ make check-jit RUNTESTFLAGS="-v -v -v jit.exp=jit.dg/test-asm.cc"
Put the path to your custom build of libgccjit in the file config.toml.
You now need to set the gcc-path value in config.toml with the result of this command:
$ dirname $(readlink -f `find . -name libgccjit.so`)
and to comment the download-gccjit setting:
gcc-path = "[MY PATH]" # download-gccjit = true
Then you can run commands like this:
$ ./y.sh prepare # download and patch sysroot src and install hyperfine for benchmarking $ ./y.sh build --sysroot --release
To run the tests:
$ ./y.sh test --release
You have to run these commands, in the corresponding order:
$ ./y.sh prepare $ ./y.sh build --sysroot
To check if all is working correctly, run:
$ ./y.sh cargo build --manifest-path tests/hello-world/Cargo.toml
$ CHANNEL="release" $CG_GCCJIT_DIR/y.sh cargo run
If you compiled cg_gccjit in debug mode (aka you didn't pass --release to ./y.sh test) you should use CHANNEL="debug" instead or omit CHANNEL="release" completely.
To use LTO, you need to set the variable EMBED_LTO_BITCODE=1 in addition to setting lto = "fat" in the Cargo.toml.
Failing to set EMBED_LTO_BITCODE will give you the following error:
error: failed to copy bitcode to object file: No such file or directory (os error 2)
If you want to run rustc directly, you can do so with:
$ ./y.sh rustc my_crate.rs
You can do the same manually (although we don't recommend it):
$ LIBRARY_PATH="[gcc-path value]" LD_LIBRARY_PATH="[gcc-path value]" rustc +$(cat $CG_GCCJIT_DIR/rust-toolchain | grep 'channel' | cut -d '=' -f 2 | sed 's/"//g' | sed 's/ //g') -Cpanic=abort -Zcodegen-backend=$CG_GCCJIT_DIR/target/release/librustc_codegen_gcc.so --sysroot $CG_GCCJIT_DIR/build_sysroot/sysroot my_crate.rs
/tmp/reproducers/.CG_GCCJIT_DUMP_MODULE=module_name, a dump of that specific module is created in /tmp/reproducers/.CG_RUSTFLAGS=-Cpanic=abort.More specific documentation is available in the doc folder:
While this crate is licensed under a dual Apache/MIT license, it links to libgccjit which is under the GPLv3+ and thus, the resulting toolchain (rustc + GCC codegen) will need to be released under the GPL license.
However, programs compiled with rustc_codegen_gcc do not need to be released under a GPL license.