* typeck.c (get_member_function_from_ptrfunc): Don't do
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 14 Apr 2002 13:14:52 +0000 (13:14 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 14 Apr 2002 13:14:52 +0000 (13:14 +0000)
        gratuitious division and multiplication on
        ptrmemfunc_vbit_in_delta targets.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52293 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/typeck.c

index e615310..d7755fd 100644 (file)
@@ -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.
index 7ccbee9..060097a 100644 (file)
@@ -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.  */