#5292: libHSghc exports more symbols than Windows can handle
---------------------------------+------------------------------------------
    Reporter:  batterseapower    |       Owner:               
        Type:  bug               |      Status:  new          
    Priority:  normal            |   Component:  Compiler     
     Version:  7.0.3             |    Keywords:               
    Testcase:                    |   Blockedby:               
          Os:  Windows           |    Blocking:               
Architecture:  Unknown/Multiple  |     Failure:  Runtime crash
---------------------------------+------------------------------------------

Comment(by batterseapower):

 A cursory inspection of the .o files doesn't reveal anything being
 exported that is obviously useless. It does give a clue as to where at
 least some of the bloat comes from though: Data instances for GHCs various
 data types account for 8661 exported symbols alone!

 As to your second suggestion, this may help. I note that currently all of
 GHCs modules are marked as exposed, so to implement it we would have to
 start hiding some modules.

 I quickly went through the list of exposed modules and created list of
 modules we could probably hide without hurting anyone (mostly the ones
 related to code generation):

 {{{
   Llvm
   LlvmziAbsSyn
   LlvmziPpLlvm
   LlvmziTypes
   LlvmCodeGen
   LlvmCodeGenziBase
   LlvmCodeGenziCodeGen
   LlvmCodeGenziData
   LlvmCodeGenziPpr
   LlvmCodeGenziRegs
   LlvmMangler
   Cmm
   CmmBuildInfoTables
   CmmPipeline
   CmmCallConv
   CmmCommonBlockElim
   CmmContFlowOpt
   CmmCvt
   CmmDecl
   CmmExpr
   CmmInfo
   CmmLex
   CmmLint
   CmmLive
   CmmMachOp
   CmmNode
   CmmOpt
   CmmParse
   CmmProcPoint
   CmmSpillReload
   CmmRewriteAssignments
   CmmStackLayout
   CmmType
   CmmUtils
   CgBindery
   CgCallConv
   CgCase
   CgClosure
   CgCon
   CgExpr
   CgExtCode
   CgForeignCall
   CgHeapery
   CgHpc
   CgInfoTbls
   CgLetNoEscape
   CgMonad
   CgParallel
   CgPrimOp
   CgProf
   CgStackery
   CgTailCall
   CgTicky
   CgUtils
   StgCmm
   StgCmmBind
   StgCmmClosure
   StgCmmCon
   StgCmmEnv
   StgCmmExpr
   StgCmmForeign
   StgCmmGran
   StgCmmHeap
   StgCmmHpc
   StgCmmLayout
   StgCmmMonad
   StgCmmPrim
   StgCmmProf
   StgCmmTicky
   StgCmmUtils
   Coverage
   SimplEnv
   SimplMonad
   SimplUtils
   SpecConstr
   Specialise
   CoreToStg
   DmdAnal
   WorkWrap
   WwLib
   VectoriseziBuiltinsziBase
   VectoriseziBuiltinsziInitialise
   VectoriseziBuiltinsziModules
   VectoriseziBuiltins
   VectoriseziMonadziBase
   VectoriseziMonadziNaming
   VectoriseziMonadziLocal
   VectoriseziMonadziGlobal
   VectoriseziMonadziInstEnv
   VectoriseziMonad
   VectoriseziUtilsziBase
   VectoriseziUtilsziClosure
   VectoriseziUtilsziHoisting
   VectoriseziUtilsziPADict
   VectoriseziUtilsziPoly
   VectoriseziUtils
   VectoriseziTypeziEnv
   VectoriseziTypeziRepr
   VectoriseziTypeziPData
   VectoriseziTypeziPRepr
   VectoriseziTypeziPADict
   VectoriseziTypeziType
   VectoriseziTypeziTyConDecl
   VectoriseziTypeziClassify
   VectoriseziConvert
   VectoriseziVect
   VectoriseziVar
   VectoriseziEnv
   VectoriseziExp
   X86ziRegs
   X86ziRegInfo
   X86ziInstr
   X86ziCond
   X86ziPpr
   X86ziCodeGen
   PPCziRegs
   PPCziRegInfo
   PPCziInstr
   PPCziCond
   PPCziPpr
   PPCziCodeGen
   SPARCziBase
   SPARCziRegs
   SPARCziRegPlate
   SPARCziImm
   SPARCziAddrMode
   SPARCziCond
   SPARCziInstr
   SPARCziStack
   SPARCziShortcutJump
   SPARCziPpr
   SPARCziCodeGen
   SPARCziCodeGenziAmode
   SPARCziCodeGenziBase
   SPARCziCodeGenziCCall
   SPARCziCodeGenziCondCode
   SPARCziCodeGenziGen32
   SPARCziCodeGenziGen64
   SPARCziCodeGenziSanity
   SPARCziCodeGenziExpand
   RegAllocziLiveness
   RegAllocziGraphziMain
   RegAllocziGraphziStats
   RegAllocziGraphziArchBase
   RegAllocziGraphziArchX86
   RegAllocziGraphziCoalesce
   RegAllocziGraphziSpill
   RegAllocziGraphziSpillClean
   RegAllocziGraphziSpillCost
   RegAllocziGraphziTrivColorable
   RegAllocziLinearziMain
   RegAllocziLinearziJoinToTargets
   RegAllocziLinearziState
   RegAllocziLinearziStats
   RegAllocziLinearziFreeRegs
   RegAllocziLinearziStackMap
   RegAllocziLinearziBase
   RegAllocziLinearziX86ziFreeRegs
   RegAllocziLinearziPPCziFreeRegs
   RegAllocziLinearziSPARCziFreeRegs
   ByteCodeAsm
   ByteCodeGen
   ByteCodeInstr
   ByteCodeItbls
   ByteCodeLink
 }}}

 Under the optimistic assumption that we don't export *any* symbols from
 these modules, by hiding these we would only need to export 60293 symbols
 from a -O build of libHSghc (as opposed to the current 75756), so we would
 be back within the limit. We would be a bit too close for comfort,
 however!

 Excluding modules from this list and modules exporting less than 400
 symbols, the major offenders are:

 {{{
 Coercion: 407
 RnEnv: 412
 TcEnv: 420
 Constants: 422
 Type: 436
 GHC: 442
 TypeRep: 467
 TysPrim: 478
 SrcLoc: 503
 TcType: 509
 RdrName: 511
 TcMType: 526
 IfaceSyn: 531
 HsPat: 568
 ForeignCall: 584
 TyCon: 585
 TcSMonad: 610
 StaticFlags: 621
 Module: 624
 DsMeta: 625
 Lexer: 658
 CoreMonad: 729
 HsTypes: 744
 OccName: 774
 TcRnMonad: 775
 Binary: 810
 TcRnTypes: 856
 CoreSyn: 917
 Outputable: 956
 PrimOp: 1083
 BinIface: 1121
 HscTypes: 1194
 CLabel: 1468
 BasicTypes: 1659
 PrelNames: 1687
 HsBinds: 1764
 HsDecls: 2393
 DynFlags: 4138
 HsExpr: 4433
 }}}

 (So HsExpr is the worst, with 4433 exports.)

 If you want to play along at home, this NM invocation may be helpful:

 {{{
 nm
 ~/Programming/Checkouts/ghc/compiler/stage2/build/libHSghc-7.3.20110702.a
 | grep ' [TD] ' |  cut -b13- | uniq > nm-exports
 }}}

 As well as this quick-and-dirty analytics tool:

 {{{

 module Main where

 import Control.Monad

 import Data.Ord
 import Data.List
 import qualified Data.Map as M
 import qualified Data.Set as S

 main = do
     let zEncode = concatMap $ \c -> if c == '.' then "zi" else if c == 'z'
 then "zz" else [c]
     all_ghc_mods <- fmap (map zEncode . lines) $ readFile "modules"

     exports <- fmap lines $ readFile "nm-exports"
     let ghc_mods_syms = [ (mod, sym)
                         | export <- exports
                         , "ghczm7zi3zi20110702_" `isPrefixOf` export
                         , let mod_sym = drop (length
 "ghczm7zi3zi20110702_") export
                               (mod, '_':sym) = span (/= '_') mod_sym
                         ]

     let unknown_mods = S.toList (S.fromList (map fst ghc_mods_syms) S.\\
 S.fromList all_ghc_mods)
     unless (null unknown_mods) $ do
         putStrLn "Unknown modules:"
         mapM_ (\mod -> putStr "  " >> putStrLn mod) unknown_mods

     showPopularity ghc_mods_syms

     putStrLn "\n====\n"

     exposed_ghc_mods <- fmap (S.fromList . map zEncode . lines) $ readFile
 "proposed-modules"

     let hidden_mods = filter (`S.notMember` exposed_ghc_mods) all_ghc_mods
     unless (null hidden_mods) $ do
         putStrLn "Hidden modules:"
         mapM_ (\mod -> putStr "  " >> putStrLn mod) hidden_mods

     let exposed_ghc_mods_syms = filter (\(mod, _sym) -> mod `S.member`
 exposed_ghc_mods) ghc_mods_syms
     showPopularity exposed_ghc_mods_syms
     putStrLn $ "Exposing " ++ show (length exposed_ghc_mods_syms) ++ " out
 of " ++ show (length ghc_mods_syms)

     let data_uses = [sym
                     | (mod, sym) <- ghc_mods_syms
                     , "zdwzdszdcgmap" `isPrefixOf` sym || "zdfData"
 `isPrefixOf` sym
                     ]
     putStrLn $ show (length data_uses) ++ " data exports out of " ++ show
 (length ghc_mods_syms)

 showPopularity ghc_mods_syms = mapM_ (\(mod, uses) -> putStrLn $ mod ++ ":
 " ++ show uses) popular_mods
   where
     mod_uses = M.unionsWith (+) [M.singleton mod 1 | (mod, _sym) <-
 ghc_mods_syms]
     popular_mods = sortBy (comparing snd) $ M.toList mod_uses
 }}}

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/5292#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to