mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-19 15:10:34 +08:00
unroll.c: Removed.
* unroll.c: Removed. * loop.h: Removed. * Makefile.in (LOOP_H, unroll.o): Removed. (toplev.o, passes.o, stmt.o, integrate.o, loop.o): Remove LOOP_H dependency. * alias.c (init_alias_analysis): Remove flag_old_unroll_loops reference. * cfgloop.h (LOOP_PREFETCH, loop_optimize): Moved from loop.h. * common.opt (fold-unroll-loops, fold-unroll-all-loops): Removed. * loop.c: Do not include loop.h. (LOOP_INFO, LOOP_MOVABLES, LOOP_REGS, LOOP_IVS, INSN_LUID, REGNO_FIRST_LUID, REGNO_LAST_LUID, enum g_types, struct induction, struct iv_class, enum iv_mode, struct iv, REG_IV_TYPE, REG_IV_INFO, REG_IV_CLASS, struct loop_ivs, struct loop_mem_info, struct loop_reg, struct loop_regs, struct loop_movables, struct loop_info): Moved from loop.h. (back_branch_in_range_p, fold_rtx_mult_add, biv_total_increment, reg_dead_after_loop, final_biv_value, loop_find_equiv_value, find_common_reg_term, loop_iterations, final_giv_value): Moved from unroll.c. (uid_luid, uid_loop, max_uid_for_loop, max_reg_before_loop, loop_dump_stream, for_each_insn_in_loop, express_from, extend_value_for_giv, loop_iv_add_mult_emit_before, loop_iv_add_mult_sink, loop_iv_add_mult_hoist, loop_insn_first_p, get_condition_for_loop, loop_insn_emit_before, loop_insn_hoist, loop_insn_sink): Made static. (loop_invariant_p): Made static. Removed flag_old_unroll_loops reference. (strength_reduce): Do not call unroller. (record_giv): Do not initialize unrolled field. (prescan_loop): Do not set loop_info->preconditioned. * passes.c: Do not include loop.h. (rest_of_handle_loop_optimize): Do not call unroller. * predict.c: Do not include loop.h. * rtl.h (NOTE_PRECONDITIONED): Removed. * stmt.c: Do not include loop.h. * toplev.c: Do not include loop.h. (process_options): Do not handle flag_old_unroll_loops. * doc/invoke.texi (fold-unroll-loops, fold-unroll-all-loops): Documentation removed. * doc/passes.texi (unroll.c, loop.h): Documentation removed. From-SVN: r87485
This commit is contained in:
parent
032618223b
commit
c94583fe55
@ -1,3 +1,49 @@
|
||||
2004-09-14 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
|
||||
|
||||
* unroll.c: Removed.
|
||||
* loop.h: Removed.
|
||||
* Makefile.in (LOOP_H, unroll.o): Removed.
|
||||
(toplev.o, passes.o, stmt.o, integrate.o, loop.o): Remove LOOP_H
|
||||
dependency.
|
||||
* alias.c (init_alias_analysis): Remove flag_old_unroll_loops
|
||||
reference.
|
||||
* cfgloop.h (LOOP_PREFETCH, loop_optimize): Moved from loop.h.
|
||||
* common.opt (fold-unroll-loops, fold-unroll-all-loops): Removed.
|
||||
* loop.c: Do not include loop.h.
|
||||
(LOOP_INFO, LOOP_MOVABLES, LOOP_REGS, LOOP_IVS, INSN_LUID,
|
||||
REGNO_FIRST_LUID, REGNO_LAST_LUID, enum g_types, struct induction,
|
||||
struct iv_class, enum iv_mode, struct iv, REG_IV_TYPE, REG_IV_INFO,
|
||||
REG_IV_CLASS, struct loop_ivs, struct loop_mem_info, struct loop_reg,
|
||||
struct loop_regs, struct loop_movables, struct loop_info): Moved
|
||||
from loop.h.
|
||||
(back_branch_in_range_p, fold_rtx_mult_add, biv_total_increment,
|
||||
reg_dead_after_loop, final_biv_value, loop_find_equiv_value,
|
||||
find_common_reg_term, loop_iterations, final_giv_value): Moved
|
||||
from unroll.c.
|
||||
(uid_luid, uid_loop, max_uid_for_loop, max_reg_before_loop,
|
||||
loop_dump_stream, for_each_insn_in_loop, express_from,
|
||||
extend_value_for_giv, loop_iv_add_mult_emit_before,
|
||||
loop_iv_add_mult_sink, loop_iv_add_mult_hoist,
|
||||
loop_insn_first_p, get_condition_for_loop,
|
||||
loop_insn_emit_before, loop_insn_hoist,
|
||||
loop_insn_sink): Made static.
|
||||
(loop_invariant_p): Made static. Removed flag_old_unroll_loops
|
||||
reference.
|
||||
(strength_reduce): Do not call unroller.
|
||||
(record_giv): Do not initialize unrolled field.
|
||||
(prescan_loop): Do not set loop_info->preconditioned.
|
||||
* passes.c: Do not include loop.h.
|
||||
(rest_of_handle_loop_optimize): Do not call unroller.
|
||||
* predict.c: Do not include loop.h.
|
||||
* rtl.h (NOTE_PRECONDITIONED): Removed.
|
||||
* stmt.c: Do not include loop.h.
|
||||
* toplev.c: Do not include loop.h.
|
||||
(process_options): Do not handle flag_old_unroll_loops.
|
||||
|
||||
* doc/invoke.texi (fold-unroll-loops, fold-unroll-all-loops):
|
||||
Documentation removed.
|
||||
* doc/passes.texi (unroll.c, loop.h): Documentation removed.
|
||||
|
||||
2004-09-14 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* Makefile.in (STAGE1_CHECKING): New variable.
|
||||
|
@ -701,7 +701,6 @@ RA_H = ra.h bitmap.h sbitmap.h hard-reg-set.h insn-modes.h
|
||||
RESOURCE_H = resource.h hard-reg-set.h
|
||||
SCHED_INT_H = sched-int.h $(INSN_ATTR_H) $(BASIC_BLOCK_H) $(RTL_H)
|
||||
INTEGRATE_H = integrate.h varray.h
|
||||
LOOP_H = loop.h varray.h bitmap.h
|
||||
CFGLAYOUT_H = cfglayout.h $(BASIC_BLOCK_H)
|
||||
CFGLOOP_H = cfgloop.h $(BASIC_BLOCK_H) $(RTL_H)
|
||||
CGRAPH_H = cgraph.h bitmap.h tree.h $(HASHTAB_H)
|
||||
@ -921,7 +920,7 @@ OBJS-common = \
|
||||
reload.o reload1.o reorg.o resource.o rtl.o rtlanal.o rtl-error.o \
|
||||
sbitmap.o sched-deps.o sched-ebb.o sched-rgn.o sched-vis.o sdbout.o \
|
||||
simplify-rtx.o sreal.o stmt.o stor-layout.o stringpool.o \
|
||||
targhooks.o timevar.o toplev.o tracer.o tree.o tree-dump.o unroll.o \
|
||||
targhooks.o timevar.o toplev.o tracer.o tree.o tree-dump.o \
|
||||
varasm.o varray.o vec.o version.o vmsdbgout.o xcoffout.o alloc-pool.o \
|
||||
et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) web.o passes.o \
|
||||
rtl-profile.o tree-profile.o rtlhooks.o cfgexpand.o lambda-mat.o \
|
||||
@ -1719,7 +1718,7 @@ tree-ssa-loop-manip.o : tree-ssa-loop-manip.c $(TREE_FLOW_H) $(CONFIG_H) \
|
||||
tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_FLOW_H) $(CONFIG_H) \
|
||||
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h $(PARAMS_H)\
|
||||
output.h diagnostic.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
|
||||
tree-pass.h flags.h
|
||||
tree-pass.h flags.h $(HASHTAB_H)
|
||||
tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
||||
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) tree-inline.h $(FLAGS_H) \
|
||||
function.h $(TIMEVAR_H) convert.h $(TM_H) coretypes.h \
|
||||
@ -1793,7 +1792,7 @@ toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) versio
|
||||
function.h $(FLAGS_H) xcoffout.h input.h $(INSN_ATTR_H) output.h $(DIAGNOSTIC_H) \
|
||||
debug.h insn-config.h intl.h $(RECOG_H) Makefile toplev.h \
|
||||
dwarf2out.h sdbout.h dbxout.h $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) \
|
||||
graph.h $(LOOP_H) except.h $(REGS_H) $(TIMEVAR_H) value-prof.h \
|
||||
graph.h except.h $(REGS_H) $(TIMEVAR_H) value-prof.h \
|
||||
$(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
|
||||
langhooks.h insn-flags.h $(CFGLAYOUT_H) real.h $(CFGLOOP_H) \
|
||||
hosthooks.h $(LANGHOOKS_DEF_H) $(CGRAPH_H) $(COVERAGE_H) alloc-pool.h
|
||||
@ -1805,7 +1804,7 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(RTL_H) function.h $(FLAGS_H) xcoffout.h input.h $(INSN_ATTR_H) output.h \
|
||||
$(DIAGNOSTIC_H) debug.h insn-config.h intl.h $(RECOG_H) toplev.h \
|
||||
dwarf2out.h sdbout.h dbxout.h $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) \
|
||||
graph.h $(LOOP_H) except.h $(REGS_H) $(TIMEVAR_H) value-prof.h \
|
||||
graph.h except.h $(REGS_H) $(TIMEVAR_H) value-prof.h \
|
||||
$(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
|
||||
langhooks.h insn-flags.h $(CFGLAYOUT_H) real.h $(CFGLOOP_H) \
|
||||
hosthooks.h $(LANGHOOKS_DEF_H) $(CGRAPH_H) $(COVERAGE_H) alloc-pool.h \
|
||||
@ -1839,7 +1838,7 @@ function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
$(TM_P_H) langhooks.h gt-function.h $(TARGET_H) basic-block.h
|
||||
stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) \
|
||||
function.h insn-config.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \
|
||||
$(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H) \
|
||||
$(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H) \
|
||||
langhooks.h $(PREDICT_H) $(OPTABS_H) $(TARGET_H)
|
||||
except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
$(TREE_H) $(FLAGS_H) except.h function.h $(EXPR_H) libfuncs.h $(INTEGRATE_H) \
|
||||
@ -1900,7 +1899,7 @@ emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(T
|
||||
real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) toplev.h $(TM_P_H)
|
||||
integrate.o : integrate.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
|
||||
$(FLAGS_H) debug.h $(INTEGRATE_H) insn-config.h $(EXPR_H) real.h $(REGS_H) \
|
||||
intl.h function.h output.h $(RECOG_H) except.h toplev.h $(LOOP_H) \
|
||||
intl.h function.h output.h $(RECOG_H) except.h toplev.h \
|
||||
$(PARAMS_H) $(TM_P_H) $(TARGET_H) langhooks.h gt-integrate.h
|
||||
jump.o : jump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \
|
||||
hard-reg-set.h $(REGS_H) insn-config.h $(RECOG_H) $(EXPR_H) real.h except.h function.h \
|
||||
@ -1977,17 +1976,13 @@ rtl-profile.o : tree-profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
value-prof.o : value-prof.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
$(BASIC_BLOCK_H) hard-reg-set.h value-prof.h $(EXPR_H) output.h $(FLAGS_H) \
|
||||
$(RECOG_H) insn-config.h $(OPTABS_H) $(REGS_H) $(GGC_H)
|
||||
loop.o : loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) $(LOOP_H) \
|
||||
loop.o : loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \
|
||||
insn-config.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) \
|
||||
real.h $(PREDICT_H) $(BASIC_BLOCK_H) function.h $(CFGLOOP_H) \
|
||||
toplev.h varray.h except.h cselib.h $(OPTABS_H) $(TM_P_H) $(GGC_H)
|
||||
loop-doloop.o : loop-doloop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \
|
||||
toplev.h $(CFGLOOP_H) output.h $(PARAMS_H)
|
||||
unroll.o : unroll.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) insn-config.h \
|
||||
function.h $(INTEGRATE_H) $(REGS_H) $(RECOG_H) $(FLAGS_H) $(EXPR_H) $(LOOP_H) toplev.h \
|
||||
hard-reg-set.h varray.h $(BASIC_BLOCK_H) $(TM_P_H) $(PREDICT_H) $(PARAMS_H) \
|
||||
$(CFGLOOP_H)
|
||||
alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASHTAB_H)
|
||||
flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
|
||||
$(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
|
||||
|
@ -2763,11 +2763,6 @@ init_alias_analysis (void)
|
||||
|
||||
new_reg_base_value = xmalloc (maxreg * sizeof (rtx));
|
||||
reg_seen = xmalloc (maxreg);
|
||||
if (! reload_completed && flag_old_unroll_loops)
|
||||
{
|
||||
alias_invariant = ggc_calloc (maxreg, sizeof (rtx));
|
||||
alias_invariant_size = maxreg;
|
||||
}
|
||||
|
||||
/* The basic idea is that each pass through this loop will use the
|
||||
"constant" information from the previous pass to propagate alias
|
||||
|
@ -458,4 +458,11 @@ extern void unroll_and_peel_loops (struct loops *, int);
|
||||
extern void doloop_optimize_loops (struct loops *);
|
||||
extern void move_loop_invariants (struct loops *);
|
||||
|
||||
/* Old loop optimizer interface. */
|
||||
|
||||
/* Flags passed to loop_optimize. */
|
||||
#define LOOP_PREFETCH 1
|
||||
|
||||
extern void loop_optimize (rtx, FILE *, int);
|
||||
|
||||
#endif /* GCC_CFGLOOP_H */
|
||||
|
@ -551,14 +551,6 @@ fnon-call-exceptions
|
||||
Common Report Var(flag_non_call_exceptions)
|
||||
Support synchronous non-call exceptions
|
||||
|
||||
fold-unroll-loops
|
||||
Common Report Var(flag_old_unroll_loops)
|
||||
Perform loop unrolling when iteration count is known
|
||||
|
||||
fold-unroll-all-loops
|
||||
Common Report Var(flag_old_unroll_all_loops)
|
||||
Perform loop unrolling for all loops
|
||||
|
||||
fomit-frame-pointer
|
||||
Common Report Var(flag_omit_frame_pointer)
|
||||
When possible do not generate stack frames
|
||||
|
@ -315,7 +315,7 @@ Objective-C and Objective-C++ Dialects}.
|
||||
-fsignaling-nans -fsingle-precision-constant -fspeculative-prefetching @gol
|
||||
-fstrength-reduce -fstrict-aliasing -ftracer -fthread-jumps @gol
|
||||
-funroll-all-loops -funroll-loops -fpeel-loops @gol
|
||||
-funswitch-loops -fold-unroll-loops -fold-unroll-all-loops @gol
|
||||
-funswitch-loops @gol
|
||||
-ftree-pre -ftree-ccp -ftree-dce -ftree-loop-optimize @gol
|
||||
-ftree-loop-linear -ftree-loop-im -ftree-loop-ivcanon -fivopts @gol
|
||||
-ftree-dominator-opts -ftree-dse -ftree-copyrename @gol
|
||||
@ -4423,8 +4423,7 @@ redundant spilling.
|
||||
@item -floop-optimize
|
||||
@opindex floop-optimize
|
||||
Perform loop optimizations: move constant expressions out of loops, simplify
|
||||
exit test conditions and optionally do strength-reduction and loop unrolling as
|
||||
well.
|
||||
exit test conditions and optionally do strength-reduction as well.
|
||||
|
||||
Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
|
||||
|
||||
@ -5222,22 +5221,6 @@ at level @option{-O1}
|
||||
Move branches with loop invariant conditions out of the loop, with duplicates
|
||||
of the loop on both branches (modified according to result of the condition).
|
||||
|
||||
@item -fold-unroll-loops
|
||||
@opindex fold-unroll-loops
|
||||
Unroll loops whose number of iterations can be determined at compile
|
||||
time or upon entry to the loop, using the old loop unroller whose loop
|
||||
recognition is based on notes from frontend. @option{-fold-unroll-loops} implies
|
||||
both @option{-fstrength-reduce} and @option{-frerun-cse-after-loop}. This
|
||||
option makes code larger, and may or may not make it run faster.
|
||||
|
||||
@item -fold-unroll-all-loops
|
||||
@opindex fold-unroll-all-loops
|
||||
Unroll all loops, even if their number of iterations is uncertain when
|
||||
the loop is entered. This is done using the old loop unroller whose loop
|
||||
recognition is based on notes from frontend. This usually makes programs run more slowly.
|
||||
@option{-fold-unroll-all-loops} implies the same options as
|
||||
@option{-fold-unroll-loops}.
|
||||
|
||||
@item -fprefetch-loop-arrays
|
||||
@opindex fprefetch-loop-arrays
|
||||
If supported by the target machine, generate instructions to prefetch
|
||||
|
@ -540,11 +540,8 @@ are in @file{lcm.c}.
|
||||
|
||||
@item Loop optimization
|
||||
|
||||
This pass moves constant expressions out of loops,
|
||||
and optionally does strength-reduction and loop unrolling as well.
|
||||
Its source files are @file{loop.c} and @file{unroll.c}, plus the header
|
||||
@file{loop.h} used for communication between them. Loop unrolling uses
|
||||
some functions in @file{integrate.c} and the header @file{integrate.h}.
|
||||
This pass moves constant expressions out of loops, and optionally does
|
||||
strength-reduction as well. The pass is located in @file{loop.c}.
|
||||
Loop dependency analysis routines are contained in @file{dependence.c}.
|
||||
This pass is seriously out-of-date and is supposed to be replaced by
|
||||
a new one described below in near future.
|
||||
|
1514
gcc/loop.c
1514
gcc/loop.c
File diff suppressed because it is too large
Load Diff
430
gcc/loop.h
430
gcc/loop.h
@ -1,430 +0,0 @@
|
||||
/* Loop optimization definitions for GCC
|
||||
Copyright (C) 1991, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
#include "bitmap.h"
|
||||
#include "sbitmap.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "basic-block.h"
|
||||
|
||||
/* Flags passed to loop_optimize. */
|
||||
#define LOOP_UNROLL 1
|
||||
#define LOOP_PREFETCH 2
|
||||
#define LOOP_AUTO_UNROLL 4
|
||||
|
||||
/* Get the loop info pointer of a loop. */
|
||||
#define LOOP_INFO(LOOP) ((struct loop_info *) (LOOP)->aux)
|
||||
|
||||
/* Get a pointer to the loop movables structure. */
|
||||
#define LOOP_MOVABLES(LOOP) (&LOOP_INFO (LOOP)->movables)
|
||||
|
||||
/* Get a pointer to the loop registers structure. */
|
||||
#define LOOP_REGS(LOOP) (&LOOP_INFO (LOOP)->regs)
|
||||
|
||||
/* Get a pointer to the loop induction variables structure. */
|
||||
#define LOOP_IVS(LOOP) (&LOOP_INFO (LOOP)->ivs)
|
||||
|
||||
/* Get the luid of an insn. Catch the error of trying to reference the LUID
|
||||
of an insn added during loop, since these don't have LUIDs. */
|
||||
|
||||
#define INSN_LUID(INSN) \
|
||||
(INSN_UID (INSN) < max_uid_for_loop ? uid_luid[INSN_UID (INSN)] \
|
||||
: (abort (), -1))
|
||||
|
||||
#define REGNO_FIRST_LUID(REGNO) \
|
||||
(REGNO_FIRST_UID (REGNO) < max_uid_for_loop \
|
||||
? uid_luid[REGNO_FIRST_UID (REGNO)] \
|
||||
: 0)
|
||||
#define REGNO_LAST_LUID(REGNO) \
|
||||
(REGNO_LAST_UID (REGNO) < max_uid_for_loop \
|
||||
? uid_luid[REGNO_LAST_UID (REGNO)] \
|
||||
: INT_MAX)
|
||||
|
||||
/* A "basic induction variable" or biv is a pseudo reg that is set
|
||||
(within this loop) only by incrementing or decrementing it. */
|
||||
/* A "general induction variable" or giv is a pseudo reg whose
|
||||
value is a linear function of a biv. */
|
||||
|
||||
/* Bivs are recognized by `basic_induction_var';
|
||||
Givs by `general_induction_var'. */
|
||||
|
||||
/* An enum for the two different types of givs, those that are used
|
||||
as memory addresses and those that are calculated into registers. */
|
||||
enum g_types
|
||||
{
|
||||
DEST_ADDR,
|
||||
DEST_REG
|
||||
};
|
||||
|
||||
|
||||
/* A `struct induction' is created for every instruction that sets
|
||||
an induction variable (either a biv or a giv). */
|
||||
|
||||
struct induction
|
||||
{
|
||||
rtx insn; /* The insn that sets a biv or giv */
|
||||
rtx new_reg; /* New register, containing strength reduced
|
||||
version of this giv. */
|
||||
rtx src_reg; /* Biv from which this giv is computed.
|
||||
(If this is a biv, then this is the biv.) */
|
||||
enum g_types giv_type; /* Indicate whether DEST_ADDR or DEST_REG */
|
||||
rtx dest_reg; /* Destination register for insn: this is the
|
||||
register which was the biv or giv.
|
||||
For a biv, this equals src_reg.
|
||||
For a DEST_ADDR type giv, this is 0. */
|
||||
rtx *location; /* Place in the insn where this giv occurs.
|
||||
If GIV_TYPE is DEST_REG, this is 0. */
|
||||
/* For a biv, this is the place where add_val
|
||||
was found. */
|
||||
enum machine_mode mode; /* The mode of this biv or giv */
|
||||
rtx mem; /* For DEST_ADDR, the memory object. */
|
||||
rtx mult_val; /* Multiplicative factor for src_reg. */
|
||||
rtx add_val; /* Additive constant for that product. */
|
||||
int benefit; /* Gain from eliminating this insn. */
|
||||
rtx final_value; /* If the giv is used outside the loop, and its
|
||||
final value could be calculated, it is put
|
||||
here, and the giv is made replaceable. Set
|
||||
the giv to this value before the loop. */
|
||||
unsigned combined_with; /* The number of givs this giv has been
|
||||
combined with. If nonzero, this giv
|
||||
cannot combine with any other giv. */
|
||||
unsigned replaceable : 1; /* 1 if we can substitute the strength-reduced
|
||||
variable for the original variable.
|
||||
0 means they must be kept separate and the
|
||||
new one must be copied into the old pseudo
|
||||
reg each time the old one is set. */
|
||||
unsigned not_replaceable : 1; /* Used to prevent duplicating work. This is
|
||||
1 if we know that the giv definitely can
|
||||
not be made replaceable, in which case we
|
||||
don't bother checking the variable again
|
||||
even if further info is available.
|
||||
Both this and the above can be zero. */
|
||||
unsigned ignore : 1; /* 1 prohibits further processing of giv */
|
||||
unsigned always_computable : 1;/* 1 if this value is computable every
|
||||
iteration. */
|
||||
unsigned always_executed : 1; /* 1 if this set occurs each iteration. */
|
||||
unsigned maybe_multiple : 1; /* Only used for a biv and 1 if this biv
|
||||
update may be done multiple times per
|
||||
iteration. */
|
||||
unsigned cant_derive : 1; /* For giv's, 1 if this giv cannot derive
|
||||
another giv. This occurs in many cases
|
||||
where a giv's lifetime spans an update to
|
||||
a biv. */
|
||||
unsigned maybe_dead : 1; /* 1 if this giv might be dead. In that case,
|
||||
we won't use it to eliminate a biv, it
|
||||
would probably lose. */
|
||||
unsigned auto_inc_opt : 1; /* 1 if this giv had its increment output next
|
||||
to it to try to form an auto-inc address. */
|
||||
unsigned unrolled : 1; /* 1 if new register has been allocated and
|
||||
initialized in unrolled loop. */
|
||||
unsigned shared : 1;
|
||||
unsigned no_const_addval : 1; /* 1 if add_val does not contain a const. */
|
||||
int lifetime; /* Length of life of this giv */
|
||||
rtx derive_adjustment; /* If nonzero, is an adjustment to be
|
||||
subtracted from add_val when this giv
|
||||
derives another. This occurs when the
|
||||
giv spans a biv update by incrementation. */
|
||||
rtx ext_dependent; /* If nonzero, is a sign or zero extension
|
||||
if a biv on which this giv is dependent. */
|
||||
struct induction *next_iv; /* For givs, links together all givs that are
|
||||
based on the same biv. For bivs, links
|
||||
together all biv entries that refer to the
|
||||
same biv register. */
|
||||
struct induction *same; /* For givs, if the giv has been combined with
|
||||
another giv, this points to the base giv.
|
||||
The base giv will have COMBINED_WITH nonzero.
|
||||
For bivs, if the biv has the same LOCATION
|
||||
than another biv, this points to the base
|
||||
biv. */
|
||||
HOST_WIDE_INT const_adjust; /* Used by loop unrolling, when an address giv
|
||||
is split, and a constant is eliminated from
|
||||
the address, the -constant is stored here
|
||||
for later use. */
|
||||
struct induction *same_insn; /* If there are multiple identical givs in
|
||||
the same insn, then all but one have this
|
||||
field set, and they all point to the giv
|
||||
that doesn't have this field set. */
|
||||
rtx last_use; /* For a giv made from a biv increment, this is
|
||||
a substitute for the lifetime information. */
|
||||
};
|
||||
|
||||
|
||||
/* A `struct iv_class' is created for each biv. */
|
||||
|
||||
struct iv_class
|
||||
{
|
||||
unsigned int regno; /* Pseudo reg which is the biv. */
|
||||
int biv_count; /* Number of insns setting this reg. */
|
||||
struct induction *biv; /* List of all insns that set this reg. */
|
||||
int giv_count; /* Number of DEST_REG givs computed from this
|
||||
biv. The resulting count is only used in
|
||||
check_dbra_loop. */
|
||||
struct induction *giv; /* List of all insns that compute a giv
|
||||
from this reg. */
|
||||
int total_benefit; /* Sum of BENEFITs of all those givs. */
|
||||
rtx initial_value; /* Value of reg at loop start. */
|
||||
rtx initial_test; /* Test performed on BIV before loop. */
|
||||
rtx final_value; /* Value of reg at loop end, if known. */
|
||||
struct iv_class *next; /* Links all class structures together. */
|
||||
rtx init_insn; /* insn which initializes biv, 0 if none. */
|
||||
rtx init_set; /* SET of INIT_INSN, if any. */
|
||||
unsigned incremented : 1; /* 1 if somewhere incremented/decremented */
|
||||
unsigned eliminable : 1; /* 1 if plausible candidate for
|
||||
elimination. */
|
||||
unsigned nonneg : 1; /* 1 if we added a REG_NONNEG note for
|
||||
this. */
|
||||
unsigned reversed : 1; /* 1 if we reversed the loop that this
|
||||
biv controls. */
|
||||
unsigned all_reduced : 1; /* 1 if all givs using this biv have
|
||||
been reduced. */
|
||||
};
|
||||
|
||||
|
||||
/* Definitions used by the basic induction variable discovery code. */
|
||||
enum iv_mode
|
||||
{
|
||||
UNKNOWN_INDUCT,
|
||||
BASIC_INDUCT,
|
||||
NOT_BASIC_INDUCT,
|
||||
GENERAL_INDUCT
|
||||
};
|
||||
|
||||
|
||||
/* A `struct iv' is created for every register. */
|
||||
|
||||
struct iv
|
||||
{
|
||||
enum iv_mode type;
|
||||
union
|
||||
{
|
||||
struct iv_class *class;
|
||||
struct induction *info;
|
||||
} iv;
|
||||
};
|
||||
|
||||
|
||||
#define REG_IV_TYPE(ivs, n) ivs->regs[n].type
|
||||
#define REG_IV_INFO(ivs, n) ivs->regs[n].iv.info
|
||||
#define REG_IV_CLASS(ivs, n) ivs->regs[n].iv.class
|
||||
|
||||
|
||||
struct loop_ivs
|
||||
{
|
||||
/* Indexed by register number, contains pointer to `struct
|
||||
iv' if register is an induction variable. */
|
||||
struct iv *regs;
|
||||
|
||||
/* Size of regs array. */
|
||||
unsigned int n_regs;
|
||||
|
||||
/* The head of a list which links together (via the next field)
|
||||
every iv class for the current loop. */
|
||||
struct iv_class *list;
|
||||
};
|
||||
|
||||
|
||||
typedef struct loop_mem_info
|
||||
{
|
||||
rtx mem; /* The MEM itself. */
|
||||
rtx reg; /* Corresponding pseudo, if any. */
|
||||
int optimize; /* Nonzero if we can optimize access to this MEM. */
|
||||
} loop_mem_info;
|
||||
|
||||
|
||||
|
||||
struct loop_reg
|
||||
{
|
||||
/* Number of times the reg is set during the loop being scanned.
|
||||
During code motion, a negative value indicates a reg that has
|
||||
been made a candidate; in particular -2 means that it is an
|
||||
candidate that we know is equal to a constant and -1 means that
|
||||
it is a candidate not known equal to a constant. After code
|
||||
motion, regs moved have 0 (which is accurate now) while the
|
||||
failed candidates have the original number of times set.
|
||||
|
||||
Therefore, at all times, == 0 indicates an invariant register;
|
||||
< 0 a conditionally invariant one. */
|
||||
int set_in_loop;
|
||||
|
||||
/* Original value of set_in_loop; same except that this value
|
||||
is not set negative for a reg whose sets have been made candidates
|
||||
and not set to 0 for a reg that is moved. */
|
||||
int n_times_set;
|
||||
|
||||
/* Contains the insn in which a register was used if it was used
|
||||
exactly once; contains const0_rtx if it was used more than once. */
|
||||
rtx single_usage;
|
||||
|
||||
/* Nonzero indicates that the register cannot be moved or strength
|
||||
reduced. */
|
||||
char may_not_optimize;
|
||||
|
||||
/* Nonzero means reg N has already been moved out of one loop.
|
||||
This reduces the desire to move it out of another. */
|
||||
char moved_once;
|
||||
};
|
||||
|
||||
|
||||
struct loop_regs
|
||||
{
|
||||
int num; /* Number of regs used in table. */
|
||||
int size; /* Size of table. */
|
||||
struct loop_reg *array; /* Register usage info. array. */
|
||||
int multiple_uses; /* Nonzero if a reg has multiple uses. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct loop_movables
|
||||
{
|
||||
/* Head of movable chain. */
|
||||
struct movable *head;
|
||||
/* Last movable in chain. */
|
||||
struct movable *last;
|
||||
};
|
||||
|
||||
|
||||
/* Information pertaining to a loop. */
|
||||
|
||||
struct loop_info
|
||||
{
|
||||
/* Nonzero if there is a subroutine call in the current loop. */
|
||||
int has_call;
|
||||
/* Nonzero if there is a libcall in the current loop. */
|
||||
int has_libcall;
|
||||
/* Nonzero if there is a non constant call in the current loop. */
|
||||
int has_nonconst_call;
|
||||
/* Nonzero if there is a prefetch instruction in the current loop. */
|
||||
int has_prefetch;
|
||||
/* Nonzero if there is a volatile memory reference in the current
|
||||
loop. */
|
||||
int has_volatile;
|
||||
/* Nonzero if there is a tablejump in the current loop. */
|
||||
int has_tablejump;
|
||||
/* Nonzero if there are ways to leave the loop other than falling
|
||||
off the end. */
|
||||
int has_multiple_exit_targets;
|
||||
/* Nonzero if there is an indirect jump in the current function. */
|
||||
int has_indirect_jump;
|
||||
/* Whether loop unrolling has emitted copies of the loop body so
|
||||
that the main loop needs no exit tests. */
|
||||
int preconditioned;
|
||||
/* Register or constant initial loop value. */
|
||||
rtx initial_value;
|
||||
/* Register or constant value used for comparison test. */
|
||||
rtx comparison_value;
|
||||
/* Register or constant approximate final value. */
|
||||
rtx final_value;
|
||||
/* Register or constant initial loop value with term common to
|
||||
final_value removed. */
|
||||
rtx initial_equiv_value;
|
||||
/* Register or constant final loop value with term common to
|
||||
initial_value removed. */
|
||||
rtx final_equiv_value;
|
||||
/* Register corresponding to iteration variable. */
|
||||
rtx iteration_var;
|
||||
/* Constant loop increment. */
|
||||
rtx increment;
|
||||
enum rtx_code comparison_code;
|
||||
/* Holds the number of loop iterations. It is zero if the number
|
||||
could not be calculated. Must be unsigned since the number of
|
||||
iterations can be as high as 2^wordsize - 1. For loops with a
|
||||
wider iterator, this number will be zero if the number of loop
|
||||
iterations is too large for an unsigned integer to hold. */
|
||||
unsigned HOST_WIDE_INT n_iterations;
|
||||
/* The number of times the loop body was unrolled. */
|
||||
unsigned int unroll_number;
|
||||
int used_count_register;
|
||||
/* The loop iterator induction variable. */
|
||||
struct iv_class *iv;
|
||||
/* List of MEMs that are stored in this loop. */
|
||||
rtx store_mems;
|
||||
/* Array of MEMs that are used (read or written) in this loop, but
|
||||
cannot be aliased by anything in this loop, except perhaps
|
||||
themselves. In other words, if mems[i] is altered during
|
||||
the loop, it is altered by an expression that is rtx_equal_p to
|
||||
it. */
|
||||
loop_mem_info *mems;
|
||||
/* The index of the next available slot in MEMS. */
|
||||
int mems_idx;
|
||||
/* The number of elements allocated in MEMS. */
|
||||
int mems_allocated;
|
||||
/* Nonzero if we don't know what MEMs were changed in the current
|
||||
loop. This happens if the loop contains a call (in which case
|
||||
`has_call' will also be set) or if we store into more than
|
||||
NUM_STORES MEMs. */
|
||||
int unknown_address_altered;
|
||||
/* The above doesn't count any readonly memory locations that are
|
||||
stored. This does. */
|
||||
int unknown_constant_address_altered;
|
||||
/* Count of memory write instructions discovered in the loop. */
|
||||
int num_mem_sets;
|
||||
/* The insn where the first of these was found. */
|
||||
rtx first_loop_store_insn;
|
||||
/* The chain of movable insns in loop. */
|
||||
struct loop_movables movables;
|
||||
/* The registers used the in loop. */
|
||||
struct loop_regs regs;
|
||||
/* The induction variable information in loop. */
|
||||
struct loop_ivs ivs;
|
||||
/* Nonzero if call is in pre_header extended basic block. */
|
||||
int pre_header_has_call;
|
||||
};
|
||||
|
||||
|
||||
/* Variables declared in loop.c, but also needed in unroll.c. */
|
||||
|
||||
extern int *uid_luid;
|
||||
extern int max_uid_for_loop;
|
||||
extern unsigned int max_reg_before_loop;
|
||||
extern struct loop **uid_loop;
|
||||
extern FILE *loop_dump_stream;
|
||||
|
||||
|
||||
/* Forward declarations for non-static functions declared in loop.c and
|
||||
unroll.c. */
|
||||
extern int loop_invariant_p (const struct loop *, rtx);
|
||||
extern rtx get_condition_for_loop (const struct loop *, rtx);
|
||||
extern void loop_iv_add_mult_hoist (const struct loop *, rtx, rtx, rtx, rtx);
|
||||
extern void loop_iv_add_mult_sink (const struct loop *, rtx, rtx, rtx, rtx);
|
||||
extern void loop_iv_add_mult_emit_before (const struct loop *, rtx, rtx,
|
||||
rtx, rtx, basic_block, rtx);
|
||||
extern rtx express_from (struct induction *, struct induction *);
|
||||
extern rtx extend_value_for_giv (struct induction *, rtx);
|
||||
|
||||
extern void unroll_loop (struct loop *, int, int);
|
||||
extern rtx biv_total_increment (const struct iv_class *);
|
||||
extern unsigned HOST_WIDE_INT loop_iterations (struct loop *);
|
||||
extern int precondition_loop_p (const struct loop *, rtx *, rtx *, rtx *,
|
||||
enum machine_mode *mode);
|
||||
extern rtx final_biv_value (const struct loop *, struct iv_class *);
|
||||
extern rtx final_giv_value (const struct loop *, struct induction *);
|
||||
extern void emit_unrolled_add (rtx, rtx, rtx);
|
||||
extern int back_branch_in_range_p (const struct loop *, rtx);
|
||||
|
||||
extern int loop_insn_first_p (rtx, rtx);
|
||||
typedef rtx (*loop_insn_callback) (struct loop *, rtx, int, int);
|
||||
extern void for_each_insn_in_loop (struct loop *, loop_insn_callback);
|
||||
extern rtx loop_insn_emit_before (const struct loop *, basic_block, rtx, rtx);
|
||||
extern rtx loop_insn_sink (const struct loop *, rtx);
|
||||
extern rtx loop_insn_hoist (const struct loop *, rtx);
|
||||
|
||||
/* Forward declarations for non-static functions declared in doloop.c. */
|
||||
extern int doloop_optimize (const struct loop *);
|
12
gcc/passes.c
12
gcc/passes.c
@ -60,7 +60,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "intl.h"
|
||||
#include "ggc.h"
|
||||
#include "graph.h"
|
||||
#include "loop.h"
|
||||
#include "regs.h"
|
||||
#include "timevar.h"
|
||||
#include "diagnostic.h"
|
||||
@ -1130,7 +1129,7 @@ rest_of_handle_gcse (void)
|
||||
static void
|
||||
rest_of_handle_loop_optimize (void)
|
||||
{
|
||||
int do_unroll, do_prefetch;
|
||||
int do_prefetch;
|
||||
|
||||
timevar_push (TV_LOOP);
|
||||
delete_dead_jumptables ();
|
||||
@ -1140,10 +1139,6 @@ rest_of_handle_loop_optimize (void)
|
||||
/* CFG is no longer maintained up-to-date. */
|
||||
free_bb_for_insn ();
|
||||
|
||||
if (flag_unroll_loops)
|
||||
do_unroll = LOOP_AUTO_UNROLL; /* Having two unrollers is useless. */
|
||||
else
|
||||
do_unroll = flag_old_unroll_loops ? LOOP_UNROLL : LOOP_AUTO_UNROLL;
|
||||
do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0;
|
||||
|
||||
if (flag_rerun_loop_opt)
|
||||
@ -1151,8 +1146,7 @@ rest_of_handle_loop_optimize (void)
|
||||
cleanup_barriers ();
|
||||
|
||||
/* We only want to perform unrolling once. */
|
||||
loop_optimize (get_insns (), dump_file, do_unroll);
|
||||
do_unroll = 0;
|
||||
loop_optimize (get_insns (), dump_file, 0);
|
||||
|
||||
/* The first call to loop_optimize makes some instructions
|
||||
trivially dead. We delete those instructions now in the
|
||||
@ -1165,7 +1159,7 @@ rest_of_handle_loop_optimize (void)
|
||||
reg_scan (get_insns (), max_reg_num (), 1);
|
||||
}
|
||||
cleanup_barriers ();
|
||||
loop_optimize (get_insns (), dump_file, do_unroll | do_prefetch);
|
||||
loop_optimize (get_insns (), dump_file, do_prefetch);
|
||||
|
||||
/* Loop can create trivially dead instructions. */
|
||||
delete_trivially_dead_insns (get_insns (), max_reg_num ());
|
||||
|
@ -51,7 +51,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "sreal.h"
|
||||
#include "params.h"
|
||||
#include "target.h"
|
||||
#include "loop.h"
|
||||
#include "cfgloop.h"
|
||||
#include "tree-flow.h"
|
||||
#include "ggc.h"
|
||||
|
@ -788,7 +788,6 @@ extern const char * const reg_note_name[];
|
||||
#define NOTE_BASIC_BLOCK(INSN) XCBBDEF (INSN, 4, NOTE)
|
||||
#define NOTE_EXPECTED_VALUE(INSN) XCEXP (INSN, 4, NOTE)
|
||||
#define NOTE_PREDICTION(INSN) XCINT (INSN, 4, NOTE)
|
||||
#define NOTE_PRECONDITIONED(INSN) XCINT (INSN, 4, NOTE)
|
||||
#define NOTE_VAR_LOCATION(INSN) XCEXP (INSN, 4, NOTE)
|
||||
|
||||
/* In a NOTE that is a line number, this is the line number.
|
||||
|
@ -39,7 +39,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "expr.h"
|
||||
#include "libfuncs.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "loop.h"
|
||||
#include "recog.h"
|
||||
#include "machmode.h"
|
||||
#include "toplev.h"
|
||||
|
20
gcc/toplev.c
20
gcc/toplev.c
@ -61,7 +61,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "intl.h"
|
||||
#include "ggc.h"
|
||||
#include "graph.h"
|
||||
#include "loop.h"
|
||||
#include "regs.h"
|
||||
#include "timevar.h"
|
||||
#include "diagnostic.h"
|
||||
@ -1684,24 +1683,7 @@ process_options (void)
|
||||
if (flag_unroll_all_loops)
|
||||
flag_unroll_loops = 1;
|
||||
|
||||
if (flag_unroll_loops)
|
||||
{
|
||||
flag_old_unroll_loops = 0;
|
||||
flag_old_unroll_all_loops = 0;
|
||||
}
|
||||
|
||||
if (flag_old_unroll_all_loops)
|
||||
flag_old_unroll_loops = 1;
|
||||
|
||||
/* Old loop unrolling requires that strength_reduction be on also. Silently
|
||||
turn on strength reduction here if it isn't already on. Also, the loop
|
||||
unrolling code assumes that cse will be run after loop, so that must
|
||||
be turned on also. */
|
||||
if (flag_old_unroll_loops)
|
||||
{
|
||||
flag_strength_reduce = 1;
|
||||
flag_rerun_cse_after_loop = 1;
|
||||
}
|
||||
/* The loop unrolling code assumes that cse will be run after loop. */
|
||||
if (flag_unroll_loops || flag_peel_loops)
|
||||
flag_rerun_cse_after_loop = 1;
|
||||
|
||||
|
3840
gcc/unroll.c
3840
gcc/unroll.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user