2020-05-10 09:54:30 -05:00
# WIP libgccjit codegen backend for rust
2023-03-05 11:03:19 -06:00
[![Chat on IRC ](https://img.shields.io/badge/irc.libera.chat-%23rustc__codegen__gcc-blue.svg )](https://web.libera.chat/#rustc_codegen_gcc)
2023-10-09 14:53:34 -05:00
[![Chat on Matrix ](https://img.shields.io/badge/matrix.org-%23rustc__codegen__gcc-blue.svg )](https://matrix.to/#/#rustc_codegen_gcc:matrix.org)
2023-03-05 11:03:19 -06:00
2020-05-10 09:54:30 -05:00
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.**
## Motivation
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.
## Building
**This requires a patched libgccjit in order to work.
2023-10-09 14:53:34 -05:00
You need to use my [fork of gcc ](https://github.com/antoyo/gcc ) which already includes these patches.**
2020-05-10 09:54:30 -05:00
2024-02-17 10:04:32 -06:00
```bash
$ cp config.example.toml config.toml
```
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.
### Building with your own GCC version
If you wrote a patch for GCC and want to test it without this backend, you will need
to do a few more things.
2023-03-05 11:03:19 -06:00
To build it (most of these instructions come from [here ](https://gcc.gnu.org/onlinedocs/jit/internals/index.html ), so don't hesitate to take a look there if you encounter an issue):
```bash
$ git clone https://github.com/antoyo/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` :
```bash
--enable-languages=jit,c++
```
Then to run libgccjit tests:
```bash
$ 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"
```
2024-02-09 08:26:44 -06:00
**Put the path to your custom build of libgccjit in the file `config.toml` .**
2024-02-17 10:04:32 -06:00
You now need to set the `gcc-path` value in `config.toml` with the result of this command:
2024-02-09 08:26:44 -06:00
```bash
2024-02-17 10:04:32 -06:00
$ dirname $(readlink -f `find . -name libgccjit.so` )
2024-02-09 08:26:44 -06:00
```
2024-02-17 10:04:32 -06:00
and to comment the `download-gccjit` setting:
2020-05-10 09:54:30 -05:00
2024-02-17 10:04:32 -06:00
```toml
gcc-path = "[MY PATH]"
# download-gccjit = true
2023-03-05 11:03:19 -06:00
```
Then you can run commands like this:
2020-05-10 09:54:30 -05:00
```bash
2023-10-09 14:53:34 -05:00
$ ./y.sh prepare # download and patch sysroot src and install hyperfine for benchmarking
2024-02-15 05:30:43 -06:00
$ ./y.sh build --release
2023-03-05 11:03:19 -06:00
```
To run the tests:
```bash
2024-02-15 05:30:43 -06:00
$ ./y.sh test --release
2020-05-10 09:54:30 -05:00
```
## Usage
2023-10-09 14:53:34 -05:00
`$CG_GCCJIT_DIR` is the directory you cloned this repo into in the following instructions:
```bash
export CG_GCCJIT_DIR=[the full path to rustc_codegen_gcc]
```
2020-05-10 09:54:30 -05:00
### Cargo
```bash
2023-12-21 16:46:41 -06:00
$ CHANNEL="release" $CG_GCCJIT_DIR/y.sh cargo run
2020-05-10 09:54:30 -05:00
```
2023-11-16 15:51:51 -06:00
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.
2020-05-10 09:54:30 -05:00
2023-10-26 16:42:02 -05:00
### LTO
2023-10-09 14:53:34 -05:00
To use LTO, you need to set the variable `FAT_LTO=1` and `EMBED_LTO_BITCODE=1` in addition to setting `lto = "fat"` in the `Cargo.toml` .
Don't set `FAT_LTO` when compiling the sysroot, though: only set `EMBED_LTO_BITCODE=1` .
2023-10-26 16:42:02 -05:00
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)
```
2020-05-10 09:54:30 -05:00
### Rustc
2024-04-05 10:35:41 -05:00
If you want to run `rustc` directly, you can do so with:
```bash
$ ./y.sh rustc my_crate.rs
```
You can do the same manually (although we don't recommend it):
2020-05-10 09:54:30 -05:00
```bash
2024-02-09 08:26:44 -06:00
$ 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
2020-05-10 09:54:30 -05:00
```
## Env vars
< dl >
< dt > CG_GCCJIT_INCR_CACHE_DISABLED< / dt >
< dd > Don't cache object files in the incremental cache. Useful during development of cg_gccjit
to make it possible to use incremental mode for all analyses performed by rustc without caching
object files when their content should have been changed by a change to cg_gccjit.< / dd >
< dt > CG_GCCJIT_DISPLAY_CG_TIME< / dt >
< dd > Display the time it took to perform codegen for a crate< / dd >
2023-10-09 14:53:34 -05:00
< dt > CG_RUSTFLAGS< / dt >
< dd > Send additional flags to rustc. Can be used to build the sysroot without unwinding by setting `CG_RUSTFLAGS=-Cpanic=abort` .</ dd >
< dt > CG_GCCJIT_DUMP_TO_FILE< / dt >
< dd > Dump a C-like representation to /tmp/gccjit_dumps and enable debug info in order to debug this C-like representation.< / dd >
2020-05-10 09:54:30 -05:00
< / dl >
2024-02-17 10:13:48 -06:00
## Extra documentation
2023-10-09 14:53:34 -05:00
2024-02-17 10:13:48 -06:00
More specific documentation is available in the [`doc` ](./doc ) folder:
2023-10-09 14:53:34 -05:00
2024-02-17 10:13:48 -06:00
* [Common errors ](./doc/errors.md )
* [Debugging GCC LTO ](./doc/debugging-gcc-lto.md )
* [Debugging libgccjit ](./doc/debugging-libgccjit.md )
* [Git subtree sync ](./doc/subtree.md )
* [List of useful commands ](./doc/tips.md )
* [Send a patch to GCC ](./doc/sending-gcc-patch.md )
2023-10-09 14:53:34 -05:00
2024-02-17 10:13:48 -06:00
## Licensing
2023-10-26 16:42:02 -05:00
2024-02-17 10:13:48 -06:00
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.
2023-10-26 16:42:02 -05:00
2024-02-17 10:13:48 -06:00
However, programs compiled with `rustc_codegen_gcc` do not need to be released under a GPL license.