aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2002-04-14 09:14:52 -0400
committerJason Merrill <jason@gcc.gnu.org>2002-04-14 09:14:52 -0400
commit85b7def6e0f1ca6f4e2af553ab9853b7dad3bf55 (patch)
tree132fd9f681e45411ec8fbf486bcd05062b045407
parentcf56e373c4b75dd96e6521637217d47261cb6b8f (diff)
downloadgcc-85b7def6e0f1ca6f4e2af553ab9853b7dad3bf55.zip
gcc-85b7def6e0f1ca6f4e2af553ab9853b7dad3bf55.tar.gz
gcc-85b7def6e0f1ca6f4e2af553ab9853b7dad3bf55.tar.bz2
typeck.c (get_member_function_from_ptrfunc): Don't do gratuitious division and multiplication on ptrmemfunc_vbit_in_delta...
* typeck.c (get_member_function_from_ptrfunc): Don't do gratuitious division and multiplication on ptrmemfunc_vbit_in_delta targets. From-SVN: r52293
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/typeck.c23
2 files changed, 16 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e615310..d7755fd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2002-04-14 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Don't do
+ gratuitious division and multiplication on
+ ptrmemfunc_vbit_in_delta targets.
+
2002-04-12 Mark Mitchell <mark@codesourcery.com>
PR c++/5373.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 7ccbee9..060097ab 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2833,6 +2833,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
{
tree fntype, idx, e1, delta, delta2, e2, e3, vtbl;
tree instance, basetype;
+ tree mask;
tree instance_ptr = *instance_ptrptr;
@@ -2864,7 +2865,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
return instance;
e3 = PFN_FROM_PTRMEMFUNC (function);
-
+
vtbl = build1 (NOP_EXPR, build_pointer_type (ptr_type_node), instance);
TREE_CONSTANT (vtbl) = TREE_CONSTANT (instance);
@@ -2879,20 +2880,14 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
to pointer-to-base-member, as long as the dynamic object
later has the right member. */
- /* Promoting idx before saving it improves performance on RISC
- targets. Without promoting, the first compare used
- load-with-sign-extend, while the second used normal load then
- shift to sign-extend. An optimizer flaw, perhaps, but it's
- easier to make this change. */
- idx = cp_build_binary_op (TRUNC_DIV_EXPR,
- build1 (NOP_EXPR, vtable_index_type, e3),
- TYPE_SIZE_UNIT (vtable_entry_type));
+ idx = build1 (NOP_EXPR, vtable_index_type, e3);
switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
{
case ptrmemfunc_vbit_in_pfn:
- e1 = cp_build_binary_op (BIT_AND_EXPR,
- build1 (NOP_EXPR, vtable_index_type, e3),
- integer_one_node);
+ /* Mask out the virtual bit from the index. */
+ e1 = cp_build_binary_op (BIT_AND_EXPR, idx, integer_one_node);
+ mask = build1 (NOP_EXPR, vtable_index_type, build_int_2 (~1, ~0));
+ idx = cp_build_binary_op (BIT_AND_EXPR, idx, mask);
break;
case ptrmemfunc_vbit_in_delta:
@@ -2916,7 +2911,9 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
build_pointer_type (build_pointer_type (vtable_entry_type)),
vtbl, cp_convert (ptrdiff_type_node, delta2));
vtbl = build_indirect_ref (vtbl, NULL);
- e2 = build_array_ref (vtbl, idx);
+
+ e2 = fold (build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx));
+ e2 = build_indirect_ref (e2, NULL);
/* When using function descriptors, the address of the
vtable entry is treated as a function pointer. */