This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to build_vtbl_ref_1
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 13 May 2002 08:59:38 +0100
- Subject: C++ PATCH to build_vtbl_ref_1
While fiddling with vtable pointer optimization, I noticed that
build_vtbl_ref_1 was doing some of the job of fixed_type_or_null; I've
fixed that.
This patch also sets TREE_CONSTANT on references to vtable contents, which
are fixed at compile time.
Tested i686-pc-linux-gnu, applied trunk.
2002-05-13 Jason Merrill <jason@redhat.com>
* class.c (build_vtbl_ref_1): Use fixed_type_or_null.
(fixed_type_or_null): See through reference vars.
(build_base_path): Vtable contents are constant.
* typeck.c (get_member_function_from_ptrfunc): Likewise.
*** class.c.~1~ Sun May 12 10:24:55 2002
--- class.c Fri May 10 00:49:58 2002
*************** build_base_path (code, expr, binfo, nonn
*** 316,322 ****
build_pointer_type (ptrdiff_type_node),
v_offset);
v_offset = build_indirect_ref (v_offset, NULL);
!
offset = cp_convert (ptrdiff_type_node,
size_diffop (offset, BINFO_OFFSET (v_binfo)));
--- 316,323 ----
build_pointer_type (ptrdiff_type_node),
v_offset);
v_offset = build_indirect_ref (v_offset, NULL);
! TREE_CONSTANT (v_offset) = 1;
!
offset = cp_convert (ptrdiff_type_node,
size_diffop (offset, BINFO_OFFSET (v_binfo)));
*************** static tree
*** 401,475 ****
build_vtbl_ref_1 (instance, idx)
tree instance, idx;
{
! tree vtbl, aref;
! tree basetype = TREE_TYPE (instance);
if (TREE_CODE (basetype) == REFERENCE_TYPE)
basetype = TREE_TYPE (basetype);
! if (instance == current_class_ref)
! vtbl = build_vfield_ref (instance, basetype);
! else
{
! if (optimize)
! {
! /* Try to figure out what a reference refers to, and
! access its virtual function table directly. */
! tree ref = NULL_TREE;
!
! if (TREE_CODE (instance) == INDIRECT_REF
! && TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE)
! ref = TREE_OPERAND (instance, 0);
! else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
! ref = instance;
!
! if (ref && TREE_CODE (ref) == VAR_DECL
! && DECL_INITIAL (ref))
! {
! tree init = DECL_INITIAL (ref);
!
! while (TREE_CODE (init) == NOP_EXPR
! || TREE_CODE (init) == NON_LVALUE_EXPR)
! init = TREE_OPERAND (init, 0);
! if (TREE_CODE (init) == ADDR_EXPR)
! {
! init = TREE_OPERAND (init, 0);
! if (IS_AGGR_TYPE (TREE_TYPE (init))
! && (TREE_CODE (init) == PARM_DECL
! || TREE_CODE (init) == VAR_DECL))
! instance = init;
! }
! }
! }
! if (IS_AGGR_TYPE (TREE_TYPE (instance))
! && (TREE_CODE (instance) == RESULT_DECL
! || TREE_CODE (instance) == PARM_DECL
! || TREE_CODE (instance) == VAR_DECL))
! {
! vtbl = TYPE_BINFO_VTABLE (basetype);
! /* Knowing the dynamic type of INSTANCE we can easily obtain
! the correct vtable entry. We resolve this back to be in
! terms of the primary vtable. */
! if (TREE_CODE (vtbl) == PLUS_EXPR)
! {
! idx = fold (build (PLUS_EXPR,
! TREE_TYPE (idx),
! idx,
! build (EXACT_DIV_EXPR,
! TREE_TYPE (idx),
! TREE_OPERAND (vtbl, 1),
! TYPE_SIZE_UNIT (vtable_entry_type))));
! vtbl = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
! }
! }
! else
! vtbl = build_vfield_ref (instance, basetype);
}
assemble_external (vtbl);
aref = build_array_ref (vtbl, idx);
return aref;
}
--- 402,437 ----
build_vtbl_ref_1 (instance, idx)
tree instance, idx;
{
! tree aref;
! tree vtbl = NULL_TREE;
+ /* Try to figure out what a reference refers to, and
+ access its virtual function table directly. */
+
+ int cdtorp = 0;
+ tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);
+
+ tree basetype = TREE_TYPE (instance);
if (TREE_CODE (basetype) == REFERENCE_TYPE)
basetype = TREE_TYPE (basetype);
! if (fixed_type && !cdtorp)
{
! tree binfo = lookup_base (fixed_type, basetype,
! ba_ignore|ba_quiet, NULL);
! if (binfo)
! vtbl = BINFO_VTABLE (binfo);
! }
! if (!vtbl)
! {
! vtbl = build_vfield_ref (instance, basetype);
}
assemble_external (vtbl);
aref = build_array_ref (vtbl, idx);
+ TREE_CONSTANT (aref) = 1;
return aref;
}
*************** fixed_type_or_null (instance, nonnull, c
*** 5396,5402 ****
return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
/* Propagate nonnull. */
! fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
return NULL_TREE;
case NOP_EXPR:
--- 5358,5364 ----
return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
/* Propagate nonnull. */
! return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
return NULL_TREE;
case NOP_EXPR:
*************** fixed_type_or_null (instance, nonnull, c
*** 5423,5428 ****
--- 5385,5391 ----
/* fall through... */
case TARGET_EXPR:
case PARM_DECL:
+ case RESULT_DECL:
if (IS_AGGR_TYPE (TREE_TYPE (instance)))
{
if (nonnull)
*************** fixed_type_or_null (instance, nonnull, c
*** 5449,5454 ****
--- 5412,5422 ----
/* Reference variables should be references to objects. */
if (nonnull)
*nonnull = 1;
+
+ if (TREE_CODE (instance) == VAR_DECL
+ && DECL_INITIAL (instance))
+ return fixed_type_or_null (DECL_INITIAL (instance),
+ nonnull, cdtorp);
}
return NULL_TREE;
*** typeck.c.~1~ Sun May 12 10:24:55 2002
--- typeck.c Fri May 10 00:36:55 2002
*************** get_member_function_from_ptrfunc (instan
*** 2911,2916 ****
--- 2911,2917 ----
/* Finally, extract the function pointer from the vtable. */
e2 = fold (build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx));
e2 = build_indirect_ref (e2, NULL);
+ TREE_CONSTANT (e2) = 1;
/* When using function descriptors, the address of the
vtable entry is treated as a function pointer. */