|
|
Subscribe / Log in / New account

Rust frontend approved for GCC

The GCC steering committee has approved the contribution of the Rust frontend to the compiler suite. "We look forward to including a preliminary, beta version of GCC Rust in GCC 13 as a non-default language".

to post comments

EXCELLENT!

Posted Jul 12, 2022 0:39 UTC (Tue) by Subsentient (guest, #142918) [Link] (25 responses)

Finally!

Rust has enormous potential, but in order for me to take a systems language that seriously, it needs multiple independent compilers.
Rust has historically opposed this because they like to keep a tight grip on the language and ecosystem -- so much so that they've bullied gccrs developers to ensure they won't add features, like -fno-strict-aliasing, that rustc refuses to add.

You'll still find lots of people speaking as if having more than one working compiler for a language is a bad thing.

From a technical perspective, Rust is a pretty great language, and could be even better if people would put in the time for e.g. non-cyclical self-referential structures in the borrow checker.

I'll feel much more comfortable using Rust long-term once I see GCC shipping a usable Rust frontend. The Rust organization has already had significant turmoil and scandals, and this is a good example of why I think that multiple independent implementations are absolutely imperative for Rust's future.

EXCELLENT!

Posted Jul 12, 2022 0:57 UTC (Tue) by Wol (subscriber, #4433) [Link] (6 responses)

> Rust has enormous potential, but in order for me to take a systems language that seriously, it needs multiple independent compilers.

Why?

> Rust has historically opposed this because they like to keep a tight grip on the language and ecosystem -- so much so that they've bullied gccrs developers to ensure they won't add features, like -fno-strict-aliasing, that rustc refuses to add.

Given that that particular option was added to disable unwanted gcc optimisation, it sounds to me like the rust developers have very good reasons for not wanting it! If it breaks rust's memory guarantees it's not a case of they "like to keep a tight grip", rather it's they don't want the language broken by idiotic and non-sensical decisions ...

Cheers,
Wol

EXCELLENT!

Posted Jul 12, 2022 1:49 UTC (Tue) by JoeBuck (subscriber, #2330) [Link] (5 responses)

Why do you think -fno-strict-aliasing would have any effect on Rust's memory guarantees? If the front end has already checked types and the borrow checker passes, the only effect of setting that flag would be to make the code worse (the compiler would be forbidden from optimizing based on pointer provenance) but you won't get a bad result, just less optimization.

-fno-strict-aliasing

Posted Jul 12, 2022 8:29 UTC (Tue) by matthias (subscriber, #94967) [Link] (3 responses)

> you won't get a bad result, just less optimization.

And why would anybody want less optimization? The only reason to enable this flag would be to mask undefined behavior (UB), i.e., to allow a developer to write unsafe code that violates the aliasing invariants of rust and avoid some crashes that might result from this. There is no good reason to ever switch on this flag. If you have code that does not work without this flag, then this code is UB and has to be fixed. If your code does not have UB, then there is no need for this flag.

If rust would allow this flag for gcc than there might be developers relying on it (instead of writing correct code) and produce code that cannot be safely compiled with rustc (llvm). This should be avoided.

-fno-strict-aliasing

Posted Jul 12, 2022 13:24 UTC (Tue) by linusw (subscriber, #40300) [Link] (2 responses)

> why would anybody want less optimization?

I regularly debug with -O0 in order to read and debug the resulting assembly using objdump to find certain bugs. With too much optimization the correspondence between the high level language and the assembly becomes hard to follow, so you want something simpler for readability, what is logically equivalent and faster isn't necessarily easy to read.

There are many times when developing the Linux kernel that you set -O0 on a file and compare the code and the assembly to figure out what is wrong, often in device drivers and such code as cache support and MMU tables where you want to scrutinize the result.

-fno-strict-aliasing

Posted Jul 12, 2022 14:19 UTC (Tue) by moltonel (guest, #45207) [Link]

Strict aliasing is not an optimization step, it's a promise to the compiler that makes some optimizations possible. Whether those optimizations are enabled still depend on the `-C opt-level` flag, and strict aliasing makes no difference at the lower optimization levels.

-fno-strict-aliasing

Posted Jul 12, 2022 14:29 UTC (Tue) by mathstuf (subscriber, #69389) [Link]

I suppose it depends on the kind of code you're working on. If the optimizer is butchering my code, I'm either looking for UB at the source level or generally hunting snipe (i.e., a compiler bug). Either way, I don't see what `-fno-strict-aliasing` would buy anyone in Rust.

EXCELLENT!

Posted Jul 12, 2022 13:41 UTC (Tue) by nix (subscriber, #2304) [Link]

... of course, Rust's provenance rules are not the same as C's (and more generally nor are its aliasing rules). This has caused trouble with LLVM in the past.

EXCELLENT!

Posted Jul 12, 2022 1:52 UTC (Tue) by ms-tg (subscriber, #89231) [Link] (1 responses)

> … they've bullied gccrs developers to ensure they won't add features …

I’ve not heard this story. Would you be willing to share links or other background? “Bullying” is a very strong word to use in this context and I’d like to understand it.

EXCELLENT!

Posted Jul 12, 2022 19:15 UTC (Tue) by tux3 (subscriber, #101245) [Link]

I think it's reasonable to call "bullying" hyperbole here.

A not inconsequential subset of people seem to strongly feel that divergence between compilers (including flags) that could result in a gcc-rs dialect and a rustc dialect, would be bad.

My understanding is that the gcc-rs people have been very receptive to that viewpoint, and so there was no strong-arming, steamrolling, or bullying, actual or necessary.

EXCELLENT!

Posted Jul 12, 2022 5:41 UTC (Tue) by areilly (subscriber, #87829) [Link] (8 responses)

There are a number of hyperbolic statements in this comment, but the claim that -fno-strict-aliasing has anything to do with Rust seems absurd. What would such a flag mean in the context of Rust? There isn't a mechanism in rust for creating the type-punned aliases that the flag refers to. It's strictly a C(family)-language construct.

EXCELLENT!

Posted Jul 12, 2022 7:31 UTC (Tue) by k8to (guest, #15413) [Link] (1 responses)

Controlling memory layout of structures is useful in situations other than unions and similar. I'm not a big fan of using it to build network or hardware data, but the feature is used for those purposes.

EXCELLENT!

Posted Jul 12, 2022 7:32 UTC (Tue) by k8to (guest, #15413) [Link]

Uh. Please ignore that comment, I was thinking of disabling mem alignment for some very strange reason. I need more sleep.

EXCELLENT!

Posted Jul 12, 2022 9:02 UTC (Tue) by pbonzini (subscriber, #60935) [Link] (4 responses)

There is https://doc.rust-lang.org/stable/std/mem/fn.transmute.html (which is unsafe, not concidentially).

EXCELLENT!

Posted Jul 12, 2022 10:20 UTC (Tue) by excors (subscriber, #95769) [Link] (1 responses)

I don't think type-punning through transmute should cause any optimisation issues, though? Rust's main aliasing rule is that an exclusive reference (&mut T) can't coexist with any other reference (&T or another &mut T) to the same object. If you have a &u32 and a &f32 referencing the same object, they're both read-only so there's no opportunity for the optimiser to mess it up. E.g. if the compiler caches one reference's value in an integer register and the other in a float register, and doesn't realise that they're linked, that's fine because the value can't change anyway.

That contrasts with C where aliasing is based on types, not mutability, in which case you might have an int* that illegally aliases a float*, and if you write to the int* the compiler may continue to use the stale cached value of the float* (unless you use -fno-strict-aliasing to change the aliasing rules).

In Rust I think you could alias &Cell<u32> and &Cell<f32> (at least I can't see any particular reason that would be undefined behaviour?), where Cell allows mutation through a non-exclusive reference. But internally it uses raw pointers, and (if I understand correctly) Rust assumes that raw pointers can alias any object of any type. That means raw pointers are effectively -fno-strict-aliasing by default, and it will generate suboptimal code when they don't actually alias (but that's okay because you can just avoid using raw pointers in performance-critical code; you should be using normal safe references instead).

EXCELLENT!

Posted Jul 12, 2022 14:40 UTC (Tue) by khim (subscriber, #9252) [Link]

Unsafe Rust has regular pointers which behave like pointers in C/C++.

Which means -fno-strict-aliasing is not entirely useless.

But given the fact that, unlike C/C++, it's hard to accidentally cause such aliasing (you have to use unsafe then transmute) I don't think supporting that mode is useful.

> But internally it uses raw pointers, and (if I understand correctly) Rust assumes that raw pointers can alias any object of any type.

That's part of the language which is not yet fully specified. You can read the blog post here and the description here.

> but that's okay because you can just avoid using raw pointers in performance-critical code; you should be using normal safe references instead

Absolutely not! Not even close! It's true that you shouldn't use pointers in performance-critical user code, but lots of abstractions designed for performance-critical code are built using unsafe and pointers.

The fact that you don't use them explicitly but instead use safe abstractions built on top of them doesn't mean pointers can be shoddily optimized. On the contrary: their optimization is critical if you want to generate speedy rust code.

transmute

Posted Jul 12, 2022 11:00 UTC (Tue) by tialaramex (subscriber, #21167) [Link] (1 responses)

Note that transmute notionally does memcpy, and memcpy is exactly how you're allowed (without Undefined Behaviour) to write type punning in C or C++. In most cases the compiler can see what you're getting at and elide the actual memcpy but if for whatever reason the compiler can't figure out what's really going on, that memcpy prevents you getting into a place where unrelated optimisations blow up your transmute.

Transmute is hideously dangerous *anyway* but not directly because of aliasing concerns. For example you can transmute some bytes you found into a string, which Rust then assumes is UTF-8 encoded. Or you can transmute the integer 0 into a NonZeroUsize, and then hand that to APIs which explicitly took NonZeroUsize because they can't handle zeroes. Or transmute 69 into a bool which is now sometimes neither equal to true nor false. Nice. Wait, no, that's not nice at all.

transmute

Posted Jul 12, 2022 13:42 UTC (Tue) by nix (subscriber, #2304) [Link]

Or transmute 69 into a bool which is now sometimes neither equal to true nor false. Nice. Wait, no, that's not nice at all.
Sounds like the perfect thing to use to encode SQL NULL :P

EXCELLENT!

Posted Jul 12, 2022 14:32 UTC (Tue) by moltonel (guest, #45207) [Link]

The Rust language does guarantee strict aliasing, but it needs to tell the backend that this guarantee is upheld. The problem is that this can trigger some bugs in the backend, and many rustc releases came with strict aliasing disabled while waiting for fixes in LLVM. Stomping strict aliasing bugs in Gcc is probably also going to take some time.

EXCELLENT!

Posted Jul 12, 2022 5:48 UTC (Tue) by reijoslav (guest, #98915) [Link]

> they've bullied gccrs developers to ensure they won't add features

Do you have any links or other sources for this?

EXCELLENT!

Posted Jul 12, 2022 9:19 UTC (Tue) by khim (subscriber, #9252) [Link] (5 responses)

> could be even better if people would put in the time for e.g. non-cyclical self-referential structures in the borrow checker

Please don't. This would require addition of move constructors and this way lies madness. Use pin in rare cases where it's needed.

I rather hope they would replicate Swift's approach to ABI stability and dynamic libraries support and supporting moveable self-referential structures would make everything immensely compilicated.

Note that Rust people have noticed Swift achievement but instead of just making dyn Trait as capable of impl Trait they think about how to add more hacks to dyn Trait. I really hope it wouldn't happen and they would just borrow Swift approach.

EXCELLENT!

Posted Jul 12, 2022 19:26 UTC (Tue) by tux3 (subscriber, #101245) [Link] (4 responses)

But this wouldn't require user-defined move constructors, right?

We don't have to use C++ as a references. You just.. apply relocations to fields tagged 'self lifetime after a move.

Today, the compilers knows moving is a memcpy.
With self-referential types, it would add (dst-src) to some fields after the memcpy, to maintain self-referentialness.

It's not obvious to me where this ought to go wrong.

EXCELLENT!

Posted Jul 12, 2022 20:29 UTC (Tue) by atnot (subscriber, #124910) [Link] (2 responses)

I don't think this is feasible, at least not in the anything but very simple cases. Imagine for example a struct that stores some text in a string type with inline storage optimization and also holds a reference to a substring. This means that depending on the length of the string, which is probably buried deep in some unsafe code, your struct might be self-referential or not.

How do you automatically determine how to move this type? If you could track all of this, you'd be halfway towards a garbage collector.

EXCELLENT!

Posted Jul 14, 2022 9:56 UTC (Thu) by khim (subscriber, #9252) [Link] (1 responses)

> If you could track all of this, you'd be halfway towards a garbage collector.

Half-way toward move constructor, not garbage collector. But yeah, it's pretty hard to stop this madness.

Rust already have support for self-referential structures. You implement them with unsafe and pointers, mark with Unpin and that's it.

I'm not yet convinced that's the problem which happens often enough that complicating safe Rust is worth it.

EXCELLENT!

Posted Jul 14, 2022 11:23 UTC (Thu) by atnot (subscriber, #124910) [Link]

> Half-way toward move constructor, not garbage collector.

What I was alluding to was that if you could track every pointer and reference to some piece of data for the purpose of modifying them as that data moves, you are just one "if refcount == 0 free" away from garbage collection.

EXCELLENT!

Posted Jul 14, 2022 9:50 UTC (Thu) by khim (subscriber, #9252) [Link]

> But this wouldn't require user-defined move constructors, right?

No, it's the opposite: move constructors would make the whole thing much harder if not impossible.

Because if move is implemented by memcpy then you may consider it atomic: it may fail, but since old piece is still valid before memcpy returns you can easily pretend you never started the process.

With user-defined move constructors you have to deal with half-moved types where both old and new copy are corrupted.

> You just.. apply relocations to fields tagged 'self lifetime after a move.

That's probably doable but you would invariably trigger ire of people who want to create some even more optimized and convoluted data structures.

> It's not obvious to me where this ought to go wrong.

There are just too much complexity. You couldn't just get away with simple self-referential types. Someone would want Option immediately. Then Result. Then derive. Then there would be huge battle with people who would [rightfully] point out that special-casing Option and Result is wrong and you need more general solution.

And eventually you end up with language whose complexity dwarfs C++ and PL/I. Just to support tiny niche corner case which 99% of time is not needed and 99.99% of time can be avoided.

I don't think it's good use of complexity budget. I like the pin solution much better. Yes, it requires use of unsafe. And thus is supposed to be used in 0.01% of time where self-referential structures offer such a compelling benefit that all that complexity is actually justified. That's enough.

Rust frontend approved for GCC

Posted Jul 12, 2022 18:53 UTC (Tue) by developer122 (guest, #152928) [Link] (1 responses)

This is nice to see, as it'll eventually pave the way towards rust in core kernel code. As others have noted, it'll also be nice if this shakes various bugs out of GCC that have been masked by C's UB until now.

Rust frontend approved for GCC

Posted Jul 13, 2022 3:44 UTC (Wed) by josh (subscriber, #17465) [Link]

> This is nice to see, as it'll eventually pave the way towards rust in core kernel code.

This is not at all blocked; rustc_codegen_gcc also enables this.


Copyright © 2022, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds