[m-rev.] preliminary review: Removing dead code at link time.

Peter Wang novalazy at gmail.com
Fri Aug 8 11:12:10 AEST 2014


Hi,

After making this patch I remembered to check what to do on OS X.
It seems there you only need to pass -dead_strip to the linker,
so the --split-sections flag is specific to Linux or ELF targets.

We could drop most of this patch and just build the standard library
and runtime with `-ffunction-sections -fdata-sections' where it helps,
and leave it to the user to pass the correct linker flag if they care.

---

This patch makes it more convenient to reduce executable sizes,
using the gcc and clang options `-ffunction-sections -fdata-sections'
and the linker option `--gc-sections'.  The former places functions and
data into their own sections in object files so they can be removed
individually; the latter performs the removal.

We introduce a Mercury compiler and mgnuc flag `--split-sections'
which passes `-ffunction-sections -fdata-sections' to the C compiler.
It is off by default because it makes the object files larger and most
user code would hopefully not see much benefit from it.  There are some
warnings about problems with gprof or debugging in the gcc manual.

We introduce a Mercury compiler and ml flag `--gc-sections' which passes
`-Wl,--gc-sections' through to the linker.  It is off by default, as it
makes linking noticeably slower.

We enable `--split-sections' when building the runtime and standard
library.

On Linux/x86-64, `hello' goes from 4.1 MiB to 663 KiB in size
and `mercury_compile' goes from 16 MiB to 13 MiB.
(both statically linked to the Mercury libraries and stripped)

configure.ac:
scripts/Mercury.config.in:
	Set CFLAGS_FOR_SPLIT_SECTIONS for gcc or clang.  gcc has
	supported `-ffunction-sections -fdata-sections' since at least
	2.95.3, and clang as of 2010, so probably long enough.

	Set LD_GC_SECTIONS_FLAG after testing if "-Wl,--gc-sections"
	works.
	XXX -dead_strip on Darwin?

compiler/options.m:
	Add options `--split-sections', `--cflags-for-split-sections',
	`--gc-sections' `--linker-gc-sections-flag'.

compiler/compile_target_code.m:
	Handle `--split-sections' when generating object files.

	Handle `--gc-sections' when linking executables or shared
	libraries.

scripts/mgnuc.in:
scripts/mgnuc_file_opts.sh-subr:
scripts/ml.in:
scripts/parse_ml_options.sh-subr.in:
	Add new options.

library/Mmakefile:
runtime/Mmakefile:
	Build with mgnuc --split-sections in these directories.

doc/user_guide.texi:
	Document new options.

	Fix a typo.

NEWS:
	Announce the change.
---
 NEWS                                |  5 +++++
 compiler/compile_target_code.m      | 22 ++++++++++++++++++++
 compiler/options.m                  | 26 +++++++++++++++++++++--
 configure.ac                        | 41 ++++++++++++++++++++++++++++++++-----
 doc/user_guide.texi                 | 16 ++++++++++++++-
 library/Mmakefile                   |  9 ++++++++
 runtime/Mmakefile                   |  2 +-
 scripts/Mercury.config.in           |  2 ++
 scripts/mgnuc.in                    |  5 +++--
 scripts/mgnuc_file_opts.sh-subr     |  5 +++++
 scripts/ml.in                       | 10 ++++++++-
 scripts/parse_ml_options.sh-subr.in |  6 ++++++
 12 files changed, 137 insertions(+), 12 deletions(-)

diff --git a/NEWS b/NEWS
index ff33f20..dac39ed 100644
--- a/NEWS
+++ b/NEWS
@@ -49,6 +49,11 @@ Changes to the Mercury compiler:
 * We configure Boehm GC to use mmap in threaded grades on Linux to avoid
   conflicts with glibc malloc leading to memory corruption.
 
+* We have added the options --split-sections and --gc-sections for reducing
+  executable sizes, corresponding to the gcc and clang options
+  -ffunction-sections -fdata-sections, and the linker option --gc-sections.
+  The standard library and runtime are built with --split-sections.
+
 Changes to the extras distribution:
 
 * We have added support for Unicode and other enhancements to the lex and
diff --git a/compiler/compile_target_code.m b/compiler/compile_target_code.m
index 55c00c9..85db33f 100644
--- a/compiler/compile_target_code.m
+++ b/compiler/compile_target_code.m
@@ -574,6 +574,15 @@ gather_c_compiler_flags(Globals, PIC, AllCFlags) :-
         Warn = no,
         WarningOpt = ""
     ),
+    globals.lookup_bool_option(Globals, split_sections, SplitSections),
+    (
+        SplitSections = yes,
+        globals.lookup_string_option(Globals, cflags_for_split_sections,
+            SplitSectionsOpts)
+    ;
+        SplitSections = no,
+        SplitSectionsOpts = ""
+    ),
 
     % The -floop-optimize option is incompatible with the global
     % register code we generate on Darwin PowerPC.
@@ -630,6 +639,7 @@ gather_c_compiler_flags(Globals, PIC, AllCFlags) :-
         AppleGCCRegWorkaroundOpt,
         C_FnAlignOpt,
         WarningOpt, " ",
+        SplitSectionsOpts, " ",
         CFLAGS, " ",
         CC_Specific_CFLAGS, " ",
         OverrideOpts], AllCFlags).
@@ -1929,6 +1939,17 @@ link_exe_or_shared_lib(Globals, ErrorStream, LinkTargetType, ModuleName,
         ReserveStackSizeOpt = reserve_stack_size_flags(Globals)
     ),
 
+    % Garbage collect unused sections in object files?
+    globals.lookup_bool_option(Globals, gc_sections, GcSections),
+    (
+        GcSections = yes,
+        globals.lookup_string_option(Globals, linker_gc_sections_flag,
+            LinkerGcSectionsOpt)
+    ;
+        GcSections = no,
+        LinkerGcSectionsOpt = ""
+    ),
+
     % Should the executable be stripped?
     globals.lookup_bool_option(Globals, strip, Strip),
     (
@@ -2099,6 +2120,7 @@ link_exe_or_shared_lib(Globals, ErrorStream, LinkTargetType, ModuleName,
             string.append_list([
                     Command, " ",
                     StaticOpts, " ",
+                    LinkerGcSectionsOpt, " ",
                     LinkerStripOpt, " ",
                     UndefOpt, " ",
                     ThreadOpts, " ",
diff --git a/compiler/options.m b/compiler/options.m
index 849fd69..be850d9 100644
--- a/compiler/options.m
+++ b/compiler/options.m
@@ -820,6 +820,7 @@
     ;       c_optimize
     ;       ansi_c
     ;       inline_alloc
+    ;       split_sections
 
     % Flags for specific C compilers.
     ;       gcc_flags
@@ -838,6 +839,7 @@
     ;       cflags_for_threads
     ;       cflags_for_debug
     ;       cflags_for_pic
+    ;       cflags_for_split_sections
     ;       c_flag_to_name_object_file
     ;       object_file_extension
     ;       pic_object_file_extension
@@ -902,6 +904,7 @@
     ;       linkage_special
     ;       mercury_linkage
     ;       mercury_linkage_special
+    ;       gc_sections
     ;       strip
     ;       demangle
     ;       main
@@ -941,6 +944,7 @@
     ;       linker_thread_flags
     ;       shlib_linker_thread_flags
     ;       linker_static_flags
+    ;       linker_gc_sections_flag
     ;       linker_strip_flag
     ;       linker_link_lib_flag
     ;       linker_link_lib_suffix
@@ -1708,6 +1712,7 @@ option_defaults_2(target_code_compilation_option, [
     c_optimize                          -   bool(no),
     ansi_c                              -   bool(yes),
     inline_alloc                        -   bool(no),
+    split_sections                      -   bool(no),
     cflags                              -   accumulating([]),
     quoted_cflag                        -   string_special,
 
@@ -1729,6 +1734,7 @@ option_defaults_2(target_code_compilation_option, [
     cflags_for_threads                  -   string(""),
     cflags_for_debug                    -   string("-g"),
     cflags_for_pic                      -   string(""),
+    cflags_for_split_sections           -   string(""),
     c_flag_to_name_object_file          -   string("-o "),
     object_file_extension               -   string(".o"),
     pic_object_file_extension           -   string(".o"),
@@ -1805,6 +1811,7 @@ option_defaults_2(link_option, [
     mercury_linkage                     -   string("shared"),
     mercury_linkage_special             -   string_special,
     demangle                            -   bool(yes),
+    gc_sections                         -   bool(no),
     strip                               -   bool(yes),
     main                                -   bool(yes),
     allow_undefined                     -   bool(yes),
@@ -1849,6 +1856,7 @@ option_defaults_2(link_option, [
     linker_thread_flags                 -   string(""),
     shlib_linker_thread_flags           -   string(""),
     linker_static_flags                 -   string("-static"),
+    linker_gc_sections_flag             -   string(""),
     linker_strip_flag                   -   string("-s"),
     linker_link_lib_flag                -   string("-l"),
     linker_link_lib_suffix              -   string(""),
@@ -2668,6 +2676,7 @@ long_option("procs-per-C-function", procs_per_c_function).
 long_option("everything-in-one-c-function", everything_in_one_c_function).
 long_option("everything-in-one-C-function", everything_in_one_c_function).
 long_option("inline-alloc",         inline_alloc).
+long_option("split-sections",       split_sections).
 long_option("local-thread-engine-base", local_thread_engine_base).
 
 % Erlang
@@ -2705,6 +2714,7 @@ long_option("cflags-for-gotos",     cflags_for_gotos).
 long_option("cflags-for-threads",   cflags_for_threads).
 long_option("cflags-for-debug",     cflags_for_debug).
 long_option("cflags-for-pic",       cflags_for_pic).
+long_option("cflags-for-split-sections", cflags_for_split_sections).
 long_option("c-flag-to-name-object-file", c_flag_to_name_object_file).
 long_option("object-file-extension",    object_file_extension).
 long_option("pic-object-file-extension", pic_object_file_extension).
@@ -2777,6 +2787,7 @@ long_option("trace-init-file",      trace_init_files).
 long_option("linkage",              linkage_special).
 long_option("mercury-linkage",      mercury_linkage_special).
 long_option("demangle",             demangle).
+long_option("gc-sections",          gc_sections).
 long_option("strip",                strip).
 long_option("main",                 main).
 long_option("allow-undefined",      allow_undefined).
@@ -2821,6 +2832,7 @@ long_option("shlib-linker-trace-flags", shlib_linker_trace_flags).
 long_option("linker-thread-flags",  linker_thread_flags).
 long_option("shlib-linker-thread-flags", shlib_linker_thread_flags).
 long_option("linker-static-flags",  linker_static_flags).
+long_option("linker-gc-sections-flag", linker_gc_sections_flag).
 long_option("linker-strip-flag",    linker_strip_flag).
 long_option("linker-link-lib-flag", linker_link_lib_flag).
 long_option("linker-link-lib-suffix",   linker_link_lib_suffix).
@@ -5476,6 +5488,10 @@ options_help_target_code_compilation -->
         "\tThis option has no effect if `--gc boehm'",
         "\tis not set or if the C compiler is not GNU C.",
 
+        "--split-sections",
+        "\tTell the C compiler to place each function or data item into",
+        "\tits own section in the object file.",
+
         "--cflags <options>, --cflag <option>",
         "\tSpecify options to be passed to the C compiler.",
         "\t`--cflag' should be used for single words which need",
@@ -5489,7 +5505,8 @@ options_help_target_code_compilation -->
         % The --cflags-for-regs, --cflags-for-gotos,
         % --cflags-for-threads, --cflags-for-pic,
         % --cflags-for-warnings, --cflags-for-ansi,
-        % --cflags-for-optimization, --c-flag-to-name-object-file,
+        % --cflags-for-optimization, --cflags-for-split-sections,
+        % --c-flag-to-name-object-file,
         % --object-file-extension, --pic-object-file-extension
         % and --link-with-pic-object-file-extension
         % options are reserved for use by the `mmc' script;
@@ -5668,6 +5685,10 @@ options_help_link -->
         "\tSpecify the command used to invoke the linker when linking",
         "\ta shared library.",
 
+        "--gc-sections",
+        "\tTell the linker to garbage collect unused input sections in",
+        "\tobject files.",
+
         "--no-strip",
         "\tDo not strip executables.",
         "--strip-executable-command <command>",
@@ -5714,7 +5735,8 @@ options_help_link -->
         % --linker-debug-flags, --shlib-linker-debug-flags,
         % --linker-trace-flags, --shlib-linker-trace-flags,
         % --linker-thread-flags, --shlib-linker-thread-flags,
-        % --linker-static-flags, --linker-strip-flag,
+        % --linker-static-flags, --linker-gc-sections-flag,
+        % --linker-strip-flag,
         % --linker-link-lib-flag, --linker-link-lib-suffix,
         % --shlib-linker-link-lib-flag, --shlib-linker-link-lib-suffix,
         % --linker-path-flag, --linker-link-with-lib-flag,
diff --git a/configure.ac b/configure.ac
index b0c8183..35f81f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1164,6 +1164,7 @@ AC_SUBST(LD_STRIP_FLAG)
 AC_SUBST(STRIP_EXE)
 AC_SUBST(STRIP_EXE_SHARED_FLAGS)
 AC_SUBST(STRIP_EXE_STATIC_FLAGS)
+AC_SUBST(LD_GC_SECTIONS_FLAG)
 AC_SUBST(LDFLAGS_FOR_TRACE)
 AC_SUBST(LD_LIBFLAGS_FOR_TRACE)
 AC_SUBST(USING_MICROSOFT_CL_COMPILER)
@@ -4554,6 +4555,7 @@ case "$mercury_cv_cc_type" in
 
         CFLAGS_FOR_DEBUG="-g"
         CFLAGS_FOR_NO_STRICT_ALIASING="-fno-strict-aliasing"
+        CFLAGS_FOR_SPLIT_SECTIONS="-ffunction-sections -fdata-sections"
         MCFLAGS_FOR_CC=
         ;;
 
@@ -4566,6 +4568,7 @@ case "$mercury_cv_cc_type" in
         CFLAGS_FOR_OPT=
         CFLAGS_FOR_DEBUG="-g"
         CFLAGS_FOR_NO_STRICT_ALIASING=
+        CFLAGS_FOR_SPLIT_SECTIONS=
         MCFLAGS_FOR_CC=
         ;;
 
@@ -4592,6 +4595,7 @@ case "$mercury_cv_cc_type" in
         esac
         CFLAGS_FOR_DEBUG="-g"
         CFLAGS_FOR_NO_STRICT_ALIASING="-fno-strict-aliasing"
+        CFLAGS_FOR_SPLIT_SECTIONS="-ffunction-sections -fdata-sections"
         MCFLAGS_FOR_CC=
         ;;
 
@@ -4604,6 +4608,7 @@ case "$mercury_cv_cc_type" in
         #CFLAGS_FOR_DEBUG="-Zi"
         CFLAGS_FOR_DEBUG=
         CFLAGS_FOR_NO_STRICT_ALIASING=
+        CFLAGS_FOR_SPLIT_SECTIONS=
 
         # Using the MSVC compiler implies that we must use
         # a maximum jump table size of 512 to avoid a fixed limit
@@ -4617,6 +4622,7 @@ case "$mercury_cv_cc_type" in
         CFLAGS_FOR_WARNINGS=
         CFLAGS_FOR_DEBUG="-g"
         CFLAGS_FOR_NO_STRICT_ALIASING=
+        CFLAGS_FOR_SPLIT_SECTIONS=
         MCFLAGS_FOR_CC=
         ;;
 esac
@@ -4628,6 +4634,7 @@ AC_SUBST([CFLAGS_FOR_WARNINGS])
 AC_SUBST([CFLAGS_FOR_OPT])
 AC_SUBST([CFLAGS_FOR_DEBUG])
 AC_SUBST([CFLAGS_FOR_NO_STRICT_ALIASING])
+AC_SUBST([CFLAGS_FOR_SPLIT_SECTIONS])
 AC_SUBST([MCFLAGS_FOR_CC])
 AC_SUBST([OPT_FLAGS_FOR_CLANG])
 AC_SUBST([C_COMPILER_TYPE])
@@ -4639,11 +4646,13 @@ AC_SUBST([C_COMPILER_TYPE])
 
 # Note that changes here may require changes in scripts/ml.in.
 
-LD_STATIC_FLAGS=
 case "$C_COMPILER_TYPE" in
     gcc*|clang*|lcc)
         LD_STATIC_FLAGS=-static
         ;;
+    *)
+        LD_STATIC_FLAGS=
+        ;;
 esac
 case "$FULLARCH" in
     *-linux*)
@@ -4652,10 +4661,7 @@ case "$FULLARCH" in
         # to _DYNAMIC in boehm_gc/dyn_load.c. (We might eventually need
         # similar treatment for other OSs too.)
         case "$C_COMPILER_TYPE" in
-            gcc*)
-                LD_STATIC_FLAGS="-static -Wl,-defsym -Wl,_DYNAMIC=0"
-                ;;
-            clang*)
+            gcc*|clang*)
                 LD_STATIC_FLAGS="-static -Wl,-defsym -Wl,_DYNAMIC=0"
                 ;;
             lcc)
@@ -4701,6 +4707,31 @@ case "$LD_STATIC_FLAGS" in
 esac
 
 #-----------------------------------------------------------------------------#
+#
+# Work out how to tell the linker to GC unused sections
+#
+
+case "$C_COMPILER_TYPE" in
+    gcc*|clang*)
+        LD_GC_SECTIONS_FLAG="-Wl,--gc-sections"
+        AC_MSG_CHECKING([whether we can use $LD_GC_SECTIONS_FLAG])
+        rm -f conftest*
+        echo "int main() { return 0; }" > conftest.c
+        if $CC $LD_GC_SECTIONS_FLAG conftest.c >&AC_FD_CC 2>&1
+        then
+            AC_MSG_RESULT(yes)
+        else
+            AC_MSG_RESULT(no)
+            LD_STATIC_FLAGS=""
+        fi
+        rm -f conftest*
+        ;;
+    *)
+        LD_GC_SECTIONS_FLAG=""
+        ;;
+esac
+
+#-----------------------------------------------------------------------------#
 
 case "$host" in
     *-cygwin*)
diff --git a/doc/user_guide.texi b/doc/user_guide.texi
index addcfac..051dccb 100644
--- a/doc/user_guide.texi
+++ b/doc/user_guide.texi
@@ -9339,6 +9339,13 @@ This option has no effect if @samp{--gc boehm}
 is not set or if the C compiler is not GNU C.
 
 @sp 1
+ at item --split-sections
+ at findex --split-sections
+Tell the C compiler to place each function or data item into
+its own section in the object file.
+This option has no effect if the C compiler is not GNU C or clang.
+
+ at sp 1
 @item --cflags @var{options}
 @item --cflag @var{option}
 @findex --cflags
@@ -9682,6 +9689,13 @@ Specify the command used to invoke the linker when linking an executable.
 Specify the command used to invoke the linker when linking a shared library.
 
 @sp 1
+ at item --gc-sections
+ at findex --gc-sections
+Tell the linker to garbage collect unused input sections in object files
+if supported.
+(This option has nothing to do with the Mercury garbage collector.)
+
+ at sp 1
 @item --no-strip
 @findex --no-strip
 Do not strip executables.
@@ -9699,7 +9713,7 @@ Specify options to pass to the strip executable command when
 linking against Mercury shared libraries.
 
 @sp 1
- at item --stripe-executable-static-flags @var{options}
+ at item --strip-executable-static-flags @var{options}
 @findex --strip-executable-static-flags
 Specify options to pass to the strip executable command when
 linking against Mercury static libraries.
diff --git a/library/Mmakefile b/library/Mmakefile
index aa82668..bb82213 100644
--- a/library/Mmakefile
+++ b/library/Mmakefile
@@ -116,6 +116,13 @@ MCFLAGS      += -R$(FINAL_INSTALL_MERC_LIB_DIR) \
 		-R$(FINAL_INSTALL_MERC_GC_LIB_DIR)
 endif
 
+# For mmc --make we need to wait for --split-sections to be accepted
+# by the bootstrap compiler.
+MGNUCFLAGS += --split-sections
+# MCFLAGS += --split-sections
+
+#-----------------------------------------------------------------------------#
+
 # Let javac find jmercury/runtime/*.java files.
 JAVACFLAGS   += -sourcepath .
 
@@ -127,6 +134,8 @@ ifneq ("$(findstring -J-Xmx,$(JAVACFLAGS))","")
 JAVACFLAGS   += -J-Xmx512m
 endif
 
+#-----------------------------------------------------------------------------#
+
 MTAGS	= $(SCRIPTS_DIR)/mtags
 
 LN	= ln
diff --git a/runtime/Mmakefile b/runtime/Mmakefile
index 7935d7d..daf8632 100644
--- a/runtime/Mmakefile
+++ b/runtime/Mmakefile
@@ -243,7 +243,7 @@ CFLAGS	+= $(DLL_CFLAGS)
 # in the runtime can be debugged without having to recompile it.  The cost
 # of doing this is negligible.  The runtime can be compiled without
 # debugging enabled by removing the `--c-debug' flag below.
-MGNUCFLAGS	+= --c-debug --no-ansi
+MGNUCFLAGS	+= --c-debug --no-ansi --split-sections
 
 #-----------------------------------------------------------------------------#
 
diff --git a/scripts/Mercury.config.in b/scripts/Mercury.config.in
index 5ff6f6c..b045177 100644
--- a/scripts/Mercury.config.in
+++ b/scripts/Mercury.config.in
@@ -71,6 +71,7 @@ DEFAULT_MCFLAGS=\
 		--cflags-for-regs "@CFLAGS_FOR_REGS@" \
 		--cflags-for-gotos "@CFLAGS_FOR_GOTOS@" \
 		--cflags-for-pic "@CFLAGS_FOR_PIC@" \
+		--cflags-for-split-sections "@CFLAGS_FOR_SPLIT_SECTIONS@" \
 		--c-flag-to-name-object-file "@OBJFILE_OPT@" \
 		--java-flags "@JAVAC_FLAGS_FOR_HEAP_SIZE@" \
 		--object-file-extension ". at OBJ_SUFFIX@" \
@@ -102,6 +103,7 @@ DEFAULT_MCFLAGS=\
 		--linker-trace-flags "@LDFLAGS_FOR_TRACE@" \
 		--shlib-linker-trace-flags "@LD_LIBFLAGS_FOR_TRACE@" \
 		--linker-static-flags "@LD_STATIC_FLAGS@" \
+		--linker-gc-sections-flag "@LD_GC_SECTIONS_FLAG@" \
 		--linker-strip-flag "@LD_STRIP_FLAG@" \
 		--linker-debug-flags "@LDFLAGS_FOR_DEBUG@" \
 		--shlib-linker-debug-flags "@LD_LIBFLAGS_FOR_DEBUG@" \
diff --git a/scripts/mgnuc.in b/scripts/mgnuc.in
index 2c8261d..ed561b0 100644
--- a/scripts/mgnuc.in
+++ b/scripts/mgnuc.in
@@ -27,6 +27,7 @@ CFLAGS_FOR_GOTOS="@CFLAGS_FOR_GOTOS@"
 CFLAGS_FOR_THREADS="@CFLAGS_FOR_THREADS@"
 CFLAGS_FOR_NO_STRICT_ALIASING="@CFLAGS_FOR_NO_STRICT_ALIASING@"
 CFLAGS_FOR_ANSI="@CFLAGS_FOR_ANSI@"
+CFLAGS_FOR_SPLIT_SECTIONS="@CFLAGS_FOR_SPLIT_SECTIONS@"
 AS="@AS@"
 BYTES_PER_WORD="@BYTES_PER_WORD@"
 MKTEMP=@MKTEMP@
@@ -109,8 +110,8 @@ case "$C_COMPILER_TYPE" in
 esac
 
 AS_OPTS=""
-SPLIT_OPTS=""
 INLINE_ALLOC_OPTS=""
+SPLIT_SECTIONS_OPTS=""
 
 verbose=false
 assemble=false
@@ -715,11 +716,11 @@ ALL_CC_OPTS="$MERC_ALL_C_INCL_DIRS\
     $RECORD_TERM_SIZE_OPTS\
     $MINIMAL_MODEL_OPTS\
     $PREGEN_SPF_OPTS\
-    $SPLIT_OPTS\
     $THREAD_OPTS\
     $THREADSCOPE_OPTS\
     $REGION_OPTS\
     $PICREG_OPTS\
+    $SPLIT_SECTIONS_OPTS\
     $ARCH_OPTS\
     $ARG_OPTS\
     $FN_ALIGN_OPTS\
diff --git a/scripts/mgnuc_file_opts.sh-subr b/scripts/mgnuc_file_opts.sh-subr
index ce9113d..9894d96 100644
--- a/scripts/mgnuc_file_opts.sh-subr
+++ b/scripts/mgnuc_file_opts.sh-subr
@@ -42,6 +42,11 @@
         --no-inline-alloc)
             INLINE_ALLOC_OPTS="" ;;
 
+	--split-sections)
+	    SPLIT_SECTIONS_OPTS="$CFLAGS_FOR_SPLIT_SECTIONS" ;;
+	--no-split-sections)
+	    SPLIT_SECTIONS_OPTS="" ;;
+
         -g|--c-debug)
             c_debug=true ;;
         -g-|--no-c-debug)
diff --git a/scripts/ml.in b/scripts/ml.in
index e527351..ca9dacb 100644
--- a/scripts/ml.in
+++ b/scripts/ml.in
@@ -46,6 +46,7 @@ SHLIB_RPATH_OPT=${MERCURY_SHLIB_RPATH_OPT="@SHLIB_RPATH_OPT@"}
 SHLIB_RPATH_SEP=${MERCURY_SHLIB_RPATH_SEP="@SHLIB_RPATH_SEP@"}
 FIX_PATH_FOR_LINKER=${MERCURY_PATH_FOR_LINKER="@FIX_PATH_FOR_CC@"}
 LD_STATIC_FLAGS="@LD_STATIC_FLAGS@"
+LD_GC_SECTIONS_FLAG="@LD_GC_SECTIONS_FLAG@"
 LDFLAGS_FOR_THREADS="@LDFLAGS_FOR_THREADS@"
 LDFLAGS_FOR_TRACE="@LDFLAGS_FOR_TRACE@"
 LD_LIBFLAGS_FOR_THREADS="@LD_LIBFLAGS_FOR_THREADS@"
@@ -110,6 +111,7 @@ BROWSER_LIB_NAME=mer_browser
 MDBCOMP_LIB_NAME=mer_mdbcomp
 
 MAYBE_STATIC_OPT=""
+MAYBE_GC_SECTIONS_OPT=""
 
 case $debug in
 	true)
@@ -195,6 +197,12 @@ case $all_libs in
 		;;
 esac
 
+case $gc_sections in
+	true)
+		MAYBE_GC_SECTIONS_OPT=$LD_GC_SECTIONS_FLAG
+		;;
+esac
+
 #
 # compute the canonical grade name from the options settings
 #
@@ -559,7 +567,7 @@ else
 	NOLOGO_OPTS=""
 fi
 
-LINKER_PRE_FLAGS="$NOLOGO_OPTS $MSVCRT_OPTS $PRINT_MAP_OPT $UNDEF_OPT $STRIP_OPTS $MAYBE_STATIC_OPT $ARCH_OPTS"
+LINKER_PRE_FLAGS="$NOLOGO_OPTS $MSVCRT_OPTS $PRINT_MAP_OPT $UNDEF_OPT $STRIP_OPTS $MAYBE_STATIC_OPT $MAYBE_GC_SECTIONS_OPT $ARCH_OPTS"
 LINKER_POST_FLAGS="@LINK_OPT_SEP@ $NODEFAULTLIB_FLAG $DEBUG_FLAG $LIBDIR_OPTS $RPATH_OPT_LIST $LIBS"
 
 case $verbose in
diff --git a/scripts/parse_ml_options.sh-subr.in b/scripts/parse_ml_options.sh-subr.in
index 8c5201d..3515769 100644
--- a/scripts/parse_ml_options.sh-subr.in
+++ b/scripts/parse_ml_options.sh-subr.in
@@ -129,6 +129,9 @@ Dynamic/static linking options:
 		libraries, not just the standard Mercury libraries.
 	--make-shared-lib
 		Produce a shared library, rather than an executable.
+	--gc-sections
+		Tell the linker to garbage collect unused input sections in
+		object files.
 
 Directory options:
 	--mercury-standard-library-directory <directory>
@@ -291,6 +294,9 @@ while : ; do
 		# make them unusable, I think, so don't strip
 		strip=false
 		;;
+	--gc-sections)
+		gc_sections=true
+		;;
 	--no-libs)
 		progname=`basename $0`
 		cat 1>&2 << EOF
-- 
1.8.4




More information about the reviews mailing list