On Thu, 15 May 2014, Richard Biener wrote:

> 
> For some odd reason I didn't implement this earlier.  This is one
> major source of 2nd-stage opportunities that come up when running
> two adjacent FRE passes.
> 
> Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu.

The following is what I have applied (with also properly
value-numbering VDEFs if there).

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Richard.

2014-05-16  Richard Biener  <rguent...@suse.de>

        * tree-ssa-sccvn.c (visit_use): Also constant-fold calls.

        * gcc.dg/tree-ssa/ssa-fre-41.c: New testcase.

Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c        (revision 210418)
--- gcc/tree-ssa-sccvn.c        (working copy)
*************** visit_use (tree use)
*** 3566,3593 ****
        else if (is_gimple_call (stmt))
        {
          tree lhs = gimple_call_lhs (stmt);
- 
-         /* ???  We could try to simplify calls.  */
- 
          if (lhs && TREE_CODE (lhs) == SSA_NAME)
            {
!             if (stmt_has_constants (stmt))
!               VN_INFO (lhs)->has_constants = true;
!             else
                {
!                 /* We reset expr and constantness here because we may
!                    have been value numbering optimistically, and
!                    iterating.  They may become non-constant in this case,
!                    even if they were optimistically constant.  */
!                 VN_INFO (lhs)->has_constants = false;
!                 VN_INFO (lhs)->expr = NULL_TREE;
                }
! 
!             if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
                {
!                 changed = defs_to_varying (stmt);
                  goto done;
                }
            }
  
          if (!gimple_call_internal_p (stmt)
--- 3566,3635 ----
        else if (is_gimple_call (stmt))
        {
          tree lhs = gimple_call_lhs (stmt);
          if (lhs && TREE_CODE (lhs) == SSA_NAME)
            {
!             /* Try constant folding based on our current lattice.  */
!             tree simplified = gimple_fold_stmt_to_constant_1 (stmt,
!                                                               vn_valueize);
!             if (simplified)
                {
!                 if (dump_file && (dump_flags & TDF_DETAILS))
!                   {
!                     fprintf (dump_file, "call ");
!                     print_gimple_expr (dump_file, stmt, 0, 0);
!                     fprintf (dump_file, " simplified to ");
!                     print_generic_expr (dump_file, simplified, 0);
!                     if (TREE_CODE (lhs) == SSA_NAME)
!                       fprintf (dump_file, " has constants %d\n",
!                                expr_has_constants (simplified));
!                     else
!                       fprintf (dump_file, "\n");
!                   }
                }
!             /* Setting value numbers to constants will occasionally
!                screw up phi congruence because constants are not
!                uniquely associated with a single ssa name that can be
!                looked up.  */
!             if (simplified
!                 && is_gimple_min_invariant (simplified))
                {
!                 VN_INFO (lhs)->expr = simplified;
!                 VN_INFO (lhs)->has_constants = true;
!                 changed = set_ssa_val_to (lhs, simplified);
!                 if (gimple_vdef (stmt))
!                   changed |= set_ssa_val_to (gimple_vdef (stmt),
!                                              gimple_vuse (stmt));
                  goto done;
                }
+             else if (simplified
+                      && TREE_CODE (simplified) == SSA_NAME)
+               {
+                 changed = visit_copy (lhs, simplified);
+                 if (gimple_vdef (stmt))
+                   changed |= set_ssa_val_to (gimple_vdef (stmt),
+                                              gimple_vuse (stmt));
+                 goto done;
+               }
+             else
+               {
+                 if (stmt_has_constants (stmt))
+                   VN_INFO (lhs)->has_constants = true;
+                 else
+                   {
+                     /* We reset expr and constantness here because we may
+                        have been value numbering optimistically, and
+                        iterating.  They may become non-constant in this case,
+                        even if they were optimistically constant.  */
+                     VN_INFO (lhs)->has_constants = false;
+                     VN_INFO (lhs)->expr = NULL_TREE;
+                   }
+ 
+                 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
+                   {
+                     changed = defs_to_varying (stmt);
+                     goto done;
+                   }
+               }
            }
  
          if (!gimple_call_internal_p (stmt)
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-41.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-41.c  (revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-41.c  (working copy)
***************
*** 0 ****
--- 1,12 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-fre1" } */
+ 
+ int x;
+ int foo (void)
+ {
+   x = 1;
+   return __builtin_ffs (x);
+ }
+ 
+ /* { dg-final { scan-tree-dump-not "ffs" "fre1" } } */
+ /* { dg-final { cleanup-tree-dump "fre1" } } */

Reply via email to