https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102876
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |hubicka at gcc dot gnu.org --- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Jason Merrill from comment #6) > It's not clear to me that this optimization should use the constexpr > machinery; as I commented on bug 4131. If optimization turns the > initialization of a static variable into a simple matter of storing a > constant value, it should go one step further and turn that constant value > into a constant initializer. I guess that would be possible, a targetted optimization pass for __static_initialization_and_destruction_* and _GLOBAL__sub_I_* functions (or just the latter). It would need to be done after IPA and after various optimization passes afterwards so that the functions can be optimized enough, on the other side with some further optimization passes still to go, so that when we optimize away all the stores something can cleanup the function and some further optimization can kick in and kill empty _GLOBAL__sub_I_* functions altogether. For each dynamically initialized var it would probably need to try to build updated DECL_INITIAL CONSTRUCTOR (starting from the one the var has if any), maybe punt whenever some particular leaf field is initialized multiple times, certainly punt if initialized by non-constant, maybe punt if a union has more than one field initialized, etc. But I'm worried about larger TUs where not all dynamic initialization can be optimized into constants. E.g. if there remain any function calls where the alias analysis could think they can read or modify the vars or their subobjects etc., we'd need to punt. Perhaps we could when generating these functions wrap the dynamic initialization of each var by calls into some new IFN that would take address of the variable and for alias analysis say it reads it but doesn't modify and doesn't escape the address. In C++ one can't read the var in other initializers until it has been constructed, right? So the opening IFN would stand as the first stmt that may read or write the variable and similarly everything after the closing IFN would be considered unrelated code to that. Not sure if we can reliably detect that the variable was declared read-only and isn't TREE_READONLY only because it has dynamic initialization (and that it is safe to optimize it into a .rodata var). And, probably it would be best if we could arrange for post-IPA to handle these global initialization functions as early as possible so that we don't need to give up because the vars were already emitted into assembly.