Call for help implementing an independent Rust frontend for GCC

libgccjit is a stable interface, while GCC internals are not. The situation is actually analogous to LLVM. LLVM's C API is stable, while C++ API is not. Rust mostly uses LLVM's C API even if C++ API is more powerful.

I was under the impression that the purpose of libgccjit was to allow the creation of “frontends” that don’t have to be linked and built with GCC itself (which is mainly useful for JIT). As such, I wouldn’t imagine any of the frontends included with GCC would move to it because it doesn’t offer them any real benefits over accessing GCC’s internals directly. But when converting something like rustc to use a GCC backend, it could be useful because you wouldn’t have to build it as part of GCC itself.

I believe this is the point that I struggle with. It seems like if the goal is to build a GCC version of Rust, it should be completely independent and built with GCC itself. I think that having a libgccjit back-end for the existing Rust compile would also be helpful and useful, but, would be a different goal entirely. Does anyone else see it like this or am I just not seeing the big picture correctly?

There is a difference between having an independent implementation and simply having an implementation that uses the GCC backend.

The former would be difficult but possible with a stable, ISO-standard-level specification for Rust and its essential tooling. However, the virtual specification for Rust and its ancillary tooling, as implied by the code in rustc, cargo, clippy, rustfmt, etc., changes as the Rust ecosystem gets new features every six weeks. Thus at the current time such a stable specification is impossible.

On the other hand, an implementation that targets GCC will permit the Rust compiler and its tooling to be incorporated into the GNU toolchain and the broader spectrum of potential use that such inclusion implies. That's a signficant broadening of Rust's footprint from today where it is largely limited to those architectures that LLVM supports.

7 posts were split to a new topic: Specification, standardization, and independent implementations

Correct me if I’m wrong, but on the topic of actual language changes, aren’t versions with certain features periodically “frozen” as “editions”? These would be the stable specs (or a reference for them, at least) that a separate implementation could target rather than try to keep feature complete with rustc itself at first. Or am I misunderstanding the concept of editions?

As for the tooling, I don’t see any reason why programs like rustfmt and clippy would have any issue being used with another compiler (though admittedly I haven’t directly used either to my knowledge, but their purposes don’t sound like something that requires a certain compiler). Cargo could be an issue and would probably need work to use it specifically with a GCC Rust frontend.

Editions are not for freezing certain features, but to be able to make backwards incompatible changes, like reserving new keywords. All editions still get all new features when possible.

1 Like

If the backend's code is to live inside GCC, then indeed there doesn't seem to be any advantage in using libgccjit. I've also proposed using it because I was already assuming that the backend would be done by adapting rustc code (namely the part that does the MIR to LLVM IR lowering) and in that case, if we wanted to output GIMPLE directly, we would need to write our own GIMPLE-producing functions (since we wouldn't have access to the ones in GCC). I'll admit I don't have any idea of how hard that would be, but regardless, I'm not a fan of the idea of having to reinvent that wheel.

Actually it's (mostly) the other way around; please read my previous reply. Also, libgccjit is self-described as "alpha quality software" so there might be API breaking changes in the future.

libgccjit is a stable interface, to quote, "The libgccjit developers strive for ABI and API backward-compatibility". See ABI and API compatibility — libgccjit 13.0.0 (experimental ) documentation for details. There will be no breakage in the future, API or ABI.

1 Like

Their docs are inconsistent about that.

Note that libgccjit is currently of “Alpha” quality; the APIs are not yet set in stone, and they shouldn’t be used in production yet. — libgccjit — libgccjit 14.0.0 (experimental ) documentation

I'm not sure which one to believe, but in either case, I don't think it really matters too much. A Rust compiler would probably help root out libgccjit bugs and API flaws.

1 Like

Okay, yes, libgccjit still claims to be "alpha", but the fact of the matter is that it is ~5 years old now and it never broke API or ABI, not even once in those 5 years. Whether you call that stable or not is your preference.

The way it is done for golang is that those functions live in the main gcc tree, they are written in c, and are kept up to date with the rest of gcc, whilst the rest of the code is out of tree.

In this way golang can be released on its own cycle, and so can gcc.

The same can be done with rust.

Changes to GIMPLE, which are not frequent, are thus isolated from the rust code.

There already exists a rustlang libgccgit project. The one that is needed here is a mirror of how golang operates: rustlang frontend, GIMPLE gcc intermediary, MIR to GIMPLE converter which goes into the main gcc tree.

But there's one major difference between the gccgo/gollvm shared frontend and rustc - rustc is written in Rust, not C++. I very much doubt that GCC will accept a frontend into tree that they can't bootstrap on a system with only a C compiler without resorting to out-of-tree bootstrapping with another compiler like mrustc (to reduce build dependencies). Except for GNAT (GCC Ada), which I'm sure the GCC devs have learned their lesson from, all of the GCC frontends can do this.

Unless, of course, someone can figure out a way to configure GCC to bootstrap the Rust frontend using an in-tree bootstrapper written in C++ (or C). mrustc could be used as the base of this if it were significantly improved (it can't compile anything on Darwin at the moment).

Where's this? If you mean gccrs, I'm pretty sure redbrain decided to attempt a full frontend, though progress is slow.

Ok, so I appreciate this is a long thread, so new people are joining. To recap: I have spoken to the gcc steering committee on behalf of rust-users and they are fine with an external bootstrap component like mrustc just as they are fine with the rust-gcc backend being in rust and also an external project. Git submodules sorts it all out just as it does for the golang frontend.

The precedents here are the D compiler, ADA and go compilers. The bootstrap process using mrustc is nearly identical to that which gcc itself uses and the only restrictive criteria will be to not utilise features of rust which mrust does not support.

Given that people already use mrustc to bootstrap the current rustlang compiler and cargo, this should not be a difficult requirement to meet, and any time it is violated I am pretty sure that mrustc will be updated to match. Even if it is not, which is highly unlikely, then yet aaannoootherr stage can be added to utilise an older version of rust-llvm as an intermediary bootstrap.

Regarding the rust-libgccgit thing, it is around somewhere and I did not take a note of its location, I only noted it in passing, it can be found with apropriate google searches, or probably by scrolling back through this thread.

4 Likes

This is probably the one.

Isn't that only bindings, i.e. a way to access libgccjit from inside rustlang the language, not rustc the compiler? I don't think anyone's made a libgccjit "backend" for rustc.

I took a look at the gccjit api, but I cant find a way to specify struct field offsets: Types — libgccjit 13.0.0 (experimental ) documentation

That discussion is of relevance to the motivations of GCC developers. Discussions naturally have multiple threads and tangents and trying to flatten them or guide them artificially diminishes them. Sometimes it makes more sense to keep the tangents inline rather than creating a new thread.

So is anyone working on this now?

Do you mean accessing fields? How about this? Expressions — libgccjit 14.0.0 (experimental ) documentation .