diff mbox

[4/n] Merge from match-and-simplify, hook into fold-const.c

Message ID alpine.LSU.2.11.1410151352510.20733@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Oct. 15, 2014, 11:53 a.m. UTC
This hooks the machinery into the GENERIC folders in fold-const.c.

For re-simplification and tree building generic_simplify uses
the fold_buildN API which remains the API to use - this is also
why I don't expose generic_simplify in any header.

To give you an example how it looks like, the following code is
generated for

/* fold_negate_exprs convert - (~A) to A + 1.  */
(simplify
 (negate (bit_not @0))
 (if (INTEGRAL_TYPE_P (type))
  (plus @0 { build_int_cst (TREE_TYPE (@0), 1); } )))

tree
generic_simplify (enum tree_code code, tree type ATTRIBUTE_UNUSED, tree op0)
{
  if ((op0 && TREE_SIDE_EFFECTS (op0)))
    return NULL_TREE;
  switch (code)
    {
...
    case NEGATE_EXPR:
      {
        switch (TREE_CODE (op0))
          {
          case BIT_NOT_EXPR:
            {
              tree o20 = TREE_OPERAND (op0, 0);
                {
                  /* #line 136 "/space/rguenther/src/svn/match-and-simplify/gcc/match.pd" */
                  tree captures[2] ATTRIBUTE_UNUSED = {};
                  captures[0] = o20;
                  /* #line 135 "/space/rguenther/src/svn/match-and-simplify/gcc/match.pd" */
                  if (INTEGRAL_TYPE_P (type))
                    {
                      if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Applying pattern match.pd:136, %s:%d\n", __FILE__, __LINE__);
                      tree res_op0;
                      res_op0 = captures[0];
                      tree res_op1;
                      res_op1 =  build_int_cst (TREE_TYPE (captures[0]), 1);
                      return fold_build2 (PLUS_EXPR, type, res_op0, res_op1);
                    }
                }
              break;
            }
...

where you can see the side-effects issue I mentioned earlier.

Ok for trunk?

Thanks,
Richard.


2014-10-15  Richard Biener  <rguenther@suse.de>

	* fold-const.c (fold_unary_loc): Dispatch to generic_simplify.
	(fold_binary_loc): Likewise.
	(fold_ternary_loc): Likewise.

Comments

Sebastian Pop Oct. 16, 2014, 6:58 p.m. UTC | #1
Richard Biener wrote:
> To give you an example how it looks like, the following code is
> generated for
> 
> /* fold_negate_exprs convert - (~A) to A + 1.  */
> (simplify
>  (negate (bit_not @0))
>  (if (INTEGRAL_TYPE_P (type))
>   (plus @0 { build_int_cst (TREE_TYPE (@0), 1); } )))
> 
> tree
> generic_simplify (enum tree_code code, tree type ATTRIBUTE_UNUSED, tree op0)

I wonder why ATTRIBUTE_UNUSED is generated for used parameters.

> {
>   if ((op0 && TREE_SIDE_EFFECTS (op0)))
>     return NULL_TREE;
>   switch (code)
>     {
> ...
>     case NEGATE_EXPR:
>       {
>         switch (TREE_CODE (op0))
>           {
>           case BIT_NOT_EXPR:
>             {
>               tree o20 = TREE_OPERAND (op0, 0);
>                 {
>                   /* #line 136 "/space/rguenther/src/svn/match-and-simplify/gcc/match.pd" */
>                   tree captures[2] ATTRIBUTE_UNUSED = {};

Same here.
Also, why do we allocate two elements when only captures[0] is used?

>                   captures[0] = o20;
>                   /* #line 135 "/space/rguenther/src/svn/match-and-simplify/gcc/match.pd" */
>                   if (INTEGRAL_TYPE_P (type))
>                     {
>                       if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Applying pattern match.pd:136, %s:%d\n", __FILE__, __LINE__);
>                       tree res_op0;
>                       res_op0 = captures[0];
>                       tree res_op1;
>                       res_op1 =  build_int_cst (TREE_TYPE (captures[0]), 1);
>                       return fold_build2 (PLUS_EXPR, type, res_op0, res_op1);
>                     }
>                 }
>               break;
>             }
> ...
Jakub Jelinek Oct. 16, 2014, 7:14 p.m. UTC | #2
On Thu, Oct 16, 2014 at 06:58:25PM +0000, Sebastian Pop wrote:
> Richard Biener wrote:
> > To give you an example how it looks like, the following code is
> > generated for
> > 
> > /* fold_negate_exprs convert - (~A) to A + 1.  */
> > (simplify
> >  (negate (bit_not @0))
> >  (if (INTEGRAL_TYPE_P (type))
> >   (plus @0 { build_int_cst (TREE_TYPE (@0), 1); } )))
> > 
> > tree
> > generic_simplify (enum tree_code code, tree type ATTRIBUTE_UNUSED, tree op0)
> 
> I wonder why ATTRIBUTE_UNUSED is generated for used parameters.

Generally, if an argument is never used (but desirable anyway), we shouldn't
name it, if it is conditionally used (e.g. used by some macros that might
or might not use the argument in the end), then ATTRIBUTE_USED should be
used.  Haven't checked which case is this.

	Jakub
Trevor Saunders Oct. 17, 2014, 5:39 a.m. UTC | #3
On Thu, Oct 16, 2014 at 09:14:18PM +0200, Jakub Jelinek wrote:
> On Thu, Oct 16, 2014 at 06:58:25PM +0000, Sebastian Pop wrote:
> > Richard Biener wrote:
> > > To give you an example how it looks like, the following code is
> > > generated for
> > > 
> > > /* fold_negate_exprs convert - (~A) to A + 1.  */
> > > (simplify
> > >  (negate (bit_not @0))
> > >  (if (INTEGRAL_TYPE_P (type))
> > >   (plus @0 { build_int_cst (TREE_TYPE (@0), 1); } )))
> > > 
> > > tree
> > > generic_simplify (enum tree_code code, tree type ATTRIBUTE_UNUSED, tree op0)
> > 
> > I wonder why ATTRIBUTE_UNUSED is generated for used parameters.
> 
> Generally, if an argument is never used (but desirable anyway), we shouldn't
> name it, if it is conditionally used (e.g. used by some macros that might
> or might not use the argument in the end), then ATTRIBUTE_USED should be
> used.  Haven't checked which case is this.

Well, I think part of the reason is the autogeneratedness of the code,
its just easier to make the codegen not worry about how many are
actually used, and fwiw gengtype does the same sort of thing.

Trev

> 
> 	Jakub
Richard Biener Oct. 17, 2014, 7:45 a.m. UTC | #4
On Thu, 16 Oct 2014, Sebastian Pop wrote:

> Richard Biener wrote:
> > To give you an example how it looks like, the following code is
> > generated for
> > 
> > /* fold_negate_exprs convert - (~A) to A + 1.  */
> > (simplify
> >  (negate (bit_not @0))
> >  (if (INTEGRAL_TYPE_P (type))
> >   (plus @0 { build_int_cst (TREE_TYPE (@0), 1); } )))
> > 
> > tree
> > generic_simplify (enum tree_code code, tree type ATTRIBUTE_UNUSED, tree op0)
> 
> I wonder why ATTRIBUTE_UNUSED is generated for used parameters.

I've added them for the initial patch set because without any patterns
defined (just 1/n and 2/n) only one of the parameters will be used.

Consider them removed again once we have enough patterns to make
bootstrap happy after that.

> > {
> >   if ((op0 && TREE_SIDE_EFFECTS (op0)))
> >     return NULL_TREE;
> >   switch (code)
> >     {
> > ...
> >     case NEGATE_EXPR:
> >       {
> >         switch (TREE_CODE (op0))
> >           {
> >           case BIT_NOT_EXPR:
> >             {
> >               tree o20 = TREE_OPERAND (op0, 0);
> >                 {
> >                   /* #line 136 "/space/rguenther/src/svn/match-and-simplify/gcc/match.pd" */
> >                   tree captures[2] ATTRIBUTE_UNUSED = {};
> 
> Same here.
> Also, why do we allocate two elements when only captures[0] is used?

Good question - I'll have a look.

Thanks,
Richard.

> >                   captures[0] = o20;
> >                   /* #line 135 "/space/rguenther/src/svn/match-and-simplify/gcc/match.pd" */
> >                   if (INTEGRAL_TYPE_P (type))
> >                     {
> >                       if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Applying pattern match.pd:136, %s:%d\n", __FILE__, __LINE__);
> >                       tree res_op0;
> >                       res_op0 = captures[0];
> >                       tree res_op1;
> >                       res_op1 =  build_int_cst (TREE_TYPE (captures[0]), 1);
> >                       return fold_build2 (PLUS_EXPR, type, res_op0, res_op1);
> >                     }
> >                 }
> >               break;
> >             }
> > ...
> 
>
diff mbox

Patch

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(svn+ssh://rguenth@gcc.gnu.org/svn/gcc/trunk/gcc/fold-const.c)	(revision 216234)
+++ gcc/fold-const.c	(.../gcc/fold-const.c)	(working copy)
@@ -7564,6 +7563,11 @@  fold_unary_loc (location_t loc, enum tre
   gcc_assert (IS_EXPR_CODE_CLASS (kind)
 	      && TREE_CODE_LENGTH (code) == 1);
 
+  extern tree generic_simplify (enum tree_code, tree, tree);
+  tem = generic_simplify (code, type, op0);
+  if (tem)
+    return tem;
+
   arg0 = op0;
   if (arg0)
     {
@@ -9909,6 +9913,11 @@  fold_binary_loc (location_t loc,
 	}
     }
 
+  extern tree generic_simplify (enum tree_code, tree, tree, tree);
+  tem = generic_simplify (code, type, op0, op1);
+  if (tem)
+    return tem;
+
   /* If this is a commutative operation, and ARG0 is a constant, move it
      to ARG1 to reduce the number of tests below.  */
   if (commutative_tree_code (code)
@@ -13799,6 +13808,11 @@  fold_ternary_loc (location_t loc, enum t
   gcc_assert (IS_EXPR_CODE_CLASS (kind)
 	      && TREE_CODE_LENGTH (code) == 3);
 
+  extern tree generic_simplify (enum tree_code, tree, tree, tree, tree);
+  tem = generic_simplify (code, type, op0, op1, op2);
+  if (tem)
+    return tem;
+
   /* Strip any conversions that don't change the mode.  This is safe
      for every expression, except for a comparison expression because
      its signedness is derived from its operands.  So, in the latter