3

How can I apply GCC's/Clang's __restrict__ qualifier to the this pointer of a class?
This question was inspired by Richard Powell's CppCon 2018 talk, "How to Argue(ment)." I saw a similar question "restrict qualifier on member functions (restrict this pointer)." (All code can be found on Compiler Explorer)

void bar();

class Foo {
 public:
  int this_example() const {
    if (value > 0) {
      bar();
      return value;
    } else {
      return value;
    }
  }

 private:
  int value;
};

The above code generates the following assembly. In it, we can see that value has to be loaded twice, via the this pointer. This makes sense, it is a consequence that C++ inherited from C and the restrict qualifier allows the programmer to turn off the behavior. I can find no way to enable the restrict functionality for the this pointer.

Foo::this_example() const:               # @Foo::this_example() const
        push    rbx
        mov     eax, dword ptr [rdi]
        test    eax, eax
        jle     .LBB2_2
        mov     rbx, rdi
        call    bar()
        mov     eax, dword ptr [rbx]
.LBB2_2:
        pop     rbx
        ret

On the Compiler Explorer page, I show examples of method arguments using __restrict__ to elide the second load. There is also an example of passing a struct reference to a function and using __restrict__ to elide the second load.

I can imagine a world where the compiler would allow the programmer to mention the implicit this pointer in the arguments of a method. The compiler could then allow application of qualifiers to the this pointer. See code below for an example.

class Foo {
 public:
  int unrestricted(Foo *this);
  int restricted(Foo *__restrict__ this);
};

As a follow up question, is there something in the C++ standard or a C++ guideline that would make it so that this could never have the restrict qualifier?

cmwt
  • 351
  • 2
  • 15
  • 1
    How about putting the entire implementation of `this_example` into a static member function, with `restrict`ed `const Foo *` parameter? – HolyBlackCat Nov 08 '18 at 21:31
  • Even if you apply it to `this`, this still does not guarantee that `bar` does not change `value`. Also it will still have to be loaded again because of function calling convention. –  Nov 08 '18 at 21:32
  • @Ivan Yes, but that would be UB. The compiler would optimize based on an assumption that would never happen, which is what OP wants, it seems. – HolyBlackCat Nov 08 '18 at 21:33
  • For better or worse, `restrict` is just not the part of C++. So there is nothing in standards. – SergeyA Nov 08 '18 at 21:36
  • @Ivan, why would it need to be loaded again? – SergeyA Nov 08 '18 at 21:37
  • @SergeyA I didn't understand the question. I though OP wanted it to be loaded again. Although I still don't understand it. Is it about applying `restrict` globally? –  Nov 08 '18 at 21:38
  • @Ivan, Thank you for your comment. I am looking for a way to tell the compiler that, for a specific method call, the data pointed to by `this` will not be changed by some other piece of code; that it can't see. Some C++ compilers allow this behavior via restrict, but only for function/method arguments that can be explicitly stated in the definition. – cmwt Nov 08 '18 at 22:53
  • @cmwt Isn't your question then duplicates [the question](https://stackoverflow.com/questions/6808472/restrict-qualifier-on-member-functions-restrict-this-pointer) you linked? One of the answers even has code example, although no the accepted answer. –  Nov 08 '18 at 23:20
  • @Ivan, They are similar. The other OP asks, "...what would be a case where one would actually want to give a member function a restrict qualifier...?" I was asking how to apply the restrict qualifier specifically to the the `this` pointer because I am trying to get the compiler to elide the second load. I thought it was different enough to warrant its own question. I am sorry if it is not. I am new to programming and Stack Overflow. @Acorn answered the question but all the compilers I have tested still preform the second load even with the restrict qualifier on the `this` pointer. – cmwt Nov 08 '18 at 23:41

1 Answers1

3

GCC's documentation for __restrict__ (as well as the linked question) mentions that you can actually restrict this:

You may also specify whether a member function’s this pointer is unaliased by using __restrict__ as a member function qualifier.

void T::fn () __restrict__
{
    /* … */
}

Within the body of T::fn, this has the effective definition T *__restrict__ const this. Notice that the interpretation of a __restrict__ member function qualifier is different to that of const or volatile qualifier, in that it is applied to the pointer rather than the object. This is consistent with other compilers that implement restricted pointers.

Note, however, that marking the this pointer as such does not prevent the second load.

Acorn
  • 24,970
  • 5
  • 40
  • 69
  • Thank you for your answer. You beat me to it. After two days I found the site you mentioned in your answer. I tried your answer in Compiler Explorer and neither Clang or GCC elide the second load. I guess I'll have to do some more digging. – cmwt Nov 08 '18 at 23:09