This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Loop IV info patch 2



This patch combines three arrays into one, allowing two independent
ones to be overlaid to save memory.   It also simplifies debugging
of IV info.

2000-12-29  Michael Hayes  <mhayes@redhat.com>

	* loop.h (struct iv): New.
	(REG_IV_TYPE, REG_IV_CLASS, REG_INFO): Modify to use 'struct iv'.
	(struct loop_ivs): Replace 'reg_iv_type', 'reg_iv_info',
	'reg_biv_class' fields with 'regs' and 'n_regs'.
	* loop.c (loop_bivs_find, strength_reduce): Use ivs->regs array.
	* unroll.c (loop_iterations): Check array bounds with ivs->n_regs.

*** loop-7.c	Thu Dec 28 15:58:06 2000
--- loop.c	Thu Dec 28 15:58:32 2000
*************** loop_bivs_find (loop)
*** 3656,3675 ****
    struct loop_ivs *ivs = LOOP_IVS (loop);
    /* Temporary list pointers for traversing ivs->loop_iv_list.  */
    struct iv_class *bl, **backbl;
-   /* Ratio of extra register life span we can justify
-      for saving an instruction.  More if loop doesn't call subroutines
-      since in that case saving an insn makes more difference
-      and more registers are available.  */
-   /* ??? could set this to last value of threshold in move_movables */
  
    ivs->loop_iv_list = 0;
  
-   VARRAY_INT_INIT (ivs->reg_iv_type, max_reg_before_loop, "reg_iv_type");
-   VARRAY_GENERIC_PTR_INIT (ivs->reg_iv_info, max_reg_before_loop,
- 			   "reg_iv_info");
-   ivs->reg_biv_class = (struct iv_class **)
-     xcalloc (max_reg_before_loop, sizeof (struct iv_class *));
- 
    for_each_insn_in_loop (loop, check_insn_for_bivs);
    
    /* Scan ivs->loop_iv_list to remove all regs that proved not to be bivs.
--- 3656,3664 ----
*************** strength_reduce (loop, insn_count, flags
*** 4311,4316 ****
--- 4300,4307 ----
    else
      end_insert_before = emit_note_after (NOTE_INSN_DELETED, loop->end);
  
+   ivs->n_regs = max_reg_before_loop;
+   ivs->regs = (struct iv *) xcalloc (ivs->n_regs, sizeof (struct iv));
  
    /* Find all BIVs in loop.  */
    loop_bivs_find (loop);
*************** strength_reduce (loop, insn_count, flags
*** 4357,4363 ****
    /* Create reg_map to hold substitutions for replaceable giv regs.
       Some givs might have been made from biv increments, so look at
       ivs->reg_iv_type for a suitable size.  */
!   reg_map_size = ivs->reg_iv_type->num_elements;
    reg_map = (rtx *) xcalloc (reg_map_size, sizeof (rtx));
  
    /* Examine each iv class for feasibility of strength reduction/induction
--- 4348,4354 ----
    /* Create reg_map to hold substitutions for replaceable giv regs.
       Some givs might have been made from biv increments, so look at
       ivs->reg_iv_type for a suitable size.  */
!   reg_map_size = ivs->n_regs;
    reg_map = (rtx *) xcalloc (reg_map_size, sizeof (rtx));
  
    /* Examine each iv class for feasibility of strength reduction/induction
*************** strength_reduce (loop, insn_count, flags
*** 4583,4591 ****
      fprintf (loop_dump_stream, "\n");
  
  egress:
!   VARRAY_FREE (ivs->reg_iv_type);
!   VARRAY_FREE (ivs->reg_iv_info);
!   free (ivs->reg_biv_class);
    {
      struct iv_class *iv = ivs->loop_iv_list;
  
--- 4574,4580 ----
      fprintf (loop_dump_stream, "\n");
  
  egress:
!   free (ivs->regs);
    {
      struct iv_class *iv = ivs->loop_iv_list;
  
*************** check_dbra_loop (loop, insn_count)
*** 7762,7768 ****
  		       REG_EQUAL notes should still be correct.  */
  		    if (! set
  			|| GET_CODE (SET_DEST (set)) != REG
! 			|| (size_t) REGNO (SET_DEST (set)) >= ivs->reg_iv_type->num_elements
  			|| REG_IV_TYPE (ivs, REGNO (SET_DEST (set))) != GENERAL_INDUCT
  			|| REG_IV_INFO (ivs, REGNO (SET_DEST (set)))->src_reg != bl->biv->src_reg)
  		      for (pnote = &REG_NOTES (p); *pnote;)
--- 7751,7757 ----
  		       REG_EQUAL notes should still be correct.  */
  		    if (! set
  			|| GET_CODE (SET_DEST (set)) != REG
! 			|| (size_t) REGNO (SET_DEST (set)) >= ivs->n_regs
  			|| REG_IV_TYPE (ivs, REGNO (SET_DEST (set))) != GENERAL_INDUCT
  			|| REG_IV_INFO (ivs, REGNO (SET_DEST (set)))->src_reg != bl->biv->src_reg)
  		      for (pnote = &REG_NOTES (p); *pnote;)
*** loop-7.h	Thu Dec 28 15:58:03 2000
--- loop.h	Thu Dec 28 15:58:35 2000
*************** struct iv_class
*** 178,183 ****
--- 178,184 ----
                                     been reduced. */
  };
  
+ 
  typedef struct loop_mem_info
  {
    rtx mem;      /* The MEM itself.  */
*************** typedef struct loop_mem_info
*** 185,212 ****
    int optimize; /* Nonzero if we can optimize access to this MEM.  */
  } loop_mem_info;
  
! struct loop_ivs
  {
!   /* Indexed by register number, indicates whether or not register is
!      an induction variable, and if so what type.  */
!   varray_type reg_iv_type;
  
    /* Indexed by register number, contains pointer to `struct
!      induction' if register is an induction variable.  This holds
!      general info for all induction variables.  */
!   varray_type reg_iv_info;
! 
!   /* Indexed by register number, contains pointer to `struct iv_class'
!      if register is a basic induction variable.  This holds info
!      describing the class (a related group) of induction variables
!      that the biv belongs to.  */
!   struct iv_class **reg_biv_class;
  
    /* The head of a list which links together (via the next field)
       every iv class for the current loop.  */
    struct iv_class *loop_iv_list;
  };
  
  struct loop_regs
  {
    int num;
--- 186,233 ----
    int optimize; /* Nonzero if we can optimize access to this MEM.  */
  } loop_mem_info;
  
! 
! /* Definitions used by the basic induction variable discovery code.  */
! enum iv_mode
  {
!   UNKNOWN_INDUCT,
!   BASIC_INDUCT,
!   NOT_BASIC_INDUCT,
!   GENERAL_INDUCT
! };
! 
! 
! 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 *loop_iv_list;
  };
  
+ 
  struct loop_regs
  {
    int num;
*************** struct loop_info
*** 338,351 ****
    int pre_header_has_call;
  };
  
- /* 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.  */
  
--- 359,364 ----
*************** extern unsigned int max_reg_before_loop;
*** 355,365 ****
  extern struct loop **uid_loop;
  extern FILE *loop_dump_stream;
  
- #define REG_IV_TYPE(ivs, n) \
-   (*(enum iv_mode *) &VARRAY_INT(ivs->reg_iv_type, (n)))
- #define REG_IV_INFO(ivs, n) \
-   (*(struct induction **) &VARRAY_GENERIC_PTR(ivs->reg_iv_info, (n)))
- #define REG_IV_CLASS(ivs, n) ivs->reg_biv_class[n]
  
  /* Forward declarations for non-static functions declared in loop.c and
     unroll.c.  */
--- 368,373 ----
*** unroll-6.c	Fri Dec 29 21:42:15 2000
--- unroll.c	Thu Dec 28 15:58:43 2000
*************** loop_iterations (loop)
*** 3545,3551 ****
       will propagate a new pseudo into the old iteration register but
       this will be marked by having the REG_USERVAR_P bit set.  */
  
!   if ((unsigned) REGNO (iteration_var) >= ivs->reg_iv_type->num_elements
        && ! REG_USERVAR_P (iteration_var))
      abort ();
  
--- 3545,3551 ----
       will propagate a new pseudo into the old iteration register but
       this will be marked by having the REG_USERVAR_P bit set.  */
  
!   if ((unsigned) REGNO (iteration_var) >= ivs->n_regs
        && ! REG_USERVAR_P (iteration_var))
      abort ();
  
*************** loop_iterations (loop)
*** 3563,3569 ****
  
    /* If this is a new register, can't handle it since we don't have any
       reg_iv_type entry for it.  */
!   if ((unsigned) REGNO (iteration_var) >= ivs->reg_iv_type->num_elements)
      {
        if (loop_dump_stream)
  	fprintf (loop_dump_stream,
--- 3563,3569 ----
  
    /* If this is a new register, can't handle it since we don't have any
       reg_iv_type entry for it.  */
!   if ((unsigned) REGNO (iteration_var) >= ivs->n_regs)
      {
        if (loop_dump_stream)
  	fprintf (loop_dump_stream,

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]