diff options
author | amacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-04-09 14:27:05 +0000 |
---|---|---|
committer | amacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-04-09 14:27:05 +0000 |
commit | 8e802be9a2066e0700a018fcb6dce8a66118d09b (patch) | |
tree | cf7c04fbaaa5ba499552edce36a0bf5ddf9db722 /gcc/alias.c | |
parent | 699a9feae1121d337b832dc9184c13501210503b (diff) | |
download | ppe42-gcc-8e802be9a2066e0700a018fcb6dce8a66118d09b.tar.gz ppe42-gcc-8e802be9a2066e0700a018fcb6dce8a66118d09b.zip |
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41207 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/alias.c')
-rw-r--r-- | gcc/alias.c | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/gcc/alias.c b/gcc/alias.c index d69b38392fe..8792da690e2 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -87,7 +87,7 @@ typedef struct alias_set_entry static int rtx_equal_for_memref_p PARAMS ((rtx, rtx)); static rtx find_symbolic_term PARAMS ((rtx)); -static rtx get_addr PARAMS ((rtx)); +rtx get_addr PARAMS ((rtx)); static int memrefs_conflict_p PARAMS ((int, rtx, int, rtx, HOST_WIDE_INT)); static void record_set PARAMS ((rtx, rtx, void *)); @@ -1340,7 +1340,7 @@ base_alias_check (x, y, x_mode, y_mode) it unchanged unless it is a value; in the latter case we call cselib to get a more useful rtx. */ -static rtx +rtx get_addr (x) rtx x; { @@ -1765,6 +1765,63 @@ true_dependence (mem, mem_mode, x, varies) varies); } +/* Canonical true dependence: X is read after store in MEM takes place. + Variant of true_dependece which assumes MEM has already been + canonicalized (hence we no longer do that here). + The mem_addr argument has been added, since true_dependence computed + this value prior to canonicalizing. */ + +int +canon_true_dependence (mem, mem_mode, mem_addr, x, varies) + rtx mem, mem_addr, x; + enum machine_mode mem_mode; + int (*varies) PARAMS ((rtx, int)); +{ + register rtx x_addr; + + if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) + return 1; + + if (DIFFERENT_ALIAS_SETS_P (x, mem)) + return 0; + + /* If X is an unchanging read, then it can't possibly conflict with any + non-unchanging store. It may conflict with an unchanging write though, + because there may be a single store to this address to initialize it. + Just fall through to the code below to resolve the case where we have + both an unchanging read and an unchanging write. This won't handle all + cases optimally, but the possible performance loss should be + negligible. */ + if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem)) + return 0; + + x_addr = get_addr (XEXP (x, 0)); + + if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode)) + return 0; + + x_addr = canon_rtx (x_addr); + if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, + SIZE_FOR_MODE (x), x_addr, 0)) + return 0; + + if (aliases_everything_p (x)) + return 1; + + /* We cannot use aliases_everyting_p to test MEM, since we must look + at MEM_MODE, rather than GET_MODE (MEM). */ + if (mem_mode == QImode || GET_CODE (mem_addr) == AND) + return 1; + + /* In true_dependence we also allow BLKmode to alias anything. Why + don't we do this in anti_dependence and output_dependence? */ + if (mem_mode == BLKmode || GET_MODE (x) == BLKmode) + return 1; + + return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, + varies); +} + /* Returns non-zero if a write to X might alias a previous read from (or, if WRITEP is non-zero, a write to) MEM. */ |