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