This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH] Compare binfo types directly
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: Mark Mitchell <mark at codesourcery dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 11 Oct 2004 16:37:50 +0100
- Subject: Re: [C++ PATCH] Compare binfo types directly
- Organization: Codesourcery LLC
- References: <416A7936.8080102@codesourcery.com> <416A97C1.4060404@codesourcery.com>
Mark Mitchell wrote:
How about this: define a new SAME_BINFO_TYPE_P macro which does the "=="
test, and use it. Put a comment on it that reflects some of this
discussion, and indicates that we might at some point switch it to use
same_type_p. That makes it easy for us to move to the "T" choice above,
but still gets us the win now.
Here's such a patch, which I've installed after testing on i686-pc-linux-gnu.
It converts the other places I tracked down that were already using pointer
comparision.
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2004-10-11 Nathan Sidwell <nathan@codesourcery.com>
* cp-tree.h (SAME_BINFO_TYPE_P): New.
* class.c (build_base_path): Use SAME_BINFO_TYPE_P to compare
binfo types.
(convert_to_base_statically, determine_primary_bases,
update_vtable_entry_for_fn, dfs_modify_vtables, build_vtt_inits,
dfs_build_secondary_vptr_vtt_inits, build_ctor_vtbl_group,
accumulate_vtbl_inits, dfs_accumulate_vtbl_inits,
build_vtbl_initializer, add_vcall_offset_vtbl_entries_1): Likewise.
* init.c (expand_member_init): Likewise.
* search.c (lookup_base_r, dynamic_cast_base_recurse,
binfo_via_virtual, copied_binfo, binfo_for_vbase,
original_binfo): Likewise.
* tree.c (copy_binfo): Likewise.
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.682
diff -c -3 -p -r1.682 class.c
*** cp/class.c 8 Oct 2004 09:33:53 -0000 1.682
--- cp/class.c 11 Oct 2004 15:09:58 -0000
*************** build_base_path (enum tree_code code,
*** 259,269 ****
if (want_pointer)
probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe));
! gcc_assert (code == MINUS_EXPR
! ? same_type_p (BINFO_TYPE (binfo), probe)
! : code == PLUS_EXPR
! ? same_type_p (BINFO_TYPE (d_binfo), probe)
! : false);
if (binfo == d_binfo)
/* Nothing to do. */
--- 259,268 ----
if (want_pointer)
probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe));
! gcc_assert ((code == MINUS_EXPR
! && SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), probe))
! || (code == PLUS_EXPR
! && SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe)));
if (binfo == d_binfo)
/* Nothing to do. */
*************** convert_to_base (tree object, tree type,
*** 445,452 ****
return build_base_path (PLUS_EXPR, object, binfo, /*nonnull=*/1);
}
! /* EXPR is an expression with class type. BASE is a base class (a
! BINFO) of that class type. Returns EXPR, converted to the BASE
type. This function assumes that EXPR is the most derived class;
therefore virtual bases can be found at their static offsets. */
--- 444,451 ----
return build_base_path (PLUS_EXPR, object, binfo, /*nonnull=*/1);
}
! /* EXPR is an expression with unqualified class type. BASE is a base
! binfo of that class type. Returns EXPR, converted to the BASE
type. This function assumes that EXPR is the most derived class;
therefore virtual bases can be found at their static offsets. */
*************** convert_to_base_statically (tree expr, t
*** 456,462 ****
tree expr_type;
expr_type = TREE_TYPE (expr);
! if (!same_type_p (expr_type, BINFO_TYPE (base)))
{
tree pointer_type;
--- 455,461 ----
tree expr_type;
expr_type = TREE_TYPE (expr);
! if (!SAME_BINFO_TYPE_P (BINFO_TYPE (base), expr_type))
{
tree pointer_type;
*************** determine_primary_bases (tree t)
*** 1276,1282 ****
tree parent_primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (parent));
if (parent_primary
! && BINFO_TYPE (base_binfo) == BINFO_TYPE (parent_primary))
/* We are the primary binfo. */
BINFO_PRIMARY_P (base_binfo) = 1;
}
--- 1275,1282 ----
tree parent_primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (parent));
if (parent_primary
! && SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo),
! BINFO_TYPE (parent_primary)))
/* We are the primary binfo. */
BINFO_PRIMARY_P (base_binfo) = 1;
}
*************** update_vtable_entry_for_fn (tree t, tree
*** 2062,2069 ****
{
/* If we find the final overrider, then we can stop
walking. */
! if (same_type_p (BINFO_TYPE (b),
! BINFO_TYPE (TREE_VALUE (overrider))))
break;
/* If we find a virtual base, and we haven't yet found the
--- 2062,2069 ----
{
/* If we find the final overrider, then we can stop
walking. */
! if (SAME_BINFO_TYPE_P (BINFO_TYPE (b),
! BINFO_TYPE (TREE_VALUE (overrider))))
break;
/* If we find a virtual base, and we haven't yet found the
*************** dfs_modify_vtables (tree binfo, void* da
*** 2153,2159 ****
/* Similarly, a base without a vtable needs no modification. */
&& TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo))
/* Don't do the primary vtable, if it's new. */
! && (BINFO_TYPE (binfo) != t || CLASSTYPE_HAS_PRIMARY_BASE_P (t)))
{
tree virtuals;
tree old_virtuals;
--- 2153,2160 ----
/* Similarly, a base without a vtable needs no modification. */
&& TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo))
/* Don't do the primary vtable, if it's new. */
! && (!SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t)
! || CLASSTYPE_HAS_PRIMARY_BASE_P (t)))
{
tree virtuals;
tree old_virtuals;
*************** build_vtt_inits (tree binfo, tree t, tre
*** 6697,6703 ****
tree init;
tree secondary_vptrs;
secondary_vptr_vtt_init_data data;
! int top_level_p = same_type_p (TREE_TYPE (binfo), t);
/* We only need VTTs for subobjects with virtual bases. */
if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
--- 6698,6704 ----
tree init;
tree secondary_vptrs;
secondary_vptr_vtt_init_data data;
! int top_level_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
/* We only need VTTs for subobjects with virtual bases. */
if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
*************** dfs_build_secondary_vptr_vtt_inits (tree
*** 6783,6789 ****
/* We're only interested in proper subobjects of the type being
constructed. */
! if (same_type_p (BINFO_TYPE (binfo), data->type_being_constructed))
return NULL_TREE;
/* We're only interested in bases with virtual bases or reachable
--- 6784,6790 ----
/* We're only interested in proper subobjects of the type being
constructed. */
! if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->type_being_constructed))
return NULL_TREE;
/* We're only interested in bases with virtual bases or reachable
*************** build_ctor_vtbl_group (tree binfo, tree
*** 6869,6875 ****
if (IDENTIFIER_GLOBAL_VALUE (id))
return;
! gcc_assert (!same_type_p (BINFO_TYPE (binfo), t));
/* Build a version of VTBL (with the wrong type) for use in
constructing the addresses of secondary vtables in the
construction vtable group. */
--- 6870,6876 ----
if (IDENTIFIER_GLOBAL_VALUE (id))
return;
! gcc_assert (!SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t));
/* Build a version of VTBL (with the wrong type) for use in
constructing the addresses of secondary vtables in the
construction vtable group. */
*************** accumulate_vtbl_inits (tree binfo,
*** 6925,6933 ****
{
int i;
tree base_binfo;
! int ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
! gcc_assert (same_type_p (BINFO_TYPE (binfo), BINFO_TYPE (orig_binfo)));
/* If it doesn't have a vptr, we don't do anything. */
if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
--- 6926,6934 ----
{
int i;
tree base_binfo;
! int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
! gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (orig_binfo)));
/* If it doesn't have a vptr, we don't do anything. */
if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
*************** dfs_accumulate_vtbl_inits (tree binfo,
*** 6975,6981 ****
{
tree inits = NULL_TREE;
tree vtbl = NULL_TREE;
! int ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
if (ctor_vtbl_p
&& BINFO_VIRTUAL_P (orig_binfo) && BINFO_PRIMARY_P (orig_binfo))
--- 6976,6982 ----
{
tree inits = NULL_TREE;
tree vtbl = NULL_TREE;
! int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
if (ctor_vtbl_p
&& BINFO_VIRTUAL_P (orig_binfo) && BINFO_PRIMARY_P (orig_binfo))
*************** build_vtbl_initializer (tree binfo,
*** 7109,7116 ****
vid.derived = t;
vid.rtti_binfo = rtti_binfo;
vid.last_init = &vid.inits;
! vid.primary_vtbl_p = (binfo == TYPE_BINFO (t));
! vid.ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
vid.generate_vcall_entries = true;
/* The first vbase or vcall offset is at index -3 in the vtable. */
vid.index = ssize_int(-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
--- 7110,7117 ----
vid.derived = t;
vid.rtti_binfo = rtti_binfo;
vid.last_init = &vid.inits;
! vid.primary_vtbl_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
! vid.ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
vid.generate_vcall_entries = true;
/* The first vbase or vcall offset is at index -3 in the vtable. */
vid.index = ssize_int(-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
*************** add_vcall_offset_vtbl_entries_1 (tree bi
*** 7523,7529 ****
/* When processing BINFO, we only want to generate vcall slots for
function slots introduced in BINFO. So don't try to generate
one if the function isn't even defined in BINFO. */
! if (!same_type_p (DECL_CONTEXT (orig_fn), BINFO_TYPE (binfo)))
continue;
add_vcall_offset (orig_fn, binfo, vid);
--- 7524,7530 ----
/* When processing BINFO, we only want to generate vcall slots for
function slots introduced in BINFO. So don't try to generate
one if the function isn't even defined in BINFO. */
! if (!SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), DECL_CONTEXT (orig_fn)))
continue;
add_vcall_offset (orig_fn, binfo, vid);
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1059
diff -c -3 -p -r1.1059 cp-tree.h
*** cp/cp-tree.h 9 Oct 2004 17:32:58 -0000 1.1059
--- cp/cp-tree.h 11 Oct 2004 15:10:09 -0000
*************** struct lang_type GTY(())
*** 1370,1375 ****
--- 1370,1383 ----
have this flag set. */
#define BINFO_NEW_VTABLE_MARKED(B) (BINFO_FLAG_2 (B))
+ /* Compare a BINFO_TYPE with another type for equality. For a binfo,
+ this is functionally equivalent to using same_type_p, but
+ measurably faster. At least one of the arguments must be a
+ BINFO_TYPE. The other can be a BINFO_TYPE or a regular type. If
+ BINFO_TYPE(T) ever stops being the main variant of the class the
+ binfo is for, this macro must change. */
+ #define SAME_BINFO_TYPE_P(A, B) ((A) == (B))
+
/* Any subobject that needs a new vtable must have a vptr and must not
be a non-virtual primary base (since it would then use the vtable from a
derived class and never become non-primary.) */
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.399
diff -c -3 -p -r1.399 init.c
*** cp/init.c 10 Oct 2004 05:02:53 -0000 1.399
--- cp/init.c 11 Oct 2004 15:10:16 -0000
*************** expand_member_init (tree name)
*** 979,985 ****
/* Look for a direct base. */
for (i = 0; BINFO_BASE_ITERATE (class_binfo, i, direct_binfo); ++i)
! if (same_type_p (basetype, BINFO_TYPE (direct_binfo)))
break;
/* Look for a virtual base -- unless the direct base is itself
--- 979,985 ----
/* Look for a direct base. */
for (i = 0; BINFO_BASE_ITERATE (class_binfo, i, direct_binfo); ++i)
! if (SAME_BINFO_TYPE_P (BINFO_TYPE (direct_binfo), basetype))
break;
/* Look for a virtual base -- unless the direct base is itself
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.328
diff -c -3 -p -r1.328 search.c
*** cp/search.c 10 Oct 2004 21:36:37 -0000 1.328
--- cp/search.c 11 Oct 2004 15:10:21 -0000
*************** lookup_base_r (tree binfo, tree base, ba
*** 90,96 ****
tree base_binfo;
base_kind found = bk_not_base;
! if (same_type_p (BINFO_TYPE (binfo), base))
{
/* We have found a base. Check against what we have found
already. */
--- 90,96 ----
tree base_binfo;
base_kind found = bk_not_base;
! if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), base))
{
/* We have found a base. Check against what we have found
already. */
*************** dynamic_cast_base_recurse (tree subtype,
*** 279,285 ****
int i;
int worst = -2;
! if (BINFO_TYPE (binfo) == subtype)
{
if (is_via_virtual)
return -1;
--- 279,285 ----
int i;
int worst = -2;
! if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), subtype))
{
if (is_via_virtual)
return -1;
*************** binfo_from_vbase (tree binfo)
*** 2346,2352 ****
tree
binfo_via_virtual (tree binfo, tree limit)
{
! for (; binfo && (!limit || !same_type_p (BINFO_TYPE (binfo), limit));
binfo = BINFO_INHERITANCE_CHAIN (binfo))
{
if (BINFO_VIRTUAL_P (binfo))
--- 2346,2352 ----
tree
binfo_via_virtual (tree binfo, tree limit)
{
! for (; binfo && !SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), limit);
binfo = BINFO_INHERITANCE_CHAIN (binfo))
{
if (BINFO_VIRTUAL_P (binfo))
*************** copied_binfo (tree binfo, tree here)
*** 2382,2388 ****
cbinfo = copied_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
for (ix = 0; BINFO_BASE_ITERATE (cbinfo, ix, base_binfo); ix++)
! if (BINFO_TYPE (base_binfo) == BINFO_TYPE (binfo))
{
result = base_binfo;
break;
--- 2382,2388 ----
cbinfo = copied_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
for (ix = 0; BINFO_BASE_ITERATE (cbinfo, ix, base_binfo); ix++)
! if (SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo), BINFO_TYPE (binfo)))
{
result = base_binfo;
break;
*************** copied_binfo (tree binfo, tree here)
*** 2390,2396 ****
}
else
{
! gcc_assert (BINFO_TYPE (here) == BINFO_TYPE (binfo));
result = here;
}
--- 2390,2396 ----
}
else
{
! gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (here), BINFO_TYPE (binfo)));
result = here;
}
*************** binfo_for_vbase (tree base, tree t)
*** 2407,2413 ****
for (vbases = CLASSTYPE_VBASECLASSES (t), ix = 0;
VEC_iterate (tree, vbases, ix, binfo); ix++)
! if (BINFO_TYPE (binfo) == base)
return binfo;
return NULL;
}
--- 2407,2413 ----
for (vbases = CLASSTYPE_VBASECLASSES (t), ix = 0;
VEC_iterate (tree, vbases, ix, binfo); ix++)
! if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), base))
return binfo;
return NULL;
}
*************** original_binfo (tree binfo, tree here)
*** 2422,2428 ****
{
tree result = NULL;
! if (BINFO_TYPE (binfo) == BINFO_TYPE (here))
result = here;
else if (BINFO_VIRTUAL_P (binfo))
result = (CLASSTYPE_VBASECLASSES (BINFO_TYPE (here))
--- 2422,2428 ----
{
tree result = NULL;
! if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (here)))
result = here;
else if (BINFO_VIRTUAL_P (binfo))
result = (CLASSTYPE_VBASECLASSES (BINFO_TYPE (here))
*************** original_binfo (tree binfo, tree here)
*** 2439,2445 ****
tree base_binfo;
for (ix = 0; (base_binfo = BINFO_BASE_BINFO (base_binfos, ix)); ix++)
! if (BINFO_TYPE (base_binfo) == BINFO_TYPE (binfo))
{
result = base_binfo;
break;
--- 2439,2446 ----
tree base_binfo;
for (ix = 0; (base_binfo = BINFO_BASE_BINFO (base_binfos, ix)); ix++)
! if (SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo),
! BINFO_TYPE (binfo)))
{
result = base_binfo;
break;
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.415
diff -c -3 -p -r1.415 tree.c
*** cp/tree.c 10 Oct 2004 21:36:37 -0000 1.415
--- cp/tree.c 11 Oct 2004 15:10:25 -0000
*************** copy_binfo (tree binfo, tree type, tree
*** 611,617 ****
tree base_binfo;
gcc_assert (!BINFO_DEPENDENT_BASE_P (binfo));
! gcc_assert (type == BINFO_TYPE (binfo));
BINFO_OFFSET (new_binfo) = BINFO_OFFSET (binfo);
BINFO_VIRTUALS (new_binfo) = BINFO_VIRTUALS (binfo);
--- 611,617 ----
tree base_binfo;
gcc_assert (!BINFO_DEPENDENT_BASE_P (binfo));
! gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), type));
BINFO_OFFSET (new_binfo) = BINFO_OFFSET (binfo);
BINFO_VIRTUALS (new_binfo) = BINFO_VIRTUALS (binfo);