Giving hints to the compiler/optimizer (#pragma hint ...)

U.Mutlu um@mutluit.com
Tue Jun 26 11:31:00 GMT 2018


Martin Sebor wrote on 06/26/2018 05:16 AM:
>>>> When the reference passed to f() is bound to an object that's
>>>> defined const GCC could assume that the call to f() doesn't
>>>> change it and emit better code but, unfortunately, it does not.
>>>> As a result, even though GCC could avoid the test below, it
>>>> emits it.
>>>>
>>>>    void g (void)
>>>>    {
>>>>      const std::vector<int> v;
>>>>
>>>>      int n = v.size ();
>>>>
>>>>      f (v);
>>>>
>>>>      if (v.size () != n)
>>>>        __builtin_abort ();
>>>>    }
>>>>
>>>> GCC does eliminate such tests in the simple cases when v is
>>>> a fundamental type like int, but not when it's a struct (even
>>>> a trivial one containing just an int).
>>>
>>> Hmm. if that is really true then I would be negatively surprised.
>>> I just tested it with the the latest g++ (v9) and it gives a compile
>>> error
>>> if one tries to modify the vector inside f().
>>> And that is the expected behaviour, so I wonder which compiler &
>>> version you
>>> mean?
>>
>> Ok, you mean this:
>>   if (v.size () != n)
>>     __builtin_abort ();
>>
>> But the compliler cannot know that size() returns a vector-internal value,
>> ie. it could also be an external value, therefore it can't optimize it
>> away, IMO.
>
> Jonathan already made it clear earlier that GCC can determine
> that the return value of vector::size() doesn't change between
> successive calls to the function because it's is trivially
> inline and doesn't modify any data, and therefore can
> eliminate all but the first call.
>
> For a reduced test case showing the missing optimization see
> bug 86318.

Ok, I see, with a deep-analysis the compiler/optimizer can determine
whether the member func, here size() const, is returning
a non-changing value, that is
  a) either an object-intern variable
     (in this case regardless of the constness of the object itself
     as a whole as it was passed to f() as a const reference,
     so v can't change in f() and therefore between the two v.size() calls)),
  b) a true const variable or value (intern or extern), or
  c) a calculated value (intern or extern) that is always the same,
then the said optimization afterwards can indeed be made, yes, true.

It's all about the quality/depthness of the analysis.
But in the general case (ie. any func), the _calculated_ return value cases 
are IMO the hardest to analyse correctly.

Therefore, I think the power-user can and should help the compiler/optimizer
with some new function attributes/hints (and maybe also variable
attributes/hints), to keep the gcc guesswork and the codebase light,
and still be flexible and powerful.




More information about the Gcc-help mailing list