X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fdriver%2Fghc.lprl;h=8ccef55cfca9dc672f56e680b4959d972549114b;hb=da61874293fdcf7c22117d3f2d1022d3981a1862;hp=2203895339820feb70c3cd22024366e53492e72f;hpb=e7d21ee4f8ac907665a7e170c71d59e13a01da09;p=ghc-hetmet.git diff --git a/ghc/driver/ghc.lprl b/ghc/driver/ghc.lprl index 2203895..8ccef55 100644 --- a/ghc/driver/ghc.lprl +++ b/ghc/driver/ghc.lprl @@ -1,5 +1,5 @@ % -% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995 +% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996 % % *** MSUB does some substitutions here *** % *** grep for $( *** @@ -160,6 +160,7 @@ $HsCpp = # but this is re-set to "cat" (after options) if -cpp not seen ( $(INSTALLING) ) ? "$InstLibDirGhc/hscpp" : "$TopPwd/$(CURRENT_DIR)/$(GHC_HSCPP)"; @HsCpp_flags = (); +$genSPECS_flag = ''; # See ../utils/hscpp/hscpp.prl $HsP = ( $(INSTALLING) ) ? "$InstLibDirGhc/hsp" : "$TopPwd/$(CURRENT_DIR)/$(GHC_HSP)"; @@ -190,8 +191,7 @@ expressed with a \tr{-O} (or \tr{-O2}) flag, or by its absence. \begin{code} $OptLevel = 0; # no -O == 0; -O == 1; -O2 == 2; -Ofile == 3 $MinusO2ForC = 0; # set to 1 if -O2 should be given to C compiler -$StolenX86Regs = 5; # **HACK*** of the very worst sort -$SpX86Mangling = 1; # **EXTREME HACK*** of an even worse sort +$StolenX86Regs = 4; # **HACK*** of the very worst sort \end{code} These variables represent parts of the -O/-O2/etc ``templates,'' @@ -205,10 +205,13 @@ $Oopt_MonadEtaExpansion = ''; #OLD:$Oopt_LambdaLift = ''; $Oopt_AddAutoSccs = ''; $Oopt_FinalStgProfilingMassage = ''; +$Oopt_StgStats = ''; $Oopt_SpecialiseUnboxed = ''; +$Oopt_DoSpecialise = '-fspecialise'; $Oopt_FoldrBuild = 1; # On by default! $Oopt_FB_Support = '-fdo-new-occur-anal -fdo-arity-expand'; #$Oopt_FoldrBuildWW = 0; # Off by default +$Oopt_FoldrBuildInline = '-fdo-inline-foldr-build'; \end{code} Things to do with C compilers/etc: @@ -234,6 +237,7 @@ $As = ''; # assembler is normally the same pgm as used for C compilation @As_flags = (); $Lnkr = ''; # linker is normally the same pgm as used for C compilation +@Ld_flags = (); # 'nm' is used for consistency checking (ToDo: mk-world-ify) # ToDo: check the OS or something ("alpha" is surely not the crucial question) @@ -272,12 +276,14 @@ $BuildTag = ''; # default is sequential build w/ Appel-style GC '_l', '$(GHC_BUILD_FLAG_l)', '_m', '$(GHC_BUILD_FLAG_m)', '_n', '$(GHC_BUILD_FLAG_n)', - '_o', '$(GHC_BUILD_FLAG_o)' ); + '_o', '$(GHC_BUILD_FLAG_o)', + '_A', '$(GHC_BUILD_FLAG_A)', + '_B', '$(GHC_BUILD_FLAG_B)' ); %BuildDescr = ('', 'normal sequential', '_p', 'profiling', '_t', 'ticky-ticky profiling', - '_t', 'unregisterized (using portable C only)', + '_u', 'unregisterized (using portable C only)', '_mc', 'concurrent', '_mr', 'profiled concurrent', '_mt', 'ticky concurrent', @@ -300,7 +306,9 @@ $BuildTag = ''; # default is sequential build w/ Appel-style GC '_l', 'user way l', '_m', 'user way m', '_n', 'user way n', - '_o', 'user way o' ); + '_o', 'user way o', + '_A', 'user way A', + '_B', 'user way B' ); # these are options that are "fed back" through the option processing loop %UserSetupOpts = ('_a', '$(GHC_BUILD_OPTS_a)', @@ -318,6 +326,8 @@ $BuildTag = ''; # default is sequential build w/ Appel-style GC '_m', '$(GHC_BUILD_OPTS_m)', '_n', '$(GHC_BUILD_OPTS_n)', '_o', '$(GHC_BUILD_OPTS_o)', + '_A', '$(GHC_BUILD_OPTS_A)', + '_B', '$(GHC_BUILD_OPTS_B)', # the GC ones don't have any "fed back" options '_2s', '', @@ -329,11 +339,11 @@ $BuildTag = ''; # default is sequential build w/ Appel-style GC # profiled sequential '_p', 'push(@HsC_flags, \'-fscc-profiling\'); - push(@CcBoth_flags, \'-DUSE_COST_CENTRES\');', + push(@CcBoth_flags, \'-DPROFILING\');', # ticky-ticky sequential - '_t', 'push(@HsC_flags, \'-fstg-reduction-counts\'); - push(@CcBoth_flags, \'-DDO_REDN_COUNTING\');', + '_t', 'push(@HsC_flags, \'-fticky-ticky\'); + push(@CcBoth_flags, \'-DTICKY_TICKY\');', # unregisterized (ToDo????) '_u', '', @@ -348,24 +358,23 @@ $BuildTag = ''; # default is sequential build w/ Appel-style GC '_mr', '$StkChkByPageFaultOK = 0; push(@HsC_flags, \'-fconcurrent\', \'-fscc-profiling\'); push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\'); - push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DUSE_COST_CENTRES\');', + push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DPROFILING\');', # ticky-ticky concurrent '_mt', '$StkChkByPageFaultOK = 0; - push(@HsC_flags, \'-fconcurrent\', \'-fstg-reduction-counts\'); + push(@HsC_flags, \'-fconcurrent\', \'-fticky-ticky\'); push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\'); - push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DDO_REDN_COUNTING\');', + push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DTICKY_TICKY\');', # parallel '_mp', '$StkChkByPageFaultOK = 0; push(@HsC_flags, \'-fconcurrent\'); push(@HsCpp_flags,\'-D__PARALLEL_HASKELL__\', \'-DPAR\'); - push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DPAR\', \'-DGUM\');', + push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DPAR\');', # GranSim '_mg', '$StkChkByPageFaultOK = 0; push(@HsC_flags, \'-fconcurrent\'); -#???????????? push(@HsCpp_flags,\'-D__PARALLEL_HASKELL__\', \'-DPAR\'); push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DGRAN\');', '_2s', 'push (@CcBoth_flags, \'-DGC2s\');', @@ -386,7 +395,9 @@ $BuildTag = ''; # default is sequential build w/ Appel-style GC '_l', '', '_m', '', '_n', '', - '_o', '' ); + '_o', '', + '_A', '', + '_B', '' ); \end{code} Import/include directories (\tr{-I} options) are sufficiently weird to @@ -453,14 +464,13 @@ $RegisteriseC = ''; # set to 'o', if using optimised C code (only if avail) # or if generating equiv asm code $DEBUGging = ''; # -DDEBUG and all that it entails (um... not really) $PROFing = ''; # set to p or e if profiling -$PROFaging = ''; # set to a if profiling with age -- only for cc consistency $PROFgroup = ''; # set to group if an explicit -Ggroup specified $PROFauto = ''; # set to relevant hsc flag if -auto or -auto-all $PROFcaf = ''; # set to relevant hsc flag if -caf-all #UNUSED:$PROFdict = ''; # set to relevant hsc flag if -dict-all $PROFignore_scc = ''; # set to relevant parser flag if explicit sccs ignored $TICKYing = ''; # set to t if compiling for ticky-ticky profiling -$PARing = ''; # set to p if compiling for PAR (ie GUM) +$PARing = ''; # set to p if compiling for PAR $CONCURing = ''; # set to c if compiling for CONCURRENT $GRANing = ''; # set to g if compiling for GRAN $StkChkByPageFaultOK = 1; # may be set to 0 (false) for some builds @@ -526,6 +536,39 @@ $Cc_consist_options = ''; # we record, in this order: Now slurp through the arguments. \begin{code} + +#---------- user defined prelude --------------------------------------- + +if (grep(/^-user-prelude$/, @ARGV)) { + + # If ARGV contains -user-prelude we are compiling a piece of + # prelude for the user, probably with additional specialise pragmas + + # We strip out the -O -f and -user-prelude flags provided on + # the command line and add the ones used to compile the prelude + # ToDo: get these options from a common definition in mkworld + + # We also enable any options forced through with -user-prelude-force + + # Hey, Check out this grep statement ;-) (PS) + + @ARGV = grep((!/^-O/ && !/^-f/ && !/^-user-prelude$/) || s/^-user-prelude-force//, + @ARGV); + + unshift(@ARGV, + '-prelude', + '-O', + '-fshow-pragma-name-errs', + '-fshow-import-specs', + '-fomit-reexported-instances', + '-fglasgow-exts', + '-genSPECS', + '-DUSE_FOLDR_BUILD', + '-dcore-lint'); + + print STDERR "ghc: -user-prelude options:\n", "@ARGV", "\n"; +} + # can't use getopt(s); what we want is too complicated arg: while($_ = $ARGV[0]) { shift(@ARGV); @@ -558,8 +601,9 @@ arg: while($_ = $ARGV[0]) { /^-nohi$/ && do { $ProduceHi = 0; next arg; }; # don't generate an interface (even if generating C) - /^-hi-diffs$/ && do { $HiDiff_flag = 1; next arg; }; - # show diffs if the interface file changes + /^-hi-diffs$/ && do { $HiDiff_flag = 1; next arg; }; + /^-no-hi-diffs$/ && do { $HiDiff_flag = 0; next arg; }; + # show/disable diffs if the interface file changes /^-E$/ && do { push(@CcBoth_flags, '-E'); $Only_preprocess_C = 1; @@ -660,11 +704,6 @@ arg: while($_ = $ARGV[0]) { /^-prof$/ && do { $PROFing = 'p'; next arg; }; # profiling -- details later! - /^-fheap-profiling-with-age$/ && do { - $PROFaging = 'a'; - push(@CcBoth_flags, '-DHEAP_PROF_WITH_AGE'); - next arg; }; - /^-auto/ && do { # generate auto SCCs on top level bindings # -auto-all = all top level bindings @@ -701,7 +740,7 @@ arg: while($_ = $ARGV[0]) { #-------------- "user ways" -------------------------------------------- - (/^-user-setup-([a-o])$/ + (/^-user-setup-([a-oA-Z])$/ || /^$(GHC_BUILD_FLAG_a)$/ || /^$(GHC_BUILD_FLAG_b)$/ || /^$(GHC_BUILD_FLAG_c)$/ @@ -717,12 +756,14 @@ arg: while($_ = $ARGV[0]) { || /^$(GHC_BUILD_FLAG_m)$/ || /^$(GHC_BUILD_FLAG_n)$/ || /^$(GHC_BUILD_FLAG_o)$/ + || /^$(GHC_BUILD_FLAG_A)$/ + || /^$(GHC_BUILD_FLAG_B)$/ || /^$(GHC_BUILD_FLAG_2s)$/ # GC ones... || /^$(GHC_BUILD_FLAG_1s)$/ || /^$(GHC_BUILD_FLAG_du)$/ ) && do { - /^-user-setup-([a-o])$/ && do { $BuildTag = "_$1"; }; + /^-user-setup-([a-oA-Z])$/ && do { $BuildTag = "_$1"; }; /^$(GHC_BUILD_FLAG_a)$/ && do { $BuildTag = '_a'; }; /^$(GHC_BUILD_FLAG_b)$/ && do { $BuildTag = '_b'; }; @@ -739,6 +780,8 @@ arg: while($_ = $ARGV[0]) { /^$(GHC_BUILD_FLAG_m)$/ && do { $BuildTag = '_m'; }; /^$(GHC_BUILD_FLAG_n)$/ && do { $BuildTag = '_n'; }; /^$(GHC_BUILD_FLAG_o)$/ && do { $BuildTag = '_o'; }; + /^$(GHC_BUILD_FLAG_A)$/ && do { $BuildTag = '_A'; }; + /^$(GHC_BUILD_FLAG_B)$/ && do { $BuildTag = '_B'; }; /^$(GHC_BUILD_FLAG_2s)$/ && do { $BuildTag = '_2s'; }; /^$(GHC_BUILD_FLAG_1s)$/ && do { $BuildTag = '_1s'; }; @@ -821,6 +864,10 @@ arg: while($_ = $ARGV[0]) { /^-D(.*)/ && do { push(@HsCpp_flags, "'-D".&grab_arg_arg('-D',$1)."'"); next arg; }; /^-U(.*)/ && do { push(@HsCpp_flags, "'-U".&grab_arg_arg('-U',$1)."'"); next arg; }; + /^-genSPECS/ && do { $Cpp_flag_set = 1; + $genSPECS_flag = $_; + next arg; }; + #---------- Haskell parser (hsp) --------------------------------------- /^-ddump-parser$/ && do { $Dump_parser_output = 1; next arg; }; @@ -834,7 +881,7 @@ arg: while($_ = $ARGV[0]) { #---------- Haskell compiler (hsc) ------------------------------------- # possibly resurrect LATER -# /^-fspat-profiling$/ && do { push(@HsC_flags, '-fstg-reduction-counts'); +# /^-fspat-profiling$/ && do { push(@HsC_flags, '-fticky-ticky'); # $ProduceS = ''; $ProduceC = 1; # must use C compiler # push(@CcBoth_flags, '-DDO_SPAT_PROFILING'); # push(@CcBoth_flags, '-fno-schedule-insns'); # not essential @@ -862,12 +909,18 @@ arg: while($_ = $ARGV[0]) { /^-prelude$/ && do { $CompilingPrelude = 1; push(@HsC_flags, $_); next arg; }; + /^-user-prelude-force/ && do { # ignore if not -user-prelude + next arg; }; + /^-split-objs(.*)/ && do { local($sname) = &grab_arg_arg('-split-objs', $1); $sname =~ s/ //g; # no spaces - if ( $TargetPlatform =~ /^(sparc|alpha|m68k|mips|i[34]86|hppa1\.1)-/ ) { + if ( $TargetPlatform =~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|sparc)-/ ) { $SplitObjFiles = 1; + $ProduceS = ''; + $ProduceC = 1; + push(@HsC_flags, "-fglobalise-toplev-names$sname"); push(@CcBoth_flags, '-DUSE_SPLIT_MARKERS'); @@ -879,8 +932,6 @@ arg: while($_ = $ARGV[0]) { } next arg; }; - /^-fglobalise-toplev-names$/&& do { push(@HsC_flags, $_); next arg; }; - /^-f(hide-builtin-names|min-builtin-names)$/ && do { push(@HsC_flags, $_); push(@HsP_flags, '-P'); # don't read Prelude.hi @@ -898,12 +949,26 @@ arg: while($_ = $ARGV[0]) { } next arg; }; - /^-fspecialise-unboxed$/ - && do { $Oopt_SpecialiseUnboxed = '-fspecialise-unboxed'; + /^-fspeciali[sz]e-unboxed$/ + && do { $Oopt_DoSpecialise = '-fspecialise'; + $Oopt_SpecialiseUnboxed = '-fspecialise-unboxed'; + next arg; }; + /^-fspeciali[sz]e$/ + && do { $Oopt_DoSpecialise = '-fspecialise'; next arg; }; + /^-fno-speciali[sz]e$/ + && do { $Oopt_DoSpecialise = ''; + next arg; }; + # Now the foldr/build options, which are *on* by default (for -O). + /^-ffoldr-build$/ + && do { $Oopt_FoldrBuild = 1; + $Oopt_FB_Support = '-fdo-new-occur-anal -fdo-arity-expand'; + #print "Yes F/B\n"; + next arg; }; + /^-fno-foldr-build$/ && do { $Oopt_FoldrBuild = 0; $Oopt_FB_Support = ''; @@ -911,12 +976,17 @@ arg: while($_ = $ARGV[0]) { /^-fno-foldr-build-rule$/ && do { $Oopt_FoldrBuild = 0; - next arg; }; + next arg; }; /^-fno-enable-tech$/ && do { $Oopt_FB_Support = ''; next arg; }; + /^-fno-snapback-to-append$/ + && do { $Oopt_FoldrBuildInline .= ' -fdo-not-fold-back-append '; + #print "No Foldback of append\n"; + next arg; }; + # /^-ffoldr-build-ww$/ # && do { $Oopt_FoldrBuildWW = 1; next arg; }; @@ -948,6 +1018,21 @@ arg: while($_ = $ARGV[0]) { /^-fdo-monad-eta-expansion$/ && do { $Oopt_MonadEtaExpansion = $_; next arg; }; + /^-fno-let-from-(case|app|strict-let)$/ # experimental, really (WDP 95/10) + && do { push(@HsC_flags, $_); next arg; }; + + /^(-freturn-in-regs-threshold)(.*)$/ + && do { local($what) = $1; + local($num) = &grab_arg_arg($what, $2); + if ($num < 2 || $num > 8) { + die "Bad experimental flag: $_\n"; + } else { + $ProduceS = ''; $ProduceC = 1; # force using C compiler + push(@HsC_flags, "$what$num"); + push(@CcRegd_flags, "-D__STG_REGS_AVAIL__=$num"); + } + next arg; }; + # /^-flambda-lift$/ # so Simon can do some testing; ToDo:rm # && do { $Oopt_LambdaLift = $_; next arg; }; @@ -961,8 +1046,13 @@ arg: while($_ = $ARGV[0]) { # --------------- - /^-mlong-calls/ && do { # for GCC for HP-PA boxes - unshift(@CcBoth_flags, ('-mlong-calls')); + /^-mlong-calls$/ && do { # for GCC for HP-PA boxes + unshift(@CcBoth_flags, ( $_ )); + next arg; }; + + /^-m(v8|sparclite|cypress|supersparc|cpu=(cypress|supersparc))$/ + && do { # for GCC for SPARCs + unshift(@CcBoth_flags, ( $_ )); next arg; }; /^-monly-([432])-regs/ && do { # for iX86 boxes only; no effect otherwise @@ -970,7 +1060,8 @@ arg: while($_ = $ARGV[0]) { next arg; }; /^-mtoggle-sp-mangling/ && do { # for iX86 boxes only; for RTS only - $SpX86Mangling = 1 - $SpX86Mangling; + print STDERR "$Pgm: warning: -mtoggle-sp-mangling is no longer supported\n"; +# $SpX86Mangling = 1 - $SpX86Mangling; next arg; }; #*************** ... and lots of debugging ones (form: -d* ) @@ -995,7 +1086,10 @@ arg: while($_ = $ARGV[0]) { /^-d(dump|ppr)-/ && do { push(@HsC_flags, $_); next arg; }; /^-dverbose-(simpl|stg)/ && do { push(@HsC_flags, $_); next arg; }; + /^-dshow-passes/ && do { push(@HsC_flags, $_); next arg; }; + /^-dsource-stats/ && do { push(@HsC_flags, $_); next arg; }; /^-dsimplifier-stats/ && do { push(@HsC_flags, $_); next arg; }; + /^-dstg-stats/ && do { $Oopt_StgStats = $_; next arg; }; #*************** ... and now all these -R* ones for its runtime system... @@ -1121,12 +1215,17 @@ arg: while($_ = $ARGV[0]) { close(OFILE); next arg; }; - /^-debug$/ && do { # all this does is mark a .hc/.o as "debugging" - # in the consistency info - $DEBUGging = 'd'; - next arg; }; -# OLD: do it another way -# /^-dgc-debug$/ && do { push(@CcBoth_flags, '-D_GC_DEBUG'); next arg; }; + /^-debug$/ && do { # all this does is mark a .hc/.o as "debugging" + # in the consistency info + $DEBUGging = 'd'; + next arg; }; + + #---------- linking .a file -------------------------------------------- + + /^-Main(.*)/ && do { + # specifies main or mainPrimIO to be linked + $Ld_main = $1; + next arg; }; #---------- catch unrecognized flags ----------------------------------- @@ -1136,8 +1235,8 @@ arg: while($_ = $ARGV[0]) { next arg; }; #---------- anything else is considered an input file ------------------ - # (well, .o files are immediately queued up as linker fodder..) - if (/\.o$/) { + # (well, .o and .a files are immediately queued up as linker fodder..) + if (/\.[oa]$/) { push(@Link_file, $_); } else { push(@Input_file, $_); @@ -1280,7 +1379,7 @@ It really really wants to be the last STG-to-STG pass that is run. = ( '-fsimplify', '\(', "$Oopt_FB_Support", - '-falways-float-lets-from-lets', +# '-falways-float-lets-from-lets', # no idea why this was here (WDP 95/09) '-ffloat-lets-exposing-whnf', '-ffloat-primops-ok', '-fcase-of-case', @@ -1303,26 +1402,27 @@ It really really wants to be the last STG-to-STG pass that is run. @HsC_minusO_flags # NOTE: used for *both* -O and -O2 (some conditional bits) = ( - # core2core passes - # initial simplify: mk specialiser happy: minimum effort please + # initial simplify: mk specialiser and autoscc happy: minimum effort please '-fsimplify', '\(', "$Oopt_FB_Support", - '-fkeep-spec-pragma-ids', + '-fkeep-spec-pragma-ids', # required before specialisation '-fsimpl-uf-use-threshold0', '-fessential-unfoldings-only', '-fmax-simplifier-iterations1', "$Oopt_PedanticBottoms", '\)', - $Oopt_AddAutoSccs, # dangerous to do with *no* simplification... + $Oopt_AddAutoSccs, # need some basic simplification first - '-fspecialise-overloaded', - $Oopt_SpecialiseUnboxed, - '-fspecialise', + ($Oopt_DoSpecialise) ? ( + '-fspecialise-overloaded', + $Oopt_SpecialiseUnboxed, + $Oopt_DoSpecialise, + ) : (), - '-fsimplify', # need tossing before calc-i... - '\(', + '-fsimplify', # need dependency anal after specialiser ... + '\(', # need tossing before calc-inlinings ... "$Oopt_FB_Support", '-ffloat-lets-exposing-whnf', '-ffloat-primops-ok', @@ -1331,7 +1431,6 @@ It really really wants to be the last STG-to-STG pass that is run. '-fdo-eta-reduction', '-fdo-lambda-eta-expansion', '-freuse-con', -# '-flet-to-case', # no point, before strictness analysis "$Oopt_PedanticBottoms", "$Oopt_MonadEtaExpansion", "$Oopt_UnfoldingUseThreshold", @@ -1353,7 +1452,6 @@ It really really wants to be the last STG-to-STG pass that is run. # '-fdo-eta-reduction', # '-fdo-lambda-eta-expansion', # '-freuse-con', -## '-flet-to-case', # no point, before strictness analysis # "$Oopt_PedanticBottoms", # "$Oopt_MonadEtaExpansion", # "$Oopt_UnfoldingUseThreshold", @@ -1366,6 +1464,8 @@ It really really wants to be the last STG-to-STG pass that is run. '-ffull-laziness', ($Oopt_FoldrBuild) ? ( + '-ffoldr-build-on', # desugar list comprehensions for foldr/build + '-fsimplify', '\(', '-fignore-inline-pragma', # **** NB! @@ -1378,7 +1478,6 @@ It really really wants to be the last STG-to-STG pass that is run. '-fdo-eta-reduction', '-fdo-lambda-eta-expansion', '-freuse-con', - # '-flet-to-case', # no point, before strictness analysis "$Oopt_PedanticBottoms", "$Oopt_MonadEtaExpansion", "$Oopt_UnfoldingUseThreshold", @@ -1398,9 +1497,10 @@ It really really wants to be the last STG-to-STG pass that is run. '-fdo-eta-reduction', '-fdo-lambda-eta-expansion', '-freuse-con', -# '-flet-to-case', # no point, before strictness analysis - '-fdo-inline-foldr-build', - # you need to inline foldr! + ($Oopt_FoldrBuildInline), + # you need to inline foldr and build + ($Oopt_FoldrBuild) ? ('-fdo-foldr-build') : (), + # but do reductions if you see them! "$Oopt_PedanticBottoms", "$Oopt_MonadEtaExpansion", "$Oopt_UnfoldingUseThreshold", @@ -1419,7 +1519,7 @@ It really really wants to be the last STG-to-STG pass that is run. '-fdo-eta-reduction', '-fdo-lambda-eta-expansion', '-freuse-con', - '-flet-to-case', # Aha! + '-flet-to-case', # Aha! Only done after strictness analysis "$Oopt_PedanticBottoms", "$Oopt_MonadEtaExpansion", "$Oopt_UnfoldingUseThreshold", @@ -1449,29 +1549,32 @@ It really really wants to be the last STG-to-STG pass that is run. '-freuse-con', '-flet-to-case', '-fignore-inline-pragma', # **** NB! - '-fdo-inline-foldr-build', # NB + $Oopt_FoldrBuildInline, + ($Oopt_FoldrBuild) ? ('-fdo-foldr-build') : (), + # but still do reductions if you see them! "$Oopt_PedanticBottoms", "$Oopt_MonadEtaExpansion", "$Oopt_UnfoldingUseThreshold", "$Oopt_MaxSimplifierIterations", '\)', -# '-fstatic-args', + # '-fstatic-args', + '-fcalc-inlinings2', # stg2stg passes '-fupdate-analysis', '-flambda-lift', $Oopt_FinalStgProfilingMassage, + $Oopt_StgStats, # flags for stg2stg '-flet-no-escape', - # how do we desugar list comprehensions ? - (($Oopt_FoldrBuild) ? '-ffoldr-build-on' : '' ), - # SPECIAL FLAGS for -O2 - (($OptLevel == 2) ? '-fsemi-tagging' : '') + ($OptLevel == 2) ? ( + '-fsemi-tagging', + ) : (), ); \end{code} @@ -1519,7 +1622,7 @@ C or via equivalent native code)? \begin{code} $RegisteriseC = ( $GccAvailable && $RegisteriseC ne 'no' # not explicitly *un*set... - && ($TargetPlatform =~ /^(alpha|hppa1\.1|i[34]86|m68k|mips|sparc)-/) + && ($TargetPlatform =~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|sparc)-/) ) ? 'o' : ''; \end{code} @@ -1597,7 +1700,46 @@ user-specified flags can clobber them (e.g., \tr{-U__STG_REV_TBLS__}). Note: a few ``always apply'' flags were set at the very beginning. \begin{code} -if ($TargetPlatform =~ /^m68k-/) { +if ($TargetPlatform =~ /^alpha-/) { + # we know how to *mangle* asm for alpha + unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__')); + unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK; + unshift(@CcBoth_flags, ('-static')) if $GccAvailable; + +} elsif ($TargetPlatform =~ /^hppa/) { + # we know how to *mangle* asm for hppa + unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__')); + unshift(@CcBoth_flags, ('-static')) if $GccAvailable; + # We don't put in '-mlong-calls', because it's only + # needed for very big modules (sigh), and we don't want + # to hobble ourselves further on all the other modules + # (most of them). + unshift(@CcBoth_flags, ('-D_HPUX_SOURCE')) if $GccAvailable; + # ___HPUX_SOURCE, not _HPUX_SOURCE, is #defined if -ansi! + # (very nice, but too bad the HP /usr/include files don't agree.) + +} elsif ($TargetPlatform =~ /^i386-/) { + # we know how to *mangle* asm for X86 + unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__')); + unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) + if $StkChkByPageFaultOK && $TargetPlatform !~ /linux/; + # NB: cannot do required signal magic on Linux for such stk chks */ + + unshift(@CcRegd_flags, ('-m486')); # not worth not doing + + # -fno-defer-pop : basically the same game as for m68k + # + # -fomit-frame-pointer : *must* ; because we're stealing + # the fp (%ebp) for our register maps. *All* register + # maps (in MachRegs.lh) must steal it. + + unshift(@CcRegd_flags_hc, '-fno-defer-pop'); + unshift(@CcRegd_flags, '-fomit-frame-pointer'); + unshift(@CcRegd_flags, "-DSTOLEN_X86_REGS=$StolenX86Regs"); + + unshift(@CcBoth_flags, ('-static')) if $GccAvailable; # maybe unnecessary??? + +} elsif ($TargetPlatform =~ /^m68k-/) { # we know how to *mangle* asm for m68k unshift (@CcRegd_flags, ('-D__STG_REV_TBLS__')); unshift (@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK; @@ -1617,49 +1759,16 @@ if ($TargetPlatform =~ /^m68k-/) { # maybe gives reg alloc a better time # also: -fno-defer-pop is not sufficiently well-behaved without it -} elsif ($TargetPlatform =~ /^i[34]86-/) { - # we know how to *mangle* asm for X86 +} elsif ($TargetPlatform =~ /^powerpc-/) { + # we know how to *mangle* asm for PowerPC unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__')); unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK; - unshift(@CcRegd_flags, ('-m486')); # not worth not doing - - # -fno-defer-pop : basically the same game as for m68k - # - # -fomit-frame-pointer : *must* ; because we're stealing - # the fp (%ebp) for our register maps. *All* register - # maps (in MachRegs.lh) must steal it. - - unshift(@CcRegd_flags_hc, '-fno-defer-pop'); - unshift(@CcRegd_flags, '-fomit-frame-pointer'); - unshift(@CcRegd_flags, "-DSTOLEN_X86_REGS=$StolenX86Regs"); - unshift(@CcRegd_flags_hc, "-DMANGLING_X86_SP=$SpX86Mangling"); # only used for checking - # the mangler will insert patch-up code if $StolenX86Regs != 5. - # *** HACK *** of the worst sort. - unshift(@CcBoth_flags, ('-static')) if $GccAvailable; # maybe unnecessary??? } elsif ($TargetPlatform =~ /^sparc-/) { # we know how to *mangle* asm for SPARC unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__')); unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK; -} elsif ($TargetPlatform =~ /^alpha-/) { - # we know how to *mangle* asm for alpha - unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__')); - unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK; - unshift(@CcBoth_flags, ('-static')) if $GccAvailable; - -} elsif ($TargetPlatform =~ /^hppa/) { - # we know how to *mangle* asm for hppa - unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__')); - unshift(@CcBoth_flags, ('-static')) if $GccAvailable; - # We don't put in '-mlong-calls', because it's only - # needed for very big modules (sigh), and we don't want - # to hobble ourselves further on all the other modules - # (most of them). - unshift(@CcBoth_flags, ('-D_HPUX_SOURCE')) if $GccAvailable; - # ___HPUX_SOURCE, not _HPUX_SOURCE, is #defined if -ansi! - # (very nice, but too bad the HP /usr/include files don't agree.) - } elsif ($TargetPlatform =~ /^mips-/) { # we (hope to) know how to *mangle* asm for MIPSen unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__')); @@ -1676,24 +1785,33 @@ not an architecture test. (JSM) \begin{code} unshift(@Ld_flags, ( $TargetPlatform =~ /^alpha-/ - || $TargetPlatform =~ /^mips-sgi-irix/ || $TargetPlatform =~ /^hppa/ + || $TargetPlatform =~ /^mips-sgi-irix/ + || $TargetPlatform =~ /^powerpc-/ || $TargetPlatform =~ /-solaris/ ) - ? ('-u', 'unsafePerformPrimIO_fast1', + ? (($Ld_main) ? ( + '-u', 'Main_' . $Ld_main . '_closure', + ) : (), + '-u', 'unsafePerformPrimIO_fast1', '-u', 'Nil_closure', '-u', 'IZh_static_info', '-u', 'False_inregs_info', '-u', 'True_inregs_info', - '-u', 'CZh_static_info') - - # non-Alphas: - : ('-u', '_unsafePerformPrimIO_fast1', + '-u', 'CZh_static_info', + '-u', 'DEBUG_REGS') # just for fun, now... + + # nice friendly a.out machines... + : (($Ld_main) ? ( + '-u', '_Main_' . $Ld_main . '_closure', + ) : (), + '-u', '_unsafePerformPrimIO_fast1', '-u', '_Nil_closure', '-u', '_IZh_static_info', '-u', '_False_inregs_info', '-u', '_True_inregs_info', - '-u', '_CZh_static_info') + '-u', '_CZh_static_info', + '-u', '_DEBUG_REGS') ); \end{code} @@ -1834,7 +1952,7 @@ if ($Do_lnkr) { local($lnkr) = ( $Lnkr ) ? $Lnkr : ($RegisteriseC ? $CcRegd : $CcUnregd ); local($output)= ($Specific_output_file ne '') ? "-o $Specific_output_file" : ''; - @Files_to_tidy = ( ($Specific_output_file ne '') ? "$Specific_output_file" : 'a.out' ); + @Files_to_tidy = ($Specific_output_file ne '') ? "$Specific_output_file" : 'a.out'; local($to_do) = "$lnkr $Verbose @Ld_flags $output @Link_file $TopClosureFile $libdirs @UserLibrary @SysLibrary"; &run_something($to_do, 'Linker'); @@ -1890,7 +2008,7 @@ EOSCRIPT1 print EXEC <<\EOSCRIPT2; # first, some magical shortcuts to run "commands" on the binary # (which is hidden) -if ($#ARGV == 1 && $ARGV[0] eq '+RTS' && $ARGV[1] =~ /^--(size|file|strip|rm)/ ) { +if ($#ARGV == 1 && $ARGV[0] eq '+RTS' && $ARGV[1] =~ /^--((size|file|strip|rm|nm).*)/ ) { local($cmd) = $1; system("$cmd $pvm_executable"); exit(0); # all done @@ -1919,7 +2037,7 @@ args: while ($a = shift(@ARGV)) { } } -exec "$SysMan $debug $nprocessors @nonPVM_args"; +exec "$SysMan $debug $pvm_executable $nprocessors @nonPVM_args"; print STDERR "Exec failed!!!: $SysMan $debug $nprocessors @nonPVM_args\n"; exit(1); EOSCRIPT2 @@ -2076,7 +2194,7 @@ it fails. } else { local($includes) = '-I' . join(' -I',@Include_dir); local($to_do) = "echo '#line 1 \"$in_lit2pgm\"' > $hscpp_hsp; ". - "$HsCpp $Verbose @HsCpp_flags -D__HASKELL1__=$haskell1_version -D__GLASGOW_HASKELL__=$ghc_version_info $includes $lit2pgm_hscpp >> $hscpp_hsp"; + "$HsCpp $Verbose $genSPECS_flag @HsCpp_flags -D__HASKELL1__=$haskell1_version -D__GLASGOW_HASKELL__=$ghc_version_info $includes $lit2pgm_hscpp >> $hscpp_hsp"; @Files_to_tidy = ( $hscpp_hsp ); &run_something($to_do, 'Haskellised C pre-processor'); } @@ -2262,7 +2380,7 @@ it fails. local($ddebug_flag) = ( $DEBUGging ) ? '-DDEBUG' : ''; if ($RegisteriseC) { $cc = $CcRegd; - $s_output = ($is_hc_file || $TargetPlatform =~ /^hppa/) ? $cc_as_o : $cc_as; + $s_output = ($is_hc_file || $TargetPlatform =~ /^(hppa|i386)/) ? $cc_as_o : $cc_as; $c_flags .= " @CcRegd_flags"; $c_flags .= ($is_hc_file) ? " @CcRegd_flags_hc" : " @CcRegd_flags_c"; } else { @@ -2309,18 +2427,20 @@ EOINCL || $Dump_asm_insn_counts || $Dump_asm_globals_info ) { # dynamically load assembler-fiddling code, which we are about to use - local($target) = ''; - $target = 'alpha' if $TargetPlatform =~ /^alpha-/; - $target = 'hppa' if $TargetPlatform =~ /^hppa/; - $target = 'iX86' if $TargetPlatform =~ /^i[34]86-/; - $target = 'm68k' if $TargetPlatform =~ /^m68k-/; - $target = 'mips' if $TargetPlatform =~ /^mips-/; - $target = 'solaris' if $TargetPlatform =~ /^sparc-sun-solaris2/; - $target = 'sparc' if $TargetPlatform =~ /^sparc-sun-sunos4/; - $target ne '' + local($target) = 'oops'; + $target = '-alpha' if $TargetPlatform =~ /^alpha-/; + $target = '-hppa' if $TargetPlatform =~ /^hppa/; + $target = '' if $TargetPlatform =~ /^i386-/; + $target = '-m68k' if $TargetPlatform =~ /^m68k-/; + $target = '-mips' if $TargetPlatform =~ /^mips-/; + $target = '' if $TargetPlatform =~ /^powerpc-/; + $target = '-solaris' if $TargetPlatform =~ /^sparc-sun-solaris2/; + $target = '-sparc' if $TargetPlatform =~ /^sparc-sun-sunos4/; + + $target ne 'oops' || &tidy_up_and_die(1,"$Pgm: panic: can't decipher $TargetPlatform!\n"); - require("ghc-asm-$target.prl") - || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-$target.prl!\n"); + require("ghc-asm$target.prl") + || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm$target.prl!\n"); } if ( $Dump_raw_asm ) { # to stderr, before mangling @@ -2332,11 +2452,18 @@ EOINCL if ($is_hc_file) { # post-process the assembler [.hc files only] &mangle_asm($cc_as_o, $cc_as); + } elsif ($TargetPlatform =~ /^hppa/) { # minor mangling of non-threaded files for hp-pa only - require("ghc-asm-hppa.prl") + require('ghc-asm-hppa.prl') || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-hppa.prl!\n"); &mini_mangle_asm($cc_as_o, $cc_as); + + } elsif ($TargetPlatform =~ /^i386/) { + # extremely-minor OFFENSIVE mangling of non-threaded just one file + require('ghc-asm.prl') + || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm.prl!\n"); + &mini_mangle_asm($cc_as_o, $cc_as); } } @@ -2436,8 +2563,8 @@ sub run_something { while ( ) { next if /attribute directive ignored/; next if /call-clobbered/; - next if /In file included .*stgdefs/; - next if /from .*rtsdefs.h:/; + next if /from .*COptRegs\.lh/; + next if /from .*(stg|rts)defs\.h:/; next if /from ghc\d+.c:\d+:/; next if /from .*\.lc/; next if /from .*SMinternal\.lh/; @@ -2531,7 +2658,11 @@ sub process_ghc_timings { local($SysSpecificTiming) = 'ghc'; open(STATS, $StatsFile) || die "Failed when opening $StatsFile\n"; + local($tot_live) = 0; # for calculating avg residency + while () { + $tot_live += $1 if /^\s*\d+\s+\d+\s+\d+\.\d+\%\s+(\d+)\s+\d+\.\d+\%/; + $BytesAlloc = $1 if /^\s*([0-9,]+) bytes allocated in the heap/; if ( /^\s*([0-9,]+) bytes maximum residency .* (\d+) sample/ ) { @@ -2549,6 +2680,9 @@ sub process_ghc_timings { } } close(STATS) || die "Failed when closing $StatsFile\n"; + if ( defined($ResidencySamples) && $ResidencySamples > 0 ) { + $AvgResidency = int ($tot_live / $ResidencySamples) ; + } # warn about what we didn't find print STDERR "Warning: BytesAlloc not found in stats file\n" unless defined($BytesAlloc); @@ -2562,6 +2696,7 @@ sub process_ghc_timings { # things we didn't necessarily expect to find $MaxResidency = 0 unless defined($MaxResidency); + $AvgResidency = 0 unless defined($AvgResidency); $ResidencySamples = 0 unless defined($ResidencySamples); # a bit of tidying @@ -2577,7 +2712,7 @@ sub process_ghc_timings { # print out what we found print STDERR "<<$SysSpecificTiming: ", - "$BytesAlloc bytes, $GCs GCs, $MaxResidency bytes residency ($ResidencySamples samples), $InitTime INIT ($InitElapsed elapsed), $MutTime MUT ($MutElapsed elapsed), $GcTime GC ($GcElapsed elapsed)", + "$BytesAlloc bytes, $GCs GCs, $AvgResidency/$MaxResidency avg/max bytes residency ($ResidencySamples samples), $InitTime INIT ($InitElapsed elapsed), $MutTime MUT ($MutElapsed elapsed), $GcTime GC ($GcElapsed elapsed)", " :$SysSpecificTiming>>\n"; # OK, party over