Commit 6f985ae8 authored by wolfgang's avatar wolfgang

[project @ 2005-01-23 06:10:15 by wolfgang]

Add support for the dead code stripping feature of recent Apple linkers.
If your code is compiled using the NCG, you can now specify
-optl-W,-dead_strip on the GHC command line when linking.
It will have basically the same effect as using split-objs to build the

Advantages over split-objs:
    * No evil perl script involved
    * Requires no special handling when building libraries

    * The current version of Apple's linker is slow when given the
      -dead_strip flag. _REALLY_ slow.
    * Mac OS X only.

This works by making the NCG emit the .subsections_via_symbols directive.
Additionally, we have to add an extra label at the top of every info table,
and make sure that the entry code references it (otherwise the info table
will be considered part of the preceding entry code).
The mangler just removes the .subsections_via_symbols directive.
parent 585d87f1
......@@ -1245,6 +1245,22 @@ dnl ** check for ld, whether it has an -x option, and if it is GNU ld
dnl ** check for Apple-style dead-stripping support
dnl (.subsections-via-symbols assembler directive)
AC_MSG_CHECKING(for .subsections_via_symbols)
AC_TRY_COMPILE(,[__asm__ (".subsections_via_symbols");],
[Define to 1 if Apple-style dead-stripping is supported.])
[Define to 1 if Apple-style dead-stripping is supported.])
AC_CONFIG_COMMANDS([mk/stamp-h],[echo timestamp > mk/stamp-h])
......@@ -87,6 +87,7 @@ module CLabel (
infoLblToEntryLbl, entryLblToInfoLbl,
needsCDecl, isAsmTemp, externallyVisibleCLabel,
......@@ -197,6 +198,9 @@ data CLabel
-- as 1b, referring to the previous definition
-- of 1: in the assembler source file.
| DeadStripPreventer CLabel
-- label before an info table to prevent excessive dead-stripping on darwin
deriving (Eq, Ord)
data IdLabelInfo
......@@ -402,6 +406,9 @@ dynamicLinkerLabelInfo _ = Nothing
mkPicBaseLabel :: CLabel
mkPicBaseLabel = PicBaseLabel
mkDeadStripPreventer :: CLabel -> CLabel
mkDeadStripPreventer lbl = DeadStripPreventer lbl
-- -----------------------------------------------------------------------------
-- Converting info labels to entry labels.
......@@ -619,6 +626,9 @@ pprCLabel (DynamicLinkerLabel info lbl)
pprCLabel PicBaseLabel
= ptext SLIT("1b")
pprCLabel (DeadStripPreventer lbl)
= pprCLabel lbl <> ptext SLIT("_dsp")
pprCLabel lbl =
......@@ -121,7 +121,14 @@ nativeCodeGen dflags cmms us
returnUs (Cmm cmms, my_vcat docs, concat imps)
in do
dumpIfSet_dyn dflags Opt_D_dump_opt_cmm "Optimised Cmm" (pprCmms [ppr_cmms])
return (insn_sdoc Pretty.$$ dyld_stubs imports)
return (insn_sdoc Pretty.$$ dyld_stubs imports
-- On recent versions of Darwin, the linker supports
-- dead-stripping of code and data on a per-symbol basis.
-- There's a hack to make this work in PprMach.pprNatCmmTop.
Pretty.$$ Pretty.text ".subsections_via_symbols"
......@@ -27,6 +27,9 @@ import MachInstrs
import CLabel ( CLabel, pprCLabel, externallyVisibleCLabel,
labelDynamic, mkAsmTempLabel, entryLblToInfoLbl )
import CLabel ( mkDeadStripPreventer )
import Panic ( panic )
import Unique ( pprUnique )
......@@ -68,8 +71,13 @@ pprNatCmmTop (CmmProc [] lbl _ []) = pprLabel lbl
pprNatCmmTop (CmmProc info lbl params blocks) =
pprSectionHeader Text $$
(if not (null info)
then vcat (map pprData info)
$$ pprLabel (entryLblToInfoLbl lbl)
pprCLabel_asm (mkDeadStripPreventer $ entryLblToInfoLbl lbl)
<> char ':' $$
vcat (map pprData info) $$
pprLabel (entryLblToInfoLbl lbl)
else empty) $$
(case blocks of
[] -> empty
......@@ -77,7 +85,22 @@ pprNatCmmTop (CmmProc info lbl params blocks) =
(if null info then pprLabel lbl else empty) $$
-- the first block doesn't get a label:
vcat (map pprInstr instrs) $$
vcat (map pprBasicBlock rest))
vcat (map pprBasicBlock rest)
-- If we are using the .subsections_via_symbols directive
-- (available on recent versions of Darwin),
-- we have to make sure that there is some kind of reference
-- from the entry code to a label on the _top_ of of the info table,
-- so that the linker will not think it is unreferenced and dead-strip
-- it. That's why the label is called a DeadStripPreventer (_dsp).
$$ if not (null info)
then text "\t.long "
<+> pprCLabel_asm (entryLblToInfoLbl lbl)
<+> char '-'
<+> pprCLabel_asm (mkDeadStripPreventer $ entryLblToInfoLbl lbl)
else empty
pprBasicBlock :: NatBasicBlock -> Doc
......@@ -533,7 +533,12 @@ sub mangle_asm {
} elsif ( /\.\.ng:$/ && $TargetPlatform =~ /^alpha-/ ) {
# Alphas: Local labels not to be confused with new chunks
$chk[$i] .= $_;
} elsif ( $TargetPlatform =~ /-darwin/
&& /^\t\.subsections_via_symbols/) {
# Don't allow Apple's linker to do any dead-stripping of symbols
# in this file, because it will mess up info-tables in mangled
# code.
# NB: all the rest start with a non-space
} elsif ( $TargetPlatform =~ /^mips-/
......@@ -534,6 +534,11 @@ extern StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg);
#ifdef darwin_TARGET_OS
static void StgRunIsImplementedInAssembler(void)
// if the toolchain supports deadstripping, we have to
// prevent it here (it tends to get confused here).
__asm__ volatile (".no_dead_strip _StgRunIsImplementedInAssembler");
__asm__ volatile (
"\n.globl _StgRun\n"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment