Semantics of OBJ_TYPE_REF

Richard Biener richard.guenther@gmail.com
Fri Jun 18 13:15:11 GMT 2021


On Fri, Jun 18, 2021 at 3:03 PM Erick Ochoa via Gcc <gcc@gcc.gnu.org> wrote:
>
> Hi,
>
> I am having some trouble understanding the semantics of OBJ_TYPE_REF.
> I understand that it is made of three operands:
>
> 1. OBJ_TYPE_REF_EXPR: An expression that evaluates the value to use.
> 2. OBJ_TYPE_REF_OBJECT: Is the object on whose behalf the lookup is
> being performed
> 3. OBJ_TYPE_REF_TOKEN: An integer index to the virtual method table.
>
> The language here is very general and makes it hard for me to understand. Is
>
> 1. OBJ_TYPE_REF_EXPR: The virtual function
> 2. OBJ_TYPE_REF_OBJECT: The "this" object
>
> ?
>
> Why is the index needed if it looks like the virtual function is
> already pointed to by the first operand? I am reading Hubicka's post
> on devirtualization and Part II
> (https://hubicka.blogspot.com/2014/01/devirtualization-in-c-part-2-low-level.html)
> seems to agree with me on the example below. There is also no mention
> of OBJ_TYPE_REF on part II, but there is on part III.
>
> Hubicka's example:
>
> int test() ()
> {
>   int (*__vtbl_ptr_type) () *tmp1;
>   int (*__vtbl_ptr_type) () tmp2;
>   struct A a;
>     struct A * b;
>
>
>   _ZN1AC2Ev (&a);
>   b = &a;
>
>   tmp1 = b->_vptr.A;
>   tmp2 = *tmp1;
>
>   // Notice no OBJ_TYPE_REF below.
>   return tmp2 (b);
> }
>
> My example:
>
> #include <cstdio>
>
> class A
> {
> public:
>   virtual void foo() { printf("hello\n"); };
>   virtual void bar() { printf("world\n"); };
> };
>
> int
> main(int argc, char**argv )
> {
>         class A* a = new A();
>         a->foo();
>         a->bar();
>         return 0;
> }
>
> // Relevant gimple:
>
>     a = D.2922;
>     _1 = a->_vptr.A;
>     _2 = *_1; // first element of the virtual table?
>
>     OBJ_TYPE_REF(_2;(struct A)a->0) (a);
>     // wouldn't this just be equivalent to
>     // _2 (a)
>
>     _3 = a->_vptr.A;
>     _4 = _3 + 8;
>
>     _5 = *_4; // second element of the virtual table
>     OBJ_TYPE_REF(_5;(struct A)a->1) (a);
>     // same
>     // _5 (a)
>
> On part III Hubicka says that OBJ_TYPE_REF is a wrapper and that it
> represents the type and token. (My guess is that these are the
> arguments 2 and 3). I fail to understand why these are needed if we
> have the function already.
>
> Thanks! Any help is appreciated.

For correctness we don't need the OBJ_TYPE_REF but could
indeed just use its first operand.  But we can use OBJ_TYPE_REF
for devirtualization, maybe Honza can explain.

Richard.


More information about the Gcc mailing list