loops: Invoke lim after successful loop interchange
authorMartin Jambor <mjambor@suse.cz>
Fri, 13 Nov 2020 14:35:18 +0000 (15:35 +0100)
committerMartin Jambor <mjambor@suse.cz>
Fri, 13 Nov 2020 14:35:18 +0000 (15:35 +0100)
This patch makes the entry point to loop invariant motion public, so
that it can be called after loop interchange when that pass has
swapped loops.  This avoids the non-LTO -Ofast run-time regressions of
410.bwaves and 503.bwaves_r (which are 19% and 15% faster than current
master on an AMD zen2 machine) while not introducing a full LIM pass
into the pass pipeline.

The patch also adds a parameter which allows not to perform any store
motion so that it is not done after an interchange.

gcc/ChangeLog:

2020-11-12  Martin Jambor  <mjambor@suse.cz>

PR tree-optimization/94406
* tree-ssa-loop-im.c (tree_ssa_lim): Renamed to
loop_invariant_motion_in_fun, added a parameter to control store
motion.
(pass_lim::execute): Adjust call to tree_ssa_lim, now
loop_invariant_motion_in_fun.
* tree-ssa-loop-manip.h (loop_invariant_motion_in_fun): Declare.
* gimple-loop-interchange.cc (pass_linterchange::execute): Call
loop_invariant_motion_in_fun if any interchange has been done.

gcc/gimple-loop-interchange.cc
gcc/tree-ssa-loop-im.c
gcc/tree-ssa-loop-manip.h

index 1656004ecf0b6bc325069675f9724fde8a9fb8a9..a36dbb49b1fa1c59bf41b6feb6e96fe4d4125912 100644 (file)
@@ -2085,8 +2085,13 @@ pass_linterchange::execute (function *fun)
     }
 
   if (changed_p)
-    scev_reset ();
-  return changed_p ? (TODO_update_ssa_only_virtuals) : 0;
+    {
+      unsigned todo = TODO_update_ssa_only_virtuals;
+      todo |= loop_invariant_motion_in_fun (cfun, false);
+      scev_reset ();
+      return todo;
+    }
+  return 0;
 }
 
 } // anon namespace
index 6bb07e133cdb316adc09f17d0d5a4b9e1b7adc41..3c7412737f02e0d5b80bd26a5c33e5d18307718b 100644 (file)
@@ -3089,10 +3089,11 @@ tree_ssa_lim_finalize (void)
 }
 
 /* Moves invariants from loops.  Only "expensive" invariants are moved out --
-   i.e. those that are likely to be win regardless of the register pressure.  */
+   i.e. those that are likely to be win regardless of the register pressure.
+   Only perform store motion if STORE_MOTION is true.  */
 
-static unsigned int
-tree_ssa_lim (function *fun)
+unsigned int
+loop_invariant_motion_in_fun (function *fun, bool store_motion)
 {
   unsigned int todo = 0;
 
@@ -3114,7 +3115,8 @@ tree_ssa_lim (function *fun)
 
   /* Execute store motion.  Force the necessary invariants to be moved
      out of the loops as well.  */
-  do_store_motion ();
+  if (store_motion)
+    do_store_motion ();
 
   free (rpo);
   rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
@@ -3175,7 +3177,7 @@ pass_lim::execute (function *fun)
 
   if (number_of_loops (fun) <= 1)
     return 0;
-  unsigned int todo = tree_ssa_lim (fun);
+  unsigned int todo = loop_invariant_motion_in_fun (fun, true);
 
   if (!in_loop_pipeline)
     loop_optimizer_finalize ();
index e789e4fcb0b3dcb4e8dbbca417ae7db9eb9223b0..d8e918ef7c9177547e0287831c01b9c0968392a9 100644 (file)
@@ -55,7 +55,7 @@ extern void tree_transform_and_unroll_loop (class loop *, unsigned,
 extern void tree_unroll_loop (class loop *, unsigned,
                              edge, class tree_niter_desc *);
 extern tree canonicalize_loop_ivs (class loop *, tree *, bool);
-
+extern unsigned int loop_invariant_motion_in_fun (function *, bool);
 
 
 #endif /* GCC_TREE_SSA_LOOP_MANIP_H */