cselib.c (cselib_subst_to_values, [...]): Remove reference to CONST_DOUBLE_MEM in...
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>
Sat, 3 Nov 2001 16:28:33 +0000 (16:28 +0000)
committerRichard Kenner <kenner@gcc.gnu.org>
Sat, 3 Nov 2001 16:28:33 +0000 (11:28 -0500)
* cselib.c (cselib_subst_to_values, case CONST_DOUBLE): Remove
  reference to CONST_DOUBLE_MEM in comment.
* emit-rtl.c (gen_rtx_CONST_DOUBLE): Remove one operand.
(gen_rtx, case CONST_DOUBLE): Call it with one less operand.
(init_emit_once): Don't clear CONST_DOUBLE_MEM.
* function.c (pop_function_context_from): Don't call
restore_varasm_status.
* function.h (restore_varasm_status): Delete declaration.
* gengenrtl.c (CONST_DOUBLE_FORMAT): Delete CONST_DOUBLE_MEM slot.
* rtl.c: Likewise.
* rtl.def (CONST_DOUBLE): Update comment.
* rtl.h (CONST_DOUBLE_HIGH, CONST_DOUBLE_LOW): Update operand number.
(CONST_DOUBLE_CHAIN): Likewise.
(CONST_DOUBLE_MEM): Delete.
(gen_rtx_CONST_DOUBLE): Update parameters.
* varasm.c (struct varasm_status): x_pool_offset now HOST_WIDE_INT.
Remove reference to CONST_DOUBLE_MEM.
(const_alias_set): New variable.
(immed_double_const): Change call to gen_rtx_CONST_DOUBLE.
(immed_real_const_1): Adjust tests for 0, 1, and 2.
Don't set CONST_DOUBLE_MEM.
(clear_const_double_mem): Don't do anything with const_tiny_rtx.
(output_constant_def): Don't look at TREE_CST_RTL if INTEGER_CST.
Put constant in const_alias_set.
(struct pool_constant): ALIGN now unsigned.
OFFSET now HOST_WIDE_INT.
Delete LABEL.
(restore_varasm_status): Deleted.
(mark_pool_constant): Mark desc->rtl.
(force_const_mem): Rework to store rtl in hash table,
not CONST_DOUBLE_MEM.
Put constant in const_alias_set.
(find_pool_constant): Check desc->rtl.
(mark_constants, mark_constant): Don't special-case CONST_DOUBLE.
(init_varasm_once): Initialize const_alias_set.

From-SVN: r46736

gcc/ChangeLog
gcc/cselib.c
gcc/emit-rtl.c
gcc/function.c
gcc/function.h
gcc/gengenrtl.c
gcc/rtl.c
gcc/rtl.def
gcc/rtl.h
gcc/varasm.c

index 41843f65b2b7303f07d83b8a00366ecf6549b552..239ac43c41018d1d2b9ffcf3e08824dab7383c9f 100644 (file)
@@ -1,5 +1,41 @@
 Sat Nov  3 10:37:56 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
+       * cselib.c (cselib_subst_to_values, case CONST_DOUBLE): Remove
+       reference to CONST_DOUBLE_MEM in comment.
+       * emit-rtl.c (gen_rtx_CONST_DOUBLE): Remove one operand.
+       (gen_rtx, case CONST_DOUBLE): Call it with one less operand.
+       (init_emit_once): Don't clear CONST_DOUBLE_MEM.
+       * function.c (pop_function_context_from): Don't call
+       restore_varasm_status.
+       * function.h (restore_varasm_status): Delete declaration.
+       * gengenrtl.c (CONST_DOUBLE_FORMAT): Delete CONST_DOUBLE_MEM slot.
+       * rtl.c: Likewise.
+       * rtl.def (CONST_DOUBLE): Update comment.
+       * rtl.h (CONST_DOUBLE_HIGH, CONST_DOUBLE_LOW): Update operand number.
+       (CONST_DOUBLE_CHAIN): Likewise.
+       (CONST_DOUBLE_MEM): Delete.
+       (gen_rtx_CONST_DOUBLE): Update parameters.
+       * varasm.c (struct varasm_status): x_pool_offset now HOST_WIDE_INT.
+       Remove reference to CONST_DOUBLE_MEM.
+       (const_alias_set): New variable.
+       (immed_double_const): Change call to gen_rtx_CONST_DOUBLE.
+       (immed_real_const_1): Adjust tests for 0, 1, and 2.
+       Don't set CONST_DOUBLE_MEM.
+       (clear_const_double_mem): Don't do anything with const_tiny_rtx.
+       (output_constant_def): Don't look at TREE_CST_RTL if INTEGER_CST.
+       Put constant in const_alias_set.
+       (struct pool_constant): ALIGN now unsigned.
+       OFFSET now HOST_WIDE_INT.
+       Delete LABEL.
+       (restore_varasm_status): Deleted.
+       (mark_pool_constant): Mark desc->rtl.
+       (force_const_mem): Rework to store rtl in hash table,
+       not CONST_DOUBLE_MEM.
+       Put constant in const_alias_set.
+       (find_pool_constant): Check desc->rtl.
+       (mark_constants, mark_constant): Don't special-case CONST_DOUBLE.
+       (init_varasm_once): Initialize const_alias_set.
+
        * expr.c (expand_expr, case ADDDR_EXPR): If at top level, don't call
        force_const_mem.
 
index 6498d869b16584900909457f821ed7f7484f4d16..a3120d2a8379c03755b43c8762660cca3e9cfca0 100644 (file)
@@ -793,8 +793,6 @@ cselib_subst_to_values (x)
        }
       return e->u.val_rtx;
 
-      /* CONST_DOUBLEs must be special-cased here so that we won't try to
-        look up the CONST_DOUBLE_MEM inside.  */
     case CONST_DOUBLE:
     case CONST_INT:
       return x;
index 61866387cf31e6b5c9cedbb075958fe761ce43e1..657e0b612cb6cdf0ed00b1adcf465e446480970f 100644 (file)
@@ -355,21 +355,19 @@ gen_rtx_CONST_INT (mode, arg)
    only at run-time.  */
 
 rtx
-gen_rtx_CONST_DOUBLE (mode, arg0, arg1, arg2)
+gen_rtx_CONST_DOUBLE (mode, arg0, arg1)
      enum machine_mode mode;
-     rtx arg0;
-     HOST_WIDE_INT arg1, arg2;
+     HOST_WIDE_INT arg0, arg1;
 {
   rtx r = rtx_alloc (CONST_DOUBLE);
   int i;
 
   PUT_MODE (r, mode);
-  XEXP (r, 0) = arg0;
-  X0EXP (r, 1) = NULL_RTX;
+  X0EXP (r, 0) = NULL_RTX;
+  XWINT (r, 1) = arg0;
   XWINT (r, 2) = arg1;
-  XWINT (r, 3) = arg2;
 
-  for (i = GET_RTX_LENGTH (CONST_DOUBLE) - 1; i > 3; --i)
+  for (i = GET_RTX_LENGTH (CONST_DOUBLE) - 1; i > 2; --i)
     XWINT (r, i) = 0;
 
   return r;
@@ -516,10 +514,10 @@ gen_rtx VPARAMS ((enum rtx_code code, enum machine_mode mode, ...))
 
     case CONST_DOUBLE:
       {
-       rtx arg0 = va_arg (p, rtx);
+       HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
        HOST_WIDE_INT arg1 = va_arg (p, HOST_WIDE_INT);
-       HOST_WIDE_INT arg2 = va_arg (p, HOST_WIDE_INT);
-        rt_val = gen_rtx_CONST_DOUBLE (mode, arg0, arg1, arg2);
+
+        rt_val = gen_rtx_CONST_DOUBLE (mode, arg0, arg1);
       }
       break;
 
@@ -4683,7 +4681,6 @@ init_emit_once (line_numbers)
            CONST_DOUBLE_HIGH (tem) = 0;
 
          memcpy (&CONST_DOUBLE_LOW (tem), &u, sizeof u);
-         CONST_DOUBLE_MEM (tem) = cc0_rtx;
          CONST_DOUBLE_CHAIN (tem) = NULL_RTX;
          PUT_MODE (tem, mode);
 
index 1f1c58bed4695cbefa118495cacfd54fd38e2e48..093e70ebe643ee9371db72a3685eaf8d929b97c1 100644 (file)
@@ -386,7 +386,6 @@ pop_function_context_from (context)
   reg_renumber = 0;
 
   restore_emit_status (p);
-  restore_varasm_status (p);
 
   if (restore_lang_status)
     (*restore_lang_status) (p);
index cc01d164975ccd425bb7ba3ef133417c704bf183..dc1dbccc9c8f6162f41bda13bf3522841a39889e 100644 (file)
@@ -597,7 +597,6 @@ extern void free_after_parsing              PARAMS ((struct function *));
 extern void free_after_compilation     PARAMS ((struct function *));
 
 extern void init_varasm_status         PARAMS ((struct function *));
-extern void restore_varasm_status      PARAMS ((struct function *));
 extern void free_varasm_status         PARAMS ((struct function *));
 extern void free_emit_status           PARAMS ((struct function *));
 extern void free_stmt_status            PARAMS ((struct function *));
index 711cede5297a6c20d517ae76b1bc7fbcaccabe20..ad1bc7fce0639477f84e61c7af15e63ba1df49c9 100644 (file)
@@ -71,19 +71,19 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #endif /* REAL_WIDTH */
 
 #if REAL_WIDTH == 1
-# define CONST_DOUBLE_FORMAT   "e0ww"
+# define CONST_DOUBLE_FORMAT   "0ww"
 #else
 # if REAL_WIDTH == 2
-#  define CONST_DOUBLE_FORMAT  "e0ww"
+#  define CONST_DOUBLE_FORMAT  "0ww"
 # else
 #  if REAL_WIDTH == 3
-#   define CONST_DOUBLE_FORMAT "e0www"
+#   define CONST_DOUBLE_FORMAT "0www"
 #  else
 #   if REAL_WIDTH == 4
-#    define CONST_DOUBLE_FORMAT        "e0wwww"
+#    define CONST_DOUBLE_FORMAT        "0wwww"
 #   else
 #    if REAL_WIDTH == 5
-#     define CONST_DOUBLE_FORMAT       "e0wwwww"
+#     define CONST_DOUBLE_FORMAT       "0wwwww"
 #    else
 #     define CONST_DOUBLE_FORMAT /* nothing - will cause syntax error */
 #    endif
index deaf22c24cf39e266670fa0a044af0f3f4303f14..3e73e4bf835456774c0576291dc214ec3e71d335 100644 (file)
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -30,7 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 /* Calculate the format for CONST_DOUBLE.  This depends on the relative
    widths of HOST_WIDE_INT and REAL_VALUE_TYPE.
 
-   We need to go out to e0wwwww, since REAL_ARITHMETIC assumes 16-bits
+   We need to go out to 0wwwww, since REAL_ARITHMETIC assumes 16-bits
    per element in REAL_VALUE_TYPE.
 
    This is duplicated in gengenrtl.c.
@@ -70,19 +70,19 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #endif /* REAL_WIDTH */
 
 #if REAL_WIDTH == 1
-# define CONST_DOUBLE_FORMAT   "e0ww"
+# define CONST_DOUBLE_FORMAT   "0ww"
 #else
 # if REAL_WIDTH == 2
-#  define CONST_DOUBLE_FORMAT  "e0ww"
+#  define CONST_DOUBLE_FORMAT  "0ww"
 # else
 #  if REAL_WIDTH == 3
-#   define CONST_DOUBLE_FORMAT "e0www"
+#   define CONST_DOUBLE_FORMAT "0www"
 #  else
 #   if REAL_WIDTH == 4
-#    define CONST_DOUBLE_FORMAT        "e0wwww"
+#    define CONST_DOUBLE_FORMAT        "0wwww"
 #   else
 #    if REAL_WIDTH == 5
-#     define CONST_DOUBLE_FORMAT       "e0wwwww"
+#     define CONST_DOUBLE_FORMAT       "0wwwww"
 #    else
 #     define CONST_DOUBLE_FORMAT       /* nothing - will cause syntax error */
 #    endif
index acd650adc783ddb19c862ea73722228373451c7c..d85fb1431fb66b75b415355638ff0e54ed3cdcb4 100644 (file)
@@ -560,10 +560,7 @@ DEF_RTL_EXPR(RESX, "resx", "i", 'x')
 DEF_RTL_EXPR(CONST_INT, "const_int", "w", 'o')
 
 /* numeric floating point constant.
-   Operand 0 ('e') is the MEM that stores this constant in memory, or
-   various other things (see comments at immed_double_const in
-   varasm.c).
-   Operand 1 ('0') is a chain of all CONST_DOUBLEs in use in the
+   Operand 0 ('0') is a chain of all CONST_DOUBLEs in use in the
    current function.
    Remaining operands hold the actual value.  They are all 'w' and
    there may be from 1 to 4; see rtl.c.  */
index db1e913be4419e4308396bcd491bddfc2658717b..6260f57feea91291c3f6d92a55483d749fb354d7 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -804,15 +804,11 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
    For a float, the number of ints varies,
     and CONST_DOUBLE_LOW is the one that should come first *in memory*.
     So use &CONST_DOUBLE_LOW(r) as the address of an array of ints.  */
-#define CONST_DOUBLE_LOW(r) XCWINT (r, 2, CONST_DOUBLE)
-#define CONST_DOUBLE_HIGH(r) XCWINT (r, 3, CONST_DOUBLE)
+#define CONST_DOUBLE_LOW(r) XCWINT (r, 1, CONST_DOUBLE)
+#define CONST_DOUBLE_HIGH(r) XCWINT (r, 2, CONST_DOUBLE)
 
 /* Link for chain of all CONST_DOUBLEs in use in current function.  */
-#define CONST_DOUBLE_CHAIN(r) XCEXP (r, 1, CONST_DOUBLE)
-/* The MEM which represents this CONST_DOUBLE's value in memory,
-   or const0_rtx if no MEM has been made for it yet,
-   or cc0_rtx if it is not on the chain.  */
-#define CONST_DOUBLE_MEM(r) XCEXP (r, 0, CONST_DOUBLE)
+#define CONST_DOUBLE_CHAIN(r) XCEXP (r, 0, CONST_DOUBLE)
 
 /* For a SUBREG rtx, SUBREG_REG extracts the value we want a subreg of.
    SUBREG_BYTE extracts the byte-number.  */
@@ -1619,7 +1615,7 @@ extern rtx return_address_pointer_rtx;
    add to this list, modify special_rtx in gengenrtl.c as well.  You
    should also modify gen_rtx to use the special function.  */
 
-extern rtx gen_rtx_CONST_DOUBLE PARAMS ((enum machine_mode, rtx,
+extern rtx gen_rtx_CONST_DOUBLE PARAMS ((enum machine_mode,
                                       HOST_WIDE_INT, HOST_WIDE_INT));
 extern rtx gen_rtx_CONST_INT PARAMS ((enum machine_mode, HOST_WIDE_INT));
 extern rtx gen_raw_REG PARAMS ((enum machine_mode, int));
index c42ad3840320aea2cadb340e464f7e042c38cd1c..ebdac3bced3bac1e6fb262eeca658138fd26480d 100644 (file)
@@ -96,13 +96,10 @@ struct varasm_status
 
   /* Current offset in constant pool (does not include any machine-specific
      header).  */
-  int x_pool_offset;
+  HOST_WIDE_INT x_pool_offset;
 
   /* Chain of all CONST_DOUBLE rtx's constructed for the current function.
-     They are chained through the CONST_DOUBLE_CHAIN.
-     A CONST_DOUBLE rtx has CONST_DOUBLE_MEM != cc0_rtx iff it is on this chain.
-     In that case, CONST_DOUBLE_MEM is either a MEM,
-     or const0_rtx if no MEM has been made for this CONST_DOUBLE yet.  */
+     They are chained through the CONST_DOUBLE_CHAIN.  */
   rtx x_const_double_chain;
 };
 
@@ -135,6 +132,15 @@ int size_directive_output;
 
 tree last_assemble_variable_decl;
 
+/* RTX_UNCHANGING_P in a MEM can mean it is stored into, for initialization.
+   So giving constant the alias set for the type will allow such
+   initializations to appear to conflict with the load of the constant.  We
+   avoid this by giving all constants an alias set for just constants.
+   Since there will be no stores to that a alias set, nothing will ever
+   conflict with them.  */
+
+static HOST_WIDE_INT const_alias_set;
+
 static const char *strip_reg_name      PARAMS ((const char *));
 static int contains_pointers_p         PARAMS ((tree));
 static void assemble_real_1            PARAMS ((PTR));
@@ -2249,7 +2255,7 @@ immed_double_const (i0, i1, mode)
        return r;
 
   /* No; make a new one and add it to the chain.  */
-  r = gen_rtx_CONST_DOUBLE (mode, const0_rtx, i0, i1);
+  r = gen_rtx_CONST_DOUBLE (mode, i0, i1);
 
   /* Don't touch const_double_chain if not inside any function.  */
   if (current_function_decl != 0)
@@ -2277,16 +2283,16 @@ immed_real_const_1 (d, mode)
 
   u.d = d;
 
-  /* Detect special cases.  */
-  if (REAL_VALUES_IDENTICAL (dconst0, d))
+  /* Detect special cases.  Check for NaN first, because some ports
+     (specifically the i386) do not emit correct ieee-fp code by default, and
+     thus will generate a core dump here if we pass a NaN to REAL_VALUES_EQUAL
+     and if REAL_VALUES_EQUAL does a floating point comparison.  */
+  if (! REAL_VALUE_ISNAN (d) && REAL_VALUES_IDENTICAL (dconst0, d))
     return CONST0_RTX (mode);
-
-  /* Check for NaN first, because some ports (specifically the i386) do not
-     emit correct ieee-fp code by default, and thus will generate a core
-     dump here if we pass a NaN to REAL_VALUES_EQUAL and if REAL_VALUES_EQUAL
-     does a floating point comparison.  */
   else if (! REAL_VALUE_ISNAN (d) && REAL_VALUES_EQUAL (dconst1, d))
     return CONST1_RTX (mode);
+  else if (! REAL_VALUE_ISNAN (d) && REAL_VALUES_EQUAL (dconst2, d))
+    return CONST2_RTX (mode);
 
   if (sizeof u == sizeof (HOST_WIDE_INT))
     return immed_double_const (u.i[0], 0, mode);
@@ -2325,12 +2331,6 @@ immed_real_const_1 (d, mode)
   else
     CONST_DOUBLE_CHAIN (r) = NULL_RTX;
 
-  /* Store const0_rtx in CONST_DOUBLE_MEM since this CONST_DOUBLE is on the
-     chain, but has not been allocated memory.  Actual use of CONST_DOUBLE_MEM
-     is only through force_const_mem.  */
-
-  CONST_DOUBLE_MEM (r) = const0_rtx;
-
   return r;
 }
 
@@ -2352,25 +2352,13 @@ void
 clear_const_double_mem ()
 {
   rtx r, next;
-  enum machine_mode mode;
-  int i;
 
   for (r = const_double_chain; r; r = next)
     {
       next = CONST_DOUBLE_CHAIN (r);
       CONST_DOUBLE_CHAIN (r) = 0;
-      CONST_DOUBLE_MEM (r) = cc0_rtx;
     }
   const_double_chain = 0;
-
-  for (i = 0; i <= 2; i++)
-    for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
-         mode = GET_MODE_WIDER_MODE (mode))
-      {
-       r = const_tiny_rtx[i][(int) mode];
-       CONST_DOUBLE_CHAIN (r) = 0;
-       CONST_DOUBLE_MEM (r) = cc0_rtx;
-      }
 }
 \f
 /* Given an expression EXP with a constant value,
@@ -3292,8 +3280,9 @@ output_constant_def (exp, defer)
   int found = 1;
   int after_function = 0;
   int labelno = -1;
+  rtx rtl;
 
-  if (TREE_CST_RTL (exp))
+  if (TREE_CODE (exp) != INTEGER_CST && TREE_CST_RTL (exp))
     return TREE_CST_RTL (exp);
 
   /* Make sure any other constants whose addresses appear in EXP
@@ -3328,16 +3317,21 @@ output_constant_def (exp, defer)
       const_hash_table[hash] = desc;
 
       /* We have a symbol name; construct the SYMBOL_REF and the MEM.  */
-      desc->rtl
+      rtl = desc->rtl
        = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
                       gen_rtx_SYMBOL_REF (Pmode, desc->label));
 
-      set_mem_attributes (desc->rtl, exp, 1);
+      set_mem_attributes (rtl, exp, 1);
+      set_mem_alias_set (rtl, 0);
+      set_mem_alias_set (rtl, const_alias_set);
 
       found = 0;
     }
+  else
+    rtl = desc->rtl;
 
-  TREE_CST_RTL (exp) = desc->rtl;
+  if (TREE_CODE (exp) != INTEGER_CST)
+    TREE_CST_RTL (exp) = rtl;
 
   /* Optionally set flags or add text to the name to record information
      such as that it is a function name.  If the name is changed, the macro
@@ -3348,7 +3342,7 @@ output_constant_def (exp, defer)
   if (! found)
     {
       ENCODE_SECTION_INFO (exp);
-      desc->rtl = TREE_CST_RTL (exp);
+      desc->rtl = rtl;
       desc->label = XSTR (XEXP (desc->rtl, 0), 0);
     }
 #endif
@@ -3360,7 +3354,7 @@ output_constant_def (exp, defer)
 #endif
 
   if (found
-      && STRING_POOL_ADDRESS_P (XEXP (desc->rtl, 0))
+      && STRING_POOL_ADDRESS_P (XEXP (rtl, 0))
       && (!defer || defer_addressed_constants_flag || after_function))
     {
       defstr = (struct deferred_string **)
@@ -3372,7 +3366,7 @@ output_constant_def (exp, defer)
             remove it from deferred string hash table.  */
          found = 0;
          labelno = (*defstr)->labelno;
-         STRING_POOL_ADDRESS_P (XEXP (desc->rtl, 0)) = 0;
+         STRING_POOL_ADDRESS_P (XEXP (rtl, 0)) = 0;
          htab_clear_slot (const_str_htab, (void **) defstr);
        }
     }
@@ -3383,8 +3377,9 @@ output_constant_def (exp, defer)
     {
       if (defer_addressed_constants_flag || after_function)
        {
-         struct deferred_constant *p;
-         p = (struct deferred_constant *) xmalloc (sizeof (struct deferred_constant));
+         struct deferred_constant *p
+           = (struct deferred_constant *)
+             xmalloc (sizeof (struct deferred_constant));
 
          p->exp = copy_constant (exp);
          p->reloc = reloc;
@@ -3425,13 +3420,13 @@ output_constant_def (exp, defer)
                  p->label = desc->label;
                  p->labelno = labelno;
                  *defstr = p;
-                 STRING_POOL_ADDRESS_P (XEXP (desc->rtl, 0)) = 1;
+                 STRING_POOL_ADDRESS_P (XEXP (rtl, 0)) = 1;
                }
            }
        }
     }
 
-  return TREE_CST_RTL (exp);
+  return rtl;
 }
 
 /* Now output assembler code to define the label for EXP,
@@ -3494,12 +3489,11 @@ struct pool_constant
 {
   struct constant_descriptor *desc;
   struct pool_constant *next, *next_sym;
-  const char *label;
   rtx constant;
   enum machine_mode mode;
   int labelno;
-  int align;
-  int offset;
+  unsigned int align;
+  HOST_WIDE_INT offset;
   int mark;
 };
 
@@ -3530,23 +3524,6 @@ init_varasm_status (f)
   p->x_const_double_chain = 0;
 }
 
-/* Nested functions diddle with our const_double_chain via
-   clear_const_double_mem and const_tiny_rtx.  Remove these
-   entries from our const_double_chain.  */
-
-void
-restore_varasm_status (f)
-     struct function *f;
-{
-  rtx *p = &f->varasm->x_const_double_chain;
-
-  while (*p)
-    if (CONST_DOUBLE_MEM (*p) == cc0_rtx)
-      *p = CONST_DOUBLE_CHAIN (*p);
-    else
-      p = &CONST_DOUBLE_CHAIN (*p);
-}
-
 /* Mark PC for GC.  */
 
 static void
@@ -3557,6 +3534,7 @@ mark_pool_constant (pc)
     {
       ggc_mark (pc);
       ggc_mark_rtx (pc->constant);
+      ggc_mark_rtx (pc->desc->rtl);
       pc = pc->next;
     }
 }
@@ -3590,19 +3568,22 @@ free_varasm_status (f)
   /* Clear out the hash tables.  */
   for (i = 0; i < MAX_RTX_HASH_TABLE; ++i)
     {
-      struct constant_descriptorcd;
+      struct constant_descriptor *cd;
 
       cd = p->x_const_rtx_hash_table[i];
-      while (cd) {
-       struct constant_descriptor* next = cd->next;
-       free (cd);
-       cd = next;
-      }
+      while (cd)
+       {
+         struct constant_descriptor *next = cd->next;
+
+         free (cd);
+         cd = next;
+       }
     }
 
   free (p->x_const_rtx_hash_table);
   free (p->x_const_rtx_sym_hash_table);
   free (p);
+
   f->varasm = NULL;
 }
 \f
@@ -3786,116 +3767,77 @@ force_const_mem (mode, x)
   int hash;
   struct constant_descriptor *desc;
   char label[256];
-  const char *found = 0;
   rtx def;
-
-  /* If we want this CONST_DOUBLE in the same mode as it is in memory
-     (this will always be true for floating CONST_DOUBLEs that have been
-     placed in memory, but not for VOIDmode (integer) CONST_DOUBLEs),
-     use the previous copy.  Otherwise, make a new one.  Note that in
-     the unlikely event that this same CONST_DOUBLE is used in two different
-     modes in an alternating fashion, we will allocate a lot of different
-     memory locations, but this should be extremely rare.  */
-
-  if (GET_CODE (x) == CONST_DOUBLE
-      && GET_CODE (CONST_DOUBLE_MEM (x)) == MEM
-      && GET_MODE (CONST_DOUBLE_MEM (x)) == mode)
-    return CONST_DOUBLE_MEM (x);
+  struct pool_constant *pool;
+  unsigned int align;
 
   /* Compute hash code of X.  Search the descriptors for that hash code
-     to see if any of them describes X.  If yes, the descriptor records
-     the label number already assigned.  */
-
+     to see if any of them describes X.  If yes, we have an rtx to use.  */
   hash = const_hash_rtx (mode, x);
-
   for (desc = const_rtx_hash_table[hash]; desc; desc = desc->next)
     if (compare_constant_rtx (mode, x, desc))
-      {
-       found = desc->label;
-       break;
-      }
-
-  if (found == 0)
-    {
-      struct pool_constant *pool;
-      int align;
-
-      /* No constant equal to X is known to have been output.
-        Make a constant descriptor to enter X in the hash table.
-        Assign the label number and record it in the descriptor for
-        future calls to this function to find.  */
-
-      desc = record_constant_rtx (mode, x);
-      desc->next = const_rtx_hash_table[hash];
-      const_rtx_hash_table[hash] = desc;
-
-      /* Align the location counter as required by EXP's data type.  */
-      align = GET_MODE_ALIGNMENT (mode == VOIDmode ? word_mode : mode);
+      return desc->rtl;
+
+  /* No constant equal to X is known to have been output.
+     Make a constant descriptor to enter X in the hash table
+     and make a MEM for it.  */
+  desc = record_constant_rtx (mode, x);
+  desc->next = const_rtx_hash_table[hash];
+  const_rtx_hash_table[hash] = desc;
+  
+  /* Align the location counter as required by EXP's data type.  */
+  align = GET_MODE_ALIGNMENT (mode == VOIDmode ? word_mode : mode);
 #ifdef CONSTANT_ALIGNMENT
-      align = CONSTANT_ALIGNMENT (make_tree (type_for_mode (mode, 0), x),
-                                 align);
+  align = CONSTANT_ALIGNMENT (make_tree (type_for_mode (mode, 0), x), align);
 #endif
 
-      pool_offset += (align / BITS_PER_UNIT) - 1;
-      pool_offset &= ~ ((align / BITS_PER_UNIT) - 1);
-
-      if (GET_CODE (x) == LABEL_REF)
-       LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
-
-      /* Allocate a pool constant descriptor, fill it in, and chain it in.  */
-
-      pool = (struct pool_constant *) ggc_alloc (sizeof (struct pool_constant));
-      pool->desc = desc;
-      pool->constant = x;
-      pool->mode = mode;
-      pool->labelno = const_labelno;
-      pool->align = align;
-      pool->offset = pool_offset;
-      pool->mark = 1;
-      pool->next = 0;
-
-      if (last_pool == 0)
-       first_pool = pool;
-      else
-       last_pool->next = pool;
-
-      last_pool = pool;
-      pool_offset += GET_MODE_SIZE (mode);
-
-      /* Create a string containing the label name, in LABEL.  */
-      ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
-
-      ++const_labelno;
+  pool_offset += (align / BITS_PER_UNIT) - 1;
+  pool_offset &= ~ ((align / BITS_PER_UNIT) - 1);
+
+  if (GET_CODE (x) == LABEL_REF)
+    LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
+
+  /* Allocate a pool constant descriptor, fill it in, and chain it in.  */
+  pool = (struct pool_constant *) ggc_alloc (sizeof (struct pool_constant));
+  pool->desc = desc;
+  pool->constant = x;
+  pool->mode = mode;
+  pool->labelno = const_labelno;
+  pool->align = align;
+  pool->offset = pool_offset;
+  pool->mark = 1;
+  pool->next = 0;
+
+  if (last_pool == 0)
+    first_pool = pool;
+  else
+    last_pool->next = pool;
+  
+  last_pool = pool;
+  pool_offset += GET_MODE_SIZE (mode);
 
-      desc->label = found = ggc_strdup (label);
+  /* Create a string containing the label name, in LABEL.  */
+  ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
 
-      /* Add label to symbol hash table.  */
-      hash = SYMHASH (found);
-      pool->label = found;
-      pool->next_sym = const_rtx_sym_hash_table[hash];
-      const_rtx_sym_hash_table[hash] = pool;
-    }
+  ++const_labelno;
 
-  /* We have a symbol name; construct the SYMBOL_REF and the MEM.  */
+  /* Construct the SYMBOL_REF and the MEM.  */
 
-  def = gen_rtx_MEM (mode, gen_rtx_SYMBOL_REF (Pmode, found));
+  pool->desc->rtl = def
+    = gen_rtx_MEM (mode, gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label)));
+  set_mem_alias_set (def, const_alias_set);
   set_mem_attributes (def, type_for_mode (mode, 0), 1);
   RTX_UNCHANGING_P (def) = 1;
 
+  /* Add label to symbol hash table.  */
+  hash = SYMHASH (XSTR (XEXP (def, 0), 0));
+  pool->next_sym = const_rtx_sym_hash_table[hash];
+  const_rtx_sym_hash_table[hash] = pool;
+
   /* Mark the symbol_ref as belonging to this constants pool.  */
   CONSTANT_POOL_ADDRESS_P (XEXP (def, 0)) = 1;
   current_function_uses_const_pool = 1;
 
-  if (GET_CODE (x) == CONST_DOUBLE)
-    {
-      if (CONST_DOUBLE_MEM (x) == cc0_rtx)
-       {
-         CONST_DOUBLE_CHAIN (x) = const_double_chain;
-         const_double_chain = x;
-       }
-      CONST_DOUBLE_MEM (x) = def;
-    }
-
   return def;
 }
 \f
@@ -3912,7 +3854,7 @@ find_pool_constant (f, addr)
 
   for (pool = f->varasm->x_const_rtx_sym_hash_table[SYMHASH (label)]; pool;
        pool = pool->next_sym)
-    if (pool->label == label)
+    if (XSTR (XEXP (pool->desc->rtl, 0), 0) == label)
       return pool;
 
   abort ();
@@ -4131,10 +4073,6 @@ mark_constants (x)
       mark_constant (&x, NULL);
       return;
     }
-  /* Never search inside a CONST_DOUBLE, because CONST_DOUBLE_MEM may be
-     a MEM, but does not constitute a use of that MEM.  */
-  else if (GET_CODE (x) == CONST_DOUBLE)
-    return;
 
   /* Insns may appear inside a SEQUENCE.  Only check the patterns of
      insns, not any notes that may be attached.  We don't want to mark
@@ -4182,7 +4120,7 @@ mark_constants (x)
 
 /* Given a SYMBOL_REF CURRENT_RTX, mark it and all constants it refers
    to as used.  Emit referenced deferred strings.  This function can
-   be used with for_each_rtx () to mark all SYMBOL_REFs in an rtx.  */
+   be used with for_each_rtx to mark all SYMBOL_REFs in an rtx.  */
 
 static int
 mark_constant (current_rtx, data)
@@ -4193,10 +4131,7 @@ mark_constant (current_rtx, data)
 
   if (x == NULL_RTX)
     return 0;
-  else if (GET_CODE(x) == CONST_DOUBLE)
-    /* Never search inside a CONST_DOUBLE because CONST_DOUBLE_MEM may
-       be a MEM but does not constitute a use of that MEM.  */
-    return -1;
+
   else if (GET_CODE (x) == SYMBOL_REF)
     {
       if (CONSTANT_POOL_ADDRESS_P (x))
@@ -5185,6 +5120,8 @@ init_varasm_once ()
                mark_const_hash_entry);
   ggc_add_root (&const_str_htab, 1, sizeof const_str_htab,
                mark_const_str_htab);
+
+  const_alias_set = new_alias_set ();
 }
 
 /* Select a set of attributes for section NAME based on the properties