Patchwork forwprop: bit_field_ref(constructor)

login
register
mail settings
Submitter Marc Glisse
Date Sept. 22, 2012, 9:17 p.m.
Message ID <alpine.DEB.2.02.1209222258440.14384@stedding.saclay.inria.fr>
Download mbox | patch
Permalink /patch/186170/
State New
Headers show

Comments

Marc Glisse - Sept. 22, 2012, 9:17 p.m.
Hello,

this patch lets forwprop fold bit_field_refs of constructors. It is 
particularly useful in forwprop4, which happens after the pass that lowers 
unsupported vector operations. Indeed, that pass keeps breaking vectors 
into pieces and reconstructing them for each operation, which is a waste 
when there are several operations in a row. This happens fairly late 
though, and dead constructors are left lying around (no dead code 
elimination after forwprop4) for the rtl layer to remove, so we are 
probably missing possible optimizations.

Bootstrap+testsuite ok (well, still about a thousand FAILs, but it doesn't 
increase with my patch).

2012-09-24  Marc Glisse  <marc.glisse@inria.fr>

gcc/
 	* tree-ssa-forwprop.c: Include tree-ssa-propagate.h.
 	(simplify_bitfield_ref): Handle constructors.
 	* Makefile.in (tree-ssa-forwprop.o): Depend on tree-ssa-propagate.h.

gcc/testsuite/
 	* gcc.dg/tree-ssa/forwprop-23.c: New testcase.
Richard Guenther - Sept. 24, 2012, 12:04 p.m.
On Sat, Sep 22, 2012 at 11:17 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
> Hello,
>
> this patch lets forwprop fold bit_field_refs of constructors. It is
> particularly useful in forwprop4, which happens after the pass that lowers
> unsupported vector operations. Indeed, that pass keeps breaking vectors into
> pieces and reconstructing them for each operation, which is a waste when
> there are several operations in a row. This happens fairly late though, and
> dead constructors are left lying around (no dead code elimination after
> forwprop4) for the rtl layer to remove, so we are probably missing possible
> optimizations.
>
> Bootstrap+testsuite ok (well, still about a thousand FAILs, but it doesn't
> increase with my patch).

Ok.

Thanks,
Richard.

> 2012-09-24  Marc Glisse  <marc.glisse@inria.fr>
>
> gcc/
>         * tree-ssa-forwprop.c: Include tree-ssa-propagate.h.
>         (simplify_bitfield_ref): Handle constructors.
>         * Makefile.in (tree-ssa-forwprop.o): Depend on tree-ssa-propagate.h.
>
> gcc/testsuite/
>         * gcc.dg/tree-ssa/forwprop-23.c: New testcase.
>
> --
> Marc Glisse
> Index: Makefile.in
> ===================================================================
> --- Makefile.in (revision 191644)
> +++ Makefile.in (working copy)
> @@ -2239,21 +2239,21 @@ tree-outof-ssa.o : tree-outof-ssa.c $(TR
>     $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) $(BITMAP_H) $(GGC_H) \
>     $(EXPR_H) $(SSAEXPAND_H) $(GIMPLE_PRETTY_PRINT_H)
>  tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
>     $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
>     $(TREE_FLOW_H) $(TREE_PASS_H) domwalk.h $(FLAGS_H) \
>     $(GIMPLE_PRETTY_PRINT_H) langhooks.h
>  tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H)
> coretypes.h \
>     $(TM_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \
>     $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
>     langhooks.h $(FLAGS_H) $(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H) $(EXPR_H) \
> -   $(OPTABS_H)
> +   $(OPTABS_H) tree-ssa-propagate.h
>  tree-ssa-phiprop.o : tree-ssa-phiprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h
> \
>     $(TM_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
>     $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
>     langhooks.h $(FLAGS_H) $(GIMPLE_PRETTY_PRINT_H)
>  tree-ssa-ifcombine.o : tree-ssa-ifcombine.c $(CONFIG_H) $(SYSTEM_H) \
>     coretypes.h $(TM_H) $(TREE_H) $(BASIC_BLOCK_H) \
>     $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
>     $(TREE_PRETTY_PRINT_H)
>  tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
>     $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
> Index: tree-ssa-forwprop.c
> ===================================================================
> --- tree-ssa-forwprop.c (revision 191644)
> +++ tree-ssa-forwprop.c (working copy)
> @@ -27,20 +27,21 @@ along with GCC; see the file COPYING3.
>  #include "basic-block.h"
>  #include "gimple-pretty-print.h"
>  #include "tree-flow.h"
>  #include "tree-pass.h"
>  #include "langhooks.h"
>  #include "flags.h"
>  #include "gimple.h"
>  #include "expr.h"
>  #include "cfgloop.h"
>  #include "optabs.h"
> +#include "tree-ssa-propagate.h"
>
>  /* This pass propagates the RHS of assignment statements into use
>     sites of the LHS of the assignment.  It's basically a specialized
>     form of tree combination.   It is hoped all of this can disappear
>     when we have a generalized tree combiner.
>
>     One class of common cases we handle is forward propagating a single use
>     variable into a COND_EXPR.
>
>       bb0:
> @@ -2575,39 +2576,49 @@ simplify_bitfield_ref (gimple_stmt_itera
>    enum tree_code code;
>
>    op = gimple_assign_rhs1 (stmt);
>    gcc_checking_assert (TREE_CODE (op) == BIT_FIELD_REF);
>
>    op0 = TREE_OPERAND (op, 0);
>    if (TREE_CODE (op0) != SSA_NAME
>        || TREE_CODE (TREE_TYPE (op0)) != VECTOR_TYPE)
>      return false;
>
> +  def_stmt = get_prop_source_stmt (op0, false, NULL);
> +  if (!def_stmt || !can_propagate_from (def_stmt))
> +    return false;
> +
> +  op1 = TREE_OPERAND (op, 1);
> +  op2 = TREE_OPERAND (op, 2);
> +  code = gimple_assign_rhs_code (def_stmt);
> +
> +  if (code == CONSTRUCTOR)
> +    {
> +      tree tem = fold_ternary (BIT_FIELD_REF, TREE_TYPE (op),
> +                              gimple_assign_rhs1 (def_stmt), op1, op2);
> +      if (!tem || !valid_gimple_rhs_p (tem))
> +       return false;
> +      gimple_assign_set_rhs_from_tree (gsi, tem);
> +      update_stmt (gsi_stmt (*gsi));
> +      return true;
> +    }
> +
>    elem_type = TREE_TYPE (TREE_TYPE (op0));
>    if (TREE_TYPE (op) != elem_type)
>      return false;
>
>    size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
> -  op1 = TREE_OPERAND (op, 1);
>    n = TREE_INT_CST_LOW (op1) / size;
>    if (n != 1)
>      return false;
> -
> -  def_stmt = get_prop_source_stmt (op0, false, NULL);
> -  if (!def_stmt || !can_propagate_from (def_stmt))
> -    return false;
> -
> -  op2 = TREE_OPERAND (op, 2);
>    idx = TREE_INT_CST_LOW (op2) / size;
>
> -  code = gimple_assign_rhs_code (def_stmt);
> -
>    if (code == VEC_PERM_EXPR)
>      {
>        tree p, m, index, tem;
>        unsigned nelts;
>        m = gimple_assign_rhs3 (def_stmt);
>        if (TREE_CODE (m) != VECTOR_CST)
>         return false;
>        nelts = VECTOR_CST_NELTS (m);
>        idx = TREE_INT_CST_LOW (VECTOR_CST_ELT (m, idx));
>        idx %= 2 * nelts;
> Index: testsuite/gcc.dg/tree-ssa/forwprop-23.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/forwprop-23.c     (revision 0)
> +++ testsuite/gcc.dg/tree-ssa/forwprop-23.c     (revision 0)
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-forwprop1" } */
> +
> +typedef long vec __attribute__ ((vector_size (2 * sizeof (long))));
> +
> +long f (long d, long e)
> +{
> +  vec x = { d, e };
> +  vec m = { 1, 0 };
> +  return __builtin_shuffle (x, m) [1];
> +}
> +
> +
> +/* { dg-final { scan-tree-dump-not "BIT_FIELD_REF" "forwprop1" } } */
> +/* { dg-final { cleanup-tree-dump "forwprop1" } } */
>
> Property changes on: testsuite/gcc.dg/tree-ssa/forwprop-23.c
> ___________________________________________________________________
> Added: svn:keywords
>    + Author Date Id Revision URL
> Added: svn:eol-style
>    + native
>
>

Patch

Index: Makefile.in

===================================================================
--- Makefile.in	(revision 191644)

+++ Makefile.in	(working copy)

@@ -2239,21 +2239,21 @@  tree-outof-ssa.o : tree-outof-ssa.c $(TR

    $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) $(BITMAP_H) $(GGC_H) \
    $(EXPR_H) $(SSAEXPAND_H) $(GIMPLE_PRETTY_PRINT_H)
 tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) domwalk.h $(FLAGS_H) \
    $(GIMPLE_PRETTY_PRINT_H) langhooks.h
 tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
    langhooks.h $(FLAGS_H) $(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H) $(EXPR_H) \
-   $(OPTABS_H)

+   $(OPTABS_H) tree-ssa-propagate.h

 tree-ssa-phiprop.o : tree-ssa-phiprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
    langhooks.h $(FLAGS_H) $(GIMPLE_PRETTY_PRINT_H)
 tree-ssa-ifcombine.o : tree-ssa-ifcombine.c $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h $(TM_H) $(TREE_H) $(BASIC_BLOCK_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
    $(TREE_PRETTY_PRINT_H)
 tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
Index: tree-ssa-forwprop.c

===================================================================
--- tree-ssa-forwprop.c	(revision 191644)

+++ tree-ssa-forwprop.c	(working copy)

@@ -27,20 +27,21 @@  along with GCC; see the file COPYING3.

 #include "basic-block.h"
 #include "gimple-pretty-print.h"
 #include "tree-flow.h"
 #include "tree-pass.h"
 #include "langhooks.h"
 #include "flags.h"
 #include "gimple.h"
 #include "expr.h"
 #include "cfgloop.h"
 #include "optabs.h"
+#include "tree-ssa-propagate.h"

 
 /* This pass propagates the RHS of assignment statements into use
    sites of the LHS of the assignment.  It's basically a specialized
    form of tree combination.   It is hoped all of this can disappear
    when we have a generalized tree combiner.
 
    One class of common cases we handle is forward propagating a single use
    variable into a COND_EXPR.
 
      bb0:
@@ -2575,39 +2576,49 @@  simplify_bitfield_ref (gimple_stmt_itera

   enum tree_code code;
 
   op = gimple_assign_rhs1 (stmt);
   gcc_checking_assert (TREE_CODE (op) == BIT_FIELD_REF);
 
   op0 = TREE_OPERAND (op, 0);
   if (TREE_CODE (op0) != SSA_NAME
       || TREE_CODE (TREE_TYPE (op0)) != VECTOR_TYPE)
     return false;
 
+  def_stmt = get_prop_source_stmt (op0, false, NULL);

+  if (!def_stmt || !can_propagate_from (def_stmt))

+    return false;

+

+  op1 = TREE_OPERAND (op, 1);

+  op2 = TREE_OPERAND (op, 2);

+  code = gimple_assign_rhs_code (def_stmt);

+

+  if (code == CONSTRUCTOR)

+    {

+      tree tem = fold_ternary (BIT_FIELD_REF, TREE_TYPE (op),

+			       gimple_assign_rhs1 (def_stmt), op1, op2);

+      if (!tem || !valid_gimple_rhs_p (tem))

+	return false;

+      gimple_assign_set_rhs_from_tree (gsi, tem);

+      update_stmt (gsi_stmt (*gsi));

+      return true;

+    }

+

   elem_type = TREE_TYPE (TREE_TYPE (op0));
   if (TREE_TYPE (op) != elem_type)
     return false;
 
   size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
-  op1 = TREE_OPERAND (op, 1);

   n = TREE_INT_CST_LOW (op1) / size;
   if (n != 1)
     return false;
-

-  def_stmt = get_prop_source_stmt (op0, false, NULL);

-  if (!def_stmt || !can_propagate_from (def_stmt))

-    return false;

-

-  op2 = TREE_OPERAND (op, 2);

   idx = TREE_INT_CST_LOW (op2) / size;
 
-  code = gimple_assign_rhs_code (def_stmt);

-

   if (code == VEC_PERM_EXPR)
     {
       tree p, m, index, tem;
       unsigned nelts;
       m = gimple_assign_rhs3 (def_stmt);
       if (TREE_CODE (m) != VECTOR_CST)
 	return false;
       nelts = VECTOR_CST_NELTS (m);
       idx = TREE_INT_CST_LOW (VECTOR_CST_ELT (m, idx));
       idx %= 2 * nelts;
Index: testsuite/gcc.dg/tree-ssa/forwprop-23.c

===================================================================
--- testsuite/gcc.dg/tree-ssa/forwprop-23.c	(revision 0)

+++ testsuite/gcc.dg/tree-ssa/forwprop-23.c	(revision 0)

@@ -0,0 +1,15 @@ 

+/* { dg-do compile } */

+/* { dg-options "-O -fdump-tree-forwprop1" } */

+

+typedef long vec __attribute__ ((vector_size (2 * sizeof (long))));

+

+long f (long d, long e)

+{

+  vec x = { d, e };

+  vec m = { 1, 0 };

+  return __builtin_shuffle (x, m) [1];

+}

+

+

+/* { dg-final { scan-tree-dump-not "BIT_FIELD_REF" "forwprop1" } } */

+/* { dg-final { cleanup-tree-dump "forwprop1" } } */