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]
Other format: [Raw text]

[PATCH]: Fix indexing used in reload1.c


Albert China wrote:
> I rebuilt LyX 1.2.3 with "gcc version 3.3 20030209" and now get the
> following:
>   g++ -DHAVE_CONFIG_H -I. -I. -I../../../src -I../../../images -I../../../src/ -I../../../src/frontends/ -I../../../src/frontends/controllers -I../../.. -I../../../boost -I/opt/TWWfsw/libxforms10/include -I/opt/TWWfsw/xpm/include -isystem /usr/include/X11R6 -O2 -c Dialogs.C
>   ../../../src/frontends/controllers/GUI.h: In destructor `virtual
>      ButtonController<OkApplyCancelPolicy, xformsBC>::~ButtonController()':
>   ../../../src/frontends/controllers/GUI.h:173: internal compiler error: Segmentation fault
>   Please submit a full bug report,
>   with preprocessed source if appropriate.
>   See <URL:http://www.gnu.org/software/gcc/bugs.html> for instructions.

The enclosed patch fixes the above segmentation fault under HP-UX.  The
problem is that the offsetting of the base pointer results in a base
pointer that points into the text space.  This caused the wrong space
register to be used for loads and stores to the array "offsets_at".

The base pointer was offset to save a subtraction.  While this works
on most architectures, it doesn't work under hpux which has a segmented
non-flat memory model.  The above code has a huge number of labels
and the offset became quite large.

The patch below revises the code to avoid doing the offset as I don't
believe that it conforms to the C standard.

Ok for 3.3 and trunk?  Tested with no regressions on hppa2.0-hp-hpux11.11.
Also tested with a full build of lyx-1.2.3.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)

2003-02-10  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	* reload1.c (first_label_num): New.
	(reload): Index offsets_known_at and offsets_at using difference of
	label number and first label number.  Don't use offset pointers.
	(set_label_offsets, set_initial_label_offsets): Likewise.

Index: reload1.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.366.2.1
diff -u -3 -p -r1.366.2.1 reload1.c
--- reload1.c	8 Jan 2003 19:29:00 -0000	1.366.2.1
+++ reload1.c	10 Feb 2003 04:12:30 -0000
@@ -352,11 +352,14 @@ static int num_eliminable_invariants;
 
 /* For each label, we record the offset of each elimination.  If we reach
    a label by more than one path and an offset differs, we cannot do the
-   elimination.  This information is indexed by the number of the label.
-   The first table is an array of flags that records whether we have yet
-   encountered a label and the second table is an array of arrays, one
-   entry in the latter array for each elimination.  */
+   elimination.  This information is indexed by the difference of the
+   number of the label and the first label number.  We can't offset the
+   pointer itself as this can cause problems on machines with segmented
+   memory.  The first table is an array of flags that records whether we
+   have yet encountered a label and the second table is an array of arrays,
+   one entry in the latter array for each elimination.  */
 
+static int first_label_num;
 static char *offsets_known_at;
 static int (*offsets_at)[NUM_ELIMINABLE_REGS];
 
@@ -673,11 +676,6 @@ reload (first, global)
   struct elim_table *ep;
   basic_block bb;
 
-  /* The two pointers used to track the true location of the memory used
-     for label offsets.  */
-  char *real_known_ptr = NULL;
-  int (*real_at_ptr)[NUM_ELIMINABLE_REGS];
-
   /* Make sure even insns with volatile mem refs are recognizable.  */
   init_recog ();
 
@@ -856,21 +854,18 @@ reload (first, global)
 
   init_elim_table ();
 
-  num_labels = max_label_num () - get_first_label_num ();
+  first_label_num = get_first_label_num ();
+  num_labels = max_label_num () - first_label_num;
 
   /* Allocate the tables used to store offset information at labels.  */
   /* We used to use alloca here, but the size of what it would try to
      allocate would occasionally cause it to exceed the stack limit and
      cause a core dump.  */
-  real_known_ptr = xmalloc (num_labels);
-  real_at_ptr
+  offsets_known_at = xmalloc (num_labels);
+  offsets_at
     = (int (*)[NUM_ELIMINABLE_REGS])
     xmalloc (num_labels * NUM_ELIMINABLE_REGS * sizeof (int));
 
-  offsets_known_at = real_known_ptr - get_first_label_num ();
-  offsets_at
-    = (int (*)[NUM_ELIMINABLE_REGS]) (real_at_ptr - get_first_label_num ());
-
   /* Alter each pseudo-reg rtx to contain its hard reg number.
      Assign stack slots to the pseudos that lack hard regs or equivalents.
      Do not touch virtual registers.  */
@@ -1269,10 +1264,10 @@ reload (first, global)
     free (reg_equiv_memory_loc);
   reg_equiv_memory_loc = 0;
 
-  if (real_known_ptr)
-    free (real_known_ptr);
-  if (real_at_ptr)
-    free (real_at_ptr);
+  if (offsets_known_at)
+    free (offsets_known_at);
+  if (offsets_at)
+    free (offsets_at);
 
   free (reg_equiv_mem);
   free (reg_equiv_init);
@@ -2155,13 +2150,13 @@ set_label_offsets (x, insn, initial_p)
 	 we guessed wrong, we will suppress an elimination that might have
 	 been possible had we been able to guess correctly.  */
 
-      if (! offsets_known_at[CODE_LABEL_NUMBER (x)])
+      if (! offsets_known_at[CODE_LABEL_NUMBER (x) - first_label_num])
 	{
 	  for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
-	    offsets_at[CODE_LABEL_NUMBER (x)][i]
+	    offsets_at[CODE_LABEL_NUMBER (x) - first_label_num][i]
 	      = (initial_p ? reg_eliminate[i].initial_offset
 		 : reg_eliminate[i].offset);
-	  offsets_known_at[CODE_LABEL_NUMBER (x)] = 1;
+	  offsets_known_at[CODE_LABEL_NUMBER (x) - first_label_num] = 1;
 	}
 
       /* Otherwise, if this is the definition of a label and it is
@@ -2178,7 +2173,7 @@ set_label_offsets (x, insn, initial_p)
 	   where the offsets disagree.  */
 
 	for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
-	  if (offsets_at[CODE_LABEL_NUMBER (x)][i]
+	  if (offsets_at[CODE_LABEL_NUMBER (x) - first_label_num][i]
 	      != (initial_p ? reg_eliminate[i].initial_offset
 		  : reg_eliminate[i].offset))
 	    reg_eliminate[i].can_eliminate = 0;
@@ -3387,7 +3382,7 @@ static void
 set_initial_label_offsets ()
 {
   rtx x;
-  memset ((char *) &offsets_known_at[get_first_label_num ()], 0, num_labels);
+  memset (offsets_known_at, 0, num_labels);
 
   for (x = forced_labels; x; x = XEXP (x, 1))
     if (XEXP (x, 0))
@@ -3408,7 +3403,8 @@ set_offsets_for_label (insn)
   num_not_at_initial_offset = 0;
   for (i = 0, ep = reg_eliminate; i < NUM_ELIMINABLE_REGS; ep++, i++)
     {
-      ep->offset = ep->previous_offset = offsets_at[label_nr][i];
+      ep->offset = ep->previous_offset
+		 = offsets_at[label_nr - first_label_num][i];
       if (ep->can_eliminate && ep->offset != ep->initial_offset)
 	num_not_at_initial_offset++;
     }


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