C++ PATCH: Avoid cp_finish_decl for vtables

Mark Mitchell mark@codesourcery.com
Mon Aug 30 01:33:00 GMT 2004


For virtual function tables and the like, there is no point in running
the initialization through cp_finish_decl.  That function does a lot
of work to check that the initializer makes sense (via digest_init,
etc.) which results in additional memory allocation as well.  This
change allows us to skip that processing.

Tested on i686-pc-linux-gnu, applied on the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2004-08-29  Mark Mitchell  <mark@codesourcery.com>

	* cp-tree.h (initialize_artificial_var): Declare.
	* decl.c (initialize_artifical_var): New function.
	* class.c (initialize_array): Remove.
	(initialize_vtable): Use initialize_artificial_var.
	(build_vtt): Likewise.
	(build_ctor_vtbl_group): Likewise.

Index: class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.661
diff -c -5 -p -r1.661 class.c
*** class.c	27 Aug 2004 17:59:20 -0000	1.661
--- class.c	30 Aug 2004 00:53:42 -0000
*************** static void dump_array (FILE *, tree);
*** 169,179 ****
  static void dump_vtable (tree, tree, tree);
  static void dump_vtt (tree, tree);
  static void dump_thunk (FILE *, int, tree);
  static tree build_vtable (tree, tree, tree);
  static void initialize_vtable (tree, tree);
- static void initialize_array (tree, tree);
  static void layout_nonempty_base_or_field (record_layout_info,
  						   tree, tree, splay_tree);
  static tree end_of_class (tree, int);
  static bool layout_empty_base (tree, tree, splay_tree);
  static void accumulate_vtbl_inits (tree, tree, tree, tree, tree);
--- 169,178 ----
*************** initialize_vtable (tree binfo, tree init
*** 6723,6746 ****
  {
    tree decl;
  
    layout_vtable_decl (binfo, list_length (inits));
    decl = get_vtbl_decl_for_binfo (binfo);
!   initialize_array (decl, inits);
    dump_vtable (BINFO_TYPE (binfo), binfo, decl);
  }
  
- /* Initialize DECL (a declaration for a namespace-scope array) with
-    the INITS.  */
- 
- static void
- initialize_array (tree decl, tree inits)
- {
-   DECL_INITIAL (decl) = build_constructor (NULL_TREE, inits);
-   cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
- }
- 
  /* Build the VTT (virtual table table) for T.
     A class requires a VTT if it has virtual bases.
     
     This holds
     1 - primary virtual pointer for complete object T
--- 6722,6735 ----
  {
    tree decl;
  
    layout_vtable_decl (binfo, list_length (inits));
    decl = get_vtbl_decl_for_binfo (binfo);
!   initialize_artificial_var (decl, inits);
    dump_vtable (BINFO_TYPE (binfo), binfo, decl);
  }
  
  /* Build the VTT (virtual table table) for T.
     A class requires a VTT if it has virtual bases.
     
     This holds
     1 - primary virtual pointer for complete object T
*************** build_vtt (tree t)
*** 6773,6783 ****
    type = build_index_type (size_int (list_length (inits) - 1));
    type = build_cplus_array_type (const_ptr_type_node, type);
  				 
    /* Now, build the VTT object itself.  */
    vtt = build_vtable (t, get_vtt_name (t), type);
!   initialize_array (vtt, inits);
    /* Add the VTT to the vtables list.  */
    TREE_CHAIN (vtt) = TREE_CHAIN (CLASSTYPE_VTABLES (t));
    TREE_CHAIN (CLASSTYPE_VTABLES (t)) = vtt;
  
    dump_vtt (t, vtt);
--- 6762,6772 ----
    type = build_index_type (size_int (list_length (inits) - 1));
    type = build_cplus_array_type (const_ptr_type_node, type);
  				 
    /* Now, build the VTT object itself.  */
    vtt = build_vtable (t, get_vtt_name (t), type);
!   initialize_artificial_var (vtt, inits);
    /* Add the VTT to the vtables list.  */
    TREE_CHAIN (vtt) = TREE_CHAIN (CLASSTYPE_VTABLES (t));
    TREE_CHAIN (CLASSTYPE_VTABLES (t)) = vtt;
  
    dump_vtt (t, vtt);
*************** build_ctor_vtbl_group (tree binfo, tree 
*** 7060,7070 ****
    type = build_cplus_array_type (vtable_entry_type, type);
    TREE_TYPE (vtbl) = type;
  
    /* Initialize the construction vtable.  */
    CLASSTYPE_VTABLES (t) = chainon (CLASSTYPE_VTABLES (t), vtbl);
!   initialize_array (vtbl, inits);
    dump_vtable (t, binfo, vtbl);
  }
  
  /* Add the vtbl initializers for BINFO (and its bases other than
     non-virtual primaries) to the list of INITS.  BINFO is in the
--- 7049,7059 ----
    type = build_cplus_array_type (vtable_entry_type, type);
    TREE_TYPE (vtbl) = type;
  
    /* Initialize the construction vtable.  */
    CLASSTYPE_VTABLES (t) = chainon (CLASSTYPE_VTABLES (t), vtbl);
!   initialize_artificial_var (vtbl, inits);
    dump_vtable (t, binfo, vtbl);
  }
  
  /* Add the vtbl initializers for BINFO (and its bases other than
     non-virtual primaries) to the list of INITS.  BINFO is in the
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1036
diff -c -5 -p -r1.1036 cp-tree.h
*** cp-tree.h	28 Aug 2004 02:33:50 -0000	1.1036
--- cp-tree.h	30 Aug 2004 00:53:42 -0000
*************** extern tree builtin_function (const char
*** 3809,3818 ****
--- 3809,3819 ----
  			      enum built_in_class cl,
  			      const char *libname, tree attrs);
  extern tree check_elaborated_type_specifier     (enum tag_types, tree, bool);
  extern void warn_extern_redeclared_static (tree, tree);
  extern bool cp_missing_noreturn_ok_p		(tree);
+ extern void initialize_artificial_var            (tree, tree);
  
  extern bool have_extern_spec;
  
  /* in decl2.c */
  extern bool check_java_method (tree);
Index: decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1283
diff -c -5 -p -r1.1283 decl.c
*** decl.c	28 Aug 2004 06:35:36 -0000	1.1283
--- decl.c	30 Aug 2004 00:53:42 -0000
*************** initialize_local_var (tree decl, tree in
*** 4637,4646 ****
--- 4637,4662 ----
    cleanup = cxx_maybe_build_cleanup (decl);
    if (DECL_SIZE (decl) && cleanup)
      finish_decl_cleanup (decl, cleanup);
  }
  
+ /* DECL is a VAR_DECL for a compiler-generated variable with static
+    storage duration (like a virtual table) whose initializer is a
+    compile-time constant.  Initialize the variable and provide it to
+    the back end.  */
+ 
+ void
+ initialize_artificial_var (tree decl, tree init)
+ {
+   DECL_INITIAL (decl) = build_constructor (NULL_TREE, init);
+   DECL_INITIALIZED_P (decl) = 1;
+   determine_visibility (decl);
+   layout_var_decl (decl);
+   maybe_commonize_var (decl);
+   make_rtl_for_nonlocal_decl (decl, init, /*asmspec=*/NULL);
+ }
+ 
  /* Finish processing of a declaration;
     install its line number and initial value.
     If the length of an array type is not known before,
     it must be determined now, from the initial value, or it is an error.
  



More information about the Gcc-patches mailing list