austern 02/12/24 09:27:30
Modified: live/gcc3/gcc/cp class.c cp-tree.h decl.c decl2.c pt.c
live/gcc3/gcc/pfe cp-freeze-thaw.c
Log:
Reviewed by: Devang
Improved vtable emission: don't put a class on the list of dynamic classes unless
it's likely to be emitted in this translation unit, i.e. unless we've seen the
key method or else there is no key method.
Revision Changes Path
1.40 +49 -2 src/live/gcc3/gcc/cp/class.c
Index: class.c
===================================================================
RCS file: /cvs/Darwin/src/live/gcc3/gcc/cp/class.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- class.c 2002/12/18 00:32:11 1.39
+++ class.c 2002/12/24 17:27:26 1.40
@@ -5455,6 +5455,39 @@
splay_tree_delete (empty_base_offsets);
}
+/* APPLE LOCAL begin improved vtable emission fsf candidate */
+
+/* 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;
+}
+/* APPLE LOCAL end improved vtable emission fsf candidate */
+
+
/* Perform processing required when the definition of T (a class type)
is complete. */
@@ -5496,6 +5529,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, emit the vtable in
+ every translation unit where the class definition appear. */
+ if (CLASSTYPE_KEY_METHOD (t) == NULL_TREE && !processing_template_decl)
+ {
+ dynamic_classes = tree_cons (NULL_TREE, t, dynamic_classes);
+ }
+ }
+
/* Layout the class itself. */
layout_class_type (t, &virtuals);
@@ -5565,8 +5611,9 @@
if (TREE_CODE (DECL_VINDEX (BV_FN (fn))) != INTEGER_CST)
DECL_VINDEX (BV_FN (fn)) = build_shared_int_cst (vindex);
- /* Add this class to the list of dynamic classes. */
- dynamic_classes = tree_cons (NULL_TREE, t, dynamic_classes);
+ /* APPLE LOCAL begin improved vtable emission */
+ /* remove unconditional addition to list of dynamic classes */
+ /* APPLE LOCAL end improved vtable emission */
}
finish_struct_bits (t);
1.76 +12 -1 src/live/gcc3/gcc/cp/cp-tree.h
Index: cp-tree.h
===================================================================
RCS file: /cvs/Darwin/src/live/gcc3/gcc/cp/cp-tree.h,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -r1.75 -r1.76
--- cp-tree.h 2002/12/18 00:32:12 1.75
+++ cp-tree.h 2002/12/24 17:27:26 1.76
@@ -761,7 +761,8 @@
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]
@@ -1182,6 +1183,9 @@
tree as_base;
tree pure_virtuals;
tree friend_classes;
+ /* APPLE LOCAL begin improved vtable emission fsf candidate */
+ tree key_method;
+ /* APPLE LOCAL end improved vtable emission fsf candidate */
tree GTY ((reorder ("resort_type_method_vec"))) methods;
tree decl_list;
tree template_info;
@@ -1302,6 +1306,13 @@
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))
+
+/* APPLE LOCAL begin improved vtable emission fsf candidate */
+/* 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)
+/* APPLE LOCAL end improved vtable emission fsf candidate */
/* Vector member functions defined in this class. Each element is
either a FUNCTION_DECL, a TEMPLATE_DECL, or an OVERLOAD. All
1.125 +18 -0 src/live/gcc3/gcc/cp/decl.c
Index: decl.c
===================================================================
RCS file: /cvs/Darwin/src/live/gcc3/gcc/cp/decl.c,v
retrieving revision 1.124
retrieving revision 1.125
diff -u -r1.124 -r1.125
--- decl.c 2002/12/18 00:32:12 1.124
+++ decl.c 2002/12/24 17:27:26 1.125
@@ -14965,6 +14965,24 @@
if (fndecl == NULL_TREE)
return error_mark_node;
+ /* APPLE LOCAL begin improved vtable emission fsf candidate */
+ 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))
+ {
+ /* If the function we thought was the key method turns out
+ to be inline, then the class has no key method. */
+ if (DECL_DECLARED_INLINE_P (fndecl))
+ CLASSTYPE_KEY_METHOD (fnclass) = NULL_TREE;
+
+ dynamic_classes = tree_cons (NULL_TREE, fnclass, dynamic_classes);
+ }
+ }
+ /* APPLE LOCAL end improved vtable emission fsf candidate */
+
/* APPLE LOCAL begin indexing dpatel */
if (flag_gen_index)
{
1.100 +45 -30 src/live/gcc3/gcc/cp/decl2.c
Index: decl2.c
===================================================================
RCS file: /cvs/Darwin/src/live/gcc3/gcc/cp/decl2.c,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -r1.99 -r1.100
--- decl2.c 2002/12/18 00:32:13 1.99
+++ decl2.c 2002/12/24 17:27:27 1.100
@@ -94,7 +94,9 @@
static tree prune_vars_needing_no_initialization PARAMS ((tree));
static void write_out_vars PARAMS ((tree));
static void import_export_class PARAMS ((tree));
-static tree key_method PARAMS ((tree));
+/* APPLE LOCAL begin improved vtable emission */
+/* remove declaration of key_method */
+/* APPLE LOCAL end improved vtable emission */
static tree get_guard_bits PARAMS ((tree));
/* APPLE LOCAL AltiVec */
@@ -1670,30 +1672,10 @@
}
}
-/* Returns the virtual function with which the vtable for TYPE is
- emitted, or NULL_TREE if that heuristic is not applicable to TYPE. */
+/* APPLE LOCAL begin improved vtable emission */
+/* remove definition of key_method */
+/* APPLE LOCAL end improved vtable emission */
-static tree
-key_method (type)
- 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.
@@ -1725,8 +1707,10 @@
/* We can only wait to decide if we have real non-inline virtual
functions in our class, or if we come from a template. */
+ /* APPLE LOCAL begin improved vtable emission fsf candidate */
int found = (CLASSTYPE_TEMPLATE_INSTANTIATION (type)
- || key_method (type));
+ || CLASSTYPE_KEY_METHOD (type) != NULL_TREE);
+ /* APPLE LOCAL end improved vtable emission fsf candidate */
if (final || ! found)
{
@@ -1786,7 +1770,9 @@
if (import_export == 0
&& TYPE_POLYMORPHIC_P (ctype))
{
- tree method = key_method (ctype);
+ /* APPLE LOCAL begin improved vtable emission fsf candidate */
+ tree method = CLASSTYPE_KEY_METHOD (ctype);
+ /* APPLE LOCAL end improved vtable emission fsf candidate */
if (method)
import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1);
}
@@ -2858,13 +2844,42 @@
them now. */
instantiate_pending_templates ();
+ /* APPLE LOCAL begin improved vtable emission fsf candidate */
+
/* 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)))
+ 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 (dynamic_classes != NULL_TREE
+ && maybe_emit_vtables (TREE_VALUE (dynamic_classes)))
+ {
reconsider = 1;
-
+ dynamic_classes = TREE_CHAIN (dynamic_classes);
+ }
+
+ t = dynamic_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);
+ }
+ }
+
+ /* APPLE LOCAL end improved vtable emission fsf candidate */
+
/* 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))
1.35 +5 -0 src/live/gcc3/gcc/cp/pt.c
Index: pt.c
===================================================================
RCS file: /cvs/Darwin/src/live/gcc3/gcc/cp/pt.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- pt.c 2002/12/18 00:32:14 1.34
+++ pt.c 2002/12/24 17:27:27 1.35
@@ -5469,6 +5469,11 @@
pop_from_top_level ();
pop_tinst_level ();
+ /* APPLE LOCAL begin improved vtable emission fsf candidate */
+ if (TYPE_CONTAINS_VPTR_P (type))
+ dynamic_classes = tree_cons (NULL_TREE, type, dynamic_classes);
+ /* APPLE LOCAL end improved vtable emission fsf candidate */
+
return type;
}
1.18 +3 -0 src/live/gcc3/gcc/pfe/cp-freeze-thaw.c
Index: cp-freeze-thaw.c
===================================================================
RCS file: /cvs/Darwin/src/live/gcc3/gcc/pfe/cp-freeze-thaw.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- cp-freeze-thaw.c 2002/12/18 00:32:28 1.17
+++ cp-freeze-thaw.c 2002/12/24 17:27:29 1.18
@@ -256,6 +256,9 @@
PFE_FREEZE_THAW_WALK (CLASSTYPE_AS_BASE (node)); /*
NEEDED? */
PFE_FREEZE_THAW_WALK (CLASSTYPE_PURE_VIRTUALS (node)); /* NEEDED? */
PFE_FREEZE_THAW_WALK (CLASSTYPE_FRIEND_CLASSES (node)); /*
NEEDED? */
+ /* APPLE LOCAL begin improved vtable emission fsf candidate */
+ PFE_FREEZE_THAW_WALK (CLASSTYPE_KEY_METHOD (node)); /* NEEDED? */
+ /* APPLE LOCAL end improved vtable emission fsf candidate */
PFE_FREEZE_THAW_WALK (CLASSTYPE_METHOD_VEC (node)); /* NEEDED? */
PFE_FREEZE_THAW_WALK (CLASSTYPE_DECL_LIST (node)); /* NEEDED? */
if (TREE_CODE (node) == RECORD_TYPE