This adjusts fold_stmt_inplace to take a gimple_stmt_iterator argument
instead of a gimple.  This allows it to operate on statements that
are only in a gimple_seq but are not (yet) associated with a basic block.
fold_stmt_* shouldn't require a CFG (and yep, I'm going to need that
in a followup).

This exposes that fold_stmt_inplace used gsi_for_stmt which is an
O(n) operation to its callers, quite a few already having a stmt
iterator handy.

Bootstrap and regtest pending on x86_64-unknown-linux-gnu.

Richard.

2011-09-09  Richard Guenther  <rguent...@suse.de>

        * gimple.h (fold_stmt_inplace): Adjust to take a gimple_stmt_iterator
        instead of a statement.
        * gimple-fold.c (fold_stmt_inplace): Likewise.
        * sese.c (graphite_copy_stmts_from_block): Adjust.
        * tree-ssa-dom.c (propagate_rhs_into_lhs): Likewise.
        * tree-ssa-forwprop.c (forward_propagate_into_comparison): Use
        fold_stmt.
        (forward_propagate_addr_into_variable_array_index): Likewise.
        (forward_propagate_addr_expr_1): adjust.
        (associate_plusminus): Likewise.
        (ssa_forward_propagate_and_combine): Likewise.
        * tree-ssa-mathopts.c (replace_reciprocal): Adjust.
        (execute_cse_reciprocals): Likewise.
        * tree-ssa.c (insert_debug_temp_for_var_def): Adjust.

Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h        (revision 178719)
--- gcc/gimple.h        (working copy)
*************** extern void dump_gimple_statistics (void
*** 5068,5074 ****
  void gimplify_and_update_call_from_tree (gimple_stmt_iterator *, tree);
  tree gimple_fold_builtin (gimple);
  bool fold_stmt (gimple_stmt_iterator *);
! bool fold_stmt_inplace (gimple);
  tree get_symbol_constant_value (tree);
  tree canonicalize_constructor_val (tree);
  extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, 
--- 5068,5074 ----
  void gimplify_and_update_call_from_tree (gimple_stmt_iterator *, tree);
  tree gimple_fold_builtin (gimple);
  bool fold_stmt (gimple_stmt_iterator *);
! bool fold_stmt_inplace (gimple_stmt_iterator *);
  tree get_symbol_constant_value (tree);
  tree canonicalize_constructor_val (tree);
  extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, 
Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c   (revision 178719)
--- gcc/gimple-fold.c   (working copy)
*************** fold_stmt (gimple_stmt_iterator *gsi)
*** 1286,1305 ****
    return fold_stmt_1 (gsi, false);
  }
  
! /* Perform the minimal folding on statement STMT.  Only operations like
     *&x created by constant propagation are handled.  The statement cannot
     be replaced with a new one.  Return true if the statement was
     changed, false otherwise.
!    The statement STMT should be in valid gimple form but may
     be in unfolded state as resulting from for example constant propagation
     which can produce *&x = 0.  */
  
  bool
! fold_stmt_inplace (gimple stmt)
  {
!   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
!   bool changed = fold_stmt_1 (&gsi, true);
!   gcc_assert (gsi_stmt (gsi) == stmt);
    return changed;
  }
  
--- 1286,1305 ----
    return fold_stmt_1 (gsi, false);
  }
  
! /* Perform the minimal folding on statement *GSI.  Only operations like
     *&x created by constant propagation are handled.  The statement cannot
     be replaced with a new one.  Return true if the statement was
     changed, false otherwise.
!    The statement *GSI should be in valid gimple form but may
     be in unfolded state as resulting from for example constant propagation
     which can produce *&x = 0.  */
  
  bool
! fold_stmt_inplace (gimple_stmt_iterator *gsi)
  {
!   gimple stmt = gsi_stmt (*gsi);
!   bool changed = fold_stmt_1 (gsi, true);
!   gcc_assert (gsi_stmt (*gsi) == stmt);
    return changed;
  }
  
Index: gcc/sese.c
===================================================================
*** gcc/sese.c  (revision 178719)
--- gcc/sese.c  (working copy)
*************** graphite_copy_stmts_from_block (basic_bl
*** 620,626 ****
  
        if (rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map,
                       gloog_error))
!       fold_stmt_inplace (copy);
  
        update_stmt (copy);
      }
--- 620,629 ----
  
        if (rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map,
                       gloog_error))
!       {
!         gcc_assert (gsi_stmt (gsi_tgt) == copy);
!         fold_stmt_inplace (&gsi_tgt);
!       }
  
        update_stmt (copy);
      }
Index: gcc/tree-ssa-dom.c
===================================================================
*** gcc/tree-ssa-dom.c  (revision 178719)
--- gcc/tree-ssa-dom.c  (working copy)
*************** propagate_rhs_into_lhs (gimple stmt, tre
*** 2656,2662 ****
               GIMPLE_ASSIGN, and there is no way to effect such a
               transformation in-place.  We might want to consider
               using the more general fold_stmt here.  */
!         fold_stmt_inplace (use_stmt);
  
          /* Sometimes propagation can expose new operands to the
             renamer.  */
--- 2656,2665 ----
               GIMPLE_ASSIGN, and there is no way to effect such a
               transformation in-place.  We might want to consider
               using the more general fold_stmt here.  */
!           {
!             gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
!             fold_stmt_inplace (&gsi);
!           }
  
          /* Sometimes propagation can expose new operands to the
             renamer.  */
Index: gcc/tree-ssa-forwprop.c
===================================================================
*** gcc/tree-ssa-forwprop.c     (revision 178719)
--- gcc/tree-ssa-forwprop.c     (working copy)
*************** forward_propagate_into_comparison (gimpl
*** 477,484 ****
    if (tmp)
      {
        gimple_assign_set_rhs_from_tree (gsi, tmp);
!       fold_stmt_inplace (stmt);
!       update_stmt (stmt);
  
        if (TREE_CODE (rhs1) == SSA_NAME)
        cfg_changed |= remove_prop_source_from_use (rhs1);
--- 477,484 ----
    if (tmp)
      {
        gimple_assign_set_rhs_from_tree (gsi, tmp);
!       fold_stmt (gsi);
!       update_stmt (gsi_stmt (*gsi));
  
        if (TREE_CODE (rhs1) == SSA_NAME)
        cfg_changed |= remove_prop_source_from_use (rhs1);
*************** forward_propagate_addr_into_variable_arr
*** 764,775 ****
        }
      }
    gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
!   use_stmt = gsi_stmt (*use_stmt_gsi);
! 
!   /* That should have created gimple, so there is no need to
!      record information to undo the propagation.  */
!   fold_stmt_inplace (use_stmt);
!   tidy_after_forward_propagate_addr (use_stmt);
    return true;
  }
  
--- 764,771 ----
        }
      }
    gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
!   fold_stmt (use_stmt_gsi);
!   tidy_after_forward_propagate_addr (gsi_stmt (*use_stmt_gsi));
    return true;
  }
  
*************** forward_propagate_addr_expr_1 (tree name
*** 982,988 ****
          TREE_OPERAND (rhs, 0) = new_ptr;
          TREE_OPERAND (rhs, 1)
            = double_int_to_tree (TREE_TYPE (TREE_OPERAND (rhs, 1)), off);
!         fold_stmt_inplace (use_stmt);
          tidy_after_forward_propagate_addr (use_stmt);
          return res;
        }
--- 978,984 ----
          TREE_OPERAND (rhs, 0) = new_ptr;
          TREE_OPERAND (rhs, 1)
            = double_int_to_tree (TREE_TYPE (TREE_OPERAND (rhs, 1)), off);
!         fold_stmt_inplace (use_stmt_gsi);
          tidy_after_forward_propagate_addr (use_stmt);
          return res;
        }
*************** forward_propagate_addr_expr_1 (tree name
*** 1018,1024 ****
          gimple_assign_set_rhs1 (use_stmt,
                                  unshare_expr (TREE_OPERAND (def_rhs, 0)));
          *def_rhs_basep = saved;
!         fold_stmt_inplace (use_stmt);
          tidy_after_forward_propagate_addr (use_stmt);
          return res;
        }
--- 1014,1020 ----
          gimple_assign_set_rhs1 (use_stmt,
                                  unshare_expr (TREE_OPERAND (def_rhs, 0)));
          *def_rhs_basep = saved;
!         fold_stmt_inplace (use_stmt_gsi);
          tidy_after_forward_propagate_addr (use_stmt);
          return res;
        }
*************** simplify_bitwise_binary (gimple_stmt_ite
*** 1906,1917 ****
     always permitted.  Returns true if the CFG was changed.  */
  
  static bool
! associate_plusminus (gimple stmt)
  {
    tree rhs1 = gimple_assign_rhs1 (stmt);
    tree rhs2 = gimple_assign_rhs2 (stmt);
    enum tree_code code = gimple_assign_rhs_code (stmt);
-   gimple_stmt_iterator gsi;
    bool changed;
  
    /* We can't reassociate at all for saturating types.  */
--- 1902,1913 ----
     always permitted.  Returns true if the CFG was changed.  */
  
  static bool
! associate_plusminus (gimple_stmt_iterator *gsi)
  {
+   gimple stmt = gsi_stmt (*gsi);
    tree rhs1 = gimple_assign_rhs1 (stmt);
    tree rhs2 = gimple_assign_rhs2 (stmt);
    enum tree_code code = gimple_assign_rhs_code (stmt);
    bool changed;
  
    /* We can't reassociate at all for saturating types.  */
*************** associate_plusminus (gimple stmt)
*** 1986,1992 ****
       via commutating the addition and contracting operations to zero
       by reassociation.  */
  
-   gsi = gsi_for_stmt (stmt);
    if (TREE_CODE (rhs1) == SSA_NAME)
      {
        gimple def_stmt = SSA_NAME_DEF_STMT (rhs1);
--- 1982,1987 ----
*************** associate_plusminus (gimple stmt)
*** 2006,2013 ****
                          ? TREE_CODE (def_rhs2) : NEGATE_EXPR);
                  rhs1 = def_rhs2;
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
              else if (operand_equal_p (def_rhs2, rhs2, 0)
--- 2001,2008 ----
                          ? TREE_CODE (def_rhs2) : NEGATE_EXPR);
                  rhs1 = def_rhs2;
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (*gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
              else if (operand_equal_p (def_rhs2, rhs2, 0)
*************** associate_plusminus (gimple stmt)
*** 2017,2024 ****
                  code = TREE_CODE (def_rhs1);
                  rhs1 = def_rhs1;
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
              else if (TREE_CODE (rhs2) == INTEGER_CST
--- 2012,2019 ----
                  code = TREE_CODE (def_rhs1);
                  rhs1 = def_rhs1;
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (*gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
              else if (TREE_CODE (rhs2) == INTEGER_CST
*************** associate_plusminus (gimple stmt)
*** 2068,2075 ****
                  code = INTEGER_CST;
                  rhs1 = build_int_cst_type (TREE_TYPE (rhs2), -1);
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
              else if (code == PLUS_EXPR
--- 2063,2070 ----
                  code = INTEGER_CST;
                  rhs1 = build_int_cst_type (TREE_TYPE (rhs2), -1);
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (*gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
              else if (code == PLUS_EXPR
*************** associate_plusminus (gimple stmt)
*** 2079,2086 ****
                  code = NEGATE_EXPR;
                  rhs1 = def_rhs1;
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
            }
--- 2074,2081 ----
                  code = NEGATE_EXPR;
                  rhs1 = def_rhs1;
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (*gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
            }
*************** associate_plusminus (gimple stmt)
*** 2106,2113 ****
                          ? NEGATE_EXPR : TREE_CODE (def_rhs2));
                  rhs1 = def_rhs2;
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
              else if (operand_equal_p (def_rhs2, rhs1, 0)
--- 2101,2108 ----
                          ? NEGATE_EXPR : TREE_CODE (def_rhs2));
                  rhs1 = def_rhs2;
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (*gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
              else if (operand_equal_p (def_rhs2, rhs1, 0)
*************** associate_plusminus (gimple stmt)
*** 2118,2125 ****
                          ? TREE_CODE (def_rhs1) : NEGATE_EXPR);
                  rhs1 = def_rhs1;
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
              else if (TREE_CODE (rhs1) == INTEGER_CST
--- 2113,2120 ----
                          ? TREE_CODE (def_rhs1) : NEGATE_EXPR);
                  rhs1 = def_rhs1;
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (*gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
              else if (TREE_CODE (rhs1) == INTEGER_CST
*************** associate_plusminus (gimple stmt)
*** 2168,2175 ****
                  code = INTEGER_CST;
                  rhs1 = build_int_cst_type (TREE_TYPE (rhs1), -1);
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
            }
--- 2163,2170 ----
                  code = INTEGER_CST;
                  rhs1 = build_int_cst_type (TREE_TYPE (rhs1), -1);
                  rhs2 = NULL_TREE;
!                 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
!                 gcc_assert (gsi_stmt (*gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
            }
*************** associate_plusminus (gimple stmt)
*** 2179,2185 ****
  out:
    if (gimple_modified_p (stmt))
      {
!       fold_stmt_inplace (stmt);
        update_stmt (stmt);
        if (maybe_clean_or_replace_eh_stmt (stmt, stmt)
          && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
--- 2174,2180 ----
  out:
    if (gimple_modified_p (stmt))
      {
!       fold_stmt_inplace (gsi);
        update_stmt (stmt);
        if (maybe_clean_or_replace_eh_stmt (stmt, stmt)
          && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
*************** ssa_forward_propagate_and_combine (void)
*** 2438,2444 ****
              else if (is_gimple_min_invariant (rhs))
                {
                  /* Make sure to fold &a[0] + off_1 here.  */
!                 fold_stmt_inplace (stmt);
                  update_stmt (stmt);
                  if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
                    gsi_next (&gsi);
--- 2433,2439 ----
              else if (is_gimple_min_invariant (rhs))
                {
                  /* Make sure to fold &a[0] + off_1 here.  */
!                 fold_stmt_inplace (&gsi);
                  update_stmt (stmt);
                  if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
                    gsi_next (&gsi);
*************** ssa_forward_propagate_and_combine (void)
*** 2495,2501 ****
                  changed = simplify_bitwise_binary (&gsi);
                else if (code == PLUS_EXPR
                         || code == MINUS_EXPR)
!                 changed = associate_plusminus (stmt);
                else if (CONVERT_EXPR_CODE_P (code)
                         || code == FLOAT_EXPR
                         || code == FIX_TRUNC_EXPR)
--- 2490,2496 ----
                  changed = simplify_bitwise_binary (&gsi);
                else if (code == PLUS_EXPR
                         || code == MINUS_EXPR)
!                 changed = associate_plusminus (&gsi);
                else if (CONVERT_EXPR_CODE_P (code)
                         || code == FLOAT_EXPR
                         || code == FIX_TRUNC_EXPR)
Index: gcc/tree-ssa-math-opts.c
===================================================================
*** gcc/tree-ssa-math-opts.c    (revision 178719)
--- gcc/tree-ssa-math-opts.c    (working copy)
*************** replace_reciprocal (use_operand_p use_p)
*** 398,406 ****
    if (optimize_bb_for_speed_p (bb)
        && occ->recip_def && use_stmt != occ->recip_def_stmt)
      {
        gimple_assign_set_rhs_code (use_stmt, MULT_EXPR);
        SET_USE (use_p, occ->recip_def);
!       fold_stmt_inplace (use_stmt);
        update_stmt (use_stmt);
      }
  }
--- 398,407 ----
    if (optimize_bb_for_speed_p (bb)
        && occ->recip_def && use_stmt != occ->recip_def_stmt)
      {
+       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
        gimple_assign_set_rhs_code (use_stmt, MULT_EXPR);
        SET_USE (use_p, occ->recip_def);
!       fold_stmt_inplace (&gsi);
        update_stmt (use_stmt);
      }
  }
*************** execute_cse_reciprocals (void)
*** 610,617 ****
  
                  FOR_EACH_IMM_USE_STMT (stmt, ui, arg1)
                    {
                      gimple_assign_set_rhs_code (stmt, MULT_EXPR);
!                     fold_stmt_inplace (stmt);
                      update_stmt (stmt);
                    }
                }
--- 611,619 ----
  
                  FOR_EACH_IMM_USE_STMT (stmt, ui, arg1)
                    {
+                     gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
                      gimple_assign_set_rhs_code (stmt, MULT_EXPR);
!                     fold_stmt_inplace (&gsi);
                      update_stmt (stmt);
                    }
                }
Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c      (revision 178719)
--- gcc/tree-ssa.c      (working copy)
*************** insert_debug_temp_for_var_def (gimple_st
*** 471,477 ****
          /* If we didn't replace uses with a debug decl fold the
             resulting expression.  Otherwise we end up with invalid IL.  */
          if (TREE_CODE (value) != DEBUG_EXPR_DECL)
!           fold_stmt_inplace (stmt);
        }
        else
        gimple_debug_bind_reset_value (stmt);
--- 471,480 ----
          /* If we didn't replace uses with a debug decl fold the
             resulting expression.  Otherwise we end up with invalid IL.  */
          if (TREE_CODE (value) != DEBUG_EXPR_DECL)
!           {
!             gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
!             fold_stmt_inplace (&gsi);
!           }
        }
        else
        gimple_debug_bind_reset_value (stmt);

Reply via email to