mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 05:30:24 +08:00
Treat ADDR_EXPR and CONSTRUCTOR as GIMPLE/GENERIC magically
The following allows to match ADDR_EXPR for both the invariant &a.b case as well as the &p->d case in a separate definition transparently. This also allows to remove the hack we employ for CONSTRUCTOR which we handle for example with (match vec_same_elem_p CONSTRUCTOR@0 (if (TREE_CODE (@0) == SSA_NAME && uniform_vector_p (gimple_assign_rhs1 (SSA_NAME_DEF_STMT (@0)))))) Note CONSTUCTORs always appear as separate definition in GIMPLE, but I continue to play safe and ADDR_EXPRs are now matched in both places where previously ADDR_EXPR@0 would have missed the &p->x case. This is a prerequesite for the PR89317 fix. * genmatch.cc (dt_node::gen_kids): Handle ADDR_EXPR in both the GENERIC and GIMPLE op position. (dt_simplify::gen): Capture both GENERIC and GIMPLE op position for ADDR_EXPR and CONSTRUCTOR. * match.pd: Simplify CONSTRUCTOR leaf handling. * gcc.dg/tree-ssa/forwprop-3.c: Adjust. * g++.dg/tree-ssa/pr31146-2.C: Likewise.
This commit is contained in:
parent
f8d136e50e
commit
26295a069f
@ -2927,8 +2927,16 @@ dt_node::gen_kids (FILE *f, int indent, bool gimple, int depth)
|
||||
if (expr *e = dyn_cast <expr *> (op->op))
|
||||
{
|
||||
if (e->ops.length () == 0
|
||||
/* In GIMPLE a CONSTRUCTOR always appears in a
|
||||
separate definition. */
|
||||
&& (!gimple || !(*e->operation == CONSTRUCTOR)))
|
||||
generic_exprs.safe_push (op);
|
||||
{
|
||||
generic_exprs.safe_push (op);
|
||||
/* But ADDR_EXPRs can appear directly when invariant
|
||||
and in a separate definition when not. */
|
||||
if (gimple && *e->operation == ADDR_EXPR)
|
||||
gimple_exprs.safe_push (op);
|
||||
}
|
||||
else if (e->operation->kind == id_base::FN)
|
||||
{
|
||||
if (gimple)
|
||||
@ -3599,14 +3607,26 @@ dt_simplify::gen (FILE *f, int indent, bool gimple, int depth ATTRIBUTE_UNUSED)
|
||||
if (s->capture_max >= 0)
|
||||
{
|
||||
char opname[20];
|
||||
fprintf_indent (f, indent, "tree captures[%u] ATTRIBUTE_UNUSED = { %s",
|
||||
s->capture_max + 1, indexes[0]->get_name (opname));
|
||||
fprintf_indent (f, indent, "tree captures[%u] ATTRIBUTE_UNUSED = {",
|
||||
s->capture_max + 1);
|
||||
|
||||
for (int i = 1; i <= s->capture_max; ++i)
|
||||
for (int i = 0; i <= s->capture_max; ++i)
|
||||
{
|
||||
if (!indexes[i])
|
||||
break;
|
||||
fprintf (f, ", %s", indexes[i]->get_name (opname));
|
||||
const char *opstr = indexes[i]->get_name (opname);
|
||||
expr *e = dyn_cast <expr *> (indexes[i]->op);
|
||||
fputs (i == 0 ? " " : ", ", f);
|
||||
if (e && gimple
|
||||
/* Transparently handle picking up CONSTRUCTOR and ADDR_EXPR
|
||||
leafs if they appear in a separate definition. */
|
||||
&& (*e->operation == CONSTRUCTOR
|
||||
|| *e->operation == ADDR_EXPR))
|
||||
fprintf (f, "(TREE_CODE (%s) == SSA_NAME "
|
||||
"? gimple_assign_rhs1 (SSA_NAME_DEF_STMT (%s)) : %s)",
|
||||
opstr, opstr, opstr);
|
||||
else
|
||||
fprintf (f, "%s", opstr);
|
||||
}
|
||||
fprintf (f, " };\n");
|
||||
}
|
||||
|
12
gcc/match.pd
12
gcc/match.pd
@ -3925,8 +3925,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
||||
(simplify
|
||||
(view_convert CONSTRUCTOR@0)
|
||||
(with
|
||||
{ tree ctor = (TREE_CODE (@0) == SSA_NAME
|
||||
? gimple_assign_rhs1 (SSA_NAME_DEF_STMT (@0)) : @0); }
|
||||
{ tree ctor = @0; }
|
||||
(switch
|
||||
(if (CONSTRUCTOR_NELTS (ctor) == 0)
|
||||
{ build_zero_cst (type); })
|
||||
@ -7292,8 +7291,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
||||
== tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (@0))))))))
|
||||
(with
|
||||
{
|
||||
tree ctor = (TREE_CODE (@0) == SSA_NAME
|
||||
? gimple_assign_rhs1 (SSA_NAME_DEF_STMT (@0)) : @0);
|
||||
tree ctor = @0;
|
||||
tree eltype = TREE_TYPE (TREE_TYPE (ctor));
|
||||
unsigned HOST_WIDE_INT width = tree_to_uhwi (TYPE_SIZE (eltype));
|
||||
unsigned HOST_WIDE_INT n = tree_to_uhwi (@1);
|
||||
@ -7941,8 +7939,7 @@ and,
|
||||
/* Fold reduction of a single nonzero element constructor. */
|
||||
(for reduc (IFN_REDUC_PLUS IFN_REDUC_IOR IFN_REDUC_XOR)
|
||||
(simplify (reduc (CONSTRUCTOR@0))
|
||||
(with { tree ctor = (TREE_CODE (@0) == SSA_NAME
|
||||
? gimple_assign_rhs1 (SSA_NAME_DEF_STMT (@0)) : @0);
|
||||
(with { tree ctor = @0;
|
||||
tree elt = ctor_single_nonzero_element (ctor); }
|
||||
(if (elt
|
||||
&& !HONOR_SNANS (type)
|
||||
@ -8161,8 +8158,7 @@ and,
|
||||
|
||||
(match vec_same_elem_p
|
||||
CONSTRUCTOR@0
|
||||
(if (TREE_CODE (@0) == SSA_NAME
|
||||
&& uniform_vector_p (gimple_assign_rhs1 (SSA_NAME_DEF_STMT (@0))))))
|
||||
(if (uniform_vector_p (@0))))
|
||||
|
||||
(match vec_same_elem_p
|
||||
@0
|
||||
|
@ -21,4 +21,4 @@ double foo (void)
|
||||
}
|
||||
|
||||
/* GCC 8 emits operator new () != NULL with -fcheck-new. */
|
||||
/* { dg-final { scan-tree-dump "Replaced .* != 0B. with .1" "forwprop1" } } */
|
||||
/* { dg-final { scan-tree-dump-times " != 0B\\)" 1 "forwprop1" } } */
|
||||
|
@ -14,4 +14,4 @@ int foo(struct bar *x)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "Replaced .p_. < q_.. with .1." "forwprop1" } } */
|
||||
/* { dg-final { scan-tree-dump "return 1;" "forwprop1" } } */
|
||||
|
Loading…
x
Reference in New Issue
Block a user