aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard@codesourcery.com>2006-03-02 19:32:52 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2006-03-02 19:32:52 +0000
commit434aeebbffe4ab538143fb7f12653e8745e077f0 (patch)
tree528d89d3defd10c4dc529d8c5dd944f7010598a6
parentc2924966db687eb67be927c2db657dc92ff25f25 (diff)
downloadgcc-434aeebbffe4ab538143fb7f12653e8745e077f0.zip
gcc-434aeebbffe4ab538143fb7f12653e8745e077f0.tar.gz
gcc-434aeebbffe4ab538143fb7f12653e8745e077f0.tar.bz2
tm.texi (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS): Document.
* doc/tm.texi (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS): Document. (ASM_OUTPUT_BSS): Describe the two ways of handling global BSS, and say that only one is needed. * doc/rtl.texi (SYMBOL_REF_BLOCK): Say that the block can be null. * target.h (have_switchable_bss_sections): New hook. * explow.c (use_anchored_address): Check that the symbol is in a block. * varasm.c (tls_comm_section, comm_section, lcomm_section) (bss_noswitch_section): New variables. (get_unnamed_section): Add SECTION_UNNAMED to the flags. (get_noswitch_section): New function. (get_block_for_section): Allow SECT to be null. (unlikely_text_section_p): Use SECTION_STYLE. (bss_initializer_p): New function. (get_variable_section): Move earlier in file. Take a new argument, prefer_noswitch_p. Move bss checks from assemble_variable to here. Return one of the new *_sections in such cases. (get_block_for_decl): New function, extracting some logic from use_blocks_for_decl_p. (change_symbol_section): Remove in favor of... (change_symbol_block): ...this new function. (use_blocks_for_decl_p): Remove checks now performed by get_block_for_decl. (make_decl_rtl): Use change_symbol_block and get_block_for_decl. (ASM_EMIT_LOCAL, ASM_EMIT_BSS, ASM_EMIT_COMMON): Delete in favor of... (emit_local, emit_bss, emit_common): ...these new functions. Return true if the alignment was honored. (emit_tls_common): New function. (asm_emit_uninitialised): Delete. (assemble_variable_noswitch): New function, split out from... (assemble_variable): ...here. Don't make decisions about common variables here. Globalize all public decls that go into non-common sections. Check whether SYMBOL_REF_BLOCK is null. (output_constant_def_contents): Check whether SYMBOL_REF_BLOCK is null. (output_constant_pool): Likewise. (init_varasm_once): Initialize the new section variables. (have_global_bss_p): New function. (categorize_decl_for_section): Use bss_initializer_p. (switch_to_section): Use SECTION_STYLE. Abort for SECTION_NOSWITCH. (place_block_symbol): Assert that the symbol must be in a block. * target-def.h (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS): New macro. (TARGET_INITIALIZER): Include it. * rtl.h (SYMBOL_REF_BLOCK): Document the null alternative. * output.h (SECTION_STYLE_MASK, SECTION_COMMON): New macros. (SECTION_MACH_DEP): Bump by two. (SECTION_UNNAMED, SECTION_NOSWITCH): New macros. (unnamed_section): Mention SECTION_UNNAMED in comment. (named_section): Likewise SECTION_NAMED. (noswitch_section_callback): New type. (noswitch_section): New structure. (section): Add a noswitch_section alternative. (SECTION_STYLE): New macro. (tls_comm_section, comm_section, lcomm_section): Declare. (bss_noswitch_section, have_global_bss_p): Declare. * config/elfos.h (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS): Override. * config/iq2000/iq2000.c (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS): Override. * config/v850/v850.c (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS): Override. * config/stormy16/stormy16.c (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS): Override. cp/ * decl.c (start_decl): Use have_global_bss_p when deciding whether to make the decl common. ada/ * utils.c (create_var_decl): Use have_global_bss_p when deciding whether to make the decl common. From-SVN: r111644
-rw-r--r--gcc/ChangeLog62
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/ada/utils.c8
-rw-r--r--gcc/config/elfos.h2
-rw-r--r--gcc/config/iq2000/iq2000.c5
-rw-r--r--gcc/config/stormy16/stormy16.c4
-rw-r--r--gcc/config/v850/v850.c5
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/decl.c11
-rw-r--r--gcc/doc/rtl.texi2
-rw-r--r--gcc/doc/tm.texi25
-rw-r--r--gcc/explow.c1
-rw-r--r--gcc/output.h56
-rw-r--r--gcc/rtl.h4
-rw-r--r--gcc/target-def.h5
-rw-r--r--gcc/target.h4
-rw-r--r--gcc/varasm.c460
17 files changed, 432 insertions, 232 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7967d68..55bb0ad 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,65 @@
+2006-03-02 Richard Sandiford <richard@codesourcery.com>
+
+ * doc/tm.texi (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS): Document.
+ (ASM_OUTPUT_BSS): Describe the two ways of handling global BSS,
+ and say that only one is needed.
+ * doc/rtl.texi (SYMBOL_REF_BLOCK): Say that the block can be null.
+ * target.h (have_switchable_bss_sections): New hook.
+ * explow.c (use_anchored_address): Check that the symbol is in a block.
+ * varasm.c (tls_comm_section, comm_section, lcomm_section)
+ (bss_noswitch_section): New variables.
+ (get_unnamed_section): Add SECTION_UNNAMED to the flags.
+ (get_noswitch_section): New function.
+ (get_block_for_section): Allow SECT to be null.
+ (unlikely_text_section_p): Use SECTION_STYLE.
+ (bss_initializer_p): New function.
+ (get_variable_section): Move earlier in file. Take a new argument,
+ prefer_noswitch_p. Move bss checks from assemble_variable to here.
+ Return one of the new *_sections in such cases.
+ (get_block_for_decl): New function, extracting some logic from
+ use_blocks_for_decl_p.
+ (change_symbol_section): Remove in favor of...
+ (change_symbol_block): ...this new function.
+ (use_blocks_for_decl_p): Remove checks now performed by
+ get_block_for_decl.
+ (make_decl_rtl): Use change_symbol_block and get_block_for_decl.
+ (ASM_EMIT_LOCAL, ASM_EMIT_BSS, ASM_EMIT_COMMON): Delete in favor of...
+ (emit_local, emit_bss, emit_common): ...these new functions.
+ Return true if the alignment was honored.
+ (emit_tls_common): New function.
+ (asm_emit_uninitialised): Delete.
+ (assemble_variable_noswitch): New function, split out from...
+ (assemble_variable): ...here. Don't make decisions about common
+ variables here. Globalize all public decls that go into non-common
+ sections. Check whether SYMBOL_REF_BLOCK is null.
+ (output_constant_def_contents): Check whether SYMBOL_REF_BLOCK is null.
+ (output_constant_pool): Likewise.
+ (init_varasm_once): Initialize the new section variables.
+ (have_global_bss_p): New function.
+ (categorize_decl_for_section): Use bss_initializer_p.
+ (switch_to_section): Use SECTION_STYLE. Abort for SECTION_NOSWITCH.
+ (place_block_symbol): Assert that the symbol must be in a block.
+ * target-def.h (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS): New macro.
+ (TARGET_INITIALIZER): Include it.
+ * rtl.h (SYMBOL_REF_BLOCK): Document the null alternative.
+ * output.h (SECTION_STYLE_MASK, SECTION_COMMON): New macros.
+ (SECTION_MACH_DEP): Bump by two.
+ (SECTION_UNNAMED, SECTION_NOSWITCH): New macros.
+ (unnamed_section): Mention SECTION_UNNAMED in comment.
+ (named_section): Likewise SECTION_NAMED.
+ (noswitch_section_callback): New type.
+ (noswitch_section): New structure.
+ (section): Add a noswitch_section alternative.
+ (SECTION_STYLE): New macro.
+ (tls_comm_section, comm_section, lcomm_section): Declare.
+ (bss_noswitch_section, have_global_bss_p): Declare.
+ * config/elfos.h (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS): Override.
+ * config/iq2000/iq2000.c (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS):
+ Override.
+ * config/v850/v850.c (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS): Override.
+ * config/stormy16/stormy16.c (TARGET_HAVE_SWITCHABLE_BSS_SECTIONS):
+ Override.
+
2006-03-02 Daniel Berlin <dberlin@dberlin.org>
* gcc/tree-vrp.c (execute_vrp): Return value.
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index c5ecc91..d87a8d6 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,8 @@
+2006-03-02 Richard Sandiford <richard@codesourcery.com>
+
+ * utils.c (create_var_decl): Use have_global_bss_p when deciding
+ whether to make the decl common.
+
2006-02-20 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
* Make-lang.in (Ada): Remove
(.PHONY): Remove Ada
diff --git a/gcc/ada/utils.c b/gcc/ada/utils.c
index 78c1237..a3fdb0d 100644
--- a/gcc/ada/utils.c
+++ b/gcc/ada/utils.c
@@ -1293,10 +1293,10 @@ create_var_decl (tree var_name, tree asm_name, tree type, tree var_init,
try to fiddle with DECL_COMMON. However, on platforms that don't
support global BSS sections, uninitialized global variables would
go in DATA instead, thus increasing the size of the executable. */
-#if !defined(ASM_OUTPUT_BSS) && !defined(ASM_OUTPUT_ALIGNED_BSS)
- if (TREE_CODE (var_decl) == VAR_DECL)
- DECL_COMMON (var_decl) = !flag_no_common;
-#endif
+ if (!flag_no_common
+ && TREE_CODE (var_decl) == VAR_DECL
+ && !have_global_bss_p ())
+ DECL_COMMON (var_decl) = 1;
DECL_INITIAL (var_decl) = var_init;
TREE_READONLY (var_decl) = const_flag;
DECL_EXTERNAL (var_decl) = extern_flag;
diff --git a/gcc/config/elfos.h b/gcc/config/elfos.h
index 181072c..31e309d 100644
--- a/gcc/config/elfos.h
+++ b/gcc/config/elfos.h
@@ -221,6 +221,8 @@ Boston, MA 02110-1301, USA. */
#define TARGET_ASM_SELECT_RTX_SECTION default_elf_select_rtx_section
#undef TARGET_ASM_SELECT_SECTION
#define TARGET_ASM_SELECT_SECTION default_elf_select_section
+#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
+#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS true
/* Define the strings used for the special svr4 .type and .size directives.
These strings generally do not vary from one system running svr4 to
diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c
index dd42fe9..4b1cb3e 100644
--- a/gcc/config/iq2000/iq2000.c
+++ b/gcc/config/iq2000/iq2000.c
@@ -186,6 +186,11 @@ static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
#undef TARGET_ASM_SELECT_SECTION
#define TARGET_ASM_SELECT_SECTION iq2000_select_section
+/* The assembler supports switchable .bss sections, but
+ iq2000_select_section doesn't yet make use of them. */
+#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
+#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
+
#undef TARGET_PROMOTE_FUNCTION_ARGS
#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
#undef TARGET_PROMOTE_FUNCTION_RETURN
diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c
index 76becfc..32513d2 100644
--- a/gcc/config/stormy16/stormy16.c
+++ b/gcc/config/stormy16/stormy16.c
@@ -2653,6 +2653,10 @@ xstormy16_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO xstormy16_encode_section_info
+/* select_section doesn't handle .bss_below100. */
+#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
+#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
+
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK xstormy16_asm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index 7629a7a..eb2771c 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -117,6 +117,11 @@ static GTY(()) section *zbss_section;
#undef TARGET_ASM_SELECT_SECTION
#define TARGET_ASM_SELECT_SECTION v850_select_section
+/* The assembler supports switchable .bss sections, but
+ v850_select_section doesn't yet make use of them. */
+#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
+#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
+
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO v850_encode_section_info
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c092c39..71541e1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2006-03-02 Richard Sandiford <richard@codesourcery.com>
+
+ * decl.c (start_decl): Use have_global_bss_p when deciding
+ whether to make the decl common.
+
2006-03-01 Mike Stump <mrs@apple.com>
PR darwin/25908
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 21ef001..a9aec67 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3824,16 +3824,17 @@ start_decl (const cp_declarator *declarator,
if (tem == error_mark_node)
return error_mark_node;
-#if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS)
/* Tell the back-end to use or not use .common as appropriate. If we say
-fconserve-space, we want this to save .data space, at the expense of
wrong semantics. If we say -fno-conserve-space, we want this to
produce errors about redefs; to do this we force variables into the
data segment. */
- DECL_COMMON (tem) = ((TREE_CODE (tem) != VAR_DECL
- || !DECL_THREAD_LOCAL_P (tem))
- && (flag_conserve_space || ! TREE_PUBLIC (tem)));
-#endif
+ if (flag_conserve_space
+ && TREE_CODE (tem) == VAR_DECL
+ && TREE_PUBLIC (tem)
+ && !DECL_THREAD_LOCAL_P (tem)
+ && !have_global_bss_p ())
+ DECL_COMMON (tem) = 1;
if (! processing_template_decl)
start_decl_1 (tem);
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index de4a8e73..76b3a3c 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -528,7 +528,7 @@ the target's use.
@findex SYMBOL_REF_BLOCK
@item SYMBOL_REF_BLOCK (@var{x})
If @samp{SYMBOL_REF_IN_BLOCK_P (@var{x})}, this is the @samp{object_block}
-structure to which the symbol belongs. The value is always nonnull.
+structure to which the symbol belongs, or @code{NULL} if none.
@findex SYMBOL_REF_BLOCK_OFFSET
@item SYMBOL_REF_BLOCK_OFFSET (@var{x})
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 778ecc9..e99989f 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -6477,6 +6477,13 @@ specify an alignment within the section directive need pay attention to
This flag is true if the target supports @code{TARGET_ASM_NAMED_SECTION}.
@end deftypefn
+@anchor{TARGET_HAVE_SWITCHABLE_BSS_SECTIONS}
+@deftypefn {Target Hook} bool TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
+This flag is true if we can create zeroed data by switching to a BSS
+section and then using @code{ASM_OUTPUT_SKIP} to allocate the space.
+This is true on most ELF targets.
+@end deftypefn
+
@deftypefn {Target Hook} {unsigned int} TARGET_SECTION_TYPE_FLAGS (tree @var{decl}, const char *@var{name}, int @var{reloc})
Choose a set of section attributes for use by @code{TARGET_ASM_NAMED_SECTION}
based on a variable or function decl, a section name, and whether or not the
@@ -6705,13 +6712,17 @@ defining this macro. If unable, use the expression
before and after that, output the additional assembler syntax for defining
the name, and a newline.
-This macro controls how the assembler definitions of uninitialized global
-variables are output. This macro exists to properly support languages like
-C++ which do not have @code{common} data. However, this macro currently
-is not defined for all targets. If this macro and
-@code{ASM_OUTPUT_ALIGNED_BSS} are not defined then @code{ASM_OUTPUT_COMMON}
-or @code{ASM_OUTPUT_ALIGNED_COMMON} or
-@code{ASM_OUTPUT_ALIGNED_DECL_COMMON} is used.
+There are two ways of handling global BSS. One is to define either
+this macro or its aligned counterpart, @code{ASM_OUTPUT_ALIGNED_BSS}.
+The other is to have @code{TARGET_ASM_SELECT_SECTION} return a
+switchable BSS section (@pxref{TARGET_HAVE_SWITCHABLE_BSS_SECTIONS}).
+You do not need to do both.
+
+Some languages do not have @code{common} data, and require a
+non-common form of global BSS in order to handle uninitialized globals
+efficiently. C++ is one example of this. However, if the target does
+not support global BSS, the front end may choose to make globals
+common in order to save space in the object file.
@end defmac
@defmac ASM_OUTPUT_ALIGNED_BSS (@var{stream}, @var{decl}, @var{name}, @var{size}, @var{alignment})
diff --git a/gcc/explow.c b/gcc/explow.c
index b56373c..361c717 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -568,6 +568,7 @@ use_anchored_address (rtx x)
if (GET_CODE (base) != SYMBOL_REF
|| !SYMBOL_REF_IN_BLOCK_P (base)
|| SYMBOL_REF_ANCHOR_P (base)
+ || SYMBOL_REF_BLOCK (base) == NULL
|| !targetm.use_anchors_for_symbol_p (base))
return x;
diff --git a/gcc/output.h b/gcc/output.h
index 5fda5ea..8974351 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -402,8 +402,22 @@ extern void no_asm_to_stream (FILE *);
#define SECTION_TLS 0x40000 /* contains thread-local storage */
#define SECTION_NOTYPE 0x80000 /* don't output @progbits */
#define SECTION_DECLARED 0x100000 /* section has been used */
-#define SECTION_NAMED 0x200000 /* section has a name */
-#define SECTION_MACH_DEP 0x400000 /* subsequent bits reserved for target */
+#define SECTION_STYLE_MASK 0x600000 /* bits used for SECTION_STYLE */
+#define SECTION_COMMON 0x800000 /* contains common data */
+#define SECTION_MACH_DEP 0x1000000 /* subsequent bits reserved for target */
+
+/* This SECTION_STYLE is used for unnamed sections that we can switch
+ to using a special assembler directive. */
+#define SECTION_UNNAMED 0x000000
+
+/* This SECTION_STYLE is used for named sections that we can switch
+ to using a general section directive. */
+#define SECTION_NAMED 0x200000
+
+/* This SECTION_STYLE is used for sections that we cannot switch to at
+ all. The choice of section is implied by the directive that we use
+ to declare the object. */
+#define SECTION_NOSWITCH 0x400000
/* A helper function for default_elf_select_section and
default_elf_unique_section. Categorizes the DECL. */
@@ -448,7 +462,7 @@ struct section_common GTY(()) {
unsigned int flags;
};
-/* Information that is provided by named sections. */
+/* Information about a SECTION_NAMED section. */
struct named_section GTY(()) {
struct section_common common;
@@ -464,7 +478,7 @@ struct named_section GTY(()) {
section. The argument provides callback-specific data. */
typedef void (*unnamed_section_callback) (const void *);
-/* Information that is provided by unnamed sections. */
+/* Information about a SECTION_UNNAMED section. */
struct unnamed_section GTY(()) {
struct section_common common;
@@ -477,14 +491,39 @@ struct unnamed_section GTY(()) {
section *next;
};
+/* A callback that writes the assembly code for a decl in a
+ SECTION_NOSWITCH section. DECL is the decl that should be assembled
+ and NAME is the name of its SYMBOL_REF. SIZE is the size of the decl
+ in bytes and ROUNDED is that size rounded up to the next
+ BIGGEST_ALIGNMENT / BITS_PER_UNIT boundary.
+
+ Return true if the callback used DECL_ALIGN to set the object's
+ alignment. A false return value implies that we are relying
+ on the rounded size to align the decl. */
+typedef bool (*noswitch_section_callback) (tree decl, const char *name,
+ unsigned HOST_WIDE_INT size,
+ unsigned HOST_WIDE_INT rounded);
+
+/* Information about a SECTION_NOSWITCH section. */
+struct noswitch_section GTY(()) {
+ struct section_common common;
+
+ /* The callback used to assemble decls in this section. */
+ noswitch_section_callback GTY ((skip)) callback;
+};
+
/* Information about a section, which may be named or unnamed. */
-union section GTY ((desc ("(%h).common.flags & SECTION_NAMED")))
+union section GTY ((desc ("SECTION_STYLE (&(%h))")))
{
struct section_common GTY ((skip)) common;
struct named_section GTY ((tag ("SECTION_NAMED"))) named;
- struct unnamed_section GTY ((tag ("0"))) unnamed;
+ struct unnamed_section GTY ((tag ("SECTION_UNNAMED"))) unnamed;
+ struct noswitch_section GTY ((tag ("SECTION_NOSWITCH"))) noswitch;
};
+/* Return the style of section SECT. */
+#define SECTION_STYLE(SECT) ((SECT)->common.flags & SECTION_STYLE_MASK)
+
struct object_block;
/* Special well-known sections. */
@@ -498,6 +537,10 @@ extern GTY(()) section *bss_section;
extern GTY(()) section *sbss_section;
extern GTY(()) section *exception_section;
extern GTY(()) section *eh_frame_section;
+extern GTY(()) section *tls_comm_section;
+extern GTY(()) section *comm_section;
+extern GTY(()) section *lcomm_section;
+extern GTY(()) section *bss_noswitch_section;
extern GTY(()) section *in_section;
extern GTY(()) bool in_cold_section_p;
@@ -523,6 +566,7 @@ extern void output_section_asm_op (const void *);
extern unsigned int default_section_type_flags (tree, const char *, int);
extern unsigned int default_section_type_flags_1 (tree, const char *, int, int);
+extern bool have_global_bss_p (void);
extern void default_no_named_section (const char *, unsigned int, tree);
extern void default_elf_asm_named_section (const char *, unsigned int, tree);
extern enum section_category categorize_decl_for_section (tree, int, int);
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 4ee188c..236c8a1 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1331,8 +1331,8 @@ do { \
#define SYMBOL_FLAG_MACH_DEP_SHIFT 9
#define SYMBOL_FLAG_MACH_DEP (1 << SYMBOL_FLAG_MACH_DEP_SHIFT)
-/* The block to which the given SYMBOL_REF belongs. Only valid if
- SYMBOL_REF_IN_BLOCK_P (RTX). */
+/* The block to which the given SYMBOL_REF belongs, or NULL if none.
+ Only valid if SYMBOL_REF_IN_BLOCK_P (RTX). */
#define SYMBOL_REF_BLOCK(RTX) (BLOCK_SYMBOL_CHECK (RTX)->block)
/* The byte offset of the given SYMBOL_REF from the start of its block,
diff --git a/gcc/target-def.h b/gcc/target-def.h
index c292567..fa38166 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -140,6 +140,10 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# endif
#endif
+#ifndef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
+#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
+#endif
+
#ifndef TARGET_ASM_INIT_SECTIONS
#define TARGET_ASM_INIT_SECTIONS hook_void_void
#endif
@@ -651,6 +655,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
TARGET_EXTRA_LIVE_ON_ENTRY, \
TARGET_UNWIND_TABLES_DEFAULT, \
TARGET_HAVE_NAMED_SECTIONS, \
+ TARGET_HAVE_SWITCHABLE_BSS_SECTIONS, \
TARGET_HAVE_CTORS_DTORS, \
TARGET_HAVE_TLS, \
TARGET_HAVE_SRODATA_SECTION, \
diff --git a/gcc/target.h b/gcc/target.h
index 63f5d4e..e6e6ba8 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -734,6 +734,10 @@ struct gcc_target
/* True if arbitrary sections are supported. */
bool have_named_sections;
+ /* True if we can create zeroed data by switching to a BSS section
+ and then using ASM_OUTPUT_SKIP to allocate the space. */
+ bool have_switchable_bss_sections;
+
/* True if "native" constructors and destructors are supported,
false if we're using collect2 for the job. */
bool have_ctors_dtors;
diff --git a/gcc/varasm.c b/gcc/varasm.c
index f07ed39..801d11e 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -138,9 +138,6 @@ static void asm_output_aligned_bss (FILE *, tree, const char *,
ATTRIBUTE_UNUSED;
#endif
#endif /* BSS_SECTION_ASM_OP */
-static bool asm_emit_uninitialised (tree, const char*,
- unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT);
static void mark_weak (tree);
/* Well-known sections, each one associated with some sort of *_ASM_OP. */
@@ -153,6 +150,15 @@ section *dtors_section;
section *bss_section;
section *sbss_section;
+/* Various forms of common section. All are guaranteed to be nonnull. */
+section *tls_comm_section;
+section *comm_section;
+section *lcomm_section;
+
+/* A SECTION_NOSWITCH section used for declaring global BSS variables.
+ May be null. */
+section *bss_noswitch_section;
+
/* The section that holds the main exception table, when known. The section
is set either by the target's init_sections hook or by the first call to
switch_to_exception_section. */
@@ -245,7 +251,7 @@ get_unnamed_section (unsigned int flags, void (*callback) (const void *),
section *sect;
sect = ggc_alloc (sizeof (struct unnamed_section));
- sect->unnamed.common.flags = flags;
+ sect->unnamed.common.flags = flags | SECTION_UNNAMED;
sect->unnamed.callback = callback;
sect->unnamed.data = data;
sect->unnamed.next = unnamed_sections;
@@ -254,6 +260,20 @@ get_unnamed_section (unsigned int flags, void (*callback) (const void *),
return sect;
}
+/* Return a SECTION_NOSWITCH section with the given fields. */
+
+static section *
+get_noswitch_section (unsigned int flags, noswitch_section_callback callback)
+{
+ section *sect;
+
+ sect = ggc_alloc (sizeof (struct unnamed_section));
+ sect->noswitch.common.flags = flags | SECTION_NOSWITCH;
+ sect->noswitch.callback = callback;
+
+ return sect;
+}
+
/* Return the named section structure associated with NAME. Create
a new section with the given fields if no such structure exists. */
@@ -300,7 +320,8 @@ use_object_blocks_p (void)
}
/* Return the object_block structure for section SECT. Create a new
- structure if we haven't created one already. */
+ structure if we haven't created one already. Return null if SECT
+ itself is null. */
static struct object_block *
get_block_for_section (section *sect)
@@ -308,6 +329,9 @@ get_block_for_section (section *sect)
struct object_block *block;
void **slot;
+ if (sect == NULL)
+ return NULL;
+
slot = htab_find_slot_with_hash (object_block_htab, sect,
hash_section (sect), INSERT);
block = (struct object_block *) *slot;
@@ -409,7 +433,7 @@ unlikely_text_section_p (section *sect)
return (name
&& sect
- && (sect->common.flags & SECTION_NAMED) != 0
+ && SECTION_STYLE (sect) == SECTION_NAMED
&& strcmp (name, sect->named.name) == 0);
}
@@ -786,81 +810,127 @@ decode_reg_name (const char *asmspec)
return -1;
}
-/* Return true if it is possible to put DECL in an object_block. */
+/* Return true if DECL's initializer is suitable for a BSS section. */
static bool
-use_blocks_for_decl_p (tree decl)
+bss_initializer_p (tree decl)
{
- /* Only data DECLs can be placed into object blocks. */
- if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != CONST_DECL)
- return false;
+ return (DECL_INITIAL (decl) == NULL
+ || DECL_INITIAL (decl) == error_mark_node
+ || (flag_zero_initialized_in_bss
+ /* Leave constant zeroes in .rodata so they
+ can be shared. */
+ && !TREE_READONLY (decl)
+ && initializer_zerop (DECL_INITIAL (decl))));
+}
+
+/* Return the section into which the given VAR_DECL or CONST_DECL
+ should be placed. PREFER_NOSWITCH_P is true if a noswitch
+ section should be used wherever possible. */
+
+static section *
+get_variable_section (tree decl, bool prefer_noswitch_p)
+{
+ int reloc;
+
+ /* If the decl has been given an explicit section name, then it
+ isn't common, and shouldn't be handled as such. */
+ if (DECL_COMMON (decl) && DECL_SECTION_NAME (decl) == NULL)
+ {
+ if (DECL_THREAD_LOCAL_P (decl))
+ return tls_comm_section;
+ if (TREE_PUBLIC (decl) && bss_initializer_p (decl))
+ return comm_section;
+ }
+
+ if (DECL_INITIAL (decl) == error_mark_node)
+ reloc = contains_pointers_p (TREE_TYPE (decl)) ? 3 : 0;
+ else if (DECL_INITIAL (decl))
+ reloc = compute_reloc_for_constant (DECL_INITIAL (decl));
+ else
+ reloc = 0;
+
+ resolve_unique_section (decl, reloc, flag_data_sections);
+ if (IN_NAMED_SECTION (decl))
+ return get_named_section (decl, NULL, reloc);
+
+ if (!DECL_THREAD_LOCAL_P (decl)
+ && !(prefer_noswitch_p && targetm.have_switchable_bss_sections)
+ && bss_initializer_p (decl))
+ {
+ if (!TREE_PUBLIC (decl))
+ return lcomm_section;
+ if (bss_noswitch_section)
+ return bss_noswitch_section;
+ }
+
+ return targetm.asm_out.select_section (decl, reloc, DECL_ALIGN (decl));
+}
+
+/* Return the block into which object_block DECL should be placed. */
+
+static struct object_block *
+get_block_for_decl (tree decl)
+{
+ section *sect;
if (TREE_CODE (decl) == VAR_DECL)
{
/* The object must be defined in this translation unit. */
if (DECL_EXTERNAL (decl))
- return false;
+ return NULL;
/* There's no point using object blocks for something that is
isolated by definition. */
if (DECL_ONE_ONLY (decl))
- return false;
-
- /* Symbols that use .common cannot be put into blocks. */
- if (DECL_COMMON (decl) && DECL_INITIAL (decl) == NULL)
- return false;
+ return NULL;
}
/* We can only calculate block offsets if the decl has a known
constant size. */
if (DECL_SIZE_UNIT (decl) == NULL)
- return false;
+ return NULL;
if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
- return false;
+ return NULL;
- /* Detect decls created by dw2_force_const_mem. Such decls are
- special because DECL_INITIAL doesn't specify the decl's true value.
- dw2_output_indirect_constants will instead call assemble_variable
- with dont_output_data set to 1 and then print the contents itself. */
- if (DECL_INITIAL (decl) == decl)
- return false;
+ /* Find out which section should contain DECL. We cannot put it into
+ an object block if it requires a standalone definition. */
+ sect = get_variable_section (decl, true);
+ if (SECTION_STYLE (sect) == SECTION_NOSWITCH)
+ return NULL;
- return true;
+ return get_block_for_section (sect);
}
-/* Make sure block symbol SYMBOL is in section SECT, moving it to a
- different block if necessary. */
+/* Make sure block symbol SYMBOL is in block BLOCK. */
static void
-change_symbol_section (rtx symbol, section *sect)
+change_symbol_block (rtx symbol, struct object_block *block)
{
- if (sect != SYMBOL_REF_BLOCK (symbol)->sect)
+ if (block != SYMBOL_REF_BLOCK (symbol))
{
gcc_assert (SYMBOL_REF_BLOCK_OFFSET (symbol) < 0);
- SYMBOL_REF_BLOCK (symbol) = get_block_for_section (sect);
+ SYMBOL_REF_BLOCK (symbol) = block;
}
}
-/* Return the section into which the given VAR_DECL or CONST_DECL
- should be placed. */
+/* Return true if it is possible to put DECL in an object_block. */
-static section *
-get_variable_section (tree decl)
+static bool
+use_blocks_for_decl_p (tree decl)
{
- int reloc;
+ /* Only data DECLs can be placed into object blocks. */
+ if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != CONST_DECL)
+ return false;
- if (DECL_INITIAL (decl) == error_mark_node)
- reloc = contains_pointers_p (TREE_TYPE (decl)) ? 3 : 0;
- else if (DECL_INITIAL (decl))
- reloc = compute_reloc_for_constant (DECL_INITIAL (decl));
- else
- reloc = 0;
+ /* Detect decls created by dw2_force_const_mem. Such decls are
+ special because DECL_INITIAL doesn't specify the decl's true value.
+ dw2_output_indirect_constants will instead call assemble_variable
+ with dont_output_data set to 1 and then print the contents itself. */
+ if (DECL_INITIAL (decl) == decl)
+ return false;
- resolve_unique_section (decl, reloc, flag_data_sections);
- if (IN_NAMED_SECTION (decl))
- return get_named_section (decl, NULL, reloc);
- else
- return targetm.asm_out.select_section (decl, reloc, DECL_ALIGN (decl));
+ return true;
}
/* Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL. DECL should
@@ -921,7 +991,7 @@ make_decl_rtl (tree decl)
if (MEM_P (x)
&& GET_CODE (XEXP (x, 0)) == SYMBOL_REF
&& SYMBOL_REF_IN_BLOCK_P (XEXP (x, 0)))
- change_symbol_section (XEXP (x, 0), get_variable_section (decl));
+ change_symbol_block (XEXP (x, 0), get_block_for_decl (decl));
/* Make this function static known to the mudflap runtime. */
if (flag_mudflap && TREE_CODE (decl) == VAR_DECL)
@@ -1020,10 +1090,7 @@ make_decl_rtl (tree decl)
DECL_COMMON (decl) = 0;
if (use_object_blocks_p () && use_blocks_for_decl_p (decl))
- {
- section *sect = get_variable_section (decl);
- x = create_block_symbol (name, get_block_for_section (sect), -1);
- }
+ x = create_block_symbol (name, get_block_for_decl (decl), -1);
else
x = gen_rtx_SYMBOL_REF (Pmode, name);
SYMBOL_REF_WEAK (x) = DECL_WEAK (decl);
@@ -1458,100 +1525,110 @@ assemble_string (const char *p, int size)
}
-#if defined ASM_OUTPUT_ALIGNED_DECL_LOCAL
-#define ASM_EMIT_LOCAL(decl, name, size, rounded) \
- ASM_OUTPUT_ALIGNED_DECL_LOCAL (asm_out_file, decl, name, size, DECL_ALIGN (decl))
-#else
-#if defined ASM_OUTPUT_ALIGNED_LOCAL
-#define ASM_EMIT_LOCAL(decl, name, size, rounded) \
- ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, DECL_ALIGN (decl))
+/* A noswitch_section_callback for lcomm_section. */
+
+static bool
+emit_local (tree decl ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED)
+{
+#if defined ASM_OUTPUT_ALIGNED_DECL_LOCAL
+ ASM_OUTPUT_ALIGNED_DECL_LOCAL (asm_out_file, decl, name,
+ size, DECL_ALIGN (decl));
+ return true;
+#elif defined ASM_OUTPUT_ALIGNED_LOCAL
+ ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, DECL_ALIGN (decl));
+ return true;
#else
-#define ASM_EMIT_LOCAL(decl, name, size, rounded) \
- ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded)
-#endif
+ ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
+ return false;
#endif
+}
+/* A noswitch_section_callback for bss_noswitch_section. */
+
+#if defined ASM_OUTPUT_ALIGNED_BSS || defined ASM_OUTPUT_BSS
+static bool
+emit_bss (tree decl ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED)
+{
#if defined ASM_OUTPUT_ALIGNED_BSS
-#define ASM_EMIT_BSS(decl, name, size, rounded) \
- ASM_OUTPUT_ALIGNED_BSS (asm_out_file, decl, name, size, DECL_ALIGN (decl))
-#else
-#if defined ASM_OUTPUT_BSS
-#define ASM_EMIT_BSS(decl, name, size, rounded) \
- ASM_OUTPUT_BSS (asm_out_file, decl, name, size, rounded)
+ ASM_OUTPUT_ALIGNED_BSS (asm_out_file, decl, name, size, DECL_ALIGN (decl));
+ return true;
#else
-#undef ASM_EMIT_BSS
+ ASM_OUTPUT_BSS (asm_out_file, decl, name, size, rounded);
+ return false;
#endif
+}
#endif
+/* A noswitch_section_callback for comm_section. */
+
+static bool
+emit_common (tree decl ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED)
+{
#if defined ASM_OUTPUT_ALIGNED_DECL_COMMON
-#define ASM_EMIT_COMMON(decl, name, size, rounded) \
- ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, decl, name, size, DECL_ALIGN (decl))
-#else
-#if defined ASM_OUTPUT_ALIGNED_COMMON
-#define ASM_EMIT_COMMON(decl, name, size, rounded) \
- ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size, DECL_ALIGN (decl))
+ ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, decl, name,
+ size, DECL_ALIGN (decl));
+ return true;
+#elif defined ASM_OUTPUT_ALIGNED_COMMON
+ ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size, DECL_ALIGN (decl));
+ return true;
#else
-#define ASM_EMIT_COMMON(decl, name, size, rounded) \
- ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded)
-#endif
+ ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
+ return false;
#endif
+}
+
+/* A noswitch_section_callback for tls_comm_section. */
static bool
-asm_emit_uninitialised (tree decl, const char *name,
- unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED,
- unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED)
+emit_tls_common (tree decl ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED)
{
- enum
- {
- asm_dest_common,
- asm_dest_bss,
- asm_dest_local
- }
- destination = asm_dest_local;
-
- /* ??? We should handle .bss via select_section mechanisms rather than
- via special target hooks. That would eliminate this special case. */
- if (TREE_PUBLIC (decl))
- {
- if (!DECL_COMMON (decl))
-#ifdef ASM_EMIT_BSS
- destination = asm_dest_bss;
+#ifdef ASM_OUTPUT_TLS_COMMON
+ ASM_OUTPUT_TLS_COMMON (asm_out_file, decl, name, size);
+ return true;
#else
- return false;
+ sorry ("thread-local COMMON data not implemented");
+ return true;
#endif
- else
- destination = asm_dest_common;
- }
+}
- if (destination != asm_dest_common)
- {
- resolve_unique_section (decl, 0, flag_data_sections);
- /* Custom sections don't belong here. */
- if (DECL_SECTION_NAME (decl))
- return false;
- }
+/* Assemble DECL given that it belongs in SECTION_NOSWITCH section SECT.
+ NAME is the name of DECL's SYMBOL_REF. */
- if (destination == asm_dest_bss)
- globalize_decl (decl);
+static void
+assemble_noswitch_variable (tree decl, const char *name, section *sect)
+{
+ unsigned HOST_WIDE_INT size, rounded;
- switch (destination)
- {
-#ifdef ASM_EMIT_BSS
- case asm_dest_bss:
- ASM_EMIT_BSS (decl, name, size, rounded);
- break;
-#endif
- case asm_dest_common:
- ASM_EMIT_COMMON (decl, name, size, rounded);
- break;
- case asm_dest_local:
- ASM_EMIT_LOCAL (decl, name, size, rounded);
- break;
- default:
- gcc_unreachable ();
- }
+ size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
+ rounded = size;
- return true;
+ /* Don't allocate zero bytes of common,
+ since that means "undefined external" in the linker. */
+ if (size == 0)
+ rounded = 1;
+
+ /* Round size up to multiple of BIGGEST_ALIGNMENT bits
+ so that each uninitialized object starts on such a boundary. */
+ rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
+ rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
+ * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
+
+ if (!sect->noswitch.callback (decl, name, size, rounded)
+ && (unsigned HOST_WIDE_INT) DECL_ALIGN_UNIT (decl) > rounded)
+ warning (0, "requested alignment for %q+D is greater than "
+ "implemented alignment of %wu", decl, rounded);
}
/* A subroutine of assemble_variable. Output the label and contents of
@@ -1602,8 +1679,8 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
{
const char *name;
unsigned int align;
- rtx decl_rtl;
- bool in_block_p;
+ rtx decl_rtl, symbol;
+ section *sect;
if (lang_hooks.decls.prepare_assemble_variable)
lang_hooks.decls.prepare_assemble_variable (decl);
@@ -1675,8 +1752,8 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
gcc_assert (MEM_P (decl_rtl));
gcc_assert (GET_CODE (XEXP (decl_rtl, 0)) == SYMBOL_REF);
- in_block_p = SYMBOL_REF_IN_BLOCK_P (XEXP (decl_rtl, 0));
- name = XSTR (XEXP (decl_rtl, 0), 0);
+ symbol = XEXP (decl_rtl, 0);
+ name = XSTR (symbol, 0);
if (TREE_PUBLIC (decl) && DECL_NAME (decl))
notice_global_symbol (decl);
@@ -1724,70 +1801,11 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
if (DECL_PRESERVE_P (decl))
targetm.asm_out.mark_decl_preserved (name);
- /* Handle uninitialized definitions. */
-
- /* If the decl has been given an explicit section name, then it
- isn't common, and shouldn't be handled as such. */
- if (DECL_SECTION_NAME (decl) || dont_output_data)
- ;
- else if (DECL_THREAD_LOCAL_P (decl))
- {
- if (DECL_COMMON (decl))
- {
-#ifdef ASM_OUTPUT_TLS_COMMON
- unsigned HOST_WIDE_INT size;
-
- size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
- ASM_OUTPUT_TLS_COMMON (asm_out_file, decl, name, size);
- return;
-#else
- sorry ("thread-local COMMON data not implemented");
-#endif
- }
- }
- /* Do not handle decls as common if they will be assigned a
- specific section position. */
- else if (in_block_p)
- ;
- else if (DECL_INITIAL (decl) == 0
- || DECL_INITIAL (decl) == error_mark_node
- || (flag_zero_initialized_in_bss
- /* Leave constant zeroes in .rodata so they can be shared. */
- && !TREE_READONLY (decl)
- && initializer_zerop (DECL_INITIAL (decl))))
- {
- unsigned HOST_WIDE_INT size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
- unsigned HOST_WIDE_INT rounded = size;
-
- /* Don't allocate zero bytes of common,
- since that means "undefined external" in the linker. */
- if (size == 0)
- rounded = 1;
-
- /* Round size up to multiple of BIGGEST_ALIGNMENT bits
- so that each uninitialized object starts on such a boundary. */
- rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
- rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
- * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
-
-#if !defined(ASM_OUTPUT_ALIGNED_COMMON) && !defined(ASM_OUTPUT_ALIGNED_DECL_COMMON) && !defined(ASM_OUTPUT_ALIGNED_BSS)
- if ((unsigned HOST_WIDE_INT) DECL_ALIGN_UNIT (decl) > rounded)
- warning (0, "requested alignment for %q+D is greater than "
- "implemented alignment of %wu", decl, rounded);
-#endif
-
- /* If the target cannot output uninitialized but not common global data
- in .bss, then we have to use .data, so fall through. */
- if (asm_emit_uninitialised (decl, name, size, rounded))
- return;
- }
-
- /* Handle initialized definitions.
- Also handle uninitialized global definitions if -fno-common and the
- target doesn't support ASM_OUTPUT_BSS. */
-
/* First make the assembler name(s) global if appropriate. */
- if (TREE_PUBLIC (decl) && DECL_NAME (decl))
+ sect = get_variable_section (decl, false);
+ if (TREE_PUBLIC (decl)
+ && DECL_NAME (decl)
+ && (sect->common.flags & SECTION_COMMON) == 0)
globalize_decl (decl);
/* Output any data that we will need to use the address of. */
@@ -1801,14 +1819,16 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
/* If the decl is part of an object_block, make sure that the decl
has been positioned within its block, but do not write out its
definition yet. output_object_blocks will do that later. */
- if (in_block_p)
+ if (SYMBOL_REF_IN_BLOCK_P (symbol) && SYMBOL_REF_BLOCK (symbol))
{
gcc_assert (!dont_output_data);
- place_block_symbol (XEXP (decl_rtl, 0));
+ place_block_symbol (symbol);
}
+ else if (SECTION_STYLE (sect) == SECTION_NOSWITCH)
+ assemble_noswitch_variable (decl, name, sect);
else
{
- switch_to_section (get_variable_section (decl));
+ switch_to_section (sect);
if (align > BITS_PER_UNIT)
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DECL_ALIGN_UNIT (decl)));
assemble_variable_contents (decl, name, dont_output_data);
@@ -2927,7 +2947,7 @@ output_constant_def_contents (rtx symbol)
/* If the constant is part of an object block, make sure that the
decl has been positioned within its block, but do not write out
its definition yet. output_object_blocks will do that later. */
- if (SYMBOL_REF_IN_BLOCK_P (symbol))
+ if (SYMBOL_REF_IN_BLOCK_P (symbol) && SYMBOL_REF_BLOCK (symbol))
place_block_symbol (symbol);
else
{
@@ -3488,7 +3508,7 @@ output_constant_pool (const char *fnname ATTRIBUTE_UNUSED,
the constant has been positioned within its block, but do not
write out its definition yet. output_object_blocks will do
that later. */
- if (SYMBOL_REF_IN_BLOCK_P (desc->sym))
+ if (SYMBOL_REF_IN_BLOCK_P (desc->sym) && SYMBOL_REF_BLOCK (desc->sym))
place_block_symbol (desc->sym);
else
{
@@ -5085,6 +5105,18 @@ init_varasm_once (void)
SBSS_SECTION_ASM_OP);
#endif
+ tls_comm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+ | SECTION_COMMON, emit_tls_common);
+ lcomm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+ | SECTION_COMMON, emit_local);
+ comm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+ | SECTION_COMMON, emit_common);
+
+#if defined ASM_OUTPUT_ALIGNED_BSS || defined ASM_OUTPUT_BSS
+ bss_noswitch_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS,
+ emit_bss);
+#endif
+
targetm.asm_out.init_sections ();
if (readonly_data_section == NULL)
@@ -5191,6 +5223,16 @@ default_section_type_flags_1 (tree decl, const char *name, int reloc,
return flags;
}
+/* Return true if the target supports some form of global BSS,
+ either through bss_noswitch_section, or by selecting a BSS
+ section in TARGET_ASM_SELECT_SECTION. */
+
+bool
+have_global_bss_p (void)
+{
+ return bss_noswitch_section || targetm.have_switchable_bss_sections;
+}
+
/* Output assembly to switch to section NAME with attribute FLAGS.
Four variants for common object file formats. */
@@ -5344,12 +5386,7 @@ categorize_decl_for_section (tree decl, int reloc, int shlib)
}
else if (TREE_CODE (decl) == VAR_DECL)
{
- if (DECL_INITIAL (decl) == NULL
- || DECL_INITIAL (decl) == error_mark_node
- || (flag_zero_initialized_in_bss
- /* Leave constant zeroes in .rodata so they can be shared. */
- && !TREE_READONLY (decl)
- && initializer_zerop (DECL_INITIAL (decl))))
+ if (bss_initializer_p (decl))
ret = SECCAT_BSS;
else if (! TREE_READONLY (decl)
|| TREE_SIDE_EFFECTS (decl)
@@ -5888,8 +5925,9 @@ switch_to_section (section *new_section)
else
in_section = new_section;
- if (new_section->common.flags & SECTION_NAMED)
+ switch (SECTION_STYLE (new_section))
{
+ case SECTION_NAMED:
if (cfun
&& !cfun->unlikely_text_section_name
&& strcmp (new_section->named.name,
@@ -5899,9 +5937,16 @@ switch_to_section (section *new_section)
targetm.asm_out.named_section (new_section->named.name,
new_section->named.common.flags,
new_section->named.decl);
+ break;
+
+ case SECTION_UNNAMED:
+ new_section->unnamed.callback (new_section->unnamed.data);
+ break;
+
+ case SECTION_NOSWITCH:
+ gcc_unreachable ();
+ break;
}
- else
- new_section->unnamed.callback (new_section->unnamed.data);
new_section->common.flags |= SECTION_DECLARED;
}
@@ -5918,6 +5963,7 @@ place_block_symbol (rtx symbol)
struct object_block *block;
tree decl;
+ gcc_assert (SYMBOL_REF_BLOCK (symbol));
if (SYMBOL_REF_BLOCK_OFFSET (symbol) >= 0)
return;