tree-data-ref.c (find_vertex_for_stmt, [...]): New.
* tree-data-ref.c (find_vertex_for_stmt, create_rdg_edge_for_ddr, create_rdg_edges_for_scalar, create_rdg_edges, create_rdg_vertices, stmts_from_loop, known_dependences_p, build_rdg): New. * tree-data-ref.h: Depends on graphds.h. (rdg_vertex, RDGV_STMT, rdg_dep_type, rdg_edge, RDGE_TYPE): New. (build_rdg): Declared. * Makefile.in (TREE_DATA_REF_H): Depends on graphds.h. From-SVN: r126859
This commit is contained in:
parent
5ab0eadfa3
commit
3a796c6fc0
@ -1,3 +1,13 @@
|
||||
2007-07-23 Sebastian Pop <sebpop@gmail.com>
|
||||
|
||||
* tree-data-ref.c (find_vertex_for_stmt, create_rdg_edge_for_ddr,
|
||||
create_rdg_edges_for_scalar, create_rdg_edges, create_rdg_vertices,
|
||||
stmts_from_loop, known_dependences_p, build_rdg): New.
|
||||
* tree-data-ref.h: Depends on graphds.h.
|
||||
(rdg_vertex, RDGV_STMT, rdg_dep_type, rdg_edge, RDGE_TYPE): New.
|
||||
(build_rdg): Declared.
|
||||
* Makefile.in (TREE_DATA_REF_H): Depends on graphds.h.
|
||||
|
||||
2007-07-23 Daniel Berlin <dberlin@dberlin.org>
|
||||
|
||||
* tree-ssa-propagate.c (valid_gimple_expression_p): Match up with
|
||||
|
@ -812,7 +812,7 @@ DIAGNOSTIC_H = diagnostic.h diagnostic.def $(PRETTY_PRINT_H) options.h
|
||||
C_PRETTY_PRINT_H = c-pretty-print.h $(PRETTY_PRINT_H) $(C_COMMON_H) $(TREE_H)
|
||||
SCEV_H = tree-scalar-evolution.h $(GGC_H) tree-chrec.h $(PARAMS_H)
|
||||
LAMBDA_H = lambda.h $(TREE_H) vec.h $(GGC_H)
|
||||
TREE_DATA_REF_H = tree-data-ref.h $(LAMBDA_H) omega.h
|
||||
TREE_DATA_REF_H = tree-data-ref.h $(LAMBDA_H) omega.h graphds.h
|
||||
VARRAY_H = varray.h $(MACHMODE_H) $(SYSTEM_H) coretypes.h $(TM_H)
|
||||
TREE_INLINE_H = tree-inline.h $(VARRAY_H) pointer-set.h
|
||||
REAL_H = real.h $(MACHMODE_H)
|
||||
|
@ -4312,3 +4312,187 @@ free_data_refs (VEC (data_reference_p, heap) *datarefs)
|
||||
VEC_free (data_reference_p, heap, datarefs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Returns the index of STMT in RDG. */
|
||||
|
||||
static int
|
||||
find_vertex_for_stmt (struct graph *rdg, tree stmt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rdg->n_vertices; i++)
|
||||
if (RDGV_STMT (&(rdg->vertices[i])) == stmt)
|
||||
return i;
|
||||
|
||||
gcc_unreachable ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Creates an edge in RDG for each distance vector from DDR. */
|
||||
|
||||
static void
|
||||
create_rdg_edge_for_ddr (struct graph *rdg, ddr_p ddr)
|
||||
{
|
||||
int va, vb;
|
||||
data_reference_p dra;
|
||||
data_reference_p drb;
|
||||
struct graph_edge *e;
|
||||
|
||||
if (DDR_REVERSED_P (ddr))
|
||||
{
|
||||
dra = DDR_B (ddr);
|
||||
drb = DDR_A (ddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
dra = DDR_A (ddr);
|
||||
drb = DDR_B (ddr);
|
||||
}
|
||||
|
||||
va = find_vertex_for_stmt (rdg, DR_STMT (dra));
|
||||
vb = find_vertex_for_stmt (rdg, DR_STMT (drb));
|
||||
|
||||
e = add_edge (rdg, va, vb);
|
||||
e->data = XNEW (struct rdg_edge);
|
||||
|
||||
/* Determines the type of the data dependence. */
|
||||
if (DR_IS_READ (dra) && DR_IS_READ (drb))
|
||||
RDGE_TYPE (e) = input_dd;
|
||||
else if (!DR_IS_READ (dra) && !DR_IS_READ (drb))
|
||||
RDGE_TYPE (e) = output_dd;
|
||||
else if (!DR_IS_READ (dra) && DR_IS_READ (drb))
|
||||
RDGE_TYPE (e) = flow_dd;
|
||||
else if (DR_IS_READ (dra) && !DR_IS_READ (drb))
|
||||
RDGE_TYPE (e) = anti_dd;
|
||||
}
|
||||
|
||||
/* Creates dependence edges in RDG for all the uses of DEF. IDEF is
|
||||
the index of DEF in RDG. */
|
||||
|
||||
static void
|
||||
create_rdg_edges_for_scalar (struct graph *rdg, tree def, int idef)
|
||||
{
|
||||
use_operand_p imm_use_p;
|
||||
imm_use_iterator iterator;
|
||||
|
||||
FOR_EACH_IMM_USE_FAST (imm_use_p, iterator, def)
|
||||
{
|
||||
int use = find_vertex_for_stmt (rdg, USE_STMT (imm_use_p));
|
||||
struct graph_edge *e = add_edge (rdg, idef, use);
|
||||
|
||||
e->data = XNEW (struct rdg_edge);
|
||||
RDGE_TYPE (e) = flow_dd;
|
||||
}
|
||||
}
|
||||
|
||||
/* Creates the edges of the reduced dependence graph RDG. */
|
||||
|
||||
static void
|
||||
create_rdg_edges (struct graph *rdg, VEC (ddr_p, heap) *ddrs)
|
||||
{
|
||||
int i;
|
||||
struct data_dependence_relation *ddr;
|
||||
def_operand_p def_p;
|
||||
ssa_op_iter iter;
|
||||
|
||||
for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
|
||||
if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
|
||||
create_rdg_edge_for_ddr (rdg, ddr);
|
||||
|
||||
for (i = 0; i < rdg->n_vertices; i++)
|
||||
FOR_EACH_PHI_OR_STMT_DEF (def_p, RDGV_STMT (&(rdg->vertices[i])),
|
||||
iter, SSA_OP_ALL_DEFS)
|
||||
create_rdg_edges_for_scalar (rdg, DEF_FROM_PTR (def_p), i);
|
||||
}
|
||||
|
||||
/* Build the vertices of the reduced dependence graph RDG. */
|
||||
|
||||
static void
|
||||
create_rdg_vertices (struct graph *rdg, VEC (tree, heap) *stmts)
|
||||
{
|
||||
int i;
|
||||
tree s;
|
||||
|
||||
for (i = 0; VEC_iterate (tree, stmts, i, s); i++)
|
||||
{
|
||||
struct vertex *v = &(rdg->vertices[i]);
|
||||
|
||||
v->data = XNEW (struct rdg_vertex);
|
||||
RDGV_STMT (v) = s;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize STMTS with all the statements and PHI nodes of LOOP. */
|
||||
|
||||
static void
|
||||
stmts_from_loop (struct loop *loop, VEC (tree, heap) **stmts)
|
||||
{
|
||||
unsigned int i;
|
||||
basic_block *bbs = get_loop_body_in_dom_order (loop);
|
||||
|
||||
for (i = 0; i < loop->num_nodes; i++)
|
||||
{
|
||||
tree phi;
|
||||
basic_block bb = bbs[i];
|
||||
block_stmt_iterator bsi;
|
||||
|
||||
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
|
||||
VEC_safe_push (tree, heap, *stmts, phi);
|
||||
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
VEC_safe_push (tree, heap, *stmts, bsi_stmt (bsi));
|
||||
}
|
||||
|
||||
free (bbs);
|
||||
}
|
||||
|
||||
/* Returns true when all the dependences are computable. */
|
||||
|
||||
static bool
|
||||
known_dependences_p (VEC (ddr_p, heap) *dependence_relations)
|
||||
{
|
||||
ddr_p ddr;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; VEC_iterate (ddr_p, dependence_relations, i, ddr); i++)
|
||||
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Build a Reduced Dependence Graph with one vertex per statement of the
|
||||
loop nest and one edge per data dependence or scalar dependence. */
|
||||
|
||||
struct graph *
|
||||
build_rdg (struct loop *loop)
|
||||
{
|
||||
int nb_data_refs = 10;
|
||||
struct graph *rdg = NULL;
|
||||
VEC (ddr_p, heap) *dependence_relations;
|
||||
VEC (data_reference_p, heap) *datarefs;
|
||||
VEC (tree, heap) *stmts = VEC_alloc (tree, heap, 10);
|
||||
|
||||
dependence_relations = VEC_alloc (ddr_p, heap, nb_data_refs * nb_data_refs) ;
|
||||
datarefs = VEC_alloc (data_reference_p, heap, nb_data_refs);
|
||||
compute_data_dependences_for_loop (loop,
|
||||
false,
|
||||
&datarefs,
|
||||
&dependence_relations);
|
||||
|
||||
if (!known_dependences_p (dependence_relations))
|
||||
goto end_rdg;
|
||||
|
||||
stmts_from_loop (loop, &stmts);
|
||||
rdg = new_graph (VEC_length (tree, stmts));
|
||||
create_rdg_vertices (rdg, stmts);
|
||||
create_rdg_edges (rdg, dependence_relations);
|
||||
|
||||
end_rdg:
|
||||
free_dependence_relations (dependence_relations);
|
||||
free_data_refs (datarefs);
|
||||
VEC_free (tree, heap, stmts);
|
||||
|
||||
return rdg;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
#ifndef GCC_TREE_DATA_REF_H
|
||||
#define GCC_TREE_DATA_REF_H
|
||||
|
||||
#include "graphds.h"
|
||||
#include "lambda.h"
|
||||
#include "omega.h"
|
||||
|
||||
@ -329,6 +330,46 @@ bool find_loop_nest (struct loop *, VEC (loop_p, heap) **);
|
||||
void compute_all_dependences (VEC (data_reference_p, heap) *,
|
||||
VEC (ddr_p, heap) **, VEC (loop_p, heap) *, bool);
|
||||
|
||||
|
||||
|
||||
/* A RDG vertex representing a statement. */
|
||||
typedef struct rdg_vertex
|
||||
{
|
||||
/* The statement represented by this vertex. */
|
||||
tree stmt;
|
||||
} *rdg_vertex_p;
|
||||
|
||||
#define RDGV_STMT(V) ((struct rdg_vertex *) ((V)->data))->stmt
|
||||
|
||||
/* Data dependence type. */
|
||||
|
||||
enum rdg_dep_type
|
||||
{
|
||||
/* Read After Write (RAW). */
|
||||
flow_dd = 'f',
|
||||
|
||||
/* Write After Read (WAR). */
|
||||
anti_dd = 'a',
|
||||
|
||||
/* Write After Write (WAW). */
|
||||
output_dd = 'o',
|
||||
|
||||
/* Read After Read (RAR). */
|
||||
input_dd = 'i'
|
||||
};
|
||||
|
||||
/* Dependence information attached to an edge of the RDG. */
|
||||
|
||||
typedef struct rdg_edge
|
||||
{
|
||||
/* Type of the dependence. */
|
||||
enum rdg_dep_type type;
|
||||
} *rdg_edge_p;
|
||||
|
||||
#define RDGE_TYPE(E) ((struct rdg_edge *) ((E)->data))->type
|
||||
|
||||
struct graph *build_rdg (struct loop *);
|
||||
|
||||
/* Return the index of the variable VAR in the LOOP_NEST array. */
|
||||
|
||||
static inline int
|
||||
|
Loading…
Reference in New Issue
Block a user