public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Use new dump scheme to emit loop unroll/peel summary info (issue6941070)
@ 2012-12-18  6:45 Teresa Johnson
  2012-12-20  9:21 ` Bernhard Reutner-Fischer
  2013-01-02 17:55 ` Richard Henderson
  0 siblings, 2 replies; 5+ messages in thread
From: Teresa Johnson @ 2012-12-18  6:45 UTC (permalink / raw)
  To: reply, richard.guenther, davidxl, singhai, gcc-patches

This patch adds a few key messages summarizing loop unrolls and peels
using the new dump infrastructure, along with an appropriate location
for each loop. See also the following threads for context:

http://gcc.gnu.org/ml/gcc/2012-12/msg00056.html
http://gcc.gnu.org/ml/gcc-patches/2012-12/msg01000.html

The new high-level optimization summary messages are emitted for both
the tree complete unroller and the rtl loop unroller/peeler, and are
emitted to both the dump files under the appropriate -fdump-* option,
as well as under -fopt-info. A few existing messages were removed as they
are subsumed by the new summary messages.

Also included is a new routine (get_loop_location), used to identify an
appropriate location for the loop to use with the summary message
(usually the line containing the loop condition), which was ported
from the google branches.

I also made a change to dump_loc to enable the filename to be printed when
dumping the source location, as we already were doing when the
location was unknown and we used the function location. This makes
it feasible to grep the output for messages and see the full source
location in each message.

Sharad plans to submit a follow-on patch that will convert the bulk
of the existing dump messages to the new dump infrastructure.

Bootstrapped and tested on x86_64-unknown-linux-gnu. Ok for trunk?

2012-12-17  Teresa Johnson  <tejohnson@google.com>

	* dumpfile.c (dump_loc): Print filename with location.
	* tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Use
        new location_t parameter to emit complete unroll message with
        new dump framework.
	(canonicalize_loop_induction_variables): Compute loops location
        and pass to try_unroll_loop_completely.
	* loop-unroll.c (report_unroll_peel): New function.
	(peel_loops_completely): Use new dump format with location
        for main dumpfile message, and invoke report_unroll_peel on success.
	(decide_unrolling_and_peeling): Ditto.
	(decide_peel_once_rolling): Remove old dumpfile message subsumed
        by report_unroll_peel.
	(decide_peel_completely): Ditto.
	(decide_unroll_constant_iterations): Ditto.
	(decide_unroll_runtime_iterations): Ditto.
	(decide_peel_simple): Ditto.
	(decide_unroll_stupid): Ditto.
	* cfgloop.c (get_loop_location): New function.
	* cfgloop.h (get_loop_location): Declare.

        testsuite/
	* gcc.dg/tree-ssa/loop-1.c: Update expected dump message.
	* gcc.dg/tree-ssa/loop-23.c: Ditto.
	* gcc.dg/tree-ssa/cunroll-1.c: Ditto.
	* gcc.dg/tree-ssa/cunroll-2.c: Ditto.
	* gcc.dg/tree-ssa/cunroll-3.c: Ditto.
	* gcc.dg/tree-ssa/cunroll-4.c: Ditto.
	* gcc.dg/tree-ssa/cunroll-5.c: Ditto.
	* testsuite/gcc.dg/unroll_1.c:
	* testsuite/gcc.dg/unroll_2.c:
	* testsuite/gcc.dg/unroll_3.c:
	* testsuite/gcc.dg/unroll_4.c:

Index: dumpfile.c
===================================================================
--- dumpfile.c	(revision 194516)
+++ dumpfile.c	(working copy)
@@ -265,7 +265,9 @@ dump_loc (int dump_kind, FILE *dfile, source_locat
                  DECL_SOURCE_FILE (current_function_decl),
                  DECL_SOURCE_LINE (current_function_decl));
      else
-        fprintf (dfile, "\n%d: ", LOCATION_LINE (loc));
+        fprintf (dfile, "\n%s:%d: note: ",
+                 LOCATION_FILE (loc),
+                 LOCATION_LINE (loc));
     }
 }
 
Index: testsuite/gcc.dg/unroll_2.c
===================================================================
--- testsuite/gcc.dg/unroll_2.c	(revision 194516)
+++ testsuite/gcc.dg/unroll_2.c	(working copy)
@@ -28,6 +28,6 @@ int foo2(void)
   return 1;
 }
 
-/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 1 "loop2_unroll" } } */
 /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
 /* { dg-excess-errors "extra notes" } */
Index: testsuite/gcc.dg/unroll_3.c
===================================================================
--- testsuite/gcc.dg/unroll_3.c	(revision 194516)
+++ testsuite/gcc.dg/unroll_3.c	(working copy)
@@ -28,6 +28,6 @@ int foo2(void)
   return 1;
 }
 
-/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 1 "loop2_unroll" } } */
 /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
 /* { dg-excess-errors "extra notes" } */
Index: testsuite/gcc.dg/tree-ssa/loop-1.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/loop-1.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/loop-1.c	(working copy)
@@ -33,7 +33,7 @@ int xxx(void)
 
 /* { dg-final { scan-tree-dump-times "Added canonical iv to loop 1, 4 iterations" 1 "ivcanon"} } */
 /* { dg-final { cleanup-tree-dump "ivcanon" } } */
-/* { dg-final { scan-tree-dump-times "Unrolled loop 1 completely" 1 "cunroll"} } */
+/* { dg-final { scan-tree-dump-times "Completely unroll loop 4 times" 1 "cunroll"} } */
 /* { dg-final { cleanup-tree-dump "cunroll" } } */
 /* { dg-final { scan-tree-dump-times "foo" 5 "optimized"} } */
 /* { dg-final { cleanup-tree-dump "optimized" } } */
Index: testsuite/gcc.dg/tree-ssa/cunroll-1.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/cunroll-1.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/cunroll-1.c	(working copy)
@@ -8,6 +8,6 @@ test(int c)
     a[i]=5;
 }
 /* Array bounds says the loop will not roll much.  */
-/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 2 times.." "cunrolli"} } */
+/* { dg-final { scan-tree-dump "Completely unroll loop 2 times" "cunrolli"} } */
 /* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunrolli"} } */
 /* { dg-final { cleanup-tree-dump "cunrolli" } } */
Index: testsuite/gcc.dg/tree-ssa/cunroll-2.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/cunroll-2.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/cunroll-2.c	(working copy)
@@ -12,5 +12,5 @@ test(int c)
     }
 }
 /* We are not able to get rid of the final conditional because the loop has two exits.  */
-/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 1 times.." "cunroll"} } */
+/* { dg-final { scan-tree-dump "Completely unroll loop 1 times" "cunroll"} } */
 /* { dg-final { cleanup-tree-dump "cunroll" } } */
Index: testsuite/gcc.dg/tree-ssa/loop-23.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/loop-23.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/loop-23.c	(working copy)
@@ -24,6 +24,6 @@ int foo(void)
   return sum;
 }
 
-/* { dg-final { scan-tree-dump-times "Unrolled loop 1 completely" 1 "cunroll" } } */
+/* { dg-final { scan-tree-dump-times "Completely unroll loop 3 times" 1 "cunroll" } } */
 
 /* { dg-final { cleanup-tree-dump "cunroll" } } */
Index: testsuite/gcc.dg/tree-ssa/cunroll-3.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/cunroll-3.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/cunroll-3.c	(working copy)
@@ -11,5 +11,5 @@ test(int c)
 }
 /* If we start duplicating headers prior curoll, this loop will have 0 iterations.  */
 
-/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 1 times.." "cunrolli"} } */
+/* { dg-final { scan-tree-dump "Completely unroll loop 1 times" "cunrolli"} } */
 /* { dg-final { cleanup-tree-dump "cunrolli" } } */
Index: testsuite/gcc.dg/tree-ssa/cunroll-4.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/cunroll-4.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/cunroll-4.c	(working copy)
@@ -16,6 +16,6 @@ test(int c)
 
 /* We should do this as part of cunrolli, but our cost model do not take into account early exit
    from the last iteration.  */
-/* { dg-final { scan-tree-dump "Turned loop 1 to non-loop; it never loops." "ivcanon"} } */
+/* { dg-final { scan-tree-dump "Turned loop into non-loop; it never loops." "ivcanon"} } */
 /* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "ivcanon"} } */
 /* { dg-final { cleanup-tree-dump "ivcanon" } } */
Index: testsuite/gcc.dg/tree-ssa/cunroll-5.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/cunroll-5.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/cunroll-5.c	(working copy)
@@ -8,7 +8,7 @@ test(int c)
     a[i]=5;
 }
 /* Basic testcase for complette unrolling.  */
-/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 5 times.." "cunroll"} } */
+/* { dg-final { scan-tree-dump "Completely unroll loop 5 times" "cunroll"} } */
 /* { dg-final { scan-tree-dump "Exit condition of peeled iterations was eliminated." "cunroll"} } */
 /* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunroll"} } */
 /* { dg-final { cleanup-tree-dump "cunroll" } } */
Index: testsuite/gcc.dg/unroll_4.c
===================================================================
--- testsuite/gcc.dg/unroll_4.c	(revision 194516)
+++ testsuite/gcc.dg/unroll_4.c	(working copy)
@@ -28,6 +28,6 @@ int foo2(void)
   return 1;
 }
 
-/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 1 "loop2_unroll" } } */
 /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
 /* { dg-excess-errors "extra notes" } */
Index: testsuite/gcc.dg/unroll_1.c
===================================================================
--- testsuite/gcc.dg/unroll_1.c	(revision 194516)
+++ testsuite/gcc.dg/unroll_1.c	(working copy)
@@ -28,5 +28,5 @@ int foo2(void)
   return 1;
 }
 
-/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely" 2 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 2 "loop2_unroll" } } */
 /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
Index: tree-ssa-loop-ivcanon.c
===================================================================
--- tree-ssa-loop-ivcanon.c	(revision 194516)
+++ tree-ssa-loop-ivcanon.c	(working copy)
@@ -639,22 +639,24 @@ unloop_loops (bitmap loop_closed_ssa_invalidated,
 
 /* Tries to unroll LOOP completely, i.e. NITER times.
    UL determines which loops we are allowed to unroll.
-   EXIT is the exit of the loop that should be eliminated.  
+   EXIT is the exit of the loop that should be eliminated.
    MAXITER specfy bound on number of iterations, -1 if it is
-   not known or too large for HOST_WIDE_INT.  */
+   not known or too large for HOST_WIDE_INT. The location
+   LOCUS corresponding to the loop is used when emitting
+   a summary of the unroll to the dump file.  */
 
 static bool
 try_unroll_loop_completely (struct loop *loop,
 			    edge exit, tree niter,
 			    enum unroll_level ul,
-			    HOST_WIDE_INT maxiter)
+			    HOST_WIDE_INT maxiter,
+                            location_t locus)
 {
   unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll, unr_insns;
   gimple cond;
   struct loop_size size;
   bool n_unroll_found = false;
   edge edge_to_cancel = NULL;
-  int num = loop->num;
 
   /* See if we proved number of iterations to be low constant.
 
@@ -862,14 +864,25 @@ try_unroll_loop_completely (struct loop *loop,
   loops_to_unloop.safe_push (loop);
   loops_to_unloop_nunroll.safe_push (n_unroll);
 
-  if (dump_file && (dump_flags & TDF_DETAILS))
+  if (dump_enabled_p ())
     {
       if (!n_unroll)
-        fprintf (dump_file, "Turned loop %d to non-loop; it never loops.\n",
-		 num);
+        dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
+                         "Turned loop into non-loop; it never loops.\n");
       else
-        fprintf (dump_file, "Unrolled loop %d completely "
-		 "(duplicated %i times).\n", num, (int)n_unroll);
+        {
+          dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
+                           "Completely unroll loop %d times", (int)n_unroll);
+          if (profile_info)
+            dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS,
+                         " (header execution count %d)",
+                         (int)loop->header->count);
+          dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, "\n");
+        }
+    }
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
       if (exit)
         fprintf (dump_file, "Exit condition of peeled iterations was "
 		 "eliminated.\n");
@@ -898,15 +911,19 @@ canonicalize_loop_induction_variables (struct loop
   tree niter;
   HOST_WIDE_INT maxiter;
   bool modified = false;
+  location_t locus = UNKNOWN_LOCATION;
 
   niter = number_of_latch_executions (loop);
   if (TREE_CODE (niter) == INTEGER_CST)
-    exit = single_exit (loop);
+    {
+      exit = single_exit (loop);
+      locus = gimple_location (last_stmt (exit->src));
+    }
   else
     {
       /* If the loop has more than one exit, try checking all of them
 	 for # of iterations determinable through scev.  */
-      if (!single_exit (loop))
+      if (!(exit = single_exit (loop)))
 	niter = find_loop_niter (loop, &exit);
 
       /* Finally if everything else fails, try brute force evaluation.  */
@@ -915,6 +932,9 @@ canonicalize_loop_induction_variables (struct loop
 	      || TREE_CODE (niter) != INTEGER_CST))
 	niter = find_loop_niter_by_eval (loop, &exit);
 
+      if (exit)
+        locus = gimple_location (last_stmt (exit->src));
+
       if (TREE_CODE (niter) != INTEGER_CST)
 	exit = NULL;
     }
@@ -949,7 +969,7 @@ canonicalize_loop_induction_variables (struct loop
      populates the loop bounds.  */
   modified |= remove_redundant_iv_tests (loop);
 
-  if (try_unroll_loop_completely (loop, exit, niter, ul, maxiter))
+  if (try_unroll_loop_completely (loop, exit, niter, ul, maxiter, locus))
     return true;
 
   if (create_iv
Index: loop-unroll.c
===================================================================
--- loop-unroll.c	(revision 194516)
+++ loop-unroll.c	(working copy)
@@ -148,6 +148,61 @@ static void combine_var_copies_in_loop_exit (struc
 					     basic_block);
 static rtx get_expansion (struct var_to_expand *);
 
+/* Emit a message summarizing the unroll or peel that will be
+   performed for LOOP, along with the loop's location LOCUS, if
+   appropriate given the dump or -fopt-info settings.  */
+
+static void
+report_unroll_peel(struct loop *loop, location_t locus)
+{
+  struct niter_desc *desc;
+  int niters = 0;
+  int report_flags = MSG_OPTIMIZED_LOCATIONS | TDF_RTL | TDF_DETAILS;
+
+  if (!dump_enabled_p ())
+    return;
+
+  /* In the special case where the loop never iterated, emit
+     a different message so that we don't report an unroll by 0.
+     This matches the equivalent message emitted during tree unrolling.  */
+  if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY
+      && !loop->lpt_decision.times)
+    {
+      dump_printf_loc (report_flags, locus,
+                       "Turned loop into non-loop; it never loops.\n");
+      return;
+    }
+
+  desc = get_simple_loop_desc (loop);
+
+  if (desc->const_iter)
+    niters = desc->niter;
+  else if (loop->header->count)
+    niters = expected_loop_iterations (loop);
+
+  dump_printf_loc (report_flags, locus,
+                   "%s loop %d times",
+                   (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY
+                    ?  "Completely unroll"
+                    : (loop->lpt_decision.decision == LPT_PEEL_SIMPLE
+                       ? "Peel" : "Unroll")),
+                   loop->lpt_decision.times);
+  if (profile_info)
+    dump_printf (report_flags,
+                 " (header execution count %d",
+                 (int)loop->header->count);
+  if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
+    dump_printf (report_flags,
+                 "%s%s iterations %d)",
+                 profile_info ? ", " : " (",
+                 desc->const_iter ? "const" : "average",
+                 niters);
+  else if (profile_info)
+    dump_printf (report_flags, ")");
+
+  dump_printf (report_flags, "\n");
+}
+
 /* Unroll and/or peel (depending on FLAGS) LOOPS.  */
 void
 unroll_and_peel_loops (int flags)
@@ -234,11 +289,13 @@ peel_loops_completely (int flags)
   FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
     {
       loop->lpt_decision.decision = LPT_NONE;
+      location_t locus = get_loop_location(loop);
 
-      if (dump_file)
-	fprintf (dump_file,
-		 "\n;; *** Considering loop %d for complete peeling ***\n",
-		 loop->num);
+      if (dump_enabled_p ())
+	dump_printf_loc (TDF_RTL, locus,
+                         ";; *** Considering loop %d at BB %d for "
+                         "complete peeling ***\n",
+                         loop->num, loop->header->index);
 
       loop->ninsns = num_loop_insns (loop);
 
@@ -248,6 +305,7 @@ peel_loops_completely (int flags)
 
       if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
 	{
+          report_unroll_peel(loop, locus);
 	  peel_loop_completely (loop);
 #ifdef ENABLE_CHECKING
 	  verify_loop_structure ();
@@ -267,9 +325,13 @@ decide_unrolling_and_peeling (int flags)
   FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
     {
       loop->lpt_decision.decision = LPT_NONE;
+      location_t locus = get_loop_location(loop);
 
-      if (dump_file)
-	fprintf (dump_file, "\n;; *** Considering loop %d ***\n", loop->num);
+      if (dump_enabled_p ())
+	dump_printf_loc (TDF_RTL, locus,
+                         ";; *** Considering loop %d at BB %d for "
+                         "unrolling and peeling ***\n",
+                         loop->num, loop->header->index);
 
       /* Do not peel cold areas.  */
       if (optimize_loop_for_size_p (loop))
@@ -309,6 +371,8 @@ decide_unrolling_and_peeling (int flags)
 	decide_unroll_stupid (loop, flags);
       if (loop->lpt_decision.decision == LPT_NONE)
 	decide_peel_simple (loop, flags);
+
+      report_unroll_peel(loop, locus);
     }
 }
 
@@ -348,8 +412,6 @@ decide_peel_once_rolling (struct loop *loop, int f
     }
 
   /* Success.  */
-  if (dump_file)
-    fprintf (dump_file, ";; Decided to peel exactly once rolling loop\n");
   loop->lpt_decision.decision = LPT_PEEL_COMPLETELY;
 }
 
@@ -429,8 +491,6 @@ decide_peel_completely (struct loop *loop, int fla
     }
 
   /* Success.  */
-  if (dump_file)
-    fprintf (dump_file, ";; Decided to peel loop completely\n");
   loop->lpt_decision.decision = LPT_PEEL_COMPLETELY;
 }
 
@@ -608,10 +668,6 @@ decide_unroll_constant_iterations (struct loop *lo
 
   loop->lpt_decision.decision = LPT_UNROLL_CONSTANT;
   loop->lpt_decision.times = best_unroll;
-
-  if (dump_file)
-    fprintf (dump_file, ";; Decided to unroll the loop %d times (%d copies).\n",
-	     loop->lpt_decision.times, best_copies);
 }
 
 /* Unroll LOOP with constant number of iterations LOOP->LPT_DECISION.TIMES times.
@@ -893,10 +949,6 @@ decide_unroll_runtime_iterations (struct loop *loo
 
   loop->lpt_decision.decision = LPT_UNROLL_RUNTIME;
   loop->lpt_decision.times = i - 1;
-
-  if (dump_file)
-    fprintf (dump_file, ";; Decided to unroll the loop %d times.\n",
-	     loop->lpt_decision.times);
 }
 
 /* Splits edge E and inserts the sequence of instructions INSNS on it, and
@@ -1305,10 +1357,6 @@ decide_peel_simple (struct loop *loop, int flags)
   /* Success.  */
   loop->lpt_decision.decision = LPT_PEEL_SIMPLE;
   loop->lpt_decision.times = npeel;
-
-  if (dump_file)
-    fprintf (dump_file, ";; Decided to simply peel the loop %d times.\n",
-	     loop->lpt_decision.times);
 }
 
 /* Peel a LOOP LOOP->LPT_DECISION.TIMES times.  The transformation does this:
@@ -1460,10 +1508,6 @@ decide_unroll_stupid (struct loop *loop, int flags
 
   loop->lpt_decision.decision = LPT_UNROLL_STUPID;
   loop->lpt_decision.times = i - 1;
-
-  if (dump_file)
-    fprintf (dump_file, ";; Decided to unroll the loop stupidly %d times.\n",
-	     loop->lpt_decision.times);
 }
 
 /* Unroll a LOOP LOOP->LPT_DECISION.TIMES times.  The transformation does this:
Index: cfgloop.c
===================================================================
--- cfgloop.c	(revision 194516)
+++ cfgloop.c	(working copy)
@@ -1666,3 +1666,59 @@ loop_exits_from_bb_p (struct loop *loop, basic_blo
 
   return false;
 }
+
+/* Return location corresponding to the loop control condition if possible. */
+
+location_t
+get_loop_location (struct loop *loop)
+{
+  rtx insn = NULL;
+  struct niter_desc *desc = NULL;
+  edge exit;
+
+  /* For a for or while loop, we would like to return the location
+   * of the for or while statement, if possible. To do this, look
+   * for the branch guarding the loop back-edge.
+   */
+
+  /* If this is a simple loop with an in_edge, then the loop control
+   * branch is typically at the end of its source.
+   */
+  desc = get_simple_loop_desc (loop);
+  if (desc->in_edge)
+    {
+      FOR_BB_INSNS_REVERSE (desc->in_edge->src, insn)
+        {
+          if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+            return INSN_LOCATION (insn);
+        }
+    }
+  /* If loop has a single exit, then the loop control branch
+   * must be at the end of its source.
+   */
+  if ((exit = single_exit(loop)))
+    {
+      FOR_BB_INSNS_REVERSE (exit->src, insn)
+        {
+          if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+            return INSN_LOCATION (insn);
+        }
+    }
+  /* Next check the latch, to see if it is non-empty. */
+  FOR_BB_INSNS_REVERSE (loop->latch, insn)
+    {
+      if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+        return INSN_LOCATION (insn);
+    }
+  /* Finally, if none of the above identifies the loop control branch,
+   * return the first location in the loop header.
+   */
+  FOR_BB_INSNS (loop->header, insn)
+    {
+      if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+        return INSN_LOCATION (insn);
+    }
+  /* If all else fails, simply return the current function location. */
+  return DECL_SOURCE_LOCATION (current_function_decl);
+}
+
Index: cfgloop.h
===================================================================
--- cfgloop.h	(revision 194516)
+++ cfgloop.h	(working copy)
@@ -239,6 +239,7 @@ extern bool loop_exit_edge_p (const struct loop *,
 extern bool loop_exits_to_bb_p (struct loop *, basic_block);
 extern bool loop_exits_from_bb_p (struct loop *, basic_block);
 extern void mark_loop_exit_edges (void);
+extern location_t get_loop_location (struct loop *loop);
 
 /* Loops & cfg manipulation.  */
 extern basic_block *get_loop_body (const struct loop *);

--
This patch is available for review at http://codereview.appspot.com/6941070

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Use new dump scheme to emit loop unroll/peel summary info (issue6941070)
  2012-12-18  6:45 [PATCH] Use new dump scheme to emit loop unroll/peel summary info (issue6941070) Teresa Johnson
@ 2012-12-20  9:21 ` Bernhard Reutner-Fischer
  2012-12-20 17:21   ` Teresa Johnson
  2013-01-02 17:55 ` Richard Henderson
  1 sibling, 1 reply; 5+ messages in thread
From: Bernhard Reutner-Fischer @ 2012-12-20  9:21 UTC (permalink / raw)
  To: Teresa Johnson; +Cc: reply, richard.guenther, davidxl, singhai, gcc-patches

On Mon, Dec 17, 2012 at 10:44:59PM -0800, Teresa Johnson wrote:
>Index: tree-ssa-loop-ivcanon.c
>===================================================================
>--- tree-ssa-loop-ivcanon.c	(revision 194516)
>+++ tree-ssa-loop-ivcanon.c	(working copy)
>@@ -639,22 +639,24 @@ unloop_loops (bitmap loop_closed_ssa_invalidated,
> 
> /* Tries to unroll LOOP completely, i.e. NITER times.
>    UL determines which loops we are allowed to unroll.
>-   EXIT is the exit of the loop that should be eliminated.  
>+   EXIT is the exit of the loop that should be eliminated.
>    MAXITER specfy bound on number of iterations, -1 if it is
>-   not known or too large for HOST_WIDE_INT.  */
>+   not known or too large for HOST_WIDE_INT. The location
>+   LOCUS corresponding to the loop is used when emitting
>+   a summary of the unroll to the dump file.  */
> 
> static bool
> try_unroll_loop_completely (struct loop *loop,
> 			    edge exit, tree niter,
> 			    enum unroll_level ul,
>-			    HOST_WIDE_INT maxiter)
>+			    HOST_WIDE_INT maxiter,
>+                            location_t locus)

whitespace damage?

>Index: loop-unroll.c
>===================================================================
>--- loop-unroll.c	(revision 194516)
>+++ loop-unroll.c	(working copy)
>@@ -148,6 +148,61 @@ static void combine_var_copies_in_loop_exit (struc
> 					     basic_block);
> static rtx get_expansion (struct var_to_expand *);
> 
>+/* Emit a message summarizing the unroll or peel that will be
>+   performed for LOOP, along with the loop's location LOCUS, if
>+   appropriate given the dump or -fopt-info settings.  */
>+
>+static void
>+report_unroll_peel(struct loop *loop, location_t locus)

missing space before (

contrib/check_GNU_style.sh generally says:
Dot, space, space, new sentence.
loop-dump.01.patch:223:+   not known or too large for HOST_WIDE_INT. The location
loop-dump.01.patch:514:+   * of the for or while statement, if possible. To do this, look

Dot, space, space, end of comment.
loop-dump.01.patch:504:+/* Return location corresponding to the loop control condition if possible. */
loop-dump.01.patch:541:+  /* Next check the latch, to see if it is non-empty. *
loop-dump.01.patch:555:+  /* If all else fails, simply return the current function location. */

There should be exactly one space between function name and parentheses.
loop-dump.01.patch:329:+report_unroll_peel(struct loop *loop, location_t locus)
loop-dump.01.patch:386:+      location_t locus = get_loop_location(loop);
loop-dump.01.patch:404:+          report_unroll_peel(loop, locus);
loop-dump.01.patch:412:+      location_t locus = get_loop_location(loop);
loop-dump.01.patch:429:+      report_unroll_peel(loop, locus);
loop-dump.01.patch:533:+  if ((exit = single_exit(loop)))

>@@ -248,6 +305,7 @@ peel_loops_completely (int flags)
> 
>       if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
> 	{
>+          report_unroll_peel(loop, locus);
> 	  peel_loop_completely (loop);

whitespace damage? You seem to have this kind of whitespace error
throughout the patch. I take it you are aware of
http://gcc.gnu.org/wiki/FormattingCodeForGCC
and just forgot to have it on the machine you edited?

I seemingly have
$ cat ~/.vim/gcc_style.vim 
" put this plugin into ~/.vim/gcc_style.vim and source it into your ~/.vimrc via
" source ~/.vim/gcc_style.vim
if exists("g:loaded_gcc_style") || &cp
  finish
endif
let g:loaded_gcc_style = 1

augroup gcc_style
  autocmd BufReadPost,FileReadPost * call s:maybe_gcc_style()
augroup END
if exists("*s:maybe_gcc_style")
  finish
endif
let s:cpo_save = &cpo
set cpo&vim

function! s:maybe_gcc_style()
  let s:i = 1 + 0
  while s:i <= line("$") && s:i <= 25
    let s:line = getline(s:i)
    if s:line =~ '^\s*This\sfile\sis\spart\sof\sGCC.*'
      " gcc-mode
      set cino=:s,{s,n-s,>2s,^-s
      set sw=2
      set sts=2
      set cindent
      set smartindent
      set autoindent
      break
    else
      let s:i = s:i + 1
    endif
  endwhile
endfunction

"command! NoGCCstyle unlet! g:loaded_gcc_style | au! gcc_style
"command! DoGCCstyle runtime gcc_style.vim
let &cpo = s:cpo_save

>Index: cfgloop.c
>===================================================================
>--- cfgloop.c	(revision 194516)
>+++ cfgloop.c	(working copy)
>@@ -1666,3 +1666,59 @@ loop_exits_from_bb_p (struct loop *loop, basic_blo
> 
>   return false;
> }
>+
>+/* Return location corresponding to the loop control condition if possible. */
>+
>+location_t
>+get_loop_location (struct loop *loop)
>+{
>+  rtx insn = NULL;
>+  struct niter_desc *desc = NULL;
>+  edge exit;
>+
>+  /* For a for or while loop, we would like to return the location
>+   * of the for or while statement, if possible. To do this, look
>+   * for the branch guarding the loop back-edge.
>+   */

IIRC there is not supposed to be a * in comments.

Other than these nits i like it (but cannot approve it).

thanks,

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Use new dump scheme to emit loop unroll/peel summary info (issue6941070)
  2012-12-20  9:21 ` Bernhard Reutner-Fischer
@ 2012-12-20 17:21   ` Teresa Johnson
  2013-01-02 15:55     ` Teresa Johnson
  0 siblings, 1 reply; 5+ messages in thread
From: Teresa Johnson @ 2012-12-20 17:21 UTC (permalink / raw)
  To: Bernhard Reutner-Fischer
  Cc: reply, Richard Biener, David Li, Sharad Singhai, gcc-patches

On Thu, Dec 20, 2012 at 1:21 AM, Bernhard Reutner-Fischer
<rep.dot.nop@gmail.com> wrote:

Thanks for your comments. Responses inlined below, and new patch include below.

> On Mon, Dec 17, 2012 at 10:44:59PM -0800, Teresa Johnson wrote:
>>Index: tree-ssa-loop-ivcanon.c
>>===================================================================
>>--- tree-ssa-loop-ivcanon.c    (revision 194516)
>>+++ tree-ssa-loop-ivcanon.c    (working copy)
>>@@ -639,22 +639,24 @@ unloop_loops (bitmap loop_closed_ssa_invalidated,
>>
>> /* Tries to unroll LOOP completely, i.e. NITER times.
>>    UL determines which loops we are allowed to unroll.
>>-   EXIT is the exit of the loop that should be eliminated.
>>+   EXIT is the exit of the loop that should be eliminated.
>>    MAXITER specfy bound on number of iterations, -1 if it is
>>-   not known or too large for HOST_WIDE_INT.  */
>>+   not known or too large for HOST_WIDE_INT. The location
>>+   LOCUS corresponding to the loop is used when emitting
>>+   a summary of the unroll to the dump file.  */
>>
>> static bool
>> try_unroll_loop_completely (struct loop *loop,
>>                           edge exit, tree niter,
>>                           enum unroll_level ul,
>>-                          HOST_WIDE_INT maxiter)
>>+                          HOST_WIDE_INT maxiter,
>>+                            location_t locus)
>
> whitespace damage?

This and the other location you pointed out below as possible
whitespace damage are because the surrounding lines use tab characters
whereas mine uses spaces. Is there a guideline on which one is correct
for gcc? I looked in the style guide but didn't find anything. The
existing code uses a mix of indentation via tabs and spaces. I have
fixed this location and the one you point out below to use a tab
character so that the diff goes away, but I haven't searched the patch
exhaustively for similar issues.

>
>>Index: loop-unroll.c
>>===================================================================
>>--- loop-unroll.c      (revision 194516)
>>+++ loop-unroll.c      (working copy)
>>@@ -148,6 +148,61 @@ static void combine_var_copies_in_loop_exit (struc
>>                                            basic_block);
>> static rtx get_expansion (struct var_to_expand *);
>>
>>+/* Emit a message summarizing the unroll or peel that will be
>>+   performed for LOOP, along with the loop's location LOCUS, if
>>+   appropriate given the dump or -fopt-info settings.  */
>>+
>>+static void
>>+report_unroll_peel(struct loop *loop, location_t locus)
>
> missing space before (
>
> contrib/check_GNU_style.sh generally says:
> Dot, space, space, new sentence.
> loop-dump.01.patch:223:+   not known or too large for HOST_WIDE_INT. The location
> loop-dump.01.patch:514:+   * of the for or while statement, if possible. To do this, look
>
> Dot, space, space, end of comment.
> loop-dump.01.patch:504:+/* Return location corresponding to the loop control condition if possible. */
> loop-dump.01.patch:541:+  /* Next check the latch, to see if it is non-empty. *
> loop-dump.01.patch:555:+  /* If all else fails, simply return the current function location. */
>
> There should be exactly one space between function name and parentheses.
> loop-dump.01.patch:329:+report_unroll_peel(struct loop *loop, location_t locus)
> loop-dump.01.patch:386:+      location_t locus = get_loop_location(loop);
> loop-dump.01.patch:404:+          report_unroll_peel(loop, locus);
> loop-dump.01.patch:412:+      location_t locus = get_loop_location(loop);
> loop-dump.01.patch:429:+      report_unroll_peel(loop, locus);
> loop-dump.01.patch:533:+  if ((exit = single_exit(loop)))

I fixed all these and verified that check_GNU_style.sh no longer reports these.

>
>>@@ -248,6 +305,7 @@ peel_loops_completely (int flags)
>>
>>       if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
>>       {
>>+          report_unroll_peel(loop, locus);
>>         peel_loop_completely (loop);
>
> whitespace damage? You seem to have this kind of whitespace error
> throughout the patch. I take it you are aware of
> http://gcc.gnu.org/wiki/FormattingCodeForGCC
> and just forgot to have it on the machine you edited?

This was the same issue described above (tab vs space). As noted
above, I fixed this instance too, but there may be others and I'm not
sure what is required or correct.

>
> I seemingly have
> $ cat ~/.vim/gcc_style.vim
> " put this plugin into ~/.vim/gcc_style.vim and source it into your ~/.vimrc via
> " source ~/.vim/gcc_style.vim
> if exists("g:loaded_gcc_style") || &cp
>   finish
> endif
> let g:loaded_gcc_style = 1
>
> augroup gcc_style
>   autocmd BufReadPost,FileReadPost * call s:maybe_gcc_style()
> augroup END
> if exists("*s:maybe_gcc_style")
>   finish
> endif
> let s:cpo_save = &cpo
> set cpo&vim
>
> function! s:maybe_gcc_style()
>   let s:i = 1 + 0
>   while s:i <= line("$") && s:i <= 25
>     let s:line = getline(s:i)
>     if s:line =~ '^\s*This\sfile\sis\spart\sof\sGCC.*'
>       " gcc-mode
>       set cino=:s,{s,n-s,>2s,^-s
>       set sw=2
>       set sts=2
>       set cindent
>       set smartindent
>       set autoindent
>       break
>     else
>       let s:i = s:i + 1
>     endif
>   endwhile
> endfunction
>
> "command! NoGCCstyle unlet! g:loaded_gcc_style | au! gcc_style
> "command! DoGCCstyle runtime gcc_style.vim
> let &cpo = s:cpo_save

Thanks! I will see if I can use something like this too -
unfortunately I have multiple coding styles I need to code for, but I
will see if I can get myself to use this when editing gcc.

>
>>Index: cfgloop.c
>>===================================================================
>>--- cfgloop.c  (revision 194516)
>>+++ cfgloop.c  (working copy)
>>@@ -1666,3 +1666,59 @@ loop_exits_from_bb_p (struct loop *loop, basic_blo
>>
>>   return false;
>> }
>>+
>>+/* Return location corresponding to the loop control condition if possible. */
>>+
>>+location_t
>>+get_loop_location (struct loop *loop)
>>+{
>>+  rtx insn = NULL;
>>+  struct niter_desc *desc = NULL;
>>+  edge exit;
>>+
>>+  /* For a for or while loop, we would like to return the location
>>+   * of the for or while statement, if possible. To do this, look
>>+   * for the branch guarding the loop back-edge.
>>+   */
>
> IIRC there is not supposed to be a * in comments.

Fixed.

>
> Other than these nits i like it (but cannot approve it).

Thanks!
Teresa

>
> thanks,

New patch:

2012-12-20  Teresa Johnson  <tejohnson@google.com>

	* dumpfile.c (dump_loc): Print filename with location.
	* tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Use
        new location_t parameter to emit complete unroll message with
        new dump framework.
	(canonicalize_loop_induction_variables): Compute loops location
        and pass to try_unroll_loop_completely.
	* loop-unroll.c (report_unroll_peel): New function.
	(peel_loops_completely): Use new dump format with location
        for main dumpfile message, and invoke report_unroll_peel on success.
	(decide_unrolling_and_peeling): Ditto.
	(decide_peel_once_rolling): Remove old dumpfile message subsumed
        by report_unroll_peel.
	(decide_peel_completely): Ditto.
	(decide_unroll_constant_iterations): Ditto.
	(decide_unroll_runtime_iterations): Ditto.
	(decide_peel_simple): Ditto.
	(decide_unroll_stupid): Ditto.
	* cfgloop.c (get_loop_location): New function.
	* cfgloop.h (get_loop_location): Declare.

        testsuite/
	* gcc.dg/tree-ssa/loop-1.c: Update expected dump message.
	* gcc.dg/tree-ssa/loop-23.c: Ditto.
	* gcc.dg/tree-ssa/cunroll-1.c: Ditto.
	* gcc.dg/tree-ssa/cunroll-2.c: Ditto.
	* gcc.dg/tree-ssa/cunroll-3.c: Ditto.
	* gcc.dg/tree-ssa/cunroll-4.c: Ditto.
	* gcc.dg/tree-ssa/cunroll-5.c: Ditto.
	* testsuite/gcc.dg/unroll_1.c: Ditto.
	* testsuite/gcc.dg/unroll_2.c: Ditto.
	* testsuite/gcc.dg/unroll_3.c: Ditto.
	* testsuite/gcc.dg/unroll_4.c: Ditto.

Index: dumpfile.c
===================================================================
--- dumpfile.c	(revision 194516)
+++ dumpfile.c	(working copy)
@@ -265,7 +265,9 @@ dump_loc (int dump_kind, FILE *dfile, source_locat
                  DECL_SOURCE_FILE (current_function_decl),
                  DECL_SOURCE_LINE (current_function_decl));
      else
-        fprintf (dfile, "\n%d: ", LOCATION_LINE (loc));
+        fprintf (dfile, "\n%s:%d: note: ",
+                 LOCATION_FILE (loc),
+                 LOCATION_LINE (loc));
     }
 }

Index: testsuite/gcc.dg/unroll_2.c
===================================================================
--- testsuite/gcc.dg/unroll_2.c	(revision 194516)
+++ testsuite/gcc.dg/unroll_2.c	(working copy)
@@ -28,6 +28,6 @@ int foo2(void)
   return 1;
 }

-/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely"
1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it
never loops" 1 "loop2_unroll" } } */
 /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
 /* { dg-excess-errors "extra notes" } */
Index: testsuite/gcc.dg/unroll_3.c
===================================================================
--- testsuite/gcc.dg/unroll_3.c	(revision 194516)
+++ testsuite/gcc.dg/unroll_3.c	(working copy)
@@ -28,6 +28,6 @@ int foo2(void)
   return 1;
 }

-/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely"
1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it
never loops" 1 "loop2_unroll" } } */
 /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
 /* { dg-excess-errors "extra notes" } */
Index: testsuite/gcc.dg/tree-ssa/loop-1.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/loop-1.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/loop-1.c	(working copy)
@@ -33,7 +33,7 @@ int xxx(void)

 /* { dg-final { scan-tree-dump-times "Added canonical iv to loop 1, 4
iterations" 1 "ivcanon"} } */
 /* { dg-final { cleanup-tree-dump "ivcanon" } } */
-/* { dg-final { scan-tree-dump-times "Unrolled loop 1 completely" 1
"cunroll"} } */
+/* { dg-final { scan-tree-dump-times "Completely unroll loop 4 times"
1 "cunroll"} } */
 /* { dg-final { cleanup-tree-dump "cunroll" } } */
 /* { dg-final { scan-tree-dump-times "foo" 5 "optimized"} } */
 /* { dg-final { cleanup-tree-dump "optimized" } } */
Index: testsuite/gcc.dg/tree-ssa/cunroll-1.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/cunroll-1.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/cunroll-1.c	(working copy)
@@ -8,6 +8,6 @@ test(int c)
     a[i]=5;
 }
 /* Array bounds says the loop will not roll much.  */
-/* { dg-final { scan-tree-dump "Unrolled loop 1 completely
.duplicated 2 times.." "cunrolli"} } */
+/* { dg-final { scan-tree-dump "Completely unroll loop 2 times"
"cunrolli"} } */
 /* { dg-final { scan-tree-dump "Last iteration exit edge was proved
true." "cunrolli"} } */
 /* { dg-final { cleanup-tree-dump "cunrolli" } } */
Index: testsuite/gcc.dg/tree-ssa/cunroll-2.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/cunroll-2.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/cunroll-2.c	(working copy)
@@ -12,5 +12,5 @@ test(int c)
     }
 }
 /* We are not able to get rid of the final conditional because the
loop has two exits.  */
-/* { dg-final { scan-tree-dump "Unrolled loop 1 completely
.duplicated 1 times.." "cunroll"} } */
+/* { dg-final { scan-tree-dump "Completely unroll loop 1 times" "cunroll"} } */
 /* { dg-final { cleanup-tree-dump "cunroll" } } */
Index: testsuite/gcc.dg/tree-ssa/loop-23.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/loop-23.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/loop-23.c	(working copy)
@@ -24,6 +24,6 @@ int foo(void)
   return sum;
 }

-/* { dg-final { scan-tree-dump-times "Unrolled loop 1 completely" 1
"cunroll" } } */
+/* { dg-final { scan-tree-dump-times "Completely unroll loop 3 times"
1 "cunroll" } } */

 /* { dg-final { cleanup-tree-dump "cunroll" } } */
Index: testsuite/gcc.dg/tree-ssa/cunroll-3.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/cunroll-3.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/cunroll-3.c	(working copy)
@@ -11,5 +11,5 @@ test(int c)
 }
 /* If we start duplicating headers prior curoll, this loop will have
0 iterations.  */

-/* { dg-final { scan-tree-dump "Unrolled loop 1 completely
.duplicated 1 times.." "cunrolli"} } */
+/* { dg-final { scan-tree-dump "Completely unroll loop 1 times"
"cunrolli"} } */
 /* { dg-final { cleanup-tree-dump "cunrolli" } } */
Index: testsuite/gcc.dg/tree-ssa/cunroll-4.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/cunroll-4.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/cunroll-4.c	(working copy)
@@ -16,6 +16,6 @@ test(int c)

 /* We should do this as part of cunrolli, but our cost model do not
take into account early exit
    from the last iteration.  */
-/* { dg-final { scan-tree-dump "Turned loop 1 to non-loop; it never
loops." "ivcanon"} } */
+/* { dg-final { scan-tree-dump "Turned loop into non-loop; it never
loops." "ivcanon"} } */
 /* { dg-final { scan-tree-dump "Last iteration exit edge was proved
true." "ivcanon"} } */
 /* { dg-final { cleanup-tree-dump "ivcanon" } } */
Index: testsuite/gcc.dg/tree-ssa/cunroll-5.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/cunroll-5.c	(revision 194516)
+++ testsuite/gcc.dg/tree-ssa/cunroll-5.c	(working copy)
@@ -8,7 +8,7 @@ test(int c)
     a[i]=5;
 }
 /* Basic testcase for complette unrolling.  */
-/* { dg-final { scan-tree-dump "Unrolled loop 1 completely
.duplicated 5 times.." "cunroll"} } */
+/* { dg-final { scan-tree-dump "Completely unroll loop 5 times" "cunroll"} } */
 /* { dg-final { scan-tree-dump "Exit condition of peeled iterations
was eliminated." "cunroll"} } */
 /* { dg-final { scan-tree-dump "Last iteration exit edge was proved
true." "cunroll"} } */
 /* { dg-final { cleanup-tree-dump "cunroll" } } */
Index: testsuite/gcc.dg/unroll_4.c
===================================================================
--- testsuite/gcc.dg/unroll_4.c	(revision 194516)
+++ testsuite/gcc.dg/unroll_4.c	(working copy)
@@ -28,6 +28,6 @@ int foo2(void)
   return 1;
 }

-/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely"
1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it
never loops" 1 "loop2_unroll" } } */
 /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
 /* { dg-excess-errors "extra notes" } */
Index: testsuite/gcc.dg/unroll_1.c
===================================================================
--- testsuite/gcc.dg/unroll_1.c	(revision 194516)
+++ testsuite/gcc.dg/unroll_1.c	(working copy)
@@ -28,5 +28,5 @@ int foo2(void)
   return 1;
 }

-/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely"
2 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it
never loops" 2 "loop2_unroll" } } */
 /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
Index: tree-ssa-loop-ivcanon.c
===================================================================
--- tree-ssa-loop-ivcanon.c	(revision 194516)
+++ tree-ssa-loop-ivcanon.c	(working copy)
@@ -639,22 +639,24 @@ unloop_loops (bitmap loop_closed_ssa_invalidated,

 /* Tries to unroll LOOP completely, i.e. NITER times.
    UL determines which loops we are allowed to unroll.
-   EXIT is the exit of the loop that should be eliminated.
+   EXIT is the exit of the loop that should be eliminated.
    MAXITER specfy bound on number of iterations, -1 if it is
-   not known or too large for HOST_WIDE_INT.  */
+   not known or too large for HOST_WIDE_INT.  The location
+   LOCUS corresponding to the loop is used when emitting
+   a summary of the unroll to the dump file.  */

 static bool
 try_unroll_loop_completely (struct loop *loop,
 			    edge exit, tree niter,
 			    enum unroll_level ul,
-			    HOST_WIDE_INT maxiter)
+			    HOST_WIDE_INT maxiter,
+			    location_t locus)
 {
   unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll, unr_insns;
   gimple cond;
   struct loop_size size;
   bool n_unroll_found = false;
   edge edge_to_cancel = NULL;
-  int num = loop->num;

   /* See if we proved number of iterations to be low constant.

@@ -862,14 +864,25 @@ try_unroll_loop_completely (struct loop *loop,
   loops_to_unloop.safe_push (loop);
   loops_to_unloop_nunroll.safe_push (n_unroll);

-  if (dump_file && (dump_flags & TDF_DETAILS))
+  if (dump_enabled_p ())
     {
       if (!n_unroll)
-        fprintf (dump_file, "Turned loop %d to non-loop; it never loops.\n",
-		 num);
+        dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
+                         "Turned loop into non-loop; it never loops.\n");
       else
-        fprintf (dump_file, "Unrolled loop %d completely "
-		 "(duplicated %i times).\n", num, (int)n_unroll);
+        {
+          dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
+                           "Completely unroll loop %d times", (int)n_unroll);
+          if (profile_info)
+            dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS,
+                         " (header execution count %d)",
+                         (int)loop->header->count);
+          dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, "\n");
+        }
+    }
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
       if (exit)
         fprintf (dump_file, "Exit condition of peeled iterations was "
 		 "eliminated.\n");
@@ -898,15 +911,19 @@ canonicalize_loop_induction_variables (struct loop
   tree niter;
   HOST_WIDE_INT maxiter;
   bool modified = false;
+  location_t locus = UNKNOWN_LOCATION;

   niter = number_of_latch_executions (loop);
   if (TREE_CODE (niter) == INTEGER_CST)
-    exit = single_exit (loop);
+    {
+      exit = single_exit (loop);
+      locus = gimple_location (last_stmt (exit->src));
+    }
   else
     {
       /* If the loop has more than one exit, try checking all of them
 	 for # of iterations determinable through scev.  */
-      if (!single_exit (loop))
+      if (!(exit = single_exit (loop)))
 	niter = find_loop_niter (loop, &exit);

       /* Finally if everything else fails, try brute force evaluation.  */
@@ -915,6 +932,9 @@ canonicalize_loop_induction_variables (struct loop
 	      || TREE_CODE (niter) != INTEGER_CST))
 	niter = find_loop_niter_by_eval (loop, &exit);

+      if (exit)
+        locus = gimple_location (last_stmt (exit->src));
+
       if (TREE_CODE (niter) != INTEGER_CST)
 	exit = NULL;
     }
@@ -949,7 +969,7 @@ canonicalize_loop_induction_variables (struct loop
      populates the loop bounds.  */
   modified |= remove_redundant_iv_tests (loop);

-  if (try_unroll_loop_completely (loop, exit, niter, ul, maxiter))
+  if (try_unroll_loop_completely (loop, exit, niter, ul, maxiter, locus))
     return true;

   if (create_iv
Index: loop-unroll.c
===================================================================
--- loop-unroll.c	(revision 194516)
+++ loop-unroll.c	(working copy)
@@ -148,6 +148,61 @@ static void combine_var_copies_in_loop_exit (struc
 					     basic_block);
 static rtx get_expansion (struct var_to_expand *);

+/* Emit a message summarizing the unroll or peel that will be
+   performed for LOOP, along with the loop's location LOCUS, if
+   appropriate given the dump or -fopt-info settings.  */
+
+static void
+report_unroll_peel (struct loop *loop, location_t locus)
+{
+  struct niter_desc *desc;
+  int niters = 0;
+  int report_flags = MSG_OPTIMIZED_LOCATIONS | TDF_RTL | TDF_DETAILS;
+
+  if (!dump_enabled_p ())
+    return;
+
+  /* In the special case where the loop never iterated, emit
+     a different message so that we don't report an unroll by 0.
+     This matches the equivalent message emitted during tree unrolling.  */
+  if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY
+      && !loop->lpt_decision.times)
+    {
+      dump_printf_loc (report_flags, locus,
+                       "Turned loop into non-loop; it never loops.\n");
+      return;
+    }
+
+  desc = get_simple_loop_desc (loop);
+
+  if (desc->const_iter)
+    niters = desc->niter;
+  else if (loop->header->count)
+    niters = expected_loop_iterations (loop);
+
+  dump_printf_loc (report_flags, locus,
+                   "%s loop %d times",
+                   (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY
+                    ?  "Completely unroll"
+                    : (loop->lpt_decision.decision == LPT_PEEL_SIMPLE
+                       ? "Peel" : "Unroll")),
+                   loop->lpt_decision.times);
+  if (profile_info)
+    dump_printf (report_flags,
+                 " (header execution count %d",
+                 (int)loop->header->count);
+  if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
+    dump_printf (report_flags,
+                 "%s%s iterations %d)",
+                 profile_info ? ", " : " (",
+                 desc->const_iter ? "const" : "average",
+                 niters);
+  else if (profile_info)
+    dump_printf (report_flags, ")");
+
+  dump_printf (report_flags, "\n");
+}
+
 /* Unroll and/or peel (depending on FLAGS) LOOPS.  */
 void
 unroll_and_peel_loops (int flags)
@@ -234,11 +289,13 @@ peel_loops_completely (int flags)
   FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
     {
       loop->lpt_decision.decision = LPT_NONE;
+      location_t locus = get_loop_location (loop);

-      if (dump_file)
-	fprintf (dump_file,
-		 "\n;; *** Considering loop %d for complete peeling ***\n",
-		 loop->num);
+      if (dump_enabled_p ())
+	dump_printf_loc (TDF_RTL, locus,
+                         ";; *** Considering loop %d at BB %d for "
+                         "complete peeling ***\n",
+                         loop->num, loop->header->index);

       loop->ninsns = num_loop_insns (loop);

@@ -248,6 +305,7 @@ peel_loops_completely (int flags)

       if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
 	{
+	  report_unroll_peel (loop, locus);
 	  peel_loop_completely (loop);
 #ifdef ENABLE_CHECKING
 	  verify_loop_structure ();
@@ -267,9 +325,13 @@ decide_unrolling_and_peeling (int flags)
   FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
     {
       loop->lpt_decision.decision = LPT_NONE;
+      location_t locus = get_loop_location (loop);

-      if (dump_file)
-	fprintf (dump_file, "\n;; *** Considering loop %d ***\n", loop->num);
+      if (dump_enabled_p ())
+	dump_printf_loc (TDF_RTL, locus,
+                         ";; *** Considering loop %d at BB %d for "
+                         "unrolling and peeling ***\n",
+                         loop->num, loop->header->index);

       /* Do not peel cold areas.  */
       if (optimize_loop_for_size_p (loop))
@@ -309,6 +371,8 @@ decide_unrolling_and_peeling (int flags)
 	decide_unroll_stupid (loop, flags);
       if (loop->lpt_decision.decision == LPT_NONE)
 	decide_peel_simple (loop, flags);
+
+      report_unroll_peel (loop, locus);
     }
 }

@@ -348,8 +412,6 @@ decide_peel_once_rolling (struct loop *loop, int f
     }

   /* Success.  */
-  if (dump_file)
-    fprintf (dump_file, ";; Decided to peel exactly once rolling loop\n");
   loop->lpt_decision.decision = LPT_PEEL_COMPLETELY;
 }

@@ -429,8 +491,6 @@ decide_peel_completely (struct loop *loop, int fla
     }

   /* Success.  */
-  if (dump_file)
-    fprintf (dump_file, ";; Decided to peel loop completely\n");
   loop->lpt_decision.decision = LPT_PEEL_COMPLETELY;
 }

@@ -608,10 +668,6 @@ decide_unroll_constant_iterations (struct loop *lo

   loop->lpt_decision.decision = LPT_UNROLL_CONSTANT;
   loop->lpt_decision.times = best_unroll;
-
-  if (dump_file)
-    fprintf (dump_file, ";; Decided to unroll the loop %d times (%d
copies).\n",
-	     loop->lpt_decision.times, best_copies);
 }

 /* Unroll LOOP with constant number of iterations
LOOP->LPT_DECISION.TIMES times.
@@ -893,10 +949,6 @@ decide_unroll_runtime_iterations (struct loop *loo

   loop->lpt_decision.decision = LPT_UNROLL_RUNTIME;
   loop->lpt_decision.times = i - 1;
-
-  if (dump_file)
-    fprintf (dump_file, ";; Decided to unroll the loop %d times.\n",
-	     loop->lpt_decision.times);
 }

 /* Splits edge E and inserts the sequence of instructions INSNS on it, and
@@ -1305,10 +1357,6 @@ decide_peel_simple (struct loop *loop, int flags)
   /* Success.  */
   loop->lpt_decision.decision = LPT_PEEL_SIMPLE;
   loop->lpt_decision.times = npeel;
-
-  if (dump_file)
-    fprintf (dump_file, ";; Decided to simply peel the loop %d times.\n",
-	     loop->lpt_decision.times);
 }

 /* Peel a LOOP LOOP->LPT_DECISION.TIMES times.  The transformation does this:
@@ -1460,10 +1508,6 @@ decide_unroll_stupid (struct loop *loop, int flags

   loop->lpt_decision.decision = LPT_UNROLL_STUPID;
   loop->lpt_decision.times = i - 1;
-
-  if (dump_file)
-    fprintf (dump_file, ";; Decided to unroll the loop stupidly %d times.\n",
-	     loop->lpt_decision.times);
 }

 /* Unroll a LOOP LOOP->LPT_DECISION.TIMES times.  The transformation does this:
Index: cfgloop.c
===================================================================
--- cfgloop.c	(revision 194516)
+++ cfgloop.c	(working copy)
@@ -1666,3 +1666,55 @@ loop_exits_from_bb_p (struct loop *loop, basic_blo

   return false;
 }
+
+/* Return location corresponding to the loop control condition if possible.  */
+
+location_t
+get_loop_location (struct loop *loop)
+{
+  rtx insn = NULL;
+  struct niter_desc *desc = NULL;
+  edge exit;
+
+  /* For a for or while loop, we would like to return the location
+     of the for or while statement, if possible.  To do this, look
+     for the branch guarding the loop back-edge.  */
+
+  /* If this is a simple loop with an in_edge, then the loop control
+     branch is typically at the end of its source.  */
+  desc = get_simple_loop_desc (loop);
+  if (desc->in_edge)
+    {
+      FOR_BB_INSNS_REVERSE (desc->in_edge->src, insn)
+        {
+          if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+            return INSN_LOCATION (insn);
+        }
+    }
+  /* If loop has a single exit, then the loop control branch
+     must be at the end of its source.  */
+  if ((exit = single_exit (loop)))
+    {
+      FOR_BB_INSNS_REVERSE (exit->src, insn)
+        {
+          if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+            return INSN_LOCATION (insn);
+        }
+    }
+  /* Next check the latch, to see if it is non-empty.  */
+  FOR_BB_INSNS_REVERSE (loop->latch, insn)
+    {
+      if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+        return INSN_LOCATION (insn);
+    }
+  /* Finally, if none of the above identifies the loop control branch,
+     return the first location in the loop header.  */
+  FOR_BB_INSNS (loop->header, insn)
+    {
+      if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+        return INSN_LOCATION (insn);
+    }
+  /* If all else fails, simply return the current function location.  */
+  return DECL_SOURCE_LOCATION (current_function_decl);
+}
+
Index: cfgloop.h
===================================================================
--- cfgloop.h	(revision 194516)
+++ cfgloop.h	(working copy)
@@ -239,6 +239,7 @@ extern bool loop_exit_edge_p (const struct loop *,
 extern bool loop_exits_to_bb_p (struct loop *, basic_block);
 extern bool loop_exits_from_bb_p (struct loop *, basic_block);
 extern void mark_loop_exit_edges (void);
+extern location_t get_loop_location (struct loop *loop);

 /* Loops & cfg manipulation.  */
 extern basic_block *get_loop_body (const struct loop *);

--
Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Use new dump scheme to emit loop unroll/peel summary info (issue6941070)
  2012-12-20 17:21   ` Teresa Johnson
@ 2013-01-02 15:55     ` Teresa Johnson
  0 siblings, 0 replies; 5+ messages in thread
From: Teresa Johnson @ 2013-01-02 15:55 UTC (permalink / raw)
  To: Bernhard Reutner-Fischer
  Cc: reply, Richard Biener, David Li, Sharad Singhai, gcc-patches

On Thu, Dec 20, 2012 at 9:20 AM, Teresa Johnson <tejohnson@google.com> wrote:
> On Thu, Dec 20, 2012 at 1:21 AM, Bernhard Reutner-Fischer
> <rep.dot.nop@gmail.com> wrote:
>
> Thanks for your comments. Responses inlined below, and new patch include below.
>
>> On Mon, Dec 17, 2012 at 10:44:59PM -0800, Teresa Johnson wrote:
>>>Index: tree-ssa-loop-ivcanon.c
>>>===================================================================
>>>--- tree-ssa-loop-ivcanon.c    (revision 194516)
>>>+++ tree-ssa-loop-ivcanon.c    (working copy)
>>>@@ -639,22 +639,24 @@ unloop_loops (bitmap loop_closed_ssa_invalidated,
>>>
>>> /* Tries to unroll LOOP completely, i.e. NITER times.
>>>    UL determines which loops we are allowed to unroll.
>>>-   EXIT is the exit of the loop that should be eliminated.
>>>+   EXIT is the exit of the loop that should be eliminated.
>>>    MAXITER specfy bound on number of iterations, -1 if it is
>>>-   not known or too large for HOST_WIDE_INT.  */
>>>+   not known or too large for HOST_WIDE_INT. The location
>>>+   LOCUS corresponding to the loop is used when emitting
>>>+   a summary of the unroll to the dump file.  */
>>>
>>> static bool
>>> try_unroll_loop_completely (struct loop *loop,
>>>                           edge exit, tree niter,
>>>                           enum unroll_level ul,
>>>-                          HOST_WIDE_INT maxiter)
>>>+                          HOST_WIDE_INT maxiter,
>>>+                            location_t locus)
>>
>> whitespace damage?
>
> This and the other location you pointed out below as possible
> whitespace damage are because the surrounding lines use tab characters
> whereas mine uses spaces. Is there a guideline on which one is correct
> for gcc? I looked in the style guide but didn't find anything. The
> existing code uses a mix of indentation via tabs and spaces. I have
> fixed this location and the one you point out below to use a tab
> character so that the diff goes away, but I haven't searched the patch
> exhaustively for similar issues.
>
>>
>>>Index: loop-unroll.c
>>>===================================================================
>>>--- loop-unroll.c      (revision 194516)
>>>+++ loop-unroll.c      (working copy)
>>>@@ -148,6 +148,61 @@ static void combine_var_copies_in_loop_exit (struc
>>>                                            basic_block);
>>> static rtx get_expansion (struct var_to_expand *);
>>>
>>>+/* Emit a message summarizing the unroll or peel that will be
>>>+   performed for LOOP, along with the loop's location LOCUS, if
>>>+   appropriate given the dump or -fopt-info settings.  */
>>>+
>>>+static void
>>>+report_unroll_peel(struct loop *loop, location_t locus)
>>
>> missing space before (
>>
>> contrib/check_GNU_style.sh generally says:
>> Dot, space, space, new sentence.
>> loop-dump.01.patch:223:+   not known or too large for HOST_WIDE_INT. The location
>> loop-dump.01.patch:514:+   * of the for or while statement, if possible. To do this, look
>>
>> Dot, space, space, end of comment.
>> loop-dump.01.patch:504:+/* Return location corresponding to the loop control condition if possible. */
>> loop-dump.01.patch:541:+  /* Next check the latch, to see if it is non-empty. *
>> loop-dump.01.patch:555:+  /* If all else fails, simply return the current function location. */
>>
>> There should be exactly one space between function name and parentheses.
>> loop-dump.01.patch:329:+report_unroll_peel(struct loop *loop, location_t locus)
>> loop-dump.01.patch:386:+      location_t locus = get_loop_location(loop);
>> loop-dump.01.patch:404:+          report_unroll_peel(loop, locus);
>> loop-dump.01.patch:412:+      location_t locus = get_loop_location(loop);
>> loop-dump.01.patch:429:+      report_unroll_peel(loop, locus);
>> loop-dump.01.patch:533:+  if ((exit = single_exit(loop)))
>
> I fixed all these and verified that check_GNU_style.sh no longer reports these.
>
>>
>>>@@ -248,6 +305,7 @@ peel_loops_completely (int flags)
>>>
>>>       if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
>>>       {
>>>+          report_unroll_peel(loop, locus);
>>>         peel_loop_completely (loop);
>>
>> whitespace damage? You seem to have this kind of whitespace error
>> throughout the patch. I take it you are aware of
>> http://gcc.gnu.org/wiki/FormattingCodeForGCC
>> and just forgot to have it on the machine you edited?
>
> This was the same issue described above (tab vs space). As noted
> above, I fixed this instance too, but there may be others and I'm not
> sure what is required or correct.
>
>>
>> I seemingly have
>> $ cat ~/.vim/gcc_style.vim
>> " put this plugin into ~/.vim/gcc_style.vim and source it into your ~/.vimrc via
>> " source ~/.vim/gcc_style.vim
>> if exists("g:loaded_gcc_style") || &cp
>>   finish
>> endif
>> let g:loaded_gcc_style = 1
>>
>> augroup gcc_style
>>   autocmd BufReadPost,FileReadPost * call s:maybe_gcc_style()
>> augroup END
>> if exists("*s:maybe_gcc_style")
>>   finish
>> endif
>> let s:cpo_save = &cpo
>> set cpo&vim
>>
>> function! s:maybe_gcc_style()
>>   let s:i = 1 + 0
>>   while s:i <= line("$") && s:i <= 25
>>     let s:line = getline(s:i)
>>     if s:line =~ '^\s*This\sfile\sis\spart\sof\sGCC.*'
>>       " gcc-mode
>>       set cino=:s,{s,n-s,>2s,^-s
>>       set sw=2
>>       set sts=2
>>       set cindent
>>       set smartindent
>>       set autoindent
>>       break
>>     else
>>       let s:i = s:i + 1
>>     endif
>>   endwhile
>> endfunction
>>
>> "command! NoGCCstyle unlet! g:loaded_gcc_style | au! gcc_style
>> "command! DoGCCstyle runtime gcc_style.vim
>> let &cpo = s:cpo_save
>
> Thanks! I will see if I can use something like this too -
> unfortunately I have multiple coding styles I need to code for, but I
> will see if I can get myself to use this when editing gcc.
>
>>
>>>Index: cfgloop.c
>>>===================================================================
>>>--- cfgloop.c  (revision 194516)
>>>+++ cfgloop.c  (working copy)
>>>@@ -1666,3 +1666,59 @@ loop_exits_from_bb_p (struct loop *loop, basic_blo
>>>
>>>   return false;
>>> }
>>>+
>>>+/* Return location corresponding to the loop control condition if possible. */
>>>+
>>>+location_t
>>>+get_loop_location (struct loop *loop)
>>>+{
>>>+  rtx insn = NULL;
>>>+  struct niter_desc *desc = NULL;
>>>+  edge exit;
>>>+
>>>+  /* For a for or while loop, we would like to return the location
>>>+   * of the for or while statement, if possible. To do this, look
>>>+   * for the branch guarding the loop back-edge.
>>>+   */
>>
>> IIRC there is not supposed to be a * in comments.
>
> Fixed.
>
>>
>> Other than these nits i like it (but cannot approve it).
>
> Thanks!
> Teresa
>
>>
>> thanks,
>
> New patch:
>

Ping.

Thanks,
Teresa

> 2012-12-20  Teresa Johnson  <tejohnson@google.com>
>
>         * dumpfile.c (dump_loc): Print filename with location.
>         * tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Use
>         new location_t parameter to emit complete unroll message with
>         new dump framework.
>         (canonicalize_loop_induction_variables): Compute loops location
>         and pass to try_unroll_loop_completely.
>         * loop-unroll.c (report_unroll_peel): New function.
>         (peel_loops_completely): Use new dump format with location
>         for main dumpfile message, and invoke report_unroll_peel on success.
>         (decide_unrolling_and_peeling): Ditto.
>         (decide_peel_once_rolling): Remove old dumpfile message subsumed
>         by report_unroll_peel.
>         (decide_peel_completely): Ditto.
>         (decide_unroll_constant_iterations): Ditto.
>         (decide_unroll_runtime_iterations): Ditto.
>         (decide_peel_simple): Ditto.
>         (decide_unroll_stupid): Ditto.
>         * cfgloop.c (get_loop_location): New function.
>         * cfgloop.h (get_loop_location): Declare.
>
>         testsuite/
>         * gcc.dg/tree-ssa/loop-1.c: Update expected dump message.
>         * gcc.dg/tree-ssa/loop-23.c: Ditto.
>         * gcc.dg/tree-ssa/cunroll-1.c: Ditto.
>         * gcc.dg/tree-ssa/cunroll-2.c: Ditto.
>         * gcc.dg/tree-ssa/cunroll-3.c: Ditto.
>         * gcc.dg/tree-ssa/cunroll-4.c: Ditto.
>         * gcc.dg/tree-ssa/cunroll-5.c: Ditto.
>         * testsuite/gcc.dg/unroll_1.c: Ditto.
>         * testsuite/gcc.dg/unroll_2.c: Ditto.
>         * testsuite/gcc.dg/unroll_3.c: Ditto.
>         * testsuite/gcc.dg/unroll_4.c: Ditto.
>
> Index: dumpfile.c
> ===================================================================
> --- dumpfile.c  (revision 194516)
> +++ dumpfile.c  (working copy)
> @@ -265,7 +265,9 @@ dump_loc (int dump_kind, FILE *dfile, source_locat
>                   DECL_SOURCE_FILE (current_function_decl),
>                   DECL_SOURCE_LINE (current_function_decl));
>       else
> -        fprintf (dfile, "\n%d: ", LOCATION_LINE (loc));
> +        fprintf (dfile, "\n%s:%d: note: ",
> +                 LOCATION_FILE (loc),
> +                 LOCATION_LINE (loc));
>      }
>  }
>
> Index: testsuite/gcc.dg/unroll_2.c
> ===================================================================
> --- testsuite/gcc.dg/unroll_2.c (revision 194516)
> +++ testsuite/gcc.dg/unroll_2.c (working copy)
> @@ -28,6 +28,6 @@ int foo2(void)
>    return 1;
>  }
>
> -/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely"
> 1 "loop2_unroll" } } */
> +/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it
> never loops" 1 "loop2_unroll" } } */
>  /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
>  /* { dg-excess-errors "extra notes" } */
> Index: testsuite/gcc.dg/unroll_3.c
> ===================================================================
> --- testsuite/gcc.dg/unroll_3.c (revision 194516)
> +++ testsuite/gcc.dg/unroll_3.c (working copy)
> @@ -28,6 +28,6 @@ int foo2(void)
>    return 1;
>  }
>
> -/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely"
> 1 "loop2_unroll" } } */
> +/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it
> never loops" 1 "loop2_unroll" } } */
>  /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
>  /* { dg-excess-errors "extra notes" } */
> Index: testsuite/gcc.dg/tree-ssa/loop-1.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/loop-1.c  (revision 194516)
> +++ testsuite/gcc.dg/tree-ssa/loop-1.c  (working copy)
> @@ -33,7 +33,7 @@ int xxx(void)
>
>  /* { dg-final { scan-tree-dump-times "Added canonical iv to loop 1, 4
> iterations" 1 "ivcanon"} } */
>  /* { dg-final { cleanup-tree-dump "ivcanon" } } */
> -/* { dg-final { scan-tree-dump-times "Unrolled loop 1 completely" 1
> "cunroll"} } */
> +/* { dg-final { scan-tree-dump-times "Completely unroll loop 4 times"
> 1 "cunroll"} } */
>  /* { dg-final { cleanup-tree-dump "cunroll" } } */
>  /* { dg-final { scan-tree-dump-times "foo" 5 "optimized"} } */
>  /* { dg-final { cleanup-tree-dump "optimized" } } */
> Index: testsuite/gcc.dg/tree-ssa/cunroll-1.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/cunroll-1.c       (revision 194516)
> +++ testsuite/gcc.dg/tree-ssa/cunroll-1.c       (working copy)
> @@ -8,6 +8,6 @@ test(int c)
>      a[i]=5;
>  }
>  /* Array bounds says the loop will not roll much.  */
> -/* { dg-final { scan-tree-dump "Unrolled loop 1 completely
> .duplicated 2 times.." "cunrolli"} } */
> +/* { dg-final { scan-tree-dump "Completely unroll loop 2 times"
> "cunrolli"} } */
>  /* { dg-final { scan-tree-dump "Last iteration exit edge was proved
> true." "cunrolli"} } */
>  /* { dg-final { cleanup-tree-dump "cunrolli" } } */
> Index: testsuite/gcc.dg/tree-ssa/cunroll-2.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/cunroll-2.c       (revision 194516)
> +++ testsuite/gcc.dg/tree-ssa/cunroll-2.c       (working copy)
> @@ -12,5 +12,5 @@ test(int c)
>      }
>  }
>  /* We are not able to get rid of the final conditional because the
> loop has two exits.  */
> -/* { dg-final { scan-tree-dump "Unrolled loop 1 completely
> .duplicated 1 times.." "cunroll"} } */
> +/* { dg-final { scan-tree-dump "Completely unroll loop 1 times" "cunroll"} } */
>  /* { dg-final { cleanup-tree-dump "cunroll" } } */
> Index: testsuite/gcc.dg/tree-ssa/loop-23.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/loop-23.c (revision 194516)
> +++ testsuite/gcc.dg/tree-ssa/loop-23.c (working copy)
> @@ -24,6 +24,6 @@ int foo(void)
>    return sum;
>  }
>
> -/* { dg-final { scan-tree-dump-times "Unrolled loop 1 completely" 1
> "cunroll" } } */
> +/* { dg-final { scan-tree-dump-times "Completely unroll loop 3 times"
> 1 "cunroll" } } */
>
>  /* { dg-final { cleanup-tree-dump "cunroll" } } */
> Index: testsuite/gcc.dg/tree-ssa/cunroll-3.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/cunroll-3.c       (revision 194516)
> +++ testsuite/gcc.dg/tree-ssa/cunroll-3.c       (working copy)
> @@ -11,5 +11,5 @@ test(int c)
>  }
>  /* If we start duplicating headers prior curoll, this loop will have
> 0 iterations.  */
>
> -/* { dg-final { scan-tree-dump "Unrolled loop 1 completely
> .duplicated 1 times.." "cunrolli"} } */
> +/* { dg-final { scan-tree-dump "Completely unroll loop 1 times"
> "cunrolli"} } */
>  /* { dg-final { cleanup-tree-dump "cunrolli" } } */
> Index: testsuite/gcc.dg/tree-ssa/cunroll-4.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/cunroll-4.c       (revision 194516)
> +++ testsuite/gcc.dg/tree-ssa/cunroll-4.c       (working copy)
> @@ -16,6 +16,6 @@ test(int c)
>
>  /* We should do this as part of cunrolli, but our cost model do not
> take into account early exit
>     from the last iteration.  */
> -/* { dg-final { scan-tree-dump "Turned loop 1 to non-loop; it never
> loops." "ivcanon"} } */
> +/* { dg-final { scan-tree-dump "Turned loop into non-loop; it never
> loops." "ivcanon"} } */
>  /* { dg-final { scan-tree-dump "Last iteration exit edge was proved
> true." "ivcanon"} } */
>  /* { dg-final { cleanup-tree-dump "ivcanon" } } */
> Index: testsuite/gcc.dg/tree-ssa/cunroll-5.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/cunroll-5.c       (revision 194516)
> +++ testsuite/gcc.dg/tree-ssa/cunroll-5.c       (working copy)
> @@ -8,7 +8,7 @@ test(int c)
>      a[i]=5;
>  }
>  /* Basic testcase for complette unrolling.  */
> -/* { dg-final { scan-tree-dump "Unrolled loop 1 completely
> .duplicated 5 times.." "cunroll"} } */
> +/* { dg-final { scan-tree-dump "Completely unroll loop 5 times" "cunroll"} } */
>  /* { dg-final { scan-tree-dump "Exit condition of peeled iterations
> was eliminated." "cunroll"} } */
>  /* { dg-final { scan-tree-dump "Last iteration exit edge was proved
> true." "cunroll"} } */
>  /* { dg-final { cleanup-tree-dump "cunroll" } } */
> Index: testsuite/gcc.dg/unroll_4.c
> ===================================================================
> --- testsuite/gcc.dg/unroll_4.c (revision 194516)
> +++ testsuite/gcc.dg/unroll_4.c (working copy)
> @@ -28,6 +28,6 @@ int foo2(void)
>    return 1;
>  }
>
> -/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely"
> 1 "loop2_unroll" } } */
> +/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it
> never loops" 1 "loop2_unroll" } } */
>  /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
>  /* { dg-excess-errors "extra notes" } */
> Index: testsuite/gcc.dg/unroll_1.c
> ===================================================================
> --- testsuite/gcc.dg/unroll_1.c (revision 194516)
> +++ testsuite/gcc.dg/unroll_1.c (working copy)
> @@ -28,5 +28,5 @@ int foo2(void)
>    return 1;
>  }
>
> -/* { dg-final { scan-rtl-dump-times "Decided to peel loop completely"
> 2 "loop2_unroll" } } */
> +/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it
> never loops" 2 "loop2_unroll" } } */
>  /* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
> Index: tree-ssa-loop-ivcanon.c
> ===================================================================
> --- tree-ssa-loop-ivcanon.c     (revision 194516)
> +++ tree-ssa-loop-ivcanon.c     (working copy)
> @@ -639,22 +639,24 @@ unloop_loops (bitmap loop_closed_ssa_invalidated,
>
>  /* Tries to unroll LOOP completely, i.e. NITER times.
>     UL determines which loops we are allowed to unroll.
> -   EXIT is the exit of the loop that should be eliminated.
> +   EXIT is the exit of the loop that should be eliminated.
>     MAXITER specfy bound on number of iterations, -1 if it is
> -   not known or too large for HOST_WIDE_INT.  */
> +   not known or too large for HOST_WIDE_INT.  The location
> +   LOCUS corresponding to the loop is used when emitting
> +   a summary of the unroll to the dump file.  */
>
>  static bool
>  try_unroll_loop_completely (struct loop *loop,
>                             edge exit, tree niter,
>                             enum unroll_level ul,
> -                           HOST_WIDE_INT maxiter)
> +                           HOST_WIDE_INT maxiter,
> +                           location_t locus)
>  {
>    unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll, unr_insns;
>    gimple cond;
>    struct loop_size size;
>    bool n_unroll_found = false;
>    edge edge_to_cancel = NULL;
> -  int num = loop->num;
>
>    /* See if we proved number of iterations to be low constant.
>
> @@ -862,14 +864,25 @@ try_unroll_loop_completely (struct loop *loop,
>    loops_to_unloop.safe_push (loop);
>    loops_to_unloop_nunroll.safe_push (n_unroll);
>
> -  if (dump_file && (dump_flags & TDF_DETAILS))
> +  if (dump_enabled_p ())
>      {
>        if (!n_unroll)
> -        fprintf (dump_file, "Turned loop %d to non-loop; it never loops.\n",
> -                num);
> +        dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
> +                         "Turned loop into non-loop; it never loops.\n");
>        else
> -        fprintf (dump_file, "Unrolled loop %d completely "
> -                "(duplicated %i times).\n", num, (int)n_unroll);
> +        {
> +          dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
> +                           "Completely unroll loop %d times", (int)n_unroll);
> +          if (profile_info)
> +            dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS,
> +                         " (header execution count %d)",
> +                         (int)loop->header->count);
> +          dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, "\n");
> +        }
> +    }
> +
> +  if (dump_file && (dump_flags & TDF_DETAILS))
> +    {
>        if (exit)
>          fprintf (dump_file, "Exit condition of peeled iterations was "
>                  "eliminated.\n");
> @@ -898,15 +911,19 @@ canonicalize_loop_induction_variables (struct loop
>    tree niter;
>    HOST_WIDE_INT maxiter;
>    bool modified = false;
> +  location_t locus = UNKNOWN_LOCATION;
>
>    niter = number_of_latch_executions (loop);
>    if (TREE_CODE (niter) == INTEGER_CST)
> -    exit = single_exit (loop);
> +    {
> +      exit = single_exit (loop);
> +      locus = gimple_location (last_stmt (exit->src));
> +    }
>    else
>      {
>        /* If the loop has more than one exit, try checking all of them
>          for # of iterations determinable through scev.  */
> -      if (!single_exit (loop))
> +      if (!(exit = single_exit (loop)))
>         niter = find_loop_niter (loop, &exit);
>
>        /* Finally if everything else fails, try brute force evaluation.  */
> @@ -915,6 +932,9 @@ canonicalize_loop_induction_variables (struct loop
>               || TREE_CODE (niter) != INTEGER_CST))
>         niter = find_loop_niter_by_eval (loop, &exit);
>
> +      if (exit)
> +        locus = gimple_location (last_stmt (exit->src));
> +
>        if (TREE_CODE (niter) != INTEGER_CST)
>         exit = NULL;
>      }
> @@ -949,7 +969,7 @@ canonicalize_loop_induction_variables (struct loop
>       populates the loop bounds.  */
>    modified |= remove_redundant_iv_tests (loop);
>
> -  if (try_unroll_loop_completely (loop, exit, niter, ul, maxiter))
> +  if (try_unroll_loop_completely (loop, exit, niter, ul, maxiter, locus))
>      return true;
>
>    if (create_iv
> Index: loop-unroll.c
> ===================================================================
> --- loop-unroll.c       (revision 194516)
> +++ loop-unroll.c       (working copy)
> @@ -148,6 +148,61 @@ static void combine_var_copies_in_loop_exit (struc
>                                              basic_block);
>  static rtx get_expansion (struct var_to_expand *);
>
> +/* Emit a message summarizing the unroll or peel that will be
> +   performed for LOOP, along with the loop's location LOCUS, if
> +   appropriate given the dump or -fopt-info settings.  */
> +
> +static void
> +report_unroll_peel (struct loop *loop, location_t locus)
> +{
> +  struct niter_desc *desc;
> +  int niters = 0;
> +  int report_flags = MSG_OPTIMIZED_LOCATIONS | TDF_RTL | TDF_DETAILS;
> +
> +  if (!dump_enabled_p ())
> +    return;
> +
> +  /* In the special case where the loop never iterated, emit
> +     a different message so that we don't report an unroll by 0.
> +     This matches the equivalent message emitted during tree unrolling.  */
> +  if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY
> +      && !loop->lpt_decision.times)
> +    {
> +      dump_printf_loc (report_flags, locus,
> +                       "Turned loop into non-loop; it never loops.\n");
> +      return;
> +    }
> +
> +  desc = get_simple_loop_desc (loop);
> +
> +  if (desc->const_iter)
> +    niters = desc->niter;
> +  else if (loop->header->count)
> +    niters = expected_loop_iterations (loop);
> +
> +  dump_printf_loc (report_flags, locus,
> +                   "%s loop %d times",
> +                   (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY
> +                    ?  "Completely unroll"
> +                    : (loop->lpt_decision.decision == LPT_PEEL_SIMPLE
> +                       ? "Peel" : "Unroll")),
> +                   loop->lpt_decision.times);
> +  if (profile_info)
> +    dump_printf (report_flags,
> +                 " (header execution count %d",
> +                 (int)loop->header->count);
> +  if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
> +    dump_printf (report_flags,
> +                 "%s%s iterations %d)",
> +                 profile_info ? ", " : " (",
> +                 desc->const_iter ? "const" : "average",
> +                 niters);
> +  else if (profile_info)
> +    dump_printf (report_flags, ")");
> +
> +  dump_printf (report_flags, "\n");
> +}
> +
>  /* Unroll and/or peel (depending on FLAGS) LOOPS.  */
>  void
>  unroll_and_peel_loops (int flags)
> @@ -234,11 +289,13 @@ peel_loops_completely (int flags)
>    FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
>      {
>        loop->lpt_decision.decision = LPT_NONE;
> +      location_t locus = get_loop_location (loop);
>
> -      if (dump_file)
> -       fprintf (dump_file,
> -                "\n;; *** Considering loop %d for complete peeling ***\n",
> -                loop->num);
> +      if (dump_enabled_p ())
> +       dump_printf_loc (TDF_RTL, locus,
> +                         ";; *** Considering loop %d at BB %d for "
> +                         "complete peeling ***\n",
> +                         loop->num, loop->header->index);
>
>        loop->ninsns = num_loop_insns (loop);
>
> @@ -248,6 +305,7 @@ peel_loops_completely (int flags)
>
>        if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
>         {
> +         report_unroll_peel (loop, locus);
>           peel_loop_completely (loop);
>  #ifdef ENABLE_CHECKING
>           verify_loop_structure ();
> @@ -267,9 +325,13 @@ decide_unrolling_and_peeling (int flags)
>    FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
>      {
>        loop->lpt_decision.decision = LPT_NONE;
> +      location_t locus = get_loop_location (loop);
>
> -      if (dump_file)
> -       fprintf (dump_file, "\n;; *** Considering loop %d ***\n", loop->num);
> +      if (dump_enabled_p ())
> +       dump_printf_loc (TDF_RTL, locus,
> +                         ";; *** Considering loop %d at BB %d for "
> +                         "unrolling and peeling ***\n",
> +                         loop->num, loop->header->index);
>
>        /* Do not peel cold areas.  */
>        if (optimize_loop_for_size_p (loop))
> @@ -309,6 +371,8 @@ decide_unrolling_and_peeling (int flags)
>         decide_unroll_stupid (loop, flags);
>        if (loop->lpt_decision.decision == LPT_NONE)
>         decide_peel_simple (loop, flags);
> +
> +      report_unroll_peel (loop, locus);
>      }
>  }
>
> @@ -348,8 +412,6 @@ decide_peel_once_rolling (struct loop *loop, int f
>      }
>
>    /* Success.  */
> -  if (dump_file)
> -    fprintf (dump_file, ";; Decided to peel exactly once rolling loop\n");
>    loop->lpt_decision.decision = LPT_PEEL_COMPLETELY;
>  }
>
> @@ -429,8 +491,6 @@ decide_peel_completely (struct loop *loop, int fla
>      }
>
>    /* Success.  */
> -  if (dump_file)
> -    fprintf (dump_file, ";; Decided to peel loop completely\n");
>    loop->lpt_decision.decision = LPT_PEEL_COMPLETELY;
>  }
>
> @@ -608,10 +668,6 @@ decide_unroll_constant_iterations (struct loop *lo
>
>    loop->lpt_decision.decision = LPT_UNROLL_CONSTANT;
>    loop->lpt_decision.times = best_unroll;
> -
> -  if (dump_file)
> -    fprintf (dump_file, ";; Decided to unroll the loop %d times (%d
> copies).\n",
> -            loop->lpt_decision.times, best_copies);
>  }
>
>  /* Unroll LOOP with constant number of iterations
> LOOP->LPT_DECISION.TIMES times.
> @@ -893,10 +949,6 @@ decide_unroll_runtime_iterations (struct loop *loo
>
>    loop->lpt_decision.decision = LPT_UNROLL_RUNTIME;
>    loop->lpt_decision.times = i - 1;
> -
> -  if (dump_file)
> -    fprintf (dump_file, ";; Decided to unroll the loop %d times.\n",
> -            loop->lpt_decision.times);
>  }
>
>  /* Splits edge E and inserts the sequence of instructions INSNS on it, and
> @@ -1305,10 +1357,6 @@ decide_peel_simple (struct loop *loop, int flags)
>    /* Success.  */
>    loop->lpt_decision.decision = LPT_PEEL_SIMPLE;
>    loop->lpt_decision.times = npeel;
> -
> -  if (dump_file)
> -    fprintf (dump_file, ";; Decided to simply peel the loop %d times.\n",
> -            loop->lpt_decision.times);
>  }
>
>  /* Peel a LOOP LOOP->LPT_DECISION.TIMES times.  The transformation does this:
> @@ -1460,10 +1508,6 @@ decide_unroll_stupid (struct loop *loop, int flags
>
>    loop->lpt_decision.decision = LPT_UNROLL_STUPID;
>    loop->lpt_decision.times = i - 1;
> -
> -  if (dump_file)
> -    fprintf (dump_file, ";; Decided to unroll the loop stupidly %d times.\n",
> -            loop->lpt_decision.times);
>  }
>
>  /* Unroll a LOOP LOOP->LPT_DECISION.TIMES times.  The transformation does this:
> Index: cfgloop.c
> ===================================================================
> --- cfgloop.c   (revision 194516)
> +++ cfgloop.c   (working copy)
> @@ -1666,3 +1666,55 @@ loop_exits_from_bb_p (struct loop *loop, basic_blo
>
>    return false;
>  }
> +
> +/* Return location corresponding to the loop control condition if possible.  */
> +
> +location_t
> +get_loop_location (struct loop *loop)
> +{
> +  rtx insn = NULL;
> +  struct niter_desc *desc = NULL;
> +  edge exit;
> +
> +  /* For a for or while loop, we would like to return the location
> +     of the for or while statement, if possible.  To do this, look
> +     for the branch guarding the loop back-edge.  */
> +
> +  /* If this is a simple loop with an in_edge, then the loop control
> +     branch is typically at the end of its source.  */
> +  desc = get_simple_loop_desc (loop);
> +  if (desc->in_edge)
> +    {
> +      FOR_BB_INSNS_REVERSE (desc->in_edge->src, insn)
> +        {
> +          if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
> +            return INSN_LOCATION (insn);
> +        }
> +    }
> +  /* If loop has a single exit, then the loop control branch
> +     must be at the end of its source.  */
> +  if ((exit = single_exit (loop)))
> +    {
> +      FOR_BB_INSNS_REVERSE (exit->src, insn)
> +        {
> +          if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
> +            return INSN_LOCATION (insn);
> +        }
> +    }
> +  /* Next check the latch, to see if it is non-empty.  */
> +  FOR_BB_INSNS_REVERSE (loop->latch, insn)
> +    {
> +      if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
> +        return INSN_LOCATION (insn);
> +    }
> +  /* Finally, if none of the above identifies the loop control branch,
> +     return the first location in the loop header.  */
> +  FOR_BB_INSNS (loop->header, insn)
> +    {
> +      if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
> +        return INSN_LOCATION (insn);
> +    }
> +  /* If all else fails, simply return the current function location.  */
> +  return DECL_SOURCE_LOCATION (current_function_decl);
> +}
> +
> Index: cfgloop.h
> ===================================================================
> --- cfgloop.h   (revision 194516)
> +++ cfgloop.h   (working copy)
> @@ -239,6 +239,7 @@ extern bool loop_exit_edge_p (const struct loop *,
>  extern bool loop_exits_to_bb_p (struct loop *, basic_block);
>  extern bool loop_exits_from_bb_p (struct loop *, basic_block);
>  extern void mark_loop_exit_edges (void);
> +extern location_t get_loop_location (struct loop *loop);
>
>  /* Loops & cfg manipulation.  */
>  extern basic_block *get_loop_body (const struct loop *);
>
> --
> Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413



-- 
Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Use new dump scheme to emit loop unroll/peel summary info (issue6941070)
  2012-12-18  6:45 [PATCH] Use new dump scheme to emit loop unroll/peel summary info (issue6941070) Teresa Johnson
  2012-12-20  9:21 ` Bernhard Reutner-Fischer
@ 2013-01-02 17:55 ` Richard Henderson
  1 sibling, 0 replies; 5+ messages in thread
From: Richard Henderson @ 2013-01-02 17:55 UTC (permalink / raw)
  To: Teresa Johnson; +Cc: reply, richard.guenther, davidxl, singhai, gcc-patches

On 12/17/2012 10:44 PM, Teresa Johnson wrote:
> 2012-12-17  Teresa Johnson  <tejohnson@google.com>
> 
> 	* dumpfile.c (dump_loc): Print filename with location.
> 	* tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Use
>         new location_t parameter to emit complete unroll message with
>         new dump framework.
> 	(canonicalize_loop_induction_variables): Compute loops location
>         and pass to try_unroll_loop_completely.
> 	* loop-unroll.c (report_unroll_peel): New function.
> 	(peel_loops_completely): Use new dump format with location
>         for main dumpfile message, and invoke report_unroll_peel on success.
> 	(decide_unrolling_and_peeling): Ditto.
> 	(decide_peel_once_rolling): Remove old dumpfile message subsumed
>         by report_unroll_peel.
> 	(decide_peel_completely): Ditto.
> 	(decide_unroll_constant_iterations): Ditto.
> 	(decide_unroll_runtime_iterations): Ditto.
> 	(decide_peel_simple): Ditto.
> 	(decide_unroll_stupid): Ditto.
> 	* cfgloop.c (get_loop_location): New function.
> 	* cfgloop.h (get_loop_location): Declare.
> 
>         testsuite/
> 	* gcc.dg/tree-ssa/loop-1.c: Update expected dump message.
> 	* gcc.dg/tree-ssa/loop-23.c: Ditto.
> 	* gcc.dg/tree-ssa/cunroll-1.c: Ditto.
> 	* gcc.dg/tree-ssa/cunroll-2.c: Ditto.
> 	* gcc.dg/tree-ssa/cunroll-3.c: Ditto.
> 	* gcc.dg/tree-ssa/cunroll-4.c: Ditto.
> 	* gcc.dg/tree-ssa/cunroll-5.c: Ditto.
> 	* testsuite/gcc.dg/unroll_1.c:
> 	* testsuite/gcc.dg/unroll_2.c:
> 	* testsuite/gcc.dg/unroll_3.c:
> 	* testsuite/gcc.dg/unroll_4.c:

Ok except,

> -      if (!single_exit (loop))
> +      if (!(exit = single_exit (loop)))

Avoid nested assignment when its easy, as it is in this case.


r~

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-01-02 17:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-18  6:45 [PATCH] Use new dump scheme to emit loop unroll/peel summary info (issue6941070) Teresa Johnson
2012-12-20  9:21 ` Bernhard Reutner-Fischer
2012-12-20 17:21   ` Teresa Johnson
2013-01-02 15:55     ` Teresa Johnson
2013-01-02 17:55 ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).