tree-data-ref.c (struct rdg_vertex_info): Remove.
authorRichard Guenther <rguenther@suse.de>
Mon, 4 Jun 2012 13:18:16 +0000 (13:18 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 4 Jun 2012 13:18:16 +0000 (13:18 +0000)
2012-06-04  Richard Guenther  <rguenther@suse.de>

* tree-data-ref.c (struct rdg_vertex_info): Remove.
(rdg_vertex_for_stmt): Simplify using gimple_uid.
(create_rdg_vertices): Pass loop argument, remove stmt to RDG index
hashtable.   Record stmt data-references.
(hash_stmt_vertex_info): Remove.
(eq_stmt_vertex_info): Likewise.
(hash_stmt_vertex_del): Likewise.
(build_empty_rdg): Simplify.
(build_rdg): Adjust.
(free_rdg): Likewise.
(ref_base_address): Remove.
(have_similar_memory_accesses): Likewise.
* tree-data-ref.h (create_rdg_vertices): Remove.
(struct rdg_vertex): Add datarefs member.
(RDGV_DATAREFS): New define.
(RDG_DATAREFS): Likewise.
(have_similar_memory_accesses): Remove.
(rdg_has_similar_memory_accesses): Likewise.
* tree-loop-distribution.c (ref_base_address): Re-implement here.
(similar_memory_accesses): Re-implement using existing data-references.
(tree_loop_distribution): Initialize stmt uids for the stmt to
RDG index mapping.
* tree-vect-loop.c (vect_create_epilog_for_reduction): Only
access stmt vinfo for stmts in loop.

From-SVN: r188180

gcc/ChangeLog
gcc/tree-data-ref.c
gcc/tree-data-ref.h
gcc/tree-loop-distribution.c
gcc/tree-vect-loop.c

index 9ab51e8f4e416ff32d24d81345ec412f012dcafc..7722dd587e7ca2db2be7b70cddd24cb9fd760568 100644 (file)
@@ -1,3 +1,30 @@
+2012-06-04  Richard Guenther  <rguenther@suse.de>
+
+       * tree-data-ref.c (struct rdg_vertex_info): Remove.
+       (rdg_vertex_for_stmt): Simplify using gimple_uid.
+       (create_rdg_vertices): Pass loop argument, remove stmt to RDG index
+       hashtable.   Record stmt data-references.
+       (hash_stmt_vertex_info): Remove.
+       (eq_stmt_vertex_info): Likewise.
+       (hash_stmt_vertex_del): Likewise.
+       (build_empty_rdg): Simplify.
+       (build_rdg): Adjust.
+       (free_rdg): Likewise.
+       (ref_base_address): Remove.
+       (have_similar_memory_accesses): Likewise.
+       * tree-data-ref.h (create_rdg_vertices): Remove.
+       (struct rdg_vertex): Add datarefs member.
+       (RDGV_DATAREFS): New define.
+       (RDG_DATAREFS): Likewise.
+       (have_similar_memory_accesses): Remove.
+       (rdg_has_similar_memory_accesses): Likewise.
+       * tree-loop-distribution.c (ref_base_address): Re-implement here.
+       (similar_memory_accesses): Re-implement using existing data-references.
+       (tree_loop_distribution): Initialize stmt uids for the stmt to
+       RDG index mapping.
+       * tree-vect-loop.c (vect_create_epilog_for_reduction): Only
+       access stmt vinfo for stmts in loop.
+
 2012-06-04  Andreas Schwab  <schwab@linux-m68k.org>
 
        PR target/53461
index bbfc32154ef0f1d9da39771004a721e680abec25..bf1d859178b46969adfb507c0ec943afce7a215c 100644 (file)
@@ -4924,29 +4924,14 @@ dot_rdg (struct graph *rdg)
 #endif
 }
 
-/* This structure is used for recording the mapping statement index in
-   the RDG.  */
-
-struct GTY(()) rdg_vertex_info
-{
-  gimple stmt;
-  int index;
-};
-
 /* Returns the index of STMT in RDG.  */
 
 int
-rdg_vertex_for_stmt (struct graph *rdg, gimple stmt)
+rdg_vertex_for_stmt (struct graph *rdg ATTRIBUTE_UNUSED, gimple stmt)
 {
-  struct rdg_vertex_info rvi, *slot;
-
-  rvi.stmt = stmt;
-  slot = (struct rdg_vertex_info *) htab_find (rdg->indices, &rvi);
-
-  if (!slot)
-    return -1;
-
-  return slot->index;
+  int index = gimple_uid (stmt);
+  gcc_checking_assert (index == -1 || RDG_STMT (rdg, index) == stmt);
+  return index;
 }
 
 /* Creates an edge in RDG for each distance vector from DDR.  The
@@ -5041,8 +5026,8 @@ create_rdg_edges (struct graph *rdg, VEC (ddr_p, heap) *ddrs)
 
 /* Build the vertices of the reduced dependence graph RDG.  */
 
-void
-create_rdg_vertices (struct graph *rdg, VEC (gimple, heap) *stmts)
+static void
+create_rdg_vertices (struct graph *rdg, VEC (gimple, heap) *stmts, loop_p loop)
 {
   int i, j;
   gimple stmt;
@@ -5052,33 +5037,31 @@ create_rdg_vertices (struct graph *rdg, VEC (gimple, heap) *stmts)
       VEC (data_ref_loc, heap) *references;
       data_ref_loc *ref;
       struct vertex *v = &(rdg->vertices[i]);
-      struct rdg_vertex_info *rvi = XNEW (struct rdg_vertex_info);
-      struct rdg_vertex_info **slot;
 
-      rvi->stmt = stmt;
-      rvi->index = i;
-      slot = (struct rdg_vertex_info **) htab_find_slot (rdg->indices, rvi, INSERT);
-
-      if (!*slot)
-       *slot = rvi;
-      else
-       free (rvi);
+      /* Record statement to vertex mapping.  */
+      gimple_set_uid (stmt, i);
 
       v->data = XNEW (struct rdg_vertex);
-      RDG_STMT (rdg, i) = stmt;
-
-      RDG_MEM_WRITE_STMT (rdg, i) = false;
-      RDG_MEM_READS_STMT (rdg, i) = false;
+      RDGV_STMT (v) = stmt;
+      RDGV_DATAREFS (v) = NULL;
+      RDGV_HAS_MEM_WRITE (v) = false;
+      RDGV_HAS_MEM_READS (v) = false;
       if (gimple_code (stmt) == GIMPLE_PHI)
        continue;
 
       get_references_in_stmt (stmt, &references);
       FOR_EACH_VEC_ELT (data_ref_loc, references, j, ref)
-       if (!ref->is_read)
-         RDG_MEM_WRITE_STMT (rdg, i) = true;
-       else
-         RDG_MEM_READS_STMT (rdg, i) = true;
-
+       {
+         data_reference_p dr;
+         if (!ref->is_read)
+           RDGV_HAS_MEM_WRITE (v) = true;
+         else
+           RDGV_HAS_MEM_READS (v) = true;
+         dr = create_data_ref (loop, loop_containing_stmt (stmt),
+                               *ref->pos, stmt, ref->is_read);
+         if (dr)
+           VEC_safe_push (data_reference_p, heap, RDGV_DATAREFS (v), dr);
+       }
       VEC_free (data_ref_loc, heap, references);
     }
 }
@@ -5130,37 +5113,6 @@ known_dependences_p (VEC (ddr_p, heap) *dependence_relations)
   return true;
 }
 
-/* Computes a hash function for element ELT.  */
-
-static hashval_t
-hash_stmt_vertex_info (const void *elt)
-{
-  const struct rdg_vertex_info *const rvi =
-    (const struct rdg_vertex_info *) elt;
-  gimple stmt = rvi->stmt;
-
-  return htab_hash_pointer (stmt);
-}
-
-/* Compares database elements E1 and E2.  */
-
-static int
-eq_stmt_vertex_info (const void *e1, const void *e2)
-{
-  const struct rdg_vertex_info *elt1 = (const struct rdg_vertex_info *) e1;
-  const struct rdg_vertex_info *elt2 = (const struct rdg_vertex_info *) e2;
-
-  return elt1->stmt == elt2->stmt;
-}
-
-/* Free the element E.  */
-
-static void
-hash_stmt_vertex_del (void *e)
-{
-  free (e);
-}
-
 /* Build the Reduced Dependence Graph (RDG) with one vertex per
    statement of the loop nest, and one edge per data dependence or
    scalar dependence.  */
@@ -5168,11 +5120,7 @@ hash_stmt_vertex_del (void *e)
 struct graph *
 build_empty_rdg (int n_stmts)
 {
-  int nb_data_refs = 10;
   struct graph *rdg = new_graph (n_stmts);
-
-  rdg->indices = htab_create (nb_data_refs, hash_stmt_vertex_info,
-                             eq_stmt_vertex_info, hash_stmt_vertex_del);
   return rdg;
 }
 
@@ -5195,7 +5143,7 @@ build_rdg (struct loop *loop,
       VEC (gimple, heap) *stmts = VEC_alloc (gimple, heap, 10);
       stmts_from_loop (loop, &stmts);
       rdg = build_empty_rdg (VEC_length (gimple, stmts));
-      create_rdg_vertices (rdg, stmts);
+      create_rdg_vertices (rdg, stmts, loop);
       create_rdg_edges (rdg, *dependence_relations);
       VEC_free (gimple, heap, stmts);
     }
@@ -5218,10 +5166,11 @@ free_rdg (struct graph *rdg)
       for (e = v->succ; e; e = e->succ_next)
        free (e->data);
 
+      gimple_set_uid (RDGV_STMT (v), -1);
+      free_data_refs (RDGV_DATAREFS (v));
       free (v->data);
     }
 
-  htab_delete (rdg->indices);
   free_graph (rdg);
 }
 
@@ -5307,40 +5256,6 @@ stores_zero_from_loop (struct loop *loop, VEC (gimple, heap) **stmts)
   free (bbs);
 }
 
-/* For a data reference REF, return the declaration of its base
-   address or NULL_TREE if the base is not determined.  */
-
-static inline tree
-ref_base_address (gimple stmt, data_ref_loc *ref)
-{
-  tree base = NULL_TREE;
-  tree base_address;
-  struct data_reference *dr = XCNEW (struct data_reference);
-
-  DR_STMT (dr) = stmt;
-  DR_REF (dr) = *ref->pos;
-  dr_analyze_innermost (dr, loop_containing_stmt (stmt));
-  base_address = DR_BASE_ADDRESS (dr);
-
-  if (!base_address)
-    goto end;
-
-  switch (TREE_CODE (base_address))
-    {
-    case ADDR_EXPR:
-      base = TREE_OPERAND (base_address, 0);
-      break;
-
-    default:
-      base = base_address;
-      break;
-    }
-
- end:
-  free_data_ref (dr);
-  return base;
-}
-
 /* Determines whether the statement from vertex V of the RDG has a
    definition used outside the loop that contains this statement.  */
 
@@ -5368,38 +5283,3 @@ rdg_defs_used_in_other_loops_p (struct graph *rdg, int v)
 
   return false;
 }
-
-/* Determines whether statements S1 and S2 access to similar memory
-   locations.  Two memory accesses are considered similar when they
-   have the same base address declaration, i.e. when their
-   ref_base_address is the same.  */
-
-bool
-have_similar_memory_accesses (gimple s1, gimple s2)
-{
-  bool res = false;
-  unsigned i, j;
-  VEC (data_ref_loc, heap) *refs1, *refs2;
-  data_ref_loc *ref1, *ref2;
-
-  get_references_in_stmt (s1, &refs1);
-  get_references_in_stmt (s2, &refs2);
-
-  FOR_EACH_VEC_ELT (data_ref_loc, refs1, i, ref1)
-    {
-      tree base1 = ref_base_address (s1, ref1);
-
-      if (base1)
-       FOR_EACH_VEC_ELT (data_ref_loc, refs2, j, ref2)
-         if (base1 == ref_base_address (s2, ref2))
-           {
-             res = true;
-             goto end;
-           }
-    }
-
- end:
-  VEC_free (data_ref_loc, heap, refs1);
-  VEC_free (data_ref_loc, heap, refs2);
-  return res;
-}
index da4802ef4f2ec5b7e32dc54467017a5cdc3685b0..2edddc03d441bae102c4a82da6d11ad43d64a22e 100644 (file)
@@ -403,7 +403,6 @@ extern bool compute_all_dependences (VEC (data_reference_p, heap) *,
 extern tree find_data_references_in_bb (struct loop *, basic_block,
                                         VEC (data_reference_p, heap) **);
 
-extern void create_rdg_vertices (struct graph *, VEC (gimple, heap) *);
 extern bool dr_may_alias_p (const struct data_reference *,
                            const struct data_reference *, bool);
 extern bool dr_equal_offsets_p (struct data_reference *,
@@ -525,6 +524,9 @@ typedef struct rdg_vertex
   /* The statement represented by this vertex.  */
   gimple stmt;
 
+  /* Vector of data-references in this statement.  */
+  VEC(data_reference_p, heap) *datarefs;
+
   /* True when the statement contains a write to memory.  */
   bool has_mem_write;
 
@@ -533,9 +535,11 @@ typedef struct rdg_vertex
 } *rdg_vertex_p;
 
 #define RDGV_STMT(V)     ((struct rdg_vertex *) ((V)->data))->stmt
+#define RDGV_DATAREFS(V) ((struct rdg_vertex *) ((V)->data))->datarefs
 #define RDGV_HAS_MEM_WRITE(V) ((struct rdg_vertex *) ((V)->data))->has_mem_write
 #define RDGV_HAS_MEM_READS(V) ((struct rdg_vertex *) ((V)->data))->has_mem_reads
 #define RDG_STMT(RDG, I) RDGV_STMT (&(RDG->vertices[I]))
+#define RDG_DATAREFS(RDG, I) RDGV_DATAREFS (&(RDG->vertices[I]))
 #define RDG_MEM_WRITE_STMT(RDG, I) RDGV_HAS_MEM_WRITE (&(RDG->vertices[I]))
 #define RDG_MEM_READS_STMT(RDG, I) RDGV_HAS_MEM_READS (&(RDG->vertices[I]))
 
@@ -608,7 +612,6 @@ index_in_loop_nest (int var, VEC (loop_p, heap) *loop_nest)
 void stores_from_loop (struct loop *, VEC (gimple, heap) **);
 void stores_zero_from_loop (struct loop *, VEC (gimple, heap) **);
 bool rdg_defs_used_in_other_loops_p (struct graph *, int);
-bool have_similar_memory_accesses (gimple, gimple);
 bool stmt_with_adjacent_zero_store_dr_p (gimple);
 
 /* Returns true when STRIDE is equal in absolute value to the size of
@@ -623,16 +626,6 @@ stride_of_unit_type_p (tree stride, tree type)
                                 TYPE_SIZE_UNIT (type)));
 }
 
-/* Determines whether RDG vertices V1 and V2 access to similar memory
-   locations, in which case they have to be in the same partition.  */
-
-static inline bool
-rdg_has_similar_memory_accesses (struct graph *rdg, int v1, int v2)
-{
-  return have_similar_memory_accesses (RDG_STMT (rdg, v1),
-                                      RDG_STMT (rdg, v2));
-}
-
 /* In tree-data-ref.c  */
 void split_constant_offset (tree , tree *, tree *);
 
index 1fc1d8d249b6b39056489cf142523b1554833161..f4476cbcf316e12c64be8115836baa8c58503052 100644 (file)
@@ -878,6 +878,20 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition)
     partition->kind = PKIND_MEMSET;
 }
 
+/* For a data reference REF, return the declaration of its base
+   address or NULL_TREE if the base is not determined.  */
+
+static tree
+ref_base_address (data_reference_p dr)
+{
+  tree base_address = DR_BASE_ADDRESS (dr);
+  if (base_address
+      && TREE_CODE (base_address) == ADDR_EXPR)
+    return TREE_OPERAND (base_address, 0);
+
+  return base_address;
+}
+
 /* Returns true when PARTITION1 and PARTITION2 have similar memory
    accesses in RDG.  */
 
@@ -885,17 +899,36 @@ static bool
 similar_memory_accesses (struct graph *rdg, partition_t partition1,
                         partition_t partition2)
 {
-  unsigned i, j;
+  unsigned i, j, k, l;
   bitmap_iterator bi, bj;
+  data_reference_p ref1, ref2;
+
+  /* First check whether in the intersection of the two partitions are
+     any loads or stores.  Common loads are the situation that happens
+     most often.  */
+  EXECUTE_IF_AND_IN_BITMAP (partition1->stmts, partition2->stmts, 0, i, bi)
+    if (RDG_MEM_WRITE_STMT (rdg, i)
+       || RDG_MEM_READS_STMT (rdg, i))
+      return true;
 
+  /* Then check all data-references against each other.  */
   EXECUTE_IF_SET_IN_BITMAP (partition1->stmts, 0, i, bi)
     if (RDG_MEM_WRITE_STMT (rdg, i)
        || RDG_MEM_READS_STMT (rdg, i))
       EXECUTE_IF_SET_IN_BITMAP (partition2->stmts, 0, j, bj)
        if (RDG_MEM_WRITE_STMT (rdg, j)
            || RDG_MEM_READS_STMT (rdg, j))
-         if (rdg_has_similar_memory_accesses (rdg, i, j))
-           return true;
+         {
+           FOR_EACH_VEC_ELT (data_reference_p, RDG_DATAREFS (rdg, i), k, ref1)
+             {
+               tree base1 = ref_base_address (ref1);
+               if (base1)
+                 FOR_EACH_VEC_ELT (data_reference_p,
+                                   RDG_DATAREFS (rdg, j), l, ref2)
+                   if (base1 == ref_base_address (ref2))
+                     return true;
+             }
+         }
 
   return false;
 }
@@ -1252,6 +1285,16 @@ tree_loop_distribution (void)
   struct loop *loop;
   loop_iterator li;
   bool changed = false;
+  basic_block bb;
+
+  FOR_ALL_BB (bb)
+    {
+      gimple_stmt_iterator gsi;
+      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+       gimple_set_uid (gsi_stmt (gsi), -1);
+      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+       gimple_set_uid (gsi_stmt (gsi), -1);
+    }
 
   /* We can at the moment only distribute non-nested loops, thus restrict
      walking to innermost loops.  */
index ea48b4ba514f3c3a58ceabf4ca27d7a384d6ff98..93a785a5f913c3246f10a6ab1f1724e42e5d881f 100644 (file)
@@ -4211,7 +4211,7 @@ vect_finalize_reduction:
               orig_name = PHI_RESULT (exit_phi);
               FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, orig_name)
                 {
-                  stmt_vec_info use_stmt_vinfo = vinfo_for_stmt (use_stmt);
+                  stmt_vec_info use_stmt_vinfo;
                   stmt_vec_info new_phi_vinfo;
                   tree vect_phi_init, preheader_arg, vect_phi_res, init_def;
                   basic_block bb = gimple_bb (use_stmt);
@@ -4221,11 +4221,13 @@ vect_finalize_reduction:
                      node.  */
                   if (gimple_code (use_stmt) != GIMPLE_PHI
                       || gimple_phi_num_args (use_stmt) != 2
-                      || !use_stmt_vinfo
-                      || STMT_VINFO_DEF_TYPE (use_stmt_vinfo)
-                          != vect_double_reduction_def
                       || bb->loop_father != outer_loop)
                     continue;
+                  use_stmt_vinfo = vinfo_for_stmt (use_stmt);
+                  if (!use_stmt_vinfo
+                      || STMT_VINFO_DEF_TYPE (use_stmt_vinfo)
+                          != vect_double_reduction_def)
+                   continue;
 
                   /* Create vector phi node for double reduction:
                      vs1 = phi <vs0, vs2>