[killloop] Make loop-iv.c use df.c
Zdenek Dvorak
rakdver@atrey.karlin.mff.cuni.cz
Tue Aug 30 09:39:00 GMT 2005
Hello,
loop-iv.c used very primitive version of UD chains. Now that
performance problems of df.c are more or less solved, this is just
a bad design and limits usefulness of loop-iv.c. This patch makes
the rtl iv analysis use df.c instead.
Zdenek
* cfgloop.h (struct rtx_iv): Remove analysed field. Added biv_p field.
(iv_get_reaching_def): Removed.
(iv_analyze_result, iv_analyze_expr): Declare.
& df.c (df_bitmaps_free, df_bb_modify): Only work on the specified part
of cfg.
(df_find_use): Handle subregs.
* Makefile.in (loop-iv.o): Add DF_H dependency.
* loop-iv.c: Include df.h.
(enum iv_grd_result): New enum.
(DF_REF_IV, DF_REF_IV_SET): New macros.
(df): New global variable.
(struct insn_info, insn_info, last_def, bivs, max_insn_no, max_reg_no,
assign_luids, mark_sets, kill_sets, mark_single_set, simple_set_p):
Removed.
(clear_iv_info, latch_dominating_def, record_iv, iv_analyze_expr,
iv_analyze_result, iv_analyze_def): New functions.
(iv_analysis_loop_init, iv_get_reaching_def, simple_reg_p,
get_biv_step_1, get_biv_step, iv_analyze_biv, iv_analyze_op,
iv_analyze, biv_p, iv_analysis_done): Work with df representation of
UD chains.
(iv_constant, iv_subreg, iv_extend, iv_mult, iv_shift): Initialize
biv_p, do not set analysed.
(iv_number_of_iterations): Use new interface to iv analysis.
* loop-unroll.c (analyze_iv_to_split_insn): Ditto.
* loop-unswitch.c (may_unswitch_on): Ditto.
Index: cfgloop.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgloop.h,v
retrieving revision 1.48
diff -c -3 -p -r1.48 cfgloop.h
*** cfgloop.h 25 Jun 2005 01:59:29 -0000 1.48
--- cfgloop.h 30 Aug 2005 09:02:00 -0000
*************** struct rtx_iv
*** 350,360 ****
/* The mode the variable iterates in. */
enum machine_mode mode;
- /* Whether we have already filled the remaining fields. */
- unsigned analysed : 1;
-
/* Whether the first iteration needs to be handled specially. */
unsigned first_special : 1;
};
/* The description of an exit from the loop and of the number of iterations
--- 350,360 ----
/* The mode the variable iterates in. */
enum machine_mode mode;
/* Whether the first iteration needs to be handled specially. */
unsigned first_special : 1;
+
+ /* True if this is a biv. */
+ unsigned biv_p : 1;
};
/* The description of an exit from the loop and of the number of iterations
*************** struct niter_desc
*** 402,409 ****
};
extern void iv_analysis_loop_init (struct loop *);
- extern rtx iv_get_reaching_def (rtx, rtx);
extern bool iv_analyze (rtx, rtx, struct rtx_iv *);
extern rtx get_iv_value (struct rtx_iv *, rtx);
extern bool biv_p (rtx, rtx);
extern void find_simple_exit (struct loop *, struct niter_desc *);
--- 402,410 ----
};
extern void iv_analysis_loop_init (struct loop *);
extern bool iv_analyze (rtx, rtx, struct rtx_iv *);
+ extern bool iv_analyze_result (rtx, rtx, struct rtx_iv *);
+ extern bool iv_analyze_expr (rtx, rtx, enum machine_mode, struct rtx_iv *);
extern rtx get_iv_value (struct rtx_iv *, rtx);
extern bool biv_p (rtx, rtx);
extern void find_simple_exit (struct loop *, struct niter_desc *);
Index: df.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/df.c,v
retrieving revision 1.86.2.1
diff -c -3 -p -r1.86.2.1 df.c
*** df.c 30 Aug 2005 07:42:24 -0000 1.86.2.1
--- df.c 30 Aug 2005 09:02:00 -0000
*************** df_bitmaps_alloc (struct df *df, bitmap
*** 451,464 ****
static void
df_bitmaps_free (struct df *df, int flags)
{
! basic_block bb;
!
! FOR_EACH_BB (bb)
{
! struct bb_info *bb_info = DF_BB_INFO (df, bb);
!
! if (!bb_info)
! continue;
if ((flags & DF_RD) && bb_info->rd_in)
{
--- 451,461 ----
static void
df_bitmaps_free (struct df *df, int flags)
{
! unsigned i;
!
! for (i = 0; i < df->n_bbs; i++)
{
! struct bb_info *bb_info = &df->bbs[i];
if ((flags & DF_RD) && bb_info->rd_in)
{
*************** static void
*** 2648,2654 ****
df_bb_modify (struct df *df, basic_block bb)
{
if ((unsigned) bb->index >= df->n_bbs)
! df_bb_table_realloc (df, df->n_bbs);
bitmap_set_bit (df->bbs_modified, bb->index);
}
--- 2645,2651 ----
df_bb_modify (struct df *df, basic_block bb)
{
if ((unsigned) bb->index >= df->n_bbs)
! df_bb_table_realloc (df, bb->index);
bitmap_set_bit (df->bbs_modified, bb->index);
}
*************** df_find_use (struct df *df, rtx insn, rt
*** 3060,3067 ****
struct df_link *uses;
for (uses = DF_INSN_USES (df, insn); uses; uses = uses->next)
! if (rtx_equal_p (DF_REF_REG (uses->ref), reg))
! return uses->ref;
return NULL;
}
--- 3057,3070 ----
struct df_link *uses;
for (uses = DF_INSN_USES (df, insn); uses; uses = uses->next)
! {
! rtx areg = DF_REF_REG (uses->ref);
! if (GET_CODE (areg) == SUBREG)
! areg = SUBREG_REG (areg);
!
! if (rtx_equal_p (areg, reg))
! return uses->ref;
! }
return NULL;
}
Index: loop-iv.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop-iv.c,v
retrieving revision 2.35
diff -c -3 -p -r2.35 loop-iv.c
*** loop-iv.c 21 Jul 2005 07:24:07 -0000 2.35
--- loop-iv.c 30 Aug 2005 09:02:00 -0000
*************** along with GCC; see the file COPYING. I
*** 18,47 ****
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
! /* This is just a very simplistic analysis of induction variables of the loop.
! The major use is for determining the number of iterations of a loop for
! loop unrolling, doloop optimization and branch prediction. For this we
! are only interested in bivs and a fairly limited set of givs that are
! needed in the exit condition. We also only compute the iv information on
! demand.
!
! The interesting registers are determined. A register is interesting if
!
! -- it is set only in the blocks that dominate the latch of the current loop
! -- all its sets are simple -- i.e. in the form we understand
!
! We also number the insns sequentially in each basic block. For a use of the
! interesting reg, it is now easy to find a reaching definition (there may be
! only one).
! Induction variable is then simply analyzed by walking the use-def
! chains.
! Usage:
iv_analysis_loop_init (loop);
! insn = iv_get_reaching_def (where, reg);
! if (iv_analyze (insn, reg, &iv))
{
...
}
--- 18,34 ----
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
! /* This is a simple analysis of induction variables of the loop. The major use
! is for determining the number of iterations of a loop for loop unrolling,
! doloop optimization and branch prediction. The iv information is computed
! on demand.
! Induction variable is analyzed by walking the use-def chains.
! Usage (REG must be used in WHERE):
iv_analysis_loop_init (loop);
! if (iv_analyze (where, reg, &iv))
{
...
}
*************** Software Foundation, 51 Franklin Street,
*** 60,99 ****
#include "intl.h"
#include "output.h"
#include "toplev.h"
! /* The insn information. */
! struct insn_info
{
! /* Id of the insn. */
! unsigned luid;
! /* The previous definition of the register defined by the single
! set in the insn. */
! rtx prev_def;
! /* The description of the iv. */
! struct rtx_iv iv;
! };
!
! static struct insn_info *insn_info;
! /* The last definition of register. */
!
! static rtx *last_def;
! /* The bivs. */
! static struct rtx_iv *bivs;
! /* Maximal insn number for that there is place in insn_info array. */
! static unsigned max_insn_no;
! /* Maximal register number for that there is place in bivs and last_def
! arrays. */
! static unsigned max_reg_no;
/* Dumps information about IV to FILE. */
--- 47,87 ----
#include "intl.h"
#include "output.h"
#include "toplev.h"
+ #include "df.h"
! /* Possible return values of iv_get_reaching_def. */
! enum iv_grd_result
{
! /* More than one reaching def, or reaching def that does not
! dominate the use. */
! GRD_INVALID,
! /* The use is trivial invariant of the loop, i.e. is not changed
! inside the loop. */
! GRD_INVARIANT,
! /* The use is reached by initial value and a value from the
! previous iteration. */
! GRD_MAYBE_BIV,
! /* The use has single dominating def. */
! GRD_SINGLE_DOM
! };
! /* Induction variable stored at the reference. */
! #define DF_REF_IV(REF) ((struct rtx_iv *) DF_REF_DATA (REF))
! #define DF_REF_IV_SET(REF, IV) DF_REF_DATA (REF) = (IV)
! /* The current loop. */
! struct loop *current_loop;
! /* Dataflow information for the current loop. */
! struct df *df;
! static bool iv_analyze_op (rtx, rtx, struct rtx_iv *);
/* Dumps information about IV to FILE. */
*************** dump_iv_info (FILE *file, struct rtx_iv
*** 139,161 ****
fprintf (file, " (first special)");
}
- /* Assigns luids to insns in basic block BB. */
-
- static void
- assign_luids (basic_block bb)
- {
- unsigned i = 0, uid;
- rtx insn;
-
- FOR_BB_INSNS (bb, insn)
- {
- uid = INSN_UID (insn);
- insn_info[uid].luid = i++;
- insn_info[uid].prev_def = NULL_RTX;
- insn_info[uid].iv.analysed = false;
- }
- }
-
/* Generates a subreg to get the least significant part of EXPR (in mode
INNER_MODE) to OUTER_MODE. */
--- 127,132 ----
*************** simple_reg_p (rtx reg)
*** 191,419 ****
if (GET_MODE_CLASS (GET_MODE (reg)) != MODE_INT)
return false;
- if (last_def[r] == const0_rtx)
- return false;
-
return true;
}
! /* Checks whether assignment LHS = RHS is simple enough for us to process. */
! static bool
! simple_set_p (rtx lhs, rtx rhs)
{
! rtx op0, op1;
!
! if (!REG_P (lhs)
! || !simple_reg_p (lhs))
! return false;
!
! if (CONSTANT_P (rhs))
! return true;
! switch (GET_CODE (rhs))
{
! case SUBREG:
! case REG:
! return simple_reg_p (rhs);
!
! case SIGN_EXTEND:
! case ZERO_EXTEND:
! case NEG:
! return simple_reg_p (XEXP (rhs, 0));
!
! case PLUS:
! case MINUS:
! case MULT:
! case ASHIFT:
! op0 = XEXP (rhs, 0);
! op1 = XEXP (rhs, 1);
!
! if (!simple_reg_p (op0)
! && !CONSTANT_P (op0))
! return false;
!
! if (!simple_reg_p (op1)
! && !CONSTANT_P (op1))
! return false;
!
! if (GET_CODE (rhs) == MULT
! && !CONSTANT_P (op0)
! && !CONSTANT_P (op1))
! return false;
!
! if (GET_CODE (rhs) == ASHIFT
! && CONSTANT_P (op0))
! return false;
!
! return true;
! default:
! return false;
}
}
! /* Mark single SET in INSN. */
!
! static rtx
! mark_single_set (rtx insn, rtx set)
! {
! rtx def = SET_DEST (set), src;
! unsigned regno, uid;
!
! src = find_reg_equal_equiv_note (insn);
! if (src)
! src = XEXP (src, 0);
! else
! src = SET_SRC (set);
!
! if (!simple_set_p (SET_DEST (set), src))
! return NULL_RTX;
!
! regno = REGNO (def);
! uid = INSN_UID (insn);
!
! bivs[regno].analysed = false;
! insn_info[uid].prev_def = last_def[regno];
! last_def[regno] = insn;
!
! return def;
! }
!
! /* Invalidate register REG unless it is equal to EXCEPT. */
! static void
! kill_sets (rtx reg, rtx by ATTRIBUTE_UNUSED, void *except)
{
! if (GET_CODE (reg) == SUBREG)
! reg = SUBREG_REG (reg);
! if (!REG_P (reg))
! return;
! if (reg == except)
! return;
!
! last_def[REGNO (reg)] = const0_rtx;
! }
! /* Marks sets in basic block BB. If DOM is true, BB dominates the loop
! latch. */
! static void
! mark_sets (basic_block bb, bool dom)
! {
! rtx insn, set, def;
! FOR_BB_INSNS (bb, insn)
{
! if (!INSN_P (insn))
! continue;
! if (dom
! && (set = single_set (insn)))
! def = mark_single_set (insn, set);
! else
! def = NULL_RTX;
! note_stores (PATTERN (insn), kill_sets, def);
}
}
! /* Prepare the data for an induction variable analysis of a LOOP. */
! void
! iv_analysis_loop_init (struct loop *loop)
{
! basic_block *body = get_loop_body_in_dom_order (loop);
! unsigned b;
! if ((unsigned) get_max_uid () >= max_insn_no)
{
! /* Add some reserve for insns and registers produced in optimizations. */
! max_insn_no = get_max_uid () + 100;
! if (insn_info)
! free (insn_info);
! insn_info = xmalloc (max_insn_no * sizeof (struct insn_info));
! }
! if ((unsigned) max_reg_num () >= max_reg_no)
! {
! max_reg_no = max_reg_num () + 100;
! if (last_def)
! free (last_def);
! last_def = xmalloc (max_reg_no * sizeof (rtx));
! if (bivs)
! free (bivs);
! bivs = xmalloc (max_reg_no * sizeof (struct rtx_iv));
! }
! memset (last_def, 0, max_reg_num () * sizeof (rtx));
! for (b = 0; b < loop->num_nodes; b++)
! {
! assign_luids (body[b]);
! mark_sets (body[b], just_once_each_iteration_p (loop, body[b]));
}
! free (body);
}
! /* Gets definition of REG reaching the INSN. If REG is not simple, const0_rtx
! is returned. If INSN is before the first def in the loop, NULL_RTX is
! returned. */
! rtx
! iv_get_reaching_def (rtx insn, rtx reg)
{
! unsigned regno, luid, auid;
! rtx ainsn;
! basic_block bb, abb;
!
if (GET_CODE (reg) == SUBREG)
! {
! if (!subreg_lowpart_p (reg))
! return const0_rtx;
! reg = SUBREG_REG (reg);
! }
! if (!REG_P (reg))
! return NULL_RTX;
! regno = REGNO (reg);
! if (!last_def[regno]
! || last_def[regno] == const0_rtx)
! return last_def[regno];
! bb = BLOCK_FOR_INSN (insn);
! luid = insn_info[INSN_UID (insn)].luid;
! ainsn = last_def[regno];
! while (1)
! {
! abb = BLOCK_FOR_INSN (ainsn);
! if (dominated_by_p (CDI_DOMINATORS, bb, abb))
! break;
! auid = INSN_UID (ainsn);
! ainsn = insn_info[auid].prev_def;
!
! if (!ainsn)
! return NULL_RTX;
! }
! while (1)
{
! abb = BLOCK_FOR_INSN (ainsn);
! if (abb != bb)
! return ainsn;
!
! auid = INSN_UID (ainsn);
! if (luid > insn_info[auid].luid)
! return ainsn;
!
! ainsn = insn_info[auid].prev_def;
! if (!ainsn)
! return NULL_RTX;
}
}
/* Sets IV to invariant CST in MODE. Always returns true (just for
--- 162,315 ----
if (GET_MODE_CLASS (GET_MODE (reg)) != MODE_INT)
return false;
return true;
}
! /* Clears the information about ivs stored in df. */
! static void
! clear_iv_info (void)
{
! unsigned i;
! struct rtx_iv *iv;
! for (i = 0; i < df->n_defs; i++)
{
! if (!df->defs[i])
! continue;
! iv = DF_REF_IV (df->defs[i]);
! if (!iv)
! continue;
! free (iv);
! DF_REF_IV_SET (df->defs[i], NULL);
}
}
! /* Prepare the data for an induction variable analysis of a LOOP. */
! void
! iv_analysis_loop_init (struct loop *loop)
{
! basic_block *body = get_loop_body_in_dom_order (loop), bb;
! bitmap blocks = BITMAP_ALLOC (NULL);
! unsigned i;
! rtx insn;
! bool first_time = (df == NULL);
! current_loop = loop;
! /* Clear the information from the analysis of the previous loop. */
! if (first_time)
! df = df_init ();
! else
! clear_iv_info ();
! for (i = 0; i < loop->num_nodes; i++)
{
! bb = body[i];
! bitmap_set_bit (blocks, bb->index);
! if (first_time)
! continue;
! /* Mark everything in the body of the loop as modified, since this may be
! the case, and we do not keep track of what changes. */
! FOR_BB_INSNS (bb, insn)
! {
! df_insn_modify (df, bb, insn);
! }
}
+
+ df_analyze_subcfg (df, blocks, DF_UD_CHAIN | DF_EQUIV_NOTES);
+ BITMAP_FREE (blocks);
+ free (body);
}
! /* Finds the definition of REG that dominates loop latch and stores
! it to DEF. Returns false if there is not a single definition
! dominating the latch. If REG has no definition in loop, DEF
! is set to NULL and true is returned. */
! static bool
! latch_dominating_def (rtx reg, struct ref **def)
{
! struct ref *single_rd = NULL, *adef;
! struct df_link *def_link;
! unsigned regno = REGNO (reg);
! struct bb_info *bb_info = DF_BB_INFO (df, current_loop->latch);
! for (def_link = df->regs[regno].defs; def_link; def_link = def_link->next)
{
! adef = def_link->ref;
! if (!bitmap_bit_p (bb_info->rd_out, DF_REF_ID (adef)))
! continue;
! /* More than one reaching definition. */
! if (single_rd)
! return false;
! if (!just_once_each_iteration_p (current_loop, DF_REF_BB (adef)))
! return false;
!
! single_rd = adef;
}
! *def = single_rd;
! return true;
}
! /* Gets definition of REG reaching its use in INSN and stores it to DEF. */
! static enum iv_grd_result
! iv_get_reaching_def (rtx insn, rtx reg, struct ref **def)
{
! struct ref *use, *adef;
! basic_block def_bb, use_bb;
! rtx def_insn;
! bool dom_p;
!
! *def = NULL;
! if (!simple_reg_p (reg))
! return GRD_INVALID;
if (GET_CODE (reg) == SUBREG)
! reg = SUBREG_REG (reg);
! gcc_assert (REG_P (reg));
! use = df_find_use (df, insn, reg);
! gcc_assert (use != NULL);
! if (!DF_REF_CHAIN (use))
! return GRD_INVARIANT;
! /* More than one reaching def. */
! if (DF_REF_CHAIN (use)->next)
! return GRD_INVALID;
! adef = DF_REF_CHAIN (use)->ref;
! def_insn = DF_REF_INSN (adef);
! def_bb = DF_REF_BB (adef);
! use_bb = BLOCK_FOR_INSN (insn);
! if (use_bb == def_bb)
! dom_p = (DF_INSN_LUID (df, def_insn) < DF_INSN_LUID (df, insn));
! else
! dom_p = dominated_by_p (CDI_DOMINATORS, use_bb, def_bb);
! if (dom_p)
{
! *def = adef;
! return GRD_SINGLE_DOM;
}
+
+ /* The definition does not dominate the use. This is still OK if
+ this may be a use of a biv, i.e. if the def_bb dominates loop
+ latch. */
+ if (just_once_each_iteration_p (current_loop, def_bb))
+ return GRD_MAYBE_BIV;
+
+ return GRD_INVALID;
}
/* Sets IV to invariant CST in MODE. Always returns true (just for
*************** iv_constant (struct rtx_iv *iv, rtx cst,
*** 425,431 ****
if (mode == VOIDmode)
mode = GET_MODE (cst);
- iv->analysed = true;
iv->mode = mode;
iv->base = cst;
iv->step = const0_rtx;
--- 321,326 ----
*************** iv_constant (struct rtx_iv *iv, rtx cst,
*** 434,439 ****
--- 329,335 ----
iv->extend_mode = iv->mode;
iv->delta = const0_rtx;
iv->mult = const1_rtx;
+ iv->biv_p = false;
return true;
}
*************** iv_constant (struct rtx_iv *iv, rtx cst,
*** 443,448 ****
--- 339,346 ----
static bool
iv_subreg (struct rtx_iv *iv, enum machine_mode mode)
{
+ iv->biv_p = false;
+
/* If iv is invariant, just calculate the new value. */
if (iv->step == const0_rtx
&& !iv->first_special)
*************** iv_subreg (struct rtx_iv *iv, enum machi
*** 483,488 ****
--- 381,388 ----
static bool
iv_extend (struct rtx_iv *iv, enum rtx_code extend, enum machine_mode mode)
{
+ iv->biv_p = false;
+
/* If iv is invariant, just calculate the new value. */
if (iv->step == const0_rtx
&& !iv->first_special)
*************** iv_extend (struct rtx_iv *iv, enum rtx_c
*** 515,520 ****
--- 415,422 ----
static bool
iv_neg (struct rtx_iv *iv)
{
+ iv->biv_p = false;
+
if (iv->extend == UNKNOWN)
{
iv->base = simplify_gen_unary (NEG, iv->extend_mode,
*************** iv_add (struct rtx_iv *iv0, struct rtx_i
*** 541,546 ****
--- 443,450 ----
enum machine_mode mode;
rtx arg;
+ iv0->biv_p = false;
+
/* Extend the constant to extend_mode of the other operand if necessary. */
if (iv0->extend == UNKNOWN
&& iv0->mode == iv0->extend_mode
*************** iv_mult (struct rtx_iv *iv, rtx mby)
*** 609,614 ****
--- 513,520 ----
{
enum machine_mode mode = iv->extend_mode;
+ iv->biv_p = false;
+
if (GET_MODE (mby) != VOIDmode
&& GET_MODE (mby) != mode)
return false;
*************** iv_shift (struct rtx_iv *iv, rtx mby)
*** 634,639 ****
--- 540,547 ----
{
enum machine_mode mode = iv->extend_mode;
+ iv->biv_p = false;
+
if (GET_MODE (mby) != VOIDmode
&& GET_MODE (mby) != mode)
return false;
*************** iv_shift (struct rtx_iv *iv, rtx mby)
*** 653,672 ****
}
/* The recursive part of get_biv_step. Gets the value of the single value
! defined in INSN wrto initial value of REG inside loop, in shape described
at get_biv_step. */
static bool
! get_biv_step_1 (rtx insn, rtx reg,
rtx *inner_step, enum machine_mode *inner_mode,
enum rtx_code *extend, enum machine_mode outer_mode,
rtx *outer_step)
{
rtx set, rhs, op0 = NULL_RTX, op1 = NULL_RTX;
! rtx next, nextr, def_insn, tmp;
enum rtx_code code;
set = single_set (insn);
rhs = find_reg_equal_equiv_note (insn);
if (rhs)
rhs = XEXP (rhs, 0);
--- 561,586 ----
}
/* The recursive part of get_biv_step. Gets the value of the single value
! defined by DEF wrto initial value of REG inside loop, in shape described
at get_biv_step. */
static bool
! get_biv_step_1 (struct ref *def, rtx reg,
rtx *inner_step, enum machine_mode *inner_mode,
enum rtx_code *extend, enum machine_mode outer_mode,
rtx *outer_step)
{
rtx set, rhs, op0 = NULL_RTX, op1 = NULL_RTX;
! rtx next, nextr, tmp;
enum rtx_code code;
+ rtx insn = DF_REF_INSN (def);
+ struct ref *next_def;
+ enum iv_grd_result res;
set = single_set (insn);
+ if (!set)
+ return false;
+
rhs = find_reg_equal_equiv_note (insn);
if (rhs)
rhs = XEXP (rhs, 0);
*************** get_biv_step_1 (rtx insn, rtx reg,
*** 742,752 ****
else
nextr = next;
! def_insn = iv_get_reaching_def (insn, nextr);
! if (def_insn == const0_rtx)
return false;
! if (!def_insn)
{
if (!rtx_equal_p (nextr, reg))
return false;
--- 656,667 ----
else
nextr = next;
! res = iv_get_reaching_def (insn, nextr, &next_def);
!
! if (res == GRD_INVALID || res == GRD_INVARIANT)
return false;
! if (res == GRD_MAYBE_BIV)
{
if (!rtx_equal_p (nextr, reg))
return false;
*************** get_biv_step_1 (rtx insn, rtx reg,
*** 756,762 ****
*inner_mode = outer_mode;
*outer_step = const0_rtx;
}
! else if (!get_biv_step_1 (def_insn, reg,
inner_step, inner_mode, extend, outer_mode,
outer_step))
return false;
--- 671,677 ----
*inner_mode = outer_mode;
*outer_step = const0_rtx;
}
! else if (!get_biv_step_1 (next_def, reg,
inner_step, inner_mode, extend, outer_mode,
outer_step))
return false;
*************** get_biv_step_1 (rtx insn, rtx reg,
*** 803,809 ****
break;
default:
! gcc_unreachable ();
}
return true;
--- 718,724 ----
break;
default:
! return false;
}
return true;
*************** get_biv_step_1 (rtx insn, rtx reg,
*** 813,828 ****
OUTER_STEP + EXTEND_{OUTER_MODE} (SUBREG_{INNER_MODE} (REG + INNER_STEP))
! If the operation cannot be described in this shape, return false. */
static bool
! get_biv_step (rtx reg, rtx *inner_step, enum machine_mode *inner_mode,
! enum rtx_code *extend, enum machine_mode *outer_mode,
! rtx *outer_step)
{
*outer_mode = GET_MODE (reg);
! if (!get_biv_step_1 (last_def[REGNO (reg)], reg,
inner_step, inner_mode, extend, *outer_mode,
outer_step))
return false;
--- 728,744 ----
OUTER_STEP + EXTEND_{OUTER_MODE} (SUBREG_{INNER_MODE} (REG + INNER_STEP))
! If the operation cannot be described in this shape, return false.
! LAST_DEF is the definition of REG that dominates loop latch. */
static bool
! get_biv_step (struct ref *last_def, rtx reg, rtx *inner_step,
! enum machine_mode *inner_mode, enum rtx_code *extend,
! enum machine_mode *outer_mode, rtx *outer_step)
{
*outer_mode = GET_MODE (reg);
! if (!get_biv_step_1 (last_def, reg,
inner_step, inner_mode, extend, *outer_mode,
outer_step))
return false;
*************** get_biv_step (rtx reg, rtx *inner_step,
*** 833,848 ****
return true;
}
/* Determines whether DEF is a biv and if so, stores its description
to *IV. */
static bool
iv_analyze_biv (rtx def, struct rtx_iv *iv)
{
- unsigned regno;
rtx inner_step, outer_step;
enum machine_mode inner_mode, outer_mode;
enum rtx_code extend;
if (dump_file)
{
--- 749,775 ----
return true;
}
+ /* Records information that DEF is induction variable IV. */
+
+ static void
+ record_iv (struct ref *def, struct rtx_iv *iv)
+ {
+ struct rtx_iv *recorded_iv = xmalloc (sizeof (struct rtx_iv));
+
+ *recorded_iv = *iv;
+ DF_REF_IV_SET (def, recorded_iv);
+ }
+
/* Determines whether DEF is a biv and if so, stores its description
to *IV. */
static bool
iv_analyze_biv (rtx def, struct rtx_iv *iv)
{
rtx inner_step, outer_step;
enum machine_mode inner_mode, outer_mode;
enum rtx_code extend;
+ struct ref *last_def;
if (dump_file)
{
*************** iv_analyze_biv (rtx def, struct rtx_iv *
*** 859,889 ****
return iv_constant (iv, def, VOIDmode);
}
! regno = REGNO (def);
! if (last_def[regno] == const0_rtx)
{
if (dump_file)
fprintf (dump_file, " not simple.\n");
return false;
}
! if (last_def[regno] && bivs[regno].analysed)
{
if (dump_file)
fprintf (dump_file, " already analysed.\n");
! *iv = bivs[regno];
return iv->base != NULL_RTX;
}
! if (!last_def[regno])
! {
! iv_constant (iv, def, VOIDmode);
! goto end;
! }
!
! iv->analysed = true;
! if (!get_biv_step (def, &inner_step, &inner_mode, &extend,
&outer_mode, &outer_step))
{
iv->base = NULL_RTX;
--- 786,811 ----
return iv_constant (iv, def, VOIDmode);
}
! if (!latch_dominating_def (def, &last_def))
{
if (dump_file)
fprintf (dump_file, " not simple.\n");
return false;
}
! if (!last_def)
! return iv_constant (iv, def, VOIDmode);
!
! if (DF_REF_IV (last_def))
{
if (dump_file)
fprintf (dump_file, " already analysed.\n");
! *iv = *DF_REF_IV (last_def);
return iv->base != NULL_RTX;
}
! if (!get_biv_step (last_def, def, &inner_step, &inner_mode, &extend,
&outer_mode, &outer_step))
{
iv->base = NULL_RTX;
*************** iv_analyze_biv (rtx def, struct rtx_iv *
*** 904,909 ****
--- 826,832 ----
iv->mult = const1_rtx;
iv->delta = outer_step;
iv->first_special = inner_mode != outer_mode;
+ iv->biv_p = true;
end:
if (dump_file)
*************** iv_analyze_biv (rtx def, struct rtx_iv *
*** 913,1031 ****
fprintf (dump_file, "\n");
}
! bivs[regno] = *iv;
!
return iv->base != NULL_RTX;
}
! /* Analyzes operand OP of INSN and stores the result to *IV. */
! static bool
! iv_analyze_op (rtx insn, rtx op, struct rtx_iv *iv)
{
! rtx def_insn;
! unsigned regno;
! bool inv = CONSTANT_P (op);
!
! if (dump_file)
! {
! fprintf (dump_file, "Analyzing operand ");
! print_rtl (dump_file, op);
! fprintf (dump_file, " of insn ");
! print_rtl_single (dump_file, insn);
! }
!
! if (GET_CODE (op) == SUBREG)
! {
! if (!subreg_lowpart_p (op))
! return false;
! if (!iv_analyze_op (insn, SUBREG_REG (op), iv))
! return false;
! return iv_subreg (iv, GET_MODE (op));
! }
! if (!inv)
{
! regno = REGNO (op);
! if (!last_def[regno])
! inv = true;
! else if (last_def[regno] == const0_rtx)
{
! if (dump_file)
! fprintf (dump_file, " not simple.\n");
! return false;
}
}
! if (inv)
{
! iv_constant (iv, op, VOIDmode);
! if (dump_file)
{
! fprintf (dump_file, " ");
! dump_iv_info (dump_file, iv);
! fprintf (dump_file, "\n");
}
! return true;
! }
! def_insn = iv_get_reaching_def (insn, op);
! if (def_insn == const0_rtx)
! {
! if (dump_file)
! fprintf (dump_file, " not simple.\n");
return false;
}
! return iv_analyze (def_insn, op, iv);
! }
!
! /* Analyzes iv DEF defined in INSN and stores the result to *IV. */
!
! bool
! iv_analyze (rtx insn, rtx def, struct rtx_iv *iv)
! {
! unsigned uid;
! rtx set, rhs, mby = NULL_RTX, tmp;
! rtx op0 = NULL_RTX, op1 = NULL_RTX;
! struct rtx_iv iv0, iv1;
! enum machine_mode amode;
! enum rtx_code code;
! if (insn == const0_rtx)
return false;
! if (GET_CODE (def) == SUBREG)
{
! if (!subreg_lowpart_p (def))
return false;
! if (!iv_analyze (insn, SUBREG_REG (def), iv))
return false;
! return iv_subreg (iv, GET_MODE (def));
}
! if (!insn)
! return iv_analyze_biv (def, iv);
if (dump_file)
{
! fprintf (dump_file, "Analyzing def of ");
! print_rtl (dump_file, def);
fprintf (dump_file, " in insn ");
print_rtl_single (dump_file, insn);
}
! uid = INSN_UID (insn);
! if (insn_info[uid].iv.analysed)
{
if (dump_file)
fprintf (dump_file, " already analysed.\n");
! *iv = insn_info[uid].iv;
return iv->base != NULL_RTX;
}
--- 836,990 ----
fprintf (dump_file, "\n");
}
! record_iv (last_def, iv);
return iv->base != NULL_RTX;
}
! /* Analyzes expression RHS used at INSN and stores the result to *IV.
! The mode of the induction variable is MODE. */
! bool
! iv_analyze_expr (rtx insn, rtx rhs, enum machine_mode mode, struct rtx_iv *iv)
{
! rtx mby = NULL_RTX, tmp;
! rtx op0 = NULL_RTX, op1 = NULL_RTX;
! struct rtx_iv iv0, iv1;
! enum rtx_code code = GET_CODE (rhs);
! enum machine_mode omode = mode;
! iv->mode = VOIDmode;
! iv->base = NULL_RTX;
! iv->step = NULL_RTX;
! gcc_assert (GET_MODE (rhs) == mode || GET_MODE (rhs) == VOIDmode);
! if (CONSTANT_P (rhs)
! || REG_P (rhs)
! || code == SUBREG)
{
! if (!iv_analyze_op (insn, rhs, iv))
! return false;
!
! if (iv->mode == VOIDmode)
{
! iv->mode = mode;
! iv->extend_mode = mode;
}
+
+ return true;
}
! switch (code)
{
! case REG:
! op0 = rhs;
! break;
! case SIGN_EXTEND:
! case ZERO_EXTEND:
! case NEG:
! op0 = XEXP (rhs, 0);
! omode = GET_MODE (op0);
! break;
!
! case PLUS:
! case MINUS:
! op0 = XEXP (rhs, 0);
! op1 = XEXP (rhs, 1);
! break;
!
! case MULT:
! op0 = XEXP (rhs, 0);
! mby = XEXP (rhs, 1);
! if (!CONSTANT_P (mby))
{
! tmp = op0;
! op0 = mby;
! mby = tmp;
}
! if (!CONSTANT_P (mby))
! return false;
! break;
! case ASHIFT:
! op0 = XEXP (rhs, 0);
! mby = XEXP (rhs, 1);
! if (!CONSTANT_P (mby))
! return false;
! break;
!
! default:
return false;
}
! if (op0
! && !iv_analyze_expr (insn, op0, omode, &iv0))
! return false;
! if (op1
! && !iv_analyze_expr (insn, op1, omode, &iv1))
return false;
! switch (code)
{
! case SIGN_EXTEND:
! case ZERO_EXTEND:
! if (!iv_extend (&iv0, code, mode))
return false;
+ break;
! case NEG:
! if (!iv_neg (&iv0))
return false;
+ break;
+
+ case PLUS:
+ case MINUS:
+ if (!iv_add (&iv0, &iv1, code))
+ return false;
+ break;
+
+ case MULT:
+ if (!iv_mult (&iv0, mby))
+ return false;
+ break;
! case ASHIFT:
! if (!iv_shift (&iv0, mby))
! return false;
! break;
!
! default:
! iv0.biv_p = false;
! break;
}
! *iv = iv0;
! return iv->base != NULL_RTX;
! }
!
! /* Analyzes iv DEF and stores the result to *IV. */
!
! static bool
! iv_analyze_def (struct ref *def, struct rtx_iv *iv)
! {
! rtx insn = DF_REF_INSN (def);
! rtx reg = DF_REF_REG (def);
! rtx set, rhs;
if (dump_file)
{
! fprintf (dump_file, "Analysing def of ");
! print_rtl (dump_file, reg);
fprintf (dump_file, " in insn ");
print_rtl_single (dump_file, insn);
}
! if (DF_REF_IV (def))
{
if (dump_file)
fprintf (dump_file, " already analysed.\n");
! *iv = *DF_REF_IV (def);
return iv->base != NULL_RTX;
}
*************** iv_analyze (rtx insn, rtx def, struct rt
*** 1034,1179 ****
iv->step = NULL_RTX;
set = single_set (insn);
rhs = find_reg_equal_equiv_note (insn);
if (rhs)
rhs = XEXP (rhs, 0);
else
rhs = SET_SRC (set);
- code = GET_CODE (rhs);
! if (CONSTANT_P (rhs))
{
! op0 = rhs;
! amode = GET_MODE (def);
}
- else
- {
- switch (code)
- {
- case SUBREG:
- if (!subreg_lowpart_p (rhs))
- goto end;
- op0 = rhs;
- break;
-
- case REG:
- op0 = rhs;
- break;
! case SIGN_EXTEND:
! case ZERO_EXTEND:
! case NEG:
! op0 = XEXP (rhs, 0);
! break;
! case PLUS:
! case MINUS:
! op0 = XEXP (rhs, 0);
! op1 = XEXP (rhs, 1);
! break;
! case MULT:
! op0 = XEXP (rhs, 0);
! mby = XEXP (rhs, 1);
! if (!CONSTANT_P (mby))
! {
! gcc_assert (CONSTANT_P (op0));
! tmp = op0;
! op0 = mby;
! mby = tmp;
! }
! break;
! case ASHIFT:
! gcc_assert (!CONSTANT_P (XEXP (rhs, 0)));
! op0 = XEXP (rhs, 0);
! mby = XEXP (rhs, 1);
! break;
! default:
! gcc_unreachable ();
! }
! amode = GET_MODE (rhs);
! }
! if (op0)
{
! if (!iv_analyze_op (insn, op0, &iv0))
! goto end;
!
! if (iv0.mode == VOIDmode)
{
! iv0.mode = amode;
! iv0.extend_mode = amode;
}
}
! if (op1)
{
! if (!iv_analyze_op (insn, op1, &iv1))
! goto end;
! if (iv1.mode == VOIDmode)
{
! iv1.mode = amode;
! iv1.extend_mode = amode;
}
}
! switch (code)
! {
! case SIGN_EXTEND:
! case ZERO_EXTEND:
! if (!iv_extend (&iv0, code, amode))
! goto end;
! break;
! case NEG:
! if (!iv_neg (&iv0))
! goto end;
! break;
! case PLUS:
! case MINUS:
! if (!iv_add (&iv0, &iv1, code))
! goto end;
! break;
! case MULT:
! if (!iv_mult (&iv0, mby))
! goto end;
! break;
! case ASHIFT:
! if (!iv_shift (&iv0, mby))
! goto end;
! break;
! default:
! break;
}
! *iv = iv0;
! end:
! iv->analysed = true;
! insn_info[uid].iv = *iv;
! if (dump_file)
! {
! print_rtl (dump_file, def);
! fprintf (dump_file, " in insn ");
! print_rtl_single (dump_file, insn);
! fprintf (dump_file, " is ");
! dump_iv_info (dump_file, iv);
! fprintf (dump_file, "\n");
! }
! return iv->base != NULL_RTX;
}
! /* Checks whether definition of register REG in INSN a basic induction
variable. IV analysis must have been initialized (via a call to
iv_analysis_loop_init) for this function to produce a result. */
--- 993,1121 ----
iv->step = NULL_RTX;
set = single_set (insn);
+ if (!set || SET_DEST (set) != reg)
+ return false;
+
rhs = find_reg_equal_equiv_note (insn);
if (rhs)
rhs = XEXP (rhs, 0);
else
rhs = SET_SRC (set);
! iv_analyze_expr (insn, rhs, GET_MODE (reg), iv);
! record_iv (def, iv);
!
! if (dump_file)
{
! print_rtl (dump_file, reg);
! fprintf (dump_file, " in insn ");
! print_rtl_single (dump_file, insn);
! fprintf (dump_file, " is ");
! dump_iv_info (dump_file, iv);
! fprintf (dump_file, "\n");
}
! return iv->base != NULL_RTX;
! }
! /* Analyzes operand OP of INSN and stores the result to *IV. */
! static bool
! iv_analyze_op (rtx insn, rtx op, struct rtx_iv *iv)
! {
! struct ref *def = NULL;
! enum iv_grd_result res;
! if (dump_file)
! {
! fprintf (dump_file, "Analysing operand ");
! print_rtl (dump_file, op);
! fprintf (dump_file, " of insn ");
! print_rtl_single (dump_file, insn);
! }
! if (CONSTANT_P (op))
! res = GRD_INVARIANT;
! else if (GET_CODE (op) == SUBREG)
! {
! if (!subreg_lowpart_p (op))
! return false;
! if (!iv_analyze_op (insn, SUBREG_REG (op), iv))
! return false;
! return iv_subreg (iv, GET_MODE (op));
! }
! else
{
! res = iv_get_reaching_def (insn, op, &def);
! if (res == GRD_INVALID)
{
! if (dump_file)
! fprintf (dump_file, " not simple.\n");
! return false;
}
}
! if (res == GRD_INVARIANT)
{
! iv_constant (iv, op, VOIDmode);
! if (dump_file)
{
! fprintf (dump_file, " ");
! dump_iv_info (dump_file, iv);
! fprintf (dump_file, "\n");
}
+ return true;
}
! if (res == GRD_MAYBE_BIV)
! return iv_analyze_biv (op, iv);
! return iv_analyze_def (def, iv);
! }
! /* Analyzes value VAL at INSN and stores the result to *IV. */
! bool
! iv_analyze (rtx insn, rtx val, struct rtx_iv *iv)
! {
! rtx reg;
! /* We must find the insn in that val is used, so that we get to UD chains.
! Since the function is sometimes called on result of get_condition,
! this does not necessarily have to be directly INSN; scan also the
! following insns. */
! if (simple_reg_p (val))
! {
! if (GET_CODE (val) == SUBREG)
! reg = SUBREG_REG (val);
! else
! reg = val;
! while (!df_find_use (df, insn, reg))
! insn = NEXT_INSN (insn);
}
! return iv_analyze_op (insn, val, iv);
! }
! /* Analyzes definition of DEF in INSN and stores the result to IV. */
! bool
! iv_analyze_result (rtx insn, rtx def, struct rtx_iv *iv)
! {
! struct ref *adef;
! adef = df_find_def (df, insn, def);
! if (!adef)
! return false;
!
! return iv_analyze_def (adef, iv);
}
! /* Checks whether definition of register REG in INSN is a basic induction
variable. IV analysis must have been initialized (via a call to
iv_analysis_loop_init) for this function to produce a result. */
*************** bool
*** 1181,1194 ****
biv_p (rtx insn, rtx reg)
{
struct rtx_iv iv;
! if (!REG_P (reg))
return false;
! if (last_def[REGNO (reg)] != insn)
return false;
! return iv_analyze_biv (reg, &iv);
}
/* Calculates value of IV at ITERATION-th iteration. */
--- 1123,1144 ----
biv_p (rtx insn, rtx reg)
{
struct rtx_iv iv;
+ struct ref *def, *last_def;
! if (!simple_reg_p (reg))
return false;
! def = df_find_def (df, insn, reg);
! gcc_assert (def != NULL);
! if (!latch_dominating_def (reg, &last_def))
! return false;
! if (last_def != def)
return false;
! if (!iv_analyze_biv (reg, &iv))
! return false;
!
! return iv.biv_p;
}
/* Calculates value of IV at ITERATION-th iteration. */
*************** get_iv_value (struct rtx_iv *iv, rtx ite
*** 1230,1251 ****
void
iv_analysis_done (void)
{
! max_insn_no = 0;
! max_reg_no = 0;
! if (insn_info)
! {
! free (insn_info);
! insn_info = NULL;
! }
! if (last_def)
! {
! free (last_def);
! last_def = NULL;
! }
! if (bivs)
{
! free (bivs);
! bivs = NULL;
}
}
--- 1180,1190 ----
void
iv_analysis_done (void)
{
! if (df)
{
! clear_iv_info ();
! df_finish (df);
! df = NULL;
}
}
*************** static void
*** 1996,2002 ****
iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition,
struct niter_desc *desc)
{
! rtx op0, op1, delta, step, bound, may_xform, def_insn, tmp, tmp0, tmp1;
struct rtx_iv iv0, iv1, tmp_iv;
rtx assumption, may_not_xform;
enum rtx_code cond;
--- 1935,1941 ----
iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition,
struct niter_desc *desc)
{
! rtx op0, op1, delta, step, bound, may_xform, tmp, tmp0, tmp1;
struct rtx_iv iv0, iv1, tmp_iv;
rtx assumption, may_not_xform;
enum rtx_code cond;
*************** iv_number_of_iterations (struct loop *lo
*** 2038,2052 ****
goto fail;
op0 = XEXP (condition, 0);
! def_insn = iv_get_reaching_def (insn, op0);
! if (!iv_analyze (def_insn, op0, &iv0))
goto fail;
if (iv0.extend_mode == VOIDmode)
iv0.mode = iv0.extend_mode = mode;
op1 = XEXP (condition, 1);
! def_insn = iv_get_reaching_def (insn, op1);
! if (!iv_analyze (def_insn, op1, &iv1))
goto fail;
if (iv1.extend_mode == VOIDmode)
iv1.mode = iv1.extend_mode = mode;
--- 1977,1989 ----
goto fail;
op0 = XEXP (condition, 0);
! if (!iv_analyze (insn, op0, &iv0))
goto fail;
if (iv0.extend_mode == VOIDmode)
iv0.mode = iv0.extend_mode = mode;
op1 = XEXP (condition, 1);
! if (!iv_analyze (insn, op1, &iv1))
goto fail;
if (iv1.extend_mode == VOIDmode)
iv1.mode = iv1.extend_mode = mode;
Index: loop-unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop-unroll.c,v
retrieving revision 1.36
diff -c -3 -p -r1.36 loop-unroll.c
*** loop-unroll.c 25 Jun 2005 02:00:35 -0000 1.36
--- loop-unroll.c 30 Aug 2005 09:02:01 -0000
*************** analyze_iv_to_split_insn (rtx insn)
*** 1657,1663 ****
if (!biv_p (insn, dest))
return NULL;
! ok = iv_analyze (insn, dest, &iv);
gcc_assert (ok);
if (iv.step == const0_rtx
--- 1666,1672 ----
if (!biv_p (insn, dest))
return NULL;
! ok = iv_analyze_result (insn, dest, &iv);
gcc_assert (ok);
if (iv.step == const0_rtx
Index: loop-unswitch.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop-unswitch.c,v
retrieving revision 1.32
diff -c -3 -p -r1.32 loop-unswitch.c
*** loop-unswitch.c 25 Jun 2005 02:00:36 -0000 1.32
--- loop-unswitch.c 30 Aug 2005 09:02:01 -0000
*************** unswitch_loops (struct loops *loops)
*** 172,178 ****
static rtx
may_unswitch_on (basic_block bb, struct loop *loop, rtx *cinsn)
{
! rtx test, at, insn, op[2], stest;
struct rtx_iv iv;
unsigned i;
enum machine_mode mode;
--- 172,178 ----
static rtx
may_unswitch_on (basic_block bb, struct loop *loop, rtx *cinsn)
{
! rtx test, at, op[2], stest;
struct rtx_iv iv;
unsigned i;
enum machine_mode mode;
*************** may_unswitch_on (basic_block bb, struct
*** 205,212 ****
if (CONSTANT_P (op[i]))
continue;
! insn = iv_get_reaching_def (at, op[i]);
! if (!iv_analyze (insn, op[i], &iv))
return NULL_RTX;
if (iv.step != const0_rtx
|| iv.first_special)
--- 205,211 ----
if (CONSTANT_P (op[i]))
continue;
! if (!iv_analyze (at, op[i], &iv))
return NULL_RTX;
if (iv.step != const0_rtx
|| iv.first_special)
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1530.2.1
diff -c -3 -p -r1.1530.2.1 Makefile.in
*** Makefile.in 30 Aug 2005 07:42:22 -0000 1.1530.2.1
--- Makefile.in 30 Aug 2005 09:10:12 -0000
*************** cfgloopanal.o : cfgloopanal.c $(CONFIG_H
*** 2295,2301 ****
$(OBSTACK_H) output.h
loop-iv.o : loop-iv.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(BASIC_BLOCK_H) \
hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h $(TM_H) $(OBSTACK_H) \
! output.h intl.h
loop-invariant.o : loop-invariant.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h \
$(TM_H) function.h $(FLAGS_H) $(DF_H) $(OBSTACK_H) output.h \
--- 2295,2301 ----
$(OBSTACK_H) output.h
loop-iv.o : loop-iv.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(BASIC_BLOCK_H) \
hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h $(TM_H) $(OBSTACK_H) \
! output.h intl.h $(DF_H)
loop-invariant.o : loop-invariant.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h \
$(TM_H) function.h $(FLAGS_H) $(DF_H) $(OBSTACK_H) output.h \
More information about the Gcc-patches
mailing list