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.