From: Jeffrey A Law Date: Mon, 15 Nov 1999 08:12:29 +0000 (+0000) Subject: basic-block.h: Remove all #defines and prototypes related to integer lists. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6b8cf0c57c029951422b2d1beefe8548e9d98618;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a5845e30687..ca68fd2a280 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 c511bc61437..40cc6022376 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 cba5bccb907..894129e0aab 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 73f83734465..701c5150955 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 a4fdd75f2c8..53209f15edd 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 bcf0278e0f5..dedbe99d650 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 615ee9e08bf..19d30917f35 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. */