Go to file
2024-03-05 08:33:42 -05:00
.github/workflows Format the code 2024-02-28 17:49:16 -05:00
build_sysroot Remove unused build_sysroot.sh file 2023-12-20 14:47:42 +01:00
build_system Add documentation on git_clone_root_dir 2024-02-27 18:48:29 +01:00
deps Workaround for linker error about missing -lLLVM-18-rust-1.78.0-nightly 2024-03-05 08:23:27 -05:00
doc Split Readme even further 2024-02-17 17:58:29 +01:00
example Improve wording of static_mut_ref 2024-02-18 06:01:40 +03:00
patches Fix tests 2024-02-20 12:02:09 -05:00
src Fix formatting 2024-03-05 08:33:42 -05:00
tests Merge pull request #459 from tempdragon/master 2024-03-04 08:07:26 -05:00
tools Display run commands when using llvm-tblgen 2023-08-16 13:54:10 +02:00
.gitignore Remove paths that don't exist anymore from file 2024-02-14 15:11:34 +01:00
.ignore Implement dummy emit=llvm-ir 2024-02-14 09:38:56 -05:00
.rustfmt.toml Format the code 2024-02-28 17:49:16 -05:00
build.rs Workaround for linker error about missing -lLLVM-18-rust-1.78.0-nightly 2024-03-05 08:23:27 -05:00
Cargo.lock Update lang_tester so that panicking in a test results in the test failing 2024-03-01 17:28:57 -05:00
Cargo.toml Update lang_tester so that panicking in a test results in the test failing 2024-03-01 17:28:57 -05:00
config.example.toml Switch to config.toml instead of gcc-path 2024-02-11 21:53:56 +01:00
libgccjit.version Switch to the new set_special_chars_allowed_in_func_names API 2024-03-01 12:21:31 -05:00
LICENSE-APACHE Initial commit 2021-08-12 21:46:50 -04:00
LICENSE-MIT Initial commit 2021-08-12 21:46:50 -04:00
messages.ftl Remove unused fluent messages 2024-03-01 09:50:33 +08:00
Readme.md Split Readme even further 2024-02-17 17:58:29 +01:00
rust-toolchain Merge branch 'master' into sync_from_rust_2024_03_04 2024-03-05 08:21:27 -05:00
y.sh Correctly take into account potential position of cargo command in y.sh 2023-12-23 00:13:09 +01:00

WIP libgccjit codegen backend for rust

Chat on IRC Chat on Matrix

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. You need to use my fork of gcc which already includes these patches.

$ 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.

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/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:

--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 --release

To run the tests:

$ ./y.sh test --release

Usage

$CG_GCCJIT_DIR is the directory you cloned this repo into in the following instructions:

export CG_GCCJIT_DIR=[the full path to rustc_codegen_gcc]

Cargo

$ 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.

LTO

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.

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)

Rustc

You should prefer using the Cargo method.

$ 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

Env vars

CG_GCCJIT_INCR_CACHE_DISABLED
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.
CG_GCCJIT_DISPLAY_CG_TIME
Display the time it took to perform codegen for a crate
CG_RUSTFLAGS
Send additional flags to rustc. Can be used to build the sysroot without unwinding by setting `CG_RUSTFLAGS=-Cpanic=abort`.
CG_GCCJIT_DUMP_TO_FILE
Dump a C-like representation to /tmp/gccjit_dumps and enable debug info in order to debug this C-like representation.

Extra documentation

More specific documentation is available in the doc folder:

Licensing

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.