[project @ 1998-03-16 20:23:24 by sof]
[ghc-hetmet.git] / ghc / driver / ghc.lprl
index 0962efb..d45062b 100644 (file)
@@ -46,8 +46,8 @@ to stdout or stderr, however).
 
 The phase at which to STOP processing is determined by a command-line
 option:
 
 The phase at which to STOP processing is determined by a command-line
 option:
+    -E         stop after generating preprocessed, de-litted Haskell (used in conjunction with -cpp)
     -C         stop after generating C (.hc output)
     -C         stop after generating C (.hc output)
-    -E         stop after generating preprocessed C (.i output)
     -S         stop after generating assembler (.s output)
     -c         stop after generating object files (.o output)
 
     -S         stop after generating assembler (.s output)
     -c         stop after generating object files (.o output)
 
@@ -64,9 +64,9 @@ Other commonly-used options are:
 
     -M          Output the Makefile rules recording the
                 dependencies of a list of Haskell files.
 
     -M          Output the Makefile rules recording the
                 dependencies of a list of Haskell files.
-               (ghc driver just calls upon the help of a
-                 compatible mkdependHS script to do the
-                 actual processing)
+               (ghc driver script calls upon the help of a
+                 compatible mkdependHS script to do the actual
+                processing)
 
 The User's Guide has more information about GHC's *many* options.
 
 
 The User's Guide has more information about GHC's *many* options.
 
@@ -99,11 +99,11 @@ INSTALLING
 
 HOSTPLATFORM TARGETPLATFORM
 
 
 HOSTPLATFORM TARGETPLATFORM
 
-PROJECTNAME PROJECTVERSION PROJECTPATCHLEVEL
+ProjectName ProjectVersion ProjectVersionInt ProjectPatchLevel 
 
 TOP_PWD
 
 
 TOP_PWD
 
-INSTLIBDIR_GHC INSTDATADIR_GHC
+bindir libdir libexecdir datadir
 
 CURRENT_DIR TMPDIR
 
 
 CURRENT_DIR TMPDIR
 
@@ -129,41 +129,15 @@ select(STDERR); $| = 1; select(STDOUT); # no STDERR buffering, please.
 
 $TargetPlatform = $TARGETPLATFORM;
 
 
 $TargetPlatform = $TARGETPLATFORM;
 
-#------------------------------------------------------------------------
-# If you are adjusting paths by hand for a binary GHC distribution,
-# de-commenting the line to set GLASGOW_HASKELL_ROOT should do.
-# Or you can leave it as is, and set the environment variable externally.
-#------------------------------------------------------------------------
-# $ENV{'GLASGOW_HASKELL_ROOT'} = '/some/absolute/path/name';
-
-if (! $ENV{'GLASGOW_HASKELL_ROOT'}) { # good -- death to environment variables
-    $TopPwd        = ${TOP_PWD};
-    $InstLibDirGhc  = ${INSTLIBDIR_GHC};
-    $InstDataDirGhc = ${INSTDATADIR_GHC};
-} else {
-    $TopPwd = $ENV{'GLASGOW_HASKELL_ROOT'};
-
-    if (${INSTLIBDIR_GHC} =~ /.*(\/lib\/ghc\/\d\.\d\d\/[^-]+-[^-]+-[^-]+\/.*)/) {
-       $InstLibDirGhc  = $ENV{'GLASGOW_HASKELL_ROOT'} . $1;
-    } else {
-       print STDERR "GLASGOW_HASKELL_ROOT environment variable is set;\nBut can't untangle $INSTLIBDIR_GHC.\n(Installation error)\n";
-       exit(1);
-    }
-
-    if (${INSTDATADIR_GHC} =~ /.*(\/lib\/ghc\/\d\.\d\d\/.*)/) {
-       $InstDataDirGhc = $ENV{'GLASGOW_HASKELL_ROOT'} . $2;
-    } else {
-       print STDERR "GLASGOW_HASKELL_ROOT environment variable is set;\nBut can't untangle $INSTDATADIR_GHC.\n(Installation error)\n";
-       exit(1);
-    }
-}
-
-if ( $INSTALLING ) {
-    $InstSysLibDir  = $InstDataDirGhc;
-    $InstSysLibDir  =~ s/\/ghc\//\/hslibs\//;
-} else {
-    $InstSysLibDir  = "$TopPwd/hslibs";
-}
+$TopPwd                   = "${TOP_PWD}";
+$InstBinDirGhc     = "${bindir}";
+$InstLibDirGhc     = "${libdir}";
+#
+# Normally the same as InstLibDirGhc, but we accommodate
+# for it being separate.
+#
+$InstLibExecDirGhc = "${libexecdir}";
+$InstDataDirGhc    = "${datadir}";
 
 $Status  = 0; # just used for exit() status
 $Verbose = '';
 
 $Status  = 0; # just used for exit() status
 $Verbose = '';
@@ -186,9 +160,26 @@ if ( $ENV{'TMPDIR'} ) { # where to make tmp file names
     $ENV{'TMPDIR'} = ${TMPDIR}; # set the env var as well
 }
 
     $ENV{'TMPDIR'} = ${TMPDIR}; # set the env var as well
 }
 
+# Some shells run into real trouble when command line and environment
+# gets big (e.g., cmd lines of >4K to /bin/sh causes havoc on our 
+# Solaris-2.5.1 boxes - even though sysconf(_SC_ARG_MAX) reports 1M ...).
+# To work around any such */bin/sh* problems, we will scribble such
+# awfully long command lines into a temp file and exec that temp file
+# with $(REAL_SHELL) (don't use the SHELL variable directly as this
+# will normally get you the wrong thing when the driver is invoked
+# from within `make'). If the REAL_SHELL variable isn't set, you'll
+# get SHELL. This is all a terrible hack. (in case you hadn't reached
+# the same conclusion by now :-)
+#
+# TBC..
+#
+if ( ! $ENV{'REAL_SHELL'} ) {
+    $ENV{'REAL_SHELL'} = $ENV{'SHELL'};
+}
+
 @Files_to_tidy = (); # files we nuke in the case of abnormal termination
 
 @Files_to_tidy = (); # files we nuke in the case of abnormal termination
 
-$Unlit = ( $INSTALLING ) ? "$InstLibDirGhc/unlit"
+$Unlit = ( $INSTALLING ) ? "$InstLibExecDirGhc/unlit"
                         : "$TopPwd/${CURRENT_DIR}/${GHC_UNLIT}";
 
 $Cp   = $CP;
                         : "$TopPwd/${CURRENT_DIR}/${GHC_UNLIT}";
 
 $Cp   = $CP;
@@ -199,16 +190,16 @@ $Cmp  = 'cmp';
 $Time = '';
 
 $HsCpp  = # but this is re-set to "cat" (after options) if -cpp not seen
 $Time = '';
 
 $HsCpp  = # but this is re-set to "cat" (after options) if -cpp not seen
-          ( $INSTALLING ) ? "$InstLibDirGhc/hscpp"
+          ( $INSTALLING ) ? "$InstLibExecDirGhc/hscpp"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSCPP}";
 
 @HsCpp_flags   = ();
 $genSPECS_flag = '';           # See ../utils/hscpp/hscpp.prl
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSCPP}";
 
 @HsCpp_flags   = ();
 $genSPECS_flag = '';           # See ../utils/hscpp/hscpp.prl
-$HsC    = ( $INSTALLING ) ? "$InstLibDirGhc/hsc"
+$HsC    = ( $INSTALLING ) ? "$InstLibExecDirGhc/hsc"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSC}";
 
 # For PVM fiends only
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSC}";
 
 # For PVM fiends only
-$SysMan         = ( $INSTALLING ) ? "$InstLibDirGhc/SysMan"
+$SysMan         = ( $INSTALLING ) ? "$InstLibExecDirGhc/SysMan"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_SYSMAN}";
 
 @Unlit_flags   = ();
                           : "$TopPwd/${CURRENT_DIR}/${GHC_SYSMAN}";
 
 @Unlit_flags   = ();
@@ -242,6 +233,7 @@ sub setupOptFlags {
    $Oopt_FB_Support              = ''; # was '-fdo-arity-expand';
 #  $Oopt_FoldrBuildWW            = 0; # Off by default
    $Oopt_FoldrBuildInline        = ''; # was '-fdo-inline-foldr-build';
    $Oopt_FB_Support              = ''; # was '-fdo-arity-expand';
 #  $Oopt_FoldrBuildWW            = 0; # Off by default
    $Oopt_FoldrBuildInline        = ''; # was '-fdo-inline-foldr-build';
+   $Oopt_ShowSimplifierProgress   = '';
 } # end of setupOptFlags
 
 # Assign defaults to these right away.
 } # end of setupOptFlags
 
 # Assign defaults to these right away.
@@ -274,7 +266,30 @@ $Lnkr              = ''; # "linker" is normally GCC
 $Nm = ($TargetPlatform =~ /^alpha-/) ? 'nm -B' : 'nm';
 \end{code}
 
 $Nm = ($TargetPlatform =~ /^alpha-/) ? 'nm -B' : 'nm';
 \end{code}
 
+Warning packages that are controlled by -W and -Wall.  The 'standard'
+warnings that you get all the time are
+       
+       -fwarn-overlapping-patterns
+       -fwarn-missing-methods
+       -fwarn-duplicate-exports
+
+these are turned off by -Wnot.
+
+\begin{code}
+@StandardWarnings = ('-fwarn-overlapping-patterns', 
+                    '-fwarn-missing-methods',
+                    '-fwarn-duplicate-exports');
+@MinusWOpts              = (@StandardWarnings, 
+                    '-fwarn-incomplete-patterns', 
+                    '-fwarn-unused-binds',
+                    '-fwarn-unused-imports');
+@MinusWallOpts           = (@MinusWOpts, 
+                    '-fwarn-unused-matches',
+                    '-fwarn-name-shadowing');
+\end{code}
+
 What options \tr{-user-setup-a} turn into (user-defined ``packages''
 What options \tr{-user-setup-a} turn into (user-defined ``packages''
+
 of options).  Note that a particular user-setup implies a particular
 Prelude ({\em including} its interface file(s)).
 \begin{code}
 of options).  Note that a particular user-setup implies a particular
 Prelude ({\em including} its interface file(s)).
 \begin{code}
@@ -347,75 +362,6 @@ $BuildTag  = ''; # default is sequential build w/ Appel-style GC
        '_1s', "$WAY_1s_HC_OPTS",
        '_du', "$WAY_B_HC_OPTS" );
 
        '_1s', "$WAY_1s_HC_OPTS",
        '_du', "$WAY_B_HC_OPTS" );
 
-# per-build code fragments which are eval'd
-#%EvaldSetupOpts       = ('',      '', # this one must *not* be set!
-
-#                          # profiled sequential
-#                 '_p',    'push(@HsC_flags,  \'-fscc-profiling\');
-#                           push(@CcBoth_flags, \'-DPROFILING\');',
-
-#                          #and maybe ...
-#                          #push(@CcBoth_flags, '-DPROFILING_DETAIL_COUNTS');
-
-#                          # ticky-ticky sequential
-#                 '_t',    'push(@HsC_flags, \'-fticky-ticky\');
-#                           push(@CcBoth_flags, \'-DTICKY_TICKY\');',
-
-##OLD:                     # unregisterized (ToDo????)
-##                '_u',    '',
-
-#                          # concurrent
-#                 '_mc',   '$StkChkByPageFaultOK = 0;
-#                           push(@HsC_flags,  \'-fconcurrent\');
-#                           push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');
-#                           push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');',
-
-#                          # profiled concurrent
-#                 '_mr',   '$StkChkByPageFaultOK = 0;
-#                           push(@HsC_flags,  \'-fconcurrent\', \'-fscc-profiling\');
-#                           push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');
-#                           push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DPROFILING\');',
-
-#                          # ticky-ticky concurrent
-#                 '_mt',   '$StkChkByPageFaultOK = 0;
-#                           push(@HsC_flags,  \'-fconcurrent\', \'-fticky-ticky\');
-#                           push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');
-#                           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\');',
-
-#                          # GranSim
-#                 '_mg',   '$StkChkByPageFaultOK = 0;
-#                           push(@HsC_flags,  \'-fconcurrent\', \'-fgransim\');
-#                           push(@HsCpp_flags,\'-D__GRANSIM__\',   \'-DGRAN\');
-#                           push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DGRAN\');',
-
-#                 '_2s',   'push (@CcBoth_flags, \'-DGC2s\');',
-#                 '_1s',   'push (@CcBoth_flags, \'-DGC1s\');',
-#                 '_du',   'push (@CcBoth_flags, \'-DGCdu\');',
-
-#                 '_a',    '', # these user-way guys should not be set!
-#                 '_b',    '',
-#                 '_c',    '',
-#                 '_d',    '',
-#                 '_e',    '',
-#                 '_f',    '',
-#                 '_g',    '',
-#                 '_h',    '',
-#                 '_i',    '',
-#                 '_j',    '',
-#                 '_k',    '',
-#                 '_l',    '',
-#                 '_m',    '',
-#                 '_n',    '',
-#                 '_o',    '',
-#                 '_A',    '',
-#                 '_B',    '' );
-
 \end{code}
 
 Import/include directories (\tr{-I} options) are sufficiently weird to
 \end{code}
 
 Import/include directories (\tr{-I} options) are sufficiently weird to
@@ -425,18 +371,15 @@ require special handling.
 @Import_dir    = ('.'); #-i things
 @Include_dir   = ('.'); #-I things; other default(s) stuck on AFTER option processing
 
 @Import_dir    = ('.'); #-i things
 @Include_dir   = ('.'); #-I things; other default(s) stuck on AFTER option processing
 
-# where to look for interface files (system hi's, i.e., prelude and hslibs)
+# where to look for interface files (system hi's, i.e., prelude and syslibs)
 @SysImport_dir = ( $INSTALLING )
 @SysImport_dir = ( $INSTALLING )
-                   ? ( "$InstDataDirGhc/imports" )
-                   : ( "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/required"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/ghc"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/glaExts"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/concurrent" );
+                   ? ( "$InstLibDirGhc/imports/std" )
+                   : ( "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std" );
 
 # We need to look in ghc/ and glaExts/ when searching for implicitly needed .hi files, but 
 # we should really *not* look there for explicitly imported modules.
 
 
 # We need to look in ghc/ and glaExts/ when searching for implicitly needed .hi files, but 
 # we should really *not* look there for explicitly imported modules.
 
-$GhcVersionInfo  = int ($PROJECTVERSION * 100);
+$GhcVersionInfo  = $ProjectVersionInt;
 $Haskell1Version = 4; # i.e., Haskell 1.4
 @Cpp_define     = ();
 
 $Haskell1Version = 4; # i.e., Haskell 1.4
 @Cpp_define     = ();
 
@@ -447,8 +390,8 @@ $Haskell1Version = 4; # i.e., Haskell 1.4
                    ? $InstLibDirGhc
                    : ( "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR"
                      , "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR/gmp"
                    ? $InstLibDirGhc
                    : ( "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR"
                      , "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR/gmp"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/cbits"
+                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std"
+                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std/cbits"
                      )
                  );
 @SysLibrary = (); # will be built up as we go along
                      )
                  );
 @SysLibrary = (); # will be built up as we go along
@@ -459,10 +402,10 @@ $TopClosureFile # defaults to 1.2 one; will be mangled later
 
 # make depend for Haskell
 $MkDependHS
 
 # make depend for Haskell
 $MkDependHS
-       = ( $INSTALLING ) ? "$InstLibDirGhc/mkdependHS"
+       = ( $INSTALLING ) ? "$InstBinDirGhc/mkdependHS"
                          : "$TopPwd/$CURRENT_DIR/$GHC_UTILS_DIR/mkdependHS/mkdependHS";
 # Fill in later
                          : "$TopPwd/$CURRENT_DIR/$GHC_UTILS_DIR/mkdependHS/mkdependHS";
 # Fill in later
-@MkDependHS_flags = ( );
+@MkDependHS_flags = ();
 
 # do_link flag should not be reset while rescanning the cmd-line.
 $Do_lnkr    = 1;
 
 # do_link flag should not be reset while rescanning the cmd-line.
 $Do_lnkr    = 1;
@@ -520,17 +463,20 @@ Here are the initial defaults applied to all files:
 \begin{code}
 $Cpp_flag_set = 0;       # (hack)
 $Only_preprocess_C = 0;          # pretty hackish
 \begin{code}
 $Cpp_flag_set = 0;       # (hack)
 $Only_preprocess_C = 0;          # pretty hackish
-$Only_generate_deps = 0;  #
+$Only_preprocess_hc = 0;  # ditto
+$Only_generate_deps = 0;  # "
 $PostprocessCcOutput = 0;
 
 # native code-gen or via C?
 $HaveNativeCodeGen = $GhcWithNativeCodeGen;
 $HscOut = '-C='; # '-C=' ==> .hc output; '-S=' ==> .s output; '-N=' ==> neither
 $HscOut = '-S='
 $PostprocessCcOutput = 0;
 
 # native code-gen or via C?
 $HaveNativeCodeGen = $GhcWithNativeCodeGen;
 $HscOut = '-C='; # '-C=' ==> .hc output; '-S=' ==> .s output; '-N=' ==> neither
 $HscOut = '-S='
-    if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/;
-$ProduceHi   = '-hifile=';
-$HiOnStdout  = 0;
-$HiDiff_flag = '';
+    if $HaveNativeCodeGen && $TargetPlatform =~ /^(alpha|sparc)-/;
+# TEMP: disable x86  if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/;
+$ProduceHi    = '-hifile=';
+$HiOnStdout   = 0;
+$HiDiff_flag  = '';
+$Keep_HiDiffs = 0;
 
 $CollectingGCstats = 0;
 $CollectGhcTimings = 0;
 
 $CollectingGCstats = 0;
 $CollectGhcTimings = 0;
@@ -581,6 +527,9 @@ $NoImplicitPrelude = 0;
 # and whatever else
 @Cmd_opts  = ();
 
 # and whatever else
 @Cmd_opts  = ();
 
+# cmd line options prefixing the unit we're compiling
+@File_options = ();
+
 \end{code}
 
 We inject consistency-checking information into \tr{.hc} files (both
 \end{code}
 
 We inject consistency-checking information into \tr{.hc} files (both
@@ -595,10 +544,10 @@ $LinkChk = 1;     # set to 0 if the link check should *not* be done
 
 # major & minor version numbers; major numbers must always agree;
 # minor disagreements yield a warning.
 
 # major & minor version numbers; major numbers must always agree;
 # minor disagreements yield a warning.
-$HsC_major_version = 31;
+$HsC_major_version = 33;
 $HsC_minor_version = 0;
 $Cc_major_version  = 36;
 $HsC_minor_version = 0;
 $Cc_major_version  = 36;
-$Cc_minor_version  = 0;
+$Cc_minor_version  = 1;
 
 # options: these must always agree
 $HsC_consist_options = '';    # we record, in this order:
 
 # options: these must always agree
 $HsC_consist_options = '';    # we record, in this order:
@@ -616,37 +565,6 @@ $Cc_consist_options  = '';    # we record, in this order:
 Now slurp through the arguments.
 \begin{code}
 
 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,
-       '-fcompiling-ghc-internals=???', # ToDo!!!!
-        '-O',
-        '-fshow-pragma-name-errs',
-        '-fshow-import-specs',
-        '-fglasgow-exts',
-        '-genSPECS',
-        '-DUSE_FOLDR_BUILD',
-       '-dcore-lint');
-
-    print STDERR "ghc: -user-prelude options:\n", "@ARGV", "\n";
-}
-
 &initDriverGlobals();
 &splitCmdLine(@ARGV);
 # Run through the cmd-line first time.
 &initDriverGlobals();
 &splitCmdLine(@ARGV);
 # Run through the cmd-line first time.
@@ -658,6 +576,11 @@ if (  $Status == 0 && $Only_generate_deps ) {
 
     push (@MkDependHS_flags, "-o$Osuffix") if $Osuffix;
     push (@MkDependHS_flags, "-s$BuildTag") if $BuildTag;
 
     push (@MkDependHS_flags, "-o$Osuffix") if $Osuffix;
     push (@MkDependHS_flags, "-s$BuildTag") if $BuildTag;
+    push (@MkDependHS_flags, "-D__HASKELL1__=$Haskell1Version");
+    # They're not (currently) needed, but we need to quote any -#include options
+    foreach (@Cmd_opts) {
+       s/-#include.*$/'$&'/g;
+    };
     local($to_do) = "$MkDependHS @MkDependHS_flags -- @Cmd_opts -- @Input_file" ;
     &run_something($to_do, 'Haskell dependencies');
     exit $Status;
     local($to_do) = "$MkDependHS @MkDependHS_flags -- @Cmd_opts -- @Input_file" ;
     &run_something($to_do, 'Haskell dependencies');
     exit $Status;
@@ -762,22 +685,30 @@ sub setupOptimiseFlags {
 
    @HsC_minusNoO_flags 
     = (        '-fsimplify',
 
    @HsC_minusNoO_flags 
     = (        '-fsimplify',
-         '\(',
+         '[',
          $Oopt_FB_Support,
          $Oopt_FB_Support,
-#        '-falways-float-lets-from-lets',      # no idea why this was here (WDP 95/09)
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          '-fcase-of-case',
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          '-fcase-of-case',
+         '-fdo-case-elim',
 #        '-fdo-lambda-eta-expansion',  # too complicated
          '-freuse-con',
 #        '-fdo-lambda-eta-expansion',  # too complicated
          '-freuse-con',
-#        '-flet-to-case',      # no strictness analysis, so...
+#        '-flet-to-case',              # no strictness analysis, so...
          $Oopt_PedanticBottoms,
 #        $Oopt_MonadEtaExpansion,      # no thanks
          $Oopt_PedanticBottoms,
 #        $Oopt_MonadEtaExpansion,      # no thanks
-         '-fsimpl-uf-use-threshold0',
-         '-fessential-unfoldings-only',
-#        $Oopt_UnfoldingUseThreshold,  # no thanks
+
+# These two work fine, if you really want no simplification at all,
+# for bizarre test reasons.  But you get really terrible code if you use them,
+#      for example: let x = e in x
+# with dozens of redundant thunks etc.  So I'm leaving them out.
+#
+#        '-fsimpl-uf-use-threshold0',
+#        '-fessential-unfoldings-only',
+
+         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
        $Oopt_AddAutoSccs,
 #      '-ffull-laziness',      # removed 95/04 WDP following Andr\'e's lead
        
        $Oopt_AddAutoSccs,
 #      '-ffull-laziness',      # removed 95/04 WDP following Andr\'e's lead
        
@@ -790,14 +721,29 @@ sub setupOptimiseFlags {
 
        # initial simplify: mk specialiser happy: minimum effort please
        '-fsimplify',
 
        # initial simplify: mk specialiser happy: minimum effort please
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-fkeep-spec-pragma-ids',     # required before specialisation
          $Oopt_FB_Support,
          '-fkeep-spec-pragma-ids',     # required before specialisation
-         '-fsimpl-uf-use-threshold0',
-         '-fessential-unfoldings-only',
+
+# I don't understand why we want -fessential-unfoldings-only here
+# If we have it, the following nasty thing happens:
+#      f  = E
+#      g* = f
+#      ...g...
+# where "*" means exported.
+# In the essential-unfoldings pass we still substitute f for g
+# but we don't substitute E for f first.  So we get
+#      f  = E
+#      g* = f
+#      ...f...
+# The g=f will get reverse-substituted later, but it's untidy.
+#
+#        '-fessential-unfoldings-only',
+#        '-fsimpl-uf-use-threshold0',
+
          '-fmax-simplifier-iterations1',
          $Oopt_PedanticBottoms,
          '-fmax-simplifier-iterations1',
          $Oopt_PedanticBottoms,
-         '\)',
+         ']',
 
        ($Oopt_DoSpecialise) ? (
          '-fspecialise-overloaded',
 
        ($Oopt_DoSpecialise) ? (
          '-fspecialise-overloaded',
@@ -806,7 +752,7 @@ sub setupOptimiseFlags {
        ) : (),
 
        '-fsimplify',                   # need dependency anal after specialiser ...
        ) : (),
 
        '-fsimplify',                   # need dependency anal after specialiser ...
-         '\(',                         # need tossing before calc-inlinings ...
+         '[',                  # need tossing before calc-inlinings ...
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -820,7 +766,8 @@ sub setupOptimiseFlags {
          $Oopt_MonadEtaExpansion,
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_MonadEtaExpansion,
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
 
 #LATER:        '-fcalc-inlinings1', -- pointless for 2.01
 
 
 #LATER:        '-fcalc-inlinings1', -- pointless for 2.01
 
@@ -828,7 +775,7 @@ sub setupOptimiseFlags {
 #              '-ffoldr-build-ww-anal',
 #              '-ffoldr-build-worker-wrapper',
 #              '-fsimplify', 
 #              '-ffoldr-build-ww-anal',
 #              '-ffoldr-build-worker-wrapper',
 #              '-fsimplify', 
-#                '\(', 
+#                '[', 
 #                $Oopt_FB_Support,
 #                '-ffloat-lets-exposing-whnf',
 #                '-ffloat-primops-ok',
 #                $Oopt_FB_Support,
 #                '-ffloat-lets-exposing-whnf',
 #                '-ffloat-primops-ok',
@@ -842,7 +789,8 @@ sub setupOptimiseFlags {
 #                $Oopt_MonadEtaExpansion,
 #                $Oopt_UnfoldingUseThreshold,
 #                $Oopt_MaxSimplifierIterations,
 #                $Oopt_MonadEtaExpansion,
 #                $Oopt_UnfoldingUseThreshold,
 #                $Oopt_MaxSimplifierIterations,
-#                '\)',
+#                $Oopt_ShowSimplifierProgress,
+#                ']',
 #       ) : (),
 
        # this pass-ordering sequence was agreed by Simon and Andr\'e
 #       ) : (),
 
        # this pass-ordering sequence was agreed by Simon and Andr\'e
@@ -853,7 +801,7 @@ sub setupOptimiseFlags {
          '-ffoldr-build-on',           # desugar list comprehensions for foldr/build
 
          '-fsimplify', 
          '-ffoldr-build-on',           # desugar list comprehensions for foldr/build
 
          '-fsimplify', 
-           '\(', 
+           '[', 
            '-fignore-inline-pragma',   # **** NB!
            '-fdo-foldr-build',         # NB
            $Oopt_FB_Support,
            '-fignore-inline-pragma',   # **** NB!
            '-fdo-foldr-build',         # NB
            $Oopt_FB_Support,
@@ -869,13 +817,14 @@ sub setupOptimiseFlags {
            $Oopt_MonadEtaExpansion,
            $Oopt_UnfoldingUseThreshold,
            $Oopt_MaxSimplifierIterations,
            $Oopt_MonadEtaExpansion,
            $Oopt_UnfoldingUseThreshold,
            $Oopt_MaxSimplifierIterations,
-           '\)',
+           $Oopt_ShowSimplifierProgress,
+           ']',
        ) : (),
 
        '-ffloat-inwards',
 
        '-fsimplify',
        ) : (),
 
        '-ffloat-inwards',
 
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -893,12 +842,13 @@ sub setupOptimiseFlags {
          $Oopt_MonadEtaExpansion,
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_MonadEtaExpansion,
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
 
        '-fstrictness',
 
        '-fsimplify',
 
        '-fstrictness',
 
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -913,7 +863,8 @@ sub setupOptimiseFlags {
          $Oopt_MonadEtaExpansion,
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_MonadEtaExpansion,
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
 
        '-ffloat-inwards',
 
 
        '-ffloat-inwards',
 
@@ -922,12 +873,12 @@ sub setupOptimiseFlags {
 
 #      ( ($OptLevel != 2)
 #        ? ''
 
 #      ( ($OptLevel != 2)
 #        ? ''
-#      : "-fliberate-case -fsimplify \\( $Oopt_FB_Support -ffloat-lets-exposing-whnf -ffloat-primops-ok -fcase-of-case -fdo-case-elim -fcase-merge -fdo-eta-reduction -fdo-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MonadEtaExpansion $Oopt_UnfoldingUseThreshold $Oopt_MaxSimplifierIterations \\)" ),
+#      : "-fliberate-case -fsimplify [ $Oopt_FB_Support -ffloat-lets-exposing-whnf -ffloat-primops-ok -fcase-of-case -fdo-case-elim -fcase-merge -fdo-eta-reduction -fdo-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MonadEtaExpansion $Oopt_UnfoldingUseThreshold $Oopt_MaxSimplifierIterations $Oopt_ShowSimplifierProgress ]" ),
 
 # Final clean-up simplification:
 
        '-fsimplify',
 
 # Final clean-up simplification:
 
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -946,7 +897,8 @@ sub setupOptimiseFlags {
          $Oopt_MonadEtaExpansion,
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_MonadEtaExpansion,
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
 
       #        '-fstatic-args',
 
 
       #        '-fstatic-args',
 
@@ -993,6 +945,8 @@ if ( $OptLevel <= 0 ) {
 } else { # -Ofile, then...
 
     &add_Hsc_flags( @HsC_minusO3_flags );
 } else { # -Ofile, then...
 
     &add_Hsc_flags( @HsC_minusO3_flags );
+    push(@HsC_flags, $Oopt_FinalStgProfilingMassage) if $Oopt_FinalStgProfilingMassage;
+
     push(@CcBoth_flags, ($MinusO2ForC) ? '-O2' : '-O');        # possibly to be elaborated...
 }
 
     push(@CcBoth_flags, ($MinusO2ForC) ? '-O2' : '-O');        # possibly to be elaborated...
 }
 
@@ -1027,6 +981,9 @@ sub setupBuildFlags {
 
       $Oopt_FinalStgProfilingMassage = '-fmassage-stg-for-profiling';
 
 
       $Oopt_FinalStgProfilingMassage = '-fmassage-stg-for-profiling';
 
+      # Ignore user sccs when auto annotating, but warn when doing so.
+      $PROFignore_scc = '-W' if $PROFauto; 
+
       push(@HsP_flags, (($PROFignore_scc) ? $PROFignore_scc : '-S'));
 
       if ( $SplitObjFiles ) {
       push(@HsP_flags, (($PROFignore_scc) ? $PROFignore_scc : '-S'));
 
       if ( $SplitObjFiles ) {
@@ -1109,8 +1066,8 @@ Decide what the consistency-checking options are in force for this run:
        $Tag = "${Tag}_" if $Tag ne '';
        $HiSuffix_prelude="${Tag}hi";
   }
        $Tag = "${Tag}_" if $Tag ne '';
        $HiSuffix_prelude="${Tag}hi";
   }
-  push(@HsC_flags, "-hisuf-prelude=.${HiSuffix_prelude}"); # use appropriate Prelude .hi files
-  push(@HsC_flags, "-hisuf=.${HiSuffix}");
+  #push(@HsC_flags, "-hisuf-prelude=.${HiSuffix_prelude}"); # use appropriate Prelude .hi files
+  #push(@HsC_flags, "-hisuf=.${HiSuffix}");
 
 } # setupBuildFlags
 \end{code}
 
 } # setupBuildFlags
 \end{code}
@@ -1155,7 +1112,10 @@ sub setupMachOpts {
   } elsif ($TargetPlatform =~ /^i386-/) {
       # we know how to *mangle* asm for X86
       unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
   } 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;
+      unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK && $TargetPlatform !~ /nextstep/;
+      # I do not know how to do STACK_CHECK_BY_PAGE_FAULT
+      # on NeXTs (my fault, not theirs), so I don't.
+      # CaS
 
       # -fno-defer-pop : basically the same game as for m68k
       #
 
       # -fno-defer-pop : basically the same game as for m68k
       #
@@ -1170,7 +1130,10 @@ sub setupMachOpts {
   } elsif ($TargetPlatform =~ /^m68k-/) {
       # we know how to *mangle* asm for m68k
       unshift (@CcRegd_flags, ('-D__STG_REV_TBLS__'));
   } 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;
+      unshift (@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK && $TargetPlatform !~ /nextstep/;
+      # I do not know how to do STACK_CHECK_BY_PAGE_FAULT
+      # on NeXTs (my fault, not theirs), so I don't.
+      # CaS
 
       # -fno-defer-pop : for the .hc files, we want all the pushing/
       #    popping of args to routines to be explicit; if we let things
 
       # -fno-defer-pop : for the .hc files, we want all the pushing/
       #    popping of args to routines to be explicit; if we let things
@@ -1193,13 +1156,12 @@ sub setupMachOpts {
       unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK;
       unshift(@CcBoth_flags,  ('-static'));
 
       unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK;
       unshift(@CcBoth_flags,  ('-static'));
 
-  } elsif ($TargetPlatform =~ /^powerpc-/) {
+  } elsif ($TargetPlatform =~ /^powerpc-|^rs6000-/) {
       # we know how to *mangle* asm for PowerPC
       # we know how to *mangle* asm for PowerPC
-      unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
+# :-(   unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
       unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK;
       unshift(@CcBoth_flags,  ('-static')); # always easier to start with
       unshift(@CcRegd_flags, ('-finhibit-size-directive')); # avoids traceback tables
       unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK;
       unshift(@CcBoth_flags,  ('-static')); # always easier to start with
       unshift(@CcRegd_flags, ('-finhibit-size-directive')); # avoids traceback tables
-
   } elsif ($TargetPlatform =~ /^sparc-/) {
       # we know how to *mangle* asm for SPARC
       unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
   } elsif ($TargetPlatform =~ /^sparc-/) {
       # we know how to *mangle* asm for SPARC
       unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
@@ -1209,6 +1171,23 @@ sub setupMachOpts {
 } # end of setupMachOpts
 \end{code}
 
 } # end of setupMachOpts
 \end{code}
 
+%************************************************************************
+%*                                                                     *
+\subsection{Set up for warnings}
+%*                                                                     *
+%************************************************************************
+
+Several warnings are turned on by default.  These are supposed to be
+the 'I'm pretty sure you've made a mistake here' kind of warnings.
+The rest are turned on by the -W and -Wall options, or individually
+via their -fwarn and -fno-warn flags.
+
+\begin{code}
+sub setupWarningFlags {
+&add_Hsc_flags( @StandardWarnings );
+}
+\end{code}
+
 Same unshifting magic, but for special linker flags.
 
 The configure script determines whether the object file symbol tables
 Same unshifting magic, but for special linker flags.
 
 The configure script determines whether the object file symbol tables
@@ -1221,19 +1200,20 @@ sub setupLinkOpts {
   local($uscore) = ( ${LeadingUnderscore} eq 'YES' ) ? '_' : '';
 
   unshift(@Ld_flags,
   local($uscore) = ( ${LeadingUnderscore} eq 'YES' ) ? '_' : '';
 
   unshift(@Ld_flags,
-        (($Ld_main) ? (
-          '-u', "${uscore}Main_" . $Ld_main . '_closure',
-        ) : ()
-# What are these? -- SOF
-#         , '-u', "${uscore}STbase_unsafePerformPrimIO_fast1"
-#         , '-u', "${uscore}Prelude_Z91Z93_closure"     # i.e., []
-#         , '-u', "${uscore}Prelude_IZh_static_info"
-#         , '-u', "${uscore}Prelude_False_inregs_info"
-#         , '-u', "${uscore}Prelude_True_inregs_info"
-#         , '-u', "${uscore}Prelude_CZh_static_info"
-#         , '-u', "${uscore}DEBUG_REGS"
-       ))
-         ; # just for fun, now...
+        (($Ld_main) ? ( '-u', "${uscore}Main_" . $Ld_main . '_closure' ) : ()));
+  unshift(@Ld_flags,
+       (  '-u', "${uscore}PrelBase_Z91Z93_closure"      # i.e., []
+          ,'-u', "${uscore}PrelBase_IZh_static_info"
+          ,'-u', "${uscore}PrelBase_CZh_static_info"
+          ,'-u', "${uscore}PrelBase_False_inregs_info"
+          ,'-u', "${uscore}PrelBase_True_inregs_info"
+          ,'-u', "${uscore}DEBUG_REGS"
+       ));
+  if ($TargetPlatform =~ /^powerpc-|^rs6000-/) {
+    # sometimes we have lots of toc entries...
+    #  unshift(@Ld_flags, ('-Xlinker -bbigtoc -Xlinker -bnoquiet')); 
+    unshift(@Ld_flags, ('-Xlinker -bbigtoc')); 
+  }
 
 } # end of setupLinkOpts
 
 
 } # end of setupLinkOpts
 
@@ -1256,7 +1236,7 @@ sub setupIncPaths {
       push (@Include_dir, "$TopPwd/${CURRENT_DIR}/${GHC_INCLUDE_DIR}");
   } else {
       push (@Include_dir, "$InstLibDirGhc/includes");
       push (@Include_dir, "$TopPwd/${CURRENT_DIR}/${GHC_INCLUDE_DIR}");
   } else {
       push (@Include_dir, "$InstLibDirGhc/includes");
-      push (@Include_dir, "$InstDataDirGhc/includes");
+      push (@Include_dir, "$InstLibDirGhc/includes");
   }
 } # end of setupIncPaths
 \end{code}
   }
 } # end of setupIncPaths
 \end{code}
@@ -1348,8 +1328,8 @@ if ($#Input_file < 0 && $#Link_file < 0) {
     @Input_file = ( '-' );
 
     open(INF, "> $Tmp_prefix.hs") || &tidy_up_and_die(1,"Can't open $Tmp_prefix.hs\n");
     @Input_file = ( '-' );
 
     open(INF, "> $Tmp_prefix.hs") || &tidy_up_and_die(1,"Can't open $Tmp_prefix.hs\n");
-    print STDERR "Enter your Haskell program, end with ^D (on a line of its own):\n";
-    while (<>) { print INF $_; }
+    print STDERR "Enter your Haskell program, end with ^D (on a line of its own):\n" if -t;
+    while (<STDIN>) { print INF $_; }
     close(INF) || &tidy_up_and_die(1,"Failed writing to $Tmp_prefix.hs\n");
 }
 
     close(INF) || &tidy_up_and_die(1,"Failed writing to $Tmp_prefix.hs\n");
 }
 
@@ -1357,7 +1337,7 @@ if ($#Input_file < 0 && $#Link_file < 0) {
 
 Tell the world who we are, if they asked.
 \begin{code}
 
 Tell the world who we are, if they asked.
 \begin{code}
-print STDERR "${PROJECTNAME}, version ${PROJECTVERSION} ${PROJECTPATCHLEVEL}\n"
+print STDERR "${ProjectName}, version ${ProjectVersion}, patchlevel ${ProjectPatchLevel}\n"
     if $Verbose;
 \end{code}
 
     if $Verbose;
 \end{code}
 
@@ -1400,8 +1380,14 @@ if ($Do_lnkr) {
     # for a linker, use an explicitly given one, or the going C compiler ...
     local($lnkr) = ( $Lnkr ) ? $Lnkr : $CcRegd;
 
     # for a linker, use an explicitly given one, or the going C compiler ...
     local($lnkr) = ( $Lnkr ) ? $Lnkr : $CcRegd;
 
+    if ( ($Specific_output_file eq '') && 
+         ($TargetPlatform eq 'i386-unknown-cygwin32') ) {
+         $Specific_output_file = 'main.exe';
+         print STDERR "Output file not specified, defaulting to \"main.exe\"\n";
+    }
+
     local($output) = ($Specific_output_file ne '') ? "-o $Specific_output_file" : '';
     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');
 
     local($to_do) = "$lnkr $Verbose @Ld_flags $output @Link_file $TopClosureFile $libdirs @UserLibrary @SysLibrary";
     &run_something($to_do, 'Linker');
@@ -1448,7 +1434,7 @@ eval 'exec perl -S \$0 \${1+"\$@"}'
   if \$running_under_some_shell;
 # =!=!=!=!=!=!=!=!=!=!=!
 # This script is automatically generated: DO NOT EDIT!!!
   if \$running_under_some_shell;
 # =!=!=!=!=!=!=!=!=!=!=!
 # This script is automatically generated: DO NOT EDIT!!!
-# Generated by Glasgow Haskell, version ${PROJECTVERSION} ${PROJECTPATCHLEVEL}
+# Generated by Glasgow Haskell, version ${ProjectVersion} ${ProjectPatchLevel}
 #
 \$pvm_executable      = '$pvm_executable';
 \$pvm_executable_base = '$pvm_executable_base';
 #
 \$pvm_executable      = '$pvm_executable';
 \$pvm_executable_base = '$pvm_executable_base';
@@ -1569,26 +1555,32 @@ Again, we'll do the post-recompilation-checker parts of this later.
 
     local($is_hc_file) = 1; #Is the C code .hc or .c? Assume .hc for now
 
 
     local($is_hc_file) = 1; #Is the C code .hc or .c? Assume .hc for now
 
-    $lit2pgm_hscpp = $ifile if ($ifile =~ /\.hs$/);
+    # OK, let's strip off some literate junk..
+    if ($do_lit2pgm) {
+        &runLit2pgm($in_lit2pgm, $lit2pgm_hscpp)
+    } else {
+        $lit2pgm_hscpp = $ifile;
+    }
 
 
-    # OK, let's strip off some literate junk:
-    &runLit2pgm($in_lit2pgm, $lit2pgm_hscpp) if ($ifile =~ /\.lhs$/);
     #
     @File_options = ();
 
     # Scan the top of the de-litted file for {-# OPTIONS #-} pragmas
     #
     @File_options = ();
 
     # Scan the top of the de-litted file for {-# OPTIONS #-} pragmas
-    &check_for_source_options($lit2pgm_hscpp);
-    # options found in the source file take a back seat, i.e., we scan
+    &check_for_source_options($lit2pgm_hscpp,$ifile);
+
+    # Options found in the source file take a back seat, i.e., we scan
     # them first. Only process the command line again if source file
     # contained anything of interest *or* there's more than one
     # input file (we have to reset the options).
     #
     if ( $#Input_file >= 0 || $#File_options >= 0) {
     # them first. Only process the command line again if source file
     # contained anything of interest *or* there's more than one
     # input file (we have to reset the options).
     #
     if ( $#Input_file >= 0 || $#File_options >= 0) {
-        @File_options = (@File_options, @Cmd_opts);
+        #@File_options = (@File_options, @Cmd_opts);
 
         # Now process the command line
         &initDriverGlobals();
 
         # Now process the command line
         &initDriverGlobals();
-        &processArgs(@File_options);
+        &processArgs((@File_options,@Cmd_opts));
+       print STDERR "\nEffective command line: " .
+                    join(' ',(@File_options,@Cmd_opts)) . "\n" if $Verbose;
     }
     #
     # Having got the effective command line scanned, set up
     }
     #
     # Having got the effective command line scanned, set up
@@ -1602,6 +1594,7 @@ Again, we'll do the post-recompilation-checker parts of this later.
     &setupOptimiseFlags();
     &setupMachOpts();
     &setupIncPaths();
     &setupOptimiseFlags();
     &setupMachOpts();
     &setupIncPaths();
+    &setupWarningFlags();
     &setupHeapStackSize();
 
     #
     &setupHeapStackSize();
 
     #
@@ -1616,7 +1609,12 @@ Again, we'll do the post-recompilation-checker parts of this later.
     local($do_as)      = $Do_as;
     local($hsc_out)      = ( $HscOut eq '-C=' ) ? "$Tmp_prefix.hc" : "$Tmp_prefix.s" ;
 
     local($do_as)      = $Do_as;
     local($hsc_out)      = ( $HscOut eq '-C=' ) ? "$Tmp_prefix.hc" : "$Tmp_prefix.s" ;
 
-    if ($ifile =~ /.lhs$/ || $ifile =~ /.hs$/ ) {
+    if ($Only_preprocess_hc) { # stop after having run $Cc -E
+       $do_as=0;
+    }
+    if ($Only_preprocess_C)     { # stop after having run $hscpp
+       $do_hsc=0; $do_cc = 0; $do_as=0;
+    } elsif ($ifile =~ /.lhs$/ || $ifile =~ /.hs$/ ) {
        ;
     } elsif ($ifile =~ /\.hc$/ || $ifile =~ /_hc$/ ) { # || $ifile =~ /\.$Isuffix$/o) # ToDo: better
        $do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
        ;
     } elsif ($ifile =~ /\.hc$/ || $ifile =~ /_hc$/ ) { # || $ifile =~ /\.$Isuffix$/o) # ToDo: better
        $do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
@@ -1634,8 +1632,8 @@ Again, we'll do the post-recompilation-checker parts of this later.
     # hack to avoid running hscpp
     $HsCpp = $Cat if ! $Cpp_flag_set;
 
     # hack to avoid running hscpp
     $HsCpp = $Cat if ! $Cpp_flag_set;
 
-    &runHscpp($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc)
-       if $do_hscpp;
+    &runHscpp($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) if $do_hscpp;
+
 \end{code}
 
 We now think about whether to run hsc/cc or not (when hsc produces .s
 \end{code}
 
 We now think about whether to run hsc/cc or not (when hsc produces .s
@@ -1644,6 +1642,7 @@ stuff, it effectively takes the place of both phases).
 To get the output file name right: for each phase that we are {\em
 not} going to run, set its input (i.e., the output of its preceding
 phase) to @"$ifile_root.<suffix>"@.
 To get the output file name right: for each phase that we are {\em
 not} going to run, set its input (i.e., the output of its preceding
 phase) to @"$ifile_root.<suffix>"@.
+
 \begin{code}
     local($going_interactive) = $HscOut eq '-N=' || $ifile_root eq '_stdin';
 
 \begin{code}
     local($going_interactive) = $HscOut eq '-N=' || $ifile_root eq '_stdin';
 
@@ -1652,7 +1651,7 @@ phase) to @"$ifile_root.<suffix>"@.
     # -fvia-C (or the equivalent)
     #
     if ( $HscOut ne '-C=' && $Keep_hc_file_too ) {
     # -fvia-C (or the equivalent)
     #
     if ( $HscOut ne '-C=' && $Keep_hc_file_too ) {
-       print STDERR "Warning: Native code generator to be used, -keep-hc-file-too will be ignored\n";
+       print STDERR "$Pgm: warning: Native code generator to be used, -keep-hc-file-too will be ignored\n";
     }
 
     if (! $do_cc && ! $do_as) { # stopping after hsc
     }
 
     if (! $do_cc && ! $do_as) { # stopping after hsc
@@ -1666,7 +1665,7 @@ phase) to @"$ifile_root.<suffix>"@.
     if (! $do_as) { # stopping after gcc (or hsc)
        $cc_as = ($Specific_output_file ne '')
                 ? $Specific_output_file
     if (! $do_as) { # stopping after gcc (or hsc)
        $cc_as = ($Specific_output_file ne '')
                 ? $Specific_output_file
-                : &odir_ify($ifile_root, ( $Only_preprocess_C ) ? 'i' : 's');
+                : &odir_ify($ifile_root, ( $Only_preprocess_hc ) ? 'i' : 's');
 
        $ofile_target = $cc_as; # reset
     }
 
        $ofile_target = $cc_as; # reset
     }
@@ -1684,11 +1683,13 @@ Now the Haskell compiler, C compiler, and assembler
 
     if ($do_cc) {
        &runGcc    ($is_hc_file, $hsc_out, $cc_as_o);
 
     if ($do_cc) {
        &runGcc    ($is_hc_file, $hsc_out, $cc_as_o);
-       &runMangler($is_hc_file, $cc_as_o, $cc_as, $ifile_root);
+       &runMangler($is_hc_file, $cc_as_o, $cc_as, $ifile_root) if ! $Only_preprocess_hc;
     }
 
     &split_asm_file($cc_as)  if $do_as && $SplitObjFiles;
 
     }
 
     &split_asm_file($cc_as)  if $do_as && $SplitObjFiles;
 
+    # save a copy of the .s file..
+    &saveIntermediate($ifile_root , "s" , $cc_as) if ($do_as && $Keep_s_file_too);
     &runAs($as_out, $ifile_root) if $do_as;
 \end{code}
 
     &runAs($as_out, $ifile_root) if $do_as;
 \end{code}
 
@@ -1699,10 +1700,15 @@ Finally, decide what to queue up for linker input.
 
 #ToDo:    local($or_isuf) = ($Isuffix eq '') ? '' : "|$Isuffix";
 
 
 #ToDo:    local($or_isuf) = ($Isuffix eq '') ? '' : "|$Isuffix";
 
-    if ( $ifile !~ /\.(lhs|hs|hc|c|s)$/ && $ifile !~ /_hc$/ ) {
-       print STDERR "$Pgm: don't recognise suffix on `$ifile'; passing it through to linker\n"
-           if $ifile !~ /\.a$/;
 
 
+    if ( $ifile !~ /\.(lhs|hs|hc|c|s|a)$/ && $ifile !~ /_hc$/ ) {
+        # There's sometimes confusion regarding .hi files; users
+       # supplying them on the command line.
+        if ( $ifile =~ /\.hi$/ ) {
+           print STDERR "$Pgm: warning: found `$ifile' on command line; interface files should not be supplied here - ignoring it.\n";
+        } else {
+          print STDERR "$Pgm: don't recognise suffix on `$ifile'; passing it through to linker\n";
+        }
        # oops; we tentatively pushed the wrong thing; fix & do the right thing
        pop(@Link_file); push(@Link_file, $ifile);
     }
        # oops; we tentatively pushed the wrong thing; fix & do the right thing
        pop(@Link_file); push(@Link_file, $ifile);
     }
@@ -1721,9 +1727,13 @@ Finally, decide what to queue up for linker input.
 sub runLit2pgm {
     local($in_lit2pgm, $lit2pgm_hscpp) = @_;
 
 sub runLit2pgm {
     local($in_lit2pgm, $lit2pgm_hscpp) = @_;
 
-    local($to_do) = "echo '#line 1 \"$in_lit2pgm\"' > $lit2pgm_hscpp && ".
-                   "$Unlit @Unlit_flags $in_lit2pgm -  >> $lit2pgm_hscpp";
-    @Files_to_tidy = ( $lit2pgm_hscpp );
+    local($to_do) = "";
+
+    # Only add #line pragma if we're going to need it.
+    $to_do  = "echo '#line 1 \"$in_lit2pgm\"' > $lit2pgm_hscpp && " if ($Cpp_flag_set);
+    $to_do .= "$Unlit @Unlit_flags $in_lit2pgm -  >> $lit2pgm_hscpp";
+     
+    push(@Files_to_tidy, $lit2pgm_hscpp );
 
     &run_something($to_do, 'literate pre-processor');
 }
 
     &run_something($to_do, 'literate pre-processor');
 }
@@ -1733,20 +1743,32 @@ sub runLit2pgm {
 sub runHscpp {
     local($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) = @_;
 
 sub runHscpp {
     local($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) = @_;
 
-    local($to_do);
+    local($to_do) = "";
+
+    # Strictly speaking, echoing of the following line pragma is only required
+    # on non-delit'ed input, as we've already added it during de-lit. However,
+    # hscpp will then add a {-# LINE 1 "$lit2pgm_hsc" -} to the top of the file,
+    # which is not very informative (but harmless). Hence, we uniformly have
+    # {-# LINE 1 "$in_lit2pgm" #-} as the first line to all cpp'ed hsc input.
+    #
+    $to_do = "echo '{-# LINE 1 \"$in_lit2pgm\" -}' > $hscpp_hsc && ";
 
     if ($HsCpp eq $Cat) {
 
     if ($HsCpp eq $Cat) {
-       $to_do = "echo '#line 1 \"$in_lit2pgm\"' > $hscpp_hsc && ".
-                       "$HsCpp $lit2pgm_hscpp >> $hscpp_hsc";
-       @Files_to_tidy = ( $hscpp_hsc );
+       $to_do .= "$HsCpp $lit2pgm_hscpp >> $hscpp_hsc";
+       push(@Files_to_tidy, $hscpp_hsc );
        &run_something($to_do, 'Ineffective C pre-processor');
     } else {
        local($includes) = '-I' . join(' -I',@Include_dir);
        &run_something($to_do, 'Ineffective C pre-processor');
     } else {
        local($includes) = '-I' . join(' -I',@Include_dir);
-       $to_do = "echo '#line 1 \"$in_lit2pgm\"' > $hscpp_hsc && ".
-                       "$HsCpp $Verbose $genSPECS_flag @HsCpp_flags -D__HASKELL1__=$Haskell1Version -D__GLASGOW_HASKELL__=$GhcVersionInfo $includes $lit2pgm_hscpp >> $hscpp_hsc";
-       @Files_to_tidy = ( $hscpp_hsc );
+       $to_do .= "$HsCpp $Verbose $genSPECS_flag @HsCpp_flags -D__HASKELL1__=$Haskell1Version -D__GLASGOW_HASKELL__=$GhcVersionInfo $includes $lit2pgm_hscpp >> $hscpp_hsc";
+       push(@Files_to_tidy, $hscpp_hsc );
        &run_something($to_do, 'Haskellised C pre-processor');
     }
        &run_something($to_do, 'Haskellised C pre-processor');
     }
+   
+    if ( $Only_preprocess_C ) {
+       $to_do = "$Cat $hscpp_hsc";
+       &run_something($to_do, '');
+    }
+
 }
 \end{code}
 
 }
 \end{code}
 
@@ -1763,31 +1785,32 @@ sub runHscAndProcessInterfaces {
        
     local($source_unchanged) = 1;
 
        
     local($source_unchanged) = 1;
 
-# Check if the source file is up to date relative to the target; in
-# that case we say "source is unchanged" and let the compiler bail out
-# early if the import usage information allows it.
+    # Check if the source file is up to date relative to the target; in
+    # that case we say "source is unchanged" and let the compiler bail out
+    # early if the import usage information allows it.
 
     ($i_dev,$i_ino,$i_mode,$i_nlink,$i_uid,$i_gid,$i_rdev,$i_size,
      $i_atime,$i_mtime,$i_ctime,$i_blksize,$i_blocks) = stat($ifile);
 
 
     ($i_dev,$i_ino,$i_mode,$i_nlink,$i_uid,$i_gid,$i_rdev,$i_size,
      $i_atime,$i_mtime,$i_ctime,$i_blksize,$i_blocks) = stat($ifile);
 
-    if ( ! -f $ofile_target ) {
-#      print STDERR "$Pgm:compile:Output file $ofile_target doesn't exist\n";
+    # The informational messages below are now conditional on -v being set -- SOF
+    if ( $ofile_target ne "_stdin.s" && ! -f $ofile_target ) {
+        print STDERR "$Pgm:compile:Output file $ofile_target doesn't exist\n" if $Verbose;
        $source_unchanged = 0;
     }
 
     ($o_dev,$o_ino,$o_mode,$o_nlink,$o_uid,$o_gid,$o_rdev,$o_size,
      $o_atime,$o_mtime,$o_ctime,$o_blksize,$o_blocks) = stat(_); # stat info from -f test
 
        $source_unchanged = 0;
     }
 
     ($o_dev,$o_ino,$o_mode,$o_nlink,$o_uid,$o_gid,$o_rdev,$o_size,
      $o_atime,$o_mtime,$o_ctime,$o_blksize,$o_blocks) = stat(_); # stat info from -f test
 
-    if ( ! -f $hifile_target ) {
-#      print STDERR "$Pgm:compile:Interface file $hifile_target doesn't exist\n";
+    if ( $hifile_target ne "_stdout" && ! -f $hifile_target ) {
+        print STDERR "$Pgm:compile:Interface file $hifile_target doesn't exist\n" if $Verbose;
        $source_unchanged = 0;
     }
 
     ($hi_dev,$hi_ino,$hi_mode,$hi_nlink,$hi_uid,$hi_gid,$hi_rdev,$hi_size,
      $hi_atime,$hi_mtime,$hi_ctime,$hi_blksize,$hi_blocks) = stat(_); # stat info from -f test
 
        $source_unchanged = 0;
     }
 
     ($hi_dev,$hi_ino,$hi_mode,$hi_nlink,$hi_uid,$hi_gid,$hi_rdev,$hi_size,
      $hi_atime,$hi_mtime,$hi_ctime,$hi_blksize,$hi_blocks) = stat(_); # stat info from -f test
 
-    if ($i_mtime > $o_mtime) {
-#      print STDERR "$Pgm:recompile:Input file $ifile newer than $ofile_target\n";
+    if ( $ofile_target ne "_stdin.s" && $i_mtime > $o_mtime) {
+       print STDERR "$Pgm:recompile:Input file $ifile newer than $ofile_target\n" if $Verbose;
        $source_unchanged = 0;
     }
 
        $source_unchanged = 0;
     }
 
@@ -1797,14 +1820,14 @@ sub runHscAndProcessInterfaces {
        push(@HsC_flags, '-fsource-unchanged'); 
     }  
 
        push(@HsC_flags, '-fsource-unchanged'); 
     }  
 
-# Run the compiler
+    # Run the compiler
 
     &runHsc($ifile_root, $hsc_out, $hsc_hi, $going_interactive);
 
 
     &runHsc($ifile_root, $hsc_out, $hsc_hi, $going_interactive);
 
-# See if it bailed out early, saying nothing needed doing.  
-# We work this out by seeing if it created an output .hi file
+   # See if it bailed out early, saying nothing needed doing.  
+   # We work this out by seeing if it created an output .hi file
 
 
-    if ( ! -f $hsc_hi ) {
+    if ( ! -f $hsc_hi && $ProduceHi !~ /-nohifile=/ ) {
        # Doesn't exist, so we bailed out early.
        # Tell the C compiler and assembler not to run
        $do_cc = 0; $do_as = 0;
        # Doesn't exist, so we bailed out early.
        # Tell the C compiler and assembler not to run
        $do_cc = 0; $do_as = 0;
@@ -1822,8 +1845,10 @@ sub runHscAndProcessInterfaces {
        # out early, we still need to touch the interface file of B. The reason
         # for this is that B may export A's interface.
        #
        # out early, we still need to touch the interface file of B. The reason
         # for this is that B may export A's interface.
        #
-       &run_something("touch $ofile_target $hifile_target", 
-                      "Touch $ofile_target $hifile_target,  to propagate dependencies");
+       &run_something("touch $ofile_target",
+                      "Touch $ofile_target,  to propagate dependencies") if $HscOut ne '-N=';
+       &run_something("touch $hifile_target", 
+                      "Touch $hifile_target,  to propagate dependencies") if $ProduceHi =~ /-nohifile=/ ;
 
     } else {   
 
 
     } else {   
 
@@ -1848,28 +1873,21 @@ sub runHscAndProcessInterfaces {
 
 
        # Interface-handling is important enough to live off by itself
 
 
        # Interface-handling is important enough to live off by itself
-       require('ghc-iface.prl')
-           || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-iface.prl!\n");
-       
-       &postprocessHiFile($hsc_hi, $hifile_target, $going_interactive);
-       
-       # save a copy of the .hc file, even if we are carrying on...
-       if ($HscOut eq '-C=' && $do_cc && $Keep_hc_file_too) {
-           local($to_do) = "$Rm $ifile_root.hc; $Cp $hsc_out $ifile_root.hc";
-           &run_something($to_do, 'Saving copy of .hc file');
+        if ( $ProduceHi !~ /-nohifile=/ ) { # If we've produced one, process it.
+          require('ghc-iface.prl') || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-iface.prl!\n");
+          &postprocessHiFile($hsc_hi, $hifile_target, $going_interactive);
        }
        }
-       
-       # save a copy of the .s file, even if we are carrying on...
-       if ($HscOut eq '-S=' && $do_as && $Keep_s_file_too) {
-           local($to_do) = "$Rm $ifile_root.s; $Cp $hsc_out $ifile_root.s";
-           &run_something($to_do, 'Saving copy of .s file');
-       }
-       
        # if we're going to split up object files,
        # we inject split markers into the .hc file now
        if ( $HscOut eq '-C=' && $SplitObjFiles ) {
            &inject_split_markers ( $hsc_out );
         }
        # if we're going to split up object files,
        # we inject split markers into the .hc file now
        if ( $HscOut eq '-C=' && $SplitObjFiles ) {
            &inject_split_markers ( $hsc_out );
         }
+
+       # save a copy of the .hc file, even if we are carrying on...
+       if ($HscOut eq '-C=' && $do_cc && $Keep_hc_file_too) {
+            &saveIntermediate($ifile_root , "hc" , $hsc_out);
+       }
+
     }
 }
 \end{code}
     }
 }
 \end{code}
@@ -1883,13 +1901,12 @@ sub runHsc {
     foreach $a ( @HsP_flags ) { $a = ",$a" unless $a =~ /^,/; }
 
     &makeHiMap() unless $HiMapDone;
     foreach $a ( @HsP_flags ) { $a = ",$a" unless $a =~ /^,/; }
 
     &makeHiMap() unless $HiMapDone;
-#    print STDERR "HiIncludes: $HiIncludeString\n";
+    #print STDERR "HiIncludes: $HiIncludeString\n";
     push(@HsC_flags, "-himap=$HiIncludeString");
     push(@HsC_flags, "-himap=$HiIncludeString");
-#    push(@HsC_flags, "-himap=$HiMapFile");
 
     # here, we may produce .hc/.s and/or .hi files
     local($output) = '';
 
     # here, we may produce .hc/.s and/or .hi files
     local($output) = '';
-    @Files_to_tidy = ();
+    #@Files_to_tidy = ();
 
     if ( $going_interactive ) {
        # don't need .hi unless going to show it on stdout:
 
     if ( $going_interactive ) {
        # don't need .hi unless going to show it on stdout:
@@ -1900,7 +1917,7 @@ sub runHsc {
     # set up for producing output/.hi; note that flag twiddling
     # may mean that nothing will actually be produced:
     $output = "$ProduceHi$hsc_hi $HscOut$hsc_out";
     # set up for producing output/.hi; note that flag twiddling
     # may mean that nothing will actually be produced:
     $output = "$ProduceHi$hsc_hi $HscOut$hsc_out";
-    @Files_to_tidy = ( $hsc_hi, $hsc_out );
+    push(@Files_to_tidy, $hsc_hi, $hsc_out );
 
     # if we're compiling foo.hs, we want the GC stats to end up in foo.stat
     if ( $CollectingGCstats ) {
 
     # if we're compiling foo.hs, we want the GC stats to end up in foo.stat
     if ( $CollectingGCstats ) {
@@ -1911,6 +1928,7 @@ sub runHsc {
     if ( $CollectGhcTimings ) { # assume $RTS_style eq 'ghc'
        # emit nofibbish time/bytes-alloc stats to stderr;
        # see later .stat file post-processing
     if ( $CollectGhcTimings ) { # assume $RTS_style eq 'ghc'
        # emit nofibbish time/bytes-alloc stats to stderr;
        # see later .stat file post-processing
+       print STDERR "warning: both -Rgc-stats and -Rghc-timing used, -Rghc-timing wins." if $CollectingGCstats;
        push(@HsC_rts_flags, "-s$Tmp_prefix.stat");
        push(@Files_to_tidy, "$Tmp_prefix.stat");
     }
        push(@HsC_rts_flags, "-s$Tmp_prefix.stat");
        push(@Files_to_tidy, "$Tmp_prefix.stat");
     }
@@ -1933,9 +1951,7 @@ sub runHsc {
 Use \tr{@Import_dir} and \tr{@SysImport_dir} to make a tmp file
 of (module-name, pathname) pairs, one per line, separated by a space.
 \begin{code}
 Use \tr{@Import_dir} and \tr{@SysImport_dir} to make a tmp file
 of (module-name, pathname) pairs, one per line, separated by a space.
 \begin{code}
-#%HiMap     = ();
 $HiMapDone = 0;
 $HiMapDone = 0;
-$HiMapFile = '';
 $HiIncludeString = ();         # dir1:dir2:dir3, to pass to GHC
 
 sub makeHiMap {
 $HiIncludeString = ();         # dir1:dir2:dir3, to pass to GHC
 
 sub makeHiMap {
@@ -1945,86 +1961,29 @@ sub makeHiMap {
     local($mod, $path, $d, $e);
 
     # reset the global variables:
     local($mod, $path, $d, $e);
 
     # reset the global variables:
-    #%HiMap     = ();
     $HiMapDone = 0;
     $HiMapDone = 0;
-    $HiMapFile = '';
     $HiIncludeString = ();             # dir1:dir2:dir3, to pass to GHC
     
     foreach $d ( @Import_dir ) {
     $HiIncludeString = ();             # dir1:dir2:dir3, to pass to GHC
     
     foreach $d ( @Import_dir ) {
-       if ($HiIncludeString) { $HiIncludeString = "$HiIncludeString:$d";
-       } else { $HiIncludeString = $d; }
+       if ($HiIncludeString) { 
+          $HiIncludeString = "$HiIncludeString:${d}/%.${HiSuffix}";
+       } else { 
+          $HiIncludeString = "$d/%.${HiSuffix}"; 
+       }
 
 
-# The compiler does the searching now
-#
-#      opendir(DIR, $d) || &tidy_up_and_die(1,"$Pgm: error when reading directory: $d\n");
-#      local(@entry) = readdir(DIR);
-#      foreach $e ( @entry ) {
-#          next unless $e =~ /\b([A-Z][A-Za-z0-9_]*)\.${HiSuffix_prelude}$/o;
-#          $mod  = $1;
-#          $path = "$d/$e";
-#          $path =~ s,^\./,,;
-#
-#          if ( ! defined($HiMap{$mod}) ) {
-#              $HiMap{$mod} = $path;
-#          } else {
-#              &already_mapped_err($mod, $HiMap{$mod}, $path);
-#          }
-#      }
-#      closedir(DIR); # || &tidy_up_and_die(1,"$Pgm: error when closing directory: $d\n");
     }
 
     foreach $d ( @SysImport_dir ) {
     }
 
     foreach $d ( @SysImport_dir ) {
-       if ($HiIncludeString) { $HiIncludeString = "$HiIncludeString:$d";
-       } else { $HiIncludeString = $d; }
-
-#      opendir(DIR, $d) || &tidy_up_and_die(1,"$Pgm: error when reading directory: $d\n");
-#      local(@entry) = readdir(DIR);
-#      foreach $e ( @entry ) {
-#          next unless $e =~ /([A-Z][A-Za-z0-9_]*)\.$HiSuffix$/o;
-#          next if $NoImplicitPrelude && $e =~ /Prelude\.$HiSuffix$/o;
-#
-#          $mod  = $1;
-#          $path = "$d/$e";
-#          $path =~ s,^\./,,;
-#
-#          if ( ! defined($HiMap{$mod}) ) {
-#              $HiMap{$mod} = $path;
-#          } elsif ( $mod ne 'Main' )  { # saves useless warnings...
-#              &already_mapped_err($mod, $HiMap{$mod}, $path);
-#          }
-#      }
-#      closedir(DIR); # || &tidy_up_and_die(1,"$Pgm: error when closing directory: $d\n");
+       if ($HiIncludeString) { 
+           $HiIncludeString = "$HiIncludeString:${d}/%.${HiSuffix_prelude}";
+       } else { 
+           $HiIncludeString = "${d}/%.${HiSuffix_prelude}";
+        }
     }
 
     }
 
-#
-# Not currently used:
-#
-#    $HiMapFile = "$Tmp_prefix.himap";
-#    unlink($HiMapFile);
-#    open(HIMAP, "> $HiMapFile") || &tidy_up_and_die(1,"$Pgm: can't open $HiMapFile\n");
-#    foreach $d (keys %HiMap) {
-#      print HIMAP $d, ' ', $HiMap{$d}, "\n";
-#    }
-#    close(HIMAP) || &tidy_up_and_die(1,"$Pgm: error when closing $HiMapFile\n");
-
     $HiMapDone = 1;
 }
 
     $HiMapDone = 1;
 }
 
-sub already_mapped_err {
-    local($mod, $mapped_to, $path) = @_;
-
-    # OK, it isn't really an error if $mapped_to and $path turn
-    # out to be the same thing.
-    ($m_dev,$m_ino,$m_mode,$m_nlink,$m_uid,$m_gid,$m_rdev,$m_size,
-     $m_atime,$m_mtime,$m_ctime,$m_blksize,$m_blocks) = stat($mapped_to);
-    ($p_dev,$p_ino,$p_mode,$p_nlink,$p_uid,$p_gid,$p_rdev,$p_size,
-     $p_atime,$p_mtime,$p_ctime,$p_blksize,$p_blocks) = stat($path);
-
-    return if $m_ino == $p_ino; # same inode number
-
-    print STDERR "$Pgm: module $mod already mapped to $mapped_to";
-    print STDERR ";\n\tignoring: $path\n";
-}
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -2074,7 +2033,7 @@ sub runGcc {
     local($cc_help_s) = "ghc$$.s";
 
     $cc       = $CcRegd;
     local($cc_help_s) = "ghc$$.s";
 
     $cc       = $CcRegd;
-    $s_output = ($is_hc_file || $TargetPlatform =~ /^(hppa|i386)/) ? $cc_as_o : $cc_as;
+    $s_output = ($is_hc_file || $TargetPlatform =~ /^(powerpc|rs6000|hppa|i386)/) ? $cc_as_o : $cc_as;
     $c_flags .= " @CcRegd_flags";
     $c_flags .= ($is_hc_file) ? " @CcRegd_flags_hc"  : " @CcRegd_flags_c";
 
     $c_flags .= " @CcRegd_flags";
     $c_flags .= ($is_hc_file) ? " @CcRegd_flags_hc"  : " @CcRegd_flags_c";
 
@@ -2100,15 +2059,21 @@ EOINCL
     print TMP "#include \"$hsc_out\"\n";
     close(TMP) || &tidy_up_and_die(1,"Failed writing to $cc_help\n");
 
     print TMP "#include \"$hsc_out\"\n";
     close(TMP) || &tidy_up_and_die(1,"Failed writing to $cc_help\n");
 
-    local($to_do) = "$cc $Verbose $ddebug_flag $c_flags @Cpp_define -D__HASKELL1__=$Haskell1Version $includes $cc_help > $Tmp_prefix.ccout 2>&1 && ( if [ $cc_help_s != $s_output ] ; then mv $cc_help_s $s_output ; else exit 0 ; fi )";
+    # Don't redirect stderr into intermediate file if slamming output onto stdout (e.g., with -E)
+    local($fuse_stderr) = "2>&1" if ! $Only_preprocess_hc;
+    local($to_do) = "$cc $Verbose $ddebug_flag $c_flags @Cpp_define -D__HASKELL1__=$Haskell1Version $includes $cc_help > $Tmp_prefix.ccout $fuse_stderr && ( if [ $cc_help_s != $s_output ] ; then mv $cc_help_s $s_output ; else exit 0 ; fi )";
     # note: __GLASGOW_HASKELL__ is pointedly *not* #defined at the C level.
     # note: __GLASGOW_HASKELL__ is pointedly *not* #defined at the C level.
-    if ( $Only_preprocess_C ) { # HACK ALERT!
+
+    if ( $Only_preprocess_hc ) { # HACK ALERT!
        $to_do =~ s/ -S\b//g;
     }
        $to_do =~ s/ -S\b//g;
     }
-    @Files_to_tidy = ( $cc_help, $cc_help_s, $s_output );
-    $PostprocessCcOutput = 1;  # hack, dear hack...
+    push(@Files_to_tidy, $cc_help, $cc_help_s, $s_output );
+    $PostprocessCcOutput = 1 if ! $Only_preprocess_hc; # hack, dear hack...
     &run_something($to_do, 'C compiler');
     $PostprocessCcOutput = 0;
     &run_something($to_do, 'C compiler');
     $PostprocessCcOutput = 0;
+    if ( $Only_preprocess_hc ) {
+       system("$Cat $Tmp_prefix.ccout");
+    }
     unlink($cc_help, $cc_help_s);
 }
 \end{code}
     unlink($cc_help, $cc_help_s);
 }
 \end{code}
@@ -2155,6 +2120,11 @@ sub runMangler {
        || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-hppa.prl!\n");
        &mini_mangle_asm_hppa($cc_as_o, $cc_as);
 
        || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-hppa.prl!\n");
        &mini_mangle_asm_hppa($cc_as_o, $cc_as);
 
+    } elsif ($TargetPlatform =~ /^powerpc|^rs6000/) {
+       # minor mangling of non-threaded files for powerpcs and rs6000s 
+       require('ghc-asm.prl')
+       || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-powerpc.prl!\n");
+       &mini_mangle_asm_powerpc($cc_as_o, $cc_as);
     } elsif ($TargetPlatform =~ /^i386/) {
        # extremely-minor OFFENSIVE mangling of non-threaded just one file
        require('ghc-asm.prl')
     } elsif ($TargetPlatform =~ /^i386/) {
        # extremely-minor OFFENSIVE mangling of non-threaded just one file
        require('ghc-asm.prl')
@@ -2163,10 +2133,9 @@ sub runMangler {
     }
 
     # save a copy of the .s file, even if we are carrying on...
     }
 
     # save a copy of the .s file, even if we are carrying on...
-    if ($do_as && $Keep_s_file_too) {
-       local($to_do) = "$Rm $ifile_root.s; $Cp $cc_as $ifile_root.s";
-       &run_something($to_do, 'Saving copy of .s file');
-    }
+    #if ($do_as && $Keep_s_file_too) {
+    #    &saveIntermediate($ifile_root , "s" , $cc_as);
+    #}
 }
 \end{code}
 
 }
 \end{code}
 
@@ -2178,7 +2147,7 @@ sub runAs {
 
     if ( ! $SplitObjFiles ) {
        local($to_do)  = "$asmblr -o $as_out -c @As_flags $cc_as";
 
     if ( ! $SplitObjFiles ) {
        local($to_do)  = "$asmblr -o $as_out -c @As_flags $cc_as";
-       @Files_to_tidy = ( $as_out );
+       push(@Files_to_tidy, $as_out );
        &run_something($to_do, 'Unix assembler');
 
     } else { # more complicated split-ification...
        &run_something($to_do, 'Unix assembler');
 
     } else { # more complicated split-ification...
@@ -2198,7 +2167,7 @@ sub runAs {
        for ($f = 1; $f <= $NoOfSplitFiles; $f++ ) {
            local($split_out) = &odir_ify("${ifile_root}__${f}",'o');
            local($to_do) = "$asmblr -o $split_out -c @As_flags ${Tmp_prefix}__${f}.s";
        for ($f = 1; $f <= $NoOfSplitFiles; $f++ ) {
            local($split_out) = &odir_ify("${ifile_root}__${f}",'o');
            local($to_do) = "$asmblr -o $split_out -c @As_flags ${Tmp_prefix}__${f}.s";
-           @Files_to_tidy = ( $split_out );
+           push(@Files_to_tidy, $split_out );
 
            &run_something($to_do, 'Unix assembler');
        }
 
            &run_something($to_do, 'Unix assembler');
        }
@@ -2228,8 +2197,29 @@ sub run_something {
     }
 
     local($return_val) = 0;
     }
 
     local($return_val) = 0;
-    system("$Time $str_to_do");
-    $return_val = $?;
+
+    if ( length($str_to_do) > 4000) { 
+      # 4000 - on the random side, just like the *real* ARG_MAX 
+      # for some shells.
+
+      # With some shells, command lines of this length may
+      # very well cause trouble. To safeguard against this, we squirrel the
+      # command into a file and exec that.
+      local ($sh) = $ENV{'REAL_SHELL'};
+      print STDERR "Backup plan A: saving cmd line in ${Tmp_prefix}.sh and executing that with $sh\n" if $Verbose;
+      open (TEMP, "> ${Tmp_prefix}.sh") || 
+               &tidy_up_and_die(1,"$Pgm: failed to open `$Tmp_prefix.sh'\n");
+      print TEMP "$Time $str_to_do\n";
+      close (TEMP) ||
+               &tidy_up_and_die(1,"$Pgm: failed closing `$Tmp_prefix.sh'\n");
+      system("$sh $Tmp_prefix.sh");
+      $return_val = $?;
+      
+      unlink "${Tmp_prefix}.sh";
+    } else {
+      system("$Time $str_to_do");
+      $return_val = $?;
+    }
 
     if ( $PostprocessCcOutput ) { # hack, continued
        open(CCOUT, "< $Tmp_prefix.ccout")
 
     if ( $PostprocessCcOutput ) { # hack, continued
        open(CCOUT, "< $Tmp_prefix.ccout")
@@ -2266,7 +2256,7 @@ sub run_something {
 
 %************************************************************************
 %*                                                                     *
 
 %************************************************************************
 %*                                                                     *
-\subsection[Driver-ghctiming]{Emit nofibbish GHC timings}
+\subsection[Driver-ghc-timing]{Emit nofibbish GHC timings}
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
@@ -2278,20 +2268,27 @@ sub process_ghc_timings {
     local($SysSpecificTiming) = 'ghc';
 
     open(STATS, $StatsFile) || die "Failed when opening $StatsFile\n";
     local($SysSpecificTiming) = 'ghc';
 
     open(STATS, $StatsFile) || die "Failed when opening $StatsFile\n";
-    local($tot_live) = 0; # for calculating avg residency
+    local($max_live)    = 0; 
+    local($tot_live)    = 0; # for calculating residency stuff
+    local($tot_samples) = 0;
 
     while (<STATS>) {
 
     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 (! /Minor/ && /^\s*\d+\s+\d+\s+(\d+)\s+\d+\.\d+\%/ ) {
+               $max_live = $1 if $max_live < $1;
+               $tot_live += $1;
+               $tot_samples += 1;
+       }
+        $BytesAlloc = $1 if /^\s*([0-9,]+) bytes allocated in the heap/;
 
        if ( /^\s*([0-9,]+) bytes maximum residency .* (\d+) sample/ ) {
            $MaxResidency = $1; $ResidencySamples = $2;
        }
 
 
        if ( /^\s*([0-9,]+) bytes maximum residency .* (\d+) sample/ ) {
            $MaxResidency = $1; $ResidencySamples = $2;
        }
 
-       $GCs = $1 if /^\s*([0-9,]+) garbage collections? performed/;
+        $GCs = $1 if /^\s*([0-9,]+) garbage collections? performed/;
 
 
-       if ( /^\s*INIT\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) {
+       # The presence of -? in the following pattern is only there to
+       # accommodate 0.29 && <= 2.05 RTS'
+       if ( /^\s*INIT\s+time\s*(\d+\.\d\d)s\s*\(\s*-?(\d+\.\d\d)s elapsed\)/ ) {
            $InitTime = $1; $InitElapsed = $2;
        } elsif ( /^\s*MUT\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) {
            $MutTime = $1; $MutElapsed = $2;
            $InitTime = $1; $InitElapsed = $2;
        } elsif ( /^\s*MUT\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) {
            $MutTime = $1; $MutElapsed = $2;
@@ -2300,8 +2297,10 @@ sub process_ghc_timings {
        }
     }
     close(STATS) || die "Failed when closing $StatsFile\n";
        }
     }
     close(STATS) || die "Failed when closing $StatsFile\n";
-    if ( defined($ResidencySamples) && $ResidencySamples > 0 ) {
-       $AvgResidency = int ($tot_live / $ResidencySamples) ;
+    if ( $tot_samples > 0 ) {
+       $ResidencySamples = $tot_samples;
+       $MaxResidency = $max_live;
+       $AvgResidency = int ($tot_live / $tot_samples) ;
     }
 
     # warn about what we didn't find
     }
 
     # warn about what we didn't find
@@ -2386,7 +2385,7 @@ nonsensical).
 sub grab_arg_arg {
     local(*Args, $option, $rest_of_arg) = @_;
     
 sub grab_arg_arg {
     local(*Args, $option, $rest_of_arg) = @_;
     
-    if ($rest_of_arg) {
+    if ($rest_of_arg ne '') {
        return($rest_of_arg);
     } elsif ($#Args >= 0) {
        local($temp) = $Args[0]; shift(@Args); 
        return($rest_of_arg);
     } elsif ($#Args >= 0) {
        local($temp) = $Args[0]; shift(@Args); 
@@ -2433,6 +2432,26 @@ sub add_Hsc_flags {
 }
 \end{code}
 
 }
 \end{code}
 
+\begin{code}
+sub add_syslib {
+    local($syslib) = @_;
+    
+    unshift(@SysImport_dir,
+           $INSTALLING ? "$InstLibDirGhc/imports/$syslib"
+                         : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/$syslib");
+
+    push(@SysLibrary_dir,
+        $INSTALLING ? ("$InstLibDirGhc")
+                       : ("$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/$syslib",
+                         "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/$syslib/cbits"));
+
+    push(@SysLibrary, "-lHS$syslib");
+    push(@SysLibrary, "-lHS${syslib}_cbits")
+          unless $syslib eq 'contrib' || $syslib eq 'exts' || $syslib eq 'conc';
+         #HACK! they have no cbits
+}
+\end{code}
+
 Source files may have {-# OPTIONS ... #-} pragmas at the top, containing
 command line options we want to append to collection of commands specified
 directly. @check_for_source_options@ looks at the top of a de-lit'ified Haskell
 Source files may have {-# OPTIONS ... #-} pragmas at the top, containing
 command line options we want to append to collection of commands specified
 directly. @check_for_source_options@ looks at the top of a de-lit'ified Haskell
@@ -2440,22 +2459,41 @@ file for any such pragmas:
 
 \begin{code}
 sub check_for_source_options {
 
 \begin{code}
 sub check_for_source_options {
-    local($file) = @_;
+    local($file,$ifile) = @_;
+    local($comment_start,$comment_end);
+
+    if ($ifile =~ /\.hc$/ || 
+        $ifile =~ /_hc$/  || 
+       $ifile =~ /\.s$/  || 
+       $ifile =~ /_s$/ ) {  # `Real' C intermediate
+       $comment_start = "/\\*";
+       $comment_end   = "\\*/";
+    } else { # Assume it is a file containing Haskell source
+       $comment_start = "{-#";
+       $comment_end   = "#-}";
+    }
 
     open(FILE,$file) || return(1); # No big loss
 
     open(FILE,$file) || return(1); # No big loss
-
+    
     while (<FILE>) {
     while (<FILE>) {
-       if ( /^{-# OPTIONS (.*)#-}/ ) {
+       if ( /^${comment_start} OPTIONS (.*)${comment_end}$/ ) {
            # add the options found at the back of the command line.
           local(@entries) = split(/\s+/,$1);
            # add the options found at the back of the command line.
           local(@entries) = split(/\s+/,$1);
+          print STDERR "Found OPTIONS " . join(' ',@entries) . " in $file\n" if $Verbose;
           push(@File_options, @entries);
        }
         elsif ( /^$/ ) { # ignore empty lines
            ;
         }
           push(@File_options, @entries);
        }
         elsif ( /^$/ ) { # ignore empty lines
            ;
         }
+        elsif ( /^#line.+$/ ) { # ignore comment lines (unused..ToDo: rm )
+           ;
+        }
+        elsif ( /^{-# LINE.+$/ ) { # ignore line pragmas
+           ;
+        }
         else { # stop looking, something non-empty / not
         else { # stop looking, something non-empty / not
-              # {-# OPTIONS .. #-} encountered.
-           break;
+              # ${comment_start} OPTIONS .. ${comment_end} encountered.
+           close(FILE);return(0);
         }
     }
     close(FILE);
         }
     }
     close(FILE);
@@ -2480,11 +2518,11 @@ sub splitCmdLine {
 arg: while($_ = $args[0]) {
     shift(@args);
     # sigh, we have to deal with these -option arg specially here.
 arg: while($_ = $args[0]) {
     shift(@args);
     # sigh, we have to deal with these -option arg specially here.
-    /^-(tmpdir|odir|o|isuf|osuf|hisuf|hisuf-prelude|odump|syslib)$/ && 
+    /^-(tmpdir|odir|ohi|o|isuf|osuf|hisuf|hisuf-prelude|odump|syslib)$/ && 
        do { push(@Cmd_opts, $_); push(@Cmd_opts,$args[0]); shift(@args); next arg; };
        do { push(@Cmd_opts, $_); push(@Cmd_opts,$args[0]); shift(@args); next arg; };
-    /^-./  && do { push(@Cmd_opts, $_); next arg; };
+    /^--?./  && do { push(@Cmd_opts, $_); next arg; };
 
 
-    if (/\.[oa]$/) {
+    if (/\.([^_]+_)?[oa]$/) {
        push(@Link_file, $_);
     } else {
        push(@Input_file, $_);
        push(@Link_file, $_);
     } else {
        push(@Input_file, $_);
@@ -2500,6 +2538,35 @@ arg: while($_ = $args[0]) {
 
 \end{code}
 
 
 \end{code}
 
+When saving an intermediate file (.hc or .s) away, we 
+have to prefix any OPTIONS found in the original source file.
+
+\begin{code}
+sub saveIntermediate { 
+  local ($final,$suffix,$tmp)= @_ ;
+  local ($to_do);
+
+  # $final  -- root of where to park ${final}.${suffix}
+  # $tmp    -- temporary file where hsc put the intermediate file.
+
+  # Delete the old file
+  $to_do = "$Rm ${final}.${suffix}"; &run_something($to_do, "Removing old .${suffix} file");
+
+  if ( $#File_options >= 0 ) { # OPTIONS found in Haskell source unit
+    # Add OPTION comment to the top of the generated .${suffix} file
+    open(TEMP, "> ${final}.${suffix}") || &tidy_up_and_die(1,"Can't open ${final}.${suffix}\n");
+    print TEMP "/* OPTIONS " . join(' ',@File_options) . " */\n";
+    close(TEMP);
+    print STDERR "Prepending OPTIONS: " . join(' ',@File_options) . " to ${final}.${suffix}\n" if $Verbose;
+  }
+  $to_do = "$Cat $tmp  >> ${final}.${suffix}";
+  &run_something($to_do, "Saving copy of .${suffix} file");
+
+}
+
+\end{code}
+
+
 Command-line processor
 
 \begin{code}
 Command-line processor
 
 \begin{code}
@@ -2515,13 +2582,13 @@ arg: while($_ = $Args[0]) {
     if (/^-\?$/ || /^--?help$/) { print $LongUsage; exit $Status; }
 
     #-----------version ----------------------------------------------------
     if (/^-\?$/ || /^--?help$/) { print $LongUsage; exit $Status; }
 
     #-----------version ----------------------------------------------------
-    /^--version$/   && do { print STDERR "${PROJECTNAME}, version ${PROJECTVERSION} ${PROJECTPATCHLEVEL}\n"; exit $Status; };
+    /^--version$/   && do { print STDERR "${ProjectName}, version ${ProjectVersion}, patchlevel ${ProjectPatchLevel}\n"; exit $Status; };
 
     #---------- verbosity and such -----------------------------------------
     /^-v$/         && do { $Verbose = '-v'; $Time = 'time'; next arg; };
 
     #---------- what phases are to be run ----------------------------------
 
     #---------- verbosity and such -----------------------------------------
     /^-v$/         && do { $Verbose = '-v'; $Time = 'time'; next arg; };
 
     #---------- what phases are to be run ----------------------------------
-    /^-recomp/     && do { $Do_recomp_chkr = 1; next arg; };
+    /^-(no-)?recomp/       && do { $Do_recomp_chkr = ($1 eq '') ? 1 : 0; next arg; };
 
     /^-cpp$/       && do { $Cpp_flag_set = 1; next arg; };
     # change the global default:
 
     /^-cpp$/       && do { $Cpp_flag_set = 1; next arg; };
     # change the global default:
@@ -2542,9 +2609,11 @@ arg: while($_ = $Args[0]) {
     /^-nohi$/      && do { $ProduceHi = '-nohifile='; next arg; };
     # don't generate an interface (even if generating C)
 
     /^-nohi$/      && do { $ProduceHi = '-nohifile='; next arg; };
     # don't generate an interface (even if generating C)
 
-    /^-hi-diffs$/             && do { $HiDiff_flag = 'normal'; next arg; };
-    /^-hi-diffs-with-usages$/ && do { $HiDiff_flag = 'usages'; next arg; };
-    /^-no-hi-diffs$/          && do { $HiDiff_flag = '';       next arg; };
+    /^-hi-diffs$/             && do { $HiDiff_flag  = 'normal'; next arg; };
+    /^-hi-diffs-with-usages$/ && do { $HiDiff_flag  = 'usages'; next arg; };
+    /^-no-hi-diffs$/          && do { $HiDiff_flag  = '';       next arg; };
+    /^-keep-hi-diffs$/       && do { $Keep_HiDiffs = 1; next arg; };
+
     # show/disable diffs if the interface file changes
 
     /^-E$/         && do { push(@CcBoth_flags, '-E');
     # show/disable diffs if the interface file changes
 
     /^-E$/         && do { push(@CcBoth_flags, '-E');
@@ -2558,7 +2627,7 @@ arg: while($_ = $Args[0]) {
        
     /^-c$/         && do { $Do_lnkr = 0; next arg; };
     # stop after generating .o files
        
     /^-c$/         && do { $Do_lnkr = 0; next arg; };
     # stop after generating .o files
-       
+
     /^-link-chk$/    && do { $LinkChk = 1; next arg; };
     /^-no-link-chk$/ && do { $LinkChk = 0; next arg; };
     # don't do consistency-checking after a link
     /^-link-chk$/    && do { $LinkChk = 1; next arg; };
     /^-no-link-chk$/ && do { $LinkChk = 0; next arg; };
     # don't do consistency-checking after a link
@@ -2684,7 +2753,8 @@ arg: while($_ = $Args[0]) {
     #--------- ticky/concurrent/parallel -----------------------------------
     # we sort out the details a bit later on
 
     #--------- ticky/concurrent/parallel -----------------------------------
     # we sort out the details a bit later on
 
-    /^-concurrent$/ && do { $CONCURing = 'c'; next arg; }; # concurrent Haskell
+    /^-concurrent$/ && do { $CONCURing = 'c'; &add_syslib('conc'); next arg; }; 
+                         # concurrent Haskell; implies -syslib conc
     /^-gransim$/    && do { $GRANing   = 'g'; next arg; }; # GranSim
     /^-ticky$/     && do { $TICKYing  = 't'; next arg; }; # ticky-ticky
     /^-parallel$/   && do { $PARing    = 'p'; next arg; }; # parallel Haskell
     /^-gransim$/    && do { $GRANing   = 'g'; next arg; }; # GranSim
     /^-ticky$/     && do { $TICKYing  = 't'; next arg; }; # ticky-ticky
     /^-parallel$/   && do { $PARing    = 'p'; next arg; }; # parallel Haskell
@@ -2724,26 +2794,23 @@ arg: while($_ = $Args[0]) {
 
     /^-syslib(.*)/  && do { local($syslib) = &grab_arg_arg(*Args,'-syslib',$1);
                            print STDERR "$Pgm: no such system library (-syslib): $syslib\n",
 
     /^-syslib(.*)/  && do { local($syslib) = &grab_arg_arg(*Args,'-syslib',$1);
                            print STDERR "$Pgm: no such system library (-syslib): $syslib\n",
-                             $Status++ unless $syslib =~ /^(hbc|ghc|posix|contrib)$/;
+                             $Status++ unless $syslib =~ /^(exts|misc|posix)$/;
 
 
-                           unshift(@SysImport_dir,
-                               ${INSTALLING}
-                               ? "$InstSysLibDir/$syslib/imports"
-                               : "$TopPwd/hslibs/$syslib/src");
-
-                           if ( ${INSTALLING} ) {
-                               push(@SysLibrary_dir,
-                                       ("$InstSysLibDir/$TargetPlatform"));
-                           } else {
-                               push(@SysLibrary_dir,
-                                       ("$TopPwd/hslibs/$syslib"
-                                       ,"$TopPwd/hslibs/$syslib/cbits"));
+                           #
+                           # The posix library is a `special' in that it relies on
+                           # the ghc system library (packed strings). Wielding our
+                           # sledgehammer, the problem is solved by silently including
+                           # the ghc system library as well.
+                           # (ToDo: `nub' -syslib list)
+                           #
+                           &add_syslib($syslib);
+                           if ( $syslib eq 'posix' ) {
+                               &add_syslib('misc');
+                           } elsif ( $syslib eq 'misc' && 
+                                     $TargetName =~ /-solaris2$/ ) {
+                               # needed for Berkeley socket/nwork stuff.
+                               push(@SysLibrary, '-lnsl');
                            }
                            }
-
-                           push(@SysLibrary, "-lHS$syslib");
-                           push(@SysLibrary, "-lHS${syslib}_cbits")
-                             unless $syslib eq 'contrib'; #HACK! it has no cbits
-
                            next arg; };
 
     #=======================================================================
                            next arg; };
 
     #=======================================================================
@@ -2767,7 +2834,8 @@ arg: while($_ = $Args[0]) {
     /^-optP(.*)$/   && do { push(@HsCpp_flags,      $1); next arg; };
     /^-optCrts(.*)$/&& do { push(@HsC_rts_flags,    $1); next arg; };
     /^-optC(.*)$/   && do { push(@HsC_flags,        $1); next arg; };
     /^-optP(.*)$/   && do { push(@HsCpp_flags,      $1); next arg; };
     /^-optCrts(.*)$/&& do { push(@HsC_rts_flags,    $1); next arg; };
     /^-optC(.*)$/   && do { push(@HsC_flags,        $1); next arg; };
-    /^-optcpp(.*)$/ && do { push(@Cpp_define,       $1); next arg; };
+    /^-optp(.*)$/   && do { push(@HsP_flags,        $1); next arg; };
+    /^-optcpp(.*)$/ && do { push(@Cpp_define,       $1); $Only_preprocess_hc = ($1 eq "-E"); next arg; };
     /^-optc(.*)$/   && do { push(@CcBoth_flags,     $1); next arg; };
     /^-opta(.*)$/   && do { push(@As_flags,         $1); next arg; };
     /^-optl(.*)$/   && do { push(@Ld_flags,         $1); next arg; };
     /^-optc(.*)$/   && do { push(@CcBoth_flags,     $1); next arg; };
     /^-opta(.*)$/   && do { push(@As_flags,         $1); next arg; };
     /^-optl(.*)$/   && do { push(@Ld_flags,         $1); next arg; };
@@ -2811,11 +2879,8 @@ arg: while($_ = $Args[0]) {
     /^-fticky-ticky$/     && do { push(@HsC_flags,$_); next arg; };
     /^-fgransim$/        && do { push(@HsC_flags,$_); next arg; };
 
     /^-fticky-ticky$/     && do { push(@HsC_flags,$_); next arg; };
     /^-fgransim$/        && do { push(@HsC_flags,$_); next arg; };
 
-    /^-user-prelude-force/     && do { # ignore if not -user-prelude
-                                       next arg; };
-
     /^-split-objs/     && do {
     /^-split-objs/     && do {
-                       if ( $TargetPlatform !~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|sparc)-/ ) {
+                       if ( $TargetPlatform !~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|rs6000|sparc)-/ ) {
                            $SplitObjFiles = 0;
                            print STDERR "WARNING: don't know how to split objects on this platform: $TargetPlatform\n`-split-objs' option ignored\n";
                        } else {
                            $SplitObjFiles = 0;
                            print STDERR "WARNING: don't know how to split objects on this platform: $TargetPlatform\n`-split-objs' option ignored\n";
                        } else {
@@ -2835,6 +2900,9 @@ arg: while($_ = $Args[0]) {
                        push(@HsP_flags, '-N');
 
 #                      push(@HsC_flags, '-fshow-import-specs');
                        push(@HsP_flags, '-N');
 
 #                      push(@HsC_flags, '-fshow-import-specs');
+               
+                       # -fglasgow-exts implies -syslib exts
+                       &add_syslib('exts');
 
                        next arg; };
 
 
                        next arg; };
 
@@ -2873,10 +2941,16 @@ arg: while($_ = $Args[0]) {
                    && do { $Oopt_FoldrBuildInline .= ' -fdo-not-fold-back-append '; 
                            next arg; };
 
                    && do { $Oopt_FoldrBuildInline .= ' -fdo-not-fold-back-append '; 
                            next arg; };
 
+    # --------------- Renamer -------------
+
+
+    /^-fno-prune-tydecls$/     && do { push(@HsC_flags, $_); next arg; };
+    /^-fno-prune-instdecls$/     && do { push(@HsC_flags, $_); next arg; };
+
     # ---------------
 
     /^-fasm-(.*)$/  && do { $HscOut = '-S='; next arg; }; # force using nativeGen
     # ---------------
 
     /^-fasm-(.*)$/  && do { $HscOut = '-S='; next arg; }; # force using nativeGen
-    /^-fvia-C$/            && do { $HscOut = '-C='; next arg; }; # force using C compiler
+    /^-fvia-[cC]$/         && do { $HscOut = '-C='; next arg; }; # force using C compiler
 
     # ---------------
 
 
     # ---------------
 
@@ -2887,6 +2961,9 @@ arg: while($_ = $Args[0]) {
     /^(-fmax-simplifier-iterations)(.*)$/
                    && do { $Oopt_MaxSimplifierIterations = $1 . &grab_arg_arg(*Args,$1, $2);
                            next arg; };
     /^(-fmax-simplifier-iterations)(.*)$/
                    && do { $Oopt_MaxSimplifierIterations = $1 . &grab_arg_arg(*Args,$1, $2);
                            next arg; };
+    /^(-fshow-simplifier-progress)/
+                   && do { $Oopt_ShowSimplifierProgress = $1;
+                           next arg; };
 
     /^-fno-pedantic-bottoms$/
                    && do { $Oopt_PedanticBottoms = ''; next arg; };
 
     /^-fno-pedantic-bottoms$/
                    && do { $Oopt_PedanticBottoms = ''; next arg; };
@@ -2911,15 +2988,26 @@ arg: while($_ = $Args[0]) {
 
     # --------------- Warnings etc. ------
 
 
     # --------------- Warnings etc. ------
 
-    /^-f(show-import-specs)/
+    /^-fshow-import-specs/
                    && do { push(@HsC_flags, $_); next arg; };
 
                    && do { push(@HsC_flags, $_); next arg; };
 
-    # for now, just -fwarn-name-shadowing
-    /^-fwarn-(.*)$/   && do { push(@HsC_flags, $_); next arg; };
+    /^-fsignatures-required/      
+                   && do { push(@HsC_flags, $_); next arg; };
+
+    /^-fwarn-(.*)$/      && do { push(@HsC_flags, $_); next arg; };
+
     /^-fno-(.*)$/   && do { push(@HsC_antiflags, "-f$1");
                            &squashHscFlag("-f$1");
                            next arg; };
 
     /^-fno-(.*)$/   && do { push(@HsC_antiflags, "-f$1");
                            &squashHscFlag("-f$1");
                            next arg; };
 
+    /^-W$/         && do { push(@HsC_flags, @MinusWOpts); next arg; };
+    /^-Wall$/      && do { push(@HsC_flags, @MinusWallOpts); next arg; };
+    /^(-Wnot|w)$/   && do { foreach (@Hsc_flags) {
+                               /^-fwarn-(.*)$/ && do { $_=''; };
+                           };
+                           push(@HsC_antiflags, @StandardWarnings);
+                           next arg; };
+
     # --------------- platform specific flags (for gcc mostly) ----------------
 
     /^-mlong-calls$/ && do { # for GCC for HP-PA boxes,
     # --------------- platform specific flags (for gcc mostly) ----------------
 
     /^-mlong-calls$/ && do { # for GCC for HP-PA boxes,
@@ -2949,6 +3037,7 @@ arg: while($_ = $Args[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; };
     /^-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; };
+    /^-dshow-rn-stats/      && do { push(@HsC_flags, $_); next arg; };
     /^-dshow-rn-trace/      && do { push(@HsC_flags, $_); next arg; };
     /^-dsource-stats/        && do { push(@HsC_flags, $_); next arg; };
     /^-dsimplifier-stats/    && do { push(@HsC_flags, $_); next arg; };
     /^-dshow-rn-trace/      && do { push(@HsC_flags, $_); next arg; };
     /^-dsource-stats/        && do { push(@HsC_flags, $_); next arg; };
     /^-dsimplifier-stats/    && do { push(@HsC_flags, $_); next arg; };
@@ -2981,7 +3070,7 @@ arg: while($_ = $Args[0]) {
        }
        next arg; };
 
        }
        next arg; };
 
-    /^-(K|Rmax-(stk|stack)size)(.*)/ && do {
+    /^(-K|Rmax-(stk|stack)size)(.*)/ && do {
         local($flag) = $1;
        local($stk_size) = &grab_arg_arg(*Args,'-Rmax-stksize', $3);
        if ($stk_size =~ /(\d+)[Kk]$/) {
         local($flag) = $1;
        local($stk_size) = &grab_arg_arg(*Args,'-Rmax-stksize', $3);
        if ($stk_size =~ /(\d+)[Kk]$/) {