]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-loop-distribution.c: Include tree-vectorizer.h for find_loop_location.
authorRichard Biener <rguenther@suse.de>
Wed, 2 Oct 2013 13:46:32 +0000 (13:46 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 2 Oct 2013 13:46:32 +0000 (13:46 +0000)
2013-10-02  Richard Biener  <rguenther@suse.de>

* tree-loop-distribution.c: Include tree-vectorizer.h for
find_loop_location.
(enum partition_kind): Remove PKIND_REDUCTION.
(struct partition_s): Remove has_writes member, add reduction_p
member.
(partition_alloc): Adjust.
(partition_builtin_p): Likewise.
(partition_has_writes): Remove.
(partition_reduction_p): New function.
(partition_merge_into): Likewise.
(generate_code_for_partition): Commonize builtin partition
handling tail.
(rdg_cannot_recompute_vertex_p): Remove.
(already_processed_vertex_p): Likewise.
(rdg_flag_vertex): Do not set has_writes.
(classify_partition): Adjust.
(rdg_build_partitions): Do not set has_writes, treat all
partitions as useful.
(distribute_loop): Record number of library calls generated.
Adjust.
(tree_loop_distribution): Report number of loops and library
calls generated as opt-info.

* gcc.dg/tree-ssa/ldist-11.c: Adjust.
* gcc.dg/tree-ssa/ldist-17.c: Likewise.
* gcc.dg/tree-ssa/ldist-23.c: Likewise.
* gcc.dg/tree-ssa/ldist-pr45948.c: Likewise.
* gfortran.dg/ldist-pr45199.f: Likewise.

From-SVN: r203115

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ldist-11.c
gcc/testsuite/gcc.dg/tree-ssa/ldist-17.c
gcc/testsuite/gcc.dg/tree-ssa/ldist-23.c
gcc/testsuite/gcc.dg/tree-ssa/ldist-pr45948.c
gcc/testsuite/gfortran.dg/ldist-pr45199.f
gcc/tree-loop-distribution.c

index 237e693b19050b382946f379564c41349a9f7be7..87b789a067ff99bca9c9614558be2b2855824278 100644 (file)
@@ -1,3 +1,28 @@
+2013-10-02  Richard Biener  <rguenther@suse.de>
+
+       * tree-loop-distribution.c: Include tree-vectorizer.h for
+       find_loop_location.
+       (enum partition_kind): Remove PKIND_REDUCTION.
+       (struct partition_s): Remove has_writes member, add reduction_p
+       member.
+       (partition_alloc): Adjust.
+       (partition_builtin_p): Likewise.
+       (partition_has_writes): Remove.
+       (partition_reduction_p): New function.
+       (partition_merge_into): Likewise.
+       (generate_code_for_partition): Commonize builtin partition
+       handling tail.
+       (rdg_cannot_recompute_vertex_p): Remove.
+       (already_processed_vertex_p): Likewise.
+       (rdg_flag_vertex): Do not set has_writes.
+       (classify_partition): Adjust.
+       (rdg_build_partitions): Do not set has_writes, treat all
+       partitions as useful.
+       (distribute_loop): Record number of library calls generated.
+       Adjust.
+       (tree_loop_distribution): Report number of loops and library
+       calls generated as opt-info.
+
 2013-10-02  Andrew MacLeod  <amacleod@redhat.com>
 
        * tree-flow.h: Include new .h files.  Move prototypes.
index cbeb33dd7e7fe38a89fbbb23aa4b89f6a7ffa201..754a6a2f2934effb2c11a0f6f442ee843c09ea1a 100644 (file)
@@ -1,3 +1,11 @@
+2013-10-02  Richard Biener  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/ldist-11.c: Adjust.
+       * gcc.dg/tree-ssa/ldist-17.c: Likewise.
+       * gcc.dg/tree-ssa/ldist-23.c: Likewise.
+       * gcc.dg/tree-ssa/ldist-pr45948.c: Likewise.
+       * gfortran.dg/ldist-pr45199.f: Likewise.
+
 2013-10-02  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/58565
index e55a1b64ecc1ee57110cf345439dcb6bdedd6d03..902c25b1553083edda8e3be3b1930495b42f7b44 100644 (file)
@@ -28,6 +28,6 @@ void foo (int * __restrict__ ia,
   */
 }
 
-/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 1 "ldist" } } */
+/* { dg-final { scan-tree-dump-times "distributed: split to 1 loops and 1 library calls" 1 "ldist" } } */
 /* { dg-final { scan-tree-dump-times "generated memset zero" 1 "ldist" } } */
 /* { dg-final { cleanup-tree-dump "ldist" } } */
index 5c280b3f0c43716a4a3aa5920964e721a18ebab2..bbf54db2be913bc048bf5d3a7515a055402911a7 100644 (file)
@@ -45,6 +45,6 @@ mad_synth_mute (struct mad_synth *synth)
   return;
 }
 
-/* { dg-final { scan-tree-dump "distributed: split to 4" "ldist" } } */
+/* { dg-final { scan-tree-dump "distributed: split to 0 loops and 4 library calls" "ldist" } } */
 /* { dg-final { scan-tree-dump-times "generated memset zero" 4 "ldist" } } */
 /* { dg-final { cleanup-tree-dump "ldist" } } */
index 22b82d9920d5c93f259db12e3f8210365cdd01fd..0e7609bdb5733a0d05fdf33bc46c701645007b04 100644 (file)
@@ -29,6 +29,6 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump "split to 2 loops" "ldist" } } */
+/* { dg-final { scan-tree-dump "split to 1 loops and 1 library call" "ldist" } } */
 /* { dg-final { scan-tree-dump "generated memcpy" "ldist" } } */
 /* { dg-final { cleanup-tree-dump "ldist" } } */
index da3c7b626f9ae0ca818f8683292367c4060dfbd1..f25a910643018c9585ec8deca439b28bd4c4b9ea 100644 (file)
@@ -18,6 +18,6 @@ foo (int i, int n)
 
 /* We should apply loop distribution and generate 2 memset (0).  */
 
-/* { dg-final { scan-tree-dump "distributed: split to 2" "ldist" } } */
+/* { dg-final { scan-tree-dump "distributed: split to 0 loops and 2 library calls" "ldist" } } */
 /* { dg-final { scan-tree-dump-times "generated memset zero" 2 "ldist" } } */
 /* { dg-final { cleanup-tree-dump "ldist" } } */
index 22b202e07e6a4de33bb4d7fb3e66dc43f0ca49fc..e01d32f2664b02ba847a91f72482b8c3f64b0a5a 100644 (file)
@@ -22,6 +22,6 @@
 
 ! GCC should apply memset zero loop distribution and it should not ICE.
 
-! { dg-final { scan-tree-dump "distributed: split to 9 loops" "ldist" } }
+! { dg-final { scan-tree-dump "distributed: split to 0 loops and 9 library calls" "ldist" } }
 ! { dg-final { scan-tree-dump-times "generated memset zero" 9 "ldist" } }
 ! { dg-final { cleanup-tree-dump "ldist" } }
index fe2f7b65b590b6214429665c33f080e82f97e08b..44be6cb18838da4125f1fd0f1883095fff1c7085 100644 (file)
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-scalar-evolution.h"
 #include "tree-pass.h"
 #include "gimple-pretty-print.h"
+#include "tree-vectorizer.h"
 
 
 /* A Reduced Dependence Graph (RDG) vertex representing a statement.  */
@@ -557,14 +558,14 @@ build_rdg (vec<loop_p> loop_nest, control_dependences *cd)
 
 
 enum partition_kind {
-    PKIND_NORMAL, PKIND_REDUCTION, PKIND_MEMSET, PKIND_MEMCPY
+    PKIND_NORMAL, PKIND_MEMSET, PKIND_MEMCPY
 };
 
 typedef struct partition_s
 {
   bitmap stmts;
   bitmap loops;
-  bool has_writes;
+  bool reduction_p;
   enum partition_kind kind;
   /* data-references a kind != PKIND_NORMAL partition is about.  */
   data_reference_p main_dr;
@@ -581,7 +582,7 @@ partition_alloc (bitmap stmts, bitmap loops)
   partition_t partition = XCNEW (struct partition_s);
   partition->stmts = stmts ? stmts : BITMAP_ALLOC (NULL);
   partition->loops = loops ? loops : BITMAP_ALLOC (NULL);
-  partition->has_writes = false;
+  partition->reduction_p = false;
   partition->kind = PKIND_NORMAL;
   return partition;
 }
@@ -601,17 +602,29 @@ partition_free (partition_t partition)
 static bool
 partition_builtin_p (partition_t partition)
 {
-  return partition->kind > PKIND_REDUCTION;
+  return partition->kind != PKIND_NORMAL;
 }
 
-/* Returns true if the partition has an writes.  */
+/* Returns true if the partition contains a reduction.  */
 
 static bool
-partition_has_writes (partition_t partition)
+partition_reduction_p (partition_t partition)
 {
-  return partition->has_writes;
+  return partition->reduction_p;
 }
 
+/* Merge PARTITION into the partition DEST.  */
+
+static void
+partition_merge_into (partition_t dest, partition_t partition)
+{
+  dest->kind = PKIND_NORMAL;
+  bitmap_ior_into (dest->stmts, partition->stmts);
+  if (partition_reduction_p (partition))
+    dest->reduction_p = true;
+}
+
+
 /* Returns true when DEF is an SSA_NAME defined in LOOP and used after
    the LOOP.  */
 
@@ -998,58 +1011,31 @@ generate_code_for_partition (struct loop *loop,
 {
   switch (partition->kind)
     {
+    case PKIND_NORMAL:
+      /* Reductions all have to be in the last partition.  */
+      gcc_assert (!partition_reduction_p (partition)
+                 || !copy_p);
+      generate_loops_for_partition (loop, partition, copy_p);
+      return;
+
     case PKIND_MEMSET:
       generate_memset_builtin (loop, partition);
-      /* If this is the last partition for which we generate code, we have
-        to destroy the loop.  */
-      if (!copy_p)
-       destroy_loop (loop);
       break;
 
     case PKIND_MEMCPY:
       generate_memcpy_builtin (loop, partition);
-      /* If this is the last partition for which we generate code, we have
-        to destroy the loop.  */
-      if (!copy_p)
-       destroy_loop (loop);
-      break;
-
-    case PKIND_REDUCTION:
-      /* Reductions all have to be in the last partition.  */
-      gcc_assert (!copy_p);
-    case PKIND_NORMAL:
-      generate_loops_for_partition (loop, partition, copy_p);
       break;
 
     default:
       gcc_unreachable ();
     }
-}
-
-
-/* Returns true if the node V of RDG cannot be recomputed.  */
-
-static bool
-rdg_cannot_recompute_vertex_p (struct graph *rdg, int v)
-{
-  if (RDG_MEM_WRITE_STMT (rdg, v))
-    return true;
 
-  return false;
-}
-
-/* Returns true when the vertex V has already been generated in the
-   current partition (V is in PROCESSED), or when V belongs to another
-   partition and cannot be recomputed (V is not in REMAINING_STMTS).  */
-
-static inline bool
-already_processed_vertex_p (bitmap processed, int v)
-{
-  return bitmap_bit_p (processed, v);
+  /* Common tail for partitions we turn into a call.  If this was the last
+     partition for which we generate code, we have to destroy the loop.  */
+  if (!copy_p)
+    destroy_loop (loop);
 }
 
-static void rdg_flag_vertex_and_dependent (struct graph *, int, partition_t,
-                                          bitmap);
 
 /* Flag V from RDG as part of PARTITION, and also flag its loop number
    in LOOPS.  */
@@ -1064,9 +1050,6 @@ rdg_flag_vertex (struct graph *rdg, int v, partition_t partition)
 
   loop = loop_containing_stmt (RDG_STMT (rdg, v));
   bitmap_set_bit (partition->loops, loop->num);
-
-  if (rdg_cannot_recompute_vertex_p (rdg, v))
-    partition->has_writes = true;
 }
 
 /* Flag in the bitmap PARTITION the vertex V and all its predecessors.
@@ -1127,15 +1110,10 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition)
       if (gimple_has_volatile_ops (stmt))
        volatiles_p = true;
 
-      /* If the stmt has uses outside of the loop fail.
-        ???  If the stmt is generated in another partition that
-        is not created as builtin we can ignore this.  */
+      /* If the stmt has uses outside of the loop mark it as reduction.  */
       if (stmt_has_scalar_dependences_outside_loop (loop, stmt))
        {
-         if (dump_file && (dump_flags & TDF_DETAILS))
-           fprintf (dump_file, "not generating builtin, partition has "
-                    "scalar uses outside of the loop\n");
-         partition->kind = PKIND_REDUCTION;
+         partition->reduction_p = true;
          return;
        }
     }
@@ -1356,21 +1334,17 @@ rdg_build_partitions (struct graph *rdg,
 
       np = build_rdg_partition_for_vertex (rdg, v);
       bitmap_ior_into (partition->stmts, np->stmts);
-      partition->has_writes = partition_has_writes (np);
       bitmap_ior_into (processed, np->stmts);
       partition_free (np);
 
-      if (partition_has_writes (partition))
+      if (dump_file && (dump_flags & TDF_DETAILS))
        {
-         if (dump_file && (dump_flags & TDF_DETAILS))
-           {
-             fprintf (dump_file, "ldist useful partition:\n");
-             dump_bitmap (dump_file, partition->stmts);
-           }
-
-         partitions->safe_push (partition);
-         partition = partition_alloc (NULL, NULL);
+         fprintf (dump_file, "ldist useful partition:\n");
+         dump_bitmap (dump_file, partition->stmts);
        }
+
+      partitions->safe_push (partition);
+      partition = partition_alloc (NULL, NULL);
     }
 
   /* All vertices should have been assigned to at least one partition now,
@@ -1480,7 +1454,7 @@ partition_contains_all_rw (struct graph *rdg,
 
 static int
 distribute_loop (struct loop *loop, vec<gimple> stmts,
-                control_dependences *cd)
+                control_dependences *cd, int *nb_calls)
 {
   struct graph *rdg;
   vec<loop_p> loop_nest;
@@ -1489,6 +1463,7 @@ distribute_loop (struct loop *loop, vec<gimple> stmts,
   bool any_builtin;
   int i, nbp;
 
+  *nb_calls = 0;
   loop_nest.create (3);
   if (!find_loop_nest (loop, &loop_nest))
     {
@@ -1551,9 +1526,7 @@ distribute_loop (struct loop *loop, vec<gimple> stmts,
                  fprintf (dump_file, "because they have similar "
                           "memory accesses\n");
                }
-             bitmap_ior_into (into->stmts, partition->stmts);
-             if (partition->kind == PKIND_REDUCTION)
-               into->kind = PKIND_REDUCTION;
+             partition_merge_into (into, partition);
              partitions.ordered_remove (j);
              partition_free (partition);
              j--;
@@ -1577,9 +1550,7 @@ distribute_loop (struct loop *loop, vec<gimple> stmts,
          for (++i; partitions.iterate (i, &partition); ++i)
            if (!partition_builtin_p (partition))
              {
-               bitmap_ior_into (into->stmts, partition->stmts);
-               if (partition->kind == PKIND_REDUCTION)
-                 into->kind = PKIND_REDUCTION;
+               partition_merge_into (into, partition);
                partitions.ordered_remove (i);
                partition_free (partition);
                i--;
@@ -1597,7 +1568,7 @@ distribute_loop (struct loop *loop, vec<gimple> stmts,
       for (i = partitions.length () - 2; i >= 0; --i)
        {
          partition_t what = partitions[i];
-         if (what->kind == PKIND_REDUCTION)
+         if (partition_reduction_p (what))
            {
              if (dump_file && (dump_flags & TDF_DETAILS))
                {
@@ -1606,8 +1577,7 @@ distribute_loop (struct loop *loop, vec<gimple> stmts,
                  dump_bitmap (dump_file, what->stmts);
                  fprintf (dump_file, "because the latter has reductions\n");
                }
-             bitmap_ior_into (into->stmts, what->stmts);
-             into->kind = PKIND_REDUCTION;
+             partition_merge_into (into, what);
              partitions.ordered_remove (i);
              partition_free (what);
            }
@@ -1627,7 +1597,11 @@ distribute_loop (struct loop *loop, vec<gimple> stmts,
     dump_rdg_partitions (dump_file, partitions);
 
   FOR_EACH_VEC_ELT (partitions, i, partition)
-    generate_code_for_partition (loop, partition, i < nbp - 1);
+    {
+      if (partition_builtin_p (partition))
+       (*nb_calls)++;
+      generate_code_for_partition (loop, partition, i < nbp - 1);
+    }
 
  ldist_done:
 
@@ -1637,7 +1611,7 @@ distribute_loop (struct loop *loop, vec<gimple> stmts,
 
   free_rdg (rdg);
   loop_nest.release ();
-  return nbp;
+  return nbp - *nb_calls;
 }
 
 /* Distribute all loops in the current function.  */
@@ -1667,7 +1641,6 @@ tree_loop_distribution (void)
       vec<gimple> work_list = vNULL;
       basic_block *bbs;
       int num = loop->num;
-      int nb_generated_loops = 0;
       unsigned int i;
 
       /* If the loop doesn't have a single exit we will fail anyway,
@@ -1722,6 +1695,9 @@ tree_loop_distribution (void)
 out:
       free (bbs);
 
+      int nb_generated_loops = 0;
+      int nb_generated_calls = 0;
+      location_t loc = find_loop_location (loop);
       if (work_list.length () > 0)
        {
          if (!cd)
@@ -1731,20 +1707,20 @@ out:
              cd = new control_dependences (create_edge_list ());
              free_dominance_info (CDI_POST_DOMINATORS);
            }
-         nb_generated_loops = distribute_loop (loop, work_list, cd);
+         nb_generated_loops = distribute_loop (loop, work_list, cd,
+                                               &nb_generated_calls);
        }
 
-      if (nb_generated_loops > 0)
-       changed = true;
-
-      if (dump_file && (dump_flags & TDF_DETAILS))
+      if (nb_generated_loops + nb_generated_calls > 0)
        {
-         if (nb_generated_loops > 1)
-           fprintf (dump_file, "Loop %d distributed: split to %d loops.\n",
-                    num, nb_generated_loops);
-         else
-           fprintf (dump_file, "Loop %d is the same.\n", num);
+         changed = true;
+         dump_printf_loc (MSG_OPTIMIZED_LOCATIONS,
+                          loc, "Loop %d distributed: split to %d loops "
+                          "and %d library calls.\n",
+                          num, nb_generated_loops, nb_generated_calls);
        }
+      else if (dump_file && (dump_flags & TDF_DETAILS))
+       fprintf (dump_file, "Loop %d is the same.\n", num);
 
       work_list.release ();
     }