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]

Re: PATCH: improve vtable emission


On Thursday, January 2, 2003, at 11:20 AM, Nathan Sidwell wrote:

Matt Austern wrote:
On Monday, December 30, 2002, at 11:58 AM, Mark Mitchell wrote:
And why do we need to do this again?  Oh, I see; dynamic_classes is
misnamed.  Please rename it to something else more intuitive.
Suggestions?  I left it as dynamic_classes because I couldn't think
of a name that was both accurate and manageable.  (The actual
concept, as described in a comment, is something like "classes
whose vtables should be emitted.)  classes_to_emit isn't too awful
a name, but I'm not sure it's really an improvement on
dynamic_classes.
keyed_classes? or variant thereof
That sounds reasonable! OK, here's a revised version of the patch.
I tested it with mainline, and it doesn't cause any new test failures.

--Matt

Index: gcc/cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.507
diff -u -r1.507 class.c
--- gcc/cp/class.c 1 Jan 2003 11:58:56 -0000 1.507
+++ gcc/cp/class.c 2 Jan 2003 21:31:00 -0000
@@ -5224,6 +5224,35 @@
splay_tree_delete (empty_base_offsets);
}

+/* Returns the virtual function with which the vtable for TYPE is
+ emitted, or NULL_TREE if that heuristic is not applicable to TYPE. */
+
+static tree
+key_method (tree type)
+{
+ tree method;
+
+ if (TYPE_FOR_JAVA (type)
+ || processing_template_decl
+ || CLASSTYPE_TEMPLATE_INSTANTIATION (type)
+ || CLASSTYPE_INTERFACE_KNOWN (type))
+ return NULL_TREE;
+
+ for (method = TYPE_METHODS (type); method != NULL_TREE;
+ method = TREE_CHAIN (method))
+ if (DECL_VINDEX (method) != NULL_TREE
+ && ! DECL_DECLARED_INLINE_P (method)
+ && (! DECL_PURE_VIRTUAL_P (method)
+#if 0
+ /* This would be nice, but we didn't think of it in time. */
+ || DECL_DESTRUCTOR_P (method)
+#endif
+ ))
+ return method;
+
+ return NULL_TREE;
+}
+
/* Perform processing required when the definition of T (a class type)
is complete. */

@@ -5265,6 +5294,19 @@
bases and members and add implicitly generated methods. */
check_bases_and_members (t);

+ /* Find the key method */
+ if (TYPE_CONTAINS_VPTR_P (t))
+ {
+ CLASSTYPE_KEY_METHOD (t) = key_method (t);
+
+ /* If a polymorphic class has no key method, we may emit the vtable
+ in every translation unit where the class definition appears. */
+ if (CLASSTYPE_KEY_METHOD (t) == NULL_TREE)
+ {
+ keyed_classes = tree_cons (NULL_TREE, t, keyed_classes);
+ }
+ }
+
/* Layout the class itself. */
layout_class_type (t, &virtuals);

@@ -5342,9 +5384,6 @@
else if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
DECL_VINDEX (fndecl) = build_shared_int_cst (vindex);
}
-
- /* Add this class to the list of dynamic classes. */
- dynamic_classes = tree_cons (NULL_TREE, t, dynamic_classes);
}

finish_struct_bits (t);
Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.793
diff -u -r1.793 cp-tree.h
--- gcc/cp/cp-tree.h 1 Jan 2003 11:58:58 -0000 1.793
+++ gcc/cp/cp-tree.h 2 Jan 2003 21:31:03 -0000
@@ -628,7 +628,7 @@
CPTI_DSO_HANDLE,
CPTI_DCAST,

- CPTI_DYNAMIC_CLASSES,
+ CPTI_KEYED_CLASSES,

CPTI_MAX
};
@@ -761,9 +761,10 @@
destructors. */
#define vtt_parm_type cp_global_trees[CPTI_VTT_PARM_TYPE]

-/* A TREE_LIST of all of the dynamic classes in the program. */
+/* A TREE_LIST of the dynamic classes whose vtables may have to be
+ emitted in this translation unit. */

-#define dynamic_classes cp_global_trees[CPTI_DYNAMIC_CLASSES]
+#define keyed_classes cp_global_trees[CPTI_KEYED_CLASSES]

/* Global state. */

@@ -1182,6 +1183,7 @@
tree pure_virtuals;
tree friend_classes;
tree methods;
+ tree key_method;
tree decl_list;
tree template_info;
tree befriending_classes;
@@ -1301,6 +1303,11 @@
virtual base classes. If this is 0 for the root of a type
hierarchy, then we can use more efficient search techniques. */
#define TYPE_USES_VIRTUAL_BASECLASSES(NODE) (TREE_LANG_FLAG_3 (NODE))
+
+/* The member function with which the vtable will be emitted:
+ the first noninline non-pure-virtual member function. NULL_TREE
+ if there is no key function or if this is a class template */
+#define CLASSTYPE_KEY_METHOD(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->key_method)

/* Vector member functions defined in this class. Each element is
either a FUNCTION_DECL, a TEMPLATE_DECL, or an OVERLOAD. All
Index: gcc/cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.978
diff -u -r1.978 decl.c
--- gcc/cp/decl.c 1 Jan 2003 03:16:14 -0000 1.978
+++ gcc/cp/decl.c 2 Jan 2003 21:31:08 -0000
@@ -14352,6 +14352,17 @@
if (fndecl == NULL_TREE)
return error_mark_node;

+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
+ && DECL_VIRTUAL_P (fndecl)
+ && !processing_template_decl)
+ {
+ tree fnclass = DECL_CLASS_CONTEXT (fndecl);
+ if (fndecl == CLASSTYPE_KEY_METHOD (fnclass))
+ {
+ keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes);
+ }
+ }
+
nested = function_depth > 1;
fntype = TREE_TYPE (fndecl);

Index: gcc/cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.587
diff -u -r1.587 decl2.c
--- gcc/cp/decl2.c 31 Dec 2002 19:43:14 -0000 1.587
+++ gcc/cp/decl2.c 2 Jan 2003 21:31:10 -0000
@@ -88,7 +88,6 @@
static tree prune_vars_needing_no_initialization (tree);
static void write_out_vars (tree);
static void import_export_class (tree);
-static tree key_method (tree);
static tree get_guard_bits (tree);

/* A list of static class variables. This is needed, because a
@@ -1536,29 +1535,6 @@
}
}

-/* Returns the virtual function with which the vtable for TYPE is
- emitted, or NULL_TREE if that heuristic is not applicable to TYPE. */
-
-static tree
-key_method (tree type)
-{
- tree method;
-
- if (TYPE_FOR_JAVA (type)
- || CLASSTYPE_TEMPLATE_INSTANTIATION (type)
- || CLASSTYPE_INTERFACE_KNOWN (type))
- return NULL_TREE;
-
- for (method = TYPE_METHODS (type); method != NULL_TREE;
- method = TREE_CHAIN (method))
- if (DECL_VINDEX (method) != NULL_TREE
- && ! DECL_DECLARED_INLINE_P (method)
- && ! DECL_PURE_VIRTUAL_P (method))
- return method;
-
- return NULL_TREE;
-}
-
/* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL,
based on TYPE and other static flags.

@@ -1589,7 +1565,7 @@
functions in our class, or if we come from a template. */

int found = (CLASSTYPE_TEMPLATE_INSTANTIATION (type)
- || key_method (type));
+ || CLASSTYPE_KEY_METHOD (type) != NULL_TREE);

if (final || ! found)
{
@@ -1648,7 +1624,7 @@
if (import_export == 0
&& TYPE_POLYMORPHIC_P (ctype))
{
- tree method = key_method (ctype);
+ tree method = CLASSTYPE_KEY_METHOD (ctype);
if (method)
import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1);
}
@@ -2639,12 +2615,37 @@
instantiate_pending_templates ();

/* Write out virtual tables as required. Note that writing out
- the virtual table for a template class may cause the
- instantiation of members of that class. */
- for (t = dynamic_classes; t; t = TREE_CHAIN (t))
- if (maybe_emit_vtables (TREE_VALUE (t)))
- reconsider = true;
-
+ the virtual table for a template class may cause the
+ instantiation of members of that class. If we write out
+ vtables then we remove the class from our list so we don't
+ have to look at it again. */
+
+ while (keyed_classes != NULL_TREE
+ && maybe_emit_vtables (TREE_VALUE (keyed_classes)))
+ {
+ reconsider = 1;
+ keyed_classes = TREE_CHAIN (keyed_classes);
+ }
+
+ t = keyed_classes;
+ if (t != NULL_TREE)
+ {
+ tree next = TREE_CHAIN (t);
+
+ while (next)
+ {
+ if (maybe_emit_vtables (TREE_VALUE (next)))
+ {
+ reconsider = 1;
+ TREE_CHAIN (t) = TREE_CHAIN (next);
+ }
+ else
+ t = next;
+
+ next = TREE_CHAIN (t);
+ }
+ }
+
/* Write out needed type info variables. Writing out one variable
might cause others to be needed. */
if (walk_globals (unemitted_tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.641
diff -u -r1.641 pt.c
--- gcc/cp/pt.c 1 Jan 2003 11:58:57 -0000 1.641
+++ gcc/cp/pt.c 2 Jan 2003 21:31:13 -0000
@@ -5487,6 +5487,9 @@
pop_from_top_level ();
pop_tinst_level ();

+ if (TYPE_CONTAINS_VPTR_P (type))
+ keyed_classes = tree_cons (NULL_TREE, type, keyed_classes);
+
return type;
}



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