On Thu, Aug 28, 2025 at 04:50:15PM +0200, Jakub Jelinek wrote: > On Thu, Aug 28, 2025 at 04:24:46PM +0200, Richard Biener wrote: > > That said, if we ever want to improve on this (and solve the redundant > > store elimination issue), we need an actual GIMPLE/RTL statement > > doing what std::start_lifetime_as <T> does (but not generate code). > > > > Meaning, I'd vote for a p = __builtin_start_lifetime_as (p, (T *)0); > > I thought earlier about just providing size. > null pointer with the new type would provide even more information, > iff we only support constant size types. > And we can then handle it in GIMPLE as if it is (or could be) > void *__builtin_start_lifetime_as (void *p) > { > union { old_type old; T new; } u; > __builtin_memcpy (u.old, p, sizeof (T)); > __builtin_memcpy (p, u.new, sizeof (T)); > return p; > } > (but of course for the const case or even for data races we actually > don't want either of those copies). > Now, I bet any kind of user function could do something like that if > it isn't inlined/exposed to the compiler, so not sure if we need to > handle it in too many places through GIMPLE, perhaps say that it > does or could access directly just the [p, p + sz) bytes (and indirectly > anything reachable). > But how to lower it into RTL is unclear, having it as CALL_EXPR will > mean it has to follow the call ABIs and all extra overhead. > UNSPEC_VOLATILE might be nice, but I guess we don't have a precedent > of backend independent constants for those. > Or expand it (just for RTL?) as inline asm, > asm volatile ("" : "=g" (ptr), "m" (*(T *)ptr) : "0" (ptr), "m" (*(const T > *)ptr)); > ?
Or implement it using inline asm in the headers at least for now, until we find a reason to add a builtin for that. I believe for inline asm we really don't care about the alias set of "m" arguments, the accesses are or can be done in any way the asm likes to. Jakub