]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR bootstrap/14671 (caller-save.c:491: internal compiler error: Segmentation fault)
authorRichard Henderson <rth@redhat.com>
Sat, 24 Apr 2004 19:40:46 +0000 (12:40 -0700)
committerJohn David Anglin <danglin@gcc.gnu.org>
Sat, 24 Apr 2004 19:40:46 +0000 (19:40 +0000)
PR bootstrap/14671
        * alias.c (alias_invariant, alias_invariant_size): Mark GTY.
        (reg_known_value, reg_known_value_size): Likewise; make static.
        (reg_known_equiv_p): Make static.
        (clear_reg_alias_info): Update for new indexing.
        (get_reg_known_value, set_reg_known_value): New.
        (get_reg_known_equiv_p, set_reg_known_equiv_p): New.
        (canon_rtx): Use them.
        (init_alias_analysis): Likewise.  Allocate reg_known_value with gc.
        Don't play queer offsetting games with reg_known_value and
        reg_known_equiv_p.
        (end_alias_analysis): Don't free reg_known_value.
        * rtl.h (get_reg_known_value, get_reg_known_equiv_p): Declare.
        * sched-deps.c (reg_known_equiv_p, reg_known_value): Remove.
        (deps_may_trap_p, sched_analyze_1, sched_analyze_2): Use the new
        functions instead.

From-SVN: r81145

gcc/ChangeLog
gcc/alias.c
gcc/rtl.h
gcc/sched-deps.c

index fad2d5719f02601ca308d6b992450fe139b75776..f8e5f32154d9894bf9b8bac3b1b00fc3c887f4aa 100644 (file)
@@ -1,3 +1,22 @@
+2004-04-24  Richard Henderson  <rth@redhat.com>
+
+       PR bootstrap/14671
+        * alias.c (alias_invariant, alias_invariant_size): Mark GTY.
+        (reg_known_value, reg_known_value_size): Likewise; make static.
+        (reg_known_equiv_p): Make static.
+        (clear_reg_alias_info): Update for new indexing.
+        (get_reg_known_value, set_reg_known_value): New.
+        (get_reg_known_equiv_p, set_reg_known_equiv_p): New.
+        (canon_rtx): Use them. 
+        (init_alias_analysis): Likewise.  Allocate reg_known_value with gc.
+        Don't play queer offsetting games with reg_known_value and
+        reg_known_equiv_p.
+        (end_alias_analysis): Don't free reg_known_value.
+        * rtl.h (get_reg_known_value, get_reg_known_equiv_p): Declare.
+        * sched-deps.c (reg_known_equiv_p, reg_known_value): Remove.
+        (deps_may_trap_p, sched_analyze_1, sched_analyze_2): Use the new
+        functions instead.
+
 2004-04-21  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        * pa64-hpux.h (LIB_SPEC): Fix library specification used with GNU ld.
index dd842696402670bf0126528316abd4709c8db3ee..3213f33ed906cbb7de25a5698ab97f27f4e98e18 100644 (file)
@@ -173,16 +173,16 @@ static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];
 
    Because this array contains only pseudo registers it has no effect
    after reload.  */
-static rtx *alias_invariant;
+static GTY((length("alias_invariant_size"))) rtx *alias_invariant;
+unsigned GTY(()) int alias_invariant_size;
 
 /* Vector indexed by N giving the initial (unchanging) value known for
-   pseudo-register N.  This array is initialized in
-   init_alias_analysis, and does not change until end_alias_analysis
-   is called.  */
-rtx *reg_known_value;
+   pseudo-register N.  This array is initialized in init_alias_analysis,
+   and does not change until end_alias_analysis is called.  */
+static GTY((length("reg_known_value_size"))) rtx *reg_known_value;
 
 /* Indicates number of valid entries in reg_known_value.  */
-static unsigned int reg_known_value_size;
+static GTY(()) unsigned int reg_known_value_size;
 
 /* Vector recording for each reg_known_value whether it is due to a
    REG_EQUIV note.  Future passes (viz., reload) may replace the
@@ -196,7 +196,7 @@ static unsigned int reg_known_value_size;
    REG_EQUIV notes.  One could argue that the REG_EQUIV notes are
    wrong, but solving the problem in the scheduler will likely give
    better code, so we do it here.  */
-char *reg_known_equiv_p;
+static bool *reg_known_equiv_p;
 
 /* True when scanning insns from the start of the rtl to the
    NOTE_INSN_FUNCTION_BEG note.  */
@@ -1029,7 +1029,7 @@ record_base_value (regno, val, invariant)
   if (regno >= reg_base_value_size)
     return;
 
-  if (invariant && alias_invariant)
+  if (invariant && alias_invariant && regno < alias_invariant_size)
     alias_invariant[regno] = val;
 
   if (GET_CODE (val) == REG)
@@ -1054,10 +1054,70 @@ clear_reg_alias_info (reg)
 {
   unsigned int regno = REGNO (reg);
 
-  if (regno < reg_known_value_size && regno >= FIRST_PSEUDO_REGISTER)
-    reg_known_value[regno] = reg;
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    {
+      regno -= FIRST_PSEUDO_REGISTER;
+      if (regno < reg_known_value_size)
+       {
+         reg_known_value[regno] = reg;
+         reg_known_equiv_p[regno] = false;
+       }
+    }
+}
+
+/* If a value is known for REGNO, return it.  */
+
+rtx 
+get_reg_known_value (unsigned int regno)
+{
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    {
+      regno -= FIRST_PSEUDO_REGISTER;
+      if (regno < reg_known_value_size)
+       return reg_known_value[regno];
+    }
+  return NULL;
+}
+
+/* Set it.  */
+
+static void
+set_reg_known_value (unsigned int regno, rtx val)
+{
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    {
+      regno -= FIRST_PSEUDO_REGISTER;
+      if (regno < reg_known_value_size)
+       reg_known_value[regno] = val;
+    }
+}
+
+/* Similarly for reg_known_equiv_p.  */
+
+bool
+get_reg_known_equiv_p (unsigned int regno)
+{
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    {
+      regno -= FIRST_PSEUDO_REGISTER;
+      if (regno < reg_known_value_size)
+       return reg_known_equiv_p[regno];
+    }
+  return false;
+}
+
+static void
+set_reg_known_equiv_p (unsigned int regno, bool val)
+{
+  if (regno >= FIRST_PSEUDO_REGISTER)
+    {
+      regno -= FIRST_PSEUDO_REGISTER;
+      if (regno < reg_known_value_size)
+       reg_known_equiv_p[regno] = val;
+    }
 }
 
+
 /* Returns a canonical version of X, from the point of view alias
    analysis.  (For example, if X is a MEM whose address is a register,
    and the register has a known value (say a SYMBOL_REF), then a MEM
@@ -1068,11 +1128,16 @@ canon_rtx (x)
      rtx x;
 {
   /* Recursively look for equivalences.  */
-  if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
-      && REGNO (x) < reg_known_value_size)
-    return reg_known_value[REGNO (x)] == x
-      ? x : canon_rtx (reg_known_value[REGNO (x)]);
-  else if (GET_CODE (x) == PLUS)
+  if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
+    {
+      rtx t = get_reg_known_value (REGNO (x));
+      if (t == x)
+       return x;
+      if (t)
+       return canon_rtx (t);
+    }
+
+  if (GET_CODE (x) == PLUS)
     {
       rtx x0 = canon_rtx (XEXP (x, 0));
       rtx x1 = canon_rtx (XEXP (x, 1));
@@ -2698,14 +2763,9 @@ init_alias_analysis ()
   unsigned int ui;
   rtx insn;
 
-  reg_known_value_size = maxreg;
-
-  reg_known_value
-    = (rtx *) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (rtx))
-    - FIRST_PSEUDO_REGISTER;
-  reg_known_equiv_p
-    = (char*) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (char))
-    - FIRST_PSEUDO_REGISTER;
+  reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER;
+  reg_known_value = ggc_calloc (reg_known_value_size, sizeof (rtx));
+  reg_known_equiv_p = xcalloc (reg_known_value_size, sizeof (bool));
 
   /* Overallocate reg_base_value to allow some growth during loop
      optimization.  Loop unrolling can create a large number of
@@ -2722,6 +2782,7 @@ init_alias_analysis ()
       alias_invariant = (rtx *)xrealloc (alias_invariant,
                                         reg_base_value_size * sizeof (rtx));
       memset ((char *)alias_invariant, 0, reg_base_value_size * sizeof (rtx));
+      alias_invariant_size = reg_base_value_size;
     }
 
   /* The basic idea is that each pass through this loop will use the
@@ -2810,6 +2871,7 @@ init_alias_analysis ()
                {
                  unsigned int regno = REGNO (SET_DEST (set));
                  rtx src = SET_SRC (set);
+                 rtx t;
 
                  if (REG_NOTES (insn) != 0
                      && (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
@@ -2817,29 +2879,28 @@ init_alias_analysis ()
                          || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
                      && GET_CODE (XEXP (note, 0)) != EXPR_LIST
                      && ! rtx_varies_p (XEXP (note, 0), 1)
-                     && ! reg_overlap_mentioned_p (SET_DEST (set), XEXP (note, 0)))
+                     && ! reg_overlap_mentioned_p (SET_DEST (set),
+                                                   XEXP (note, 0)))
                    {
-                     reg_known_value[regno] = XEXP (note, 0);
-                     reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;
+                     set_reg_known_value (regno, XEXP (note, 0));
+                     set_reg_known_equiv_p (regno,
+                       REG_NOTE_KIND (note) == REG_EQUIV);
                    }
                  else if (REG_N_SETS (regno) == 1
                           && GET_CODE (src) == PLUS
                           && GET_CODE (XEXP (src, 0)) == REG
-                          && REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER
-                          && (reg_known_value[REGNO (XEXP (src, 0))])
+                          && (t = get_reg_known_value (REGNO (XEXP (src, 0))))
                           && GET_CODE (XEXP (src, 1)) == CONST_INT)
                    {
-                     rtx op0 = XEXP (src, 0);
-                     op0 = reg_known_value[REGNO (op0)];
-                     reg_known_value[regno]
-                       = plus_constant (op0, INTVAL (XEXP (src, 1)));
-                     reg_known_equiv_p[regno] = 0;
+                     t = plus_constant (t, INTVAL (XEXP (src, 1)));
+                     set_reg_known_value (regno, t);
+                     set_reg_known_equiv_p (regno, 0);
                    }
                  else if (REG_N_SETS (regno) == 1
                           && ! rtx_varies_p (src, 1))
                    {
-                     reg_known_value[regno] = src;
-                     reg_known_equiv_p[regno] = 0;
+                     set_reg_known_value (regno, src);
+                     set_reg_known_equiv_p (regno, 0);
                    }
                }
            }
@@ -2863,9 +2924,9 @@ init_alias_analysis ()
   while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
 
   /* Fill in the remaining entries.  */
-  for (i = FIRST_PSEUDO_REGISTER; i < maxreg; i++)
+  for (i = 0; i < (int)reg_known_value_size; i++)
     if (reg_known_value[i] == 0)
-      reg_known_value[i] = regno_reg_rtx[i];
+      reg_known_value[i] = regno_reg_rtx[i + FIRST_PSEUDO_REGISTER];
 
   /* Simplify the reg_base_value array so that no register refers to
      another register, except to special registers indirectly through
@@ -2908,10 +2969,9 @@ init_alias_analysis ()
 void
 end_alias_analysis ()
 {
-  free (reg_known_value + FIRST_PSEUDO_REGISTER);
   reg_known_value = 0;
   reg_known_value_size = 0;
-  free (reg_known_equiv_p + FIRST_PSEUDO_REGISTER);
+  free (reg_known_equiv_p);
   reg_known_equiv_p = 0;
   reg_base_value = 0;
   reg_base_value_size = 0;
@@ -2919,6 +2979,7 @@ end_alias_analysis ()
     {
       free (alias_invariant);
       alias_invariant = 0;
+      alias_invariant_size = 0;
     }
 }
 
index 2d66fd79ad2083d42423c5855021d23d2f83c44d..715febfddd92a2bf430c0132591831bf60ce199e 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2258,6 +2258,8 @@ extern void init_alias_once               PARAMS ((void));
 extern void init_alias_analysis                PARAMS ((void));
 extern void end_alias_analysis         PARAMS ((void));
 extern rtx addr_side_effect_eval       PARAMS ((rtx, int, int));
+extern rtx get_reg_known_value         PARAMS ((unsigned int));
+extern bool get_reg_known_equiv_p      PARAMS ((unsigned int));
 
 /* In sibcall.c */
 typedef enum {
index e261608cdfc5e0f0ca5bce7c13b275b3d8bb75d6..1befd3deb4a7fdb130d5d5b632fa6d82c295dcec 100644 (file)
@@ -41,8 +41,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "params.h"
 #include "cselib.h"
 
-extern char *reg_known_equiv_p;
-extern rtx *reg_known_value;
 
 static regset_head reg_pending_sets_head;
 static regset_head reg_pending_clobbers_head;
@@ -101,10 +99,12 @@ deps_may_trap_p (mem)
 {
   rtx addr = XEXP (mem, 0);
 
-  if (REG_P (addr)
-      && REGNO (addr) >= FIRST_PSEUDO_REGISTER
-      && reg_known_value[REGNO (addr)])
-    addr = reg_known_value[REGNO (addr)];
+  if (REG_P (addr) && REGNO (addr) >= FIRST_PSEUDO_REGISTER)
+    {
+      rtx t = get_reg_known_value (REGNO (addr));
+      if (t)
+       addr = t;
+    }
   return rtx_addr_can_trap_p (addr);
 }
 \f
@@ -628,10 +628,12 @@ sched_analyze_1 (deps, x, insn)
          /* Pseudos that are REG_EQUIV to something may be replaced
             by that during reloading.  We need only add dependencies for
             the address in the REG_EQUIV note.  */
-         if (!reload_completed
-             && reg_known_equiv_p[regno]
-             && GET_CODE (reg_known_value[regno]) == MEM)
-           sched_analyze_2 (deps, XEXP (reg_known_value[regno], 0), insn);
+         if (!reload_completed && get_reg_known_equiv_p (regno))
+           {
+             rtx t = get_reg_known_value (regno);
+             if (GET_CODE (t) == MEM)
+               sched_analyze_2 (deps, XEXP (t, 0), insn);
+           }
 
          /* Don't let it cross a call after scheduling if it doesn't
             already cross one.  */
@@ -763,10 +765,12 @@ sched_analyze_2 (deps, x, insn)
            /* Pseudos that are REG_EQUIV to something may be replaced
               by that during reloading.  We need only add dependencies for
               the address in the REG_EQUIV note.  */
-           if (!reload_completed
-               && reg_known_equiv_p[regno]
-               && GET_CODE (reg_known_value[regno]) == MEM)
-             sched_analyze_2 (deps, XEXP (reg_known_value[regno], 0), insn);
+           if (!reload_completed && get_reg_known_equiv_p (regno))
+             {
+               rtx t = get_reg_known_value (regno);
+               if (GET_CODE (t) == MEM)
+                 sched_analyze_2 (deps, XEXP (t, 0), insn);
+             }
 
            /* If the register does not already cross any calls, then add this
               insn to the sched_before_next_call list so that it will still