Hi,
This patch collects and preserves all data references in loop for whole
distribution life time. It will be used afterwards.
Bootstrap and test on x86_64 and AArch64. Is it OK?
Thanks,
bin
2017-06-07 Bin Cheng <bin.ch...@arm.com>
* tree-loop-distribution.c (datarefs_vec, datarefs_map): New
global var.
(create_rdg_vertices): Use datarefs_vec directly.
(free_rdg): Don't free data references.
(build_rdg): Update use. Don't free data references.
(distribute_loop): Compute global variable for data references.
Bail out if there are too many data references.
From 78dd9322e9c3e5af2c736997fdbd2f71285eb5c0 Mon Sep 17 00:00:00 2001
From: Bin Cheng <binch...@e108451-lin.cambridge.arm.com>
Date: Fri, 9 Jun 2017 12:09:03 +0100
Subject: [PATCH 07/14] preserve-datarefs-20170607.txt
---
gcc/tree-loop-distribution.c | 58 +++++++++++++++++++++++++++++++++-----------
1 file changed, 44 insertions(+), 14 deletions(-)
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index e1f5bce..0b16024 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -69,6 +69,12 @@ along with GCC; see the file COPYING3. If not see
/* The loop (nest) to be distributed. */
static vec<loop_p> *loop_nest;
+/* Vector of data references in the loop to be distributed. */
+static vec<data_reference_p> *datarefs_vec;
+
+/* Map of data reference in the loop to a unique id. */
+static hash_map<data_reference_p, int> *datarefs_map;
+
/* A Reduced Dependence Graph (RDG) vertex representing a statement. */
struct rdg_vertex
{
@@ -339,8 +345,7 @@ create_rdg_cd_edges (struct graph *rdg, control_dependences
*cd, loop_p loop)
if that failed. */
static bool
-create_rdg_vertices (struct graph *rdg, vec<gimple *> stmts, loop_p loop,
- vec<data_reference_p> *datarefs)
+create_rdg_vertices (struct graph *rdg, vec<gimple *> stmts, loop_p loop)
{
int i;
gimple *stmt;
@@ -360,12 +365,12 @@ create_rdg_vertices (struct graph *rdg, vec<gimple *>
stmts, loop_p loop,
if (gimple_code (stmt) == GIMPLE_PHI)
continue;
- unsigned drp = datarefs->length ();
- if (!find_data_references_in_stmt (loop, stmt, datarefs))
+ unsigned drp = datarefs_vec->length ();
+ if (!find_data_references_in_stmt (loop, stmt, datarefs_vec))
return false;
- for (unsigned j = drp; j < datarefs->length (); ++j)
+ for (unsigned j = drp; j < datarefs_vec->length (); ++j)
{
- data_reference_p dr = (*datarefs)[j];
+ data_reference_p dr = (*datarefs_vec)[j];
if (DR_IS_READ (dr))
RDGV_HAS_MEM_READS (v) = true;
else
@@ -449,7 +454,7 @@ free_rdg (struct graph *rdg)
if (v->data)
{
gimple_set_uid (RDGV_STMT (v), -1);
- free_data_refs (RDGV_DATAREFS (v));
+ (RDGV_DATAREFS (v)).release ();
free (v->data);
}
}
@@ -459,22 +464,20 @@ free_rdg (struct graph *rdg)
/* Build the Reduced Dependence Graph (RDG) with one vertex per statement of
LOOP, and one edge per flow dependence or control dependence from control
- dependence CD. */
+ dependence CD. During visiting each statement, data references are also
+ collected and recorded in global data DATAREFS_VEC. */
static struct graph *
build_rdg (struct loop *loop, control_dependences *cd)
{
struct graph *rdg;
- vec<data_reference_p> datarefs;
/* Create the RDG vertices from the stmts of the loop nest. */
auto_vec<gimple *, 10> stmts;
stmts_from_loop (loop, &stmts);
rdg = new_graph (stmts.length ());
- datarefs.create (10);
- if (!create_rdg_vertices (rdg, stmts, loop, &datarefs))
+ if (!create_rdg_vertices (rdg, stmts, loop))
{
- datarefs.release ();
free_rdg (rdg);
return NULL;
}
@@ -484,8 +487,6 @@ build_rdg (struct loop *loop, control_dependences *cd)
if (cd)
create_rdg_cd_edges (rdg, cd, loop);
- datarefs.release ();
-
return rdg;
}
@@ -1522,6 +1523,7 @@ distribute_loop (struct loop *loop, vec<gimple *> stmts,
return 0;
}
+ datarefs_vec = new vec<data_reference_p> ();
rdg = build_rdg (loop, cd);
if (!rdg)
{
@@ -1532,8 +1534,33 @@ distribute_loop (struct loop *loop, vec<gimple *> stmts,
loop_nest->release ();
delete loop_nest;
+ free_data_refs (*datarefs_vec);
+ delete datarefs_vec;
return 0;
}
+ if (datarefs_vec->length () > 64)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "Loop %d not distributed: more than 64 memory references.\n",
+ loop->num);
+
+ free_rdg (rdg);
+ loop_nest->release ();
+ delete loop_nest;
+ free_data_refs (*datarefs_vec);
+ delete datarefs_vec;
+ return 0;
+ }
+
+ data_reference_p dref;
+ datarefs_map = new hash_map<data_reference_p, int>;
+ for (i = 0; datarefs_vec->iterate (i, &dref); ++i)
+ {
+ int *slot = datarefs_map->get ((*datarefs_vec)[i]);
+ gcc_assert (slot == NULL);
+ datarefs_map->put ((*datarefs_vec)[i], i);
+ }
if (dump_file && (dump_flags & TDF_DETAILS))
dump_rdg (dump_file, rdg);
@@ -1741,6 +1768,9 @@ distribute_loop (struct loop *loop, vec<gimple *> stmts,
ldist_done:
loop_nest->release ();
delete loop_nest;
+ free_data_refs (*datarefs_vec);
+ delete datarefs_vec;
+ delete datarefs_map;
FOR_EACH_VEC_ELT (partitions, i, partition)
partition_free (partition);
--
1.9.1