diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 22056f260a22a29c6b1354fcb36362161c11b061..bd9ce0f9dc280632297b87558ad6ac07cacd6eec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2002-03-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * Makefile.in (CRTSTUFF_CFLAGS): Add -fno-zero-initialized-in-bss. + * doc/invoke.texi (-fno-zero-initialized-in-bss): Document. + * flags.h (flag_zero_initialized_in_bss): Declare. + * toplev.c (flag_zero_initialized_in_bss): New flag. + (lang_independent_options): Add flag_zero_initialized_in_bss. + * tree.c (initializer_zerop): New function. + * tree.h (initializer_zerop): Declare. + * varasm.c (assemble_variable): If we can emit bss, put zero + initializers in the bss section. + 2002-03-02 Alan Modra <amodra@bigpond.net.au> * config/rs6000/rs6000.h (ASM_WEAKEN_DECL): AIX assembler doesn't diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 604dd7dd8ff00707601b5469ec25df02bd6e1066..5d1802f174495bec352027b95ec12513b69fba1b 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -372,7 +372,8 @@ TARGET_LIBGCC2_CFLAGS = # Options to use when compiling crtbegin/end. CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ - -finhibit-size-directive -fno-inline-functions -fno-exceptions + -finhibit-size-directive -fno-inline-functions -fno-exceptions \ + -fno-zero-initialized-in-bss # Additional sources to handle exceptions; overridden on ia64. LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 8dab7a0f3a8004eaaef4b5ef021d2c0f2950b4dd..10b69c846d02612e3b8a403ab724020fe3aac665 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -273,6 +273,7 @@ in the following sections. -fno-function-cse -fno-guess-branch-probability @gol -fno-inline -fno-math-errno -fno-peephole -fno-peephole2 @gol -funsafe-math-optimizations -fno-trapping-math @gol +-fno-zero-initialized-in-bss @gol -fomit-frame-pointer -foptimize-register-move @gol -foptimize-sibling-calls -fprefetch-loop-arrays @gol -freduce-all-givs -fregmove -frename-registers @gol @@ -3407,6 +3408,19 @@ an exact implementation of IEEE or ISO rules/specifications for math functions. The default is @option{-ftrapping-math}. + +@item -fno-zero-initialized-in-bss +@opindex fno-zero-initialized-in-bss +If the target supports a BSS section, GCC by default puts variables that +are initialized to zero into BSS@. This can save space in the resulting +code. + +This option turns off this behavior because some programs explicitly +rely on variables going to the data section. E.g., so that the +resulting executable can find the beginning of that section and/or make +assumptions based on that. + +The default is @option{-fzero-initialized-in-bss}. @end table The following options control specific optimizations. The @option{-O2} diff --git a/gcc/flags.h b/gcc/flags.h index 65353e61677f71b9b3deb2aa7bec16ce5d631fa3..6de5d9b59574e8fb46832c7b30def13fdec056cd 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -636,4 +636,7 @@ extern int flag_detailed_statistics; /* Nonzero means enable synchronous exceptions for non-call instructions. */ extern int flag_non_call_exceptions; +/* Nonzero means put zero initialized data in the bss section. */ +extern int flag_zero_initialized_in_bss; + #endif /* ! GCC_FLAGS_H */ diff --git a/gcc/toplev.c b/gcc/toplev.c index 83de90890ec1781ea8ba4a739d615917ef0bb961..74605824da8cea678ba10b1bdc38b5ae4e7bf5a7 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -803,6 +803,9 @@ int flag_gnu_linker = 0; int flag_gnu_linker = 1; #endif +/* Nonzero means put zero initialized data in the bss section. */ +int flag_zero_initialized_in_bss = 1; + /* Enable SSA. */ int flag_ssa = 0; @@ -1135,6 +1138,8 @@ static const lang_independent_options f_options[] = N_("Suppress output of instruction numbers and line number notes in debugging dumps") }, {"instrument-functions", &flag_instrument_function_entry_exit, 1, N_("Instrument function entry/exit with profiling calls") }, + {"zero-initialized-in-bss", &flag_zero_initialized_in_bss, 1, + N_("Put zero initialized data in the bss section") }, {"ssa", &flag_ssa, 1, N_("Enable SSA optimizations") }, {"ssa-ccp", &flag_ssa_ccp, 1, diff --git a/gcc/tree.c b/gcc/tree.c index 5e0210b7676f5413aba751cebf6548cdf6979ab7..de65191e672135ca4b91cb8271d3d2426dee68da 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -4975,3 +4975,45 @@ make_vector (mode, innertype, unsignedp) return t; } + +/* Given an initializer INIT, return TRUE if INIT is zero or some + aggregate of zeros. Otherwise return FALSE. */ + +bool +initializer_zerop (init) + tree init; +{ + STRIP_NOPS (init); + + switch (TREE_CODE (init)) + { + case INTEGER_CST: + return integer_zerop (init); + case REAL_CST: + return real_zerop (init) + && ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (init)); + case COMPLEX_CST: + return integer_zerop (init) + || (real_zerop (init) + && ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_REALPART (init))) + && ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_IMAGPART (init)))); + case CONSTRUCTOR: + { + if (AGGREGATE_TYPE_P (TREE_TYPE (init))) + { + tree aggr_init = TREE_OPERAND (init, 1); + + while (aggr_init) + { + if (! initializer_zerop (TREE_VALUE (aggr_init))) + return false; + aggr_init = TREE_CHAIN (aggr_init); + } + return true; + } + return false; + } + default: + return false; + } +} diff --git a/gcc/tree.h b/gcc/tree.h index b13fc53cdb5397a69cce7035a03f76bc957266ac..68b96e8258771c40467cbf32a89a357a65dfee8b 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2495,6 +2495,11 @@ extern int list_length PARAMS ((tree)); extern int fields_length PARAMS ((tree)); +/* Given an initializer INIT, return TRUE if INIT is zero or some + aggregate of zeros. Otherwise return FALSE. */ + +extern bool initializer_zerop PARAMS ((tree)); + /* integer_zerop (tree x) is nonzero if X is an integer constant of value 0 */ extern int integer_zerop PARAMS ((tree)); diff --git a/gcc/varasm.c b/gcc/varasm.c index f8fb16cc88032dd6553963298fc2261be0e893d0..e7505a8c39cd93913726cd1f4eea197048eea65b 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -1608,7 +1608,12 @@ assemble_variable (decl, top_level, at_end, dont_output_data) /* Handle uninitialized definitions. */ - if ((DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node) + if ((DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node +#if defined ASM_EMIT_BSS + || (flag_zero_initialized_in_bss + && initializer_zerop (DECL_INITIAL (decl))) +#endif + ) /* If the target can't output uninitialized but not common global data in .bss, then we have to use .data. */ #if ! defined ASM_EMIT_BSS