OSDN Git Service

* decl.c (init_decl_processing): Remove duplicate decl of
[pf3gnuchains/gcc-fork.git] / gcc / loop.h
index f4cdbff..8fbde21 100644 (file)
@@ -1,5 +1,5 @@
 /* Loop optimization definitions for GNU C-Compiler
-   Copyright (C) 1991 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1995, 1998, 1999, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -15,7 +15,14 @@ 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
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "varray.h"
+#include "basic-block.h"
+
+/* Get the loop info pointer of a loop.  */
+#define LOOP_INFO(LOOP) ((struct loop_info *) (LOOP)->aux) 
 
 /* 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.  */
@@ -53,6 +60,8 @@ struct induction
                                   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 */
   enum machine_mode mem_mode;  /* For DEST_ADDR, mode of the memory object. */
   rtx mult_val;                        /* Multiplicative factor for src_reg.  */
@@ -62,6 +71,9 @@ struct induction
                                   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
@@ -74,18 +86,27 @@ struct induction
                                   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 set occurs each iteration */
+  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 combined_with : 1;  /* 1 if this giv has been combined with.  It
-                                  then cannot combine with any other giv.  */
   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. */
+  unsigned multi_insn_incr : 1;        /* 1 if multiple insns updated the biv.  */
   int lifetime;                        /* Length of life of this giv */
-  int times_used;              /* # times this giv is used. */
   rtx derive_adjustment;       /* If nonzero, is an adjustment to be
                                   subtracted from add_val when this giv
                                   derives another.  This occurs when the
@@ -97,10 +118,20 @@ struct induction
   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.  */
-  int const_adjust;            /* Used by loop unrolling, when an address giv
+  struct induction *derived_from;/* For a giv, if we decided to derive this
+                                  giv from another one.  */
+  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. */
+  int ix;                      /* Used by recombine_givs, as n index into
+                                  the stats array.  */
+  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.  */
@@ -118,7 +149,7 @@ struct iv_class {
   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 */
-  rtx init_insn;               /* insn which intializes biv, 0 if none. */
+  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. */
@@ -127,6 +158,51 @@ struct iv_class {
                                   biv controls. */
 };
 
+/* Information required to calculate the number of loop iterations. 
+   This is set by loop_iterations.  */
+
+struct loop_info
+{
+  /* Nonzero if there is a subroutine call in the current loop.  */
+  int has_call;
+  /* 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;
+  /* 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;
+};
+
 /* Definitions used by the basic induction variable discovery code.  */
 enum iv_mode { UNKNOWN_INDUCT, BASIC_INDUCT, NOT_BASIC_INDUCT,
                 GENERAL_INDUCT };
@@ -135,38 +211,43 @@ enum iv_mode { UNKNOWN_INDUCT, BASIC_INDUCT, NOT_BASIC_INDUCT,
 
 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;
-extern unsigned long loop_n_iterations;
 extern int max_reg_before_loop;
-
+extern struct loop **uid_loop;
 extern FILE *loop_dump_stream;
 
-extern enum iv_mode *reg_iv_type;
-extern struct induction **reg_iv_info;
+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)))
+
 extern struct iv_class **reg_biv_class;
 extern struct iv_class *loop_iv_list;
 
+extern int first_increment_giv, last_increment_giv;
+
 /* Forward declarations for non-static functions declared in loop.c and
    unroll.c.  */
-int invariant_p ();
-rtx get_condition_for_loop ();
-void emit_iv_add_mult ();
-
-/* Variables declared in stmt.c but also needed in loop.c.  */
-
-extern union tree_node **loop_number_first_block;
-extern union tree_node **loop_number_last_block;
-extern int *loop_number_block_level;
+int loop_invariant_p PARAMS ((const struct loop *, rtx));
+rtx get_condition_for_loop PARAMS ((const struct loop *, rtx));
+void emit_iv_add_mult PARAMS ((rtx, rtx, rtx, rtx, rtx));
+rtx express_from PARAMS ((struct induction *, struct induction *));
+
+void unroll_loop PARAMS ((struct loop *, int, rtx, int));
+rtx biv_total_increment PARAMS ((struct iv_class *));
+unsigned HOST_WIDE_INT loop_iterations PARAMS ((struct loop *));
+int precondition_loop_p PARAMS ((const struct loop *,
+                              rtx *, rtx *, rtx *, 
+                              enum machine_mode *mode));
+rtx final_biv_value PARAMS ((const struct loop *, struct iv_class *));
+rtx final_giv_value PARAMS ((const struct loop *, struct induction *));
+void emit_unrolled_add PARAMS ((rtx, rtx, rtx));
+int back_branch_in_range_p PARAMS ((const struct loop *, rtx));
+
+int loop_insn_first_p PARAMS ((rtx, rtx));
 
 /* Forward declarations for non-static functions declared in stmt.c.  */
-void find_loop_tree_blocks ();
-void unroll_block_trees ();
-
-void unroll_loop ();
-rtx biv_total_increment ();
-unsigned long loop_iterations ();
-rtx final_biv_value ();
-rtx final_giv_value ();
-void emit_unrolled_add ();
+void find_loop_tree_blocks PARAMS ((void));
+void unroll_block_trees PARAMS ((void));