Patch to string handling in mips16 code
Richard Sandiford
rsandifo@redhat.com
Wed Sep 25 05:02:00 GMT 2002
A mips16 patch...
When strings are shared between functions in the same compilation
unit, the string will go into the first function's constant pool.
As things stand, other functions will try to access the string
using PC-relative addressing. But sometimes these other functions
might not be in .text, or (in extreme cases) might be in .text but
too far way.
It seems safer to only refer directly to strings that are in
the current function's pool. This patch does that by clearing
the SYMBOL_REF flag of each string after writing out a function.
It means a slight pessimisation of code where direct access
was possible. But I think the most common case will be that
we're replacing an extended PC-relative add with an unextended
PC-relative load plus the address of the string. That
represents an increase of just 2 bytes.
mips16 patches are hard to test with a pristene tree at the moment.
I hope to do something about that for 3.4. This one was tested on
a Red Hat mips16 port, and (for sanity) on mips64-elf. Fixes
g++.ext/pretty3.C. OK for trunk?
Richard
* config/mips/mips.c (mips16_strings): New variable.
(mips_output_function_epilogue): Clear the SYMBOL_REF_FLAG of every
symbol in mips16_strings. Free the list.
(mips_encode_section_info): Keep track of local strings.
Index: config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.229
diff -c -d -p -r1.229 mips.c
*** config/mips/mips.c 20 Sep 2002 23:46:56 -0000 1.229
--- config/mips/mips.c 23 Sep 2002 11:45:24 -0000
*************** char mips_hard_regno_mode_ok[(int)MAX_MA
*** 365,370 ****
--- 365,375 ----
constant pool is output. */
int mips_string_length;
+ /* When generating mips16 code, a list of all strings that are to be
+ output after the current function. */
+
+ static GTY(()) rtx mips16_strings;
+
/* In mips16 mode, we build a list of all the string constants we see
in a particular function. */
*************** mips_output_function_epilogue (file, siz
*** 7638,7643 ****
--- 7643,7649 ----
HOST_WIDE_INT size ATTRIBUTE_UNUSED;
{
const char *fnname = ""; /* FIXME: Correct initialisation? */
+ rtx string;
#ifndef FUNCTION_NAME_ALREADY_DECLARED
/* Get the function name the same way that toplev.c does before calling
*************** mips_output_function_epilogue (file, siz
*** 7702,7707 ****
--- 7708,7724 ----
string_constants = next;
}
+ /* If any following function uses the same strings as this one, force
+ them to refer those strings indirectly. Nearby functions could
+ refer them using pc-relative addressing, but it isn't safe in
+ general. For instance, some functions may be placed in sections
+ other than .text, and we don't know whether they be close enough
+ to this one. In large files, even other .text functions can be
+ too far away. */
+ for (string = mips16_strings; string != 0; string = XEXP (string, 1))
+ SYMBOL_REF_FLAG (XEXP (string, 0)) = 0;
+ free_EXPR_LIST_list (&mips16_strings);
+
/* Restore the output file if optimizing the GP (optimizing the GP causes
the text to be diverted to a tempfile, so that data decls come before
references to the data). */
*************** mips_encode_section_info (decl, first)
*** 8080,8086 ****
&& (! current_function_decl
|| ! DECL_ONE_ONLY (current_function_decl)))
{
! SYMBOL_REF_FLAG (XEXP (TREE_CST_RTL (decl), 0)) = 1;
mips_string_length += TREE_STRING_LENGTH (decl);
}
}
--- 8097,8107 ----
&& (! current_function_decl
|| ! DECL_ONE_ONLY (current_function_decl)))
{
! rtx symref;
!
! symref = XEXP (TREE_CST_RTL (decl), 0);
! mips16_strings = alloc_EXPR_LIST (0, symref, mips16_strings);
! SYMBOL_REF_FLAG (symref) = 1;
mips_string_length += TREE_STRING_LENGTH (decl);
}
}
More information about the Gcc-patches
mailing list