alias.c (get_addr): Externalize.
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. Co-Authored-By: Jeff Law <law@redhat.com> From-SVN: r41207
This commit is contained in:
parent
92d0fb0938
commit
a13d4ebfc3
@ -1,3 +1,69 @@
|
||||
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
|
||||
Jeff Law <law@redhat.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.
|
||||
|
||||
Mon Apr 9 16:18:03 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* i386.c (expand_fp_movcc): Fix condition reversal code.
|
||||
|
61
gcc/alias.c
61
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. */
|
||||
|
||||
|
@ -611,6 +611,15 @@ extern enum graph_dump_types graph_dump_format;
|
||||
|
||||
extern int flag_no_ident;
|
||||
|
||||
/* Nonzero if we want to perform enhanced load motion during gcse. */
|
||||
|
||||
extern int flag_gcse_lm;
|
||||
|
||||
/* Nonzero if we want to perform store motion after gcse. */
|
||||
|
||||
extern int flag_gcse_sm;
|
||||
|
||||
|
||||
/* Nonzero means we should do dwarf2 duplicate elimination. */
|
||||
|
||||
extern int flag_eliminate_dwarf2_dups;
|
||||
|
1503
gcc/gcse.c
1503
gcc/gcse.c
File diff suppressed because it is too large
Load Diff
@ -241,7 +241,7 @@ in the following sections.
|
||||
-fcse-follow-jumps -fcse-skip-blocks -fdata-sections -fdce @gol
|
||||
-fdelayed-branch -fdelete-null-pointer-checks @gol
|
||||
-fexpensive-optimizations -ffast-math -ffloat-store @gol
|
||||
-fforce-addr -fforce-mem -ffunction-sections -fgcse @gol
|
||||
-fforce-addr -fforce-mem -ffunction-sections -fgcse -fgcse-lm -fgcse-sm @gol
|
||||
-finline-functions -finline-limit=@var{n} -fkeep-inline-functions @gol
|
||||
-fkeep-static-consts -fmove-all-movables @gol
|
||||
-fno-default-inline -fno-defer-pop @gol
|
||||
@ -3034,6 +3034,18 @@ Run the loop optimizer twice.
|
||||
Perform a global common subexpression elimination pass.
|
||||
This pass also performs global constant and copy propagation.
|
||||
|
||||
@item -fgcse-lm
|
||||
When -fgcse-lm is enabled, global common subexpression elimination will
|
||||
attempt to move loads which are only killed by stores into themselves. This
|
||||
allows a loop containing a load/store sequence to be changed to a load outside
|
||||
the loop, and a copy/store within the loop.
|
||||
|
||||
@item -fgcse-sm
|
||||
When -fgcse-sm is enabled, A store motion pass is run after global common
|
||||
subexpression elimination. This pass will attempt to move stores out of loops.
|
||||
When used in conjunction with -fgcse-lm, loops containing a load/store sequence
|
||||
can be changed to a load before the loop and a store after the loop.
|
||||
|
||||
@item -fdelete-null-pointer-checks
|
||||
Use global dataflow analysis to identify and eliminate useless null
|
||||
pointer checks. Programs which rely on NULL pointer dereferences @emph{not}
|
||||
|
@ -2031,6 +2031,9 @@ extern void fancy_abort PARAMS ((const char *, int, const char *))
|
||||
extern rtx canon_rtx PARAMS ((rtx));
|
||||
extern int true_dependence PARAMS ((rtx, enum machine_mode, rtx,
|
||||
int (*)(rtx, int)));
|
||||
extern rtx get_addr PARAMS ((rtx));
|
||||
extern int canon_true_dependence PARAMS ((rtx, enum machine_mode, rtx,
|
||||
rtx, int (*)(rtx, int)));
|
||||
extern int read_dependence PARAMS ((rtx, rtx));
|
||||
extern int anti_dependence PARAMS ((rtx, rtx));
|
||||
extern int output_dependence PARAMS ((rtx, rtx));
|
||||
|
16
gcc/toplev.c
16
gcc/toplev.c
@ -668,6 +668,18 @@ static int flag_gcse;
|
||||
|
||||
static int flag_delete_null_pointer_checks;
|
||||
|
||||
/* Nonzero means to do the enhanced load motion during gcse, which trys
|
||||
to hoist loads by not killing them when a store to the same location
|
||||
is seen. */
|
||||
|
||||
int flag_gcse_lm = 1;
|
||||
|
||||
/* Nonzero means to perform store motion after gcse, which will try to
|
||||
move stores closer to the exit block. Its not very effective without
|
||||
flag_gcse_lm. */
|
||||
|
||||
int flag_gcse_sm = 1;
|
||||
|
||||
/* Nonzero means to rerun cse after loop optimization. This increases
|
||||
compilation time about 20% and picks up a few more common expressions. */
|
||||
|
||||
@ -1047,6 +1059,10 @@ lang_independent_options f_options[] =
|
||||
"Attempt to fill delay slots of branch instructions" },
|
||||
{"gcse", &flag_gcse, 1,
|
||||
"Perform the global common subexpression elimination" },
|
||||
{"gcse-lm", &flag_gcse_lm, 1,
|
||||
"Perform enhanced load motion during global subexpression elimination" },
|
||||
{"gcse-sm", &flag_gcse_sm, 1,
|
||||
"Perform store motion after global subexpression elimination" },
|
||||
{"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
|
||||
"Run CSE pass after loop optimisations"},
|
||||
{"rerun-loop-opt", &flag_rerun_loop_opt, 1,
|
||||
|
Loading…
Reference in New Issue
Block a user