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]

Kill the deferred string table


As suggested earlier, this patch eliminates the deferred string table;
instead, I set SYMBOL_REF_DECL for constants to point to the tree for
that constant, which allows mark_constant to do the right thing with
STRING_POOL_ADDRESS_P constants.

An obvious augmentation is to use this mechanism for other sorts of
constant, not just strings -- consider 

extern void dummy1(__complex__ double);
extern void dummy2(const char *);

static inline int n(void) { return 23; }

void test(void)
{
  if (n() != 23) {
    dummy1 (3.14159i);
    dummy2 ("blah blah blah");
  }
}

At -O2 both function calls are eliminated, and so is the string
constant, but the complex constant is still emitted despite nothing
referring to it.  But this is supposed to be "patches toward getting
rid of TREE_CST_RTL", not "overhaul varasm.c", much as it may seem to
be the latter...

Hmm, and there's a preexisting efficiency bug which this fails to fix
- once a deferred string constant is discarded, n_deferred_strings is
perpetually inflated and mark_constant_pool will never exit early.
(Before, the string was perpetually stuck in the const_str_htab and
wouldn't even get garbage-collected.)  That should be a one-line tweak
now, but I'll save it for another patch.

Bootstrapped i686-linux.

zw

        * varasm.c (const_str_htab_hash, const_str_htab_eq, STRHASH,
        struct deferred_string, const_str_htab): Kill.
        (n_deferred_strings): New static variable.
        (build_constant_desc): Set SYMBOL_REF_DECL of the new
        symbol_ref to point to the constant.
        (output_constant_def): When a deferred string is forced out,
        just clear STRING_POOL_ADDRESS_P and decrement n_deferred_strings.
        (mark_constant): Likewise.
        (maybe_output_constant_def_contents): When deferring a string
        constant, just set STRING_POOL_ADDRESS_P and increment
        n_deferred_strings.
        (mark_constant_pool): Check n_deferred_strings, not the size
        of const_str_htab.
        (init_varasm_once): No need to create const_str_htab.

        * rtl.def, rtl.h, doc/rtl.texi: Document possibility that
        SYMBOL_REF_DECL points to a constant.

===================================================================
Index: varasm.c
--- varasm.c	27 Apr 2003 03:50:27 -0000	1.343
+++ varasm.c	27 Apr 2003 18:45:46 -0000
@@ -173,8 +173,6 @@ static void asm_output_aligned_bss
   PARAMS ((FILE *, tree, const char *, int, int)) ATTRIBUTE_UNUSED;
 #endif
 #endif /* BSS_SECTION_ASM_OP */
-static hashval_t const_str_htab_hash	PARAMS ((const void *x));
-static int const_str_htab_eq		PARAMS ((const void *x, const void *y));
 static bool asm_emit_uninitialised	PARAMS ((tree, const char*, int, int));
 static void resolve_unique_section	PARAMS ((tree, int, int));
 static void mark_weak                   PARAMS ((tree));
@@ -2166,43 +2164,7 @@ static GTY(()) struct constant_descripto
   const_hash_table[MAX_HASH_TABLE];
 
 static struct constant_descriptor_tree * build_constant_desc PARAMS ((tree));
-
-/* We maintain a hash table of STRING_CST values.  Unless we are asked to force
-   out a string constant, we defer output of the constants until we know
-   they are actually used.  This will be if something takes its address or if
-   there is a usage of the string in the RTL of a function.  */
-
-#define STRHASH(x) htab_hash_pointer (x)
-
-struct deferred_string GTY(())
-{
-  const char *label;
-  tree exp;
-};
-
-static GTY ((param_is (struct deferred_string))) htab_t const_str_htab;
-
-/* Returns a hash code for X (which is a really a
-   struct deferred_string *).  */
-
-static hashval_t
-const_str_htab_hash (x)
-     const void *x;
-{
-  return STRHASH (((const struct deferred_string *) x)->label);
-}
-
-/* Returns nonzero if the value represented by X (which is really a
-   struct deferred_string *) is the same as that given by Y
-   (which is really a char *).  */
-
-static int
-const_str_htab_eq (x, y)
-     const void *x;
-     const void *y;
-{
-  return (((const struct deferred_string *) x)->label == (const char *) y);
-}
+static unsigned int n_deferred_strings = 0;
 
 /* Compute a hash code for a constant expression.  */
 
@@ -2562,6 +2524,7 @@ build_constant_desc (exp)
   /* We have a symbol name; construct the SYMBOL_REF and the MEM.  */
   symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label));
   SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL;
+  SYMBOL_REF_DECL (symbol) = exp;
 
   rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), symbol);
   set_mem_attributes (rtl, exp, 1);
@@ -2627,20 +2590,10 @@ output_constant_def (exp, defer)
     }
   else if (!defer && STRING_POOL_ADDRESS_P (XEXP (desc->rtl, 0)))
     {
-      /* If the string is currently deferred but we need to output it
-	 now, remove it from the deferred string hash table.  */
-      struct deferred_string **defstr;
-
-      defstr = (struct deferred_string **)
-	htab_find_slot_with_hash (const_str_htab, desc->label,
-				  STRHASH (desc->label), NO_INSERT);
-#ifdef ENABLE_CHECKING
-      if (!defstr)
-	abort ();
-#endif
-
+      /* This string is currently deferred but we need to output it
+	 now; mark it no longer deferred.  */
       STRING_POOL_ADDRESS_P (XEXP (desc->rtl, 0)) = 0;
-      htab_clear_slot (const_str_htab, (void **) defstr);
+      n_deferred_strings--;
       maybe_output_constant_def_contents (exp, desc->rtl, 0);
     }
 
@@ -2658,36 +2611,18 @@ maybe_output_constant_def_contents (exp,
      rtx rtl;
      int defer;
 {
-  const char *label;
-
   if (flag_syntax_only)
     return;
 
-  label = XSTR (XEXP (rtl, 0), 0);
-
+  /* Is this a string constant that can be deferred?  */
   if (defer && TREE_CODE (exp) == STRING_CST && !flag_writable_strings)
     {
-      struct deferred_string **defstr;
-      defstr = (struct deferred_string **)
-	htab_find_slot_with_hash (const_str_htab, label,
-				  STRHASH (label), INSERT);
-      if (defstr)
-	{
-	  struct deferred_string *p;
-
-	  p = (struct deferred_string *)
-	    ggc_alloc (sizeof (struct deferred_string));
-
-	  p->exp = exp;
-	  p->label = label;
-
-	  *defstr = p;
-	  STRING_POOL_ADDRESS_P (XEXP (rtl, 0)) = 1;
-	  return;
-	}
+      STRING_POOL_ADDRESS_P (XEXP (rtl, 0)) = 1;
+      n_deferred_strings++;
+      return;
     }
 
-  output_constant_def_contents (exp, label);
+  output_constant_def_contents (exp, XSTR (XEXP (rtl, 0), 0));
 }
 
 /* Now output assembler code to define the label for EXP,
@@ -3415,7 +3350,7 @@ mark_constant_pool ()
   rtx link;
   struct pool_constant *pool;
 
-  if (first_pool == 0 && htab_elements (const_str_htab) == 0)
+  if (first_pool == 0 && n_deferred_strings == 0)
     return;
 
   for (pool = first_pool; pool; pool = pool->next)
@@ -3531,20 +3466,9 @@ mark_constant (current_rtx, data)
 	}
       else if (STRING_POOL_ADDRESS_P (x))
 	{
-	  struct deferred_string *p, **defstr;
-
-	  defstr = (struct deferred_string **)
-	    htab_find_slot_with_hash (const_str_htab, XSTR (x, 0),
-				      STRHASH (XSTR (x, 0)), NO_INSERT);
-#ifdef ENABLE_CHECKING
-	  if (!defstr)
-	    abort ();
-#endif
-
-	  p = *defstr;
 	  STRING_POOL_ADDRESS_P (x) = 0;
-	  output_constant_def_contents (p->exp, p->label);
-	  htab_clear_slot (const_str_htab, (void **) defstr);
+	  n_deferred_strings--;
+	  output_constant_def_contents (SYMBOL_REF_DECL (x), XSTR (x, 0));
 	}
     }
   return 0;
@@ -4628,8 +4552,6 @@ make_decl_one_only (decl)
 void
 init_varasm_once ()
 {
-  const_str_htab = htab_create_ggc (128, const_str_htab_hash,
-				    const_str_htab_eq, NULL);
   in_named_htab = htab_create_ggc (31, in_named_entry_hash,
 				   in_named_entry_eq, NULL);
 
===================================================================
Index: rtl.def
--- rtl.def	11 Apr 2003 21:15:36 -0000	1.67
+++ rtl.def	27 Apr 2003 18:45:43 -0000
@@ -863,7 +863,8 @@ DEF_RTL_EXPR(LABEL_REF, "label_ref", "u0
 /* Reference to a named label: 
    Operand 0: label name
    Operand 1: flags (see SYMBOL_FLAG_* in rtl.h)
-   Operand 2: tree decl from which this symbol is derived, or null.  */
+   Operand 2: tree from which this symbol is derived, or null.
+   This is either a DECL node, or some kind of constant.  */
 DEF_RTL_EXPR(SYMBOL_REF, "symbol_ref", "s00", 'o')
 
 /* The condition code register is represented, in our imagination,
===================================================================
Index: rtl.h
--- rtl.h	22 Apr 2003 23:17:44 -0000	1.400
+++ rtl.h	27 Apr 2003 18:45:44 -0000
@@ -1252,7 +1252,7 @@ do {						\
 #define SYMBOL_REF_WEAK(RTX)						\
   (RTL_FLAG_CHECK1("SYMBOL_REF_WEAK", (RTX), SYMBOL_REF)->integrated)
 
-/* The tree decl associated with the symbol, or null.  */
+/* The tree (decl or constant) associated with the symbol, or null.  */
 #define SYMBOL_REF_DECL(RTX)	X0TREE ((RTX), 2)
 
 /* A set of flags on a symbol_ref that are, in some respects, redundant with
===================================================================
Index: doc/rtl.texi
--- doc/rtl.texi	22 Apr 2003 23:17:46 -0000	1.54
+++ doc/rtl.texi	27 Apr 2003 18:45:47 -0000
@@ -438,7 +438,12 @@ declaration, this is the offset into tha
 If the @code{symbol_ref} @var{x} was created for a @code{VAR_DECL} or
 a @code{FUNCTION_DECL}, that tree is recorded here.  If this value is
 null, then @var{x} was created by back end code generation routines,
-and so there is no associated front end symbol table entry.
+and there is no associated front end symbol table entry.
+
+ at code{SYMBOL_REF_DECL} may also point to a tree of class @code{'c'},
+that is, some sort of constant.  In this case, the @code{symbol_ref}
+is an entry in the per-file constant pool; again, there is no associated
+front end symbol table entry.
 
 @findex SYMBOL_REF_FLAGS
 @item SYMBOL_REF_FLAGS (@var{x})


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