[project @ 1997-09-03 15:55:02 by simonm]
[ghc-hetmet.git] / ghc / driver / ghc.lprl
index ee1d55f..e8c7154 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:
+    -E         stop after generating preprocessed, de-litted Haskell (used in conjunction with -cpp)
     -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)
 
@@ -64,9 +64,9 @@ Other commonly-used options are:
 
     -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.
 
@@ -191,7 +191,7 @@ $Cmp  = 'cmp';
 $Time = '';
 
 $HsCpp  = # but this is re-set to "cat" (after options) if -cpp not seen
-          ( $INSTALLING ) ? "$InstLibexecDirGhc/hscpp"
+          ( $INSTALLING ) ? "$InstLibExecDirGhc/hscpp"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSCPP}";
 
 @HsCpp_flags   = ();
@@ -234,6 +234,7 @@ sub setupOptFlags {
    $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.
@@ -339,75 +340,6 @@ $BuildTag  = ''; # default is sequential build w/ Appel-style GC
        '_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
@@ -428,7 +360,7 @@ require special handling.
 # 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  = int($PROJECTVERSION * 100  + .5); # i.e., round (X.Y * 100)
 $Haskell1Version = 4; # i.e., Haskell 1.4
 @Cpp_define     = ();
 
@@ -454,7 +386,7 @@ $MkDependHS
        = ( $INSTALLING ) ? "$InstBinDirGhc/mkdependHS"
                          : "$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;
@@ -512,7 +444,8 @@ Here are the initial defaults applied to all files:
 \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?
@@ -521,9 +454,10 @@ $HscOut = '-C='; # '-C=' ==> .hc output; '-S=' ==> .s output; '-N=' ==> neither
 $HscOut = '-S='
     if $HaveNativeCodeGen && $TargetPlatform =~ /^(alpha|sparc)-/;
 # TEMP: disable x86  if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/;
-$ProduceHi   = '-hifile=';
-$HiOnStdout  = 0;
-$HiDiff_flag = '';
+$ProduceHi    = '-hifile=';
+$HiOnStdout   = 0;
+$HiDiff_flag  = '';
+$Keep_HiDiffs = 0;
 
 $CollectingGCstats = 0;
 $CollectGhcTimings = 0;
@@ -591,7 +525,7 @@ $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.
-$HsC_major_version = 32;
+$HsC_major_version = 33;
 $HsC_minor_version = 0;
 $Cc_major_version  = 36;
 $Cc_minor_version  = 1;
@@ -654,6 +588,7 @@ if (  $Status == 0 && $Only_generate_deps ) {
 
     push (@MkDependHS_flags, "-o$Osuffix") if $Osuffix;
     push (@MkDependHS_flags, "-s$BuildTag") if $BuildTag;
+    push (@MkDependHS_flags, "-D__HASKELL1__=$Haskell1Version");
     local($to_do) = "$MkDependHS @MkDependHS_flags -- @Cmd_opts -- @Input_file" ;
     &run_something($to_do, 'Haskell dependencies');
     exit $Status;
@@ -758,11 +693,12 @@ sub setupOptimiseFlags {
 
    @HsC_minusNoO_flags 
     = (        '-fsimplify',
-         '\(',
+         '[',
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          '-fcase-of-case',
+         '-fdo-case-elim',
 #        '-fdo-lambda-eta-expansion',  # too complicated
          '-freuse-con',
 #        '-flet-to-case',              # no strictness analysis, so...
@@ -779,7 +715,8 @@ sub setupOptimiseFlags {
 
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
        $Oopt_AddAutoSccs,
 #      '-ffull-laziness',      # removed 95/04 WDP following Andr\'e's lead
        
@@ -792,7 +729,7 @@ sub setupOptimiseFlags {
 
        # initial simplify: mk specialiser happy: minimum effort please
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-fkeep-spec-pragma-ids',     # required before specialisation
 
@@ -814,7 +751,7 @@ sub setupOptimiseFlags {
 
          '-fmax-simplifier-iterations1',
          $Oopt_PedanticBottoms,
-         '\)',
+         ']',
 
        ($Oopt_DoSpecialise) ? (
          '-fspecialise-overloaded',
@@ -823,7 +760,7 @@ sub setupOptimiseFlags {
        ) : (),
 
        '-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',
@@ -837,7 +774,8 @@ sub setupOptimiseFlags {
          $Oopt_MonadEtaExpansion,
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
 
 #LATER:        '-fcalc-inlinings1', -- pointless for 2.01
 
@@ -845,7 +783,7 @@ sub setupOptimiseFlags {
 #              '-ffoldr-build-ww-anal',
 #              '-ffoldr-build-worker-wrapper',
 #              '-fsimplify', 
-#                '\(', 
+#                '[', 
 #                $Oopt_FB_Support,
 #                '-ffloat-lets-exposing-whnf',
 #                '-ffloat-primops-ok',
@@ -859,7 +797,8 @@ sub setupOptimiseFlags {
 #                $Oopt_MonadEtaExpansion,
 #                $Oopt_UnfoldingUseThreshold,
 #                $Oopt_MaxSimplifierIterations,
-#                '\)',
+#                $Oopt_ShowSimplifierProgress,
+#                ']',
 #       ) : (),
 
        # this pass-ordering sequence was agreed by Simon and Andr\'e
@@ -870,7 +809,7 @@ sub setupOptimiseFlags {
          '-ffoldr-build-on',           # desugar list comprehensions for foldr/build
 
          '-fsimplify', 
-           '\(', 
+           '[', 
            '-fignore-inline-pragma',   # **** NB!
            '-fdo-foldr-build',         # NB
            $Oopt_FB_Support,
@@ -886,13 +825,14 @@ sub setupOptimiseFlags {
            $Oopt_MonadEtaExpansion,
            $Oopt_UnfoldingUseThreshold,
            $Oopt_MaxSimplifierIterations,
-           '\)',
+           $Oopt_ShowSimplifierProgress,
+           ']',
        ) : (),
 
        '-ffloat-inwards',
 
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -910,12 +850,13 @@ sub setupOptimiseFlags {
          $Oopt_MonadEtaExpansion,
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
 
        '-fstrictness',
 
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -930,7 +871,8 @@ sub setupOptimiseFlags {
          $Oopt_MonadEtaExpansion,
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
 
        '-ffloat-inwards',
 
@@ -939,12 +881,12 @@ sub setupOptimiseFlags {
 
 #      ( ($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',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -963,7 +905,8 @@ sub setupOptimiseFlags {
          $Oopt_MonadEtaExpansion,
          $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
 
       #        '-fstatic-args',
 
@@ -1010,6 +953,8 @@ if ( $OptLevel <= 0 ) {
 } 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...
 }
 
@@ -1216,15 +1161,12 @@ sub setupMachOpts {
       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
 # :-(   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(@Ld_flags, ('-Xlinker -bbigtoc -Xlinker -bnoquiet')); # we have lots of toc entries..
-      unshift(@Ld_flags, ('-Xlinker -bbigtoc')); # we have lots of toc entries...
-
   } elsif ($TargetPlatform =~ /^sparc-/) {
       # we know how to *mangle* asm for SPARC
       unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
@@ -1256,7 +1198,11 @@ sub setupLinkOpts {
          ,'-u', "${uscore}STBase_SZh_static_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
 
@@ -1371,8 +1317,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");
-    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");
 }
 
@@ -1593,7 +1539,7 @@ 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
 
     # OK, let's strip off some literate junk..
-    if ($ifile =~ /\.lhs$/) {
+    if ($do_lit2pgm) {
         &runLit2pgm($in_lit2pgm, $lit2pgm_hscpp)
     } else {
         $lit2pgm_hscpp = $ifile;
@@ -1604,7 +1550,8 @@ Again, we'll do the post-recompilation-checker parts of this later.
 
     # Scan the top of the de-litted file for {-# OPTIONS #-} pragmas
     &check_for_source_options($lit2pgm_hscpp,$ifile);
-    # options found in the source file take a back seat, i.e., we scan
+
+    # 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).
@@ -1644,7 +1591,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" ;
 
-    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;
@@ -1662,8 +1614,8 @@ Again, we'll do the post-recompilation-checker parts of this later.
     # 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
@@ -1672,6 +1624,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>"@.
+
 \begin{code}
     local($going_interactive) = $HscOut eq '-N=' || $ifile_root eq '_stdin';
 
@@ -1680,7 +1633,7 @@ phase) to @"$ifile_root.<suffix>"@.
     # -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
@@ -1694,7 +1647,7 @@ phase) to @"$ifile_root.<suffix>"@.
     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
     }
@@ -1712,7 +1665,7 @@ Now the Haskell compiler, C compiler, and assembler
 
     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;
@@ -1751,9 +1704,13 @@ Finally, decide what to queue up for linker input.
 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');
 }
@@ -1763,20 +1720,32 @@ sub runLit2pgm {
 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) {
-       $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);
-       $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');
     }
+   
+    if ( $Only_preprocess_C ) {
+       $to_do = "$Cat $hscpp_hsc";
+       &run_something($to_do, '');
+    }
+
 }
 \end{code}
 
@@ -1801,7 +1770,7 @@ sub runHscAndProcessInterfaces {
      $i_atime,$i_mtime,$i_ctime,$i_blksize,$i_blocks) = stat($ifile);
 
     # The informational messages below are now conditional on -v being set -- SOF
-    if ( ! -f $ofile_target ) {
+    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;
     }
@@ -1809,7 +1778,7 @@ sub runHscAndProcessInterfaces {
     ($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 ) {
+    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;
     }
@@ -1817,7 +1786,7 @@ sub runHscAndProcessInterfaces {
     ($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) {
+    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;
     }
@@ -1835,7 +1804,7 @@ sub runHscAndProcessInterfaces {
    # 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;
@@ -1853,8 +1822,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.
        #
-       &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 {   
 
@@ -1879,9 +1850,10 @@ sub runHscAndProcessInterfaces {
 
 
        # 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);
-       
+        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);
+       }
        # if we're going to split up object files,
        # we inject split markers into the .hc file now
        if ( $HscOut eq '-C=' && $SplitObjFiles ) {
@@ -1911,7 +1883,7 @@ sub runHsc {
 
     # 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:
@@ -1922,7 +1894,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";
-    @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 ) {
@@ -1933,6 +1905,7 @@ sub runHsc {
     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");
     }
@@ -2037,7 +2010,7 @@ sub runGcc {
     local($cc_help_s) = "ghc$$.s";
 
     $cc       = $CcRegd;
-    $s_output = ($is_hc_file || $TargetPlatform =~ /^(powerpc|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";
 
@@ -2063,15 +2036,21 @@ EOINCL
     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.
-    if ( $Only_preprocess_C ) { # HACK ALERT!
+
+    if ( $Only_preprocess_hc ) { # HACK ALERT!
        $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;
+    if ( $Only_preprocess_hc ) {
+       system("$Cat $Tmp_prefix.ccout");
+    }
     unlink($cc_help, $cc_help_s);
 }
 \end{code}
@@ -2118,8 +2097,8 @@ 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);
 
-    } elsif ($TargetPlatform =~ /^powerpc/) {
-       # minor mangling of non-threaded files for hp-pa only
+    } 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);
@@ -2145,7 +2124,7 @@ sub runAs {
 
     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...
@@ -2165,7 +2144,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";
-           @Files_to_tidy = ( $split_out );
+           push(@Files_to_tidy, $split_out );
 
            &run_something($to_do, 'Unix assembler');
        }
@@ -2266,18 +2245,23 @@ sub process_ghc_timings {
     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>) {
-       $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;
        }
 
-       $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\)/ ) {
            $InitTime = $1; $InitElapsed = $2;
@@ -2288,8 +2272,10 @@ sub process_ghc_timings {
        }
     }
     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
@@ -2374,7 +2360,7 @@ nonsensical).
 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); 
@@ -2454,7 +2440,10 @@ sub check_for_source_options {
         elsif ( /^$/ ) { # ignore empty lines
            ;
         }
-        elsif ( /^#line.+$/ ) { # ignore comment lines
+        elsif ( /^#line.+$/ ) { # ignore comment lines (unused..ToDo: rm )
+           ;
+        }
+        elsif ( /^{-# LINE.+$/ ) { # ignore line pragmas
            ;
         }
         else { # stop looking, something non-empty / not
@@ -2484,9 +2473,9 @@ sub splitCmdLine {
 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, $_); next arg; };
+    /^--?./  && do { push(@Cmd_opts, $_); next arg; };
 
     if (/\.[oa]$/) {
        push(@Link_file, $_);
@@ -2554,7 +2543,7 @@ arg: while($_ = $Args[0]) {
     /^-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 ne '') ? 1 : 0; next arg; };
 
     /^-cpp$/       && do { $Cpp_flag_set = 1; next arg; };
     # change the global default:
@@ -2575,9 +2564,11 @@ arg: while($_ = $Args[0]) {
     /^-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');
@@ -2800,7 +2791,7 @@ 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; };
-    /^-optcpp(.*)$/ && do { push(@Cpp_define,       $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; };
@@ -2848,7 +2839,7 @@ arg: while($_ = $Args[0]) {
                                        next arg; };
 
     /^-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 {
@@ -2909,13 +2900,13 @@ arg: while($_ = $Args[0]) {
     # --------------- Renamer -------------
 
 
-    /^-fno-tycon-pruning$/ 
-                   && do { push(@HsC_flags, $_); next arg; };
+    /^-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
-    /^-fvia-C$/            && do { $HscOut = '-C='; next arg; }; # force using C compiler
+    /^-fvia-[cC]$/         && do { $HscOut = '-C='; next arg; }; # force using C compiler
 
     # ---------------
 
@@ -2926,6 +2917,9 @@ arg: while($_ = $Args[0]) {
     /^(-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; };
@@ -2950,11 +2944,14 @@ arg: while($_ = $Args[0]) {
 
     # --------------- Warnings etc. ------
 
-    /^-f(show-import-specs)/
+    /^-fshow-import-specs/
                    && do { push(@HsC_flags, $_); next arg; };
 
     # for now, just -fwarn-name-shadowing
-    /^-fwarn-(.*)$/   && do { push(@HsC_flags, $_); next arg; };
+    /^-fwarn-(.*)$/      && do { push(@HsC_flags, $_);   next arg; };
+
+    /^-fno-warn-(.*)$/   && do { push(@HsC_flags, "-fno-warn-$1"); next arg; };
+
     /^-fno-(.*)$/   && do { push(@HsC_antiflags, "-f$1");
                            &squashHscFlag("-f$1");
                            next arg; };
@@ -2988,6 +2985,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; };
+    /^-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; };