basic-block.h (struct edge_list): Stucture to maintain a vector of edges.

* basic-block.h (struct edge_list): Stucture to maintain a vector
	of edges.
	(EDGE_INDEX_NO_EDGE, EDGE_INDEX, INDEX_EDGE_PRED_BB, INDEX_EDGE_SUCC_BB,
	 INDEX_EDGE, NUM_EDGES): New Macros for accessing edge list.
	(create_edge_list, free_edge-List, print_edge_list, verify_edge_list):
	New function prototypes.
	* flow.c (create_edge_list): Function to create an edge list.
	(free_edge_list): Discards memory used by an edge list.
	(print_edge_list): Debug output showing an edge list.
	(verify_edge_list): Internal consistency check for an edge list.

From-SVN: r28732
This commit is contained in:
Andrew MacLeod 1999-08-16 22:14:51 +00:00 committed by Andrew Macleod
parent b0d065155d
commit 410538ea80
3 changed files with 311 additions and 0 deletions

View File

@ -1,3 +1,17 @@
Mon Aug 16 18:08:22 EDT 1999 Andrew MacLeod <amacleod@cygnus.com>
* basic-block.h (struct edge_list): Stucture to maintain a vector
of edges.
(EDGE_INDEX_NO_EDGE, EDGE_INDEX, INDEX_EDGE_PRED_BB, INDEX_EDGE_SUCC_BB,
INDEX_EDGE, NUM_EDGES): New Macros for accessing edge list.
(create_edge_list, free_edge-List, print_edge_list, verify_edge_list):
New function prototypes.
* flow.c (create_edge_list): Function to create an edge list.
(free_edge_list): Discards memory used by an edge list.
(print_edge_list): Debug output showing an edge list.
(verify_edge_list): Internal consistency check for an edge list.
(find_edge_index): Function to find an edge index for a pred and succ.
Mon Aug 16 11:56:36 1999 Mark Mitchell <mark@codesourcery.com>
* tree.c (type_hash_add): Use permalloc to allocate nodes in the

View File

@ -244,6 +244,38 @@ extern basic_block split_edge PROTO ((edge));
extern void insert_insn_on_edge PROTO ((rtx, edge));
extern void commit_edge_insertions PROTO ((void));
/* This structure maintains an edge list vector. */
struct edge_list
{
int num_blocks;
int num_edges;
edge *index_to_edge;
};
/* This is the value which indicates no edge is present. */
#define EDGE_INDEX_NO_EDGE -1
/* EDGE_INDEX returns an integer index for an edge, or EDGE_INDEX_NO_EDGE
if there is no edge between the 2 basic blocks. */
#define EDGE_INDEX(el, pred, succ) (find_edge_index ((el), (pred), (succ)))
/* INDEX_EDGE_PRED_BB and INDEX_EDGE_SUCC_BB return a pointer to the basic
block which is either the pred or succ end of the indexed edge. */
#define INDEX_EDGE_PRED_BB(el, index) ((el)->index_to_edge[(index)]->src)
#define INDEX_EDGE_SUCC_BB(el, index) ((el)->index_to_edge[(index)]->dest)
/* INDEX_EDGE returns a pointer to the edge. */
#define INDEX_EDGE(el, index) ((el)->index_to_edge[(index)])
/* Number of edges in the compressed edge list. */
#define NUM_EDGES(el) ((el)->num_edges)
struct edge_list * create_edge_list PROTO ((void));
void free_edge_list PROTO ((struct edge_list *));
void print_edge_list PROTO ((FILE *, struct edge_list *));
void verify_edge_list PROTO ((FILE *, struct edge_list *));
int find_edge_index PROTO ((struct edge_list *, int, int));
extern void compute_preds_succs PROTO ((int_list_ptr *, int_list_ptr *,
int *, int *));
extern void compute_dominators PROTO ((sbitmap *, sbitmap *,

View File

@ -5243,3 +5243,268 @@ verify_flow_info ()
x = NEXT_INSN (x);
}
}
/* Functions to access an edge list with a vector representation.
Enough data is kept such that given an index number, the
pred and succ that edge reprsents can be determined, or
given a pred and a succ, it's index number can be returned.
This allows algorithms which comsume a lot of memory to
represent the normally full matrix of edge (pred,succ) with a
single indexed vector, edge (EDGE_INDEX (pred, succ)), with no
wasted space in the client code due to sparse flow graphs. */
/* This functions initializes the edge list. Basically the entire
flowgraph is processed, and all edges are assigned a number,
and the data structure is filed in. */
struct edge_list *
create_edge_list ()
{
struct edge_list *elist;
edge e;
int num_edges;
int x,y;
int_list_ptr ptr;
int block_count;
block_count = n_basic_blocks + 2; /* Include the entry and exit blocks. */
num_edges = 0;
/* Determine the number of edges in the flow graph by counting successor
edges on each basic block. */
for (x = 0; x < n_basic_blocks; x++)
{
basic_block bb = BASIC_BLOCK (x);
for (e = bb->succ; e; e = e->succ_next)
num_edges++;
}
/* Don't forget successors of the entry block. */
for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
num_edges++;
elist = malloc (sizeof (struct edge_list));
elist->num_blocks = block_count;
elist->num_edges = num_edges;
elist->index_to_edge = malloc (sizeof (edge) * num_edges);
num_edges = 0;
/* Follow successors of the entry block, and register these edges. */
for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
{
elist->index_to_edge[num_edges] = e;
num_edges++;
}
for (x = 0; x < n_basic_blocks; x++)
{
basic_block bb = BASIC_BLOCK (x);
/* Follow all successors of blocks, and register these edges. */
for (e = bb->succ; e; e = e->succ_next)
{
elist->index_to_edge[num_edges] = e;
num_edges++;
}
}
return elist;
}
/* This function free's memory associated with an edge list. */
void
free_edge_list (elist)
struct edge_list *elist;
{
if (elist)
{
free (elist->index_to_edge);
free (elist);
}
}
/* This function provides debug output showing an edge list. */
void
print_edge_list (f, elist)
FILE *f;
struct edge_list *elist;
{
int x;
fprintf(f, "Compressed edge list, %d BBs + entry & exit, and %d edges\n",
elist->num_blocks - 2, elist->num_edges);
for (x = 0; x < elist->num_edges; x++)
{
fprintf (f, " %-4d - edge(", x);
if (INDEX_EDGE_PRED_BB (elist, x) == ENTRY_BLOCK_PTR)
fprintf (f,"entry,");
else
fprintf (f,"%d,", INDEX_EDGE_PRED_BB (elist, x)->index);
if (INDEX_EDGE_SUCC_BB (elist, x) == EXIT_BLOCK_PTR)
fprintf (f,"exit)\n");
else
fprintf (f,"%d)\n", INDEX_EDGE_SUCC_BB (elist, x)->index);
}
}
/* This function provides an internal consistancy check of an edge list,
verifying that all edges are present, and that there are no
extra edges. */
void
verify_edge_list (f, elist)
FILE *f;
struct edge_list *elist;
{
int x, pred, succ, index;
int_list_ptr ptr;
int flawed = 0;
edge e;
for (x = 0; x < n_basic_blocks; x++)
{
basic_block bb = BASIC_BLOCK (x);
for (e = bb->succ; e; e = e->succ_next)
{
pred = e->src->index;
succ = e->dest->index;
index = EDGE_INDEX (elist, pred, succ);
if (index == EDGE_INDEX_NO_EDGE)
{
fprintf (f, "*p* No index for edge from %d to %d\n",pred, succ);
continue;
}
if (INDEX_EDGE_PRED_BB (elist, index)->index != pred)
fprintf (f, "*p* Pred for index %d should be %d not %d\n",
index, pred, INDEX_EDGE_PRED_BB (elist, index)->index);
if (INDEX_EDGE_SUCC_BB (elist, index)->index != succ)
fprintf (f, "*p* Succ for index %d should be %d not %d\n",
index, succ, INDEX_EDGE_SUCC_BB (elist, index)->index);
}
}
for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
{
pred = e->src->index;
succ = e->dest->index;
index = EDGE_INDEX (elist, pred, succ);
if (index == EDGE_INDEX_NO_EDGE)
{
fprintf (f, "*p* No index for edge from %d to %d\n",pred, succ);
continue;
}
if (INDEX_EDGE_PRED_BB (elist, index)->index != pred)
fprintf (f, "*p* Pred for index %d should be %d not %d\n",
index, pred, INDEX_EDGE_PRED_BB (elist, index)->index);
if (INDEX_EDGE_SUCC_BB (elist, index)->index != succ)
fprintf (f, "*p* Succ for index %d should be %d not %d\n",
index, succ, INDEX_EDGE_SUCC_BB (elist, index)->index);
}
/* We've verified that all the edges are in the list, no lets make sure
there are no spurious edges in the list. */
for (pred = 0 ; pred < n_basic_blocks; pred++)
for (succ = 0 ; succ < n_basic_blocks; succ++)
{
basic_block p = BASIC_BLOCK (pred);
basic_block s = BASIC_BLOCK (succ);
int found_edge = 0;
for (e = p->succ; e; e = e->succ_next)
if (e->dest == s)
{
found_edge = 1;
break;
}
for (e = s->pred; e; e = e->pred_next)
if (e->src == p)
{
found_edge = 1;
break;
}
if (EDGE_INDEX (elist, pred, succ) == EDGE_INDEX_NO_EDGE
&& found_edge != 0)
fprintf (f, "*** Edge (%d, %d) appears to not have an index\n",
pred, succ);
if (EDGE_INDEX (elist, pred, succ) != EDGE_INDEX_NO_EDGE
&& found_edge == 0)
fprintf (f, "*** Edge (%d, %d) has index %d, but there is no edge\n",
pred, succ, EDGE_INDEX (elist, pred, succ));
}
for (succ = 0 ; succ < n_basic_blocks; succ++)
{
basic_block p = ENTRY_BLOCK_PTR;
basic_block s = BASIC_BLOCK (succ);
int found_edge = 0;
for (e = p->succ; e; e = e->succ_next)
if (e->dest == s)
{
found_edge = 1;
break;
}
for (e = s->pred; e; e = e->pred_next)
if (e->src == p)
{
found_edge = 1;
break;
}
if (EDGE_INDEX (elist, ENTRY_BLOCK, succ) == EDGE_INDEX_NO_EDGE
&& found_edge != 0)
fprintf (f, "*** Edge (entry, %d) appears to not have an index\n",
succ);
if (EDGE_INDEX (elist, ENTRY_BLOCK, succ) != EDGE_INDEX_NO_EDGE
&& found_edge == 0)
fprintf (f, "*** Edge (entry, %d) has index %d, but no edge exists\n",
succ, EDGE_INDEX (elist, ENTRY_BLOCK, succ));
}
for (pred = 0 ; pred < n_basic_blocks; pred++)
{
basic_block p = BASIC_BLOCK (pred);
basic_block s = EXIT_BLOCK_PTR;
int found_edge = 0;
for (e = p->succ; e; e = e->succ_next)
if (e->dest == s)
{
found_edge = 1;
break;
}
for (e = s->pred; e; e = e->pred_next)
if (e->src == p)
{
found_edge = 1;
break;
}
if (EDGE_INDEX (elist, pred, EXIT_BLOCK) == EDGE_INDEX_NO_EDGE
&& found_edge != 0)
fprintf (f, "*** Edge (%d, exit) appears to not have an index\n",
pred);
if (EDGE_INDEX (elist, pred, EXIT_BLOCK) != EDGE_INDEX_NO_EDGE
&& found_edge == 0)
fprintf (f, "*** Edge (%d, exit) has index %d, but no edge exists\n",
pred, EDGE_INDEX (elist, pred, EXIT_BLOCK));
}
}
/* This routine will determine what, if any, edge there is between
a specified predecessor and successor. */
int
find_edge_index (edge_list, pred, succ)
struct edge_list *edge_list;
int pred, succ;
{
int x;
for (x = 0; x < NUM_EDGES (edge_list); x++)
{
if (INDEX_EDGE_PRED_BB (edge_list, x)->index == pred
&& INDEX_EDGE_SUCC_BB (edge_list, x)->index == succ)
return x;
}
return (EDGE_INDEX_NO_EDGE);
}