This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] improve C++ code by changing fold-const.c
- From: Roger Sayle <roger at eyesopen dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: Andrew Pinski <pinskia at physics dot uc dot edu>, Mark Mitchell <mark at codesourcery dot com>, <law at redhat dot com>, <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 28 May 2004 11:32:47 -0600 (MDT)
- Subject: Re: [PATCH] improve C++ code by changing fold-const.c
On Thu, 27 May 2004, Richard Henderson wrote:
> Did I not just say? Both C and C++ do not unify all appearances of
> a single type into a single tree node (and also fail to link them
> via TYPE_MAIN_VARIANT). Pointer equality IS NOT SUFFICIENT given
> the current state of these front ends!
The miscommunication appears to be that you believe that pointer
equality should be sufficient for ANY front-end. My argument is
that this shouldn't be a language hook, because Java, fortran,
pascal, treelang and GCC's other front-end would benefit from a
generic middle-end "types_compatible_p". In fact, there's very little
language specific about the C types_compatible_lang hook, other than it
only discards qualifications at the outer level (probably a bug).
I was thinking about something like:
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.373
diff -c -3 -p -r1.373 tree.c
*** tree.c 21 May 2004 00:54:35 -0000 1.373
--- tree.c 28 May 2004 17:12:06 -0000
*************** needs_to_live_in_memory (tree t)
*** 5577,5580 ****
--- 5577,5637 ----
|| decl_function_context (t) != current_function_decl);
}
+ /* This compares two types for equivalence ("compatible" in C and C++).
+ This routine should only return 1 if it is sure. It should not be used
+ in contexts where erroneously returning 0 causes problems. */
+
+ int
+ types_compatible_p (tree x, tree y)
+ {
+ if (TREE_CODE_CLASS (TREE_CODE (x)) != 't'
+ || TREE_CODE_CLASS (TREE_CODE (y)) != 't')
+ return 0;
+
+ /* Work with unqualified types. */
+ x = TYPE_MAIN_VARIANT (x);
+ y = TYPE_MAIN_VARIANT (y);
+
+ if (x == y)
+ return 1;
+
+ if (TREE_CODE (x) != TREE_CODE (y))
+ return 0;
+
+ switch (TREE_CODE (x))
+ {
+ case VOID_TYPE:
+ case BOOLEAN_TYPE:
+ return 1;
+
+ case INTEGER_TYPE:
+ case ENUMERAL_TYPE:
+ return TYPE_PRECISION (x) == TYPE_PRECISION (y)
+ && TYPE_UNSIGNED (x) == TYPE_UNSIGNED (y);
+
+ case REAL_TYPE:
+ return TYPE_PRECISION (x) == TYPE_PRECISION (y);
+
+ case COMPLEX_TYPE:
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ return types_compatible_p (TREE_TYPE (x), TREE_TYPE (y));
+
+ case ARRAY_TYPE:
+ if (! types_compatible_p (TREE_TYPE (x), TREE_TYPE (y))
+ return 0;
+ if (TYPE_DOMAIN (x) != 0 && TYPE_DOMAIN (y) != 0)
+ {
+ tree mx = TYPE_MAX_VALUE (TYPE_DOMAIN (x));
+ tree my = TYPE_MAX_VALUE (TYPE_DOMAIN (y));
+ return mx && my && tree_int_cst_equal (mx, my);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+ }
+
#include "gt-tree.h"
Notice that this type equivalence is completely language neutral, solves
the problem that pointer equality is not sufficient, not only for C, but
also for the other front-ends. Its certainly superior to the default
language hook currently used by the non-C-family front-ends.
The GCC internals documentation for tree types, at the very bottom, hints
at the existance of a same_type_p function, but this is only available in
the C++ front-end. And testing for strict equality seems less useful than
unqualified structural equivalence (as implied by types_compatible_p).
I'm wasn't arguing that pointer equality is or should be sufficient, but
that the real problem is that this affects all front-ends, and therefore
a new langhook is a less than ideal solution.
> This is insane.
Crazy as a fox!
> > As explained above, that C++ and Java require the same anti-abstraction
> > optimizations is the reason that types_compatible_p is inappropriate.
>
> As is this.
Hopefully this makes more sense now.
Roger
--