aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey A Law <law@cygnus.com>1999-11-15 08:12:29 +0000
committerJeff Law <law@gcc.gnu.org>1999-11-15 01:12:29 -0700
commit6b8cf0c57c029951422b2d1beefe8548e9d98618 (patch)
treefcd1ce3b1eaf01522a488fd1131c6709f6c06b82
parent38e90e6c3bf7ff3c4a80f95a8c405fc2a69745a7 (diff)
downloadgcc-6b8cf0c57c029951422b2d1beefe8548e9d98618.zip
gcc-6b8cf0c57c029951422b2d1beefe8548e9d98618.tar.gz
gcc-6b8cf0c57c029951422b2d1beefe8548e9d98618.tar.bz2
basic-block.h: Remove all #defines and prototypes related to integer lists.
* basic-block.h: Remove all #defines and prototypes related to integer lists. (free_bb_mem, compute_preds_succs): Remove prototype. * rtl.h (free_bb_mem): Remove prototype. * flow.c (alloc_int_list_node); Remove function. (add_inst_list_node, free_int_list, add_pred_succ): Likewise. (compute_preds_succs, free_bb_mem): Likewise. * gcse.c (gcse_main): Do not call free_bb_mem anymore. * toplev.c (rest_of_compilation): Likewise. * haifa-sched.c (build_control_flow): Use flow generated edge list to build the haifa specific edge list. (find_rgns): Use new CFG data structures instead of pred/succ lists. (schedule_insns): Do not build pred/succ lists anymore. Instead build the edge table. From-SVN: r30531
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/basic-block.h43
-rw-r--r--gcc/flow.c136
-rw-r--r--gcc/gcse.c2
-rw-r--r--gcc/haifa-sched.c148
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/toplev.c2
7 files changed, 82 insertions, 265 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a5845e3..ca68fd2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,20 @@
Sun Nov 14 23:11:05 1999 Jeffrey A Law (law@cygnus.com)
+ * basic-block.h: Remove all #defines and prototypes related to
+ integer lists.
+ (free_bb_mem, compute_preds_succs): Remove prototype.
+ * rtl.h (free_bb_mem): Remove prototype.
+ * flow.c (alloc_int_list_node); Remove function.
+ (add_inst_list_node, free_int_list, add_pred_succ): Likewise.
+ (compute_preds_succs, free_bb_mem): Likewise.
+ * gcse.c (gcse_main): Do not call free_bb_mem anymore.
+ * toplev.c (rest_of_compilation): Likewise.
+ * haifa-sched.c (build_control_flow): Use flow generated edge
+ list to build the haifa specific edge list.
+ (find_rgns): Use new CFG data structures instead of pred/succ lists.
+ (schedule_insns): Do not build pred/succ lists anymore. Instead
+ build the edge table.
+
* basic-block.h (dump_bb_data): Remove declaration.
* flow.c (dump_bb_data): Remove function.
* sbitmap.c (sbitmap_intersect_of_predsucc): Delete function.
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index c511bc6..40cc602 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -184,46 +184,6 @@ extern regset regs_live_at_setjmp;
#define REG_BLOCK_GLOBAL -2
#define REG_BASIC_BLOCK(N) (VARRAY_REG (reg_n_info, N)->basic_block)
-
-/* List of integers.
- These are used for storing things like predecessors, etc.
-
- This scheme isn't very space efficient, especially on 64 bit machines.
- The interface is designed so that the implementation can be replaced with
- something more efficient if desirable. */
-
-typedef struct int_list {
- struct int_list *next;
- int val;
-} int_list;
-
-typedef int_list *int_list_ptr;
-
-/* Integer list elements are allocated in blocks to reduce the frequency
- of calls to malloc and to reduce the associated space overhead. */
-
-typedef struct int_list_block {
- struct int_list_block *next;
- int nodes_left;
-#define INT_LIST_NODES_IN_BLK 500
- struct int_list nodes[INT_LIST_NODES_IN_BLK];
-} int_list_block;
-
-/* Given a pointer to the list, return pointer to first element. */
-#define INT_LIST_FIRST(il) (il)
-
-/* Given a pointer to a list element, return pointer to next element. */
-#define INT_LIST_NEXT(p) ((p)->next)
-
-/* Return non-zero if P points to the end of the list. */
-#define INT_LIST_END(p) ((p) == NULL)
-
-/* Return element pointed to by P. */
-#define INT_LIST_VAL(p) ((p)->val)
-
-#define INT_LIST_SET_VAL(p, new_val) ((p)->val = (new_val))
-
-extern void free_int_list PROTO ((int_list_block **));
/* Stuff for recording basic block info. */
@@ -247,7 +207,6 @@ extern void compute_bb_for_insn PROTO ((int));
extern void set_block_for_insn PROTO ((rtx, basic_block));
extern void set_block_num PROTO ((rtx, int));
-extern void free_bb_mem PROTO ((void));
extern void free_basic_block_vars PROTO ((int));
extern basic_block split_edge PROTO ((edge));
@@ -290,8 +249,6 @@ void verify_edge_list PROTO ((FILE *, struct edge_list *));
int find_edge_index PROTO ((struct edge_list *,
basic_block, basic_block));
-extern void compute_preds_succs PROTO ((int_list_ptr *, int_list_ptr *,
- int *, int *));
extern void compute_flow_dominators PROTO ((sbitmap *, sbitmap *));
extern void compute_immediate_dominators PROTO ((int *, sbitmap *));
diff --git a/gcc/flow.c b/gcc/flow.c
index cba5bcc..894129e 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -345,13 +345,6 @@ void dump_flow_info PROTO((FILE *));
void debug_flow_info PROTO((void));
static void dump_edge_info PROTO((FILE *, edge, int));
-static int_list_ptr alloc_int_list_node PROTO ((int_list_block **));
-static int_list_ptr add_int_list_node PROTO ((int_list_block **,
- int_list **, int));
-
-static void add_pred_succ PROTO ((int, int, int_list_ptr *,
- int_list_ptr *, int *, int *));
-
static void count_reg_sets_1 PROTO ((rtx));
static void count_reg_sets PROTO ((rtx));
static void count_reg_references PROTO ((rtx));
@@ -5140,135 +5133,6 @@ print_rtl_with_bb (outf, rtx_first)
}
}
-
-/* Integer list support. */
-
-/* Allocate a node from list *HEAD_PTR. */
-
-static int_list_ptr
-alloc_int_list_node (head_ptr)
- int_list_block **head_ptr;
-{
- struct int_list_block *first_blk = *head_ptr;
-
- if (first_blk == NULL || first_blk->nodes_left <= 0)
- {
- first_blk = (struct int_list_block *) xmalloc (sizeof (struct int_list_block));
- first_blk->nodes_left = INT_LIST_NODES_IN_BLK;
- first_blk->next = *head_ptr;
- *head_ptr = first_blk;
- }
-
- first_blk->nodes_left--;
- return &first_blk->nodes[first_blk->nodes_left];
-}
-
-/* Pointer to head of predecessor/successor block list. */
-static int_list_block *pred_int_list_blocks;
-
-/* Add a new node to integer list LIST with value VAL.
- LIST is a pointer to a list object to allow for different implementations.
- If *LIST is initially NULL, the list is empty.
- The caller must not care whether the element is added to the front or
- to the end of the list (to allow for different implementations). */
-
-static int_list_ptr
-add_int_list_node (blk_list, list, val)
- int_list_block **blk_list;
- int_list **list;
- int val;
-{
- int_list_ptr p = alloc_int_list_node (blk_list);
-
- p->val = val;
- p->next = *list;
- *list = p;
- return p;
-}
-
-/* Free the blocks of lists at BLK_LIST. */
-
-void
-free_int_list (blk_list)
- int_list_block **blk_list;
-{
- int_list_block *p, *next;
-
- for (p = *blk_list; p != NULL; p = next)
- {
- next = p->next;
- free (p);
- }
-
- /* Mark list as empty for the next function we compile. */
- *blk_list = NULL;
-}
-
-/* Predecessor/successor computation. */
-
-/* Mark PRED_BB a precessor of SUCC_BB,
- and conversely SUCC_BB a successor of PRED_BB. */
-
-static void
-add_pred_succ (pred_bb, succ_bb, s_preds, s_succs, num_preds, num_succs)
- int pred_bb;
- int succ_bb;
- int_list_ptr *s_preds;
- int_list_ptr *s_succs;
- int *num_preds;
- int *num_succs;
-{
- if (succ_bb != EXIT_BLOCK)
- {
- add_int_list_node (&pred_int_list_blocks, &s_preds[succ_bb], pred_bb);
- num_preds[succ_bb]++;
- }
- if (pred_bb != ENTRY_BLOCK)
- {
- add_int_list_node (&pred_int_list_blocks, &s_succs[pred_bb], succ_bb);
- num_succs[pred_bb]++;
- }
-}
-
-/* Convert edge lists into pred/succ lists for backward compatibility. */
-
-void
-compute_preds_succs (s_preds, s_succs, num_preds, num_succs)
- int_list_ptr *s_preds;
- int_list_ptr *s_succs;
- int *num_preds;
- int *num_succs;
-{
- int i, n = n_basic_blocks;
- edge e;
-
- memset (s_preds, 0, n_basic_blocks * sizeof (int_list_ptr));
- memset (s_succs, 0, n_basic_blocks * sizeof (int_list_ptr));
- memset (num_preds, 0, n_basic_blocks * sizeof (int));
- memset (num_succs, 0, n_basic_blocks * sizeof (int));
-
- for (i = 0; i < n; ++i)
- {
- basic_block bb = BASIC_BLOCK (i);
-
- for (e = bb->succ; e ; e = e->succ_next)
- add_pred_succ (i, e->dest->index, s_preds, s_succs,
- num_preds, num_succs);
- }
-
- for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
- add_pred_succ (ENTRY_BLOCK, e->dest->index, s_preds, s_succs,
- num_preds, num_succs);
-}
-
-/* Free basic block data storage. */
-
-void
-free_bb_mem ()
-{
- free_int_list (&pred_int_list_blocks);
-}
-
/* Compute dominator relationships using new flow graph structures. */
void
compute_flow_dominators (dominators, post_dominators)
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 73f8373..701c515 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -813,8 +813,6 @@ gcse_main (f, file)
obstack_free (&gcse_obstack, NULL_PTR);
/* Free reg_set_table. */
free_reg_set_mem ();
- /* Free storage used to record predecessor/successor data. */
- free_bb_mem ();
/* Free storage allocated by find_basic_blocks. */
free_basic_block_vars (0);
return run_jump_opt_after_gcse;
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index a4fdd75..53209f1 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -473,8 +473,7 @@ static int *out_edges;
static int is_cfg_nonregular PROTO ((void));
-static int build_control_flow PROTO ((int_list_ptr *, int_list_ptr *,
- int *, int *));
+static int build_control_flow PROTO ((struct edge_list *));
static void new_edge PROTO ((int, int));
@@ -513,8 +512,7 @@ static int *containing_rgn;
void debug_regions PROTO ((void));
static void find_single_block_region PROTO ((void));
-static void find_rgns PROTO ((int_list_ptr *, int_list_ptr *,
- int *, int *, sbitmap *));
+static void find_rgns PROTO ((struct edge_list *, sbitmap *));
static int too_large PROTO ((int, int *, int *));
extern void debug_live PROTO ((int, int));
@@ -1060,48 +1058,45 @@ is_cfg_nonregular ()
prevent cross block scheduling. */
static int
-build_control_flow (s_preds, s_succs, num_preds, num_succs)
- int_list_ptr *s_preds;
- int_list_ptr *s_succs;
- int *num_preds;
- int *num_succs;
+build_control_flow (edge_list)
+ struct edge_list *edge_list;
{
- int i;
- int_list_ptr succ;
- int unreachable;
+ int i, unreachable, num_edges;
- /* Count the number of edges in the cfg. */
- nr_edges = 0;
+ /* This already accounts for entry/exit edges. */
+ num_edges = NUM_EDGES (edge_list);
+
+ /* Unreachable loops with more than one basic block are detected
+ during the DFS traversal in find_rgns.
+
+ Unreachable loops with a single block are detected here. This
+ test is redundant with the one in find_rgns, but it's much
+ cheaper to go ahead and catch the trivial case here. */
unreachable = 0;
for (i = 0; i < n_basic_blocks; i++)
{
- nr_edges += num_succs[i];
-
- /* Unreachable loops with more than one basic block are detected
- during the DFS traversal in find_rgns.
+ basic_block b = BASIC_BLOCK (i);
- Unreachable loops with a single block are detected here. This
- test is redundant with the one in find_rgns, but it's much
- cheaper to go ahead and catch the trivial case here. */
- if (num_preds[i] == 0
- || (num_preds[i] == 1 && INT_LIST_VAL (s_preds[i]) == i))
+ if (b->pred == NULL
+ || (b->pred->dest == b
+ && b->pred->pred_next == NULL))
unreachable = 1;
}
- /* Account for entry/exit edges. */
- nr_edges += 2;
-
+ /* ??? We can kill these soon. */
in_edges = (int *) xcalloc (n_basic_blocks, sizeof (int));
out_edges = (int *) xcalloc (n_basic_blocks, sizeof (int));
- edge_table = (haifa_edge *) xcalloc (nr_edges, sizeof (haifa_edge));
+ edge_table = (haifa_edge *) xcalloc (num_edges, sizeof (haifa_edge));
nr_edges = 0;
- for (i = 0; i < n_basic_blocks; i++)
- for (succ = s_succs[i]; succ; succ = succ->next)
- {
- if (INT_LIST_VAL (succ) != EXIT_BLOCK)
- new_edge (i, INT_LIST_VAL (succ));
- }
+ for (i = 0; i < num_edges; i++)
+ {
+ edge e = INDEX_EDGE (edge_list, i);
+
+ if (e->dest != EXIT_BLOCK_PTR
+ && e->src != ENTRY_BLOCK_PTR)
+ new_edge (e->src->index, e->dest->index);
+ }
/* Increment by 1, since edge 0 is unused. */
nr_edges++;
@@ -1391,11 +1386,8 @@ too_large (block, num_bbs, num_insns)
of edge tables. That would simplify it somewhat. */
static void
-find_rgns (s_preds, s_succs, num_preds, num_succs, dom)
- int_list_ptr *s_preds;
- int_list_ptr *s_succs;
- int *num_preds;
- int *num_succs;
+find_rgns (edge_list, dom)
+ struct edge_list *edge_list;
sbitmap *dom;
{
int *max_hdr, *dfs_nr, *stack, *degree;
@@ -1420,6 +1412,8 @@ find_rgns (s_preds, s_succs, num_preds, num_succs, dom)
/* Note if a block is in the block queue. */
sbitmap in_stack;
+ int num_edges = NUM_EDGES (edge_list);
+
/* Perform a DFS traversal of the cfg. Identify loop headers, inner loops
and a mapping from block to its loop header (if the block is contained
in a loop, else -1).
@@ -1554,9 +1548,13 @@ find_rgns (s_preds, s_succs, num_preds, num_succs, dom)
to hold degree counts. */
degree = dfs_nr;
- /* Compute the in-degree of every block in the graph. */
- for (i = 0; i < n_basic_blocks; i++)
- degree[i] = num_preds[i];
+ for (i = 0; i < num_edges; i++)
+ {
+ edge e = INDEX_EDGE (edge_list, i);
+
+ if (e->src != ENTRY_BLOCK_PTR)
+ degree[e->src->index]++;
+ }
/* Do not perform region scheduling if there are any unreachable
blocks. */
@@ -1578,7 +1576,7 @@ find_rgns (s_preds, s_succs, num_preds, num_succs, dom)
{
if (TEST_BIT (header, i) && TEST_BIT (inner, i))
{
- int_list_ptr ps;
+ edge e;
int j;
/* Now check that the loop is reducible. We do this separate
@@ -1619,10 +1617,9 @@ find_rgns (s_preds, s_succs, num_preds, num_succs, dom)
/* Decrease degree of all I's successors for topological
ordering. */
- for (ps = s_succs[i]; ps; ps = ps->next)
- if (INT_LIST_VAL (ps) != EXIT_BLOCK
- && INT_LIST_VAL (ps) != ENTRY_BLOCK)
- --degree[INT_LIST_VAL(ps)];
+ for (e = BASIC_BLOCK (i)->succ; e; e = e->succ_next)
+ if (e->dest != EXIT_BLOCK_PTR)
+ --degree[e->dest->index];
/* Estimate # insns, and count # blocks in the region. */
num_bbs = 1;
@@ -1639,8 +1636,9 @@ find_rgns (s_preds, s_succs, num_preds, num_succs, dom)
for (j = 0; j < n_basic_blocks; j++)
/* Leaf nodes have only a single successor which must
be EXIT_BLOCK. */
- if (num_succs[j] == 1
- && INT_LIST_VAL (s_succs[j]) == EXIT_BLOCK)
+ if (BASIC_BLOCK (j)->succ
+ && BASIC_BLOCK (j)->succ->dest == EXIT_BLOCK_PTR
+ && BASIC_BLOCK (j)->succ->succ_next == NULL)
{
queue[++tail] = j;
SET_BIT (in_queue, j);
@@ -1654,15 +1652,15 @@ find_rgns (s_preds, s_succs, num_preds, num_succs, dom)
}
else
{
- int_list_ptr ps;
+ edge e;
- for (ps = s_preds[i]; ps; ps = ps->next)
+ for (e = BASIC_BLOCK (i)->pred; e; e = e->pred_next)
{
- node = INT_LIST_VAL (ps);
-
- if (node == ENTRY_BLOCK || node == EXIT_BLOCK)
+ if (e->src == ENTRY_BLOCK_PTR)
continue;
-
+
+ node = e->src->index;
+
if (max_hdr[node] == loop_head && node != i)
{
/* This is a loop latch. */
@@ -1712,16 +1710,16 @@ find_rgns (s_preds, s_succs, num_preds, num_succs, dom)
while (head < tail && !too_large_failure)
{
- int_list_ptr ps;
+ edge e;
child = queue[++head];
- for (ps = s_preds[child]; ps; ps = ps->next)
+ for (e = BASIC_BLOCK (child)->pred; e; e = e->pred_next)
{
- node = INT_LIST_VAL (ps);
+ node = e->src->index;
/* See discussion above about nodes not marked as in
this loop during the initial DFS traversal. */
- if (node == ENTRY_BLOCK || node == EXIT_BLOCK
+ if (e->src == ENTRY_BLOCK_PTR
|| max_hdr[node] != loop_head)
{
tail = -1;
@@ -1757,23 +1755,24 @@ find_rgns (s_preds, s_succs, num_preds, num_succs, dom)
the region. */
while (tail >= 0)
{
- int_list_ptr ps;
-
if (head < 0)
head = tail;
child = queue[head];
if (degree[child] == 0)
{
+ edge e;
+
degree[child] = -1;
rgn_bb_table[idx++] = child;
BLOCK_TO_BB (child) = ++count;
CONTAINING_RGN (child) = nr_regions;
queue[head] = queue[tail--];
- for (ps = s_succs[child]; ps; ps = ps->next)
- if (INT_LIST_VAL (ps) != ENTRY_BLOCK
- && INT_LIST_VAL (ps) != EXIT_BLOCK)
- --degree[INT_LIST_VAL (ps)];
+ for (e = BASIC_BLOCK (child)->succ;
+ e;
+ e = e->succ_next)
+ if (e->dest != EXIT_BLOCK_PTR)
+ --degree[e->dest->index];
}
else
--head;
@@ -6963,16 +6962,9 @@ schedule_insns (dump_file)
}
else
{
- int_list_ptr *s_preds, *s_succs;
- int *num_preds, *num_succs;
sbitmap *dom;
+ struct edge_list *edge_list;
- s_preds = (int_list_ptr *) xmalloc (n_basic_blocks
- * sizeof (int_list_ptr));
- s_succs = (int_list_ptr *) xmalloc (n_basic_blocks
- * sizeof (int_list_ptr));
- num_preds = (int *) xmalloc (n_basic_blocks * sizeof (int));
- num_succs = (int *) xmalloc (n_basic_blocks * sizeof (int));
dom = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
/* The scheduler runs after flow; therefore, we can't blindly call
@@ -6986,8 +6978,7 @@ schedule_insns (dump_file)
We could (should?) recompute register live information. Doing
so may even be beneficial. */
-
- compute_preds_succs (s_preds, s_succs, num_preds, num_succs);
+ edge_list = create_edge_list ();
/* Compute the dominators and post dominators. We don't
currently use post dominators, but we should for
@@ -6997,22 +6988,17 @@ schedule_insns (dump_file)
/* build_control_flow will return nonzero if it detects unreachable
blocks or any other irregularity with the cfg which prevents
cross block scheduling. */
- if (build_control_flow (s_preds, s_succs, num_preds, num_succs) != 0)
+ if (build_control_flow (edge_list) != 0)
find_single_block_region ();
else
- find_rgns (s_preds, s_succs, num_preds, num_succs, dom);
+ find_rgns (edge_list, dom);
if (sched_verbose >= 3)
debug_regions ();
/* For now. This will move as more and more of haifa is converted
to using the cfg code in flow.c. */
- free_bb_mem ();
free (dom);
- free (s_preds);
- free (s_succs);
- free (num_preds);
- free (num_succs);
}
}
diff --git a/gcc/rtl.h b/gcc/rtl.h
index bcf0278..dedbe99 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1539,7 +1539,6 @@ extern void recompute_reg_usage PROTO ((rtx, int));
extern void print_rtl_with_bb PROTO ((FILE *, rtx));
extern void dump_flow_info PROTO ((FILE *));
#endif
-extern void free_bb_mem PROTO ((void));
/* In expmed.c */
extern void init_expmed PROTO ((void));
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 615ee9e..19d3091 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -4464,8 +4464,6 @@ rest_of_compilation (decl)
exit_rest_of_compilation:
- free_bb_mem ();
-
/* In case the function was not output,
don't leave any temporary anonymous types
queued up for sdb output. */