diff options
author | Steven Bosscher <steven@gcc.gnu.org> | 2005-04-10 08:45:25 +0000 |
---|---|---|
committer | Steven Bosscher <steven@gcc.gnu.org> | 2005-04-10 08:45:25 +0000 |
commit | eb232f4ef11305a4c2ce9ae0cc7975eafd942153 (patch) | |
tree | 6229d5f39b16f05c907b4000ab97e789cb96da6b /gcc | |
parent | 1d1df67fa98446e02aee8912c2c5fd979b8b2e56 (diff) | |
download | gcc-eb232f4ef11305a4c2ce9ae0cc7975eafd942153.zip gcc-eb232f4ef11305a4c2ce9ae0cc7975eafd942153.tar.gz gcc-eb232f4ef11305a4c2ce9ae0cc7975eafd942153.tar.bz2 |
cselib.c (clear_table): Rename to cselib_clear_table.
* cselib.c (clear_table): Rename to cselib_clear_table.
* cselib.h (cselib_clear_table): Add prototype.
* gcse.c (gcse_main): Make 'f' argument unused.
(alloc_gcse_mem): Do not walk the insn chain, walk the contents
of each basic block instead.
(compute_sets, compute_hash_table_work): Likewise.
(constprop_register): Change int 'alter_jumps' argument to bool.
(do_local_cprop): Likewise.
(local_cprop_pass): Likewise. Also walk basic blocks instead of
the insn chain. Explicitly clear the cselib tables after finishing
one basic block. Make sure there are no unterminated libcall blocks.
Update compute_sets call.
(cprop): Walk basic blocks instead of the insn chain.
(one_cprop_pass, compute_ld_motion_mems, compute_store_table):
Likewise.
(bypass_jumps): Update alloc_gcse_mem, compute_sets, and
one_cprop_pass calls.
From-SVN: r97945
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/cselib.c | 13 | ||||
-rw-r--r-- | gcc/cselib.h | 1 | ||||
-rw-r--r-- | gcc/gcse.c | 189 |
4 files changed, 129 insertions, 98 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd836f3..d6ae852 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2005-04-10 Steven Bosscher <stevenb@suse.de> + + * cselib.c (clear_table): Rename to cselib_clear_table. + * cselib.h (cselib_clear_table): Add prototype. + * gcse.c (gcse_main): Make 'f' argument unused. + (alloc_gcse_mem): Do not walk the insn chain, walk the contents + of each basic block instead. + (compute_sets, compute_hash_table_work): Likewise. + (constprop_register): Change int 'alter_jumps' argument to bool. + (do_local_cprop): Likewise. + (local_cprop_pass): Likewise. Also walk basic blocks instead of + the insn chain. Explicitly clear the cselib tables after finishing + one basic block. Make sure there are no unterminated libcall blocks. + Update compute_sets call. + (cprop): Walk basic blocks instead of the insn chain. + (one_cprop_pass, compute_ld_motion_mems, compute_store_table): + Likewise. + (bypass_jumps): Update alloc_gcse_mem, compute_sets, and + one_cprop_pass calls. + 2005-04-10 Richard Sandiford <rsandifo@redhat.com> * combine.c (combine_simplify_rtx): Remove a transformation that @@ -1201,7 +1221,7 @@ * config/mn10300/mn10300.opt: New file. 2005-04-05 Eric Botcazou <ebotcazou@libertysurf.fr> - Sebastian Pop <sebastian.pop@cri.ensmp.fr> + Sebastian Pop <sebastian.pop@cri.ensmp.fr> PR tree-optimization/19903 * tree-chrec.c (chrec_convert): Return chrec_dont_know for constants @@ -1284,7 +1304,7 @@ CRIS epilogue as RTL. * config/cris/cris.md: Change all 0 in unspec 0 to CRIS_UNSPEC_PLT. - (CRIS_UNSPEC_PLT, CRIS_UNSPEC_FRAME_DEALLOC): New constants. + (CRIS_UNSPEC_PLT, CRIS_UNSPEC_FRAME_DEALLOC): New constants. ("*cris_load_multiple", "cris_frame_deallocated_barrier"): New patterns. ("return"): Change to define_expand. Call cris_expand_return for diff --git a/gcc/cselib.c b/gcc/cselib.c index 351d22d..b7a8963 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -50,7 +50,6 @@ static struct elt_loc_list *new_elt_loc_list (struct elt_loc_list *, rtx); static void unchain_one_value (cselib_val *); static void unchain_one_elt_list (struct elt_list **); static void unchain_one_elt_loc_list (struct elt_loc_list **); -static void clear_table (void); static int discard_useless_locs (void **, void *); static int discard_useless_values (void **, void *); static void remove_useless_values (void); @@ -106,11 +105,11 @@ static unsigned int reg_values_size; #define REG_VALUES(i) reg_values[i] /* The largest number of hard regs used by any entry added to the - REG_VALUES table. Cleared on each clear_table() invocation. */ + REG_VALUES table. Cleared on each cselib_clear_table() invocation. */ static unsigned int max_value_regs; /* Here the set of indices I with REG_VALUES(I) != 0 is saved. This is used - in clear_table() for fast emptying. */ + in cselib_clear_table() for fast emptying. */ static unsigned int *used_regs; static unsigned int n_used_regs; @@ -200,8 +199,8 @@ unchain_one_value (cselib_val *v) initialization. If CLEAR_ALL isn't set, then only clear the entries which are known to have been used. */ -static void -clear_table (void) +void +cselib_clear_table (void) { unsigned int i; @@ -1362,7 +1361,7 @@ cselib_process_insn (rtx insn) { if (find_reg_note (insn, REG_RETVAL, NULL)) cselib_current_insn_in_libcall = false; - clear_table (); + cselib_clear_table (); return; } @@ -1464,7 +1463,7 @@ cselib_finish (void) free_alloc_pool (elt_loc_list_pool); free_alloc_pool (cselib_val_pool); free_alloc_pool (value_pool); - clear_table (); + cselib_clear_table (); htab_delete (hash_table); free (used_regs); used_regs = 0; diff --git a/gcc/cselib.h b/gcc/cselib.h index 1aff251..394e731 100644 --- a/gcc/cselib.h +++ b/gcc/cselib.h @@ -64,6 +64,7 @@ struct elt_list GTY(()) extern cselib_val *cselib_lookup (rtx, enum machine_mode, int); extern void cselib_init (bool record_memory); +extern void cselib_clear_table (void); extern void cselib_finish (void); extern void cselib_process_insn (rtx); extern enum machine_mode cselib_reg_set_mode (rtx); @@ -522,13 +522,13 @@ static void *gmalloc (size_t) ATTRIBUTE_MALLOC; static void *gcalloc (size_t, size_t) ATTRIBUTE_MALLOC; static void *grealloc (void *, size_t); static void *gcse_alloc (unsigned long); -static void alloc_gcse_mem (rtx); +static void alloc_gcse_mem (void); static void free_gcse_mem (void); static void alloc_reg_set_mem (int); static void free_reg_set_mem (void); static void record_one_set (int, rtx); static void record_set_info (rtx, rtx, void *); -static void compute_sets (rtx); +static void compute_sets (void); static void hash_scan_insn (rtx, struct hash_table *, int); static void hash_scan_set (rtx, rtx, struct hash_table *); static void hash_scan_clobber (rtx, rtx, struct hash_table *); @@ -578,8 +578,8 @@ static void canon_list_insert (rtx, rtx, void *); static int cprop_insn (rtx, int); static int cprop (int); static void find_implicit_sets (void); -static int one_cprop_pass (int, int, int); -static bool constprop_register (rtx, rtx, rtx, int); +static int one_cprop_pass (int, bool, bool); +static bool constprop_register (rtx, rtx, rtx, bool); static struct expr *find_bypass_set (int, int); static bool reg_killed_on_edge (rtx, edge); static int bypass_block (basic_block, rtx, rtx); @@ -645,9 +645,9 @@ static void clear_modify_mem_tables (void); static void free_modify_mem_tables (void); static rtx gcse_emit_move_after (rtx, rtx, rtx); static void local_cprop_find_used_regs (rtx *, void *); -static bool do_local_cprop (rtx, rtx, int, rtx*); +static bool do_local_cprop (rtx, rtx, bool, rtx*); static bool adjust_libcall_notes (rtx, rtx, rtx, rtx*); -static void local_cprop_pass (int); +static void local_cprop_pass (bool); static bool is_too_expensive (const char *); @@ -656,7 +656,7 @@ static bool is_too_expensive (const char *); change is mode. */ int -gcse_main (rtx f, FILE *file) +gcse_main (rtx f ATTRIBUTE_UNUSED, FILE *file) { int changed, pass; /* Bytes used at start of pass. */ @@ -704,7 +704,7 @@ gcse_main (rtx f, FILE *file) information about memory sets when we build the hash tables. */ alloc_reg_set_mem (max_gcse_regno); - compute_sets (f); + compute_sets (); pass = 0; initial_bytes_used = bytes_used; @@ -724,12 +724,12 @@ gcse_main (rtx f, FILE *file) /* Each pass may create new registers, so recalculate each time. */ max_gcse_regno = max_reg_num (); - alloc_gcse_mem (f); + alloc_gcse_mem (); /* Don't allow constant propagation to modify jumps during this pass. */ timevar_push (TV_CPROP1); - changed = one_cprop_pass (pass + 1, 0, 0); + changed = one_cprop_pass (pass + 1, false, false); timevar_pop (TV_CPROP1); if (optimize_size) @@ -749,7 +749,7 @@ gcse_main (rtx f, FILE *file) } free_reg_set_mem (); alloc_reg_set_mem (max_reg_num ()); - compute_sets (f); + compute_sets (); run_jump_opt_after_gcse = 1; timevar_pop (TV_PRE); } @@ -771,7 +771,7 @@ gcse_main (rtx f, FILE *file) { timevar_push (TV_HOIST); max_gcse_regno = max_reg_num (); - alloc_gcse_mem (f); + alloc_gcse_mem (); changed |= one_code_hoisting_pass (); free_gcse_mem (); @@ -794,10 +794,10 @@ gcse_main (rtx f, FILE *file) conditional jumps. */ max_gcse_regno = max_reg_num (); - alloc_gcse_mem (f); + alloc_gcse_mem (); /* This time, go ahead and allow cprop to alter jumps. */ timevar_push (TV_CPROP2); - one_cprop_pass (pass + 1, 1, 0); + one_cprop_pass (pass + 1, true, false); timevar_pop (TV_CPROP2); free_gcse_mem (); @@ -923,32 +923,39 @@ gcse_alloc (unsigned long size) This is called at the start of each pass. */ static void -alloc_gcse_mem (rtx f) +alloc_gcse_mem (void) { int i; + basic_block bb; rtx insn; /* Find the largest UID and create a mapping from UIDs to CUIDs. CUIDs are like UIDs except they increase monotonically, have no gaps, - and only apply to real insns. */ + and only apply to real insns. + (Actually, there are gaps, for insn that are not inside a basic block. + but we should never see those anyway, so this is OK.) */ max_uid = get_max_uid (); uid_cuid = gcalloc (max_uid + 1, sizeof (int)); - for (insn = f, i = 0; insn; insn = NEXT_INSN (insn)) - { - if (INSN_P (insn)) - uid_cuid[INSN_UID (insn)] = i++; - else - uid_cuid[INSN_UID (insn)] = i; - } + i = 0; + FOR_EACH_BB (bb) + FOR_BB_INSNS (bb, insn) + { + if (INSN_P (insn)) + uid_cuid[INSN_UID (insn)] = i++; + else + uid_cuid[INSN_UID (insn)] = i; + } /* Create a table mapping cuids to insns. */ max_cuid = i; cuid_insn = gcalloc (max_cuid + 1, sizeof (rtx)); - for (insn = f, i = 0; insn; insn = NEXT_INSN (insn)) - if (INSN_P (insn)) - CUID_INSN (i++) = insn; + i = 0; + FOR_EACH_BB (bb) + FOR_BB_INSNS (bb, insn) + if (INSN_P (insn)) + CUID_INSN (i++) = insn; /* Allocate vars to track sets of regs. */ reg_set_bitmap = BITMAP_ALLOC (NULL); @@ -1141,13 +1148,15 @@ record_set_info (rtx dest, rtx setter ATTRIBUTE_UNUSED, void *data) `reg_set_table' for further documentation. */ static void -compute_sets (rtx f) +compute_sets (void) { + basic_block bb; rtx insn; - for (insn = f; insn != 0; insn = NEXT_INSN (insn)) - if (INSN_P (insn)) - note_stores (PATTERN (insn), record_set_info, insn); + FOR_EACH_BB (bb) + FOR_BB_INSNS (bb, insn) + if (INSN_P (insn)) + note_stores (PATTERN (insn), record_set_info, insn); } /* Hash table support. */ @@ -2038,9 +2047,7 @@ compute_hash_table_work (struct hash_table *table) ??? hard-reg reg_set_in_block computation could be moved to compute_sets since they currently don't change. */ - for (insn = BB_HEAD (current_bb); - insn && insn != NEXT_INSN (BB_END (current_bb)); - insn = NEXT_INSN (insn)) + FOR_BB_INSNS (current_bb, insn) { if (! INSN_P (insn)) continue; @@ -2064,10 +2071,8 @@ compute_hash_table_work (struct hash_table *table) BB_HEAD (current_bb), table); /* The next pass builds the hash table. */ - - for (insn = BB_HEAD (current_bb), in_libcall_block = 0; - insn && insn != NEXT_INSN (BB_END (current_bb)); - insn = NEXT_INSN (insn)) + in_libcall_block = 0; + FOR_BB_INSNS (current_bb, insn) if (INSN_P (insn)) { if (find_reg_note (insn, REG_LIBCALL, NULL_RTX)) @@ -2852,7 +2857,7 @@ cprop_jump (basic_block bb, rtx setcc, rtx jump, rtx from, rtx src) } static bool -constprop_register (rtx insn, rtx from, rtx to, int alter_jumps) +constprop_register (rtx insn, rtx from, rtx to, bool alter_jumps) { rtx sset; @@ -3030,7 +3035,7 @@ local_cprop_find_used_regs (rtx *xptr, void *data) their REG_EQUAL notes need updating. */ static bool -do_local_cprop (rtx x, rtx insn, int alter_jumps, rtx *libcall_sp) +do_local_cprop (rtx x, rtx insn, bool alter_jumps, rtx *libcall_sp) { rtx newreg = NULL, newcnst = NULL; @@ -3148,9 +3153,14 @@ adjust_libcall_notes (rtx oldreg, rtx newval, rtx insn, rtx *libcall_sp) #define MAX_NESTED_LIBCALLS 9 +/* Do local const/copy propagation (i.e. within each basic block). + If ALTER_JUMPS is true, allow propagating into jump insns, which + could modify the CFG. */ + static void -local_cprop_pass (int alter_jumps) +local_cprop_pass (bool alter_jumps) { + basic_block bb; rtx insn; struct reg_use *reg_used; rtx libcall_stack[MAX_NESTED_LIBCALLS + 1], *libcall_sp; @@ -3159,51 +3169,62 @@ local_cprop_pass (int alter_jumps) cselib_init (false); libcall_sp = &libcall_stack[MAX_NESTED_LIBCALLS]; *libcall_sp = 0; - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + FOR_EACH_BB (bb) { - if (INSN_P (insn)) + FOR_BB_INSNS (bb, insn) { - rtx note = find_reg_note (insn, REG_LIBCALL, NULL_RTX); - - if (note) - { - gcc_assert (libcall_sp != libcall_stack); - *--libcall_sp = XEXP (note, 0); - } - note = find_reg_note (insn, REG_RETVAL, NULL_RTX); - if (note) - libcall_sp++; - note = find_reg_equal_equiv_note (insn); - do + if (INSN_P (insn)) { - reg_use_count = 0; - note_uses (&PATTERN (insn), local_cprop_find_used_regs, NULL); - if (note) - local_cprop_find_used_regs (&XEXP (note, 0), NULL); + rtx note = find_reg_note (insn, REG_LIBCALL, NULL_RTX); - 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; + if (note) + { + gcc_assert (libcall_sp != libcall_stack); + *--libcall_sp = XEXP (note, 0); + } + note = find_reg_note (insn, REG_RETVAL, NULL_RTX); + if (note) + libcall_sp++; + note = find_reg_equal_equiv_note (insn); + do + { + reg_use_count = 0; + note_uses (&PATTERN (insn), local_cprop_find_used_regs, + NULL); + if (note) + local_cprop_find_used_regs (&XEXP (note, 0), NULL); + + 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 (INSN_DELETED_P (insn)) break; - } - if (INSN_DELETED_P (insn)) - break; + } + while (reg_use_count); } - while (reg_use_count); + cselib_process_insn (insn); } - cselib_process_insn (insn); + + /* Forget everything at the end of a basic block. Make sure we are + not inside a libcall, they should never cross basic blocks. */ + cselib_clear_table (); + gcc_assert (libcall_sp == &libcall_stack[MAX_NESTED_LIBCALLS]); } + cselib_finish (); + /* Global analysis may get into infinite loops for unreachable blocks. */ if (changed && alter_jumps) { delete_unreachable_blocks (); free_reg_set_mem (); alloc_reg_set_mem (max_reg_num ()); - compute_sets (get_insns ()); + compute_sets (); } } @@ -3232,9 +3253,7 @@ cprop (int alter_jumps) start of the block]. */ reset_opr_set_tables (); - for (insn = BB_HEAD (bb); - insn != NULL && insn != NEXT_INSN (BB_END (bb)); - insn = NEXT_INSN (insn)) + FOR_BB_INSNS (bb, insn) if (INSN_P (insn)) { changed |= cprop_insn (insn, alter_jumps); @@ -3358,7 +3377,7 @@ find_implicit_sets (void) perform conditional jump bypassing optimizations. */ static int -one_cprop_pass (int pass, int cprop_jumps, int bypass_jumps) +one_cprop_pass (int pass, bool cprop_jumps, bool bypass_jumps) { int changed = 0; @@ -3665,9 +3684,7 @@ bypass_conditional_jumps (void) if (!single_pred_p (bb)) { setcc = NULL_RTX; - for (insn = BB_HEAD (bb); - insn != NULL && insn != NEXT_INSN (BB_END (bb)); - insn = NEXT_INSN (insn)) + FOR_BB_INSNS (bb, insn) if (NONJUMP_INSN_P (insn)) { if (setcc) @@ -5221,9 +5238,7 @@ compute_ld_motion_mems (void) FOR_EACH_BB (bb) { - for (insn = BB_HEAD (bb); - insn && insn != NEXT_INSN (BB_END (bb)); - insn = NEXT_INSN (insn)) + FOR_BB_INSNS (bb, insn) { if (INSN_P (insn)) { @@ -5678,9 +5693,7 @@ compute_store_table (void) /* First compute the registers set in this block. */ regvec = last_set_in; - for (insn = BB_HEAD (bb); - insn != NEXT_INSN (BB_END (bb)); - insn = NEXT_INSN (insn)) + FOR_BB_INSNS (bb, insn) { if (! INSN_P (insn)) continue; @@ -5703,9 +5716,7 @@ compute_store_table (void) /* Now find the stores. */ memset (already_set, 0, sizeof (int) * max_gcse_regno); regvec = already_set; - for (insn = BB_HEAD (bb); - insn != NEXT_INSN (BB_END (bb)); - insn = NEXT_INSN (insn)) + FOR_BB_INSNS (bb, insn) { if (! INSN_P (insn)) continue; @@ -6477,11 +6488,11 @@ bypass_jumps (FILE *file) information about memory sets when we build the hash tables. */ alloc_reg_set_mem (max_gcse_regno); - compute_sets (get_insns ()); + compute_sets (); max_gcse_regno = max_reg_num (); - alloc_gcse_mem (get_insns ()); - changed = one_cprop_pass (MAX_GCSE_PASSES + 2, 1, 1); + alloc_gcse_mem (); + changed = one_cprop_pass (MAX_GCSE_PASSES + 2, true, true); free_gcse_mem (); if (file) |