From b08cd5843569977ca1c079e1dd269a55fdaa2995 Mon Sep 17 00:00:00 2001 From: hubicka Date: Mon, 23 Jul 2001 14:08:12 +0000 Subject: [PATCH] * basic-block.h (find_sub_basic_block): Declare. * flow.c (make_edges): New arguments MIN and MAX; (find_sub_basic_blocks): Revamp to use make_edges and purge_dead_edges. (find_basic_blocks): Update call of find_sub_basic_block. * recog.c (split_all_insns): Always expect CFG to be consistent; call find_sub_basic_blocks in case something has changed. * toplev.c (rest_of_compilation): Always call split_all_insns once CFG has been built. * basic-block.h (delete_noop_moves): Declare. * combine.c (combine_instructions): Call it. (recog_for_combine): Tolerate noop moves (distribute_notes): Force refresh when register dies at noop move. * flow.c (delete_noop_moves): Use BB structure; delete JUMP insns too. (life_analysis): Update delete_noop_moves call. (set_noop_p): Move too ... * rtlanal.c (noop_move_p): ... here. * rtl.h (noop_move_p): Declare. * basic-block.h (purge_all_dead_edges, purge_dead_edges): New functions. * toplev.c (rest_of_compilation): Conditionally call purge_all_dead_edges after combine. * gcse.c (cprop_cc0_jump, cprop_insn): New argument "basic_block". (cprop_jump): Likewise; call purge_dead_edges if substitution suceeded. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44267 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 30 ++++++++ gcc/basic-block.h | 4 + gcc/combine.c | 30 ++++++-- gcc/flow.c | 220 ++++++++++++++++++++++++++++++------------------------ gcc/gcse.c | 22 +++--- gcc/recog.c | 27 +++---- gcc/rtl.h | 1 + gcc/rtlanal.c | 39 ++++++++++ gcc/toplev.c | 17 ++--- 9 files changed, 247 insertions(+), 143 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b400b34..5de1093 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,33 @@ +Mon Jul 23 16:03:19 CEST 2001 Jan Hubicka + + * basic-block.h (find_sub_basic_block): Declare. + * flow.c (make_edges): New arguments MIN and MAX; + (find_sub_basic_blocks): Revamp to use make_edges + and purge_dead_edges. + (find_basic_blocks): Update call of find_sub_basic_block. + + * recog.c (split_all_insns): Always expect CFG to be consistent; + call find_sub_basic_blocks in case something has changed. + * toplev.c (rest_of_compilation): Always call split_all_insns once CFG + has been built. + + * basic-block.h (delete_noop_moves): Declare. + * combine.c (combine_instructions): Call it. + (recog_for_combine): Tolerate noop moves + (distribute_notes): Force refresh when register dies at noop move. + * flow.c (delete_noop_moves): Use BB structure; delete JUMP insns + too. + (life_analysis): Update delete_noop_moves call. + (set_noop_p): Move too ... + * rtlanal.c (noop_move_p): ... here. + * rtl.h (noop_move_p): Declare. + + * basic-block.h (purge_all_dead_edges, purge_dead_edges): New functions. + * toplev.c (rest_of_compilation): Conditionally call purge_all_dead_edges + after combine. + * gcse.c (cprop_cc0_jump, cprop_insn): New argument "basic_block". + (cprop_jump): Likewise; call purge_dead_edges if substitution suceeded. + 2001-07-23 Hans-Peter Nilsson * reload.c (push_reload): Fix typo in comment. diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 6a6039e..b6e8c11 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -597,10 +597,14 @@ extern void debug_regset PARAMS ((regset)); extern void allocate_reg_life_data PARAMS ((void)); extern void allocate_bb_life_data PARAMS ((void)); extern void find_unreachable_blocks PARAMS ((void)); +extern void delete_noop_moves PARAMS ((rtx)); extern basic_block redirect_edge_and_branch_force PARAMS ((edge, basic_block)); extern bool redirect_edge_and_branch PARAMS ((edge, basic_block)); extern rtx block_label PARAMS ((basic_block)); extern bool forwarder_block_p PARAMS ((basic_block)); +extern void purge_all_dead_edges PARAMS ((void)); +extern void purge_dead_edges PARAMS ((basic_block)); +extern void find_sub_basic_blocks PARAMS ((basic_block)); /* This function is always defined so it can be called from the diff --git a/gcc/combine.c b/gcc/combine.c index 724e9ef..633d0ac 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -713,6 +713,8 @@ combine_instructions (f, nregs) } } + delete_noop_moves (f); + if (need_refresh) { compute_bb_for_insn (get_max_uid ()); @@ -9598,8 +9600,12 @@ recog_for_combine (pnewpat, insn, pnotes) old_notes = REG_NOTES (insn); REG_NOTES (insn) = 0; - /* Is the result of combination a valid instruction? */ - insn_code_number = recog (pat, insn, &num_clobbers_to_add); + /* Is the result of combination a valid instruction? + Recognize all noop sets, these will be killed by followup pass. */ + if (GET_CODE (pat) == SET && set_noop_p (pat)) + insn_code_number = INT_MAX; + else + insn_code_number = recog (pat, insn, &num_clobbers_to_add); /* If it isn't, there is the possibility that we previously had an insn that clobbered some register as a side effect, but the combined @@ -9624,7 +9630,11 @@ recog_for_combine (pnewpat, insn, pnotes) if (pos == 1) pat = XVECEXP (pat, 0, 0); - insn_code_number = recog (pat, insn, &num_clobbers_to_add); + /* Recognize all noop sets, these will be killed by followup pass. */ + if (GET_CODE (pat) == SET && set_noop_p (pat)) + insn_code_number = INT_MAX; + else + insn_code_number = recog (pat, insn, &num_clobbers_to_add); } REG_NOTES (insn) = old_notes; @@ -12325,10 +12335,16 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) is still a REG_DEAD note, but we have hit the beginning of the block. If the existing life info says the reg was dead, there's nothing left to do. Otherwise, we'll - need to do a global life update after combine. */ - if (REG_NOTE_KIND (note) == REG_DEAD && place == 0 - && REGNO_REG_SET_P (bb->global_live_at_start, - REGNO (XEXP (note, 0)))) + need to do a global life update after combine. + + Similary we need to update in case insn is an dead set + we are about to remove soon. + */ + if (REG_NOTE_KIND (note) == REG_DEAD + && ((place && noop_move_p (place)) + || (place == 0 + && REGNO_REG_SET_P (bb->global_live_at_start, + REGNO (XEXP (note, 0)))))) { SET_BIT (refresh_blocks, this_basic_block); need_refresh = 1; diff --git a/gcc/flow.c b/gcc/flow.c index 8d795a7..ac5cee5 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -374,7 +374,7 @@ static int flow_find_cross_jump PARAMS ((int, basic_block, basic_block, static int count_basic_blocks PARAMS ((rtx)); static void find_basic_blocks_1 PARAMS ((rtx)); static rtx find_label_refs PARAMS ((rtx, rtx)); -static void make_edges PARAMS ((rtx)); +static void make_edges PARAMS ((rtx, int, int)); static void make_label_edge PARAMS ((sbitmap *, basic_block, rtx, int)); static void make_eh_edge PARAMS ((sbitmap *, basic_block, rtx)); @@ -401,8 +401,6 @@ static void tidy_fallthru_edges PARAMS ((void)); static int verify_wide_reg_1 PARAMS ((rtx *, void *)); static void verify_wide_reg PARAMS ((int, rtx, rtx)); static void verify_local_live_at_start PARAMS ((regset, basic_block)); -static int noop_move_p PARAMS ((rtx)); -static void delete_noop_moves PARAMS ((rtx)); static void notice_stack_pointer_modification_1 PARAMS ((rtx, rtx, void *)); static void notice_stack_pointer_modification PARAMS ((rtx)); static void mark_reg PARAMS ((rtx, void *)); @@ -483,7 +481,6 @@ static void flow_loop_tree_node_add PARAMS ((struct loop *, struct loop *)); static void flow_loops_tree_build PARAMS ((struct loops *)); static int flow_loop_level_compute PARAMS ((struct loop *, int)); static int flow_loops_level_compute PARAMS ((struct loops *)); -static void find_sub_basic_blocks PARAMS ((basic_block)); /* Find basic blocks of the current function. F is the first insn of the function and NREGS the number of register @@ -543,7 +540,7 @@ find_basic_blocks (f, nregs, file) compute_bb_for_insn (max_uid); /* Discover the edges of our cfg. */ - make_edges (label_value_list); + make_edges (label_value_list, 0, n_basic_blocks - 1); /* Do very simple cleanup now, for the benefit of code that runs between here and cleanup_cfg, e.g. thread_prologue_and_epilogue_insns. */ @@ -705,39 +702,30 @@ find_label_refs (f, lvl) /* Assume that someone emitted code with control flow instructions to the basic block. Update the data structure. */ -static void +void find_sub_basic_blocks (bb) basic_block bb; { - rtx first_insn = bb->head, insn; + rtx insn = bb->head; rtx end = bb->end; - edge succ_list = bb->succ; rtx jump_insn = NULL_RTX; int created = 0; int barrier = 0; edge falltru = 0; - basic_block first_bb = bb, last_bb; - int i; + basic_block first_bb = bb; + + if (insn == bb->end) + return; - if (GET_CODE (first_insn) == LABEL_REF) - first_insn = NEXT_INSN (first_insn); - first_insn = NEXT_INSN (first_insn); - bb->succ = NULL; + if (GET_CODE (insn) == CODE_LABEL) + insn = NEXT_INSN (insn); - insn = first_insn; /* Scan insn chain and try to find new basic block boundaries. */ - while (insn != end) + while (1) { enum rtx_code code = GET_CODE (insn); switch (code) { - case JUMP_INSN: - /* We need some special care for those expressions. */ - if (GET_CODE (PATTERN (insn)) == ADDR_VEC - || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) - abort(); - jump_insn = insn; - break; case BARRIER: if (!jump_insn) abort (); @@ -749,8 +737,7 @@ find_sub_basic_blocks (bb) if (jump_insn) bb->end = jump_insn; bb = falltru->dest; - if (barrier) - remove_edge (falltru); + remove_edge (falltru); barrier = 0; jump_insn = 0; created = 1; @@ -758,6 +745,7 @@ find_sub_basic_blocks (bb) make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0); break; case INSN: + case JUMP_INSN: /* In case we've previously split insn on the JUMP_INSN, move the block header to proper place. */ if (jump_insn) @@ -765,42 +753,39 @@ find_sub_basic_blocks (bb) falltru = split_block (bb, PREV_INSN (insn)); bb->end = jump_insn; bb = falltru->dest; - if (barrier) - abort (); + remove_edge (falltru); jump_insn = 0; } + /* We need some special care for those expressions. */ + if (GET_CODE (insn) == JUMP_INSN) + { + if (GET_CODE (PATTERN (insn)) == ADDR_VEC + || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) + abort(); + jump_insn = insn; + } + break; default: break; } + if (insn == end) + break; insn = NEXT_INSN (insn); } - /* Last basic block must end in the original BB end. */ - if (jump_insn) - abort (); - /* Wire in the original edges for last basic block. */ - if (created) - { - bb->succ = succ_list; - while (succ_list) - succ_list->src = bb, succ_list = succ_list->succ_next; - } - else - bb->succ = succ_list; + /* In case we've got barrier at the end of new insn stream, put it + outside basic block. */ + if (GET_CODE (bb->end) == BARRIER) + bb->end = PREV_INSN (bb->end); + + /* We've possibly replaced the conditional jump by conditional jump + followed by cleanup at fallthru edge, so the outgoing edges may + be dead. */ + purge_dead_edges (bb); /* Now re-scan and wire in all edges. This expect simple (conditional) jumps at the end of each new basic blocks. */ - last_bb = bb; - for (i = first_bb->index; i < last_bb->index; i++) - { - bb = BASIC_BLOCK (i); - if (GET_CODE (bb->end) == JUMP_INSN) - { - mark_jump_label (PATTERN (bb->end), bb->end, 0); - make_label_edge (NULL, bb, JUMP_LABEL (bb->end), 0); - } - insn = NEXT_INSN (insn); - } + make_edges (NULL, first_bb->index, bb->index - 1); } /* Find all basic blocks of the function whose first insn is F. @@ -1166,7 +1151,7 @@ clear_edges () n_edges = 0; } -/* Identify the edges between basic blocks. +/* Identify the edges between basic blocks MIN to MAX. NONLOCAL_LABEL_LIST is a list of non-local labels in the function. Blocks that are otherwise unreachable may be reachable with a non-local goto. @@ -1175,8 +1160,9 @@ clear_edges () the list of exception regions active at the end of the basic block. */ static void -make_edges (label_value_list) +make_edges (label_value_list, min, max) rtx label_value_list; + int min, max; { int i; sbitmap *edge_cache = NULL; @@ -1196,7 +1182,7 @@ make_edges (label_value_list) /* By nature of the way these get numbered, block 0 is always the entry. */ make_edge (edge_cache, ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU); - for (i = 0; i < n_basic_blocks; ++i) + for (i = min; i <= max; ++i) { basic_block bb = BASIC_BLOCK (i); rtx insn, x; @@ -4317,58 +4303,28 @@ free_basic_block_vars (keep_head_end_p) } } -/* Return nonzero if an insn consists only of SETs, each of which only sets a - value to itself. */ - -static int -noop_move_p (insn) - rtx insn; -{ - rtx pat = PATTERN (insn); - - /* Insns carrying these notes are useful later on. */ - if (find_reg_note (insn, REG_EQUAL, NULL_RTX)) - return 0; - - if (GET_CODE (pat) == SET && set_noop_p (pat)) - return 1; - - if (GET_CODE (pat) == PARALLEL) - { - int i; - /* If nothing but SETs of registers to themselves, - this insn can also be deleted. */ - for (i = 0; i < XVECLEN (pat, 0); i++) - { - rtx tem = XVECEXP (pat, 0, i); - - if (GET_CODE (tem) == USE - || GET_CODE (tem) == CLOBBER) - continue; - - if (GET_CODE (tem) != SET || ! set_noop_p (tem)) - return 0; - } - - return 1; - } - return 0; -} - /* Delete any insns that copy a register to itself. */ -static void +void delete_noop_moves (f) - rtx f; + rtx f ATTRIBUTE_UNUSED; { - rtx insn; - for (insn = f; insn; insn = NEXT_INSN (insn)) + int i; + rtx insn, next; + basic_block bb; + + for (i = 0; i < n_basic_blocks; i++) { - if (GET_CODE (insn) == INSN && noop_move_p (insn)) + bb = BASIC_BLOCK (i); + for (insn = bb->head; insn != NEXT_INSN (bb->end); insn = next) { - PUT_CODE (insn, NOTE); - NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; - NOTE_SOURCE_FILE (insn) = 0; + next = NEXT_INSN (insn); + if (INSN_P (insn) && noop_move_p (insn)) + { + if (insn == bb->end) + bb->end = PREV_INSN (insn); + flow_delete_insn (insn); + } } } } @@ -9814,3 +9770,69 @@ init_flow () flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0); } } + +/* Assume that the preceeding pass has possibly eliminated jump instructions + or converted the unconditional jumps. Eliminate the edges from CFG. */ + +void +purge_dead_edges (bb) + basic_block bb; +{ + edge e, next; + rtx insn = bb->end; + if (GET_CODE (insn) == JUMP_INSN && !simplejump_p (insn)) + return; + if (GET_CODE (insn) == JUMP_INSN) + { + for (e = bb->succ; e; e = next) + { + next = e->succ_next; + if (e->dest == EXIT_BLOCK_PTR || e->dest->head != JUMP_LABEL (insn)) + remove_edge (e); + } + if (bb->succ && bb->succ->succ_next) + abort (); + if (!bb->succ) + return; + bb->succ->probability = REG_BR_PROB_BASE; + bb->succ->count = bb->count; + + if (rtl_dump_file) + fprintf (rtl_dump_file, "Purged edges from bb %i\n", bb->index); + return; + } + /* If we don't see a jump insn, we don't know exactly why the block would + have been broken at this point. Look for a simple, non-fallthru edge, + as these are only created by conditional branches. If we find such an + edge we know that there used to be a jump here and can then safely + remove all non-fallthru edges. */ + for (e = bb->succ; e && (e->flags & (EDGE_COMPLEX | EDGE_FALLTHRU)); + e = e->succ_next); + if (!e) + return; + for (e = bb->succ; e; e = next) + { + next = e->succ_next; + if (!(e->flags & EDGE_FALLTHRU)) + remove_edge (e); + } + if (!bb->succ || bb->succ->succ_next) + abort (); + bb->succ->probability = REG_BR_PROB_BASE; + bb->succ->count = bb->count; + + if (rtl_dump_file) + fprintf (rtl_dump_file, "Purged non-fallthru edges from bb %i\n", + bb->index); + return; +} + +/* Search all basic blocks for potentionally dead edges and purge them. */ + +void +purge_all_dead_edges () +{ + int i; + for (i = 0; i < n_basic_blocks; i++) + purge_dead_edges (BASIC_BLOCK (i)); +} diff --git a/gcc/gcse.c b/gcc/gcse.c index d9f106c..7592204 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -605,14 +605,14 @@ static void compute_cprop_data PARAMS ((void)); static void find_used_regs PARAMS ((rtx *, void *)); static int try_replace_reg PARAMS ((rtx, rtx, rtx)); static struct expr *find_avail_set PARAMS ((int, rtx)); -static int cprop_jump PARAMS ((rtx, rtx, rtx)); +static int cprop_jump PARAMS ((basic_block, rtx, rtx, rtx)); #ifdef HAVE_cc0 -static int cprop_cc0_jump PARAMS ((rtx, struct reg_use *, rtx)); +static int cprop_cc0_jump PARAMS ((basic_block, rtx, struct reg_use *, rtx)); #endif static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *)); static int load_killed_in_block_p PARAMS ((basic_block, int, rtx, int)); static void canon_list_insert PARAMS ((rtx, rtx, void *)); -static int cprop_insn PARAMS ((rtx, int)); +static int cprop_insn PARAMS ((basic_block, rtx, int)); static int cprop PARAMS ((int)); static int one_cprop_pass PARAMS ((int, int)); static void alloc_pre_mem PARAMS ((int, int)); @@ -4015,10 +4015,11 @@ find_avail_set (regno, insn) nonzero if a change was made. We know INSN has just a SET. */ static int -cprop_jump (insn, from, src) +cprop_jump (bb, insn, from, src) rtx insn; rtx from; rtx src; + basic_block bb; { rtx set = PATTERN (insn); rtx new = simplify_replace_rtx (SET_SRC (set), from, src); @@ -4059,6 +4060,7 @@ cprop_jump (insn, from, src) print_rtl (gcse_file, src); fprintf (gcse_file, "\n"); } + purge_dead_edges (bb); return 1; } @@ -4072,7 +4074,8 @@ cprop_jump (insn, from, src) Returns nonzero if a change was made. */ static int -cprop_cc0_jump (insn, reg_used, src) +cprop_cc0_jump (bb, insn, reg_used, src) + basic_block bb; rtx insn; struct reg_use *reg_used; rtx src; @@ -4083,7 +4086,7 @@ cprop_cc0_jump (insn, reg_used, src) rtx new_src = simplify_replace_rtx (SET_SRC (PATTERN (insn)), reg_used->reg_rtx, src); - if (! cprop_jump (jump, cc0_rtx, new_src)) + if (! cprop_jump (bb, jump, cc0_rtx, new_src)) return 0; /* If we succeeded, delete the cc0 setter. */ @@ -4099,7 +4102,8 @@ cprop_cc0_jump (insn, reg_used, src) The result is non-zero if a change was made. */ static int -cprop_insn (insn, alter_jumps) +cprop_insn (bb, insn, alter_jumps) + basic_block bb; rtx insn; int alter_jumps; { @@ -4183,7 +4187,7 @@ cprop_insn (insn, alter_jumps) && GET_CODE (insn) == JUMP_INSN && condjump_p (insn) && ! simplejump_p (insn)) - changed |= cprop_jump (insn, reg_used->reg_rtx, src); + changed |= cprop_jump (bb, insn, reg_used->reg_rtx, src); #ifdef HAVE_cc0 /* Similar code for machines that use a pair of CC0 setter and @@ -4252,7 +4256,7 @@ cprop (alter_jumps) insn = NEXT_INSN (insn)) if (INSN_P (insn)) { - changed |= cprop_insn (insn, alter_jumps); + changed |= cprop_insn (BASIC_BLOCK (bb), insn, alter_jumps); /* Keep track of everything modified by this insn. */ /* ??? Need to be careful w.r.t. mods done to INSN. Don't diff --git a/gcc/recog.c b/gcc/recog.c index ef30528..b4b9b9d 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -2725,22 +2725,6 @@ split_all_insns (upd_life) int changed; int i; - if (!upd_life) - { - rtx next, insn; - - for (insn = get_insns (); insn ; insn = next) - { - rtx last; - - /* Can't use `next_real_insn' because that might go across - CODE_LABELS and short-out basic blocks. */ - next = NEXT_INSN (insn); - last = split_insn (insn); - } - return; - } - blocks = sbitmap_alloc (n_basic_blocks); sbitmap_zero (blocks); changed = 0; @@ -2775,12 +2759,21 @@ split_all_insns (upd_life) abort (); } - if (changed && upd_life) + if (changed) { compute_bb_for_insn (get_max_uid ()); + for (i = 0; i < n_basic_blocks; i++) + find_sub_basic_blocks (BASIC_BLOCK (i)); + } + + if (changed && upd_life) + { count_or_remove_death_notes (blocks, 1); update_life_info (blocks, UPDATE_LIFE_LOCAL, PROP_DEATH_NOTES); } +#ifdef ENABLE_CHECKING + verify_flow_info (); +#endif sbitmap_free (blocks); } diff --git a/gcc/rtl.h b/gcc/rtl.h index e9227b1..278e9d0 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1387,6 +1387,7 @@ extern int reg_set_p PARAMS ((rtx, rtx)); extern rtx single_set_2 PARAMS ((rtx, rtx)); extern int multiple_sets PARAMS ((rtx)); extern int set_noop_p PARAMS ((rtx)); +extern int noop_move_p PARAMS ((rtx)); extern rtx find_last_value PARAMS ((rtx, rtx *, rtx, int)); extern int refers_to_regno_p PARAMS ((unsigned int, unsigned int, rtx, rtx *)); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 2f9696c..c9152ab 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -1020,6 +1020,45 @@ set_noop_p (set) return (GET_CODE (src) == REG && GET_CODE (dst) == REG && REGNO (src) == REGNO (dst)); } + +/* Return nonzero if an insn consists only of SETs, each of which only sets a + value to itself. */ + +int +noop_move_p (insn) + rtx insn; +{ + rtx pat = PATTERN (insn); + + /* Insns carrying these notes are useful later on. */ + if (find_reg_note (insn, REG_EQUAL, NULL_RTX)) + return 0; + + if (GET_CODE (pat) == SET && set_noop_p (pat)) + return 1; + + if (GET_CODE (pat) == PARALLEL) + { + int i; + /* If nothing but SETs of registers to themselves, + this insn can also be deleted. */ + for (i = 0; i < XVECLEN (pat, 0); i++) + { + rtx tem = XVECEXP (pat, 0, i); + + if (GET_CODE (tem) == USE + || GET_CODE (tem) == CLOBBER) + continue; + + if (GET_CODE (tem) != SET || ! set_noop_p (tem)) + return 0; + } + + return 1; + } + return 0; +} + /* Return the last thing that X was assigned from before *PINSN. If VALID_TO is not NULL_RTX then verify that the object is not modified up to VALID_TO. diff --git a/gcc/toplev.c b/gcc/toplev.c index 13a5d05..613ef0d 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -3265,7 +3265,7 @@ rest_of_compilation (decl) timevar_pop (TV_JUMP); timevar_push (TV_FLOW); - find_basic_blocks (insns, max_reg_num (), rtl_dump_file); + purge_all_dead_edges (); cleanup_cfg (CLEANUP_EXPENSIVE); /* Blimey. We've got to have the CFG up to date for the call to @@ -3441,16 +3441,6 @@ rest_of_compilation (decl) timevar_pop (TV_RELOAD_CSE_REGS); } - /* If optimizing, then go ahead and split insns now since we are about - to recompute flow information anyway. */ - if (optimize > 0) - { - int old_labelnum = max_label_num (); - - split_all_insns (0); - rebuild_label_notes_after_reload |= old_labelnum != max_label_num (); - } - /* Register allocation and reloading may have turned an indirect jump into a direct jump. If so, we must rebuild the JUMP_LABEL fields of jumping instructions. */ @@ -3470,6 +3460,11 @@ rest_of_compilation (decl) open_dump_file (DFI_flow2, decl); find_basic_blocks (insns, max_reg_num (), rtl_dump_file); + + /* If optimizing, then go ahead and split insns now. */ + if (optimize > 0) + split_all_insns (0); + cleanup_cfg (0); /* On some machines, the prologue and epilogue code, or parts thereof, -- 2.7.4