summaryrefslogtreecommitdiffstats
path: root/gcc/alias.c
diff options
context:
space:
mode:
authoramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>2001-04-09 14:27:05 +0000
committeramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>2001-04-09 14:27:05 +0000
commit8e802be9a2066e0700a018fcb6dce8a66118d09b (patch)
treecf7c04fbaaa5ba499552edce36a0bf5ddf9db722 /gcc/alias.c
parent699a9feae1121d337b832dc9184c13501210503b (diff)
downloadppe42-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.c61
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. */
OpenPOWER on IntegriCloud