Hi,

I've had this flagged to look at "later" for quite long now...

On Mon, Apr 30, 2012 at 07:34:24AM +0000, Mailaripillai, Kannan Jeganathan 
wrote:
> Hi,
> 
> This is related to pr45605.C test.
> 
> ---- Reduced testcase
> 
> struct B {
>   virtual void Run(){};
> };
> 
> struct D : public B {
>   virtual void Run() { };
> };
> 
> int main() {
>   D d;
>   static_cast<B&>(d).Run();
> }
> 
> With x86_64 linux the call to Run through object d is devirtualized.
> Whereas it looks like in ia64 hp-ux it is not devirtualized.
> 
> -fdump-tree-fre1 output for both:
> 
> ---- x86_64 linux:
> 
>   MEM[(struct B *)&d]._vptr.B = &MEM[(void *)&_ZTV1B + 16B];
>   d.D.2197._vptr.B = &MEM[(void *)&_ZTV1D + 16B];
>   D.2248_1 = &MEM[(void *)&_ZTV1D + 16B];
>   D.2249_2 = Run;
>   D::Run (&d.D.2197);
>   d ={v} {CLOBBER};
>   return 0;
> 
> ---- ia64 hp-ux:
> 
>   MEM[(struct B *)&d]._vptr.B = &MEM[(void *)&_ZTV1B + 16B];
>   d.D.1878._vptr.B = &MEM[(void *)&_ZTV1D + 16B];
>   D.1929_1 = &MEM[(void *)&_ZTV1D + 16B];
>   D.1930_2 = (int (*__vtbl_ptr_type) ()) &MEM[(void *)&_ZTV1D + 16B];
>   OBJ_TYPE_REF(D.1930_2;&d.D.1878->0) (&d.D.1878);
> 
> Is it a bug (unexpected with O1 compilation) that it is not optimized to 
> direct call?


There are two important and related differences.  The first one is
that virtual method tables on ia64 constist of FDESC_EXPRs rather than
mere ADDR_EXPRs.  The second one can be seen in the dumps just before
fre1 (i.e. esra):

i686:
  d.D.1854._vptr.B = &MEM[(void *)&_ZTV1D + 8B];
  D.1961_4 = d.D.1854._vptr.B;
  D.1962_5 = *D.1961_4;
  OBJ_TYPE_REF(D.1962_5;&d.D.1854->0) (&d.D.1854);

ia64:
  d.D.1883._vptr.B = &MEM[(void *)&_ZTV1D + 16B];
  D.1991_4 = d.D.1883._vptr.B;
  D.1992_5 = (int (*__vtbl_ptr_type) ()) D.1991_4;
  OBJ_TYPE_REF(D.1992_5;&d.D.1883->0) (&d.D.1883);

The main difference is not the type cast in the third assignment but
the fact that there is no dereference there, which means that gimple
folder has to deal with it at a different place.

I played with it a bit this afternoon and came up with the following
untested patch to fix the pr45605.C testcase.  I can bootstrap and
test it on ia64 if we do not mind this special casing of FDESC_EXPRs
in the midle end (I hope that all platforms that use it use it in the
same way, I only know ia64...)

Thanks,

Martin


2012-08-06  Martin Jambor  <mjam...@suse.cz>

        * gimple-fold.c (gimple_fold_stmt_to_constant_1): Also fold
        assignments of V_C_Es of addresses of FDESC_EXPRs.


*** gcc/gimple-fold.c   Mon Aug  6 14:36:37 2012
--- /tmp/FcpIKb_gimple-fold.c   Mon Aug  6 20:17:26 2012
*************** gimple_fold_stmt_to_constant_1 (gimple s
*** 2542,2548 ****
                     == TYPE_ADDR_SPACE (TREE_TYPE (op0))
                  && TYPE_MODE (TREE_TYPE (lhs))
                     == TYPE_MODE (TREE_TYPE (op0)))
!               return op0;
  
                return
                fold_unary_ignore_overflow_loc (loc, subcode,
--- 2542,2556 ----
                     == TYPE_ADDR_SPACE (TREE_TYPE (op0))
                  && TYPE_MODE (TREE_TYPE (lhs))
                     == TYPE_MODE (TREE_TYPE (op0)))
!               {
!                 tree t;
!                 if (TREE_CODE (op0) != ADDR_EXPR)
!                   return op0;
!                 t = fold_const_aggregate_ref_1 (TREE_OPERAND (op0, 0), 
valueize);
!                 if (t && TREE_CODE (t) == FDESC_EXPR)
!                   return build_fold_addr_expr_loc (loc, TREE_OPERAND (t, 0));
!                 return op0;
!               }
  
                return
                fold_unary_ignore_overflow_loc (loc, subcode,

Reply via email to