Whether or not a local variable is allocated on the stack at runtime (vs. stored in a register) is a decision that the developer must make.
The difference there is that we have an algorithm to do it optimally based on load/store counts, the available registers and the ABI. If such an algorithm existed for “does anyone need this at runtime?”, I would say to use it. This is a case where the compiler being wrong has large performance implications, just like with autovectorization, so it’s better to make the developer say what they want to happen.
Modular has world class compiler engineers on their team, so I am hopeful that they can achieve something along these lines. But I will leave it to them.
Someone may find a solution, but I don’t think there is a generally better option that won’t massively blow up compile times (figuring out whether it can constant fold every single access down to a small set of values, and even then the definition of small is up for debate). Having the compiler guess whether to keep things at compile time and materialize only some stuff or throw it all in .rodata.
do programmers actually need to know whether the compiler will store a value in .rodata or not, given they have no idea whether the compiler will store a local variable on the stack?
Yes, because otherwise the compiler has to analyze the whole program to figure out if some reference to that data is ever passed outside of Mojo, at which point it must materialize the entire thing. Even then, it could be grabbed via dlopen or be used in PTX that is packaged with the binary. Values present in .rodata will also show up in some kinds of analysis tools.