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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 06/22/2018 12:32 AM, U.Mutlu wrote:
Hi,
it would be nice to have a mechanism to let the programmer give hints to
the compiler/optimizer.

Example:

for (size_t i = 1; i < vec.size(); ++i)
  ...

If the size of vec cannot change while in this code block, then one
better would do this instead:

{
const size_t vec_sz = vec.size();
for (size_t i = 1; i < vec_sz; ++i)
  ...
}


But, IMO it would be much better if one could just give a hint to the
compiler/optimizer instead:

#pragma hint const vec.size()
for (size_t i = 1; i < vec.size(); ++i)
  ...

Then the compiler/optimizer could cache the vec.size(), ie. fill a const
(register) variable just once and use that instead, like in the previous
manual version.
(The manual version has of course the disadvantage that user has to
define an additional variable and because of that, put the code in its
own scope...)

So, passing such hints to the compiler/optimizer is IMO a good general way.
Would be nice if the gcc developers would implement such a mechanism.

Technically: such a "#pragma hint ..." would apply just to the next line
of code, ie. automatically 'unhinting'.

Unfortunately, const alone isn't always sufficient because programs
can add constness to references and pointers and then cast it away,
and because internally GCC doesn't rely on constness as much as it
could.

For instance in this example, f() can cast the constness of its
argument away and change it.  If the reference is bound to a non-
const object the program is valid:

  void f (const std::vector<int>&);

  void g (const std::vector<int> &v)
  {
    int n = v.size ();

    f (v);

    if (v.size () != n)
      __builtin_abort ();
  }

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).

But adding a #pragma isn't a solution to the problem.  Both C
and to a slightly lesser extent also C++(*) have the necessary
mechanisms to let compilers emit efficient code.  GCC just needs
to take better advantage of them.

Martin

[*] C++ doesn't have the restrict keyword so it cannot express
all the same constraints as C can.



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux