This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: Recursively Mark Used Constants
- To: gcc-patches at gcc dot gnu dot org
- Subject: PATCH: Recursively Mark Used Constants
- From: Jeffrey Oldham <oldham at codesourcery dot com>
- Date: Fri, 5 Jan 2001 12:28:11 -0800
- Cc: Jeffrey Oldham <oldham at codesourcery dot com>
- Organization: CodeSourcery LLC
Modify gcc/varasm.c's search for constants that are used by insns to
recursively mark all constants referred to by a constant that itself
is used. For example, gcc/testsuite/gcc.c-torture/execute/991227-1.c
has a constant '1 + (flag ? "\0wrong\n" : "\0right\n")' that itself
contains two constant strings for which assembly code must be
produced.
Tested on mips-sgi-irix6.5 and i686-pc-linux-gnu
Approved by Mark Mitchell (mark@codesourcery.com)
2001-01-05 Jeffrey Oldham <oldham@codesourcery.com>
* varasm.c (mark_constant_pool): Improve initial comments.
(mark_constants): Move marking of constants to mark_constant.
(mark_constant): New function to recursively mark all constants
referred to by a constant.
Thanks,
Jeffrey D. Oldham
oldham@codesourcery.com
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.153
diff -c -p -r1.153 varasm.c
*** varasm.c 2001/01/05 05:58:23 1.153
--- varasm.c 2001/01/05 20:20:51
*************** static struct constant_descriptor *recor
*** 169,174 ****
--- 169,175 ----
static struct pool_constant *find_pool_constant PARAMS ((struct function *, rtx));
static void mark_constant_pool PARAMS ((void));
static void mark_constants PARAMS ((rtx));
+ static int mark_constant PARAMS ((rtx *current_rtx, void *data));
static int output_addressed_constants PARAMS ((tree));
static void output_after_function_constants PARAMS ((void));
static unsigned HOST_WIDE_INT array_size_for_constructor PARAMS ((tree));
*************** output_constant_pool (fnname, fndecl)
*** 3927,3933 ****
}
/* Look through the instructions for this function, and mark all the
! entries in the constant pool which are actually being used. */
static void
mark_constant_pool ()
--- 3928,3935 ----
}
/* Look through the instructions for this function, and mark all the
! entries in the constant pool which are actually being used.
! Emit used deferred strings. */
static void
mark_constant_pool ()
*************** mark_constant_pool ()
*** 3950,3990 ****
insn = XEXP (insn, 1))
if (INSN_P (insn))
mark_constants (PATTERN (insn));
-
- /* It's possible that the only reference to a symbol is in a symbol
- that's in the constant pool. This happens in Fortran under some
- situations. (When the constant contains the address of another
- constant, and only the first is used directly in an insn.)
- This is potentially suboptimal if there's ever a possibility of
- backwards (in pool order) 2'd level references. However, it's
- not clear that 2'd level references can happen. */
- for (pool = first_pool; pool; pool = pool->next)
- {
- struct pool_constant *tem;
- const char *label;
-
- /* skip unmarked entries; no insn refers to them. */
- if (!pool->mark)
- continue;
-
- /* Skip everything except SYMBOL_REFs. */
- if (GET_CODE (pool->constant) != SYMBOL_REF)
- continue;
- label = XSTR (pool->constant, 0);
-
- /* Be sure the symbol's value is marked. */
- for (tem = const_rtx_sym_hash_table[SYMHASH (label)]; tem;
- tem = tem->next)
- if (tem->label == label)
- tem->mark = 1;
- /* If we didn't find it, there's something truly wrong here, but it
- will be announced by the assembler. */
- }
}
static void
mark_constants (x)
! register rtx x;
{
register int i;
register const char *format_ptr;
--- 3952,3967 ----
insn = XEXP (insn, 1))
if (INSN_P (insn))
mark_constants (PATTERN (insn));
}
+ /* Look through appropriate parts of X, marking all entries in the
+ constant pool which are actually being used. Entries that are only
+ referenced by other constants are also marked as used. Emit
+ deferred strings that are used. */
+
static void
mark_constants (x)
! rtx x;
{
register int i;
register const char *format_ptr;
*************** mark_constants (x)
*** 3994,4017 ****
if (GET_CODE (x) == SYMBOL_REF)
{
! if (CONSTANT_POOL_ADDRESS_P (x))
! find_pool_constant (cfun, x)->mark = 1;
! else if (STRING_POOL_ADDRESS_P (x))
! {
! struct deferred_string **defstr;
!
! defstr = (struct deferred_string **)
! htab_find_slot_with_hash (const_str_htab, XSTR (x, 0),
! STRHASH (XSTR (x, 0)), NO_INSERT);
! if (defstr)
! {
! struct deferred_string *p = *defstr;
!
! STRING_POOL_ADDRESS_P (x) = 0;
! output_constant_def_contents (p->exp, 0, p->labelno);
! htab_clear_slot (const_str_htab, (void **) defstr);
! }
! }
return;
}
/* Never search inside a CONST_DOUBLE, because CONST_DOUBLE_MEM may be
--- 3971,3977 ----
if (GET_CODE (x) == SYMBOL_REF)
{
! mark_constant (&x, NULL);
return;
}
/* Never search inside a CONST_DOUBLE, because CONST_DOUBLE_MEM may be
*************** mark_constants (x)
*** 4061,4066 ****
--- 4021,4075 ----
abort ();
}
}
+ }
+
+ /* 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. */
+
+ static int
+ mark_constant (current_rtx, data)
+ rtx *current_rtx;
+ void *data ATTRIBUTE_UNUSED;
+ {
+ rtx x = *current_rtx;
+
+ 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))
+ {
+ struct pool_constant *pool = find_pool_constant (cfun, x);
+ if (pool->mark == 0) {
+ pool->mark = 1;
+ for_each_rtx (&(pool->constant), &mark_constant, NULL);
+ }
+ else
+ return -1;
+ }
+ else if (STRING_POOL_ADDRESS_P (x))
+ {
+ struct deferred_string **defstr;
+
+ defstr = (struct deferred_string **)
+ htab_find_slot_with_hash (const_str_htab, XSTR (x, 0),
+ STRHASH (XSTR (x, 0)), NO_INSERT);
+ if (defstr)
+ {
+ struct deferred_string *p = *defstr;
+
+ STRING_POOL_ADDRESS_P (x) = 0;
+ output_constant_def_contents (p->exp, 0, p->labelno);
+ htab_clear_slot (const_str_htab, (void **) defstr);
+ }
+ }
+ }
+ return 0;
}
/* Find all the constants whose addresses are referenced inside of EXP,