* Global CSE and constant/copy propagation.

* Makefile.in (OBJS): Add gcse.o
        (STAGESTUFF): Add *.gcse.
        (gcse.o): Add dependencies.
        (mostlyclean): Remove *.gcse and */*.gcse.
        * gcse.c: New file.
        * loop.c (loop_optimize): Move call to init_alias_analysis.
        * recog.c (validate_replace_src): New function.
        * toplev.c (gcse_dump): New global variable.
        (flag_gcse, gcse_time): Likewise.
        (compile_file): Initialize gcse_time and clean out the gcse dump
        file if necessary.
        (rest_of_compilation): Call gcse_main as requested.  Dump RTL
        after gcse if requested.
        (main): Enable gcse for -O2 and above.  Handle -dG.  Enable gcse
        dumps for -da.
        * gcc.texi: Add gcse related internal documentation.
        * invoke.texi: Note new command line options for gcse.
        * tm.texi: Document AVOID_CCMODE_COPIES.
        * mips.h (AVOID_CCMODE_COPIES): Define.

Co-Authored-By: Jeffrey A Law <law@cygnus.com>

From-SVN: r19901
This commit is contained in:
Doug Evans 1998-05-20 00:24:32 +00:00 committed by Jeff Law
parent d392d163c5
commit 7506f49132
10 changed files with 4811 additions and 6 deletions

View File

@ -1,3 +1,27 @@
Wed May 20 01:11:02 1998 Doug Evans (devans@cygnus.com)
Jeff Law (law@cygnus.com)
* Global CSE and constant/copy propagation.
* Makefile.in (OBJS): Add gcse.o
(STAGESTUFF): Add *.gcse.
(gcse.o): Add dependencies.
(mostlyclean): Remove *.gcse and */*.gcse.
* gcse.c: New file.
* loop.c (loop_optimize): Move call to init_alias_analysis.
* recog.c (validate_replace_src): New function.
* toplev.c (gcse_dump): New global variable.
(flag_gcse, gcse_time): Likewise.
(compile_file): Initialize gcse_time and clean out the gcse dump
file if necessary.
(rest_of_compilation): Call gcse_main as requested. Dump RTL
after gcse if requested.
(main): Enable gcse for -O2 and above. Handle -dG. Enable gcse
dumps for -da.
* gcc.texi: Add gcse related internal documentation.
* invoke.texi: Note new command line options for gcse.
* tm.texi: Document AVOID_CCMODE_COPIES.
* mips.h (AVOID_CCMODE_COPIES): Define.
Tue May 19 22:31:20 1998 Jeffrey A Law (law@cygnus.com)
* Makefile.in (deduced.h): Only run scan-types if $(SYSTEM_HEADER_DIR)

View File

@ -652,7 +652,7 @@ OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o genrtl.o real.o regmove.o \
dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o \
integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o \
regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o \
regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o gcse.o \
insn-peep.o reorg.o $(SCHED_PREFIX)sched.o final.o recog.o reg-stack.o \
insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \
profile.o insn-attrtab.o $(out_object_file) getpwd.o $(EXTRA_OBJS) convert.o
@ -685,7 +685,7 @@ STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
specs collect2$(exeext) $(USE_COLLECT2) underscore.c \
gcov$(exeext) *.bp \
*.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop \
*.dbr *.jump2 *.sched *.cse2 *.sched2 *.stack \
*.dbr *.jump2 *.sched *.cse2 *.sched2 *.stack *.gcse \
*.[si] \
$(LANG_STAGESTUFF)
@ -1449,6 +1449,8 @@ stupid.o : stupid.c $(CONFIG_H) system.h $(RTL_H) regs.h hard-reg-set.h flags.h
cse.o : cse.c $(CONFIG_H) system.h $(RTL_H) regs.h hard-reg-set.h flags.h \
real.h insn-config.h insn-codes.h $(RECOG_H) expr.h
gcse.o : gcse.c $(CONFIG_H) system.h $(RTL_H) regs.h hard-reg-set.h flags.h \
real.h insn-config.h insn-codes.h $(RECOG_H) expr.h basic-block.h
profile.o : profile.c $(CONFIG_H) system.h $(RTL_H) flags.h insn-flags.h \
gcov-io.h $(TREE_H) output.h regs.h toplev.h
loop.o : loop.c $(CONFIG_H) system.h $(RTL_H) flags.h loop.h insn-config.h \
@ -2159,10 +2161,11 @@ mostlyclean: lang.mostlyclean
-rm -f */stamp-* */tmp-*
# Delete debugging dump files.
-rm -f *.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop
-rm -f *.dbr *.jump2 *.sched *.cse2 *.sched2 *.stack *.addressof *.regmove *.mach *.bp
-rm -f *.dbr *.jump2 *.sched *.cse2 *.sched2 *.stack *.addressof
-rm -f *.regmove *.mach *.bp *.gcse
-rm -f */*.greg */*.lreg */*.combine */*.flow */*.cse */*.jump */*.rtl
-rm -f */*.tree */*.loop */*.dbr */*.jump2 */*.sched */*.cse2
-rm -f */*.sched2 */*.stack */*.regmove
-rm -f */*.sched2 */*.stack */*.regmove */*.gcse
# Delete some files made during installation.
-rm -f specs gfloat.h float.h-* enquire SYSCALLS.c.X SYSCALLS.c
-rm -f collect collect2 mips-tfile mips-tdump alloca.s

View File

@ -3561,6 +3561,13 @@ while (0)
(((mips_cpu == PROCESSOR_R4000 || mips_cpu == PROCESSOR_R6000) ? 6 : 4) \
+ memory_move_secondary_cost ((MODE), (CLASS), (TO_P)))
/* Define if copies to/from condition code registers should be avoided.
This is needed for the MIPS because reload_outcc is not complete;
it needs to handle cases where the source is a general or another
condition code register. */
#define AVOID_CCMODE_COPIES
/* A C expression for the cost of a branch instruction. A value of
1 is the default; other values are interpreted relative to that. */

View File

@ -3302,6 +3302,22 @@ The option @samp{-ds} causes a debugging dump of the RTL code after
this pass. This dump file's name is made by appending @samp{.cse} to
the input file name.
@cindex global common subexpression elimination
@cindex constant propagation
@cindex copy propagation
@item
Global common subexpression elimination. This pass performs GCSE
using Morel-Renvoise Partial Redundancy Elimination, with the exception
that it does not try to move invariants out of loops - that is left to
the loop optimization pass. This pass also performs global constant
and copy propagation.
The source file for this pass is gcse.c.
The option @samp{-dG} causes a debugging dump of the RTL code after
this pass. This dump file's name is made by appending @samp{.gcse} to
the input file name.
@cindex loop optimization
@cindex code motion
@cindex strength-reduction

4690
gcc/gcse.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -149,7 +149,7 @@ in the following sections.
-fcaller-saves -fcse-follow-jumps -fcse-skip-blocks
-fdelayed-branch -fexpensive-optimizations
-ffast-math -ffloat-store -fforce-addr -fforce-mem
-ffunction-sections -finline-functions
-ffunction-sections -fgcse -finline-functions
-fkeep-inline-functions -fno-default-inline
-fno-defer-pop -fno-function-cse
-fno-inline -fno-peephole -fomit-frame-pointer -fregmove
@ -1986,6 +1986,8 @@ Dump after purging ADDRESSOF, to @file{@var{file}.addressof}.
Dump after flow analysis, to @file{@var{file}.flow}.
@item g
Dump after global register allocation, to @file{@var{file}.greg}.
@item G
Dump after GCSE, to @file{@var{file}.gcse}.
@item j
Dump after first jump optimization, to @file{@var{file}.jump}.
@item J
@ -2299,6 +2301,10 @@ performed.
@item -frerun-loop-opt
Run the loop optimizer twice.
@item -fgcse
Perform a global common subexpression elimination pass.
This pass also performs global constant and copy propagation.
@item -fexpensive-optimizations
Perform a number of minor optimizations that are relatively expensive.

View File

@ -400,7 +400,6 @@ loop_optimize (f, dumpfile, unroll_p)
loop_dump_stream = dumpfile;
init_recog_no_volatile ();
init_alias_analysis ();
max_reg_before_loop = max_reg_num ();
@ -477,6 +476,13 @@ loop_optimize (f, dumpfile, unroll_p)
function. */
reg_scan (f, max_reg_num (), 1);
/* This must occur after reg_scan so that registers created by gcse
will have entries in the register tables.
We could have added a call to reg_scan after gcse_main in toplev.c,
but moving this call to init_alias_analysis is more efficient. */
init_alias_analysis ();
/* See if we went too far. */
if (get_max_uid () > max_uid_for_loop)
abort ();

View File

@ -537,6 +537,25 @@ validate_replace_rtx (from, to, insn)
validate_replace_rtx_1 (&PATTERN (insn), from, to, insn);
return apply_change_group ();
}
/* Try replacing every occurrence of FROM in INSN with TO, avoiding
SET_DESTs. After all changes have been made, validate by seeing if
INSN is still valid. */
int
validate_replace_src (from, to, insn)
rtx from, to, insn;
{
if ((GET_CODE (insn) != INSN && GET_CODE (insn) != JUMP_INSN)
|| GET_CODE (PATTERN (insn)) != SET)
abort ();
validate_replace_rtx_1 (&SET_SRC (PATTERN (insn)), from, to, insn);
if (GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
validate_replace_rtx_1 (&XEXP (SET_DEST (PATTERN (insn)), 0),
from, to, insn);
return apply_change_group ();
}
#ifdef HAVE_cc0
/* Return 1 if the insn using CC0 set by INSN does not contain

View File

@ -1505,6 +1505,12 @@ accessibility of the value in a narrower mode.
You should define this macro to return nonzero in as many cases as
possible since doing so will allow GNU CC to perform better register
allocation.
@findex AVOID_CCMODE_COPIES
@item AVOID_CCMODE_COPIES
Define this macro if the compiler should avoid copies to/from @code{CCmode}
registers. You should only define this macro if support fo copying to/from
@code{CCmode} is incomplete.
@end table
@node Leaf Functions

View File

@ -267,6 +267,7 @@ int rtl_dump_and_exit = 0;
int jump_opt_dump = 0;
int addressof_dump = 0;
int cse_dump = 0;
int gcse_dump = 0;
int loop_dump = 0;
int cse2_dump = 0;
int branch_prob_dump = 0;
@ -538,6 +539,10 @@ int flag_volatile_global;
int flag_syntax_only = 0;
/* Nonzero means perform global cse. */
static int flag_gcse;
/* Nonzero means to rerun cse after loop optimization. This increases
compilation time about 20% and picks up a few more common expressions. */
@ -738,6 +743,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
{"pcc-struct-return", &flag_pcc_struct_return, 1},
{"reg-struct-return", &flag_pcc_struct_return, 0},
{"delayed-branch", &flag_delayed_branch, 1},
{"gcse", &flag_gcse, 1},
{"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1},
{"rerun-loop-opt", &flag_rerun_loop_opt, 1},
{"pretend-float", &flag_pretend_float, 1},
@ -977,6 +983,7 @@ int varconst_time;
int integration_time;
int jump_time;
int cse_time;
int gcse_time;
int loop_time;
int cse2_time;
int branch_prob_time;
@ -2274,6 +2281,7 @@ compile_file (name)
integration_time = 0;
jump_time = 0;
cse_time = 0;
gcse_time = 0;
loop_time = 0;
cse2_time = 0;
branch_prob_time = 0;
@ -2360,6 +2368,8 @@ compile_file (name)
if (dbr_sched_dump)
clean_dump_file (".dbr");
#endif
if (gcse_dump)
clean_dump_file (".gcse");
#ifdef STACK_REGS
if (stack_reg_dump)
clean_dump_file (".stack");
@ -2840,6 +2850,7 @@ compile_file (name)
print_time ("integration", integration_time);
print_time ("jump", jump_time);
print_time ("cse", cse_time);
print_time ("gcse", gcse_time);
print_time ("loop", loop_time);
print_time ("cse2", cse2_time);
print_time ("branch-prob", branch_prob_time);
@ -3257,6 +3268,18 @@ rest_of_compilation (decl)
if (addressof_dump)
dump_rtl (".addressof", decl, print_rtl, insns);
/* Perform global cse. */
if (optimize > 0 && flag_gcse)
{
if (gcse_dump)
open_dump_file (".gcse", IDENTIFIER_POINTER (DECL_NAME (decl)));
TIMEVAR (gcse_time, gcse_main (insns, rtl_dump_file));
if (gcse_dump)
close_dump_file (print_rtl, insns);
}
/* Move constant computations out of loops. */
if (optimize > 0)
@ -3801,6 +3824,7 @@ main (argc, argv, envp)
{
flag_cse_follow_jumps = 1;
flag_cse_skip_blocks = 1;
flag_gcse = 1;
flag_expensive_optimizations = 1;
flag_strength_reduce = 1;
flag_rerun_cse_after_loop = 1;
@ -3879,6 +3903,7 @@ main (argc, argv, envp)
regmove_dump = 1;
rtl_dump = 1;
cse_dump = 1, cse2_dump = 1;
gcse_dump = 1;
sched_dump = 1;
sched2_dump = 1;
#ifdef STACK_REGS
@ -3911,6 +3936,9 @@ main (argc, argv, envp)
case 'g':
global_reg_dump = 1;
break;
case 'G':
gcse_dump = 1;
break;
case 'j':
jump_opt_dump = 1;
break;