This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH to build_vtbl_ref_1


While fiddling with vtable pointer optimization, I noticed that
build_vtbl_ref_1 was doing some of the job of fixed_type_or_null; I've
fixed that.

This patch also sets TREE_CONSTANT on references to vtable contents, which
are fixed at compile time.

Tested i686-pc-linux-gnu, applied trunk.

2002-05-13  Jason Merrill  <jason@redhat.com>

	* class.c (build_vtbl_ref_1): Use fixed_type_or_null.
	(fixed_type_or_null): See through reference vars.
	(build_base_path): Vtable contents are constant.
	* typeck.c (get_member_function_from_ptrfunc): Likewise.

*** class.c.~1~	Sun May 12 10:24:55 2002
--- class.c	Fri May 10 00:49:58 2002
*************** build_base_path (code, expr, binfo, nonn
*** 316,322 ****
  			 build_pointer_type (ptrdiff_type_node),
  			 v_offset);
        v_offset = build_indirect_ref (v_offset, NULL);
!       
        offset = cp_convert (ptrdiff_type_node,
  			   size_diffop (offset, BINFO_OFFSET (v_binfo)));
  
--- 316,323 ----
  			 build_pointer_type (ptrdiff_type_node),
  			 v_offset);
        v_offset = build_indirect_ref (v_offset, NULL);
!       TREE_CONSTANT (v_offset) = 1;
! 
        offset = cp_convert (ptrdiff_type_node,
  			   size_diffop (offset, BINFO_OFFSET (v_binfo)));
  
*************** static tree
*** 401,475 ****
  build_vtbl_ref_1 (instance, idx)
       tree instance, idx;
  {
!   tree vtbl, aref;
!   tree basetype = TREE_TYPE (instance);
  
    if (TREE_CODE (basetype) == REFERENCE_TYPE)
      basetype = TREE_TYPE (basetype);
  
!   if (instance == current_class_ref)
!     vtbl = build_vfield_ref (instance, basetype);
!   else
      {
!       if (optimize)
! 	{
! 	  /* Try to figure out what a reference refers to, and
! 	     access its virtual function table directly.  */
! 	  tree ref = NULL_TREE;
! 
! 	  if (TREE_CODE (instance) == INDIRECT_REF
! 	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE)
! 	    ref = TREE_OPERAND (instance, 0);
! 	  else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
! 	    ref = instance;
! 
! 	  if (ref && TREE_CODE (ref) == VAR_DECL
! 	      && DECL_INITIAL (ref))
! 	    {
! 	      tree init = DECL_INITIAL (ref);
! 
! 	      while (TREE_CODE (init) == NOP_EXPR
! 		     || TREE_CODE (init) == NON_LVALUE_EXPR)
! 		init = TREE_OPERAND (init, 0);
! 	      if (TREE_CODE (init) == ADDR_EXPR)
! 		{
! 		  init = TREE_OPERAND (init, 0);
! 		  if (IS_AGGR_TYPE (TREE_TYPE (init))
! 		      && (TREE_CODE (init) == PARM_DECL
! 			  || TREE_CODE (init) == VAR_DECL))
! 		    instance = init;
! 		}
! 	    }
! 	}
  
!       if (IS_AGGR_TYPE (TREE_TYPE (instance))
! 	  && (TREE_CODE (instance) == RESULT_DECL
! 	      || TREE_CODE (instance) == PARM_DECL
! 	      || TREE_CODE (instance) == VAR_DECL))
! 	{
! 	  vtbl = TYPE_BINFO_VTABLE (basetype);
! 	  /* Knowing the dynamic type of INSTANCE we can easily obtain
! 	     the correct vtable entry.  We resolve this back to be in
! 	     terms of the primary vtable.  */
! 	  if (TREE_CODE (vtbl) == PLUS_EXPR)
! 	    {
! 	      idx = fold (build (PLUS_EXPR,
! 				 TREE_TYPE (idx),
! 				 idx,
! 				 build (EXACT_DIV_EXPR,
! 					TREE_TYPE (idx),
! 					TREE_OPERAND (vtbl, 1),
! 					TYPE_SIZE_UNIT (vtable_entry_type))));
! 	      vtbl = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
! 	    }
! 	}
!       else
! 	vtbl = build_vfield_ref (instance, basetype);
      }
  
    assemble_external (vtbl);
  
    aref = build_array_ref (vtbl, idx);
  
    return aref;
  }
--- 402,437 ----
  build_vtbl_ref_1 (instance, idx)
       tree instance, idx;
  {
!   tree aref;
!   tree vtbl = NULL_TREE;
  
+   /* Try to figure out what a reference refers to, and
+      access its virtual function table directly.  */
+ 
+   int cdtorp = 0;
+   tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);
+ 
+   tree basetype = TREE_TYPE (instance);
    if (TREE_CODE (basetype) == REFERENCE_TYPE)
      basetype = TREE_TYPE (basetype);
  
!   if (fixed_type && !cdtorp)
      {
!       tree binfo = lookup_base (fixed_type, basetype,
! 				ba_ignore|ba_quiet, NULL);
!       if (binfo)
! 	vtbl = BINFO_VTABLE (binfo);
!     }
  
!   if (!vtbl)
!     {
!       vtbl = build_vfield_ref (instance, basetype);
      }
  
    assemble_external (vtbl);
  
    aref = build_array_ref (vtbl, idx);
+   TREE_CONSTANT (aref) = 1;
  
    return aref;
  }
*************** fixed_type_or_null (instance, nonnull, c
*** 5396,5402 ****
  	return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
        if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
  	/* Propagate nonnull.  */
! 	fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
        return NULL_TREE;
  
      case NOP_EXPR:
--- 5358,5364 ----
  	return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
        if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
  	/* Propagate nonnull.  */
! 	return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
        return NULL_TREE;
  
      case NOP_EXPR:
*************** fixed_type_or_null (instance, nonnull, c
*** 5423,5428 ****
--- 5385,5391 ----
        /* fall through...  */
      case TARGET_EXPR:
      case PARM_DECL:
+     case RESULT_DECL:
        if (IS_AGGR_TYPE (TREE_TYPE (instance)))
  	{
  	  if (nonnull)
*************** fixed_type_or_null (instance, nonnull, c
*** 5449,5454 ****
--- 5412,5422 ----
            /* Reference variables should be references to objects.  */
            if (nonnull)
  	    *nonnull = 1;
+ 
+ 	  if (TREE_CODE (instance) == VAR_DECL
+ 	      && DECL_INITIAL (instance))
+ 	    return fixed_type_or_null (DECL_INITIAL (instance),
+ 				       nonnull, cdtorp);
  	}
        return NULL_TREE;
  
*** typeck.c.~1~	Sun May 12 10:24:55 2002
--- typeck.c	Fri May 10 00:36:55 2002
*************** get_member_function_from_ptrfunc (instan
*** 2911,2916 ****
--- 2911,2917 ----
        /* Finally, extract the function pointer from the vtable.  */
        e2 = fold (build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx));
        e2 = build_indirect_ref (e2, NULL);
+       TREE_CONSTANT (e2) = 1;
  
        /* When using function descriptors, the address of the
  	 vtable entry is treated as a function pointer.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]