* target-def.h (TARGET_BINDS_LOCAL_P): New.
* target.h (struct gcc_target): Move boolean fields to the end.
Add binds_local_p.
* varasm.c (default_binds_local_p): New.
* output.h: Declare it.
* config/alpha/alpha.c (alpha_encode_section_info): Use the new hook.
* config/cris/cris.c (cris_encode_section_info): Likewise.
* config/i386/i386.c (i386_encode_section_info): Likewise.
* config/ia64/ia64.c (ia64_encode_section_info): Likewise.
* config/sh/sh.c (sh_encode_section_info): Likewise.
* doc/tm.texi (TARGET_IN_SMALL_DATA_P): New.
(TARGET_BINDS_LOCAL_P): New.
From-SVN: r53620
+2002-05-19 Richard Henderson <rth@redhat.com>
+
+ * target-def.h (TARGET_BINDS_LOCAL_P): New.
+ * target.h (struct gcc_target): Move boolean fields to the end.
+ Add binds_local_p.
+ * varasm.c (default_binds_local_p): New.
+ * output.h: Declare it.
+
+ * config/alpha/alpha.c (alpha_encode_section_info): Use the new hook.
+ * config/cris/cris.c (cris_encode_section_info): Likewise.
+ * config/i386/i386.c (i386_encode_section_info): Likewise.
+ * config/ia64/ia64.c (ia64_encode_section_info): Likewise.
+ * config/sh/sh.c (sh_encode_section_info): Likewise.
+
+ * doc/tm.texi (TARGET_IN_SMALL_DATA_P): New.
+ (TARGET_BINDS_LOCAL_P): New.
+
2002-05-19 Richard Henderson <rth@redhat.com>
* system.h (BLOCK_PROFILER, BLOCK_PROFILER_CODE,
{
const char *symbol_str;
bool is_local, is_small;
+ rtx rtl, symbol;
+ rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
+
+ /* Careful not to prod global register variables. */
+ if (GET_CODE (rtl) != MEM)
+ return;
+ symbol = XEXP (rtl, 0);
+ if (GET_CODE (symbol) != SYMBOL_REF)
+ return;
+
if (TREE_CODE (decl) == FUNCTION_DECL)
{
/* We mark public functions once they are emitted; otherwise we
if (! decl_in_text_section (decl))
return;
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
+ SYMBOL_REF_FLAG (symbol) = 1;
return;
}
if (! TARGET_EXPLICIT_RELOCS)
return;
- /* Careful not to prod global register variables. */
- if (TREE_CODE (decl) != VAR_DECL
- || GET_CODE (DECL_RTL (decl)) != MEM
- || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
- return;
-
- symbol_str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+ symbol_str = XSTR (symbol, 0);
/* A variable is considered "local" if it is defined in this module. */
-
- /* Local binding occurs for any non-default visibility. */
- if (MODULE_LOCAL_P (decl))
- is_local = true;
- /* Otherwise, variables defined outside this object may not be local. */
- else if (DECL_EXTERNAL (decl))
- is_local = false;
- /* Linkonce and weak data is never local. */
- else if (DECL_ONE_ONLY (decl) || DECL_WEAK (decl))
- is_local = false;
- /* Static variables are always local. */
- else if (! TREE_PUBLIC (decl))
- is_local = true;
- /* If PIC, then assume that any global name can be overridden by
- symbols resolved from other modules. */
- else if (flag_pic)
- is_local = false;
- /* Uninitialized COMMON variable may be unified with symbols
- resolved from other modules. */
- else if (DECL_COMMON (decl)
- && (DECL_INITIAL (decl) == NULL
- || DECL_INITIAL (decl) == error_mark_node))
- is_local = false;
- /* Otherwise we're left with initialized (or non-common) global data
- which is of necessity defined locally. */
- else
- is_local = true;
+ is_local = (*targetm.binds_local_p) (decl);
/* Determine if DECL will wind up in .sdata/.sbss. */
is_small = alpha_in_small_data_p (decl);
/* Finally, encode this into the symbol string. */
if (is_local)
{
- const char *string;
char *newstr;
size_t len;
newstr[1] = (is_small ? 's' : 'v');
memcpy (newstr + 2, symbol_str, len);
- string = ggc_alloc_string (newstr, len + 2 - 1);
- XSTR (XEXP (DECL_RTL (decl), 0), 0) = string;
+ XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2 - 1);
}
else if (symbol_str[0] == '@')
{
{
if (flag_pic)
{
- if (DECL_P (exp))
- {
- if (TREE_CODE (exp) == FUNCTION_DECL
- && (TREE_PUBLIC (exp) || DECL_WEAK (exp))
- && ! MODULE_LOCAL_P (exp))
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (exp), 0)) = 0;
- else
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (exp), 0))
- = ((! TREE_PUBLIC (exp) && ! DECL_WEAK (exp))
- || MODULE_LOCAL_P (exp));
- }
- else
- /* Others are local entities. */
- SYMBOL_REF_FLAG (XEXP (TREE_CST_RTL (exp), 0)) = 1;
+ rtx rtl = DECL_P (exp) ? DECL_RTL (exp) : TREE_CST_RTL (exp);
+
+ if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF)
+ SYMBOL_REF_FLAG (XEXP (rtl, 0)) = (*targetm.binds_local_p) (exp);
}
}
{
if (flag_pic)
{
- rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
- ? TREE_CST_RTL (decl) : DECL_RTL (decl));
+ rtx rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
- if (GET_CODE (rtl) == MEM)
- {
- if (TARGET_DEBUG_ADDR
- && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
- {
- fprintf (stderr, "Encode %s, public = %d\n",
- IDENTIFIER_POINTER (DECL_NAME (decl)),
- TREE_PUBLIC (decl));
- }
-
- SYMBOL_REF_FLAG (XEXP (rtl, 0))
- = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
- || ! TREE_PUBLIC (decl)
- || MODULE_LOCAL_P (decl));
- }
+ if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF)
+ SYMBOL_REF_FLAG (XEXP (rtl, 0)) = (*targetm.binds_local_p) (decl);
}
}
\f
symbol = XEXP (DECL_RTL (decl), 0);
symbol_str = XSTR (symbol, 0);
- /* A variable is considered "local" if it is defined by this module. */
-
- if (MODULE_LOCAL_P (decl))
- is_local = true;
- /* Otherwise, variables defined outside this object may not be local. */
- else if (DECL_EXTERNAL (decl))
- is_local = false;
- /* Linkonce and weak data are never local. */
- else if (DECL_ONE_ONLY (decl) || DECL_WEAK (decl))
- is_local = false;
- /* Static variables are always local. */
- else if (! TREE_PUBLIC (decl))
- is_local = true;
- /* If PIC, then assume that any global name can be overridden by
- symbols resolved from other modules. */
- else if (flag_pic)
- is_local = false;
- /* Uninitialized COMMON variable may be unified with symbols
- resolved from other modules. */
- else if (DECL_COMMON (decl)
- && (DECL_INITIAL (decl) == NULL
- || DECL_INITIAL (decl) == error_mark_node))
- is_local = false;
- /* Otherwise we're left with initialized (or non-common) global data
- which is of necessity defined locally. */
- else
- is_local = true;
+ is_local = (*targetm.binds_local_p) (decl);
/* Determine if DECL will wind up in .sdata/.sbss. */
is_small = ia64_in_small_data_p (decl);
return;
if (flag_pic)
- {
- SYMBOL_REF_FLAG (symbol) =
- (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
- || MODULE_LOCAL_P (decl)
- || ! TREE_PUBLIC (decl));
- }
+ SYMBOL_REF_FLAG (symbol) = (*targetm.binds_local_p) (decl);
if (TARGET_SH5 && first && TREE_CODE (decl) != FUNCTION_DECL)
XEXP (rtl, 0) = gen_datalabel_ref (symbol);
may have added.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_IN_SMALL_DATA_P (tree @var{exp})
+Returns true if @var{exp} should be placed into a ``small data'' section.
+The default version of this hook always returns false.
+@end deftypefn
+
+@deftypefn {Target Hook} bool TARGET_BINDS_LOCAL_P (tree @var{exp})
+Returns true if @var{exp} names an object for which name resolution
+rules must resolve to the current ``module'' (dynamic shared library
+or executable image).
+
+The default version of this hook implements the name resolution rules
+for ELF, which has a looser model of global name binding than other
+currently supported object file formats.
+@end deftypefn
+
@node PIC
@section Position Independent Code
@cindex position independent code
extern void default_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT));
extern const char *default_strip_name_encoding PARAMS ((const char *));
+extern bool default_binds_local_p PARAMS ((tree));
/* Emit data for vtable gc for GNU binutils. */
extern void assemble_vtable_entry PARAMS ((struct rtx_def *, HOST_WIDE_INT));
#define TARGET_STRIP_NAME_ENCODING default_strip_name_encoding
#endif
+#ifndef TARGET_BINDS_LOCAL_P
+#define TARGET_BINDS_LOCAL_P default_binds_local_p
+#endif
+
/* In hook.c. */
#define TARGET_CANNOT_MODIFY_JUMPS_P hook_void_bool_false
#define TARGET_IN_SMALL_DATA_P hook_tree_bool_false
TARGET_INIT_BUILTINS, \
TARGET_EXPAND_BUILTIN, \
TARGET_SECTION_TYPE_FLAGS, \
- TARGET_HAVE_NAMED_SECTIONS, \
- TARGET_HAVE_CTORS_DTORS, \
TARGET_CANNOT_MODIFY_JUMPS_P, \
TARGET_IN_SMALL_DATA_P, \
+ TARGET_BINDS_LOCAL_P, \
TARGET_ENCODE_SECTION_INFO, \
- TARGET_STRIP_NAME_ENCODING \
+ TARGET_STRIP_NAME_ENCODING, \
+ TARGET_HAVE_NAMED_SECTIONS, \
+ TARGET_HAVE_CTORS_DTORS, \
}
#include "hooks.h"
/* ??? Should be merged with SELECT_SECTION and UNIQUE_SECTION. */
unsigned int (* section_type_flags) PARAMS ((tree, const char *, int));
- /* True if arbitrary sections are supported. */
- bool have_named_sections;
-
- /* True if "native" constructors and destructors are supported,
- false if we're using collect2 for the job. */
- bool have_ctors_dtors;
-
/* True if new jumps cannot be created, to replace existing ones or
not, at the current point in the compilation. */
bool (* cannot_modify_jumps_p) PARAMS ((void));
/* True if EXP should be placed in a "small data" section. */
bool (* in_small_data_p) PARAMS ((tree));
+ /* True if EXP names an object for which name resolution must resolve
+ to the current module. */
+ bool (* binds_local_p) PARAMS ((tree));
+
/* Do something target-specific to record properties of the DECL into
the associated SYMBOL_REF. */
void (* encode_section_info) PARAMS ((tree, int));
/* Undo the effects of encode_section_info on the symbol string. */
const char * (* strip_name_encoding) PARAMS ((const char *));
+
+ /* Leave the boolean fields at the end. */
+
+ /* True if arbitrary sections are supported. */
+ bool have_named_sections;
+
+ /* True if "native" constructors and destructors are supported,
+ false if we're using collect2 for the job. */
+ bool have_ctors_dtors;
};
extern struct gcc_target targetm;
{
return str + (*str == '*');
}
+
+/* Assume ELF-ish defaults, since that's pretty much the most liberal
+ wrt cross-module name binding. */
+
+bool
+default_binds_local_p (exp)
+ tree exp;
+{
+ bool local_p;
+
+ /* A non-decl is an entry in the constant pool. */
+ if (!DECL_P (exp))
+ local_p = true;
+ /* A variable is considered "local" if it is defined by this module. */
+ if (MODULE_LOCAL_P (exp))
+ local_p = true;
+ /* Otherwise, variables defined outside this object may not be local. */
+ else if (DECL_EXTERNAL (exp))
+ local_p = false;
+ /* Linkonce and weak data are never local. */
+ else if (DECL_ONE_ONLY (exp) || DECL_WEAK (exp))
+ local_p = false;
+ /* Static variables are always local. */
+ else if (! TREE_PUBLIC (exp))
+ local_p = true;
+ /* If PIC, then assume that any global name can be overridden by
+ symbols resolved from other modules. */
+ else if (flag_pic)
+ local_p = false;
+ /* Uninitialized COMMON variable may be unified with symbols
+ resolved from other modules. */
+ else if (DECL_COMMON (exp)
+ && (DECL_INITIAL (exp) == NULL
+ || DECL_INITIAL (exp) == error_mark_node))
+ local_p = false;
+ /* Otherwise we're left with initialized (or non-common) global data
+ which is of necessity defined locally. */
+ else
+ local_p = true;
+
+ return local_p;
+}