[project @ 1996-01-22 18:59:42 by partain]
[ghc-hetmet.git] / ghc / driver / ghc.lprl
index 2203895..8ccef55 100644 (file)
@@ -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 ( <CCOUT> ) {
            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 (<STATS>) {
+       $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