diff options
author | Daniel Berlin <dberlin@gcc.gnu.org> | 2007-06-11 18:02:15 +0000 |
---|---|---|
committer | Daniel Berlin <dberlin@gcc.gnu.org> | 2007-06-11 18:02:15 +0000 |
commit | 6fb5fa3cbc0d78cf9f4ff7cac5e1d8af1e65c5bb (patch) | |
tree | fdb9e9f8a0700a2713dc690fed1a2cf20dae8392 /gcc/gcse.c | |
parent | a91d32a4a65d54cccf639a1541417e39cb7b7deb (diff) | |
download | gcc-6fb5fa3cbc0d78cf9f4ff7cac5e1d8af1e65c5bb.zip gcc-6fb5fa3cbc0d78cf9f4ff7cac5e1d8af1e65c5bb.tar.gz gcc-6fb5fa3cbc0d78cf9f4ff7cac5e1d8af1e65c5bb.tar.bz2 |
Merge dataflow branch into mainline
From-SVN: r125624
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r-- | gcc/gcse.c | 78 |
1 files changed, 42 insertions, 36 deletions
@@ -171,6 +171,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "timevar.h" #include "tree-pass.h" #include "hashtab.h" +#include "df.h" +#include "dbgcnt.h" /* Propagate flow information through back edges and thus enable PRE's moving loop invariant calculations out of loops. @@ -584,7 +586,7 @@ static void free_pre_mem (void); static void compute_pre_data (void); static int pre_expr_reaches_here_p (basic_block, struct expr *, basic_block); -static void insert_insn_end_bb (struct expr *, basic_block, int); +static void insert_insn_end_basic_block (struct expr *, basic_block, int); static void pre_insert_copy_insn (struct expr *, rtx); static void pre_insert_copies (void); static int pre_delete (void); @@ -628,7 +630,7 @@ static bool store_killed_in_insn (rtx, rtx, rtx, int); static bool store_killed_after (rtx, rtx, rtx, basic_block, int *, rtx *); static bool store_killed_before (rtx, rtx, rtx, basic_block, int *); static void build_store_vectors (void); -static void insert_insn_start_bb (rtx, basic_block); +static void insert_insn_start_basic_block (rtx, basic_block); static int insert_store (struct ls_expr *, edge); static void remove_reachable_equiv_notes (basic_block, struct ls_expr *); static void replace_store_insn (rtx, rtx, basic_block, struct ls_expr *); @@ -673,6 +675,9 @@ gcse_main (rtx f ATTRIBUTE_UNUSED) successors and predecessors. */ max_gcse_regno = max_reg_num (); + df_note_add_problem (); + df_analyze (); + if (dump_file) dump_flow_info (dump_file, dump_flags); @@ -806,7 +811,6 @@ gcse_main (rtx f ATTRIBUTE_UNUSED) /* We are finished with alias. */ end_alias_analysis (); - allocate_reg_info (max_reg_num (), FALSE, FALSE); if (!optimize_size && flag_gcse_sm) { @@ -1728,8 +1732,11 @@ hash_scan_set (rtx pat, rtx insn, struct hash_table *table) { /* An expression is not anticipatable if its operands are modified before this insn or if this is not the only SET in - this insn. */ - int antic_p = oprs_anticipatable_p (src, insn) && single_set (insn); + this insn. The latter condition does not have to mean that + SRC itself is not anticipatable, but we just will not be + able to handle code motion of insns with multiple sets. */ + int antic_p = oprs_anticipatable_p (src, insn) + && !multiple_sets (insn); /* An expression is not available if its operands are subsequently modified, including this insn. It's also not available if this is a branch, because we can't insert @@ -2670,7 +2677,6 @@ try_replace_reg (rtx from, rtx to, rtx insn) if (note != 0 && REG_NOTE_KIND (note) == REG_EQUAL) set_unique_reg_note (insn, REG_EQUAL, simplify_replace_rtx (XEXP (note, 0), from, to)); - if (!success && set && reg_mentioned_p (from, SET_SRC (set))) { /* If above failed and this is a single set, try to simplify the source of @@ -3095,7 +3101,7 @@ do_local_cprop (rtx x, rtx insn, bool alter_jumps, rtx *libcall_sp) /* If we find a case where we can't fix the retval REG_EQUAL notes match the new register, we either have to abandon this replacement or fix delete_trivially_dead_insns to preserve the setting insn, - or make it delete the REG_EUAQL note, and fix up all passes that + or make it delete the REG_EQUAL note, and fix up all passes that require the REG_EQUAL note there. */ bool adjusted; @@ -3164,6 +3170,7 @@ adjust_libcall_notes (rtx oldreg, rtx newval, rtx insn, rtx *libcall_sp) } } XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), oldreg, newval); + df_notes_rescan (end); insn = end; } return true; @@ -3214,12 +3221,14 @@ local_cprop_pass (bool alter_jumps) for (reg_used = ®_use_table[0]; reg_use_count > 0; reg_used++, reg_use_count--) - if (do_local_cprop (reg_used->reg_rtx, insn, alter_jumps, - libcall_sp)) - { - changed = true; - break; - } + { + if (do_local_cprop (reg_used->reg_rtx, insn, alter_jumps, + libcall_sp)) + { + changed = true; + break; + } + } if (INSN_DELETED_P (insn)) break; } @@ -3991,7 +4000,7 @@ process_insert_insn (struct expr *expr) no sense for code hoisting. */ static void -insert_insn_end_bb (struct expr *expr, basic_block bb, int pre) +insert_insn_end_basic_block (struct expr *expr, basic_block bb, int pre) { rtx insn = BB_END (bb); rtx new_insn; @@ -4048,7 +4057,7 @@ insert_insn_end_bb (struct expr *expr, basic_block bb, int pre) } #endif /* FIXME: What if something in cc0/jump uses value set in new insn? */ - new_insn = emit_insn_before_noloc (pat, insn); + new_insn = emit_insn_before_noloc (pat, insn, bb); } /* Likewise if the last insn is a call, as will happen in the presence @@ -4087,10 +4096,10 @@ insert_insn_end_bb (struct expr *expr, basic_block bb, int pre) || NOTE_INSN_BASIC_BLOCK_P (insn)) insn = NEXT_INSN (insn); - new_insn = emit_insn_before_noloc (pat, insn); + new_insn = emit_insn_before_noloc (pat, insn, bb); } else - new_insn = emit_insn_after_noloc (pat, insn); + new_insn = emit_insn_after_noloc (pat, insn, bb); while (1) { @@ -4168,7 +4177,7 @@ pre_edge_insert (struct edge_list *edge_list, struct expr **index_map) now. */ if (eg->flags & EDGE_ABNORMAL) - insert_insn_end_bb (index_map[j], bb, 0); + insert_insn_end_basic_block (index_map[j], bb, 0); else { insn = process_insert_insn (index_map[j]); @@ -4438,7 +4447,8 @@ pre_delete (void) /* We only delete insns that have a single_set. */ if (TEST_BIT (pre_delete_map[bb->index], indx) - && (set = single_set (insn)) != 0) + && (set = single_set (insn)) != 0 + && dbg_cnt (pre_insn)) { /* Create a pseudo-reg to store the result of reaching expressions into. Get the mode for the new pseudo from @@ -4515,7 +4525,6 @@ pre_gcse (void) - we know which insns are redundant when we go to create copies */ changed = pre_delete (); - did_insert = pre_edge_insert (edge_list, index_map); /* In other places with reaching expressions, copy the expression to the @@ -4966,7 +4975,7 @@ hoist_code (void) occr->deleted_p = 1; if (!insn_inserted_p) { - insert_insn_end_bb (index_map[i], bb, 0); + insert_insn_end_basic_block (index_map[i], bb, 0); insn_inserted_p = 1; } } @@ -5437,6 +5446,7 @@ update_ld_motion_stores (struct expr * expr) new = emit_insn_before (copy, insn); record_one_set (REGNO (reg), new); SET_SRC (pat) = reg; + df_insn_rescan (insn); /* un-recognize this pattern since it's probably different now. */ INSN_CODE (insn) = -1; @@ -5553,8 +5563,10 @@ extract_mentioned_regs_helper (rtx x, rtx accum) case PRE_DEC: case PRE_INC: + case PRE_MODIFY: case POST_DEC: case POST_INC: + case POST_MODIFY: /* We do not run this function with arguments having side effects. */ gcc_unreachable (); @@ -6148,7 +6160,7 @@ build_store_vectors (void) the BB_HEAD if needed. */ static void -insert_insn_start_bb (rtx insn, basic_block bb) +insert_insn_start_basic_block (rtx insn, basic_block bb) { /* Insert at start of successor block. */ rtx prev = PREV_INSN (BB_HEAD (bb)); @@ -6164,7 +6176,7 @@ insert_insn_start_bb (rtx insn, basic_block bb) before = NEXT_INSN (before); } - insn = emit_insn_after_noloc (insn, prev); + insn = emit_insn_after_noloc (insn, prev, bb); if (dump_file) { @@ -6221,7 +6233,7 @@ insert_store (struct ls_expr * expr, edge e) int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest); RESET_BIT (pre_insert_map[index], expr->index); } - insert_insn_start_bb (insn, bb); + insert_insn_start_basic_block (insn, bb); return 0; } @@ -6590,7 +6602,6 @@ bypass_jumps (void) /* We are finished with alias. */ end_alias_analysis (); - allocate_reg_info (max_reg_num (), FALSE, FALSE); return changed; } @@ -6645,14 +6656,12 @@ gate_handle_jump_bypass (void) static unsigned int rest_of_handle_jump_bypass (void) { - cleanup_cfg (CLEANUP_EXPENSIVE); - reg_scan (get_insns (), max_reg_num ()); - + delete_unreachable_blocks (); if (bypass_jumps ()) { - rebuild_jump_labels (get_insns ()); - cleanup_cfg (CLEANUP_EXPENSIVE); delete_trivially_dead_insns (get_insns (), max_reg_num ()); + rebuild_jump_labels (get_insns ()); + cleanup_cfg (0); } return 0; } @@ -6688,11 +6697,9 @@ rest_of_handle_gcse (void) { int save_csb, save_cfj; int tem2 = 0, tem; - tem = gcse_main (get_insns ()); - rebuild_jump_labels (get_insns ()); delete_trivially_dead_insns (get_insns (), max_reg_num ()); - + rebuild_jump_labels (get_insns ()); save_csb = flag_cse_skip_blocks; save_cfj = flag_cse_follow_jumps; flag_cse_skip_blocks = flag_cse_follow_jumps = 0; @@ -6702,7 +6709,6 @@ rest_of_handle_gcse (void) if (flag_expensive_optimizations) { timevar_push (TV_CSE); - reg_scan (get_insns (), max_reg_num ()); tem2 = cse_main (get_insns (), max_reg_num ()); purge_all_dead_edges (); delete_trivially_dead_insns (get_insns (), max_reg_num ()); @@ -6716,8 +6722,7 @@ rest_of_handle_gcse (void) { timevar_push (TV_JUMP); rebuild_jump_labels (get_insns ()); - delete_dead_jumptables (); - cleanup_cfg (CLEANUP_EXPENSIVE); + cleanup_cfg (0); timevar_pop (TV_JUMP); } @@ -6739,6 +6744,7 @@ struct tree_opt_pass pass_gcse = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ + TODO_df_finish | TODO_dump_func | TODO_verify_flow | TODO_ggc_collect, /* todo_flags_finish */ 'G' /* letter */ |