From: wolfgang Date: Sun, 23 Jan 2005 06:10:24 +0000 (+0000) Subject: [project @ 2005-01-23 06:10:15 by wolfgang] X-Git-Tag: Initial_conversion_from_CVS_complete~1202 X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=6f985ae88171fb52ca68d75f667669e139b6b8c2 [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 libraries. Advantages over split-objs: * No evil perl script involved * Requires no special handling when building libraries Disadvantages: * 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. --- diff --git a/configure.ac b/configure.ac index 7351b39..76e961d 100644 --- a/configure.ac +++ b/configure.ac @@ -1245,6 +1245,22 @@ dnl ** check for ld, whether it has an -x option, and if it is GNU ld FP_PROG_LD_X FP_PROG_LD_IS_GNU +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");], + [ + AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_SUBSECTIONS_VIA_SYMBOLS],[1], + [Define to 1 if Apple-style dead-stripping is supported.]) + ], + [ + AC_DEFINE([HAVE_SUBSECTIONS_VIA_SYMBOLS],[0], + [Define to 1 if Apple-style dead-stripping is supported.]) + ]) + AC_CONFIG_FILES([mk/config.mk]) AC_CONFIG_COMMANDS([mk/stamp-h],[echo timestamp > mk/stamp-h]) AC_OUTPUT diff --git a/ghc/compiler/cmm/CLabel.hs b/ghc/compiler/cmm/CLabel.hs index 6f95be9..0fd4ba4 100644 --- a/ghc/compiler/cmm/CLabel.hs +++ b/ghc/compiler/cmm/CLabel.hs @@ -87,6 +87,7 @@ module CLabel ( dynamicLinkerLabelInfo, mkPicBaseLabel, + mkDeadStripPreventer, 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") #endif pprCLabel lbl = diff --git a/ghc/compiler/nativeGen/AsmCodeGen.lhs b/ghc/compiler/nativeGen/AsmCodeGen.lhs index b8fd0e3..5844c89 100644 --- a/ghc/compiler/nativeGen/AsmCodeGen.lhs +++ b/ghc/compiler/nativeGen/AsmCodeGen.lhs @@ -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 +#if HAVE_SUBSECTIONS_VIA_SYMBOLS + -- 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" +#endif + ) where diff --git a/ghc/compiler/nativeGen/PprMach.hs b/ghc/compiler/nativeGen/PprMach.hs index b1547f1..9c73def 100644 --- a/ghc/compiler/nativeGen/PprMach.hs +++ b/ghc/compiler/nativeGen/PprMach.hs @@ -27,6 +27,9 @@ import MachInstrs import CLabel ( CLabel, pprCLabel, externallyVisibleCLabel, labelDynamic, mkAsmTempLabel, entryLblToInfoLbl ) +#if HAVE_SUBSECTIONS_VIA_SYMBOLS +import CLabel ( mkDeadStripPreventer ) +#endif 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) + then +#if HAVE_SUBSECTIONS_VIA_SYMBOLS + pprCLabel_asm (mkDeadStripPreventer $ entryLblToInfoLbl lbl) + <> char ':' $$ +#endif + 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 HAVE_SUBSECTIONS_VIA_SYMBOLS + -- 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 +#endif pprBasicBlock :: NatBasicBlock -> Doc diff --git a/ghc/driver/mangler/ghc-asm.lprl b/ghc/driver/mangler/ghc-asm.lprl index 886ada8..77010c8 100644 --- a/ghc/driver/mangler/ghc-asm.lprl +++ b/ghc/driver/mangler/ghc-asm.lprl @@ -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-/ diff --git a/ghc/rts/StgCRun.c b/ghc/rts/StgCRun.c index b835a49..dc29597 100644 --- a/ghc/rts/StgCRun.c +++ b/ghc/rts/StgCRun.c @@ -534,6 +534,11 @@ extern StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg); #ifdef darwin_TARGET_OS static void StgRunIsImplementedInAssembler(void) { +#if HAVE_SUBSECTIONS_VIA_SYMBOLS + // if the toolchain supports deadstripping, we have to + // prevent it here (it tends to get confused here). + __asm__ volatile (".no_dead_strip _StgRunIsImplementedInAssembler"); +#endif __asm__ volatile ( "\n.globl _StgRun\n" "_StgRun:\n"