Lots of reasons. First off, you don’t always have all the code available. If you call code from another crate, or through a trait object, I’d like to be able to optimize well without having to know just what code you are calling.
In the general case, no. But there are ways to enable it. For example, C99 added the restrict keyword precisely for this purpose.
Both. Consider the case of Fortran vs C. Fortran is generally held to be the faster choice for numerical computing, precisely because of its strong aliasing guarantees:
[Fortran and C] have similar feature-set. The performance difference comes from the fact that Fortran says aliasing is not allowed. Any code that has aliasing is not valid Fortran but it is up to the programmer and not the compiler to detect these errors.
To a large extent what I’ve been advocating for the TPM is that we optimize unsafe code like C compilers, but we do better with safe Rust code. But the pushback is all about doing better than C compilers with unsafe code. Which I am definitely sympathetic to! =)
To be clear, this would only be in unsafe code, but yes – this is one thing I am worried about!
Certainly every model has its hazards. In the case of the TPM, the hazard is moving code that used to live inside an unsafe boundary outside of an unsafe boundary. In other models, the hazard might be outlining code into a separate function. I agree it’s important to minimize these hazards – ideally not at the cost of making things complicated everywhere. =)
I am intrigued by this idea. I cannot understand it. The goal of the Tootsie Pop model, indeed, is to basically emulate the effect of -fno-strict-aliasing. I’m not even sure what “opting out” of it would mean – forgoing optimizations on safe code?
Actually, nothing in my post talked about eliminating loads or stores. That, indeed, is somewhat easier – if you have two loads, you have some evidence that the pointer is valid between them. What I talked about was code reordering – specifically, moving a load without evidence of another load to come. And I’m not sure how important it is: maybe it’s not. Mostly I’m currently in a mode of trying to push on the boundaries of what the safe type system ought to allow: I focused on this test case because it’s one where, if you only look at the actual loads, you wouldn’t be able to do.
I’m not sure where your list of “high priority” optimizations came from. I don’t know that this particular question (can we move a load later past unknown code) will affect the answers much. But I promise you that, whatever the case, the less we have to know about the surrounding code, the better. =)
As an aside, from conversations I’ve had with people working on the C specification and the like, there is very little data on which instances of UB help the most with optimizing and how. I’d love to see citations and references on this!