On Sat, Mar 25, 2023 at 10:28:02AM -0600, Jeff Law via Gcc wrote:
> On 3/24/23 07:48, Paul Iannetta via Gcc wrote:
> > Hi,
> > 
> > Currently, the macro STACK_BOUNDARY is defined as
> > 
> >    Macro: STACK_BOUNDARY
> >       Define this macro to the minimum alignment enforced by hardware for
> >       the stack pointer on this machine.  The definition is a C
> >       expression for the desired alignment (measured in bits).  This
> >       value is used as a default if 'PREFERRED_STACK_BOUNDARY' is not
> >       defined.  On most machines, this should be the same as
> >       'PARM_BOUNDARY'.
> > 
> > with no mentions about its type and bounds.  However, at some point, the 
> > value
> > of this macro gets assigned to the field "regno_pointer_align" of "struct
> > emit_status" which points to an "unsigned char", hence if STACK_BOUNDARY 
> > gets
> > bigger than 255, it will overflow...  Thankfully, the backend which defines 
> > the
> > highest value is microblaze with 128 < 255.
> > 
> > The assignment happens in "emit-rtl.c" through the REGNO_POINTER_ALIGN 
> > macro:
> > 
> > in function.h:
> >    #define REGNO_POINTER_ALIGN(REGNO) 
> > (crtl->emit.regno_pointer_align[REGNO])
> > in emit-rtl.cc:
> >    REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY;
> >    [...]
> >    REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM) = STACK_BOUNDARY;
> > 
> > Would it be possible to, either add an explicit bound to STACK_BOUNDARY in 
> > the
> > manual, and/or use an "unsigned int *" rather than and "unsigned char *" for
> > the field "regno_pointer_align".
> Feel free to send a suitable patch to gcc-patches.  THe alignment data isn't
> held in the RTX structures, so it's not critical that it be kept as small as
> possible.  We don't want to waste space, so an unsigned short might be
> better.  A char was good for 30 years, so we don't need to go crazy here.
> 
> The alternative would be to change the representation to store the log2 of
> the alignment.  That would be a much larger change and would trade off
> runtime for memory consumption.  I would have suggested this approach if the
> data were in the RTX structures amd space at a premium.
> 
> While I do see a trend in processor design to reduce/remove the misalignment
> penalties (thus eliminating the driver for increasing data alignment),
> that's been primarily in high end designs.
> 
> jeff

Hi,

Here is a patch that changes the type of the variable holding the
alignment to unsigned short for the reasons outlined above.  Should I
also mention the new upper bound for STACK_BOUNDARY in the
documentation or keep it silent?

Thanks,
Paul

---->8-------------------------------------------------------8<----
From: Paul Iannetta <pianne...@kalrayinc.com>
Date: Fri, 12 Jan 2024 10:18:34 +0100
Subject: [PATCH] make regno_pointer_align a unsigned short*

This changes allows to align values greater than 128 to be used for
alignment.

        * emit-rtl.cc (emit_status::ensure_regno_capacity): Change
          unsigned char* to unsigned short*
        (init_emit): Likewise.
        * function.h (struct GTY): Likewise.
---
 gcc/emit-rtl.cc | 6 +++---
 gcc/function.h  | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
index 1856fa4884f..f0f0ad193b5 100644
--- a/gcc/emit-rtl.cc
+++ b/gcc/emit-rtl.cc
@@ -1231,9 +1231,9 @@ emit_status::ensure_regno_capacity ()
   while (reg_rtx_no >= new_size)
     new_size *= 2;
 
-  char *tmp = XRESIZEVEC (char, regno_pointer_align, new_size);
+  short *tmp = XRESIZEVEC (short, regno_pointer_align, new_size);
   memset (tmp + old_size, 0, new_size - old_size);
-  regno_pointer_align = (unsigned char *) tmp;
+  regno_pointer_align = (unsigned short *) tmp;
 
   rtx *new1 = GGC_RESIZEVEC (rtx, regno_reg_rtx, new_size);
   memset (new1 + old_size, 0, (new_size - old_size) * sizeof (rtx));
@@ -5972,7 +5972,7 @@ init_emit (void)
   crtl->emit.regno_pointer_align_length = LAST_VIRTUAL_REGISTER + 101;
 
   crtl->emit.regno_pointer_align
-    = XCNEWVEC (unsigned char, crtl->emit.regno_pointer_align_length);
+    = XCNEWVEC (unsigned short, crtl->emit.regno_pointer_align_length);
 
   regno_reg_rtx
     = ggc_cleared_vec_alloc<rtx> (crtl->emit.regno_pointer_align_length);
diff --git a/gcc/function.h b/gcc/function.h
index 2d775b877fc..c4a20060844 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -72,7 +72,7 @@ struct GTY(()) emit_status {
   /* 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((skip)) regno_pointer_align;
+  unsigned short * GTY((skip)) regno_pointer_align;
 };





Reply via email to