Commit 7506f491 by Doug Evans Committed by Jeff Law

* 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
parent d392d163
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) 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) * Makefile.in (deduced.h): Only run scan-types if $(SYSTEM_HEADER_DIR)
......
...@@ -652,7 +652,7 @@ OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \ ...@@ -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 \ 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 \ 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 \ 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-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 \ 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 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 \ ...@@ -685,7 +685,7 @@ STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
specs collect2$(exeext) $(USE_COLLECT2) underscore.c \ specs collect2$(exeext) $(USE_COLLECT2) underscore.c \
gcov$(exeext) *.bp \ gcov$(exeext) *.bp \
*.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop \ *.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop \
*.dbr *.jump2 *.sched *.cse2 *.sched2 *.stack \ *.dbr *.jump2 *.sched *.cse2 *.sched2 *.stack *.gcse \
*.[si] \ *.[si] \
$(LANG_STAGESTUFF) $(LANG_STAGESTUFF)
...@@ -1449,6 +1449,8 @@ stupid.o : stupid.c $(CONFIG_H) system.h $(RTL_H) regs.h hard-reg-set.h flags.h ...@@ -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 \ 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 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 \ 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 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 \ loop.o : loop.c $(CONFIG_H) system.h $(RTL_H) flags.h loop.h insn-config.h \
...@@ -2159,10 +2161,11 @@ mostlyclean: lang.mostlyclean ...@@ -2159,10 +2161,11 @@ mostlyclean: lang.mostlyclean
-rm -f */stamp-* */tmp-* -rm -f */stamp-* */tmp-*
# Delete debugging dump files. # Delete debugging dump files.
-rm -f *.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop -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 */*.greg */*.lreg */*.combine */*.flow */*.cse */*.jump */*.rtl
-rm -f */*.tree */*.loop */*.dbr */*.jump2 */*.sched */*.cse2 -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. # Delete some files made during installation.
-rm -f specs gfloat.h float.h-* enquire SYSCALLS.c.X SYSCALLS.c -rm -f specs gfloat.h float.h-* enquire SYSCALLS.c.X SYSCALLS.c
-rm -f collect collect2 mips-tfile mips-tdump alloca.s -rm -f collect collect2 mips-tfile mips-tdump alloca.s
......
...@@ -3561,6 +3561,13 @@ while (0) ...@@ -3561,6 +3561,13 @@ while (0)
(((mips_cpu == PROCESSOR_R4000 || mips_cpu == PROCESSOR_R6000) ? 6 : 4) \ (((mips_cpu == PROCESSOR_R4000 || mips_cpu == PROCESSOR_R6000) ? 6 : 4) \
+ memory_move_secondary_cost ((MODE), (CLASS), (TO_P))) + 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 /* A C expression for the cost of a branch instruction. A value of
1 is the default; other values are interpreted relative to that. */ 1 is the default; other values are interpreted relative to that. */
......
...@@ -3302,6 +3302,22 @@ The option @samp{-ds} causes a debugging dump of the RTL code after ...@@ -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 this pass. This dump file's name is made by appending @samp{.cse} to
the input file name. 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 loop optimization
@cindex code motion @cindex code motion
@cindex strength-reduction @cindex strength-reduction
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -149,7 +149,7 @@ in the following sections. ...@@ -149,7 +149,7 @@ in the following sections.
-fcaller-saves -fcse-follow-jumps -fcse-skip-blocks -fcaller-saves -fcse-follow-jumps -fcse-skip-blocks
-fdelayed-branch -fexpensive-optimizations -fdelayed-branch -fexpensive-optimizations
-ffast-math -ffloat-store -fforce-addr -fforce-mem -ffast-math -ffloat-store -fforce-addr -fforce-mem
-ffunction-sections -finline-functions -ffunction-sections -fgcse -finline-functions
-fkeep-inline-functions -fno-default-inline -fkeep-inline-functions -fno-default-inline
-fno-defer-pop -fno-function-cse -fno-defer-pop -fno-function-cse
-fno-inline -fno-peephole -fomit-frame-pointer -fregmove -fno-inline -fno-peephole -fomit-frame-pointer -fregmove
...@@ -1986,6 +1986,8 @@ Dump after purging ADDRESSOF, to @file{@var{file}.addressof}. ...@@ -1986,6 +1986,8 @@ Dump after purging ADDRESSOF, to @file{@var{file}.addressof}.
Dump after flow analysis, to @file{@var{file}.flow}. Dump after flow analysis, to @file{@var{file}.flow}.
@item g @item g
Dump after global register allocation, to @file{@var{file}.greg}. Dump after global register allocation, to @file{@var{file}.greg}.
@item G
Dump after GCSE, to @file{@var{file}.gcse}.
@item j @item j
Dump after first jump optimization, to @file{@var{file}.jump}. Dump after first jump optimization, to @file{@var{file}.jump}.
@item J @item J
...@@ -2299,6 +2301,10 @@ performed. ...@@ -2299,6 +2301,10 @@ performed.
@item -frerun-loop-opt @item -frerun-loop-opt
Run the loop optimizer twice. 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 @item -fexpensive-optimizations
Perform a number of minor optimizations that are relatively expensive. Perform a number of minor optimizations that are relatively expensive.
......
...@@ -400,7 +400,6 @@ loop_optimize (f, dumpfile, unroll_p) ...@@ -400,7 +400,6 @@ loop_optimize (f, dumpfile, unroll_p)
loop_dump_stream = dumpfile; loop_dump_stream = dumpfile;
init_recog_no_volatile (); init_recog_no_volatile ();
init_alias_analysis ();
max_reg_before_loop = max_reg_num (); max_reg_before_loop = max_reg_num ();
...@@ -477,6 +476,13 @@ loop_optimize (f, dumpfile, unroll_p) ...@@ -477,6 +476,13 @@ loop_optimize (f, dumpfile, unroll_p)
function. */ function. */
reg_scan (f, max_reg_num (), 1); 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. */ /* See if we went too far. */
if (get_max_uid () > max_uid_for_loop) if (get_max_uid () > max_uid_for_loop)
abort (); abort ();
......
...@@ -537,6 +537,25 @@ validate_replace_rtx (from, to, insn) ...@@ -537,6 +537,25 @@ validate_replace_rtx (from, to, insn)
validate_replace_rtx_1 (&PATTERN (insn), from, to, insn); validate_replace_rtx_1 (&PATTERN (insn), from, to, insn);
return apply_change_group (); 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 #ifdef HAVE_cc0
/* Return 1 if the insn using CC0 set by INSN does not contain /* Return 1 if the insn using CC0 set by INSN does not contain
......
...@@ -1505,6 +1505,12 @@ accessibility of the value in a narrower mode. ...@@ -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 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 possible since doing so will allow GNU CC to perform better register
allocation. 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 @end table
@node Leaf Functions @node Leaf Functions
......
...@@ -267,6 +267,7 @@ int rtl_dump_and_exit = 0; ...@@ -267,6 +267,7 @@ int rtl_dump_and_exit = 0;
int jump_opt_dump = 0; int jump_opt_dump = 0;
int addressof_dump = 0; int addressof_dump = 0;
int cse_dump = 0; int cse_dump = 0;
int gcse_dump = 0;
int loop_dump = 0; int loop_dump = 0;
int cse2_dump = 0; int cse2_dump = 0;
int branch_prob_dump = 0; int branch_prob_dump = 0;
...@@ -538,6 +539,10 @@ int flag_volatile_global; ...@@ -538,6 +539,10 @@ int flag_volatile_global;
int flag_syntax_only = 0; int flag_syntax_only = 0;
/* Nonzero means perform global cse. */
static int flag_gcse;
/* Nonzero means to rerun cse after loop optimization. This increases /* Nonzero means to rerun cse after loop optimization. This increases
compilation time about 20% and picks up a few more common expressions. */ 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[] = ...@@ -738,6 +743,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
{"pcc-struct-return", &flag_pcc_struct_return, 1}, {"pcc-struct-return", &flag_pcc_struct_return, 1},
{"reg-struct-return", &flag_pcc_struct_return, 0}, {"reg-struct-return", &flag_pcc_struct_return, 0},
{"delayed-branch", &flag_delayed_branch, 1}, {"delayed-branch", &flag_delayed_branch, 1},
{"gcse", &flag_gcse, 1},
{"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1}, {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1},
{"rerun-loop-opt", &flag_rerun_loop_opt, 1}, {"rerun-loop-opt", &flag_rerun_loop_opt, 1},
{"pretend-float", &flag_pretend_float, 1}, {"pretend-float", &flag_pretend_float, 1},
...@@ -977,6 +983,7 @@ int varconst_time; ...@@ -977,6 +983,7 @@ int varconst_time;
int integration_time; int integration_time;
int jump_time; int jump_time;
int cse_time; int cse_time;
int gcse_time;
int loop_time; int loop_time;
int cse2_time; int cse2_time;
int branch_prob_time; int branch_prob_time;
...@@ -2274,6 +2281,7 @@ compile_file (name) ...@@ -2274,6 +2281,7 @@ compile_file (name)
integration_time = 0; integration_time = 0;
jump_time = 0; jump_time = 0;
cse_time = 0; cse_time = 0;
gcse_time = 0;
loop_time = 0; loop_time = 0;
cse2_time = 0; cse2_time = 0;
branch_prob_time = 0; branch_prob_time = 0;
...@@ -2360,6 +2368,8 @@ compile_file (name) ...@@ -2360,6 +2368,8 @@ compile_file (name)
if (dbr_sched_dump) if (dbr_sched_dump)
clean_dump_file (".dbr"); clean_dump_file (".dbr");
#endif #endif
if (gcse_dump)
clean_dump_file (".gcse");
#ifdef STACK_REGS #ifdef STACK_REGS
if (stack_reg_dump) if (stack_reg_dump)
clean_dump_file (".stack"); clean_dump_file (".stack");
...@@ -2840,6 +2850,7 @@ compile_file (name) ...@@ -2840,6 +2850,7 @@ compile_file (name)
print_time ("integration", integration_time); print_time ("integration", integration_time);
print_time ("jump", jump_time); print_time ("jump", jump_time);
print_time ("cse", cse_time); print_time ("cse", cse_time);
print_time ("gcse", gcse_time);
print_time ("loop", loop_time); print_time ("loop", loop_time);
print_time ("cse2", cse2_time); print_time ("cse2", cse2_time);
print_time ("branch-prob", branch_prob_time); print_time ("branch-prob", branch_prob_time);
...@@ -3257,6 +3268,18 @@ rest_of_compilation (decl) ...@@ -3257,6 +3268,18 @@ rest_of_compilation (decl)
if (addressof_dump) if (addressof_dump)
dump_rtl (".addressof", decl, print_rtl, insns); 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. */ /* Move constant computations out of loops. */
if (optimize > 0) if (optimize > 0)
...@@ -3801,6 +3824,7 @@ main (argc, argv, envp) ...@@ -3801,6 +3824,7 @@ main (argc, argv, envp)
{ {
flag_cse_follow_jumps = 1; flag_cse_follow_jumps = 1;
flag_cse_skip_blocks = 1; flag_cse_skip_blocks = 1;
flag_gcse = 1;
flag_expensive_optimizations = 1; flag_expensive_optimizations = 1;
flag_strength_reduce = 1; flag_strength_reduce = 1;
flag_rerun_cse_after_loop = 1; flag_rerun_cse_after_loop = 1;
...@@ -3879,6 +3903,7 @@ main (argc, argv, envp) ...@@ -3879,6 +3903,7 @@ main (argc, argv, envp)
regmove_dump = 1; regmove_dump = 1;
rtl_dump = 1; rtl_dump = 1;
cse_dump = 1, cse2_dump = 1; cse_dump = 1, cse2_dump = 1;
gcse_dump = 1;
sched_dump = 1; sched_dump = 1;
sched2_dump = 1; sched2_dump = 1;
#ifdef STACK_REGS #ifdef STACK_REGS
...@@ -3911,6 +3936,9 @@ main (argc, argv, envp) ...@@ -3911,6 +3936,9 @@ main (argc, argv, envp)
case 'g': case 'g':
global_reg_dump = 1; global_reg_dump = 1;
break; break;
case 'G':
gcse_dump = 1;
break;
case 'j': case 'j':
jump_opt_dump = 1; jump_opt_dump = 1;
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment