From 5e00ec74d8ce58f99801200d4d3d0412c7cc1b28 Mon Sep 17 00:00:00 2001 From: kan Date: Wed, 28 Jul 2004 03:11:36 +0000 Subject: Gcc 3.4.2 20040728. --- contrib/gcc/cfganal.c | 191 ++++++++++++++++++++++---------------------------- 1 file changed, 83 insertions(+), 108 deletions(-) (limited to 'contrib/gcc/cfganal.c') diff --git a/contrib/gcc/cfganal.c b/contrib/gcc/cfganal.c index 3831c5f..aa3965c 100644 --- a/contrib/gcc/cfganal.c +++ b/contrib/gcc/cfganal.c @@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA /* This file contains various simple utilities to analyze the CFG. */ #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "rtl.h" #include "hard-reg-set.h" #include "basic-block.h" @@ -44,29 +46,25 @@ struct depth_first_search_dsS { }; typedef struct depth_first_search_dsS *depth_first_search_ds; -static void flow_dfs_compute_reverse_init - PARAMS ((depth_first_search_ds)); -static void flow_dfs_compute_reverse_add_bb - PARAMS ((depth_first_search_ds, basic_block)); -static basic_block flow_dfs_compute_reverse_execute - PARAMS ((depth_first_search_ds)); -static void flow_dfs_compute_reverse_finish - PARAMS ((depth_first_search_ds)); -static void remove_fake_successors PARAMS ((basic_block)); -static bool need_fake_edge_p PARAMS ((rtx)); -static bool flow_active_insn_p PARAMS ((rtx)); +static void flow_dfs_compute_reverse_init (depth_first_search_ds); +static void flow_dfs_compute_reverse_add_bb (depth_first_search_ds, + basic_block); +static basic_block flow_dfs_compute_reverse_execute (depth_first_search_ds); +static void flow_dfs_compute_reverse_finish (depth_first_search_ds); +static void remove_fake_successors (basic_block); +static bool need_fake_edge_p (rtx); +static bool flow_active_insn_p (rtx); /* Like active_insn_p, except keep the return value clobber around even after reload. */ static bool -flow_active_insn_p (insn) - rtx insn; +flow_active_insn_p (rtx insn) { if (active_insn_p (insn)) return true; - /* A clobber of the function return value exists for buggy + /* A clobber of the function return value exists for buggy programs that fail to return a value. Its effect is to keep the return value from being live across the entire function. If we allow it to be skipped, we introduce the @@ -83,8 +81,7 @@ flow_active_insn_p (insn) its single destination. */ bool -forwarder_block_p (bb) - basic_block bb; +forwarder_block_p (basic_block bb) { rtx insn; @@ -92,7 +89,7 @@ forwarder_block_p (bb) || !bb->succ || bb->succ->succ_next) return false; - for (insn = bb->head; insn != bb->end; insn = NEXT_INSN (insn)) + for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn)) if (INSN_P (insn) && flow_active_insn_p (insn)) return false; @@ -104,16 +101,15 @@ forwarder_block_p (bb) /* Return nonzero if we can reach target from src by falling through. */ bool -can_fallthru (src, target) - basic_block src, target; +can_fallthru (basic_block src, basic_block target) { - rtx insn = src->end; - rtx insn2 = target->head; + rtx insn = BB_END (src); + rtx insn2 = target == EXIT_BLOCK_PTR ? NULL : BB_HEAD (target); if (src->next_bb != target) return 0; - if (!active_insn_p (insn2)) + if (insn2 && !active_insn_p (insn2)) insn2 = next_active_insn (insn2); /* ??? Later we may add code to move jump tables offline. */ @@ -131,7 +127,7 @@ can_fallthru (src, target) and heavily borrowed from flow_depth_first_order_compute. */ bool -mark_dfs_back_edges () +mark_dfs_back_edges (void) { edge *stack; int *pre; @@ -143,11 +139,11 @@ mark_dfs_back_edges () bool found = false; /* Allocate the preorder and postorder number arrays. */ - pre = (int *) xcalloc (last_basic_block, sizeof (int)); - post = (int *) xcalloc (last_basic_block, sizeof (int)); + pre = xcalloc (last_basic_block, sizeof (int)); + post = xcalloc (last_basic_block, sizeof (int)); /* Allocate stack for back-tracking up CFG. */ - stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge)); + stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge)); sp = 0; /* Allocate bitmap to track nodes that have been visited. */ @@ -215,7 +211,7 @@ mark_dfs_back_edges () /* Set the flag EDGE_CAN_FALLTHRU for edges that can be fallthru. */ void -set_edge_can_fallthru_flag () +set_edge_can_fallthru_flag (void) { basic_block bb; @@ -232,15 +228,15 @@ set_edge_can_fallthru_flag () e->flags |= EDGE_CAN_FALLTHRU; } - /* If the BB ends with an invertable condjump all (2) edges are + /* If the BB ends with an invertible condjump all (2) edges are CAN_FALLTHRU edges. */ if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next) continue; - if (!any_condjump_p (bb->end)) + if (!any_condjump_p (BB_END (bb))) continue; - if (!invert_jump (bb->end, JUMP_LABEL (bb->end), 0)) + if (!invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0)) continue; - invert_jump (bb->end, JUMP_LABEL (bb->end), 0); + invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0); bb->succ->flags |= EDGE_CAN_FALLTHRU; bb->succ->succ_next->flags |= EDGE_CAN_FALLTHRU; } @@ -250,8 +246,7 @@ set_edge_can_fallthru_flag () Helper function for the flow_call_edges_add. */ static bool -need_fake_edge_p (insn) - rtx insn; +need_fake_edge_p (rtx insn) { if (!INSN_P (insn)) return false; @@ -280,8 +275,7 @@ need_fake_edge_p (insn) that all subsequent instructions must be executed. */ int -flow_call_edges_add (blocks) - sbitmap blocks; +flow_call_edges_add (sbitmap blocks) { int i; int blocks_split = 0; @@ -311,10 +305,10 @@ flow_call_edges_add (blocks) if (check_last_block) { basic_block bb = EXIT_BLOCK_PTR->prev_bb; - rtx insn = bb->end; + rtx insn = BB_END (bb); /* Back up past insns that must be kept in the same block as a call. */ - while (insn != bb->head + while (insn != BB_HEAD (bb) && keep_with_call_p (insn)) insn = PREV_INSN (insn); @@ -339,6 +333,7 @@ flow_call_edges_add (blocks) for (i = 0; i < last_bb; i++) { basic_block bb = BASIC_BLOCK (i); + rtx libcall_end = NULL_RTX; rtx insn; rtx prev_insn; @@ -348,7 +343,7 @@ flow_call_edges_add (blocks) if (blocks && !TEST_BIT (blocks, i)) continue; - for (insn = bb->end; ; insn = prev_insn) + for (insn = BB_END (bb); ; insn = prev_insn) { prev_insn = PREV_INSN (insn); if (need_fake_edge_p (insn)) @@ -356,10 +351,14 @@ flow_call_edges_add (blocks) edge e; rtx split_at_insn = insn; + /* Don't split libcalls. */ + if (libcall_end) + split_at_insn = libcall_end; + /* Don't split the block between a call and an insn that should remain in the same block as the call. */ - if (GET_CODE (insn) == CALL_INSN) - while (split_at_insn != bb->end + else if (GET_CODE (insn) == CALL_INSN) + while (split_at_insn != BB_END (bb) && keep_with_call_p (NEXT_INSN (split_at_insn))) split_at_insn = NEXT_INSN (split_at_insn); @@ -369,7 +368,7 @@ flow_call_edges_add (blocks) cause us to mark that edge as fake and remove it later. */ #ifdef ENABLE_CHECKING - if (split_at_insn == bb->end) + if (split_at_insn == BB_END (bb)) for (e = bb->succ; e; e = e->succ_next) if (e->dest == EXIT_BLOCK_PTR) abort (); @@ -377,7 +376,7 @@ flow_call_edges_add (blocks) /* Note that the following may create a new basic block and renumber the existing basic blocks. */ - if (split_at_insn != bb->end) + if (split_at_insn != BB_END (bb)) { e = split_block (bb, split_at_insn); if (e) @@ -387,7 +386,15 @@ flow_call_edges_add (blocks) make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE); } - if (insn == bb->head) + /* Watch out for REG_LIBCALL/REG_RETVAL notes so that we know + whether we are currently in a libcall or not. Remember that + we are scanning backwards! */ + if (find_reg_note (insn, REG_RETVAL, NULL_RTX)) + libcall_end = insn; + if (find_reg_note (insn, REG_LIBCALL, NULL_RTX)) + libcall_end = NULL_RTX; + + if (insn == BB_HEAD (bb)) break; } } @@ -403,13 +410,12 @@ flow_call_edges_add (blocks) block is reachable. */ void -find_unreachable_blocks () +find_unreachable_blocks (void) { edge e; basic_block *tos, *worklist, bb; - tos = worklist = - (basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks); + tos = worklist = xmalloc (sizeof (basic_block) * n_basic_blocks); /* Clear all the reachability flags. */ @@ -459,7 +465,7 @@ find_unreachable_blocks () and the data structure is filled in. */ struct edge_list * -create_edge_list () +create_edge_list (void) { struct edge_list *elist; edge e; @@ -479,10 +485,10 @@ create_edge_list () num_edges++; } - elist = (struct edge_list *) xmalloc (sizeof (struct edge_list)); + elist = xmalloc (sizeof (struct edge_list)); elist->num_blocks = block_count; elist->num_edges = num_edges; - elist->index_to_edge = (edge *) xmalloc (sizeof (edge) * num_edges); + elist->index_to_edge = xmalloc (sizeof (edge) * num_edges); num_edges = 0; @@ -497,8 +503,7 @@ create_edge_list () /* This function free's memory associated with an edge list. */ void -free_edge_list (elist) - struct edge_list *elist; +free_edge_list (struct edge_list *elist) { if (elist) { @@ -510,9 +515,7 @@ free_edge_list (elist) /* This function provides debug output showing an edge list. */ void -print_edge_list (f, elist) - FILE *f; - struct edge_list *elist; +print_edge_list (FILE *f, struct edge_list *elist) { int x; @@ -539,9 +542,7 @@ print_edge_list (f, elist) extra edges. */ void -verify_edge_list (f, elist) - FILE *f; - struct edge_list *elist; +verify_edge_list (FILE *f, struct edge_list *elist) { int pred, succ, index; edge e; @@ -606,9 +607,7 @@ verify_edge_list (f, elist) a specified predecessor and successor. */ int -find_edge_index (edge_list, pred, succ) - struct edge_list *edge_list; - basic_block pred, succ; +find_edge_index (struct edge_list *edge_list, basic_block pred, basic_block succ) { int x; @@ -623,10 +622,7 @@ find_edge_index (edge_list, pred, succ) /* Dump the list of basic blocks in the bitmap NODES. */ void -flow_nodes_print (str, nodes, file) - const char *str; - const sbitmap nodes; - FILE *file; +flow_nodes_print (const char *str, const sbitmap nodes, FILE *file) { int node; @@ -641,11 +637,7 @@ flow_nodes_print (str, nodes, file) /* Dump the list of edges in the array EDGE_LIST. */ void -flow_edge_list_print (str, edge_list, num_edges, file) - const char *str; - const edge *edge_list; - int num_edges; - FILE *file; +flow_edge_list_print (const char *str, const edge *edge_list, int num_edges, FILE *file) { int i; @@ -666,8 +658,7 @@ flow_edge_list_print (str, edge_list, num_edges, file) list it is in. */ static void -remove_fake_successors (bb) - basic_block bb; +remove_fake_successors (basic_block bb) { edge e; @@ -686,7 +677,7 @@ remove_fake_successors (bb) fake predecessors. */ void -remove_fake_edges () +remove_fake_edges (void) { basic_block bb; @@ -699,7 +690,7 @@ remove_fake_edges () edges to exist. */ void -add_noreturn_fake_exit_edges () +add_noreturn_fake_exit_edges (void) { basic_block bb; @@ -720,7 +711,7 @@ add_noreturn_fake_exit_edges () nodes not reachable from the exit block. */ void -connect_infinite_loops_to_exit () +connect_infinite_loops_to_exit (void) { basic_block unvisited_block; struct depth_first_search_dsS dfs_ds; @@ -745,11 +736,10 @@ connect_infinite_loops_to_exit () return; } -/* Compute reverse top sort order */ +/* Compute reverse top sort order. */ void -flow_reverse_top_sort_order_compute (rts_order) - int *rts_order; +flow_reverse_top_sort_order_compute (int *rts_order) { edge *stack; int sp; @@ -757,7 +747,7 @@ flow_reverse_top_sort_order_compute (rts_order) sbitmap visited; /* Allocate stack for back-tracking up CFG. */ - stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge)); + stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge)); sp = 0; /* Allocate bitmap to track nodes that have been visited. */ @@ -817,9 +807,7 @@ flow_reverse_top_sort_order_compute (rts_order) possible. */ int -flow_depth_first_order_compute (dfs_order, rc_order) - int *dfs_order; - int *rc_order; +flow_depth_first_order_compute (int *dfs_order, int *rc_order) { edge *stack; int sp; @@ -828,7 +816,7 @@ flow_depth_first_order_compute (dfs_order, rc_order) sbitmap visited; /* Allocate stack for back-tracking up CFG. */ - stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge)); + stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge)); sp = 0; /* Allocate bitmap to track nodes that have been visited. */ @@ -920,8 +908,7 @@ struct dfst_node 2) Walking the resulting tree from right to left. */ void -flow_preorder_transversal_compute (pot_order) - int *pot_order; +flow_preorder_transversal_compute (int *pot_order) { edge e; edge *stack; @@ -934,12 +921,11 @@ flow_preorder_transversal_compute (pot_order) basic_block bb; /* Allocate stack for back-tracking up CFG. */ - stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge)); + stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge)); sp = 0; /* Allocate the tree. */ - dfst = (struct dfst_node *) xcalloc (last_basic_block, - sizeof (struct dfst_node)); + dfst = xcalloc (last_basic_block, sizeof (struct dfst_node)); FOR_EACH_BB (bb) { @@ -949,9 +935,7 @@ flow_preorder_transversal_compute (pot_order) dfst[bb->index].node = (max_successors - ? (struct dfst_node **) xcalloc (max_successors, - sizeof (struct dfst_node *)) - : NULL); + ? xcalloc (max_successors, sizeof (struct dfst_node *)) : NULL); } /* Allocate bitmap to track nodes that have been visited. */ @@ -1060,12 +1044,11 @@ flow_preorder_transversal_compute (pot_order) element on the stack. */ static void -flow_dfs_compute_reverse_init (data) - depth_first_search_ds data; +flow_dfs_compute_reverse_init (depth_first_search_ds data) { /* Allocate stack for back-tracking up CFG. */ - data->stack = (basic_block *) xmalloc ((n_basic_blocks - (INVALID_BLOCK + 1)) - * sizeof (basic_block)); + data->stack = xmalloc ((n_basic_blocks - (INVALID_BLOCK + 1)) + * sizeof (basic_block)); data->sp = 0; /* Allocate bitmap to track nodes that have been visited. */ @@ -1082,9 +1065,7 @@ flow_dfs_compute_reverse_init (data) block. */ static void -flow_dfs_compute_reverse_add_bb (data, bb) - depth_first_search_ds data; - basic_block bb; +flow_dfs_compute_reverse_add_bb (depth_first_search_ds data, basic_block bb) { data->stack[data->sp++] = bb; SET_BIT (data->visited_blocks, bb->index - (INVALID_BLOCK + 1)); @@ -1096,8 +1077,7 @@ flow_dfs_compute_reverse_add_bb (data, bb) available. */ static basic_block -flow_dfs_compute_reverse_execute (data) - depth_first_search_ds data; +flow_dfs_compute_reverse_execute (depth_first_search_ds data) { basic_block bb; edge e; @@ -1125,8 +1105,7 @@ flow_dfs_compute_reverse_execute (data) reverse graph. */ static void -flow_dfs_compute_reverse_finish (data) - depth_first_search_ds data; +flow_dfs_compute_reverse_finish (depth_first_search_ds data) { free (data->stack); sbitmap_free (data->visited_blocks); @@ -1136,13 +1115,9 @@ flow_dfs_compute_reverse_finish (data) if REVERSE, go against direction of edges. Returns number of blocks found and their list in RSLT. RSLT can contain at most RSLT_MAX items. */ int -dfs_enumerate_from (bb, reverse, predicate, rslt, rslt_max, data) - basic_block bb; - int reverse; - bool (*predicate) PARAMS ((basic_block, void *)); - basic_block *rslt; - int rslt_max; - void *data; +dfs_enumerate_from (basic_block bb, int reverse, + bool (*predicate) (basic_block, void *), + basic_block *rslt, int rslt_max, void *data) { basic_block *st, lbb; int sp = 0, tv = 0; -- cgit v1.1