Even more trim down init_emit usage

Jan Hubicka jh@suse.cz
Thu Jan 22 11:54:00 GMT 2004


Hi,
my first reaction to see init_emit datastructures top on the list was to reuse arrays.
After my previous patch it makes much less difference than before, but it still save
2MB of garbage for regno_reg_rtx array and 1.3MB for pointer_align.
I've moved pointer_align to the reg_attrs that has been my plan for a while anyway.

Bootstrapped/regtested i686-pc-gnu-linux
OK?

Honza

2004-01-22  Jan Hubicka  <jh@suse.cz>
	* combine.c (nonzero_bits1): Use REG_POINTER_ALIGN
	* emit-rtl.c (get_reg_attrs): Accept alignment argument.
	(reg_attrs_htab_hash, reg_attrs_htab_eq): Hash using alignment too.
	(gen_reg_rtx): Do not resize regno_pointer_align array.
	(gen_rtx_REG_offset, set_reg_attrs_from_mem): Update.
	(set_decl_rtl): Compute pointer alignment.
	(set_reg_pointer_align): New function.
	(old_regno_reg_rtx, old_regno_reg_rtx_length): New.
	(init_emit): Reuse regno_rtx array; do not construct pointer_align
	array.
	(finish_emit): New.
	(mark_reg_pointer): Update to REG_POINTER_ALIGN.
	* function.c (free_after_compilation): Use finish_emit.
	* function.h (struct function): Kill regno_pointer_align array;
	rename regno_pointer_align_length to regno_reg_rtx_length.
	(REGNO_POINTER_ALIGN): Use REG_POINTER_ALIGN.
	* integrate.c (expand_inline_function): Do not use regno_pointer_align.
	(copy_rtx_and_substitute): Use REG_POINTER_ALIGN.
	* integrate.h (struct inline_remap): Kill regno_pointer_align.
	* loop.c (lop_givs_rescan): Use REG_POINTER_ALIGN.
	* reload.c (find_reloads_subreg_address): Likewise.
	* reload1.c (reload): Likewise.
	* rtl.h (struct reg_attrs): Add pointer_align field
	(REG_POINTER_ALIGN): New macro.
	(set_reg_pointer_align): New.
	* unroll.c (unroll_loop): Use new macro.
Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.400
diff -c -3 -p -r1.400 combine.c
*** combine.c	12 Jan 2004 19:42:42 -0000	1.400
--- combine.c	21 Jan 2004 18:23:09 -0000
*************** nonzero_bits1 (rtx x, enum machine_mode 
*** 8130,8139 ****
        if ((x == stack_pointer_rtx
  	   || x == frame_pointer_rtx
  	   || x == arg_pointer_rtx)
! 	  && REGNO_POINTER_ALIGN (REGNO (x)))
  	{
  	  unsigned HOST_WIDE_INT alignment
! 	    = REGNO_POINTER_ALIGN (REGNO (x)) / BITS_PER_UNIT;
  
  #ifdef PUSH_ROUNDING
  	  /* If PUSH_ROUNDING is defined, it is possible for the
--- 8130,8139 ----
        if ((x == stack_pointer_rtx
  	   || x == frame_pointer_rtx
  	   || x == arg_pointer_rtx)
! 	  && REG_POINTER_ALIGN (x))
  	{
  	  unsigned HOST_WIDE_INT alignment
! 	    = REG_POINTER_ALIGN (x) / BITS_PER_UNIT;
  
  #ifdef PUSH_ROUNDING
  	  /* If PUSH_ROUNDING is defined, it is possible for the
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v
retrieving revision 1.366
diff -c -3 -p -r1.366 emit-rtl.c
*** emit-rtl.c	17 Jan 2004 22:14:17 -0000	1.366
--- emit-rtl.c	21 Jan 2004 18:23:50 -0000
*************** static mem_attrs *get_mem_attrs (HOST_WI
*** 194,200 ****
  				 enum machine_mode);
  static hashval_t reg_attrs_htab_hash (const void *);
  static int reg_attrs_htab_eq (const void *, const void *);
- static reg_attrs *get_reg_attrs (tree, int);
  static tree component_ref_for_mem_expr (tree);
  static rtx gen_const_vector_0 (enum machine_mode);
  static rtx gen_complex_constant_part (enum machine_mode, rtx, int);
--- 194,199 ----
*************** reg_attrs_htab_hash (const void *x)
*** 328,334 ****
  {
    reg_attrs *p = (reg_attrs *) x;
  
!   return ((p->offset * 1000) ^ (long) p->decl);
  }
  
  /* Returns nonzero if the value represented by X (which is really a
--- 327,333 ----
  {
    reg_attrs *p = (reg_attrs *) x;
  
!   return ((p->offset * 1000) ^ (long) p->decl ^ (long) p->pointer_align);
  }
  
  /* Returns nonzero if the value represented by X (which is really a
*************** reg_attrs_htab_eq (const void *x, const 
*** 341,354 ****
    reg_attrs *p = (reg_attrs *) x;
    reg_attrs *q = (reg_attrs *) y;
  
!   return (p->decl == q->decl && p->offset == q->offset);
  }
  /* Allocate a new reg_attrs structure and insert it into the hash table if
     one identical to it is not already in the table.  We are doing this for
     MEM of mode MODE.  */
  
  static reg_attrs *
! get_reg_attrs (tree decl, int offset)
  {
    reg_attrs attrs;
    void **slot;
--- 340,354 ----
    reg_attrs *p = (reg_attrs *) x;
    reg_attrs *q = (reg_attrs *) y;
  
!   return (p->decl == q->decl && p->offset == q->offset
! 	  && p->pointer_align == q->pointer_align);
  }
  /* Allocate a new reg_attrs structure and insert it into the hash table if
     one identical to it is not already in the table.  We are doing this for
     MEM of mode MODE.  */
  
  static reg_attrs *
! get_reg_attrs (tree decl, int offset, unsigned int align)
  {
    reg_attrs attrs;
    void **slot;
*************** get_reg_attrs (tree decl, int offset)
*** 359,364 ****
--- 359,365 ----
  
    attrs.decl = decl;
    attrs.offset = offset;
+   attrs.pointer_align = align;
  
    slot = htab_find_slot (reg_attrs_htab, &attrs, INSERT);
    if (*slot == 0)
*************** gen_reg_rtx (enum machine_mode mode)
*** 838,859 ****
    /* Make sure regno_pointer_align, and regno_reg_rtx are large
       enough to have an element for this pseudo reg number.  */
  
!   if (reg_rtx_no == f->emit->regno_pointer_align_length)
      {
!       int old_size = f->emit->regno_pointer_align_length;
!       char *new;
        rtx *new1;
  
-       new = ggc_realloc (f->emit->regno_pointer_align, old_size * 2);
-       memset (new + old_size, 0, old_size);
-       f->emit->regno_pointer_align = (unsigned char *) new;
- 
        new1 = ggc_realloc (f->emit->x_regno_reg_rtx,
  			  old_size * 2 * sizeof (rtx));
        memset (new1 + old_size, 0, old_size * sizeof (rtx));
        regno_reg_rtx = new1;
  
!       f->emit->regno_pointer_align_length = old_size * 2;
      }
  
    val = gen_raw_REG (mode, reg_rtx_no);
--- 839,855 ----
    /* Make sure regno_pointer_align, and regno_reg_rtx are large
       enough to have an element for this pseudo reg number.  */
  
!   if (reg_rtx_no == f->emit->regno_reg_rtx_length)
      {
!       int old_size = f->emit->regno_reg_rtx_length;
        rtx *new1;
  
        new1 = ggc_realloc (f->emit->x_regno_reg_rtx,
  			  old_size * 2 * sizeof (rtx));
        memset (new1 + old_size, 0, old_size * sizeof (rtx));
        regno_reg_rtx = new1;
  
!       f->emit->regno_reg_rtx_length = old_size * 2;
      }
  
    val = gen_raw_REG (mode, reg_rtx_no);
*************** gen_rtx_REG_offset (rtx reg, enum machin
*** 869,875 ****
  {
    rtx new = gen_rtx_REG (mode, regno);
    REG_ATTRS (new) = get_reg_attrs (REG_EXPR (reg),
! 				   REG_OFFSET (reg) + offset);
    return new;
  }
  
--- 865,872 ----
  {
    rtx new = gen_rtx_REG (mode, regno);
    REG_ATTRS (new) = get_reg_attrs (REG_EXPR (reg),
! 				   REG_OFFSET (reg) + offset,
! 				   REG_POINTER_ALIGN (reg));
    return new;
  }
  
*************** set_reg_attrs_from_mem (rtx reg, rtx mem
*** 880,886 ****
  {
    if (MEM_OFFSET (mem) && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
      REG_ATTRS (reg)
!       = get_reg_attrs (MEM_EXPR (mem), INTVAL (MEM_OFFSET (mem)));
  }
  
  /* Set the register attributes for registers contained in PARM_RTX.
--- 877,884 ----
  {
    if (MEM_OFFSET (mem) && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
      REG_ATTRS (reg)
!       = get_reg_attrs (MEM_EXPR (mem), INTVAL (MEM_OFFSET (mem)),
! 		       REG_POINTER_ALIGN (reg));
  }
  
  /* Set the register attributes for registers contained in PARM_RTX.
*************** set_reg_attrs_for_parm (rtx parm_rtx, rt
*** 902,933 ****
  	  if (GET_CODE (XEXP (x, 0)) == REG)
  	    REG_ATTRS (XEXP (x, 0))
  	      = get_reg_attrs (MEM_EXPR (mem),
! 			       INTVAL (XEXP (x, 1)));
  	}
      }
  }
  
  /* Assign the RTX X to declaration T.  */
  void
  set_decl_rtl (tree t, rtx x)
  {
    DECL_CHECK (t)->decl.rtl = x;
  
    if (!x)
      return;
    /* For register, we maintain the reverse information too.  */
    if (GET_CODE (x) == REG)
!     REG_ATTRS (x) = get_reg_attrs (t, 0);
    else if (GET_CODE (x) == SUBREG)
      REG_ATTRS (SUBREG_REG (x))
!       = get_reg_attrs (t, -SUBREG_BYTE (x));
    if (GET_CODE (x) == CONCAT)
      {
        if (REG_P (XEXP (x, 0)))
!         REG_ATTRS (XEXP (x, 0)) = get_reg_attrs (t, 0);
        if (REG_P (XEXP (x, 1)))
  	REG_ATTRS (XEXP (x, 1))
! 	  = get_reg_attrs (t, GET_MODE_UNIT_SIZE (GET_MODE (XEXP (x, 0))));
      }
    if (GET_CODE (x) == PARALLEL)
      {
--- 900,944 ----
  	  if (GET_CODE (XEXP (x, 0)) == REG)
  	    REG_ATTRS (XEXP (x, 0))
  	      = get_reg_attrs (MEM_EXPR (mem),
! 			       INTVAL (XEXP (x, 1)), 0);
  	}
      }
  }
+ /* Set the alignment of reg .  */
+ 
+ void
+ set_reg_pointer_align (rtx reg, unsigned int align)
+ {
+   REG_ATTRS (reg)
+     = get_reg_attrs (REG_EXPR (reg), REG_OFFSET (reg),
+ 		     align);
+ }
  
  /* Assign the RTX X to declaration T.  */
  void
  set_decl_rtl (tree t, rtx x)
  {
+   int align = 0;
    DECL_CHECK (t)->decl.rtl = x;
  
    if (!x)
      return;
+ 
+   if (TREE_TYPE (t) && POINTER_TYPE_P (TREE_TYPE (t)))
+    align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
    /* For register, we maintain the reverse information too.  */
    if (GET_CODE (x) == REG)
!     REG_ATTRS (x) = get_reg_attrs (t, 0, align);
    else if (GET_CODE (x) == SUBREG)
      REG_ATTRS (SUBREG_REG (x))
!       = get_reg_attrs (t, -SUBREG_BYTE (x), align);
    if (GET_CODE (x) == CONCAT)
      {
        if (REG_P (XEXP (x, 0)))
!         REG_ATTRS (XEXP (x, 0)) = get_reg_attrs (t, 0, 0);
        if (REG_P (XEXP (x, 1)))
  	REG_ATTRS (XEXP (x, 1))
! 	  = get_reg_attrs (t, GET_MODE_UNIT_SIZE (GET_MODE (XEXP (x, 0))), 0);
      }
    if (GET_CODE (x) == PARALLEL)
      {
*************** set_decl_rtl (tree t, rtx x)
*** 936,942 ****
  	{
  	  rtx y = XVECEXP (x, 0, i);
  	  if (REG_P (XEXP (y, 0)))
! 	    REG_ATTRS (XEXP (y, 0)) = get_reg_attrs (t, INTVAL (XEXP (y, 1)));
  	}
      }
  }
--- 947,953 ----
  	{
  	  rtx y = XVECEXP (x, 0, i);
  	  if (REG_P (XEXP (y, 0)))
! 	    REG_ATTRS (XEXP (y, 0)) = get_reg_attrs (t, INTVAL (XEXP (y, 1)), 0);
  	}
      }
  }
*************** mark_reg_pointer (rtx reg, int align)
*** 968,978 ****
        REG_POINTER (reg) = 1;
  
        if (align)
! 	REGNO_POINTER_ALIGN (REGNO (reg)) = align;
      }
!   else if (align && align < REGNO_POINTER_ALIGN (REGNO (reg)))
      /* We can no-longer be sure just how aligned this pointer is.  */
!     REGNO_POINTER_ALIGN (REGNO (reg)) = align;
  }
  
  /* Return 1 plus largest pseudo reg number used in the current function.  */
--- 979,989 ----
        REG_POINTER (reg) = 1;
  
        if (align)
! 	set_reg_pointer_align (reg, align);
      }
!   else if (align && align < (int)REG_POINTER_ALIGN (reg))
      /* We can no-longer be sure just how aligned this pointer is.  */
!     set_reg_pointer_align (reg, align);
  }
  
  /* Return 1 plus largest pseudo reg number used in the current function.  */
*************** copy_insn (rtx insn)
*** 5141,5146 ****
--- 5244,5253 ----
    return copy_insn_1 (insn);
  }
  
+ /* Avoid re-allocating the big arrays we use.  */
+ static GTY ((deletable (""))) rtx *old_regno_reg_rtx;
+ static int old_regno_reg_rtx_length;
+ 
  /* Initialize data structures and variables in this file
     before generating rtl for each function.  */
  
*************** init_emit (void)
*** 5163,5176 ****
  
    /* Init the tables that describe all the pseudo regs.  */
  
!   f->emit->regno_pointer_align_length = LAST_VIRTUAL_REGISTER + 101;
! 
!   f->emit->regno_pointer_align
!     = ggc_alloc_cleared (f->emit->regno_pointer_align_length
! 			 * sizeof (unsigned char));
  
!   regno_reg_rtx
!     = ggc_alloc (f->emit->regno_pointer_align_length * sizeof (rtx));
  
    /* Put copies of all the hard registers into regno_reg_rtx.  */
    memcpy (regno_reg_rtx,
--- 5270,5288 ----
  
    /* Init the tables that describe all the pseudo regs.  */
  
!   if (!old_regno_reg_rtx)
!     {
!       f->emit->regno_reg_rtx_length = LAST_VIRTUAL_REGISTER + 101;
  
!       regno_reg_rtx
! 	= ggc_alloc (f->emit->regno_reg_rtx_length * sizeof (rtx));
!     }
!   else
!     {
!        regno_reg_rtx = old_regno_reg_rtx;
!        f->emit->regno_reg_rtx_length = old_regno_reg_rtx_length;
!        old_regno_reg_rtx = NULL;
!     }
  
    /* Put copies of all the hard registers into regno_reg_rtx.  */
    memcpy (regno_reg_rtx,
*************** init_emit (void)
*** 5194,5214 ****
    REG_POINTER (virtual_cfa_rtx) = 1;
  
  #ifdef STACK_BOUNDARY
!   REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY;
!   REGNO_POINTER_ALIGN (FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
!   REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
!   REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = STACK_BOUNDARY;
! 
!   REGNO_POINTER_ALIGN (VIRTUAL_INCOMING_ARGS_REGNUM) = STACK_BOUNDARY;
!   REGNO_POINTER_ALIGN (VIRTUAL_STACK_VARS_REGNUM) = STACK_BOUNDARY;
!   REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) = STACK_BOUNDARY;
!   REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM) = STACK_BOUNDARY;
!   REGNO_POINTER_ALIGN (VIRTUAL_CFA_REGNUM) = BITS_PER_WORD;
  #endif
  
  #ifdef INIT_EXPANDERS
    INIT_EXPANDERS;
  #endif
  }
  
  /* Generate the constant 0.  */
--- 5306,5339 ----
    REG_POINTER (virtual_cfa_rtx) = 1;
  
  #ifdef STACK_BOUNDARY
!   set_reg_pointer_align (stack_pointer_rtx, STACK_BOUNDARY);
!   set_reg_pointer_align (frame_pointer_rtx, STACK_BOUNDARY);
!   set_reg_pointer_align (hard_frame_pointer_rtx, STACK_BOUNDARY);
!   set_reg_pointer_align (arg_pointer_rtx, STACK_BOUNDARY);
! 
!   set_reg_pointer_align (virtual_incoming_args_rtx, STACK_BOUNDARY);
!   set_reg_pointer_align (virtual_stack_vars_rtx, STACK_BOUNDARY);
!   set_reg_pointer_align (virtual_stack_dynamic_rtx, STACK_BOUNDARY);
!   set_reg_pointer_align (virtual_outgoing_args_rtx, STACK_BOUNDARY);
!   set_reg_pointer_align (virtual_cfa_rtx, STACK_BOUNDARY);
  #endif
  
  #ifdef INIT_EXPANDERS
    INIT_EXPANDERS;
  #endif
+ }
+ 
+ /* Release datastructures used by emit-rtl.  */
+ void
+ finish_emit (struct function *fun)
+ {
+   if (!old_regno_reg_rtx
+       || old_regno_reg_rtx_length < cfun->emit->regno_reg_rtx_length)
+     {
+       old_regno_reg_rtx = fun->emit->x_regno_reg_rtx;
+       old_regno_reg_rtx_length = cfun->emit->regno_reg_rtx_length;
+     }
+   fun->emit = NULL;
  }
  
  /* Generate the constant 0.  */
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.484
diff -c -3 -p -r1.484 function.c
*** function.c	17 Jan 2004 22:11:58 -0000	1.484
--- function.c	21 Jan 2004 18:24:25 -0000
*************** free_after_compilation (struct function 
*** 438,444 ****
  {
    f->eh = NULL;
    f->expr = NULL;
!   f->emit = NULL;
    f->varasm = NULL;
    f->machine = NULL;
  
--- 438,444 ----
  {
    f->eh = NULL;
    f->expr = NULL;
!   finish_emit (f);
    f->varasm = NULL;
    f->machine = NULL;
  
Index: function.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.h,v
retrieving revision 1.108
diff -c -3 -p -r1.108 function.h
*** function.h	13 Jan 2004 01:58:36 -0000	1.108
--- function.h	21 Jan 2004 18:24:27 -0000
*************** struct emit_status GTY(())
*** 90,106 ****
       This is used to avoid generating duplicates.  */
    location_t x_last_location;
  
!   /* The length of the regno_pointer_align, regno_decl, and x_regno_reg_rtx
!      vectors.  Since these vectors are needed during the expansion phase when
       the total number of registers in the function is not yet known, the
       vectors are copied and made bigger when necessary.  */
!   int regno_pointer_align_length;
! 
!   /* Indexed by pseudo register number, if nonzero gives the known alignment
!      for that pseudo (if REG_POINTER is set in x_regno_reg_rtx).
!      Allocated in parallel with x_regno_reg_rtx.  */
!   unsigned char * GTY ((length ("%h.x_reg_rtx_no")))
!     regno_pointer_align;
  
    /* Indexed by pseudo register number, gives the rtx for that pseudo.
       Allocated in parallel with regno_pointer_align.
--- 90,100 ----
       This is used to avoid generating duplicates.  */
    location_t x_last_location;
  
!   /* The length of the x_regno_reg_rtx vector.  Since these vectors
!      are needed during the expansion phase when
       the total number of registers in the function is not yet known, the
       vectors are copied and made bigger when necessary.  */
!   int regno_reg_rtx_length;
  
    /* Indexed by pseudo register number, gives the rtx for that pseudo.
       Allocated in parallel with regno_pointer_align.
*************** struct emit_status GTY(())
*** 116,122 ****
  #define regno_reg_rtx (cfun->emit->x_regno_reg_rtx)
  #define seq_stack (cfun->emit->sequence_stack)
  
! #define REGNO_POINTER_ALIGN(REGNO) (cfun->emit->regno_pointer_align[REGNO])
  
  struct expr_status GTY(())
  {
--- 110,116 ----
  #define regno_reg_rtx (cfun->emit->x_regno_reg_rtx)
  #define seq_stack (cfun->emit->sequence_stack)
  
! #define REGNO_POINTER_ALIGN(REGNO) REG_POINTER_ALIGN (regno_reg_rtx[REGNO])
  
  struct expr_status GTY(())
  {
Index: integrate.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/integrate.c,v
retrieving revision 1.244
diff -c -3 -p -r1.244 integrate.c
*** integrate.c	16 Jan 2004 01:44:06 -0000	1.244
--- integrate.c	21 Jan 2004 18:24:47 -0000
*************** expand_inline_function (tree fndecl, tre
*** 873,879 ****
    if (map->insns_at_start == 0)
      map->insns_at_start = emit_note (NOTE_INSN_DELETED);
  
-   map->regno_pointer_align = inl_f->emit->regno_pointer_align;
    map->x_regno_reg_rtx = inl_f->emit->x_regno_reg_rtx;
  
    /* Update the outgoing argument size to allow for those in the inlined
--- 873,878 ----
*************** copy_rtx_and_substitute (rtx orig, struc
*** 2028,2034 ****
  
  	  if (REG_POINTER (map->x_regno_reg_rtx[regno]))
  	    mark_reg_pointer (map->reg_map[regno],
! 			      map->regno_pointer_align[regno]);
  	}
        return map->reg_map[regno];
  
--- 2027,2033 ----
  
  	  if (REG_POINTER (map->x_regno_reg_rtx[regno]))
  	    mark_reg_pointer (map->reg_map[regno],
! 			      REG_POINTER_ALIGN (map->x_regno_reg_rtx[regno]));
  	}
        return map->reg_map[regno];
  
*************** copy_rtx_and_substitute (rtx orig, struc
*** 2067,2073 ****
  	  if (REG_P (map->x_regno_reg_rtx[regno])
  	      && REG_POINTER (map->x_regno_reg_rtx[regno]))
  	    mark_reg_pointer (map->reg_map[regno],
! 			      map->regno_pointer_align[regno]);
  	  regno = REGNO (map->reg_map[regno]);
  	}
        ADDRESSOF_REGNO (copy) = regno;
--- 2066,2072 ----
  	  if (REG_P (map->x_regno_reg_rtx[regno])
  	      && REG_POINTER (map->x_regno_reg_rtx[regno]))
  	    mark_reg_pointer (map->reg_map[regno],
! 			      REG_POINTER_ALIGN (map->x_regno_reg_rtx[regno]));
  	  regno = REGNO (map->reg_map[regno]);
  	}
        ADDRESSOF_REGNO (copy) = regno;
Index: integrate.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/integrate.h,v
retrieving revision 1.28
diff -c -3 -p -r1.28 integrate.h
*** integrate.h	10 Jul 2003 11:38:17 -0000	1.28
--- integrate.h	21 Jan 2004 18:24:47 -0000
*************** struct inline_remap
*** 101,108 ****
    /* Target of a return insn, if needed and inlining.  */
    rtx local_return_label;
  
!   /* Indications for regs being pointers and their alignment.  */
!   unsigned char *regno_pointer_align;
    rtx *x_regno_reg_rtx;
  
    /* The next few fields are used for subst_constants to record the SETs
--- 101,107 ----
    /* Target of a return insn, if needed and inlining.  */
    rtx local_return_label;
  
!   /* Indications for regs being pointers.  */
    rtx *x_regno_reg_rtx;
  
    /* The next few fields are used for subst_constants to record the SETs
Index: loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop.c,v
retrieving revision 1.488
diff -c -3 -p -r1.488 loop.c
*** loop.c	16 Jan 2004 01:44:06 -0000	1.488
--- loop.c	21 Jan 2004 18:25:21 -0000
*************** loop_givs_rescan (struct loop *loop, str
*** 4888,4898 ****
  	  && v->giv_type == DEST_REG
  	  && REG_POINTER (v->dest_reg))
  	mark_reg_pointer (v->new_reg,
! 			  REGNO_POINTER_ALIGN (REGNO (v->dest_reg)));
        else if (GET_CODE (v->new_reg) == REG
  	       && REG_POINTER (v->src_reg))
  	{
! 	  unsigned int align = REGNO_POINTER_ALIGN (REGNO (v->src_reg));
  
  	  if (align == 0
  	      || GET_CODE (v->add_val) != CONST_INT
--- 4888,4898 ----
  	  && v->giv_type == DEST_REG
  	  && REG_POINTER (v->dest_reg))
  	mark_reg_pointer (v->new_reg,
! 			  REG_POINTER_ALIGN (v->dest_reg));
        else if (GET_CODE (v->new_reg) == REG
  	       && REG_POINTER (v->src_reg))
  	{
! 	  unsigned int align = REG_POINTER_ALIGN (v->src_reg);
  
  	  if (align == 0
  	      || GET_CODE (v->add_val) != CONST_INT
*************** loop_givs_rescan (struct loop *loop, str
*** 4905,4911 ****
  	       && GET_CODE (v->add_val) == REG
  	       && REG_POINTER (v->add_val))
  	{
! 	  unsigned int align = REGNO_POINTER_ALIGN (REGNO (v->add_val));
  
  	  if (align == 0 || GET_CODE (v->mult_val) != CONST_INT
  	      || INTVAL (v->mult_val) % (align / BITS_PER_UNIT) != 0)
--- 4905,4911 ----
  	       && GET_CODE (v->add_val) == REG
  	       && REG_POINTER (v->add_val))
  	{
! 	  unsigned int align = REG_POINTER_ALIGN (v->add_val);
  
  	  if (align == 0 || GET_CODE (v->mult_val) != CONST_INT
  	      || INTVAL (v->mult_val) % (align / BITS_PER_UNIT) != 0)
Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.229
diff -c -3 -p -r1.229 reload.c
*** reload.c	11 Jan 2004 15:56:26 -0000	1.229
--- reload.c	21 Jan 2004 18:25:48 -0000
*************** find_reloads_subreg_address (rtx x, int 
*** 5854,5860 ****
  		      base = XEXP (base, 0);
  		    }
  		  if (GET_CODE (base) != REG
! 		      || (REGNO_POINTER_ALIGN (REGNO (base))
  			  < outer_size * BITS_PER_UNIT))
  		    return x;
  		}
--- 5854,5860 ----
  		      base = XEXP (base, 0);
  		    }
  		  if (GET_CODE (base) != REG
! 		      || (REG_POINTER_ALIGN (base)
  			  < outer_size * BITS_PER_UNIT))
  		    return x;
  		}
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.420
diff -c -3 -p -r1.420 reload1.c
*** reload1.c	17 Jan 2004 22:14:17 -0000	1.420
--- reload1.c	21 Jan 2004 18:26:17 -0000
*************** reload (rtx first, int global)
*** 1258,1264 ****
       to STACK_BOUNDARY.  It is very likely no longer valid if
       the hard frame pointer was used for register allocation.  */
    if (!frame_pointer_needed)
!     REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT;
  #endif
  
    return failure;
--- 1258,1264 ----
       to STACK_BOUNDARY.  It is very likely no longer valid if
       the hard frame pointer was used for register allocation.  */
    if (!frame_pointer_needed)
!     set_reg_pointer_align (hard_frame_pointer_rtx, BITS_PER_UNIT);
  #endif
  
    return failure;
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.449
diff -c -3 -p -r1.449 rtl.h
*** rtl.h	17 Jan 2004 22:14:17 -0000	1.449
--- rtl.h	21 Jan 2004 18:26:26 -0000
*************** typedef struct reg_attrs GTY(())
*** 112,117 ****
--- 113,119 ----
  {
    tree decl;			/* decl corresponding to REG.  */
    HOST_WIDE_INT offset;		/* Offset from start of DECL.  */
+   unsigned int pointer_align;	/* Align of the pointer.  */
  } reg_attrs;
  
  /* Common union for an element of an rtx.  */
*************** do {						\
*** 1200,1209 ****
     refer to part of a DECL.  */
  #define REG_EXPR(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->decl)
  
! /* For a MEM rtx, the offset from the start of MEM_DECL, if known, as a
     RTX that is always a CONST_INT.  */
  #define REG_OFFSET(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->offset)
  
  /* Copy the attributes that apply to memory locations from RHS to LHS.  */
  #define MEM_COPY_ATTRIBUTES(LHS, RHS)				\
    (MEM_VOLATILE_P (LHS) = MEM_VOLATILE_P (RHS),			\
--- 1202,1215 ----
     refer to part of a DECL.  */
  #define REG_EXPR(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->decl)
  
! /* For a REG rtx, the offset from the start of MEM_DECL, if known, as a
     RTX that is always a CONST_INT.  */
  #define REG_OFFSET(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->offset)
  
+ /* For a REG rtx, return the alignment, 0 if unknown.  */
+ #define REG_POINTER_ALIGN(RTX) (REG_ATTRS (RTX) == 0 \
+ 				? 0 : REG_ATTRS (RTX)->pointer_align)
+ 
  /* Copy the attributes that apply to memory locations from RHS to LHS.  */
  #define MEM_COPY_ATTRIBUTES(LHS, RHS)				\
    (MEM_VOLATILE_P (LHS) = MEM_VOLATILE_P (RHS),			\
*************** extern rtx emit_copy_of_insn_after (rtx,
*** 1452,1460 ****
  extern void set_reg_attrs_from_mem (rtx, rtx);
  extern void set_mem_attrs_from_reg (rtx, rtx);
  extern void set_reg_attrs_for_parm (rtx, rtx);
  
  /* In rtl.c */
! extern rtx rtx_alloc (RTX_CODE);
  extern rtvec rtvec_alloc (int);
  extern rtx copy_rtx (rtx);
  extern void dump_rtx_statistics (void);
--- 1458,1467 ----
  extern void set_reg_attrs_from_mem (rtx, rtx);
  extern void set_mem_attrs_from_reg (rtx, rtx);
  extern void set_reg_attrs_for_parm (rtx, rtx);
+ extern void set_reg_pointer_align (rtx, unsigned int);
  
  /* In rtl.c */
! extern rtx rtx_alloc (RTX_CODE);
  extern rtvec rtvec_alloc (int);
  extern rtx copy_rtx (rtx);
  extern void dump_rtx_statistics (void);
*************** extern int get_max_uid (void);
*** 2057,2062 ****
--- 2067,2073 ----
  extern int in_sequence_p (void);
  extern void force_next_line_note (void);
  extern void init_emit (void);
+ extern void finish_emit (struct function *);
  extern void init_emit_once (int);
  extern void push_topmost_sequence (void);
  extern void pop_topmost_sequence (void);
Index: unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/unroll.c,v
retrieving revision 1.205
diff -c -3 -p -r1.205 unroll.c
*** unroll.c	1 Dec 2003 21:57:07 -0000	1.205
--- unroll.c	21 Jan 2004 18:27:21 -0000
*************** unroll_loop (struct loop *loop, int insn
*** 1183,1189 ****
      }
  
    /* Use our current register alignment and pointer flags.  */
-   map->regno_pointer_align = cfun->emit->regno_pointer_align;
    map->x_regno_reg_rtx = cfun->emit->x_regno_reg_rtx;
  
    /* If the loop is being partially unrolled, and the iteration variables
--- 1183,1188 ----
Index: config/sparc/sparc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.h,v
retrieving revision 1.236
diff -c -3 -p -r1.236 sparc.h
*** config/sparc/sparc.h	9 Nov 2003 14:05:10 -0000	1.236
--- config/sparc/sparc.h	21 Jan 2004 18:27:40 -0000
*************** extern int sparc_mode_class[];
*** 1111,1118 ****
    do {									 \
      if (cfun && cfun->emit->regno_pointer_align && SPARC_STACK_BIAS)	 \
        {									 \
! 	REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = BITS_PER_UNIT;	 \
! 	REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT; \
        }									 \
    } while (0)
  
--- 1111,1118 ----
    do {									 \
      if (cfun && cfun->emit->regno_pointer_align && SPARC_STACK_BIAS)	 \
        {									 \
! 	set_reg_pointer_align (stack_pointer_rtx, BITS_PER_UNIT);	 \
! 	set_reg_pointer_align (hard_frame_pointer_rtx, BITS_PER_UNIT);   \
        }									 \
    } while (0)
  



More information about the Gcc-patches mailing list