stringpool.c: New file.

* stringpool.c: New file.
	* ggc-common.c (ggc_mark_string_ptr, ggc_add_string_root): Delete.
	(ggc_alloc_string): Now in stringpool.o.
	* ggc-page.c, ggc-simple.c: Do not define or allocate empty_string.
	* ggc.h: Delete prototype of ggc_add_string_root.  #define
	ggc_add_string_root and ggc_mark_string to nothing.  Prototype
	init_stringpool and stringpool_statistics.
	(ggc_alloc_string): Returns a const char *.
	* tree.c (hash_table, do_identifier_warnings): Delete.
	(init_obstacks): Don't initialize the identifier hash table.
	(get_identifier, maybe_get_identifier, start_identifier_warnings,
	set_identifier_size): Now in stringpool.c.
	* tree.h (struct tree_string): Constify pointer field.
	(approx_sqrt): Prototype.

	* Makefile.in (stringpool.o): Add rule, mention in OBJS.

	* toplev.c (approx_sqrt): New function.
	(compile_file): Call stringpool_statistics if mem_report is on.
	(main): Call init_stringpool.

	* builtins.c (c_strlen), c-decl.c (finish_decl), c-lex.c
	(process_directive), c-typeck.c (constructor_asmspec, struct
	initializer_stack, start_init), except.c (create_rethrow_ref),
	stmt.c (digit_strings), toplev.c (decode_f_option), tree.c
	(built_in_filename), varasm,c (in_named_name,
	assemble_static_space, struct constant_descriptor, struct
	deferred_string, struct pool_constant, force_const_mem),
	i386.c (pic_label_name, global_offset_table_name), rs6000.c
	(rs6000_emit_prologue, rs6000_emit_epilogue) : Constify a char *.

	* c-common.c (combine_strings): Combine strings in scratch
	buffer, then pass to build_string.
	* optabs.c (init_libfuncs), profile.c (init_edge_profiler,
	output_func_start_profiler), stmt.c (init_stmt), alpha.c
	(alpha_need_linkage), arm.c (arm_encode_call_attribute),
	i386.c (load_pic_register), ia64.c (ia64_encode_section_info),
	rs6000.c (rs6000_encode_section_info): Create string in
	scratch buffer, then pass to ggc_alloc_string.

	* stmt.c (expand_asm_operands): If we must adjust the
	constraint strings, do so by creating a new one, not by
	modifying the old one in place.  Constify some char *s.
	* config/pa/pa.c (hppa_encode_label): Drop unnecessary second
	argument.  Create string in scratch buffer, then pass to
	ggc_alloc_string.
	* config/pa/pa-protos.h: Update prototype.
	* config/pa/elf.h, config/pa/pa.h, config/pa/som.h:
	hppa_encode_label takes only one argument.

	* c-parse.in (if_prefix): Find the filename and line number at
	$-2 and $-1 respectively.
	* diagnostic.c (error_recursion): Add missing newline, use
	fputs, translate string.

cp:
	* lex.c (struct impl_files, internal_filename): Constify a char *.
java:
	* jcf-parse.c (get_constant), parse.y (do_merge_string_cste):
	Create string in scratch buffer, then pass to build_string.

From-SVN: r37514
This commit is contained in:
Zack Weinberg 2000-11-17 06:05:31 +00:00 committed by Zack Weinberg
parent 5af655ccee
commit 520a57c81c
37 changed files with 642 additions and 333 deletions

View file

@ -1,3 +1,62 @@
2000-11-16 Zack Weinberg <zack@wolery.stanford.edu>
* c-parse.in (if_prefix): Find the filename and line number at
$-2 and $-1 respectively.
* diagnostic.c (error_recursion): Add missing newline, use
fputs, translate string.
2000-11-16 Zack Weinberg <zack@wolery.stanford.edu>
* stringpool.c: New file.
* ggc-common.c (ggc_mark_string_ptr, ggc_add_string_root): Delete.
(ggc_alloc_string): Now in stringpool.o.
* ggc-page.c, ggc-simple.c: Do not define or allocate empty_string.
* ggc.h: Delete prototype of ggc_add_string_root. #define
ggc_add_string_root and ggc_mark_string to nothing. Prototype
init_stringpool and stringpool_statistics.
(ggc_alloc_string): Returns a const char *.
* tree.c (hash_table, do_identifier_warnings): Delete.
(init_obstacks): Don't initialize the identifier hash table.
(get_identifier, maybe_get_identifier, start_identifier_warnings,
set_identifier_size): Now in stringpool.c.
* tree.h (struct tree_string): Constify pointer field.
(approx_sqrt): Prototype.
* Makefile.in (stringpool.o): Add rule, mention in OBJS.
* toplev.c (approx_sqrt): New function.
(compile_file): Call stringpool_statistics if mem_report is on.
(main): Call init_stringpool.
* builtins.c (c_strlen), c-decl.c (finish_decl), c-lex.c
(process_directive), c-typeck.c (constructor_asmspec, struct
initializer_stack, start_init), except.c (create_rethrow_ref),
stmt.c (digit_strings), toplev.c (decode_f_option), tree.c
(built_in_filename), varasm,c (in_named_name,
assemble_static_space, struct constant_descriptor, struct
deferred_string, struct pool_constant, force_const_mem),
i386.c (pic_label_name, global_offset_table_name), rs6000.c
(rs6000_emit_prologue, rs6000_emit_epilogue) : Constify a char *.
* c-common.c (combine_strings): Combine strings in scratch
buffer, then pass to build_string.
* optabs.c (init_libfuncs), profile.c (init_edge_profiler,
output_func_start_profiler), stmt.c (init_stmt), alpha.c
(alpha_need_linkage), arm.c (arm_encode_call_attribute),
i386.c (load_pic_register), ia64.c (ia64_encode_section_info),
rs6000.c (rs6000_encode_section_info): Create string in
scratch buffer, then pass to ggc_alloc_string.
* stmt.c (expand_asm_operands): If we must adjust the
constraint strings, do so by creating a new one, not by
modifying the old one in place. Constify some char *s.
* config/pa/pa.c (hppa_encode_label): Drop unnecessary second
argument. Create string in scratch buffer, then pass to
ggc_alloc_string.
* config/pa/pa-protos.h: Update prototype.
* config/pa/elf.h, config/pa/pa.h, config/pa/som.h:
hppa_encode_label takes only one argument.
2000-11-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* mcore.c (mcore_expand_prolog): Call xmalloc/xrealloc, not

View file

@ -734,7 +734,7 @@ OBJS = diagnostic.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o lcm.o \
profile.o insn-attrtab.o $(out_object_file) $(EXTRA_OBJS) convert.o \
mbchar.o splay-tree.o graph.o sbitmap.o resource.o hash.o predict.o \
lists.o ggc-common.o $(GGC) simplify-rtx.o ssa.o bb-reorder.o \
lists.o ggc-common.o $(GGC) stringpool.o simplify-rtx.o ssa.o bb-reorder.o \
sibcall.o conflict.o timevar.o ifcvt.o dominance.o dependence.o dce.o
BACKEND = toplev.o libbackend.a
@ -1268,6 +1268,9 @@ ggc-simple.o: ggc-simple.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h \
ggc-page.o: ggc-page.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h toplev.h \
$(GGC_H) varray.h $(TIMEVAR_H)
stringpool.o: stringpool.c $(CONFIG_H) system.h $(TREE_H) $(OBSTACK_H) \
flags.h toplev.h
ggc-none.o: ggc-none.c $(CONFIG_H) $(RTL_H) $(GGC_H)
obstack.o: $(srcdir)/../libiberty/obstack.c $(CONFIG_H)

View file

@ -210,7 +210,7 @@ c_strlen (src)
{
tree offset_node;
int offset, max;
char *ptr;
const char *ptr;
src = string_constant (src, &offset_node);
if (src == 0)

View file

@ -377,7 +377,7 @@ combine_strings (strings)
if (wide_flag)
length = length * wchar_bytes + wide_length;
p = ggc_alloc_string (NULL, length);
p = alloca (length);
/* Copy the individual strings into the new combined string.
If the combined string is wide, convert the chars to ints
@ -416,9 +416,7 @@ combine_strings (strings)
else
*q = 0;
value = make_node (STRING_CST);
TREE_STRING_POINTER (value) = p;
TREE_STRING_LENGTH (value) = length;
value = build_string (length, p);
}
else
{

View file

@ -3634,7 +3634,7 @@ finish_decl (decl, init, asmspec_tree)
{
register tree type = TREE_TYPE (decl);
int was_incomplete = (DECL_SIZE (decl) == 0);
char *asmspec = 0;
const char *asmspec = 0;
/* If a name was specified, get the string. */
if (asmspec_tree)

View file

@ -443,7 +443,7 @@ process_directive ()
int saw_line;
enum { act_none, act_push, act_pop } action;
int action_number, l;
char *new_file;
const char *new_file;
#ifndef NO_IMPLICIT_EXTERN_C
int entering_c_header = 0;
#endif

View file

@ -1765,8 +1765,8 @@ if_prefix:
{ c_expand_start_cond (truthvalue_conversion ($3),
compstmt_count);
$<itype>$ = stmt_count;
if_stmt_file = $<filename>-1;
if_stmt_line = $<lineno>0; }
if_stmt_file = $<filename>-2;
if_stmt_line = $<lineno>-1; }
;
/* This is a subroutine of stmt.

View file

@ -4944,7 +4944,7 @@ static int require_constant_elements;
static tree constructor_decl;
/* start_init saves the ASMSPEC arg here for really_start_incremental_init. */
static char *constructor_asmspec;
static const char *constructor_asmspec;
/* Nonzero if this is an initializer for a top-level decl. */
static int constructor_top_level;
@ -4989,7 +4989,7 @@ struct initializer_stack
{
struct initializer_stack *next;
tree decl;
char *asmspec;
const char *asmspec;
struct constructor_stack *constructor_stack;
tree elements;
struct spelling *spelling;
@ -5014,7 +5014,7 @@ start_init (decl, asmspec_tree, top_level)
const char *locus;
struct initializer_stack *p
= (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack));
char *asmspec = 0;
const char *asmspec = 0;
if (asmspec_tree)
asmspec = TREE_STRING_POINTER (asmspec_tree);

View file

@ -6232,12 +6232,12 @@ alpha_need_linkage (name, is_local)
/* Construct a SYMBOL_REF for us to call. */
{
size_t name_len = strlen (name);
char *linksym = ggc_alloc_string (NULL, name_len + 6);
char *linksym = alloca (name_len + 6);
linksym[0] = '$';
memcpy (linksym + 1, name, name_len);
memcpy (linksym + 1 + name_len, "..lk", 5);
al->linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
al->linkage = gen_rtx_SYMBOL_REF (Pmode,
ggc_alloc_string (linksym, name_len + 5));
}
splay_tree_insert (alpha_links, (splay_tree_key) name,

View file

@ -1726,11 +1726,12 @@ arm_encode_call_attribute (decl, flag)
/* Do not allow weak functions to be treated as short call. */
if (DECL_WEAK (decl) && flag == SHORT_CALL_FLAG_CHAR)
return;
newstr = ggc_alloc_string (NULL, len + 2);
sprintf (newstr, "%c%s", flag, str);
newstr = alloca (len + 2);
newstr[0] = flag;
strcpy (newstr + 1, str);
newstr = ggc_alloc_string (newstr, len + 1);
XSTR (XEXP (DECL_RTL (decl), 0), 0) = newstr;
}

View file

@ -1675,9 +1675,9 @@ ix86_can_use_return_insn_p ()
return tsize == 0 && nregs == 0;
}
static char *pic_label_name;
static const char *pic_label_name;
static int pic_label_output;
static char *global_offset_table_name;
static const char *global_offset_table_name;
/* This function generates code for -fpic that loads %ebx with
the return address of the caller and then returns. */
@ -1733,9 +1733,10 @@ load_pic_register ()
{
if (pic_label_name == NULL)
{
pic_label_name = ggc_alloc_string (NULL, 32);
char buf[32];
ASM_GENERATE_INTERNAL_LABEL (buf, "LPR", 0);
pic_label_name = ggc_alloc_string (buf, -1);
ggc_add_string_root (&pic_label_name, 1);
ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", 0);
}
pclab = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, pic_label_name));
}

View file

@ -4801,12 +4801,12 @@ ia64_encode_section_info (decl)
&& symbol_str[0] != SDATA_NAME_FLAG_CHAR)
{
size_t len = strlen (symbol_str);
char *newstr;
char *newstr = alloca (len + 1);
newstr = ggc_alloc_string (NULL, len + 1);
*newstr = SDATA_NAME_FLAG_CHAR;
memcpy (newstr + 1, symbol_str, len + 1);
newstr = ggc_alloc_string (newstr, len + 1);
XSTR (XEXP (DECL_RTL (decl), 0), 0) = newstr;
}
}

View file

@ -84,7 +84,7 @@ do { \
#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, RTL) \
do { fputs ("\t.IMPORT ", FILE); \
if (!function_label_operand (RTL, VOIDmode)) \
hppa_encode_label (RTL, 1); \
hppa_encode_label (RTL); \
assemble_name (FILE, XSTR ((RTL), 0)); \
fputs (",ENTRY\n", FILE); \
} while (0)

View file

@ -61,7 +61,7 @@ extern void output_global_address PARAMS ((FILE *, rtx, int));
extern void print_operand PARAMS ((FILE *, rtx, int));
extern rtx legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
extern struct rtx_def *gen_cmp_fp PARAMS ((enum rtx_code, rtx, rtx));
extern void hppa_encode_label PARAMS ((rtx, int));
extern void hppa_encode_label PARAMS ((rtx));
extern int arith11_operand PARAMS ((rtx, enum machine_mode));
extern int symbolic_expression_p PARAMS ((rtx));
extern int hppa_address_cost PARAMS ((rtx));

View file

@ -5939,29 +5939,22 @@ output_call (insn, call_dest, sibcall)
/* In HPUX 8.0's shared library scheme, special relocations are needed
for function labels if they might be passed to a function
in a shared library (because shared libraries don't live in code
space), and special magic is needed to construct their address.
For reasons too disgusting to describe storage for the new name
is allocated as a ggc string, or as a string on the saveable_obstack
(released at function exit) or on the permanent_obstack for things
that can never change (libcall names for example). */
space), and special magic is needed to construct their address. */
void
hppa_encode_label (sym, permanent)
hppa_encode_label (sym)
rtx sym;
int permanent;
{
const char *str = XSTR (sym, 0);
int len = strlen (str);
char *newstr;
newstr = ggc_alloc_string (NULL, len + 1);
char *newstr = alloca (len + 1);
if (str[0] == '*')
*newstr++ = *str++;
strcpy (newstr + 1, str);
*newstr = '@';
XSTR (sym,0) = newstr;
XSTR (sym,0) = ggc_alloc_string (newstr, len);
}
int

View file

@ -1494,7 +1494,7 @@ do \
_rtl = TREE_CST_RTL (DECL); \
SYMBOL_REF_FLAG (XEXP (_rtl, 0)) = 1; \
if (TREE_CODE (DECL) == FUNCTION_DECL) \
hppa_encode_label (XEXP (DECL_RTL (DECL), 0), 0);\
hppa_encode_label (XEXP (DECL_RTL (DECL), 0));\
} \
} \
while (0)

View file

@ -352,7 +352,7 @@ DTORS_SECTION_FUNCTION
#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, RTL) \
do { fputs ("\t.IMPORT ", FILE); \
if (!function_label_operand (RTL, VOIDmode)) \
hppa_encode_label (RTL, 1); \
hppa_encode_label (RTL); \
assemble_name (FILE, XSTR ((RTL), 0)); \
fputs (",CODE\n", FILE); \
} while (0)

View file

@ -5604,7 +5604,7 @@ rs6000_emit_prologue()
{
int i;
char rname[30];
char *alloc_rname;
const char *alloc_rname;
rtvec p;
p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
@ -6057,7 +6057,7 @@ rs6000_emit_epilogue(sibcall)
{
int i;
char rname[30];
char *alloc_rname;
const char *alloc_rname;
sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
@ -7578,14 +7578,12 @@ rs6000_encode_section_info (decl)
{
size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
size_t len2 = strlen (XSTR (sym_ref, 0));
char *str;
str = ggc_alloc_string (NULL, len1 + len2);
char *str = alloca (len1 + len2 + 1);
str[0] = '.';
str[1] = '.';
memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
XSTR (sym_ref, 0) = str;
XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
}
}
else if (rs6000_sdata != SDATA_NONE
@ -7625,13 +7623,11 @@ rs6000_encode_section_info (decl)
{
rtx sym_ref = XEXP (DECL_RTL (decl), 0);
size_t len = strlen (XSTR (sym_ref, 0));
char *str;
char *str = alloca (len + 1);
str = ggc_alloc_string (NULL, len + 1);
str[0] = '@';
memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
XSTR (sym_ref, 0) = str;
XSTR (sym_ref, 0) = ggc_alloc_string (str, len);
}
}
}

View file

@ -1,3 +1,7 @@
2000-11-16 Zack Weinberg <zack@wolery.stanford.edu>
* lex.c (struct impl_files, internal_filename): Constify a char *.
2000-11-16 Mark Mitchell <mark@codesourcery.com>
* mangle.c (write_special_name_constructor): Don't generate

View file

@ -131,7 +131,7 @@ extern int *token_count;
struct impl_files
{
char *filename;
const char *filename;
struct impl_files *next;
};
@ -140,7 +140,7 @@ static struct impl_files *impl_file_chain;
/* The string used to represent the filename of internally generated
tree nodes. The variable, which is dynamically allocated, should
be used; the macro is only used to initialize it. */
static char *internal_filename;
static const char *internal_filename;
#define INTERNAL_FILENAME ("<internal>")
/* Return something to represent absolute declarators containing a *.

View file

@ -1637,8 +1637,8 @@ error_recursion ()
if (diagnostic_lock < 3)
finish_diagnostic ();
fprintf (stderr,
"Internal compiler error: Error reporting routines re-entered.");
fputs (_("Internal compiler error: Error reporting routines re-entered.\n"),
stderr);
finish_abort ();
}

View file

@ -500,7 +500,7 @@ create_rethrow_ref (region_num)
int region_num;
{
rtx def;
char *ptr;
const char *ptr;
char buf[60];
ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", region_num);

View file

@ -47,7 +47,6 @@ static void ggc_mark_tree_ptr PARAMS ((void *));
static void ggc_mark_rtx_varray_ptr PARAMS ((void *));
static void ggc_mark_tree_varray_ptr PARAMS ((void *));
static void ggc_mark_tree_hash_table_ptr PARAMS ((void *));
static void ggc_mark_string_ptr PARAMS ((void *));
static void ggc_mark_trees PARAMS ((void));
static boolean ggc_mark_tree_hash_table_entry PARAMS ((struct hash_entry *,
hash_table_key));
@ -143,16 +142,6 @@ ggc_add_tree_hash_table_root (base, nelt)
ggc_mark_tree_hash_table_ptr);
}
/* Register an array of strings as a GC root. */
void
ggc_add_string_root (base, nelt)
char **base;
int nelt;
{
ggc_add_root (base, nelt, sizeof (char *), ggc_mark_string_ptr);
}
/* Remove the previously registered GC root at BASE. */
void
@ -557,43 +546,6 @@ ggc_mark_tree_hash_table_ptr (elt)
ggc_mark_tree_hash_table (*(struct hash_table **) elt);
}
/* Type-correct function to pass to ggc_add_root. It just forwards
ELT (which is really a char **) to ggc_mark_string. */
static void
ggc_mark_string_ptr (elt)
void *elt;
{
ggc_mark_string (*(char **) elt);
}
/* Allocate a gc-able string. If CONTENTS is null, then the memory will
be uninitialized. If LENGTH is -1, then CONTENTS is assumed to be a
null-terminated string and the memory sized accordingly. Otherwise,
the memory is filled with LENGTH bytes from CONTENTS. */
char *
ggc_alloc_string (contents, length)
const char *contents;
int length;
{
char *string;
if (length < 0)
{
if (contents == NULL)
return NULL;
length = strlen (contents);
}
string = (char *) ggc_alloc (length + 1);
if (contents != NULL)
memcpy (string, contents, length);
string[length] = 0;
return string;
}
/* Allocate a block of memory, then clear it. */
void *
ggc_alloc_cleared (size)

View file

@ -99,8 +99,6 @@ Boston, MA 02111-1307, USA. */
#define HOST_BITS_PER_PTR HOST_BITS_PER_LONG
#endif
/* The "" allocated string. */
char *empty_string;
/* A two-level tree is used to look up the page-entry for a given
pointer. Two chunks of the pointer's bits are extracted to index
@ -839,9 +837,6 @@ init_ggc ()
munmap (p, G.pagesize);
}
#endif
empty_string = ggc_alloc_string ("", 0);
ggc_add_string_root (&empty_string, 1);
}
/* Increment the `GC context'. Objects allocated in an outer context

View file

@ -52,10 +52,6 @@
#define GGC_ALWAYS_COLLECT
#endif
/* Constants for general use. */
char *empty_string;
#ifndef HOST_BITS_PER_PTR
#define HOST_BITS_PER_PTR HOST_BITS_PER_LONG
#endif
@ -374,9 +370,6 @@ void
init_ggc ()
{
G.allocated_last_gc = GGC_MIN_LAST_ALLOCATED;
empty_string = ggc_alloc_string ("", 0);
ggc_add_string_root (&empty_string, 1);
}
/* Start a new GGC context. Memory allocated in previous contexts

View file

@ -40,7 +40,7 @@ union tree_node;
struct varasm_status;
/* Constants for general use. */
extern char *empty_string;
extern const char empty_string[];
/* Trees that have been marked, but whose children still need marking. */
extern varray_type ggc_pending_trees;
@ -49,12 +49,14 @@ extern varray_type ggc_pending_trees;
void ggc_add_root PARAMS ((void *base, int nelt, int size, void (*)(void *)));
void ggc_add_rtx_root PARAMS ((struct rtx_def **, int nelt));
void ggc_add_tree_root PARAMS ((union tree_node **, int nelt));
void ggc_add_string_root PARAMS ((char **, int nelt));
void ggc_add_rtx_varray_root PARAMS ((struct varray_head_tag **, int nelt));
void ggc_add_tree_varray_root PARAMS ((struct varray_head_tag **, int nelt));
void ggc_add_tree_hash_table_root PARAMS ((struct hash_table **, int nelt));
void ggc_del_root PARAMS ((void *base));
/* Temporary */
#define ggc_add_string_root(ptr, nelt) /* nothing */
/* Mark nodes from the gc_add_root callback. These functions follow
pointers to mark other objects too. */
extern void ggc_mark_rtx_varray PARAMS ((struct varray_head_tag *));
@ -91,12 +93,8 @@ extern void ggc_mark_rtvec_children PARAMS ((struct rtvec_def *));
ggc_mark_rtvec_children (v__); \
} while (0)
#define ggc_mark_string(EXPR) \
do { \
const char *s__ = (EXPR); \
if (s__ != NULL) \
ggc_set_mark (s__); \
} while (0)
/* Temporary */
#define ggc_mark_string(EXPR) /* nothing */
#define ggc_mark(EXPR) \
do { \
@ -112,6 +110,7 @@ extern void ggc_mark_if_gcable PARAMS ((const void *));
/* Initialize the garbage collector. */
extern void init_ggc PARAMS ((void));
extern void init_stringpool PARAMS ((void));
/* Start a new GGC context. Memory allocated in previous contexts
will not be collected while the new context is active. */
@ -138,11 +137,10 @@ void *ggc_alloc_cleared PARAMS ((size_t));
#define ggc_alloc_tree(LENGTH) ((union tree_node *) ggc_alloc (LENGTH))
/* Allocate a gc-able string. If CONTENTS is null, then the memory will
be uninitialized. If LENGTH is -1, then CONTENTS is assumed to be a
null-terminated string and the memory sized accordingly. Otherwise,
the memory is filled with LENGTH bytes from CONTENTS. */
char *ggc_alloc_string PARAMS ((const char *contents, int length));
/* Allocate a gc-able string, and fill it with LENGTH bytes from CONTENTS.
If LENGTH is -1, then CONTENTS is assumed to be a
null-terminated string and the memory sized accordingly. */
const char *ggc_alloc_string PARAMS ((const char *contents, int length));
/* Make a copy of S, in GC-able memory. */
#define ggc_strdup(S) ggc_alloc_string((S), -1)
@ -214,3 +212,4 @@ void ggc_print_common_statistics PARAMS ((FILE *, ggc_statistics *));
/* Print allocation statistics. */
extern void ggc_print_statistics PARAMS ((void));
void stringpool_statistics PARAMS ((void));

View file

@ -1,3 +1,8 @@
2000-11-16 Zack Weinberg <zack@wolery.stanford.edu>
* jcf-parse.c (get_constant), parse.y (do_merge_string_cste):
Create string in scratch buffer, then pass to build_string.
2000-11-13 Joseph S. Myers <jsm28@cam.ac.uk>
* parse.y (issue_warning_error_from_context): Add

View file

@ -328,29 +328,33 @@ get_constant (jcf, index)
{
tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
const char *utf8_ptr = IDENTIFIER_POINTER (name);
unsigned char *str_ptr;
int utf8_len = IDENTIFIER_LENGTH (name);
const unsigned char *str = (const unsigned char *)utf8_ptr;
int i = utf8_len;
int str_len;
unsigned char *str_ptr;
unsigned char *str;
const unsigned char *utf8;
int i, str_len;
/* Count the number of Unicode characters in the string,
while checking for a malformed Utf8 string. */
for (str_len = 0; i > 0; str_len++)
utf8 = (const unsigned char *) utf8_ptr;
i = utf8_len;
str_len = 0;
while (i > 0)
{
int char_len = UT8_CHAR_LENGTH (*str);
int char_len = UT8_CHAR_LENGTH (*utf8);
if (char_len < 0 || char_len > 3 || char_len > i)
fatal ("bad string constant");
str += char_len;
utf8 += char_len;
i -= char_len;
str_len++;
}
value = make_node (STRING_CST);
TREE_TYPE (value) = build_pointer_type (string_type_node);
TREE_STRING_LENGTH (value) = 2 * str_len;
TREE_STRING_POINTER (value) = ggc_alloc (2 * str_len);
str_ptr = (unsigned char *) TREE_STRING_POINTER (value);
str = (const unsigned char *)utf8_ptr;
/* Allocate a scratch buffer, convert the string to UCS2, and copy it
into the new space. */
str_ptr = (unsigned char *) alloca (2 * str_len);
str = str_ptr;
utf8 = (const unsigned char *)utf8_ptr;
for (i = 0; i < str_len; i++)
{
int char_value;
@ -358,31 +362,33 @@ get_constant (jcf, index)
switch (char_len)
{
case 1:
char_value = *str++;
char_value = *utf8++;
break;
case 2:
char_value = *str++ & 0x1F;
char_value = (char_value << 6) | (*str++ & 0x3F);
char_value = *utf8++ & 0x1F;
char_value = (char_value << 6) | (*utf8++ & 0x3F);
break;
case 3:
char_value = *str++ & 0x0F;
char_value = (char_value << 6) | (*str++ & 0x3F);
char_value = (char_value << 6) | (*str++ & 0x3F);
char_value = *utf8++ & 0x0F;
char_value = (char_value << 6) | (*utf8++ & 0x3F);
char_value = (char_value << 6) | (*utf8++ & 0x3F);
break;
default:
goto bad;
}
if (BYTES_BIG_ENDIAN)
{
*str_ptr++ = char_value >> 8;
*str_ptr++ = char_value & 0xFF;
*str++ = char_value >> 8;
*str++ = char_value & 0xFF;
}
else
{
*str_ptr++ = char_value & 0xFF;
*str_ptr++ = char_value >> 8;
*str++ = char_value & 0xFF;
*str++ = char_value >> 8;
}
}
value = build_string (str - str_ptr, str_ptr);
TREE_TYPE (value) = build_pointer_type (string_type_node);
}
break;
default:

View file

@ -13070,11 +13070,7 @@ do_merge_string_cste (cste, string, string_len, after)
const char *old = TREE_STRING_POINTER (cste);
int old_len = TREE_STRING_LENGTH (cste);
int len = old_len + string_len;
char *new;
cste = make_node (STRING_CST);
TREE_STRING_LENGTH (cste) = len;
new = TREE_STRING_POINTER (cste) = ggc_alloc (len+1);
char *new = alloca (len+1);
if (after)
{
@ -13087,7 +13083,7 @@ do_merge_string_cste (cste, string, string_len, after)
memcpy (&new [old_len], string, string_len);
}
new [len] = '\0';
return cste;
return build_string (len, new);
}
/* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a

View file

@ -4466,8 +4466,7 @@ init_libfuncs (optable, first_mode, last_mode, opname, suffix)
{
register const char *mname = GET_MODE_NAME(mode);
register unsigned mname_len = strlen (mname);
register char *libfunc_name
= ggc_alloc_string (NULL, 2 + opname_len + mname_len + 1 + 1);
register char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
register char *p;
register const char *q;
@ -4479,10 +4478,11 @@ init_libfuncs (optable, first_mode, last_mode, opname, suffix)
for (q = mname; *q; q++)
*p++ = TOLOWER (*q);
*p++ = suffix;
*p++ = '\0';
*p = '\0';
optable->handlers[(int) mode].libfunc
= gen_rtx_SYMBOL_REF (Pmode, libfunc_name);
= gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
p - libfunc_name));
}
}

View file

@ -1025,9 +1025,9 @@ static void
init_edge_profiler ()
{
/* Generate and save a copy of this so it can be shared. */
char *name = ggc_alloc_string (NULL, 20);
ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 2);
profiler_label = gen_rtx_SYMBOL_REF (Pmode, name);
char buf[20];
ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1));
ggc_add_rtx_root (&profiler_label, 1);
}
@ -1066,6 +1066,7 @@ output_func_start_profiler ()
{
tree fnname, fndecl;
char *name;
char buf[20];
const char *cfnname;
rtx table_address;
enum machine_mode mode = mode_for_size (LONG_TYPE_SIZE, MODE_INT, 0);
@ -1121,9 +1122,10 @@ output_func_start_profiler ()
expand_function_start (fndecl, 0);
/* Actually generate the code to call __bb_init_func. */
name = ggc_alloc_string (NULL, 20);
ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
table_address = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, name));
ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 0);
table_address = force_reg (Pmode,
gen_rtx_SYMBOL_REF (Pmode,
ggc_alloc_string (buf, -1)));
emit_library_call (gen_rtx_SYMBOL_REF
(Pmode, ggc_alloc_string ("__bb_init_func", 14)), 0,
mode, 1, table_address, Pmode);

View file

@ -394,7 +394,7 @@ struct stmt_status
static int using_eh_for_cleanups_p = 0;
/* Character strings, each containing a single decimal digit. */
static char *digit_strings[10];
static const char *digit_strings[10];
static int n_occurrences PARAMS ((int, const char *));
static void expand_goto_internal PARAMS ((tree, rtx, rtx));
@ -598,13 +598,15 @@ void
init_stmt ()
{
int i;
char buf[2];
gcc_obstack_init (&stmt_obstack);
buf[1] = 0;
for (i = 0; i < 10; i++)
{
digit_strings[i] = ggc_alloc_string (NULL, 1);
digit_strings[i][0] = '0' + i;
buf[0] = '0' + i;
digit_strings[i] = ggc_alloc_string (buf, 1);
}
ggc_add_string_root (digit_strings, 10);
}
@ -1408,7 +1410,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
{
tree val = TREE_VALUE (tail);
tree type = TREE_TYPE (val);
char *constraint;
const char *constraint;
char *p;
int c_len;
int j;
@ -1425,8 +1427,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
the worst that happens if we get it wrong is we issue an error
message. */
c_len = strlen (TREE_STRING_POINTER (TREE_PURPOSE (tail)));
constraint = TREE_STRING_POINTER (TREE_PURPOSE (tail));
c_len = strlen (constraint);
/* Allow the `=' or `+' to not be at the beginning of the string,
since it wasn't explicitly documented that way, and there is a
@ -1443,19 +1445,25 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
error ("output operand constraint lacks `='");
return;
}
j = p - constraint;
is_inout = *p == '+';
if (p != constraint)
if (j || is_inout)
{
j = *p;
bcopy (constraint, constraint+1, p-constraint);
*constraint = j;
/* Have to throw away this constraint string and get a new one. */
char *buf = alloca (c_len + 1);
buf[0] = '=';
if (j)
memcpy (buf + 1, constraint, j);
memcpy (buf + 1 + j, p + 1, c_len - j); /* not -j-1 - copy null */
constraint = ggc_alloc_string (buf, c_len);
warning ("output constraint `%c' for operand %d is not at the beginning", j, i);
if (j)
warning (
"output constraint `%c' for operand %d is not at the beginning",
*p, i);
}
is_inout = constraint[0] == '+';
/* Replace '+' with '='. */
constraint[0] = '=';
/* Make sure we can specify the matching operand. */
if (is_inout && i > 9)
{
@ -1611,7 +1619,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
{
int j;
int allows_reg = 0, allows_mem = 0;
char *constraint, *orig_constraint;
const char *constraint, *orig_constraint;
int c_len;
rtx op;
@ -1629,8 +1637,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
return;
}
c_len = strlen (TREE_STRING_POINTER (TREE_PURPOSE (tail)));
constraint = TREE_STRING_POINTER (TREE_PURPOSE (tail));
c_len = strlen (constraint);
orig_constraint = constraint;
/* Make sure constraint has neither `=', `+', nor '&'. */
@ -1691,8 +1699,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
for (j = constraint[j] - '0'; j > 0; --j)
o = TREE_CHAIN (o);
c_len = strlen (TREE_STRING_POINTER (TREE_PURPOSE (o)));
constraint = TREE_STRING_POINTER (TREE_PURPOSE (o));
c_len = strlen (constraint);
j = 0;
break;
}

405
gcc/stringpool.c Normal file
View file

@ -0,0 +1,405 @@
/* String pool for GCC.
Copyright (C) 2000 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* String pool allocator. All strings allocated by ggc_alloc_string are
uniquified and stored in an obstack which is never shrunk. You can
associate a tree with a string if you wish; this is used to implement
get_identifier.
We have our own private hash table implementation which is similar
to the one in cpphash.c (actually, it's a further refinement of
that code). libiberty's hashtab.c is not used because it requires
100% average space overhead per string, which is unacceptable.
Also, this algorithm is faster. */
#include "config.h"
#include "system.h"
#include "ggc.h"
#include "tree.h"
#include "obstack.h"
#include "flags.h"
#include "toplev.h"
/* The "" allocated string. */
const char empty_string[] = "";
static struct obstack string_stack;
/* This is the hash entry associated with each string. It lives in
the hash table; only the string lives in the obstack. Note that
the string is not necessarily NUL terminated. */
struct str_header
{
const char *ptr;
tree data; /* for get_identifier */
unsigned int len;
};
/* This is the hash table structure. There's only one. */
struct str_hash
{
struct str_header *entries;
size_t nslots; /* total slots in the entries array */
size_t nelements; /* number of live elements */
/* table usage statistics */
unsigned int searches;
unsigned int collisions;
};
#define INITIAL_HASHSIZE (16*1024)
static struct str_hash string_hash = { 0, INITIAL_HASHSIZE, 0, 0, 0 };
enum insert_option { INSERT, NO_INSERT };
static struct str_header *alloc_string PARAMS ((const char *, size_t,
enum insert_option));
static inline unsigned int calc_hash PARAMS ((const unsigned char *, size_t));
static void mark_string_hash PARAMS ((void *));
static struct str_header *expand_string_table PARAMS ((struct str_header *));
/* Convenience macro for iterating over the hash table. E is set to
each live entry in turn. */
#define FORALL_STRINGS(E) \
for (E = string_hash.entries; E < string_hash.entries+string_hash.nslots; E++) \
if (E->ptr != NULL)
/* block here */
/* Likewise, but tests ->data instead of ->ptr (for cases where we only
care about entries with ->data set) */
#define FORALL_IDS(E) \
for (E = string_hash.entries; E < string_hash.entries+string_hash.nslots; E++) \
if (E->data != NULL)
/* 0 while creating built-in identifiers. */
static int do_identifier_warnings;
/* Initialize the string pool. */
void
init_stringpool ()
{
gcc_obstack_init (&string_stack);
ggc_add_root (&string_hash, 1, sizeof string_hash, mark_string_hash);
/* Strings need no alignment. */
obstack_alignment_mask (&string_stack) = 0;
string_hash.entries = (struct str_header *)
xcalloc (string_hash.nslots, sizeof (struct str_header));
}
/* Enable warnings on similar identifiers (if requested).
Done after the built-in identifiers are created. */
void
start_identifier_warnings ()
{
do_identifier_warnings = 1;
}
/* Record the size of an identifier node for the language in use.
SIZE is the total size in bytes.
This is called by the language-specific files. This must be
called before allocating any identifiers. */
void
set_identifier_size (size)
int size;
{
tree_code_length[(int) IDENTIFIER_NODE]
= (size - sizeof (struct tree_common)) / sizeof (tree);
}
/* Calculate the hash of the string STR, which is of length LEN. */
static inline unsigned int
calc_hash (str, len)
const unsigned char *str;
size_t len;
{
size_t n = len;
unsigned int r = 0;
#define HASHSTEP(r, c) ((r) * 67 + (c - 113));
while (n--)
r = HASHSTEP (r, *str++);
return r + len;
#undef HASHSTEP
}
/* Internal primitive: returns the header structure for the string of
length LENGTH, containing CONTENTS. If that string already exists
in the table, returns the existing entry. If the string hasn't
been seen before and the last argument is INSERT, inserts and returns
a new entry. Otherwise returns NULL. */
static struct str_header *
alloc_string (contents, length, insert)
const char *contents;
size_t length;
enum insert_option insert;
{
unsigned int hash = calc_hash ((const unsigned char *)contents, length);
unsigned int hash2;
unsigned int index;
size_t sizemask;
struct str_header *entry;
struct str_header *entries = string_hash.entries;
sizemask = string_hash.nslots - 1;
index = hash & sizemask;
/* hash2 must be odd, so we're guaranteed to visit every possible
location in the table during rehashing. */
hash2 = ((hash * 17) & sizemask) | 1;
string_hash.searches++;
for (;;)
{
entry = entries + index;
if (entry->ptr == NULL)
break;
if (entry->len == length
&& !memcmp (entry->ptr, contents, length))
return entry;
index = (index + hash2) & sizemask;
string_hash.collisions++;
}
if (insert == NO_INSERT)
return NULL;
obstack_grow0 (&string_stack, contents, length);
entry->ptr = (const char *) obstack_finish (&string_stack);
entry->len = length;
entry->data = NULL;
if (++string_hash.nelements * 4 < string_hash.nslots * 3)
return entry;
/* Must expand the string table. */
return expand_string_table (entry);
}
/* Subroutine of alloc_string which doubles the size of the hash table
and rehashes all the strings into the new table. Returns the entry
in the new table corresponding to ENTRY. */
static struct str_header *
expand_string_table (entry)
struct str_header *entry;
{
struct str_header *nentries;
struct str_header *e, *nentry = NULL;
size_t size, sizemask;
size = string_hash.nslots * 2;
nentries = (struct str_header *) xcalloc (size, sizeof (struct str_header));
sizemask = size - 1;
FORALL_STRINGS (e)
{
unsigned int index, hash, hash2;
hash = calc_hash ((const unsigned char *) e->ptr, e->len);
hash2 = ((hash * 17) & sizemask) | 1;
index = hash & sizemask;
for (;;)
{
if (nentries[index].ptr == NULL)
{
nentries[index].ptr = e->ptr;
nentries[index].len = e->len;
nentries[index].data = e->data;
if (e == entry)
nentry = nentries + index;
break;
}
index = (index + hash2) & sizemask;
}
}
free (string_hash.entries);
string_hash.entries = nentries;
string_hash.nslots = size;
return nentry;
}
/* Allocate and return a string constant of length LENGTH, containing
CONTENTS. If LENGTH is -1, CONTENTS is assumed to be a
nul-terminated string, and the length is calculated using strlen.
If the same string constant has been allocated before, that copy is
returned this time too. */
const char *
ggc_alloc_string (contents, length)
const char *contents;
int length;
{
struct str_header *str;
if (length == -1)
length = strlen (contents);
if (length == 0)
return empty_string;
str = alloc_string (contents, length, INSERT);
return str->ptr;
}
/* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string).
If an identifier with that name has previously been referred to,
the same node is returned this time. */
tree
get_identifier (text)
const char *text;
{
tree idp;
struct str_header *str;
size_t length = strlen (text);
str = alloc_string (text, length, INSERT);
idp = str->data;
if (idp == NULL)
{
if (TREE_CODE_LENGTH (IDENTIFIER_NODE) < 0)
abort (); /* set_identifier_size hasn't been called. */
/* If this identifier is longer than the clash-warning length,
do a brute force search of the entire table for clashes. */
if (warn_id_clash && do_identifier_warnings && length >= (size_t) id_clash_len)
{
struct str_header *e;
FORALL_IDS (e)
{
if (e->len >= (size_t)id_clash_len
&& !strncmp (e->ptr, text, id_clash_len))
{
warning ("\"%s\" and \"%s\" identical in first %d characters",
text, e->ptr, id_clash_len);
break;
}
}
}
idp = make_node (IDENTIFIER_NODE);
IDENTIFIER_LENGTH (idp) = length;
IDENTIFIER_POINTER (idp) = str->ptr;
#ifdef GATHER_STATISTICS
id_string_size += length;
#endif
str->data = idp;
}
return idp;
}
/* If an identifier with the name TEXT (a null-terminated string) has
previously been referred to, return that node; otherwise return
NULL_TREE. */
tree
maybe_get_identifier (text)
const char *text;
{
struct str_header *str;
size_t length = strlen (text);
str = alloc_string (text, length, NO_INSERT);
if (str)
return str->data; /* N.B. str->data might be null here, if the
string has been used but not as an identifier. */
return NULL_TREE;
}
/* Report some basic statistics about the string pool. */
void
stringpool_statistics ()
{
size_t nelts, overhead, headers;
size_t total_bytes, longest, sum_of_squares;
double exp_len, exp_len2, exp2_len;
struct str_header *e;
#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
? (x) \
: ((x) < 1024*1024*10 \
? (x) / 1024 \
: (x) / (1024*1024))))
#define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
total_bytes = longest = sum_of_squares = 0;
FORALL_STRINGS (e)
{
size_t n = e->len;
total_bytes += n;
sum_of_squares += n*n;
if (n > longest)
longest = n;
}
nelts = string_hash.nelements;
overhead = obstack_memory_used (&string_stack) - total_bytes;
headers = string_hash.nslots * sizeof (struct str_header);
fprintf (stderr,
"\nString pool\n\
entries\t\t%lu\n\
slots\t\t%lu\n\
bytes\t\t%lu%c (%lu%c overhead)\n\
table size\t%lu%c\n",
(unsigned long) nelts, (unsigned long) string_hash.nslots,
SCALE (total_bytes), LABEL (total_bytes),
SCALE (overhead), LABEL (overhead),
SCALE (headers), LABEL (headers));
exp_len = (double)total_bytes / (double)nelts;
exp2_len = exp_len * exp_len;
exp_len2 = (double)sum_of_squares / (double)nelts;
fprintf (stderr,
"coll/search\t%.4f\n\
ins/search\t%.4f\n\
avg. entry\t%.2f bytes (+/- %.2f)\n\
longest entry\t%lu\n",
(double) string_hash.collisions / (double) string_hash.searches,
(double) nelts / (double) string_hash.searches,
exp_len, approx_sqrt (exp_len2 - exp2_len),
(unsigned long) longest);
#undef SCALE
#undef LABEL
}
/* Mark the string hash for GC. */
static void
mark_string_hash (arg)
void *arg ATTRIBUTE_UNUSED;
{
struct str_header *h;
FORALL_IDS (h)
{
ggc_mark_tree (h->data);
}
}

View file

@ -1577,6 +1577,29 @@ floor_log2_wide (x)
return log;
}
/* Return the approximate positive square root of a number N. This is for
statistical reports, not code generation. */
double
approx_sqrt (x)
double x;
{
double s, d;
if (x < 0)
abort ();
if (x == 0)
return 0;
s = x;
do
{
d = (s * s - x) / (2 * s);
s -= d;
}
while (d > .0001);
return s;
}
static int float_handler_set;
int float_handled;
jmp_buf float_handler;
@ -2516,7 +2539,10 @@ compile_file (name)
}
if (mem_report)
ggc_print_statistics ();
{
ggc_print_statistics ();
stringpool_statistics ();
}
/* Free up memory for the benefit of leak detectors. */
free_reg_info ();
@ -4085,7 +4111,7 @@ decode_f_option (arg)
else if ((option_value
= skip_leading_substring (arg, "stack-limit-symbol=")))
{
char *nm;
const char *nm;
nm = ggc_strdup (option_value);
stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, nm);
}
@ -4557,6 +4583,7 @@ main (argc, argv)
/* Initialize the garbage-collector. */
init_ggc ();
init_stringpool ();
ggc_add_root (&input_file_stack, 1, sizeof input_file_stack,
mark_file_stack);
ggc_add_rtx_root (&stack_limit_rtx, 1);

View file

@ -131,14 +131,6 @@ static const char * const tree_node_kind_names[] = {
"lang_type kinds"
};
/* Hash table for uniquizing IDENTIFIER_NODEs by name. */
#define MAX_HASH_TABLE 1009
static tree hash_table[MAX_HASH_TABLE]; /* id hash buckets */
/* 0 while creating built-in identifiers. */
static int do_identifier_warnings;
/* Unique id for next decl created. */
static int next_decl_uid;
/* Unique id for next type created. */
@ -191,7 +183,7 @@ void (*lang_unsave_expr_now) PARAMS ((tree));
built-in tree nodes. The variable, which is dynamically allocated,
should be used; the macro is only used to initialize it. */
static char *built_in_filename;
static const char *built_in_filename;
#define BUILT_IN_FILENAME ("<built-in>")
tree global_trees[TI_MAX];
@ -204,10 +196,6 @@ init_obstacks ()
{
gcc_obstack_init (&permanent_obstack);
/* Init the hash table of identifiers. */
memset ((char *) hash_table, 0, sizeof hash_table);
ggc_add_tree_root (hash_table, sizeof hash_table / sizeof (tree));
/* Initialize the hash table of types. */
type_hash_table = htab_create (TYPE_HASH_INITIAL_SIZE, type_hash_hash,
type_hash_eq, 0);
@ -555,133 +543,7 @@ copy_list (list)
}
return head;
}
#define HASHBITS 30
/* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string).
If an identifier with that name has previously been referred to,
the same node is returned this time. */
tree
get_identifier (text)
register const char *text;
{
register int hi;
register int i;
register tree idp;
register int len, hash_len;
/* Compute length of text in len. */
len = strlen (text);
/* Decide how much of that length to hash on */
hash_len = len;
if (warn_id_clash && len > id_clash_len)
hash_len = id_clash_len;
/* Compute hash code */
hi = hash_len * 613 + (unsigned) text[0];
for (i = 1; i < hash_len; i += 2)
hi = ((hi * 613) + (unsigned) (text[i]));
hi &= (1 << HASHBITS) - 1;
hi %= MAX_HASH_TABLE;
/* Search table for identifier. */
for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp))
if (IDENTIFIER_LENGTH (idp) == len
&& IDENTIFIER_POINTER (idp)[0] == text[0]
&& !memcmp (IDENTIFIER_POINTER (idp), text, len))
/* Return if found. */
return idp;
/* Not found; optionally warn about a similar identifier. */
if (warn_id_clash && do_identifier_warnings && len >= id_clash_len)
for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp))
if (!strncmp (IDENTIFIER_POINTER (idp), text, id_clash_len))
{
warning ("`%s' and `%s' identical in first %d characters",
IDENTIFIER_POINTER (idp), text, id_clash_len);
break;
}
if (TREE_CODE_LENGTH (IDENTIFIER_NODE) < 0)
abort (); /* set_identifier_size hasn't been called. */
/* Not found, create one, add to chain */
idp = make_node (IDENTIFIER_NODE);
IDENTIFIER_LENGTH (idp) = len;
#ifdef GATHER_STATISTICS
id_string_size += len;
#endif
IDENTIFIER_POINTER (idp) = ggc_alloc_string (text, len);
TREE_CHAIN (idp) = hash_table[hi];
hash_table[hi] = idp;
return idp; /* <-- return if created */
}
/* If an identifier with the name TEXT (a null-terminated string) has
previously been referred to, return that node; otherwise return
NULL_TREE. */
tree
maybe_get_identifier (text)
register const char *text;
{
register int hi;
register int i;
register tree idp;
register int len, hash_len;
/* Compute length of text in len. */
len = strlen (text);
/* Decide how much of that length to hash on */
hash_len = len;
if (warn_id_clash && len > id_clash_len)
hash_len = id_clash_len;
/* Compute hash code */
hi = hash_len * 613 + (unsigned) text[0];
for (i = 1; i < hash_len; i += 2)
hi = ((hi * 613) + (unsigned) (text[i]));
hi &= (1 << HASHBITS) - 1;
hi %= MAX_HASH_TABLE;
/* Search table for identifier. */
for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp))
if (IDENTIFIER_LENGTH (idp) == len
&& IDENTIFIER_POINTER (idp)[0] == text[0]
&& !memcmp (IDENTIFIER_POINTER (idp), text, len))
return idp; /* <-- return if found */
return NULL_TREE;
}
/* Enable warnings on similar identifiers (if requested).
Done after the built-in identifiers are created. */
void
start_identifier_warnings ()
{
do_identifier_warnings = 1;
}
/* Record the size of an identifier node for the language in use.
SIZE is the total size in bytes.
This is called by the language-specific files. This must be
called before allocating any identifiers. */
void
set_identifier_size (size)
int size;
{
tree_code_length[(int) IDENTIFIER_NODE]
= (size - sizeof (struct tree_common)) / sizeof (tree);
}
/* Return a newly constructed INTEGER_CST node whose constant value
is specified by the two ints LOW and HI.

View file

@ -713,7 +713,7 @@ struct tree_string
struct rtx_def *rtl; /* acts as link to register transfer language
(rtl) info */
int length;
char *pointer;
const char *pointer;
};
/* In a COMPLEX_CST node. */
@ -1852,6 +1852,10 @@ extern tree integer_types[itk_none];
extern int exact_log2_wide PARAMS ((unsigned HOST_WIDE_INT));
extern int floor_log2_wide PARAMS ((unsigned HOST_WIDE_INT));
/* Approximate positive square root of a host double. This is for
statistical reports, not code generation. */
extern double approx_sqrt PARAMS ((double));
extern char *permalloc PARAMS ((int));
extern char *expralloc PARAMS ((int));

View file

@ -213,7 +213,7 @@ static enum in_section { no_section, in_text, in_data, in_named
#endif
/* Text of section name when in_section == in_named. */
static char *in_named_name;
static const char *in_named_name;
/* Define functions like text_section for any extra sections. */
#ifdef EXTRA_SECTION_FUNCTIONS
@ -1798,7 +1798,7 @@ assemble_static_space (size)
int size;
{
char name[12];
char *namestring;
const char *namestring;
rtx x;
#if 0
@ -2330,7 +2330,7 @@ struct rtx_const
struct constant_descriptor
{
struct constant_descriptor *next;
char *label;
const char *label;
rtx rtl;
/* Make sure the data is reasonably aligned. */
union
@ -2352,7 +2352,7 @@ static struct constant_descriptor *const_hash_table[MAX_HASH_TABLE];
struct deferred_string
{
char *label;
const char *label;
tree exp;
int labelno;
};
@ -3335,7 +3335,7 @@ struct pool_constant
{
struct constant_descriptor *desc;
struct pool_constant *next, *next_sym;
char *label;
const char *label;
rtx constant;
enum machine_mode mode;
int labelno;
@ -3613,7 +3613,7 @@ force_const_mem (mode, x)
register int hash;
register struct constant_descriptor *desc;
char label[256];
char *found = 0;
const char *found = 0;
rtx def;
/* If we want this CONST_DOUBLE in the same mode as it is in memory