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:
Andrew MacLeod 2001-04-09 14:27:05 +00:00 committed by Andrew Macleod
parent 92d0fb0938
commit a13d4ebfc3
7 changed files with 1669 additions and 3 deletions

View File

@ -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.

View File

@ -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. */

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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}

View File

@ -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));

View File

@ -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,