1992-03-14 00:04:21 -05:00
|
|
|
/* Loop optimization definitions for GNU C-Compiler
|
1999-01-28 10:36:05 -05:00
|
|
|
Copyright (C) 1991, 1995, 1998, 1999 Free Software Foundation, Inc.
|
1992-03-14 00:04:21 -05:00
|
|
|
|
|
|
|
This file is part of GNU CC.
|
|
|
|
|
|
|
|
GNU CC 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.
|
|
|
|
|
|
|
|
GNU CC 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 GNU CC; see the file COPYING. If not, write to
|
1995-06-15 07:52:21 -04:00
|
|
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
|
|
Boston, MA 02111-1307, USA. */
|
1992-03-14 00:04:21 -05:00
|
|
|
|
rtl.h (insn_first_p): Declare.
* rtl.h (insn_first_p): Declare.
* rtlanal.c (insn_first_p): New function.
* loop.h (varray.h): Include.
(struct induction): Change combined_with to unsigned.
New members derived, ix and last_use.
(reg_iv_type, reg_iv_info): Now varray_type. All references changed.
(REG_IV_TYPE, REG_IV_INFO): Define.
(first_increment_giv, last_increment_giv): Declare.
* loop.c (loop_number_loop_cont): New static variable.
(loop_number_cont_dominator): Likewise.
(reg_iv_type, reg_iv_info): Now varray_type.
(first_increment_giv, last_increment_giv): New variables.
(compute_luids, verify_dominator, find_life_end): New functions.
(cmp_recombine_givs_stats, recombine_givs): Likewise.
(loop_optimize): Allocate loop_number_loop_cont and
loop_number_cont_dominator. Use compute_luids.
(find_and_verify_loops): Initialize loop_number_loop_cont and
loop_number_cont_dominator.
(strength_reduce): Try to find bivs that can be expressed as givs
of another biv, and to convert biv increments into givs.
Call recombine_givs. Handle derived givs.
(record_biv): New argument location. All callers changed.
(record_giv): Initialize derived and last_use fields.
(basic_induction_var): New argument location. All callers changed.
(combine_givs): Don't combine a DEST_REG giv with a DEST_ADDR giv.
Increment combined_with instead of setting to 1.
* unroll.c (derived_regs): New static variable.
(unroll_loop): Initialize it.
Allocate local_regno according to max_reg_num.
(copy_loop_body): Cope with derived givs.
(find_splittable_givs): Check for Givs made from biv increments.
Set derived_regs for givs.
* Makefile.in (stmt.o, loop.o, unroll.o): Depend on loop.h .
From-SVN: r24889
1999-01-27 10:45:50 -05:00
|
|
|
#include "varray.h"
|
|
|
|
|
1992-03-14 00:04:21 -05:00
|
|
|
/* 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))
|
|
|
|
|
|
|
|
/* 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_induct_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. */
|
rtl.h (insn_first_p): Declare.
* rtl.h (insn_first_p): Declare.
* rtlanal.c (insn_first_p): New function.
* loop.h (varray.h): Include.
(struct induction): Change combined_with to unsigned.
New members derived, ix and last_use.
(reg_iv_type, reg_iv_info): Now varray_type. All references changed.
(REG_IV_TYPE, REG_IV_INFO): Define.
(first_increment_giv, last_increment_giv): Declare.
* loop.c (loop_number_loop_cont): New static variable.
(loop_number_cont_dominator): Likewise.
(reg_iv_type, reg_iv_info): Now varray_type.
(first_increment_giv, last_increment_giv): New variables.
(compute_luids, verify_dominator, find_life_end): New functions.
(cmp_recombine_givs_stats, recombine_givs): Likewise.
(loop_optimize): Allocate loop_number_loop_cont and
loop_number_cont_dominator. Use compute_luids.
(find_and_verify_loops): Initialize loop_number_loop_cont and
loop_number_cont_dominator.
(strength_reduce): Try to find bivs that can be expressed as givs
of another biv, and to convert biv increments into givs.
Call recombine_givs. Handle derived givs.
(record_biv): New argument location. All callers changed.
(record_giv): Initialize derived and last_use fields.
(basic_induction_var): New argument location. All callers changed.
(combine_givs): Don't combine a DEST_REG giv with a DEST_ADDR giv.
Increment combined_with instead of setting to 1.
* unroll.c (derived_regs): New static variable.
(unroll_loop): Initialize it.
Allocate local_regno according to max_reg_num.
(copy_loop_body): Cope with derived givs.
(find_splittable_givs): Check for Givs made from biv increments.
Set derived_regs for givs.
* Makefile.in (stmt.o, loop.o, unroll.o): Depend on loop.h .
From-SVN: r24889
1999-01-27 10:45:50 -05:00
|
|
|
/* For a biv, this is the place where add_val
|
|
|
|
was found. */
|
1992-03-14 00:04:21 -05:00
|
|
|
enum machine_mode mode; /* The mode of this biv or giv */
|
|
|
|
enum machine_mode mem_mode; /* For DEST_ADDR, mode of 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. */
|
rtl.h (insn_first_p): Declare.
* rtl.h (insn_first_p): Declare.
* rtlanal.c (insn_first_p): New function.
* loop.h (varray.h): Include.
(struct induction): Change combined_with to unsigned.
New members derived, ix and last_use.
(reg_iv_type, reg_iv_info): Now varray_type. All references changed.
(REG_IV_TYPE, REG_IV_INFO): Define.
(first_increment_giv, last_increment_giv): Declare.
* loop.c (loop_number_loop_cont): New static variable.
(loop_number_cont_dominator): Likewise.
(reg_iv_type, reg_iv_info): Now varray_type.
(first_increment_giv, last_increment_giv): New variables.
(compute_luids, verify_dominator, find_life_end): New functions.
(cmp_recombine_givs_stats, recombine_givs): Likewise.
(loop_optimize): Allocate loop_number_loop_cont and
loop_number_cont_dominator. Use compute_luids.
(find_and_verify_loops): Initialize loop_number_loop_cont and
loop_number_cont_dominator.
(strength_reduce): Try to find bivs that can be expressed as givs
of another biv, and to convert biv increments into givs.
Call recombine_givs. Handle derived givs.
(record_biv): New argument location. All callers changed.
(record_giv): Initialize derived and last_use fields.
(basic_induction_var): New argument location. All callers changed.
(combine_givs): Don't combine a DEST_REG giv with a DEST_ADDR giv.
Increment combined_with instead of setting to 1.
* unroll.c (derived_regs): New static variable.
(unroll_loop): Initialize it.
Allocate local_regno according to max_reg_num.
(copy_loop_body): Cope with derived givs.
(find_splittable_givs): Check for Givs made from biv increments.
Set derived_regs for givs.
* Makefile.in (stmt.o, loop.o, unroll.o): Depend on loop.h .
From-SVN: r24889
1999-01-27 10:45:50 -05:00
|
|
|
unsigned combined_with; /* The number of givs this giv has been
|
|
|
|
combined with. If nonzero, this giv
|
|
|
|
cannot combine with any other giv. */
|
1992-03-14 00:04:21 -05:00
|
|
|
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 */
|
1996-01-24 14:54:00 -05:00
|
|
|
unsigned always_computable : 1;/* 1 if this value is computable every
|
|
|
|
iteration. */
|
|
|
|
unsigned always_executed : 1; /* 1 if this set occurs each iteration. */
|
1992-03-27 18:46:51 -05:00
|
|
|
unsigned maybe_multiple : 1; /* Only used for a biv and 1 if this biv
|
|
|
|
update may be done multiple times per
|
|
|
|
iteration. */
|
1992-03-14 00:04:21 -05:00
|
|
|
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. */
|
1996-01-24 14:54:00 -05:00
|
|
|
unsigned auto_inc_opt : 1; /* 1 if this giv had its increment output next
|
|
|
|
to it to try to form an auto-inc address. */
|
1998-06-19 14:54:44 -04:00
|
|
|
unsigned unrolled : 1; /* 1 if new register has been allocated and
|
|
|
|
initialized in unrolled loop. */
|
* Integrate alias analysis changes from jfc@mit.edu
* Makefile.in (OBJS): Add alias.o
(alias.o): Add dependencies.
* alias.c: New file.
* sched.c: Remove alias analysis code. It lives in alias.c now.
(reg_last_uses_size): Declare.
(sched_analyze_2): Add new arguments to true_dependence.
(sched_analyze_insn): Use reg_last_uses_size instead of max_reg.
(schedule_block): Initialize reg_last_uses_size.
(schedule_insns): Always call init_alias_analysis.
* calls.c (expand_call): Note calls to malloc, calloc, and realloc;
mark return value from such functions as a pointer and keep track of
them for alias analysis. If a return value from a function is a
pointer, mark it as such.
* combine.c (distribute_notes): Handle REG_NOALIAS.
* cse.c (struct write_data): Delete. No longer needed.
(invalidate): Don't call set_nonvarying_address_components anymore.
Use true_dependence to decide if an entry should be removed from
the hash table.
(invalidate_memory): Remove WRITES argument, simplify appropriately.
Fix all callers.
(note_mem_written): Similarly for WRITE_PTR argument.
(invalidate_from_clobbers): Similarly for W argument.
(invalidate_for_call): Remove memory elements from the hash table.
(refers_to_mem_p, cse_rtx_addr_varies_p): Deleted.
(cse_rtx_varies_p): New function. Derived from old
cse_rtx_addr_varies_p.
(cse_insn): Remove WRITES_MEMORY and INIT variables and all references.
Don't call note_mem_written anymore. Stack pushes invalidate the stack
pointer if PUSH_ROUNDING is defined. No longer need to call
cse_rtx_addr_varies_p to decide if a MEM should be invalidated.
(skipped_writes_memory): Remove variable.
(invalidate_skipped_set): Simplify and wewrite to use invalidate_memory.
(invalidate_skipped_block): Simplify for new alias analysis code.
(cse_set_around_loop): Likewise.
(cse_main): Call init_alias_analysis.
* flags.h (flag_alias_check, flag_argument_noalias): Declare.
* toplev.c (flag_alias_check, flag_argument_noalias): Define.
(f_options): Add new alias checking arguments.
(main): Set flag_alias_check when optimizing.
* local_alloc (validate_equiv_mem_from_store): Add new arguments
to true_dependence.
(memref_referenced_p): Likewise.
* loop.c (NUM_STORES): Increase to 30.
(prescan_loop): Only non-constant calls set unknown_address_altered.
(invariant_p): Add new arguments to true_dependence.
(record_giv): Initialize unrolled and shared fields.
(emit_iv_add_mult): Call record_base_value as needed.
* loop.h (struct induction): Add unrolled and shared fields.
* unroll.c (unroll_loop): Call record_base_value as needed.
(copy_loop_body): Likewise.
(final_biv_value): Likewise.
(final_giv_value): Likewise.
(find_splittable_regs): Likewise. Only create one new pseudo
if we have multiple address GIVs that were combined with the same
dst_reg GIV. Note when a new register is created due to unrolling.
* rtl.c (reg_note_name): Add REG_NOALIAS.
* rtl.h (enum reg_note): Similarly.
(rtx_varies_p, may_trap_p, side_effects_p): Declare.
(volatile_refs_p, volatile_insn_p, remove_note): Likewise.
(note_stores, refers_to_regno_p, reg_overlap_mentioned_p): Likewise.
(true_dependence, read_dependence, anti_dependence): Likewise.
(output_dependence, init_alias_analysis, end_alias_analysis): Likewise.
(mark_user_reg, mark_reg_pointer): Likewise.
jfc's alias analysis code.
From-SVN: r14768
1997-08-11 16:07:24 -04:00
|
|
|
unsigned shared : 1;
|
1998-07-17 10:46:06 -04:00
|
|
|
unsigned no_const_addval : 1; /* 1 if add_val does not contain a const. */
|
1992-03-14 00:04:21 -05:00
|
|
|
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. */
|
|
|
|
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; /* If this giv has been combined with another
|
|
|
|
giv, this points to the base giv. The base
|
|
|
|
giv will have COMBINED_WITH non-zero. */
|
1999-02-03 07:48:48 -05:00
|
|
|
struct induction *derived_from;/* For a giv, if we decided to derive this
|
|
|
|
giv from another one. */
|
1992-07-06 15:55:04 -04:00
|
|
|
HOST_WIDE_INT const_adjust; /* Used by loop unrolling, when an address giv
|
1992-03-14 00:04:21 -05:00
|
|
|
is split, and a constant is eliminated from
|
|
|
|
the address, the -constant is stored here
|
|
|
|
for later use. */
|
rtl.h (insn_first_p): Declare.
* rtl.h (insn_first_p): Declare.
* rtlanal.c (insn_first_p): New function.
* loop.h (varray.h): Include.
(struct induction): Change combined_with to unsigned.
New members derived, ix and last_use.
(reg_iv_type, reg_iv_info): Now varray_type. All references changed.
(REG_IV_TYPE, REG_IV_INFO): Define.
(first_increment_giv, last_increment_giv): Declare.
* loop.c (loop_number_loop_cont): New static variable.
(loop_number_cont_dominator): Likewise.
(reg_iv_type, reg_iv_info): Now varray_type.
(first_increment_giv, last_increment_giv): New variables.
(compute_luids, verify_dominator, find_life_end): New functions.
(cmp_recombine_givs_stats, recombine_givs): Likewise.
(loop_optimize): Allocate loop_number_loop_cont and
loop_number_cont_dominator. Use compute_luids.
(find_and_verify_loops): Initialize loop_number_loop_cont and
loop_number_cont_dominator.
(strength_reduce): Try to find bivs that can be expressed as givs
of another biv, and to convert biv increments into givs.
Call recombine_givs. Handle derived givs.
(record_biv): New argument location. All callers changed.
(record_giv): Initialize derived and last_use fields.
(basic_induction_var): New argument location. All callers changed.
(combine_givs): Don't combine a DEST_REG giv with a DEST_ADDR giv.
Increment combined_with instead of setting to 1.
* unroll.c (derived_regs): New static variable.
(unroll_loop): Initialize it.
Allocate local_regno according to max_reg_num.
(copy_loop_body): Cope with derived givs.
(find_splittable_givs): Check for Givs made from biv increments.
Set derived_regs for givs.
* Makefile.in (stmt.o, loop.o, unroll.o): Depend on loop.h .
From-SVN: r24889
1999-01-27 10:45:50 -05:00
|
|
|
int ix; /* Used by recombine_givs, as n index into
|
|
|
|
the stats array. */
|
1995-01-20 21:10:54 -05:00
|
|
|
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. */
|
rtl.h (insn_first_p): Declare.
* rtl.h (insn_first_p): Declare.
* rtlanal.c (insn_first_p): New function.
* loop.h (varray.h): Include.
(struct induction): Change combined_with to unsigned.
New members derived, ix and last_use.
(reg_iv_type, reg_iv_info): Now varray_type. All references changed.
(REG_IV_TYPE, REG_IV_INFO): Define.
(first_increment_giv, last_increment_giv): Declare.
* loop.c (loop_number_loop_cont): New static variable.
(loop_number_cont_dominator): Likewise.
(reg_iv_type, reg_iv_info): Now varray_type.
(first_increment_giv, last_increment_giv): New variables.
(compute_luids, verify_dominator, find_life_end): New functions.
(cmp_recombine_givs_stats, recombine_givs): Likewise.
(loop_optimize): Allocate loop_number_loop_cont and
loop_number_cont_dominator. Use compute_luids.
(find_and_verify_loops): Initialize loop_number_loop_cont and
loop_number_cont_dominator.
(strength_reduce): Try to find bivs that can be expressed as givs
of another biv, and to convert biv increments into givs.
Call recombine_givs. Handle derived givs.
(record_biv): New argument location. All callers changed.
(record_giv): Initialize derived and last_use fields.
(basic_induction_var): New argument location. All callers changed.
(combine_givs): Don't combine a DEST_REG giv with a DEST_ADDR giv.
Increment combined_with instead of setting to 1.
* unroll.c (derived_regs): New static variable.
(unroll_loop): Initialize it.
Allocate local_regno according to max_reg_num.
(copy_loop_body): Cope with derived givs.
(find_splittable_givs): Check for Givs made from biv increments.
Set derived_regs for givs.
* Makefile.in (stmt.o, loop.o, unroll.o): Depend on loop.h .
From-SVN: r24889
1999-01-27 10:45:50 -05:00
|
|
|
rtx last_use; /* For a giv made from a biv increment, this is
|
|
|
|
a substitute for the lifetime information. */
|
1992-03-14 00:04:21 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
/* A `struct iv_class' is created for each biv. */
|
|
|
|
|
|
|
|
struct iv_class {
|
|
|
|
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 */
|
|
|
|
struct iv_class *next; /* Links all class structures together */
|
1992-05-07 02:41:23 -04:00
|
|
|
rtx init_insn; /* insn which initializes biv, 0 if none. */
|
1992-03-14 00:04:21 -05:00
|
|
|
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. */
|
|
|
|
};
|
|
|
|
|
1998-11-25 16:19:21 -05:00
|
|
|
/* Information required to calculate the number of loop iterations.
|
|
|
|
This is set by loop_iterations. */
|
|
|
|
|
|
|
|
struct loop_info
|
|
|
|
{
|
|
|
|
/* 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 loop unrolling factor.
|
|
|
|
Potential values:
|
|
|
|
0: unrolled
|
|
|
|
1: not unrolled.
|
|
|
|
-1: completely unrolled
|
|
|
|
>0: holds the unroll exact factor. */
|
1998-12-15 15:31:18 -05:00
|
|
|
unsigned int unroll_number;
|
|
|
|
/* Non-zero if the loop has a NOTE_INSN_LOOP_VTOP. */
|
|
|
|
rtx vtop;
|
1998-11-25 16:19:21 -05:00
|
|
|
};
|
|
|
|
|
1992-03-14 00:04:21 -05:00
|
|
|
/* Definitions used by the basic induction variable discovery code. */
|
|
|
|
enum iv_mode { UNKNOWN_INDUCT, BASIC_INDUCT, NOT_BASIC_INDUCT,
|
|
|
|
GENERAL_INDUCT };
|
|
|
|
|
|
|
|
/* Variables declared in loop.c, but also needed in unroll.c. */
|
|
|
|
|
|
|
|
extern int *uid_luid;
|
|
|
|
extern int max_uid_for_loop;
|
|
|
|
extern int *uid_loop_num;
|
|
|
|
extern int *loop_outer_loop;
|
|
|
|
extern rtx *loop_number_exit_labels;
|
1995-07-14 08:23:39 -04:00
|
|
|
extern int *loop_number_exit_count;
|
1992-03-14 00:04:21 -05:00
|
|
|
extern int max_reg_before_loop;
|
|
|
|
|
|
|
|
extern FILE *loop_dump_stream;
|
|
|
|
|
rtl.h (insn_first_p): Declare.
* rtl.h (insn_first_p): Declare.
* rtlanal.c (insn_first_p): New function.
* loop.h (varray.h): Include.
(struct induction): Change combined_with to unsigned.
New members derived, ix and last_use.
(reg_iv_type, reg_iv_info): Now varray_type. All references changed.
(REG_IV_TYPE, REG_IV_INFO): Define.
(first_increment_giv, last_increment_giv): Declare.
* loop.c (loop_number_loop_cont): New static variable.
(loop_number_cont_dominator): Likewise.
(reg_iv_type, reg_iv_info): Now varray_type.
(first_increment_giv, last_increment_giv): New variables.
(compute_luids, verify_dominator, find_life_end): New functions.
(cmp_recombine_givs_stats, recombine_givs): Likewise.
(loop_optimize): Allocate loop_number_loop_cont and
loop_number_cont_dominator. Use compute_luids.
(find_and_verify_loops): Initialize loop_number_loop_cont and
loop_number_cont_dominator.
(strength_reduce): Try to find bivs that can be expressed as givs
of another biv, and to convert biv increments into givs.
Call recombine_givs. Handle derived givs.
(record_biv): New argument location. All callers changed.
(record_giv): Initialize derived and last_use fields.
(basic_induction_var): New argument location. All callers changed.
(combine_givs): Don't combine a DEST_REG giv with a DEST_ADDR giv.
Increment combined_with instead of setting to 1.
* unroll.c (derived_regs): New static variable.
(unroll_loop): Initialize it.
Allocate local_regno according to max_reg_num.
(copy_loop_body): Cope with derived givs.
(find_splittable_givs): Check for Givs made from biv increments.
Set derived_regs for givs.
* Makefile.in (stmt.o, loop.o, unroll.o): Depend on loop.h .
From-SVN: r24889
1999-01-27 10:45:50 -05:00
|
|
|
extern varray_type reg_iv_type;
|
|
|
|
extern varray_type reg_iv_info;
|
|
|
|
|
|
|
|
#define REG_IV_TYPE(n) \
|
|
|
|
(*(enum iv_mode *) &VARRAY_INT(reg_iv_type, (n)))
|
|
|
|
#define REG_IV_INFO(n) \
|
|
|
|
(*(struct induction **) &VARRAY_GENERIC_PTR(reg_iv_info, (n)))
|
|
|
|
|
1992-03-14 00:04:21 -05:00
|
|
|
extern struct iv_class **reg_biv_class;
|
|
|
|
extern struct iv_class *loop_iv_list;
|
|
|
|
|
rtl.h (insn_first_p): Declare.
* rtl.h (insn_first_p): Declare.
* rtlanal.c (insn_first_p): New function.
* loop.h (varray.h): Include.
(struct induction): Change combined_with to unsigned.
New members derived, ix and last_use.
(reg_iv_type, reg_iv_info): Now varray_type. All references changed.
(REG_IV_TYPE, REG_IV_INFO): Define.
(first_increment_giv, last_increment_giv): Declare.
* loop.c (loop_number_loop_cont): New static variable.
(loop_number_cont_dominator): Likewise.
(reg_iv_type, reg_iv_info): Now varray_type.
(first_increment_giv, last_increment_giv): New variables.
(compute_luids, verify_dominator, find_life_end): New functions.
(cmp_recombine_givs_stats, recombine_givs): Likewise.
(loop_optimize): Allocate loop_number_loop_cont and
loop_number_cont_dominator. Use compute_luids.
(find_and_verify_loops): Initialize loop_number_loop_cont and
loop_number_cont_dominator.
(strength_reduce): Try to find bivs that can be expressed as givs
of another biv, and to convert biv increments into givs.
Call recombine_givs. Handle derived givs.
(record_biv): New argument location. All callers changed.
(record_giv): Initialize derived and last_use fields.
(basic_induction_var): New argument location. All callers changed.
(combine_givs): Don't combine a DEST_REG giv with a DEST_ADDR giv.
Increment combined_with instead of setting to 1.
* unroll.c (derived_regs): New static variable.
(unroll_loop): Initialize it.
Allocate local_regno according to max_reg_num.
(copy_loop_body): Cope with derived givs.
(find_splittable_givs): Check for Givs made from biv increments.
Set derived_regs for givs.
* Makefile.in (stmt.o, loop.o, unroll.o): Depend on loop.h .
From-SVN: r24889
1999-01-27 10:45:50 -05:00
|
|
|
extern int first_increment_giv, last_increment_giv;
|
|
|
|
|
1992-03-14 00:04:21 -05:00
|
|
|
/* Forward declarations for non-static functions declared in loop.c and
|
|
|
|
unroll.c. */
|
1993-03-19 21:17:20 -05:00
|
|
|
int invariant_p PROTO((rtx));
|
|
|
|
rtx get_condition_for_loop PROTO((rtx));
|
|
|
|
void emit_iv_add_mult PROTO((rtx, rtx, rtx, rtx, rtx));
|
1999-02-03 07:48:48 -05:00
|
|
|
rtx express_from PROTO((struct induction *, struct induction *));
|
1992-03-14 00:04:21 -05:00
|
|
|
|
1998-11-25 16:19:21 -05:00
|
|
|
void unroll_loop PROTO((rtx, int, rtx, rtx, struct loop_info *, int));
|
1993-03-19 21:17:20 -05:00
|
|
|
rtx biv_total_increment PROTO((struct iv_class *, rtx, rtx));
|
1998-11-25 16:19:21 -05:00
|
|
|
unsigned HOST_WIDE_INT loop_iterations PROTO((rtx, rtx, struct loop_info *));
|
|
|
|
int precondition_loop_p PROTO((rtx, struct loop_info *,
|
1998-11-25 16:32:27 -05:00
|
|
|
rtx *, rtx *, rtx *,
|
|
|
|
enum machine_mode *mode));
|
1998-11-25 16:19:21 -05:00
|
|
|
rtx final_biv_value PROTO((struct iv_class *, rtx, rtx,
|
|
|
|
unsigned HOST_WIDE_INT));
|
|
|
|
rtx final_giv_value PROTO((struct induction *, rtx, rtx,
|
|
|
|
unsigned HOST_WIDE_INT));
|
1993-03-19 21:17:20 -05:00
|
|
|
void emit_unrolled_add PROTO((rtx, rtx, rtx));
|
1995-05-13 10:57:22 -04:00
|
|
|
int back_branch_in_range_p PROTO((rtx, rtx, rtx));
|
1999-02-24 06:50:54 -05:00
|
|
|
int loop_insn_first_p PROTO((rtx, rtx));
|
1997-08-12 00:07:19 -04:00
|
|
|
|
1998-11-25 16:19:21 -05:00
|
|
|
extern int *loop_unroll_number;
|
unroll.c (loop_iteration_var, [...]): No longer static.
* unroll.c (loop_iteration_var, loop_initial_value, loop_increment
loop_final_value, loop_comparison_code): No longer static.
(unroll_loop): Delete loop_start_value update.
* loop.h (loop_iteration_var, loop_initial_value, loop_increment,
loop_final_value, loop_comparison_code): Extern.
(loop_start_value): Delete extern.
* loop.c (loop_can_insert_bct, loop_increment, loop_start_value,
loop_comparison_value, loop_comparison_code): Delete.
(loop_optimize): Remove initialization for deleted variables.
(strength_reduce): Delete analyze_loop_iterations call. Only call
insert_bct if flag_branch_count_on_reg set.
(analyze_loop_iterations): Delete.
(insert_bct): Remove iteration count calculation. Move checks for
viable BCT optimization to here. Obtain iteration count from
loop_iterations and correct for unrolling. Check for enough
iteration to be beneficial. Comment out runtime iteration count
case.
(insert_bct): Print iteration count in dump file. Remove
loop_var_mode and use word_mode directly.
* rs6000.h (processor_type): Add PROCESSOR_PPC604e.
* rs6000.c (rs6000_override_options): Use it.
(optimization_options): Enable use of flag_branch_on_count_reg.
* rs6000.md (define_function_unit): Describe 604e.
From-SVN: r22852
1998-10-05 18:03:25 -04:00
|
|
|
|
1999-02-24 06:50:54 -05:00
|
|
|
/* Forward declarations for non-static functions declared in stmt.c. */
|
|
|
|
void find_loop_tree_blocks PROTO((void));
|
|
|
|
void unroll_block_trees PROTO((void));
|