> > So I think all we can hope for is merging memcpy with the extra write of 0.
> 
> That's not actually clear.
> 
> It would be reasonable to assume that foo isn't likely to change the string
> and have the inlined destructor for a string that was initialized as a short
> string like here do something like
> 
> if (stuff_got_changed) [[unlikely]]
>   obj.noninlined_full_destructor();
> 
> That would still work if someone were to naughtily cast away the "const", but
> they would pay the price in the form of two jumps and the function call.

Using const as a hint is an interesting idea which did not come to my
mind.  Sadly I do not see how to fit it into the optimization pipeline.
We first do early inlining (essentially intra-module inlining for size)
followed by early optimizations (basic cleanup of the code).  Then
profile is constructed and inter-procedural optimizations starts.
Interesting inlining happens in inter-procedural inlining and thus at
the profile construction time we do not yeat know what the constructor
and destructor is doing, so we do not know it has likely hot path.

Moreover the destruction is now:
  _48 = D.35539._M_dataplus._M_p;
  if (&D.35539.D.25336._M_local_buf == _48)
    goto <bb 8>; [18.09%]
  else
    goto <bb 7>; [81.91%]

  <bb 7> [local count: 879501928]:
  _50 = D.35539.D.25336._M_allocated_capacity;
  _51 = _50 + 1;
  operator delete (_48, _51);

Which is essentially one if (that would need to stay to test if
something changed) and a call. Only what we could save is computing the
string size which we could save anyway by calling variant of delete with
unknown size...

Reply via email to