#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