The following adjusts gsi_remove to do what is documented - not touch
operand caches or force updating by marking it modified when the
remove is not permanent.  This avoids redundant operand scans for
stmt move (gsi_move_* does a gsi_remove / gsi_insert combo as well).

For the original testcase motivating PR93199 this cuts down operand
scanner time from

tree operand scan                  :1053.72 ( 38%) 730.65 (48%)1790.31 ( 42%)   
54141 kB (  0%)

to

tree operand scan                  :   0.93 (  0%)   0.41 (3%)   1.36 (  0%)   
54141 kB (  0%)

Fallout is in places that relied on the implicit side-effect of
the gsi_remove to mark a stmt modified and thus trigger update_stmt
at gsi_insert time.  Likewise dangling stmts where passes remove
stmts but do not tell gsi_remove the remove is final (the gimple FE
change is of that kind).

Bootstrapped on x86_64-unknown-linux-gnu, re-testing after the
interchange and GIMPLE FE fix.

Richard.

2019-01-08  Richard Biener  <rguent...@suse.de>

        PR middle-end/93199
        c/
        * gimple-parser.c (c_parser_parse_gimple_body): Remove __PHI IFN
        permanently.

        * gimple-fold.c (rewrite_to_defined_overflow): Mark stmt modified.
        * tree-ssa-loop-im.c (move_computations_worker): Properly adjust
        virtual operand, also updating SSA use.
        * gimple-loop-interchange.cc (loop_cand::undo_simple_reduction):
        Update stmt after resetting virtual operand.
        (tree_loop_interchange::move_code_to_inner_loop): Likewise.

        * gimple-iterator.c (gsi_remove): When not removing the stmt
        permanently do not delink immediate uses or mark the stmt modified.

Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c   (revision 279992)
+++ gcc/gimple-fold.c   (working copy)
@@ -7380,6 +7380,7 @@ rewrite_to_defined_overflow (gimple *stm
   gimple_assign_set_lhs (stmt, make_ssa_name (type, stmt));
   if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
     gimple_assign_set_rhs_code (stmt, PLUS_EXPR);
+  gimple_set_modified (stmt, true);
   gimple_seq_add_stmt (&stmts, stmt);
   gimple *cvt = gimple_build_assign (lhs, NOP_EXPR, gimple_assign_lhs (stmt));
   gimple_seq_add_stmt (&stmts, cvt);
Index: gcc/gimple-iterator.c
===================================================================
--- gcc/gimple-iterator.c       (revision 279992)
+++ gcc/gimple-iterator.c       (working copy)
@@ -558,16 +558,18 @@ gsi_remove (gimple_stmt_iterator *i, boo
   gimple *stmt = gsi_stmt (*i);
   bool require_eh_edge_purge = false;
 
+  /* ???  Do we want to do this for non-permanent operation?  */
   if (gimple_code (stmt) != GIMPLE_PHI)
     insert_debug_temps_for_defs (i);
 
-  /* Free all the data flow information for STMT.  */
   gimple_set_bb (stmt, NULL);
-  delink_stmt_imm_use (stmt);
-  gimple_set_modified (stmt, true);
 
   if (remove_permanently)
     {
+      /* Free all the data flow information for STMT.  */
+      delink_stmt_imm_use (stmt);
+      gimple_set_modified (stmt, true);
+
       if (gimple_debug_nonbind_marker_p (stmt))
        /* We don't need this to be exact, but try to keep it at least
           close.  */
Index: gcc/tree-ssa-loop-im.c
===================================================================
--- gcc/tree-ssa-loop-im.c      (revision 279992)
+++ gcc/tree-ssa-loop-im.c      (working copy)
@@ -1231,7 +1231,8 @@ move_computations_worker (basic_block bb
              gphi *phi = gsi2.phi ();
              if (virtual_operand_p (gimple_phi_result (phi)))
                {
-                 gimple_set_vuse (stmt, PHI_ARG_DEF_FROM_EDGE (phi, e));
+                 SET_USE (gimple_vuse_op (stmt),
+                          PHI_ARG_DEF_FROM_EDGE (phi, e));
                  break;
                }
            }
Index: gcc/c/gimple-parser.c
===================================================================
--- gcc/c/gimple-parser.c       (revision 279944)
+++ gcc/c/gimple-parser.c       (working copy)
@@ -327,7 +327,7 @@ c_parser_parse_gimple_body (c_parser *cp
                      add_phi_arg (phi, gimple_call_arg (stmt, i + 1), e,
                                   UNKNOWN_LOCATION);
                  }
-               gsi_remove (&gsi, false);
+               gsi_remove (&gsi, true);
              }
          /* Fill SSA name gaps, putting them on the freelist.  */
          for (unsigned i = 1; i < num_ssa_names; ++i)
Index: gcc/gimple-loop-interchange.cc
===================================================================
--- gcc/gimple-loop-interchange.cc      (revision 279944)
+++ gcc/gimple-loop-interchange.cc      (working copy)
@@ -879,6 +879,7 @@ loop_cand::undo_simple_reduction (reduct
   if (re->producer != NULL)
     {
       gimple_set_vuse (re->producer, NULL_TREE);
+      update_stmt (re->producer);
       from = gsi_for_stmt (re->producer);
       gsi_remove (&from, false);
       gimple_seq_add_stmt_without_update (&stmts, re->producer);
@@ -920,6 +921,7 @@ loop_cand::undo_simple_reduction (reduct
   gimple_set_vdef (re->consumer, NULL_TREE);
   gimple_set_vuse (re->consumer, NULL_TREE);
   gimple_assign_set_rhs1 (re->consumer, re->next);
+  update_stmt (re->consumer);
   from = gsi_for_stmt (re->consumer);
   to = gsi_for_stmt (SSA_NAME_DEF_STMT (re->next));
   gsi_move_after (&from, &to);
@@ -1248,14 +1250,17 @@ tree_loop_interchange::move_code_to_inne
              continue;
            }
 
-         if (gimple_vuse (stmt))
-           gimple_set_vuse (stmt, NULL_TREE);
          if (gimple_vdef (stmt))
            {
              unlink_stmt_vdef (stmt);
              release_ssa_name (gimple_vdef (stmt));
              gimple_set_vdef (stmt, NULL_TREE);
            }
+         if (gimple_vuse (stmt))
+           {
+             gimple_set_vuse (stmt, NULL_TREE);
+             update_stmt (stmt);
+           }
 
          reset_debug_uses (stmt);
          gsi_move_before (&gsi, &to);

Reply via email to