mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-16 04:40:25 +08:00
* 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:
parent
d392d163c5
commit
7506f49132
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
||||
|
16
gcc/gcc.texi
16
gcc/gcc.texi
@ -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
4690
gcc/gcse.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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.
|
||||
|
||||
|
@ -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 ();
|
||||
|
19
gcc/recog.c
19
gcc/recog.c
@ -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
|
||||
|
@ -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
|
||||
|
28
gcc/toplev.c
28
gcc/toplev.c
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user