This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Re: fold_builtin_memcpy cannot optimize <retval>? (take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Mark Mitchell <mark at codesourcery dot com>
- Cc: law at redhat dot com, Richard Guenther <rguenth at tat dot physik dot uni-tuebingen dot de>, gcc-patches at gcc dot gnu dot org
- Date: Fri, 21 Jan 2005 16:51:38 -0500
- Subject: [PATCH] Re: fold_builtin_memcpy cannot optimize <retval>? (take 2)
- References: <Pine.LNX.4.44.0501211136170.16464-100000@alwazn.tat.physik.uni-tuebingen.de> <20050121105158.GH4777@sunsite.mff.cuni.cz> <1106330271.30575.265.camel@localhost.localdomain> <41F14409.8000200@codesourcery.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Fri, Jan 21, 2005 at 10:03:53AM -0800, Mark Mitchell wrote:
> Jeffrey A Law wrote:
>
> >I'm not an expert on the differences in the semantics of POINTER_TYPE
> >and REFERENCE_TYPE, but I do know that I've been treating them as
> >effectively the same.
>
> The only difference is that a REFERENCE_TYPE object can never be NULL.
> Other than that, they are identical. (In C++, you cannot assign to a
> reference, but that is expressed by TREE_READONLY on the object.)
>
> I think that it makes sense to use POINTER_TYPE_P almost everywhere in
> the middle-end. The other choices is to introduce explicit NOP_EXPRs to
> do the conversions -- but that's just a waste of memory, in my opinion.
Is this ok to commit then assuming bootstrap/regtest are ok?
Certainly cures the testcase.
2005-01-21 Jakub Jelinek <jakub@redhat.com>
* builtins.c (get_pointer_alignment, gimplify_va_arg_expr,
expand_builtin_printf, expand_builtin_fprintf,
expand_builtin_sprintf): Use POINTER_TYPE_P instead TREE_CODE
checking against POINTER_TYPE.
(validate_arglist): Handle POINTER_TYPE code by checking
POINTER_TYPE_P.
* g++.dg/tree-ssa/empty-1.C: New test.
--- gcc/builtins.c.jj 2005-01-13 21:25:42.000000000 +0100
+++ gcc/builtins.c 2005-01-21 22:46:16.495272151 +0100
@@ -201,7 +201,7 @@ get_pointer_alignment (tree exp, unsigne
{
unsigned int align, inner;
- if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
+ if (! POINTER_TYPE_P (TREE_TYPE (exp)))
return 0;
align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
@@ -215,7 +215,7 @@ get_pointer_alignment (tree exp, unsigne
case CONVERT_EXPR:
case NON_LVALUE_EXPR:
exp = TREE_OPERAND (exp, 0);
- if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
+ if (! POINTER_TYPE_P (TREE_TYPE (exp)))
return align;
inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
@@ -3988,7 +3988,7 @@ gimplify_va_arg_expr (tree *expr_p, tree
In that case, unwrap both types so that we can compare the
underlying records. */
if (TREE_CODE (have_va_type) == ARRAY_TYPE
- || TREE_CODE (have_va_type) == POINTER_TYPE)
+ || POINTER_TYPE_P (have_va_type))
{
want_va_type = TREE_TYPE (want_va_type);
have_va_type = TREE_TYPE (have_va_type);
@@ -4486,7 +4486,7 @@ expand_builtin_printf (tree arglist, rtx
if (! arglist)
return 0;
fmt = TREE_VALUE (arglist);
- if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
+ if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
return 0;
arglist = TREE_CHAIN (arglist);
@@ -4499,7 +4499,7 @@ expand_builtin_printf (tree arglist, rtx
if (strcmp (fmt_str, "%s\n") == 0)
{
if (! arglist
- || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
+ || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
|| TREE_CHAIN (arglist))
return 0;
fn = fn_puts;
@@ -4588,13 +4588,13 @@ expand_builtin_fprintf (tree arglist, rt
if (! arglist)
return 0;
fp = TREE_VALUE (arglist);
- if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
+ if (! POINTER_TYPE_P (TREE_TYPE (fp)))
return 0;
arglist = TREE_CHAIN (arglist);
if (! arglist)
return 0;
fmt = TREE_VALUE (arglist);
- if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
+ if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
return 0;
arglist = TREE_CHAIN (arglist);
@@ -4607,7 +4607,7 @@ expand_builtin_fprintf (tree arglist, rt
if (strcmp (fmt_str, "%s") == 0)
{
if (! arglist
- || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
+ || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
|| TREE_CHAIN (arglist))
return 0;
arg = TREE_VALUE (arglist);
@@ -4675,13 +4675,13 @@ expand_builtin_sprintf (tree arglist, rt
if (! arglist)
return 0;
dest = TREE_VALUE (arglist);
- if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
+ if (! POINTER_TYPE_P (TREE_TYPE (dest)))
return 0;
arglist = TREE_CHAIN (arglist);
if (! arglist)
return 0;
fmt = TREE_VALUE (arglist);
- if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
+ if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
return 0;
arglist = TREE_CHAIN (arglist);
@@ -4717,7 +4717,7 @@ expand_builtin_sprintf (tree arglist, rt
if (! arglist || TREE_CHAIN (arglist))
return 0;
arg = TREE_VALUE (arglist);
- if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
+ if (! POINTER_TYPE_P (TREE_TYPE (arg)))
return 0;
if (target != const0_rtx)
@@ -8054,6 +8054,15 @@ validate_arglist (tree arglist, ...)
true, otherwise return false. */
res = arglist == 0;
goto end;
+ case POINTER_TYPE:
+ /* If no parameters remain or the parameter's code does not
+ match the specified code, return false. Otherwise continue
+ checking any remaining arguments. POINTER_TYPE is handled
+ specially, because REFERENCE_TYPE should match it as well. */
+ if (arglist == 0
+ || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
+ goto end;
+ break;
default:
/* If no parameters remain or the parameter's code does not
match the specified code, return false. Otherwise continue
--- gcc/testsuite/g++.dg/tree-ssa/empty-1.C.jj 2005-01-21 15:45:06.000000000 +0100
+++ gcc/testsuite/g++.dg/tree-ssa/empty-1.C 2005-01-21 15:46:07.000000000 +0100
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+struct S {};
+S bar (const S &a)
+{
+ S s;
+ s = a;
+ return s;
+}
+
+/* Test whether memcpy call has been optimized out. */
+/* { dg-final { scan-tree-dump-times "memcpy" 0 "optimized"} } */
Jakub