• Stars
    star
    875
  • Rank 52,157 (Top 2 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created over 4 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

libgccjit AOT codegen for rustc

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.

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

$ dirname $(readlink -f `find . -name libgccjit.so`) > gcc_path

You also need to set RUST_COMPILER_RT_ROOT:

$ git clone https://github.com/llvm/llvm-project llvm --depth 1 --single-branch
$ export RUST_COMPILER_RT_ROOT="$PWD/llvm/compiler-rt"

Then you can run commands like this:

$ ./prepare.sh # download and patch sysroot src and install hyperfine for benchmarking
$ LIBRARY_PATH=$(cat gcc_path) LD_LIBRARY_PATH=$(cat gcc_path) ./build.sh --release

To run the tests:

$ ./test.sh --release

Usage

$cg_gccjit_dir is the directory you cloned this repo into in the following instructions.

Cargo

$ CHANNEL="release" $cg_gccjit_dir/cargo.sh run

If you compiled cg_gccjit in debug mode (aka you didn't pass --release to ./test.sh) you should use CHANNEL="debug" instead or omit CHANNEL="release" completely.

Rustc

You should prefer using the Cargo method.

$ rustc +$(cat $cg_gccjit_dir/rust-toolchain) -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

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.

Debugging

Sometimes, libgccjit will crash and output an error like this:

during RTL pass: expand
libgccjit.so: error: in expmed_mode_index, at expmed.h:249
0x7f0da2e61a35 expmed_mode_index
	../../../gcc/gcc/expmed.h:249
0x7f0da2e61aa4 expmed_op_cost_ptr
	../../../gcc/gcc/expmed.h:271
0x7f0da2e620dc sdiv_cost_ptr
	../../../gcc/gcc/expmed.h:540
0x7f0da2e62129 sdiv_cost
	../../../gcc/gcc/expmed.h:558
0x7f0da2e73c12 expand_divmod(int, tree_code, machine_mode, rtx_def*, rtx_def*, rtx_def*, int)
	../../../gcc/gcc/expmed.c:4335
0x7f0da2ea1423 expand_expr_real_2(separate_ops*, rtx_def*, machine_mode, expand_modifier)
	../../../gcc/gcc/expr.c:9240
0x7f0da2cd1a1e expand_gimple_stmt_1
	../../../gcc/gcc/cfgexpand.c:3796
0x7f0da2cd1c30 expand_gimple_stmt
	../../../gcc/gcc/cfgexpand.c:3857
0x7f0da2cd90a9 expand_gimple_basic_block
	../../../gcc/gcc/cfgexpand.c:5898
0x7f0da2cdade8 execute
	../../../gcc/gcc/cfgexpand.c:6582

To see the code which causes this error, call the following function:

gcc_jit_context_dump_to_file(ctxt, "/tmp/output.c", 1 /* update_locations */)

This will create a C-like file and add the locations into the IR pointing to this C file. Then, rerun the program and it will output the location in the second line:

libgccjit.so: /tmp/something.c:61322:0: error: in expmed_mode_index, at expmed.h:249

Or add a breakpoint to add_error in gdb and print the line number using:

p loc->m_line
p loc->m_filename->m_buffer

To print a debug representation of a tree:

debug_tree(expr);

(defined in print-tree.h)

To print a debug reprensentation of a gimple struct:

debug_gimple_stmt(gimple_struct)

To get the rustc command to run in gdb, add the --verbose flag to cargo build.

To have the correct file paths in gdb instead of /usr/src/debug/gcc/libstdc++-v3/libsupc++/eh_personality.cc:

Maybe by calling the following at the beginning of gdb:

set substitute-path /usr/src/debug/gcc /path/to/gcc-repo/gcc

TODO(antoyo): but that's not what I remember I was doing.

How to use a custom-build rustc

  • Build the stage2 compiler (rustup toolchain link debug-current build/x86_64-unknown-linux-gnu/stage2).
  • Clean and rebuild the codegen with debug-current in the file rust-toolchain.

How to install a forked git-subtree

Using git-subtree with rustc requires a patched git to make it work. The PR that is needed is here. Use the following instructions to install it:

git clone [email protected]:tqc/git.git
cd git
git checkout tqc/subtree
make
make install
cd contrib/subtree
make
cp git-subtree ~/bin

Then, do a sync with this command:

PATH="$HOME/bin:$PATH" ~/bin/git-subtree push -P compiler/rustc_codegen_gcc/ ../rustc_codegen_gcc/ sync_branch_name
cd ../rustc_codegen_gcc
git checkout master
git pull
git checkout sync_branch_name
git merge master

TODO: write a script that does the above.

https://rust-lang.zulipchat.com/#narrow/stream/301329-t-devtools/topic/subtree.20madness/near/258877725

How to use mem-trace

rustc needs to be built without jemalloc so that mem-trace can overload malloc since jemalloc is linked statically, so a LD_PRELOAD-ed library won't a chance to intercept the calls to malloc.

How to generate GIMPLE

If you need to check what gccjit is generating (GIMPLE), then take a look at how to generate it in gimple.md.

How to build a cross-compiling libgccjit

Building libgccjit

  • Follow these instructions: https://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/ with the following changes:
  • Configure gcc with ../gcc/configure --enable-host-shared --disable-multilib --enable-languages=c,jit,c++ --disable-bootstrap --enable-checking=release --prefix=/opt/m68k-gcc/ --target=m68k-linux --without-headers.
  • Some shells, like fish, don't define the environment variable $MACHTYPE.
  • Add CFLAGS="-Wno-error=attributes -g -O2" at the end of the configure command for building glibc (CFLAGS="-Wno-error=attributes -Wno-error=array-parameter -Wno-error=stringop-overflow -Wno-error=array-bounds -g -O2" for glibc 2.31, which is useful for Debian).

Configuring rustc_codegen_gcc

  • Set TARGET_TRIPLE="m68k-unknown-linux-gnu" in config.sh.
  • Since rustc doesn't support this architecture yet, set it back to TARGET_TRIPLE="mips-unknown-linux-gnu" (or another target having the same attributes). Alternatively, create a target specification file (note that the arch specified in this file must be supported by the rust compiler).
  • Set linker='-Clinker=m68k-linux-gcc'.
  • Set the path to the cross-compiling libgccjit in gcc_path.
  • Comment the line: context.add_command_line_option("-masm=intel"); in src/base.rs.
  • (might not be necessary) Disable the compilation of libstd.so (and possibly libcore.so?).

More Repositories

1

rust

Empowering everyone to build reliable and efficient software.
Rust
85,122
star
2

rustlings

🦀 Small exercises to get you used to reading and writing Rust code!
Rust
47,148
star
3

mdBook

Create book from markdown files. Like Gitbook but implemented in Rust
Rust
15,892
star
4

book

The Rust Programming Language
Rust
13,981
star
5

rust-analyzer

A Rust compiler front-end for IDEs
Rust
13,571
star
6

cargo

The Rust package manager
Rust
11,293
star
7

rust-clippy

A bunch of lints to catch common mistakes and improve your Rust code. Book: https://doc.rust-lang.org/clippy/
Rust
9,860
star
8

rust-by-example

Learn Rust with examples (Live code editor included)
6,109
star
9

rustup

The Rust toolchain installer
Rust
5,558
star
10

rustfmt

Format Rust code
Rust
5,524
star
11

rfcs

RFCs for changes to Rust
Markdown
5,390
star
12

futures-rs

Zero-cost asynchronous programming in Rust
Rust
5,119
star
13

rust-bindgen

Automatically generates Rust FFI bindings to C (and some C++) libraries.
Rust
3,830
star
14

rust.vim

Vim configuration for Rust.
Vim Script
3,628
star
15

miri

An interpreter for Rust's mid-level intermediate representation
Rust
3,581
star
16

rls

Repository for the Rust Language Server (aka RLS)
Rust
3,513
star
17

regex

An implementation of regular expressions for Rust. This implementation uses finite automata and guarantees linear time matching on all inputs.
Rust
3,083
star
18

crates.io

The Rust package registry
Rust
2,554
star
19

hashbrown

Rust port of Google's SwissTable hash map
Rust
2,266
star
20

log

Logging implementation for Rust
Rust
2,180
star
21

this-week-in-rust

Data for this-week-in-rust.org
HTML
1,826
star
22

libc

Raw bindings to platform APIs for Rust
Rust
1,786
star
23

chalk

An implementation and definition of the Rust trait system using a PROLOG-like logic solver
Rust
1,713
star
24

async-book

Asynchronous Programming in Rust
Shell
1,699
star
25

nomicon

The Dark Arts of Advanced and Unsafe Rust Programming
CSS
1,698
star
26

rustc-dev-guide

A guide to how rustc works and how to contribute to it.
HTML
1,580
star
27

rustc_codegen_cranelift

Cranelift based backend for rustc
Rust
1,538
star
28

git2-rs

libgit2 bindings for Rust
Rust
1,520
star
29

cc-rs

Rust library for build scripts to compile C/C++ code into a Rust library
Rust
1,491
star
30

vscode-rust

Rust extension for Visual Studio Code
TypeScript
1,386
star
31

polonius

Defines the Rust borrow checker.
Rust
1,255
star
32

api-guidelines

Rust API guidelines
1,202
star
33

reference

The Rust Reference
Rust
1,140
star
34

rust-playground

The Rust Playground
Rust
1,076
star
35

rust-mode

Emacs configuration for Rust
Emacs Lisp
1,009
star
36

docs.rs

crates.io documentation generator
Rust
891
star
37

rustfix

Automatically apply the suggestions made by rustc
Rust
853
star
38

portable-simd

The testing ground for the future of portable SIMD in Rust
Rust
816
star
39

datafrog

A lightweight Datalog engine in Rust
Rust
783
star
40

flate2-rs

DEFLATE, gzip, and zlib bindings for Rust
Rust
730
star
41

socket2

Advanced configuration options for sockets.
Rust
681
star
42

unsafe-code-guidelines

Forum for discussion about what unsafe code can and can't do
641
star
43

rust-semverver

Automatic checking for semantic versioning in library crates
Rust
639
star
44

stdarch

Rust's standard library vendor-specific APIs and run-time feature detection
Rust
597
star
45

crater

Run experiments across parts of the Rust ecosystem!
Rust
588
star
46

packed_simd

Portable Packed SIMD Vectors for Rust standard library
Rust
575
star
47

rustc-perf

Website for graphing performance of rustc
Rust
539
star
48

libm

A port of MUSL's libm to Rust.
Rust
499
star
49

cfg-if

A if/elif-like macro for Rust #[cfg] statements
Rust
479
star
50

crates.io-index

Registry index for crates.io
476
star
51

backtrace-rs

Backtraces in Rust
Rust
473
star
52

style-team

Home of the Rust style team
Rust
438
star
53

docker-rust

The official Docker images for Rust
Dockerfile
414
star
54

glob

Support for matching file paths against Unix shell style patterns.
Rust
381
star
55

rust-forge

Information useful to people contributing to Rust
Rust
380
star
56

compiler-team

A home for compiler team planning documents, meeting minutes, and other such things.
HTML
380
star
57

wg-async

Working group dedicated to improving the foundations of Async I/O in Rust
Rust
365
star
58

www.rust-lang.org

The home of the Rust website
Fluent
358
star
59

compiler-builtins

Porting `compiler-rt` intrinsics to Rust
Rust
328
star
60

measureme

Support crate for rustc's self-profiling feature
Rust
324
star
61

rustc-hash

Custom hash algorithm used by rustc (plus hashmap/set aliases): fast, deterministic, not secure
Rust
312
star
62

blog.rust-lang.org

The Rust Programming Language Blog
HTML
302
star
63

team

Rust teams structure
Rust
293
star
64

glacier

A big 'ol pile of ICE.
Rust
289
star
65

project-error-handling

Error handling project group
264
star
66

atom-ide-rust

Rust IDE support for Atom, powered by the Rust Analyzer or Rust Language Server
JavaScript
259
star
67

stacker

Manual segmented stacks for Rust
Rust
252
star
68

a-mir-formality

a model of MIR and the Rust type/trait system
Rust
245
star
69

cmake-rs

Rust build dependency for running cmake
Rust
241
star
70

edition-guide

A guide to changes between various editions of Rust
238
star
71

getopts

The getopts repo maintained by the rust-lang project
Rust
229
star
72

annotate-snippets-rs

Library for snippet annotations
Rust
223
star
73

rust-roadmap-2017

Tracking Rust's roadmap
215
star
74

areweasyncyet.rs

Are we async yet?
Rust
211
star
75

rust-playpen

A web interface for running Rust code
Rust
208
star
76

wg-allocators

Home of the Allocators working group: Paving a path for a standard set of allocator traits to be used in collections!
199
star
77

rustc-demangle

Rust symbol demangling
Rust
196
star
78

lang-team

Home of the Rust lang team
JavaScript
191
star
79

highfive

Github hooks to provide an encouraging atmosphere for new contributors
Python
185
star
80

ferris-says

A Rust flavored implementation of `cowsay`
Rust
182
star
81

rust-guidelines

This repository has moved
179
star
82

cargo-bisect-rustc

Bisects rustc, either nightlies or CI artifacts
Rust
177
star
83

rustwide

Execute your code on the Rust ecosystem.
Rust
177
star
84

homu

A bot that integrates with GitHub and your favorite continuous integration service
Python
174
star
85

triagebot

Automation/tooling for Rust spaces
Rust
162
star
86

rfcbot-rs

Coordinates asynchronous decision making on Rust repositories. Status of tracked issues and PRs can be viewed at https://rfcbot.rs.
Rust
157
star
87

prev.rust-lang.org

The previous Rust website. The current website's code is at https://github.com/rust-lang/www.rust-lang.org.
HTML
153
star
88

pkg-config-rs

Build library for invoking pkg-config for Rust
Rust
147
star
89

thanks

Celebrate Rust contributors.
Rust
146
star
90

rustc-reading-club

Rust Code Reading Clubs
141
star
91

simpleinfra

Rust Infrastructure automation
HCL
140
star
92

gll

GLL parsing framework.
Rust
137
star
93

ena

An implementation of union-find / congruence-closure in Rust. Extracted from rustc for independent experimentation.
Rust
131
star
94

wg-cargo-std-aware

Repo for working on "std aware cargo"
130
star
95

rust-memory-model

Collecting examples and information to help design a memory model for Rust.
Python
125
star
96

rust-artwork

Official artwork for the Rust project.
122
star
97

libs-team

The home of the library team
Rust
107
star
98

google-summer-of-code

Rust project ideas for Google Summer of Code
105
star
99

rustup-components-history

Rustup package status history
Rust
102
star
100

wg-grammar

Where the work of WG-grammar, aiming to provide a canonical grammar for Rust, resides
Rust
101
star