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.