[project @ 1997-07-05 02:19:07 by sof]
[ghc-hetmet.git] / ghc / driver / ghc.lprl
index 0962efb..d805d85 100644 (file)
@@ -103,7 +103,7 @@ PROJECTNAME PROJECTVERSION PROJECTPATCHLEVEL
 
 TOP_PWD
 
-INSTLIBDIR_GHC INSTDATADIR_GHC
+bindir libdir libexecdir datadir
 
 CURRENT_DIR TMPDIR
 
@@ -129,41 +129,16 @@ select(STDERR); $| = 1; select(STDOUT); # no STDERR buffering, please.
 
 $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}";
+$InstSysLibDir     = ( $INSTALLING ) ? "${InstLibDirGhc}/hslibs" : "$TopPwd/hslibs";
 
 $Status  = 0; # just used for exit() status
 $Verbose = '';
@@ -186,9 +161,26 @@ if ( $ENV{'TMPDIR'} ) { # where to make tmp file names
     $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
 
-$Unlit = ( $INSTALLING ) ? "$InstLibDirGhc/unlit"
+$Unlit = ( $INSTALLING ) ? "$InstLibExecDirGhc/unlit"
                         : "$TopPwd/${CURRENT_DIR}/${GHC_UNLIT}";
 
 $Cp   = $CP;
@@ -199,16 +191,16 @@ $Cmp  = 'cmp';
 $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
-$HsC    = ( $INSTALLING ) ? "$InstLibDirGhc/hsc"
+$HsC    = ( $INSTALLING ) ? "$InstLibExecDirGhc/hsc"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSC}";
 
 # For PVM fiends only
-$SysMan         = ( $INSTALLING ) ? "$InstLibDirGhc/SysMan"
+$SysMan         = ( $INSTALLING ) ? "$InstLibExecDirGhc/SysMan"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_SYSMAN}";
 
 @Unlit_flags   = ();
@@ -427,7 +419,7 @@ require special handling.
 
 # where to look for interface files (system hi's, i.e., prelude and hslibs)
 @SysImport_dir = ( $INSTALLING )
-                   ? ( "$InstDataDirGhc/imports" )
+                   ? ( "$InstLibDirGhc/imports" )
                    : ( "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/required"
                      , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/ghc"
                      , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/glaExts"
@@ -459,7 +451,7 @@ $TopClosureFile # defaults to 1.2 one; will be mangled later
 
 # make depend for Haskell
 $MkDependHS
-       = ( $INSTALLING ) ? "$InstLibDirGhc/mkdependHS"
+       = ( $INSTALLING ) ? "$InstBinDirGhc/mkdependHS"
                          : "$TopPwd/$CURRENT_DIR/$GHC_UTILS_DIR/mkdependHS/mkdependHS";
 # Fill in later
 @MkDependHS_flags = ( );
@@ -527,7 +519,8 @@ $PostprocessCcOutput = 0;
 $HaveNativeCodeGen = $GhcWithNativeCodeGen;
 $HscOut = '-C='; # '-C=' ==> .hc output; '-S=' ==> .s output; '-N=' ==> neither
 $HscOut = '-S='
-    if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/;
+    if $HaveNativeCodeGen && $TargetPlatform =~ /^(alpha|sparc)-/;
+# TEMP: disable x86  if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/;
 $ProduceHi   = '-hifile=';
 $HiOnStdout  = 0;
 $HiDiff_flag = '';
@@ -581,6 +574,9 @@ $NoImplicitPrelude = 0;
 # 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
@@ -595,10 +591,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.
-$HsC_major_version = 31;
+$HsC_major_version = 33;
 $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:
@@ -764,18 +760,24 @@ sub setupOptimiseFlags {
     = (        '-fsimplify',
          '\(',
          $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',
 #        '-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
-         '-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_AddAutoSccs,
@@ -793,8 +795,23 @@ sub setupOptimiseFlags {
          '\(', 
          $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,
          '\)',
@@ -1109,8 +1126,8 @@ Decide what the consistency-checking options are in force for this run:
        $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}
@@ -1155,7 +1172,10 @@ sub setupMachOpts {
   } 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
       #
@@ -1170,7 +1190,10 @@ sub setupMachOpts {
   } 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
@@ -1193,13 +1216,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, ('-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
-
   } elsif ($TargetPlatform =~ /^sparc-/) {
       # we know how to *mangle* asm for SPARC
       unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
@@ -1221,19 +1243,21 @@ sub setupLinkOpts {
   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}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
 
@@ -1256,7 +1280,7 @@ sub setupIncPaths {
       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}
@@ -1357,7 +1381,7 @@ if ($#Input_file < 0 && $#Link_file < 0) {
 
 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}
 
@@ -1569,26 +1593,31 @@ 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
 
-    $lit2pgm_hscpp = $ifile if ($ifile =~ /\.hs$/);
+    # OK, let's strip off some literate junk..
+    if ($ifile =~ /\.lhs$/) {
+        &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
-    &check_for_source_options($lit2pgm_hscpp);
+    &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) {
-        @File_options = (@File_options, @Cmd_opts);
+        #@File_options = (@File_options, @Cmd_opts);
 
         # 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
@@ -1689,6 +1718,8 @@ Now the Haskell compiler, C compiler, and assembler
 
     &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}
 
@@ -1763,15 +1794,16 @@ sub runHscAndProcessInterfaces {
        
     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);
 
+    # The informational messages below are now conditional on -v being set -- SOF
     if ( ! -f $ofile_target ) {
-#      print STDERR "$Pgm:compile:Output file $ofile_target doesn't exist\n";
+        print STDERR "$Pgm:compile:Output file $ofile_target doesn't exist\n" if $Verbose;
        $source_unchanged = 0;
     }
 
@@ -1779,7 +1811,7 @@ sub runHscAndProcessInterfaces {
      $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";
+        print STDERR "$Pgm:compile:Interface file $hifile_target doesn't exist\n" if $Verbose;
        $source_unchanged = 0;
     }
 
@@ -1787,7 +1819,7 @@ sub runHscAndProcessInterfaces {
      $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";
+       print STDERR "$Pgm:recompile:Input file $ifile newer than $ofile_target\n" if $Verbose;
        $source_unchanged = 0;
     }
 
@@ -1797,14 +1829,14 @@ sub runHscAndProcessInterfaces {
        push(@HsC_flags, '-fsource-unchanged'); 
     }  
 
-# Run the compiler
+    # Run the compiler
 
     &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;
@@ -1822,8 +1854,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 {   
 
@@ -1848,28 +1882,21 @@ 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);
-       
-       # 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');
-       }
-       
-       # 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 ( $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 ) {
            &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}
@@ -1883,9 +1910,8 @@ sub runHsc {
     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=$HiMapFile");
 
     # here, we may produce .hc/.s and/or .hi files
     local($output) = '';
@@ -1933,9 +1959,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}
-#%HiMap     = ();
 $HiMapDone = 0;
-$HiMapFile = '';
 $HiIncludeString = ();         # dir1:dir2:dir3, to pass to GHC
 
 sub makeHiMap {
@@ -1945,86 +1969,29 @@ sub makeHiMap {
     local($mod, $path, $d, $e);
 
     # reset the global variables:
-    #%HiMap     = ();
     $HiMapDone = 0;
-    $HiMapFile = '';
     $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 ) {
-       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;
 }
 
-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}
 
 %************************************************************************
@@ -2074,7 +2041,7 @@ sub runGcc {
     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";
 
@@ -2155,6 +2122,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);
 
+    } 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')
@@ -2163,10 +2135,9 @@ sub runMangler {
     }
 
     # 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}
 
@@ -2228,8 +2199,29 @@ sub run_something {
     }
 
     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")
@@ -2266,7 +2258,7 @@ sub run_something {
 
 %************************************************************************
 %*                                                                     *
-\subsection[Driver-ghctiming]{Emit nofibbish GHC timings}
+\subsection[Driver-ghc-timing]{Emit nofibbish GHC timings}
 %*                                                                     *
 %************************************************************************
 
@@ -2440,22 +2432,38 @@ file for any such pragmas:
 
 \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
-
+    
     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);
+          print STDERR "Found OPTIONS " . join(' ',@entries) . " in $file\n" if $Verbose;
           push(@File_options, @entries);
        }
         elsif ( /^$/ ) { # ignore empty lines
            ;
         }
+        elsif ( /^#line.+$/ ) { # ignore comment lines
+           ;
+        }
         else { # stop looking, something non-empty / not
-              # {-# OPTIONS .. #-} encountered.
-           break;
+              # ${comment_start} OPTIONS .. ${comment_end} encountered.
+           close(FILE);return(0);
         }
     }
     close(FILE);
@@ -2482,7 +2490,7 @@ arg: while($_ = $args[0]) {
     # sigh, we have to deal with these -option arg specially here.
     /^-(tmpdir|odir|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, $_);
@@ -2500,6 +2508,35 @@ arg: while($_ = $args[0]) {
 
 \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}
@@ -2515,7 +2552,7 @@ arg: while($_ = $Args[0]) {
     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; };
@@ -2558,7 +2595,7 @@ arg: while($_ = $Args[0]) {
        
     /^-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
@@ -2733,7 +2770,7 @@ arg: while($_ = $Args[0]) {
 
                            if ( ${INSTALLING} ) {
                                push(@SysLibrary_dir,
-                                       ("$InstSysLibDir/$TargetPlatform"));
+                                       ("$InstSysLibDir"));
                            } else {
                                push(@SysLibrary_dir,
                                        ("$TopPwd/hslibs/$syslib"
@@ -2815,7 +2852,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 {
@@ -2873,6 +2910,12 @@ arg: while($_ = $Args[0]) {
                    && 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
@@ -2915,7 +2958,10 @@ arg: while($_ = $Args[0]) {
                    && 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; };
@@ -2949,6 +2995,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; };