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++] Fix some dfs_walk uses


This patch removes some unnecessary dfs_walk calls, and replaces
the truely baroque get_template_base with a more sane version.  You'll
notice that it was marking only those bases that it could ever reach
once.  I suspect it merely _needs_ to traverse the bases once, and I'll
get to that once I've improved dfs_walk itself.

booted & tested on i686-pc-linux-gnu.

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2004-09-27  Nathan Sidwell  <nathan@codesourcery.com>

	* class.c (struct count_depth_data): Remove.
	(dfs_depth_post, dfs_depth_q): Remove.
	(find_final_overrider): Use number of vbase classes as depth
	bound.
	
	* cp-tree.h (types_overlap_p): Remove.
	* search.c (struct overlap_info): Remove.
	(dfs_check_overlap, dfs_no_overlap_yet, types_overlap_p): Remove.
	
	* pt.c (GTB_VIA_VIRTUAL, GTB_IGNORE_TYPE): Remove.
	(get_template_base_recursive): Remove. Replace with ...
	(get_template_base_r): ... this.
	(struct get_template_base_data_s): New.
	(get_template_base): Use get_template_base_r via dfs_walk.  Always
	return NULL on failure.
	(unify): Remove error_mark_node check from get_template_base result.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.676
diff -c -3 -p -r1.676 class.c
*** cp/class.c	21 Sep 2004 15:38:50 -0000	1.676
--- cp/class.c	27 Sep 2004 11:57:14 -0000
*************** base_derived_from (tree derived, tree ba
*** 1801,1836 ****
    return false;
  }
  
- typedef struct count_depth_data {
-   /* The depth of the current subobject, with "1" as the depth of the
-      most derived object in the hierarchy.  */
-   size_t depth;
-   /* The maximum depth found so far.  */
-   size_t max_depth;
- } count_depth_data;
- 
- /* Called from find_final_overrider via dfs_walk.  */
- 
- static tree
- dfs_depth_post (tree binfo ATTRIBUTE_UNUSED, void *data)
- {
-   count_depth_data *cd = (count_depth_data *) data;
-   if (cd->depth > cd->max_depth)
-     cd->max_depth = cd->depth;
-   cd->depth--;
-   return NULL_TREE;
- }
- 
- /* Called from find_final_overrider via dfs_walk.  */
- 
- static tree
- dfs_depth_q (tree derived, int i, void *data)
- {
-   count_depth_data *cd = (count_depth_data *) data;
-   cd->depth++;
-   return BINFO_BASE_BINFO (derived, i);
- }
- 
  typedef struct find_final_overrider_data_s {
    /* The function for which we are trying to find a final overrider.  */
    tree fn;
--- 1801,1806 ----
*************** static tree
*** 1943,1949 ****
  find_final_overrider (tree derived, tree binfo, tree fn)
  {
    find_final_overrider_data ffod;
-   count_depth_data cd;
  
    /* Getting this right is a little tricky.  This is valid:
  
--- 1913,1918 ----
*************** find_final_overrider (tree derived, tree
*** 1967,1981 ****
      fn = THUNK_TARGET (fn);
  
    /* Determine the depth of the hierarchy.  */
-   cd.depth = 0;
-   cd.max_depth = 0;
-   dfs_walk (derived, dfs_depth_post, dfs_depth_q, &cd);
- 
    ffod.fn = fn;
    ffod.declaring_base = binfo;
    ffod.most_derived_type = BINFO_TYPE (derived);
    ffod.candidates = NULL_TREE;
!   ffod.vpath_list = (tree *) xcalloc (cd.max_depth, sizeof (tree));
    ffod.vpath = ffod.vpath_list;
  
    dfs_walk_real (derived,
--- 1936,1950 ----
      fn = THUNK_TARGET (fn);
  
    /* Determine the depth of the hierarchy.  */
    ffod.fn = fn;
    ffod.declaring_base = binfo;
    ffod.most_derived_type = BINFO_TYPE (derived);
    ffod.candidates = NULL_TREE;
!   /* The virtual depth cannot be greater than the number of virtual
!      bases.  */
!   ffod.vpath_list = (tree *) xcalloc
!     (VEC_length (tree, CLASSTYPE_VBASECLASSES (BINFO_TYPE (derived))),
!      sizeof (tree));
    ffod.vpath = ffod.vpath_list;
  
    dfs_walk_real (derived,
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1052
diff -c -3 -p -r1.1052 cp-tree.h
*** cp/cp-tree.h	22 Sep 2004 18:12:04 -0000	1.1052
--- cp/cp-tree.h	27 Sep 2004 11:57:24 -0000
*************** extern bool emit_tinfo_decl (tree);
*** 3981,3987 ****
  /* in search.c */
  extern bool accessible_base_p (tree, tree);
  extern tree lookup_base (tree, tree, base_access, base_kind *);
- extern int types_overlap_p			(tree, tree);
  extern tree get_dynamic_cast_base_type          (tree, tree);
  extern int accessible_p                         (tree, tree);
  extern tree lookup_field_1                      (tree, tree, bool);
--- 3981,3986 ----
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.926
diff -c -3 -p -r1.926 pt.c
*** cp/pt.c	21 Sep 2004 15:38:58 -0000	1.926
--- cp/pt.c	27 Sep 2004 11:57:49 -0000
*************** static htab_t local_specializations;
*** 87,98 ****
  #define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
  #define UNIFY_ALLOW_MAX_CORRECTION 128
  
- #define GTB_VIA_VIRTUAL 1 /* The base class we are examining is
- 			     virtual, or a base class of a virtual
- 			     base.  */
- #define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current
- 			     type with the desired type.  */
- 
  static void push_access_scope (tree);
  static void pop_access_scope (tree);
  static int resolve_overloaded_unification (tree, tree, tree, tree,
--- 87,92 ----
*************** static tree process_partial_specializati
*** 154,160 ****
  static void set_current_access_from_decl (tree);
  static void check_default_tmpl_args (tree, tree, int, int);
  static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree);
! static tree get_template_base_recursive (tree, tree, tree, tree, tree, int); 
  static tree get_template_base (tree, tree, tree, tree);
  static int verify_class_unification (tree, tree, tree);
  static tree try_class_unification (tree, tree, tree, tree);
--- 148,154 ----
  static void set_current_access_from_decl (tree);
  static void check_default_tmpl_args (tree, tree, int, int);
  static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree);
! static tree get_template_base_r (tree, void *);
  static tree get_template_base (tree, tree, tree, tree);
  static int verify_class_unification (tree, tree, tree);
  static tree try_class_unification (tree, tree, tree, tree);
*************** try_class_unification (tree tparms, tree
*** 9475,9545 ****
    return arg;
  }
  
! /* Subroutine of get_template_base.  RVAL, if non-NULL, is a base we
!    have already discovered to be satisfactory.  ARG_BINFO is the binfo
!    for the base class of ARG that we are currently examining.  */
  
  static tree
! get_template_base_recursive (tree tparms, 
!                              tree targs, 
!                              tree parm,
!                              tree arg_binfo, 
!                              tree rval, 
!                              int flags)
  {
!   tree base_binfo;
!   int i;
!   tree arg = BINFO_TYPE (arg_binfo);
  
!   if (!(flags & GTB_IGNORE_TYPE))
      {
!       tree r = try_class_unification (tparms, targs,
! 				      parm, arg);
! 
!       /* If there is more than one satisfactory baseclass, then:
! 
! 	   [temp.deduct.call]
! 
! 	   If they yield more than one possible deduced A, the type
! 	   deduction fails.
  
! 	   applies.  */
!       if (r && rval && !same_type_p (r, rval))
! 	return error_mark_node;
!       else if (r)
! 	rval = r;
!     }
  
!   /* Process base types.  */
!   for (i = 0; BINFO_BASE_ITERATE (arg_binfo, i, base_binfo); i++)
!     {
!       int this_virtual;
  
!       /* Skip this base, if we've already seen it.  */
!       if (BINFO_MARKED (base_binfo))
! 	continue;
  
!       this_virtual = 
! 	(flags & GTB_VIA_VIRTUAL) || BINFO_VIRTUAL_P (base_binfo);
!       
!       /* When searching for a non-virtual, we cannot mark virtually
! 	 found binfos.  */
!       if (! this_virtual)
! 	BINFO_MARKED (base_binfo) = 1;
!       
!       rval = get_template_base_recursive (tparms, targs,
! 					  parm,
! 					  base_binfo, 
! 					  rval,
! 					  GTB_VIA_VIRTUAL * this_virtual);
!       
!       /* If we discovered more than one matching base class, we can
! 	 stop now.  */
!       if (rval == error_mark_node)
! 	return error_mark_node;
      }
  
!   return rval;
  }
  
  /* Given a template type PARM and a class type ARG, find the unique
--- 9469,9521 ----
    return arg;
  }
  
! typedef struct get_template_base_data_s 
! {
!   /* Parameters for unification.  */
!   tree tparms;
!   tree targs;
!   tree parm;
!   /* Base we've found to be satisfactory.  */
!   tree rval;
! } get_template_base_data;
! 
! /* Called from get_template_base via dfs_walk.  */
  
  static tree
! get_template_base_r (tree arg_binfo,
! 		     void *data_)
  {
!   get_template_base_data *data = data_;
  
!   /* Do not look at the most derived binfo -- that's not a proper
!      base.  */
!   if (BINFO_INHERITANCE_CHAIN (arg_binfo))
      {
!       tree r = try_class_unification (data->tparms, data->targs,
! 				      data->parm, BINFO_TYPE (arg_binfo));
  
!       if (r)
! 	{
! 	  /* If there is more than one satisfactory baseclass, then:
  
! 	       [temp.deduct.call]
  
! 	      If they yield more than one possible deduced A, the type
! 	      deduction fails.
  
! 	     applies.  */
! 	  if (data->rval && !same_type_p (r, data->rval))
! 	    {
! 	      data->rval = NULL_TREE;
! 	      /* Terminate the walk with any non-NULL value.  */
! 	      return r;
! 	    }
! 	  
! 	  data->rval = r;
! 	}
      }
  
!   return NULL_TREE;
  }
  
  /* Given a template type PARM and a class type ARG, find the unique
*************** get_template_base_recursive (tree tparms
*** 9552,9558 ****
  static tree
  get_template_base (tree tparms, tree targs, tree parm, tree arg)
  {
!   tree rval;
    tree arg_binfo;
  
    gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)));
--- 9528,9534 ----
  static tree
  get_template_base (tree tparms, tree targs, tree parm, tree arg)
  {
!   get_template_base_data data;
    tree arg_binfo;
  
    gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)));
*************** get_template_base (tree tparms, tree tar
*** 9561,9577 ****
    if (!arg_binfo)
      /* The type could not be completed.  */
      return NULL_TREE;
-   
-   rval = get_template_base_recursive (tparms, targs,
- 				      parm, arg_binfo, 
- 				      NULL_TREE,
- 				      GTB_IGNORE_TYPE);
- 
-   /* Since get_template_base_recursive marks the bases classes, we
-      must unmark them here.  */
-   dfs_walk (arg_binfo, dfs_unmark, markedp, 0);
  
!   return rval;
  }
  
  /* Returns the level of DECL, which declares a template parameter.  */
--- 9537,9551 ----
    if (!arg_binfo)
      /* The type could not be completed.  */
      return NULL_TREE;
  
!   data.tparms = tparms;
!   data.targs = targs;
!   data.parm = parm;
!   data.rval = NULL_TREE;
! 
!   dfs_walk_real (arg_binfo, get_template_base_r, 0, 0, &data);
! 
!   return data.rval;
  }
  
  /* Returns the level of DECL, which declares a template parameter.  */
*************** unify (tree tparms, tree targs, tree par
*** 10058,10067 ****
  		       a class of the form template-id, A can be a
  		       pointer to a derived class pointed to by the
  		       deduced A.  */
! 		  t = get_template_base (tparms, targs,
! 					 parm, arg);
  
! 		  if (! t || t == error_mark_node)
  		    return 1;
  		}
  	    }
--- 10032,10040 ----
  		       a class of the form template-id, A can be a
  		       pointer to a derived class pointed to by the
  		       deduced A.  */
! 		  t = get_template_base (tparms, targs, parm, arg);
  
! 		  if (!t)
  		    return 1;
  		}
  	    }
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.322
diff -c -3 -p -r1.322 search.c
*** cp/search.c	24 Sep 2004 14:04:47 -0000	1.322
--- cp/search.c	27 Sep 2004 11:57:54 -0000
*************** struct vbase_info 
*** 46,53 ****
  };
  
  static int is_subobject_of_p (tree, tree);
- static tree dfs_check_overlap (tree, void *);
- static tree dfs_no_overlap_yet (tree, int, void *);
  static base_kind lookup_base_r (tree, tree, base_access, bool, tree *);
  static int dynamic_cast_base_recurse (tree, tree, bool, tree *);
  static tree dfs_debug_unmarkedp (tree, int, void *);
--- 46,51 ----
*************** lookup_conversions (tree type)
*** 2272,2336 ****
    return list;
  }
  
- struct overlap_info 
- {
-   tree compare_type;
-   int found_overlap;
- };
- 
- /* Check whether the empty class indicated by EMPTY_BINFO is also present
-    at offset 0 in COMPARE_TYPE, and set found_overlap if so.  */
- 
- static tree
- dfs_check_overlap (tree empty_binfo, void *data)
- {
-   struct overlap_info *oi = (struct overlap_info *) data;
-   tree binfo;
-   
-   for (binfo = TYPE_BINFO (oi->compare_type); 
-        ; 
-        binfo = BINFO_BASE_BINFO (binfo, 0))
-     {
-       if (BINFO_TYPE (binfo) == BINFO_TYPE (empty_binfo))
- 	{
- 	  oi->found_overlap = 1;
- 	  break;
- 	}
-       else if (!BINFO_N_BASE_BINFOS (binfo))
- 	break;
-     }
- 
-   return NULL_TREE;
- }
- 
- /* Trivial function to stop base traversal when we find something.  */
- 
- static tree
- dfs_no_overlap_yet (tree derived, int ix, void *data)
- {
-   tree binfo = BINFO_BASE_BINFO (derived, ix);
-   struct overlap_info *oi = (struct overlap_info *) data;
-   
-   return !oi->found_overlap ? binfo : NULL_TREE;
- }
- 
- /* Returns nonzero if EMPTY_TYPE or any of its bases can also be found at
-    offset 0 in NEXT_TYPE.  Used in laying out empty base class subobjects.  */
- 
- int
- types_overlap_p (tree empty_type, tree next_type)
- {
-   struct overlap_info oi;
- 
-   if (! IS_AGGR_TYPE (next_type))
-     return 0;
-   oi.compare_type = next_type;
-   oi.found_overlap = 0;
-   dfs_walk (TYPE_BINFO (empty_type), dfs_check_overlap,
- 	    dfs_no_overlap_yet, &oi);
-   return oi.found_overlap;
- }
- 
  /* Returns the binfo of the first direct or indirect virtual base derived
     from BINFO, or NULL if binfo is not via virtual.  */
  
--- 2270,2275 ----

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