diff options
author | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-04-26 12:28:53 +0000 |
---|---|---|
committer | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-04-26 12:28:53 +0000 |
commit | 2e81afe57232d323f4fb4c44c4b81863fbc77f19 (patch) | |
tree | ba68c087a6658019b7bd358d32f6fa131ac208c8 /gcc/gcse.c | |
parent | 5c758b8341b16fd0a1473be817e40c29f8906840 (diff) | |
download | ppe42-gcc-2e81afe57232d323f4fb4c44c4b81863fbc77f19.tar.gz ppe42-gcc-2e81afe57232d323f4fb4c44c4b81863fbc77f19.zip |
* df-scan.c (df_insn_rescan): Salvage insn's LUID if the insn is
not new but only being rescanned.
* gcse.c (uid_cuid, max_uid, INSN_CUID, max_cuid, struct reg_set,
reg_set_table, REG_SET_TABLE_SLOP, reg_set_in_block,
alloc_reg_set_mem, free_reg_set_mem, record_one_set,
record_set_info, compute_set, grealloc): Remove.
(recompute_all_luids): New function.
(gcse_main): Don't compute sets, and don't do related memory
allocations/free-ing. If something changed before the end of the
pass, update LUIDs using recompute_all_luids.
(alloc_gcse_mem): Don't compute LUIDs. Don't allocate reg_set memory.
(free_gcse_mem): Don't free it either.
(oprs_unchanged_p, load_killed_in_block, record_last_reg_set_info):
Use the df insn LUIDs.
(load_killed_in_block): Likewise.
(compute_hash_table_work): Don't compute reg_set_in_block.
(compute_transp): Use DF_REG_DEF_CHAINs.
(local_cprop_pass): Don't use compute_sets and related functions.
(one_cprop_pass, pre_gcse, one_pre_gcse_pass, one_code_hoisting_pass):
Use get_max_uid() instead of max_cuid.
(insert_insn_end_basic_block, pre_insert_copy_insn,
update_ld_motion_stores): Don't try to
keep reg_set tables up to date.
(pre_insert_copies): Use df insn LUIDs.
(sbitmap pre_redundant_insns): Replace with uses of INSN_DELETED_P.
(reg_set_info): Don't use extra bitmap argument.
(compute_store_table): Don't compute reg_set_in_block. Use DF scan
information to compute regs_set_in_block.
(free_store_memory, store_motion): Don't nullify reg_set_in_block.
(bypass_jumps): Don't use compute_sets and friends.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146799 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r-- | gcc/gcse.c | 409 |
1 files changed, 67 insertions, 342 deletions
diff --git a/gcc/gcse.c b/gcc/gcse.c index 3195c989c5e..6bf1d502bbe 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -27,9 +27,6 @@ along with GCC; see the file COPYING3. If not see - a store to the same address as a load does not kill the load if the source of the store is also the destination of the load. Handling this allows more load motion, particularly out of loops. - - ability to realloc sbitmap vectors would allow one initial computation - of reg_set_in_block with only subsequent additions, rather than - recomputing it for each pass */ @@ -373,70 +370,11 @@ static struct hash_table expr_hash_table; /* Copy propagation hash table. */ static struct hash_table set_hash_table; -/* Mapping of uids to cuids. - Only real insns get cuids. */ -static int *uid_cuid; - -/* Highest UID in UID_CUID. */ -static int max_uid; - -/* Get the cuid of an insn. */ -#ifdef ENABLE_CHECKING -#define INSN_CUID(INSN) \ - (gcc_assert (INSN_UID (INSN) <= max_uid), uid_cuid[INSN_UID (INSN)]) -#else -#define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)]) -#endif - -/* Number of cuids. */ -static int max_cuid; - /* Maximum register number in function prior to doing gcse + 1. Registers created during this pass have regno >= max_gcse_regno. This is named with "gcse" to not collide with global of same name. */ static unsigned int max_gcse_regno; -/* Table of registers that are modified. - - For each register, each element is a list of places where the pseudo-reg - is set. - - For simplicity, GCSE is done on sets of pseudo-regs only. PRE GCSE only - requires knowledge of which blocks kill which regs [and thus could use - a bitmap instead of the lists `reg_set_table' uses]. - - `reg_set_table' and could be turned into an array of bitmaps (num-bbs x - num-regs) [however perhaps it may be useful to keep the data as is]. One - advantage of recording things this way is that `reg_set_table' is fairly - sparse with respect to pseudo regs but for hard regs could be fairly dense - [relatively speaking]. And recording sets of pseudo-regs in lists speeds - up functions like compute_transp since in the case of pseudo-regs we only - need to iterate over the number of times a pseudo-reg is set, not over the - number of basic blocks [clearly there is a bit of a slow down in the cases - where a pseudo is set more than once in a block, however it is believed - that the net effect is to speed things up]. This isn't done for hard-regs - because recording call-clobbered hard-regs in `reg_set_table' at each - function call can consume a fair bit of memory, and iterating over - hard-regs stored this way in compute_transp will be more expensive. */ - -typedef struct reg_set -{ - /* The next setting of this register. */ - struct reg_set *next; - /* The index of the block where it was set. */ - int bb_index; -} reg_set; - -static reg_set **reg_set_table; - -/* Size of `reg_set_table'. - The table starts out at max_gcse_regno + slop, and is enlarged as - necessary. */ -static int reg_set_table_size; - -/* Amount to grow `reg_set_table' by when it's full. */ -#define REG_SET_TABLE_SLOP 100 - /* This is a list of expressions which are MEMs and will be used by load or store motion. Load motion tracks MEMs which aren't killed by @@ -476,13 +414,6 @@ static htab_t pre_ldst_table = NULL; the start of the basic block. */ static regset reg_set_bitmap; -/* For each block, a bitmap of registers set in the block. - This is used by compute_transp. - It is computed during hash table computation and not by compute_sets - as it includes registers added since the last pass (or between cprop and - gcse) and it's currently not easy to realloc sbitmap vectors. */ -static sbitmap *reg_set_in_block; - /* Array, indexed by basic block number for a list of insns which modify memory within that block. */ static rtx * modify_mem_list; @@ -519,17 +450,12 @@ static int global_copy_prop_count; static sbitmap *ae_kill, *ae_gen; static void compute_can_copy (void); +static void recompute_all_luids (void); 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 (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, const_rtx, void *); -static void compute_sets (void); static void hash_scan_insn (rtx, struct hash_table *); static void hash_scan_set (rtx, rtx, struct hash_table *); static void hash_scan_clobber (rtx, rtx, struct hash_table *); @@ -655,11 +581,9 @@ static bool is_too_expensive (const char *); #define GNEWVEC(T, N) ((T *) gmalloc (sizeof (T) * (N))) #define GCNEWVEC(T, N) ((T *) gcalloc ((N), sizeof (T))) -#define GRESIZEVEC(T, P, N) ((T *) grealloc ((void *) (P), sizeof (T) * (N))) #define GNEWVAR(T, S) ((T *) gmalloc ((S))) #define GCNEWVAR(T, S) ((T *) gcalloc (1, (S))) -#define GRESIZEVAR(T, P, S) ((T *) grealloc ((P), (S))) #define GOBNEW(T) ((T *) gcse_alloc (sizeof (T))) #define GOBNEWVAR(T, S) ((T *) gcse_alloc ((S))) @@ -705,21 +629,6 @@ gcse_main (rtx f ATTRIBUTE_UNUSED) /* We need alias. */ init_alias_analysis (); - /* Record where pseudo-registers are set. This data is kept accurate - during each pass. ??? We could also record hard-reg information here - [since it's unchanging], however it is currently done during hash table - computation. - - It may be tempting to compute MEM set information here too, but MEM sets - will be subject to code motion one day and thus we need to compute - information about memory sets when we build the hash tables. - - ??? Actually, we already know the information that compute_sets computes - because it is available from DF. FIXME. */ - - alloc_reg_set_mem (max_gcse_regno); - compute_sets (); - gcse_obstack_bottom = GOBNEWVAR (char, 1); changed = 0; @@ -736,6 +645,8 @@ gcse_main (rtx f ATTRIBUTE_UNUSED) { timevar_push (TV_CPROP1); changed = one_cprop_pass (1, false, false); + if (changed) + recompute_all_luids (); timevar_pop (TV_CPROP1); } @@ -757,12 +668,7 @@ gcse_main (rtx f ATTRIBUTE_UNUSED) canon_modify_mem_list = GCNEWVEC (rtx, last_basic_block); } - /* ??? When we allocate this at the start of the function, - the comment says that "this data is kept accurate during - each pass". Apparently this is not so? FIXME. */ - free_reg_set_mem (); - alloc_reg_set_mem (max_reg_num ()); - compute_sets (); + df_analyze (); run_jump_opt_after_gcse = 1; timevar_pop (TV_PRE); } @@ -799,7 +705,9 @@ gcse_main (rtx f ATTRIBUTE_UNUSED) /* This time, go ahead and allow cprop to alter jumps. */ timevar_push (TV_CPROP2); - one_cprop_pass (2, true, true); + changed = one_cprop_pass (2, true, true); + if (changed) + recompute_all_luids (); timevar_pop (TV_CPROP2); free_gcse_mem (); } @@ -812,7 +720,6 @@ gcse_main (rtx f ATTRIBUTE_UNUSED) } obstack_free (&gcse_obstack, NULL); - free_reg_set_mem (); /* We are finished with alias. ??? Actually we recompute alias in store_motion. */ @@ -882,6 +789,20 @@ can_copy_p (enum machine_mode mode) return can_copy[mode] != 0; } + +/* Recompute the DF LUIDs for all basic blocks. If a sub-pass in this + file changes something, we have to recompute them for the next pass. + FIXME: If we would track which basic blocks we touch, we could + update LUIDs in only those basic blocks. */ + +static void +recompute_all_luids (void) +{ + basic_block bb; + FOR_EACH_BB (bb) + df_recompute_luids (bb); +} + /* Cover function to xmalloc to record bytes allocated. */ @@ -901,16 +822,6 @@ gcalloc (size_t nelem, size_t elsize) return xcalloc (nelem, elsize); } -/* Cover function to xrealloc. - We don't record the additional size since we don't know it. - It won't affect memory usage stats much anyway. */ - -static void * -grealloc (void *ptr, size_t size) -{ - return xrealloc (ptr, size); -} - /* Cover function to obstack_alloc. */ static void * @@ -920,43 +831,15 @@ gcse_alloc (unsigned long size) return obstack_alloc (&gcse_obstack, size); } -/* Allocate memory for the cuid mapping array, - and reg/memory set tracking tables. - +/* Allocate memory for the reg/memory set tracking tables. This is called at the start of each pass. */ static void 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. - (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 = GCNEWVEC (int, max_uid + 1); - 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; - } - - max_cuid = i; - /* Allocate vars to track sets of regs. */ reg_set_bitmap = BITMAP_ALLOC (NULL); - /* Allocate vars to track sets of regs, memory per block. */ - reg_set_in_block = sbitmap_vector_alloc (last_basic_block, max_gcse_regno); /* Allocate array to keep a list of insns which modify memory in each basic block. */ modify_mem_list = GCNEWVEC (rtx, last_basic_block); @@ -970,11 +853,6 @@ alloc_gcse_mem (void) static void free_gcse_mem (void) { - free (uid_cuid); - - BITMAP_FREE (reg_set_bitmap); - - sbitmap_vector_free (reg_set_in_block); free_modify_mem_tables (); BITMAP_FREE (modify_mem_list_set); BITMAP_FREE (blocks_with_calls); @@ -1073,85 +951,6 @@ compute_local_properties (sbitmap *transp, sbitmap *comp, sbitmap *antloc, } } -/* Register set information. - - `reg_set_table' records where each register is set or otherwise - modified. */ - -static struct obstack reg_set_obstack; - -static void -alloc_reg_set_mem (int n_regs) -{ - reg_set_table_size = n_regs + REG_SET_TABLE_SLOP; - reg_set_table = GCNEWVEC (struct reg_set *, reg_set_table_size); - - gcc_obstack_init (®_set_obstack); -} - -static void -free_reg_set_mem (void) -{ - free (reg_set_table); - obstack_free (®_set_obstack, NULL); -} - -/* Record REGNO in the reg_set table. */ - -static void -record_one_set (int regno, rtx insn) -{ - /* Allocate a new reg_set element and link it onto the list. */ - struct reg_set *new_reg_info; - - /* If the table isn't big enough, enlarge it. */ - if (regno >= reg_set_table_size) - { - int new_size = regno + REG_SET_TABLE_SLOP; - - reg_set_table = GRESIZEVEC (struct reg_set *, reg_set_table, new_size); - memset (reg_set_table + reg_set_table_size, 0, - (new_size - reg_set_table_size) * sizeof (struct reg_set *)); - reg_set_table_size = new_size; - } - - new_reg_info = XOBNEW (®_set_obstack, struct reg_set); - bytes_used += sizeof (struct reg_set); - new_reg_info->bb_index = BLOCK_NUM (insn); - new_reg_info->next = reg_set_table[regno]; - reg_set_table[regno] = new_reg_info; -} - -/* Called from compute_sets via note_stores to handle one SET or CLOBBER in - an insn. The DATA is really the instruction in which the SET is - occurring. */ - -static void -record_set_info (rtx dest, const_rtx setter ATTRIBUTE_UNUSED, void *data) -{ - rtx record_set_insn = (rtx) data; - - if (REG_P (dest) && REGNO (dest) >= FIRST_PSEUDO_REGISTER) - record_one_set (REGNO (dest), record_set_insn); -} - -/* Scan the function and record each set of each pseudo-register. - - This is called once, at the start of the gcse pass. See the comments for - `reg_set_table' for further documentation. */ - -static void -compute_sets (void) -{ - basic_block bb; - rtx 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. */ struct reg_avail_info @@ -1257,13 +1056,13 @@ oprs_unchanged_p (const_rtx x, const_rtx insn, int avail_p) if (info->last_bb != current_bb) return 1; if (avail_p) - return info->last_set < INSN_CUID (insn); + return info->last_set < DF_INSN_LUID (insn); else - return info->first_set >= INSN_CUID (insn); + return info->first_set >= DF_INSN_LUID (insn); } case MEM: - if (load_killed_in_block_p (current_bb, INSN_CUID (insn), + if (load_killed_in_block_p (current_bb, DF_INSN_LUID (insn), x, avail_p)) return 0; else @@ -1362,7 +1161,7 @@ mems_conflict_for_gcse_p (rtx dest, const_rtx setter ATTRIBUTE_UNUSED, } /* Return nonzero if the expression in X (a memory reference) is killed - in block BB before or after the insn with the CUID in UID_LIMIT. + in block BB before or after the insn with the LUID in UID_LIMIT. AVAIL_P is nonzero for kills after UID_LIMIT, and zero for kills before UID_LIMIT. @@ -1383,9 +1182,9 @@ load_killed_in_block_p (const_basic_block bb, int uid_limit, const_rtx x, int av rtx setter; /* Ignore entries in the list that do not apply. */ if ((avail_p - && INSN_CUID (XEXP (list_entry, 0)) < uid_limit) + && DF_INSN_LUID (XEXP (list_entry, 0)) < uid_limit) || (! avail_p - && INSN_CUID (XEXP (list_entry, 0)) > uid_limit)) + && DF_INSN_LUID (XEXP (list_entry, 0)) > uid_limit)) { list_entry = XEXP (list_entry, 1); continue; @@ -1923,23 +1722,19 @@ dump_hash_table (FILE *file, const char *name, struct hash_table *table) is set and is used to compute "availability". last_bb records the block for which first_set and last_set are - valid, as a quick test to invalidate them. - - reg_set_in_block records whether the register is set in the block - and is used to compute "transparency". */ + valid, as a quick test to invalidate them. */ static void record_last_reg_set_info (rtx insn, int regno) { struct reg_avail_info *info = ®_avail_info[regno]; - int cuid = INSN_CUID (insn); + int luid = DF_INSN_LUID (insn); - info->last_set = cuid; + info->last_set = luid; if (info->last_bb != current_bb) { info->last_bb = current_bb; - info->first_set = cuid; - SET_BIT (reg_set_in_block[current_bb->index], regno); + info->first_set = luid; } } @@ -2046,12 +1841,6 @@ compute_hash_table_work (struct hash_table *table) { unsigned int i; - /* While we compute the hash table we also compute a bit array of which - registers are set in which blocks. - ??? This isn't needed during const/copy propagation, but it's cheap to - compute. Later. */ - sbitmap_vector_zero (reg_set_in_block, last_basic_block); - /* re-Cache any INSN_LIST nodes we have allocated. */ clear_modify_mem_tables (); /* Some working arrays used to track first and last set in each block. */ @@ -2066,10 +1855,7 @@ compute_hash_table_work (struct hash_table *table) unsigned int regno; /* First pass over the instructions records information used to - determine when registers and memory are first and last set. - ??? hard-reg reg_set_in_block computation - could be moved to compute_sets since they currently don't change. */ - + determine when registers and memory are first and last set. */ FOR_BB_INSNS (current_bb, insn) { if (! INSN_P (insn)) @@ -2274,7 +2060,7 @@ oprs_not_set_p (const_rtx x, const_rtx insn) case MEM: if (load_killed_in_block_p (BLOCK_FOR_INSN (insn), - INSN_CUID (insn), x, 0)) + DF_INSN_LUID (insn), x, 0)) return 0; else return oprs_not_set_p (XEXP (x, 0), insn); @@ -2429,9 +2215,7 @@ static void compute_transp (const_rtx x, int indx, sbitmap *bmap, int set_p) { int i, j; - basic_block bb; enum rtx_code code; - reg_set *r; const char *fmt; /* repeat is used to turn tail-recursion into iteration since GCC @@ -2447,31 +2231,19 @@ compute_transp (const_rtx x, int indx, sbitmap *bmap, int set_p) case REG: if (set_p) { - if (REGNO (x) < FIRST_PSEUDO_REGISTER) - { - FOR_EACH_BB (bb) - if (TEST_BIT (reg_set_in_block[bb->index], REGNO (x))) - SET_BIT (bmap[bb->index], indx); - } - else - { - for (r = reg_set_table[REGNO (x)]; r != NULL; r = r->next) - SET_BIT (bmap[r->bb_index], indx); - } + df_ref def; + for (def = DF_REG_DEF_CHAIN (REGNO (x)); + def; + def = DF_REF_NEXT_REG (def)) + SET_BIT (bmap[DF_REF_BB (def)->index], indx); } else { - if (REGNO (x) < FIRST_PSEUDO_REGISTER) - { - FOR_EACH_BB (bb) - if (TEST_BIT (reg_set_in_block[bb->index], REGNO (x))) - RESET_BIT (bmap[bb->index], indx); - } - else - { - for (r = reg_set_table[REGNO (x)]; r != NULL; r = r->next) - RESET_BIT (bmap[r->bb_index], indx); - } + df_ref def; + for (def = DF_REG_DEF_CHAIN (REGNO (x)); + def; + def = DF_REF_NEXT_REG (def)) + RESET_BIT (bmap[DF_REF_BB (def)->index], indx); } return; @@ -3188,12 +2960,7 @@ local_cprop_pass (bool alter_jumps) /* 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 (); - } + delete_unreachable_blocks (); } /* Forward propagate copies. This includes copies and constants. Return @@ -3359,7 +3126,7 @@ one_cprop_pass (int pass, bool cprop_jumps, bool bypass_jumps) implicit_sets = XCNEWVEC (rtx, last_basic_block); find_implicit_sets (); - alloc_hash_table (max_cuid, &set_hash_table, 1); + alloc_hash_table (get_max_uid (), &set_hash_table, 1); compute_hash_table (&set_hash_table); /* Free implicit_sets before peak usage. */ @@ -3720,9 +3487,6 @@ static sbitmap *pre_delete_map; /* Contains the edge_list returned by pre_edge_lcm. */ static struct edge_list *edge_list; -/* Redundant insns. */ -static sbitmap pre_redundant_insns; - /* Allocate vars used for PRE analysis. */ static void @@ -4045,10 +3809,7 @@ insert_insn_end_basic_block (struct expr *expr, basic_block bb, int pre) while (1) { if (INSN_P (pat)) - { - add_label_notes (PATTERN (pat), new_insn); - note_stores (PATTERN (pat), record_set_info, pat); - } + add_label_notes (PATTERN (pat), new_insn); if (pat == pat_end) break; pat = NEXT_INSN (pat); @@ -4221,17 +3982,11 @@ pre_insert_copy_insn (struct expr *expr, rtx insn) { new_insn = gen_move_insn (old_reg, reg); new_insn = emit_insn_after (new_insn, insn); - - /* Keep register set table up to date. */ - record_one_set (regno, insn); } else { new_insn = gen_move_insn (reg, old_reg); new_insn = emit_insn_after (new_insn, insn); - - /* Keep register set table up to date. */ - record_one_set (regno, new_insn); } } else /* This is possible only in case of a store to memory. */ @@ -4244,9 +3999,6 @@ pre_insert_copy_insn (struct expr *expr, rtx insn) new_insn = emit_insn_before (new_insn, insn); else new_insn = emit_insn_after (new_insn, insn); - - /* Keep register set table up to date. */ - record_one_set (regno, new_insn); } gcse_create_count++; @@ -4303,7 +4055,7 @@ pre_insert_copies (void) continue; /* Don't handle this one if it's a redundant one. */ - if (TEST_BIT (pre_redundant_insns, INSN_CUID (insn))) + if (INSN_DELETED_P (insn)) continue; /* Or if the expression doesn't reach the deleted one. */ @@ -4400,7 +4152,6 @@ pre_delete (void) gcse_emit_move_after (expr->reaching_reg, SET_DEST (set), insn); delete_insn (insn); occr->deleted_p = 1; - SET_BIT (pre_redundant_insns, INSN_CUID (insn)); changed = 1; gcse_subst_count++; @@ -4455,10 +4206,6 @@ pre_gcse (void) for (expr = expr_hash_table.table[i]; expr != NULL; expr = expr->next_same_hash) index_map[expr->bitmap_index] = expr; - /* Reset bitmap used to track which insns are redundant. */ - pre_redundant_insns = sbitmap_alloc (max_cuid); - sbitmap_zero (pre_redundant_insns); - /* Delete the redundant insns first so that - we know what register to use for the new insns and for the other ones with reaching expressions @@ -4477,7 +4224,6 @@ pre_gcse (void) } free (index_map); - sbitmap_free (pre_redundant_insns); return changed; } @@ -4493,7 +4239,7 @@ one_pre_gcse_pass (int pass) gcse_subst_count = 0; gcse_create_count = 0; - alloc_hash_table (max_cuid, &expr_hash_table, 0); + alloc_hash_table (get_max_uid (), &expr_hash_table, 0); add_noreturn_fake_exit_edges (); if (flag_gcse_lm) compute_ld_motion_mems (); @@ -4947,7 +4693,7 @@ one_code_hoisting_pass (void) { int changed = 0; - alloc_hash_table (max_cuid, &expr_hash_table, 0); + alloc_hash_table (get_max_uid (), &expr_hash_table, 0); compute_hash_table (&expr_hash_table); if (dump_file) dump_hash_table (dump_file, "Code Hosting Expressions", &expr_hash_table); @@ -5393,9 +5139,8 @@ update_ld_motion_stores (struct expr * expr) fprintf (dump_file, "\n"); } - copy = gen_move_insn ( reg, copy_rtx (SET_SRC (pat))); + copy = gen_move_insn (reg, copy_rtx (SET_SRC (pat))); new_rtx = emit_insn_before (copy, insn); - record_one_set (REGNO (reg), new_rtx); SET_SRC (pat) = reg; df_insn_rescan (insn); @@ -5430,19 +5175,13 @@ static int num_stores; static void reg_set_info (rtx dest, const_rtx setter ATTRIBUTE_UNUSED, - void *data) + void *data ATTRIBUTE_UNUSED) { - sbitmap bb_reg = (sbitmap) data; - if (GET_CODE (dest) == SUBREG) dest = SUBREG_REG (dest); if (REG_P (dest)) - { - regvec[REGNO (dest)] = INSN_UID (compute_store_table_current_insn); - if (bb_reg) - SET_BIT (bb_reg, REGNO (dest)); - } + regvec[REGNO (dest)] = INSN_UID (compute_store_table_current_insn); } /* Clear any mark that says that this insn sets dest. Called from @@ -5705,9 +5444,6 @@ compute_store_table (void) max_gcse_regno = max_reg_num (); - reg_set_in_block = sbitmap_vector_alloc (last_basic_block, - max_gcse_regno); - sbitmap_vector_zero (reg_set_in_block, last_basic_block); pre_ldst_mems = 0; pre_ldst_table = htab_create (13, pre_ldst_expr_hash, pre_ldst_expr_eq, NULL); @@ -5729,15 +5465,12 @@ compute_store_table (void) { for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)) - { - last_set_in[regno] = INSN_UID (insn); - SET_BIT (reg_set_in_block[bb->index], regno); - } + last_set_in[regno] = INSN_UID (insn); } pat = PATTERN (insn); compute_store_table_current_insn = insn; - note_stores (pat, reg_set_info, reg_set_in_block[bb->index]); + note_stores (pat, reg_set_info, NULL); } /* Now find the stores. */ @@ -6029,7 +5762,6 @@ build_store_vectors (void) int *regs_set_in_block; rtx insn, st; struct ls_expr * ptr; - unsigned regno; /* Build the gen_vector. This is any store in the table which is not killed by aliasing later in its block. */ @@ -6078,8 +5810,17 @@ build_store_vectors (void) FOR_EACH_BB (bb) { - for (regno = 0; regno < max_gcse_regno; regno++) - regs_set_in_block[regno] = TEST_BIT (reg_set_in_block[bb->index], regno); + FOR_BB_INSNS (bb, insn) + if (INSN_P (insn)) + { + df_ref *def_rec; + for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) + { + unsigned int ref_regno = DF_REF_REGNO (*def_rec); + if (ref_regno < max_gcse_regno) + regs_set_in_block[DF_REF_REGNO (*def_rec)] = 1; + } + } for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr)) { @@ -6395,11 +6136,9 @@ free_store_memory (void) sbitmap_vector_free (pre_insert_map); if (pre_delete_map) sbitmap_vector_free (pre_delete_map); - if (reg_set_in_block) - sbitmap_vector_free (reg_set_in_block); ae_gen = ae_kill = transp = st_antloc = NULL; - pre_insert_map = pre_delete_map = reg_set_in_block = NULL; + pre_insert_map = pre_delete_map = NULL; } /* Perform store motion. Much like gcse, except we move expressions the @@ -6427,7 +6166,6 @@ store_motion (void) { htab_delete (pre_ldst_table); pre_ldst_table = NULL; - sbitmap_vector_free (reg_set_in_block); end_alias_analysis (); return; } @@ -6512,18 +6250,6 @@ bypass_jumps (void) /* We need alias. */ init_alias_analysis (); - /* Record where pseudo-registers are set. This data is kept accurate - during each pass. ??? We could also record hard-reg information here - [since it's unchanging], however it is currently done during hash table - computation. - - It may be tempting to compute MEM set information here too, but MEM sets - will be subject to code motion one day and thus we need to compute - information about memory sets when we build the hash tables. */ - - alloc_reg_set_mem (max_gcse_regno); - compute_sets (); - max_gcse_regno = max_reg_num (); alloc_gcse_mem (); changed = one_cprop_pass (3, true, true); @@ -6537,7 +6263,6 @@ bypass_jumps (void) } obstack_free (&gcse_obstack, NULL); - free_reg_set_mem (); /* We are finished with alias. */ end_alias_analysis (); |