tree-data-ref.h (known_dependences_p): Move here ...
2013-09-13 Richard Biener <rguenther@suse.de> * tree-data-ref.h (known_dependences_p): Move here ... * tree-loop-distribution.c (known_dependences_p): ... from here. (dump_rdg_component, debug_rdg_component): Remove. (dump_rdg): Adjust. (generate_loops_for_partition): Use gimple_uid instead of relying on matching stmt visit order. (rdg_build_partitions): Take starting stmt vector. (ldist_gen): Merge into ... (distribute_loop): ... this function. Do not compute starting vertices vector. * tree-cfg.c (gimple_duplicate_bb): Copy UID for PHIs. From-SVN: r202561
This commit is contained in:
parent
86eb4bd726
commit
2fd5894f38
@ -1,3 +1,17 @@
|
|||||||
|
2013-09-13 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* tree-data-ref.h (known_dependences_p): Move here ...
|
||||||
|
* tree-loop-distribution.c (known_dependences_p): ... from here.
|
||||||
|
(dump_rdg_component, debug_rdg_component): Remove.
|
||||||
|
(dump_rdg): Adjust.
|
||||||
|
(generate_loops_for_partition): Use gimple_uid instead of
|
||||||
|
relying on matching stmt visit order.
|
||||||
|
(rdg_build_partitions): Take starting stmt vector.
|
||||||
|
(ldist_gen): Merge into ...
|
||||||
|
(distribute_loop): ... this function. Do not compute starting
|
||||||
|
vertices vector.
|
||||||
|
* tree-cfg.c (gimple_duplicate_bb): Copy UID for PHIs.
|
||||||
|
|
||||||
2013-09-13 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
2013-09-13 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||||
|
|
||||||
* config/arm/arm.md (arm_cmpsi_insn): Split rI alternative.
|
* config/arm/arm.md (arm_cmpsi_insn): Split rI alternative.
|
||||||
|
@ -5563,6 +5563,7 @@ gimple_duplicate_bb (basic_block bb)
|
|||||||
copy = create_phi_node (NULL_TREE, new_bb);
|
copy = create_phi_node (NULL_TREE, new_bb);
|
||||||
create_new_def_for (gimple_phi_result (phi), copy,
|
create_new_def_for (gimple_phi_result (phi), copy,
|
||||||
gimple_phi_result_ptr (copy));
|
gimple_phi_result_ptr (copy));
|
||||||
|
gimple_set_uid (copy, gimple_uid (phi));
|
||||||
}
|
}
|
||||||
|
|
||||||
gsi_tgt = gsi_start_bb (new_bb);
|
gsi_tgt = gsi_start_bb (new_bb);
|
||||||
|
@ -482,6 +482,21 @@ ddrs_have_anti_deps (vec<ddr_p> dependence_relations)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true when all the dependences are computable. */
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
known_dependences_p (vec<ddr_p> dependence_relations)
|
||||||
|
{
|
||||||
|
ddr_p ddr;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
FOR_EACH_VEC_ELT (dependence_relations, i, ddr)
|
||||||
|
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns the dependence level for a vector DIST of size LENGTH.
|
/* Returns the dependence level for a vector DIST of size LENGTH.
|
||||||
LEVEL = 0 means a lexicographic dependence, i.e. a dependence due
|
LEVEL = 0 means a lexicographic dependence, i.e. a dependence due
|
||||||
to the sequence of statements, not carried by any loop. */
|
to the sequence of statements, not carried by any loop. */
|
||||||
|
@ -150,52 +150,15 @@ debug_rdg_vertex (struct graph *rdg, int i)
|
|||||||
dump_rdg_vertex (stderr, rdg, i);
|
dump_rdg_vertex (stderr, rdg, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dump component C of RDG to FILE. If DUMPED is non-null, set the
|
|
||||||
dumped vertices to that bitmap. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
dump_rdg_component (FILE *file, struct graph *rdg, int c, bitmap dumped)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
fprintf (file, "(%d\n", c);
|
|
||||||
|
|
||||||
for (i = 0; i < rdg->n_vertices; i++)
|
|
||||||
if (rdg->vertices[i].component == c)
|
|
||||||
{
|
|
||||||
if (dumped)
|
|
||||||
bitmap_set_bit (dumped, i);
|
|
||||||
|
|
||||||
dump_rdg_vertex (file, rdg, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf (file, ")\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call dump_rdg_vertex on stderr. */
|
|
||||||
|
|
||||||
DEBUG_FUNCTION void
|
|
||||||
debug_rdg_component (struct graph *rdg, int c)
|
|
||||||
{
|
|
||||||
dump_rdg_component (stderr, rdg, c, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dump the reduced dependence graph RDG to FILE. */
|
/* Dump the reduced dependence graph RDG to FILE. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_rdg (FILE *file, struct graph *rdg)
|
dump_rdg (FILE *file, struct graph *rdg)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
bitmap dumped = BITMAP_ALLOC (NULL);
|
|
||||||
|
|
||||||
fprintf (file, "(rdg\n");
|
fprintf (file, "(rdg\n");
|
||||||
|
for (int i = 0; i < rdg->n_vertices; i++)
|
||||||
for (i = 0; i < rdg->n_vertices; i++)
|
dump_rdg_vertex (file, rdg, i);
|
||||||
if (!bitmap_bit_p (dumped, i))
|
|
||||||
dump_rdg_component (file, rdg, rdg->vertices[i].component, dumped);
|
|
||||||
|
|
||||||
fprintf (file, ")\n");
|
fprintf (file, ")\n");
|
||||||
BITMAP_FREE (dumped);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call dump_rdg on stderr. */
|
/* Call dump_rdg on stderr. */
|
||||||
@ -425,11 +388,10 @@ create_rdg_vertices (struct graph *rdg, vec<gimple> stmts, loop_p loop,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize STMTS with all the statements of LOOP. When
|
/* Initialize STMTS with all the statements of LOOP. The order in
|
||||||
INCLUDE_PHIS is true, include also the PHI nodes. The order in
|
|
||||||
which we discover statements is important as
|
which we discover statements is important as
|
||||||
generate_loops_for_partition is using the same traversal for
|
generate_loops_for_partition is using the same traversal for
|
||||||
identifying statements. */
|
identifying statements in loop copies. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stmts_from_loop (struct loop *loop, vec<gimple> *stmts)
|
stmts_from_loop (struct loop *loop, vec<gimple> *stmts)
|
||||||
@ -458,21 +420,6 @@ stmts_from_loop (struct loop *loop, vec<gimple> *stmts)
|
|||||||
free (bbs);
|
free (bbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true when all the dependences are computable. */
|
|
||||||
|
|
||||||
static bool
|
|
||||||
known_dependences_p (vec<ddr_p> dependence_relations)
|
|
||||||
{
|
|
||||||
ddr_p ddr;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
FOR_EACH_VEC_ELT (dependence_relations, i, ddr)
|
|
||||||
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build the Reduced Dependence Graph (RDG) with one vertex per
|
/* Build the Reduced Dependence Graph (RDG) with one vertex per
|
||||||
statement of the loop nest, and one edge per data dependence or
|
statement of the loop nest, and one edge per data dependence or
|
||||||
scalar dependence. */
|
scalar dependence. */
|
||||||
@ -693,7 +640,7 @@ static void
|
|||||||
generate_loops_for_partition (struct loop *loop, partition_t partition,
|
generate_loops_for_partition (struct loop *loop, partition_t partition,
|
||||||
bool copy_p)
|
bool copy_p)
|
||||||
{
|
{
|
||||||
unsigned i, x;
|
unsigned i;
|
||||||
gimple_stmt_iterator bsi;
|
gimple_stmt_iterator bsi;
|
||||||
basic_block *bbs;
|
basic_block *bbs;
|
||||||
|
|
||||||
@ -705,53 +652,52 @@ generate_loops_for_partition (struct loop *loop, partition_t partition,
|
|||||||
create_bb_after_loop (loop);
|
create_bb_after_loop (loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove stmts not in the PARTITION bitmap. The order in which we
|
/* Remove stmts not in the PARTITION bitmap. */
|
||||||
visit the phi nodes and the statements is exactly as in
|
|
||||||
stmts_from_loop. */
|
|
||||||
bbs = get_loop_body_in_dom_order (loop);
|
bbs = get_loop_body_in_dom_order (loop);
|
||||||
|
|
||||||
if (MAY_HAVE_DEBUG_STMTS)
|
if (MAY_HAVE_DEBUG_STMTS)
|
||||||
for (x = 0, i = 0; i < loop->num_nodes; i++)
|
for (i = 0; i < loop->num_nodes; i++)
|
||||||
{
|
{
|
||||||
basic_block bb = bbs[i];
|
basic_block bb = bbs[i];
|
||||||
|
|
||||||
for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
|
for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
|
||||||
if (!virtual_operand_p (gimple_phi_result (gsi_stmt (bsi)))
|
{
|
||||||
&& !bitmap_bit_p (partition->stmts, x++))
|
gimple phi = gsi_stmt (bsi);
|
||||||
reset_debug_uses (gsi_stmt (bsi));
|
if (!virtual_operand_p (gimple_phi_result (phi))
|
||||||
|
&& !bitmap_bit_p (partition->stmts, gimple_uid (phi)))
|
||||||
|
reset_debug_uses (phi);
|
||||||
|
}
|
||||||
|
|
||||||
for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
|
for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
|
||||||
{
|
{
|
||||||
gimple stmt = gsi_stmt (bsi);
|
gimple stmt = gsi_stmt (bsi);
|
||||||
if (gimple_code (stmt) != GIMPLE_LABEL
|
if (gimple_code (stmt) != GIMPLE_LABEL
|
||||||
&& !is_gimple_debug (stmt)
|
&& !is_gimple_debug (stmt)
|
||||||
&& !bitmap_bit_p (partition->stmts, x++))
|
&& !bitmap_bit_p (partition->stmts, gimple_uid (stmt)))
|
||||||
reset_debug_uses (stmt);
|
reset_debug_uses (stmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x = 0, i = 0; i < loop->num_nodes; i++)
|
for (i = 0; i < loop->num_nodes; i++)
|
||||||
{
|
{
|
||||||
basic_block bb = bbs[i];
|
basic_block bb = bbs[i];
|
||||||
|
|
||||||
for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi);)
|
for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi);)
|
||||||
if (!virtual_operand_p (gimple_phi_result (gsi_stmt (bsi)))
|
{
|
||||||
&& !bitmap_bit_p (partition->stmts, x++))
|
gimple phi = gsi_stmt (bsi);
|
||||||
{
|
if (!virtual_operand_p (gimple_phi_result (phi))
|
||||||
gimple phi = gsi_stmt (bsi);
|
&& !bitmap_bit_p (partition->stmts, gimple_uid (phi)))
|
||||||
if (virtual_operand_p (gimple_phi_result (phi)))
|
|
||||||
mark_virtual_phi_result_for_renaming (phi);
|
|
||||||
remove_phi_node (&bsi, true);
|
remove_phi_node (&bsi, true);
|
||||||
}
|
else
|
||||||
else
|
gsi_next (&bsi);
|
||||||
gsi_next (&bsi);
|
}
|
||||||
|
|
||||||
for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi);)
|
for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi);)
|
||||||
{
|
{
|
||||||
gimple stmt = gsi_stmt (bsi);
|
gimple stmt = gsi_stmt (bsi);
|
||||||
if (gimple_code (stmt) != GIMPLE_LABEL
|
if (gimple_code (stmt) != GIMPLE_LABEL
|
||||||
&& !is_gimple_debug (stmt)
|
&& !is_gimple_debug (stmt)
|
||||||
&& !bitmap_bit_p (partition->stmts, x++))
|
&& !bitmap_bit_p (partition->stmts, gimple_uid (stmt)))
|
||||||
{
|
{
|
||||||
unlink_stmt_vdef (stmt);
|
unlink_stmt_vdef (stmt);
|
||||||
gsi_remove (&bsi, true);
|
gsi_remove (&bsi, true);
|
||||||
@ -1372,16 +1318,22 @@ similar_memory_accesses (struct graph *rdg, partition_t partition1,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
rdg_build_partitions (struct graph *rdg,
|
rdg_build_partitions (struct graph *rdg,
|
||||||
vec<int> starting_vertices,
|
vec<gimple> starting_stmts,
|
||||||
vec<partition_t> *partitions)
|
vec<partition_t> *partitions)
|
||||||
{
|
{
|
||||||
bitmap processed = BITMAP_ALLOC (NULL);
|
bitmap processed = BITMAP_ALLOC (NULL);
|
||||||
int i, v;
|
int i;
|
||||||
|
gimple stmt;
|
||||||
partition_t partition = partition_alloc (NULL, NULL);
|
partition_t partition = partition_alloc (NULL, NULL);
|
||||||
|
|
||||||
FOR_EACH_VEC_ELT (starting_vertices, i, v)
|
FOR_EACH_VEC_ELT (starting_stmts, i, stmt)
|
||||||
{
|
{
|
||||||
partition_t np;
|
partition_t np;
|
||||||
|
int v = rdg_vertex_for_stmt (rdg, stmt);
|
||||||
|
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
fprintf (dump_file,
|
||||||
|
"ldist asked to generate code for vertex %d\n", v);
|
||||||
|
|
||||||
if (bitmap_bit_p (processed, v))
|
if (bitmap_bit_p (processed, v))
|
||||||
continue;
|
continue;
|
||||||
@ -1504,20 +1456,46 @@ partition_contains_all_rw (struct graph *rdg,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate code from STARTING_VERTICES in RDG. Returns the number of
|
|
||||||
distributed loops. */
|
/* Distributes the code from LOOP in such a way that producer
|
||||||
|
statements are placed before consumer statements. Tries to separate
|
||||||
|
only the statements from STMTS into separate loops.
|
||||||
|
Returns the number of distributed loops. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ldist_gen (struct loop *loop, struct graph *rdg,
|
distribute_loop (struct loop *loop, vec<gimple> stmts)
|
||||||
vec<int> starting_vertices)
|
|
||||||
{
|
{
|
||||||
int i, nbp;
|
struct graph *rdg;
|
||||||
|
vec<loop_p> loop_nest;
|
||||||
vec<partition_t> partitions;
|
vec<partition_t> partitions;
|
||||||
partitions.create (3);
|
|
||||||
partition_t partition;
|
partition_t partition;
|
||||||
bool any_builtin;
|
bool any_builtin;
|
||||||
|
int i, nbp;
|
||||||
|
|
||||||
rdg_build_partitions (rdg, starting_vertices, &partitions);
|
loop_nest.create (3);
|
||||||
|
if (!find_loop_nest (loop, &loop_nest))
|
||||||
|
{
|
||||||
|
loop_nest.release ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rdg = build_rdg (loop_nest);
|
||||||
|
if (!rdg)
|
||||||
|
{
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
fprintf (dump_file,
|
||||||
|
"Loop %d not distributed: failed to build the RDG.\n",
|
||||||
|
loop->num);
|
||||||
|
|
||||||
|
loop_nest.release ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
dump_rdg (dump_file, rdg);
|
||||||
|
|
||||||
|
partitions.create (3);
|
||||||
|
rdg_build_partitions (rdg, stmts, &partitions);
|
||||||
|
|
||||||
any_builtin = false;
|
any_builtin = false;
|
||||||
FOR_EACH_VEC_ELT (partitions, i, partition)
|
FOR_EACH_VEC_ELT (partitions, i, partition)
|
||||||
@ -1637,70 +1615,11 @@ ldist_gen (struct loop *loop, struct graph *rdg,
|
|||||||
|
|
||||||
FOR_EACH_VEC_ELT (partitions, i, partition)
|
FOR_EACH_VEC_ELT (partitions, i, partition)
|
||||||
partition_free (partition);
|
partition_free (partition);
|
||||||
|
|
||||||
partitions.release ();
|
partitions.release ();
|
||||||
return nbp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Distributes the code from LOOP in such a way that producer
|
|
||||||
statements are placed before consumer statements. When STMTS is
|
|
||||||
NULL, performs the maximal distribution, if STMTS is not NULL,
|
|
||||||
tries to separate only these statements from the LOOP's body.
|
|
||||||
Returns the number of distributed loops. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
distribute_loop (struct loop *loop, vec<gimple> stmts)
|
|
||||||
{
|
|
||||||
int res = 0;
|
|
||||||
struct graph *rdg;
|
|
||||||
gimple s;
|
|
||||||
unsigned i;
|
|
||||||
vec<int> vertices;
|
|
||||||
vec<loop_p> loop_nest;
|
|
||||||
|
|
||||||
loop_nest.create (3);
|
|
||||||
if (!find_loop_nest (loop, &loop_nest))
|
|
||||||
{
|
|
||||||
loop_nest.release ();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rdg = build_rdg (loop_nest);
|
|
||||||
if (!rdg)
|
|
||||||
{
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
||||||
fprintf (dump_file,
|
|
||||||
"Loop %d not distributed: failed to build the RDG.\n",
|
|
||||||
loop->num);
|
|
||||||
|
|
||||||
loop_nest.release ();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
vertices.create (3);
|
|
||||||
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
||||||
dump_rdg (dump_file, rdg);
|
|
||||||
|
|
||||||
FOR_EACH_VEC_ELT (stmts, i, s)
|
|
||||||
{
|
|
||||||
int v = rdg_vertex_for_stmt (rdg, s);
|
|
||||||
|
|
||||||
if (v >= 0)
|
|
||||||
{
|
|
||||||
vertices.safe_push (v);
|
|
||||||
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
||||||
fprintf (dump_file,
|
|
||||||
"ldist asked to generate code for vertex %d\n", v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res = ldist_gen (loop, rdg, vertices);
|
|
||||||
vertices.release ();
|
|
||||||
free_rdg (rdg);
|
free_rdg (rdg);
|
||||||
loop_nest.release ();
|
loop_nest.release ();
|
||||||
return res;
|
return nbp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Distribute all loops in the current function. */
|
/* Distribute all loops in the current function. */
|
||||||
|
Loading…
Reference in New Issue
Block a user