Instead these should be explicit programming language features (like defining a regular struct but then slice this struct into an SoA).
The rest should be handled by debugging and profiling tools which need to be much better integrated into the programming workflow than what is common today.
(I’m sympathetic to the concern of things breaking in unexpected ways.)
For instance Zig has a MultiArrayList container in its stdlib which slices its generic item type into one array for each struct item. This isn't a special compiler feature, but a regular usage of Zig's comptime stuff:
https://github.com/ziglang/zig/blob/master/lib/std/multi_arr...
On the other hand, giving up that control and designing languages where more automatic optimizations are possible also seems really great. A lot of programming shouldn’t be concerned with low level perf anymore.
> Compilers really shouldn't do this under the hood, it adds more complexity to the compiler [...] Instead [...] like [...] SoA
Curious. I read GP as "I really want to be able to tell compilers to make these changes", but with exception of your SoA example, all (5) responses assumed it was a desire for a sufficiently magical black-box optimizer. Which in retrospect seems plausible, but first seemed to me quite odd. Of course you want to be able to slap in a paragraph of Halide, or annotate with memory organization... <puzzled expression>. Too much time thinking metaprogramming open compilers and inline multilingualism.
I don't blame the compiler guys. They have to deal with tortuously complex real-world code. Sight unseen. And that code may only work correctly because of some unwritten assumptions, side-effects, and undefined behaviors, which no good program would ever rely upon.
Stop trying to be as lazy as possible in such a bad way. Making compilers make up for a lack of programming ability is a mistake.
Our intuitions are wrong. In reality it takes a shockingly small problem to break these optimizations and make them do something in violation of the semantics of the language, and as a result, the compiler can't perform the optimization even if it is smart enough to try. Many, many, many compilers have tried. It is not a new idea, it is one that has been tried and failed over and over again.
This is one of the reasons why the functional programming crew advocate so hard for simpler semantics like pervasively immutable variables. The idea is that if the program's semantics promise less, the optimizations ought to be a lot easier. And at least at the surface level this is arguably true; Haskell does quite significant map (rather than "loop") fusion successfully. However, to date, the "sufficiently smart compiler" has not manifested to the extent that we'd like, the one that turns functional code into 2x - 3x faster code than imperative code. Generally the real-world smart compilers are straining just to keep up with C, as long as you write in a particular subset of the language.
I have quoted the term "sufficiently smart compiler" because if you want to dig further in, it is a good search term.
Many of our intuitions about our code are similarly broken. There was a lot of hope for exploiting "implicit paralellization" in our codebases; surely, our brains thought, there's just a ton of things in every code base that can be automatically turned into parallel code. That turned out to be false. There was a paper that took some representative code bases and extracted out the theoretical maximum parallelization that could even be done by any conceivable compiler optimization by analyzing the data dependencies themselves and it turned out to be shockingly small, thus effectively killing the idea. This story has been repeated a lot; another search term you can play with is "supercompiler", which amounts to "compilers are pretty good at optimizations in the small, surely our code bases are rife with opportunities to optimize at much higher levels across packages or the entire code base?" to which the answer to date has amounted to "No, not really."
In my opinion, the only hope for any of these ideas is someone sitting down and designing a language from the very get-go intended to work with these ideas. However, given the amount of experience necessary to do that and the subtlety of the task, I'm not sure that I'm not specifying a super-human degree of work by saying that.
It seems that today, very few compilers are willing/able to mess with data structures and rearrange them.
I'd like to see compilers that can at a minimum rearrange arrays of structures into structures of arrays depending on likely data access patterns of the different members of the structure.
I'd also like to see compilers 'factoring out' things like vtables or structure members when they identify that they are constants or never read/written.