[project @ 2000-05-16 09:08:03 by simonmar]
[ghc-hetmet.git] / ghc / driver / ghc.lprl
index 4b2ea21..7ec0015 100644 (file)
@@ -158,7 +158,14 @@ $SIG{'QUIT'} = 'quit_upon_signal';
                           : "$TopPwd/${CURRENT_DIR}" );
 
 if ( $ENV{'TMPDIR'} ) { # where to make tmp file names
-    $Tmp_prefix = ($ENV{'TMPDIR'} . "/ghc$$");
+    # Try to find a $Tmp_prefix which isn't being used...
+    $tmp = $$;
+    do {
+      $Tmp_prefix = ($ENV{'TMPDIR'} . "/ghc$tmp");
+      $tmp++;
+    } while ( -e "$Tmp_prefix.hc" ||
+             -e "$Tmp_Prefix.s"  || 
+             -e "$Tmp_Prefix.hi" );
 } else {
     print STDERR "TMPDIR has not been set to anything useful!\n" if (${TMPDIR} eq '');
     $Tmp_prefix ="${TMPDIR}/ghc$$"; # TMPDIR set via Makefile when booting..
@@ -462,12 +469,15 @@ $PostprocessCcOutput = 0;
 $Static = 1;
 $Static = 0 if ($EnableWin32DLLs eq 'YES');
 
-# native code-gen or via C?
+# Output language
 $HaveNativeCodeGen = $GhcWithNativeCodeGen;
-$HscOut = '-C='; # '-C=' ==> .hc output; '-S=' ==> .s output; '-N=' ==> neither
-$HscOut = '-S='
-    if ($HaveNativeCodeGen ne 'YES') && $TargetPlatform =~ /^(alpha)-/;
-# TEMP: disable x86 & Sparc if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/;
+$HscLang = 'C';        # 'C'    ==> .hc output; 
+                       # 'asm'  ==> .s output; 
+                       # 'java' ==> .java output
+                       # 'none' ==> no code output
+$HscLang = 'asm'
+    if ($HaveNativeCodeGen eq 'YES') && $TargetPlatform =~ /^(i386)-/;
+
 $ProduceHi    = '-hifile=';
 $HiOnStdout   = 0;
 $HiWith       = '';
@@ -495,7 +505,7 @@ $Osuffix    = '';   # default: use the normal suffix for that kind of output
 $HiSuffix   = 'hi';
 $HiSuffix_prelude = '';
 $CompilingPrelude=0;
-$Do_recomp_chkr = 0;   # don't use the recompilatio checker unless asked
+$Do_recomp_chkr = 1;   # Use the recompilation checker by default
 $Do_cc     = -1;   # a MAGIC indeterminate value; will be set to 1 or 0.
 $Do_as     = 1;
 
@@ -677,12 +687,6 @@ The (outwards-)let-floater should be the {\em last} Core-to-Core pass
 that's run.  (Um, well, howzabout the simplifier just once more...)
 \end{description}
 
-STG-TO-STG PASSES:
-\begin{description}
-\item[\tr{-fupdate-analysis}:]
-It really really wants to be the last STG-to-STG pass that is run.
-\end{description}
-
 \begin{code}
 
 sub setupOptimiseFlags {
@@ -726,25 +730,18 @@ sub setupOptimiseFlags {
                '-fno-rules',           # Similarly, don't apply any rules until after full laziness
                                        # Notably, list fusion can prevent floating.
 
+               '-fno-case-of-case',    # Don't do case-of-case transformations.
+                                       # This makes full laziness work better
+
                '-fmax-simplifier-iterations2',
          ']',
 
        # Specialisation is best done before full laziness
        # so that overloaded functions have all their dictionary lambdas manifest
        ($Oopt_DoSpecialise) ? ( $Oopt_DoSpecialise, ) : (),
-       '-ffull-laziness',
+       '-ffloat-outwards',
        '-ffloat-inwards',
 
-#      '-fsimplify',
-#        '[', 
-#              # Run the simplifier before specialising, so that overloaded functions
-#              # look like             f = \d -> ...
-#              # (Full laziness may lift out something hiding the \d
-#              '-finline-phase1',
-#              '-fmax-simplifier-iterations1',
-#        ']',
-
-
        '-fsimplify',
          '[', 
                '-finline-phase1',
@@ -766,10 +763,17 @@ sub setupOptimiseFlags {
                # before strictness analysis runs
 
                '-finline-phase2',
-               $Oopt_MaxSimplifierIterations,  
+               '-fmax-simplifier-iterations2',
          ']',
 
 
+       '-fsimplify',
+         '[', 
+               '-fmax-simplifier-iterations2',
+               # No -finline-phase: allow all Ids to be inlined now
+               # This gets foldr inlined before strictness analysis
+         ']',
+
        '-fstrictness',
        '-fcpr-analyse',
        '-fworker-wrapper',
@@ -780,12 +784,19 @@ sub setupOptimiseFlags {
                # No -finline-phase: allow all Ids to be inlined now
          ']',
 
-       '-ffull-laziness',      # nofib/spectral/hartel/wang doubles in speed if you
+       '-ffloat-outwards',     # nofib/spectral/hartel/wang doubles in speed if you
                                # do full laziness late in the day.  It only happens
                                # after fusion and other stuff, so the early pass doesn't
                                # catch it.  For the record, the redex is 
                                #       f_el22 (f_el21 r_midblock)
 
+# Leave out lambda lifting for now
+#      '-fsimplify',   # Tidy up results of full laziness
+#        '[', 
+#              '-fmax-simplifier-iterations2',
+#        ']',
+#      '-ffloat-outwards-full',        
+
        # We want CSE to follow the final full-laziness pass, because it may
        # succeed in commoning up things floated out by full laziness.
        #
@@ -828,8 +839,7 @@ sub setupOptimiseFlags {
 
       # SPECIAL FLAGS for -O2
        ($OptLevel == 2) ? (
-         '-fupdate-analysis',  # virtually useless; relegated to -O2
-         '-fsemi-tagging',
+           # none at the present time
        ) : (),
       );
 
@@ -942,9 +952,9 @@ After the sanity checks, add flags to the necessary parts of the driver pipeline
   if ( $BuildTag ne '' ) { # something other than normal sequential...
 
       local($Tag) = "${BuildTag}";
-      $Tag =~ s/_//;  # move the underscore to the back
+      $Tag =~ s/_//;   # move the underscore to the back
 
-      $HscOut = '-C='; # must go via C
+      $HscLang = 'C';  # must go via C
       &processArgs(split(' ', $SetupOpts{$BuildTag}));
 #      eval($EvaldSetupOpts{$BuildTag});
   }
@@ -1096,15 +1106,16 @@ sub setupLinkOpts {
           ,'-u', "${uscore}PrelAddr_I64zh_con_info"
           ,'-u', "${uscore}PrelAddr_W64zh_con_info"
           ,'-u', "${uscore}PrelStable_StablePtr_con_info"
-          ,'-u', "${uscore}PrelBase_False_static_closure"
-          ,'-u', "${uscore}PrelBase_True_static_closure"
+          ,'-u', "${uscore}PrelBase_False_closure"
+          ,'-u', "${uscore}PrelBase_True_closure"
           ,'-u', "${uscore}PrelPack_unpackCString_closure"
           ,'-u', "${uscore}PrelException_stackOverflow_closure"
           ,'-u', "${uscore}PrelException_heapOverflow_closure"
-          ,'-u', "${uscore}PrelException_NonTermination_static_closure"
-          ,'-u', "${uscore}PrelException_PutFullMVar_static_closure"
-          ,'-u', "${uscore}PrelException_BlockedOnDeadMVar_static_closure"
+          ,'-u', "${uscore}PrelException_NonTermination_closure"
+          ,'-u', "${uscore}PrelException_PutFullMVar_closure"
+          ,'-u', "${uscore}PrelException_BlockedOnDeadMVar_closure"
           ,'-u', "${uscore}__init_Prelude"
+          ,'-u', "${uscore}__init_PrelMain"
        ));
   if (!$NoHaskellMain) {
    unshift (@Ld_flags,'-u', "${uscore}PrelMain_mainIO_closure");
@@ -1139,14 +1150,13 @@ sub setupIncPaths {
       push (@Include_dir, "$TopPwd/${CURRENT_DIR}/${GHC_INCLUDE_DIR}");
   } else {
       push (@Include_dir, "$InstLibDirGhc/includes");
-      push (@Include_dir, "$InstLibDirGhc/includes");
   }
 } # end of setupIncPaths
 \end{code}
 
 \begin{code}
 sub setupSyslibs {
-  push(@SysLibrary, ( '-lHS', '-lHS_cbits' )); # basic I/O and prelude stuff
+  push(@SysLibrary, ( '-lHSstd', '-lHSstd_cbits' )); # basic I/O and prelude stuff
 
   local($f);
   foreach $f (@SysLibrary) {
@@ -1155,9 +1165,7 @@ sub setupSyslibs {
   }
 
   # Push library HSrts, plus boring clib bit
-  # Note: The scheduler references a closure from PrelException,
-  # so the prelude lib is mentioned once again here.
-  push(@SysLibrary, "-lHSrts${BuildTag} -lHS${BuildTag}");
+  push(@SysLibrary, "-lHSrts${BuildTag}");
 
   #
   # RTS compiled with cygwin32, uses the WinMM API
@@ -1402,11 +1410,17 @@ Again, we'll do the post-recompilation-checker parts of this later.
     # 
     local($do_cc)      = ( $Do_cc != -1) # i.e., it was set explicitly
                          ? $Do_cc
-                         : ( ($HscOut eq '-C=') ? 1 : 0 );
+                         : ( ($HscLang eq 'C') ? 1 : 0 );
     local($do_as)      = $Do_as;
-    local($hsc_out)       = ( $HscOut eq '-C=' ) ? "$Tmp_prefix.hc" : "$Tmp_prefix.s" ;
-    local($hsc_out_c_stub) = ( $HscOut eq '-C=' ) ? "${Tmp_prefix}_stb.c" : "";
-    local($hsc_out_h_stub) = ( $HscOut eq '-C=' ) ? "${Tmp_prefix}_stb.h" : "";
+
+    local($hsc_out_suffix) = ( $HscLang eq 'C' )    ? "hc" : 
+                            ( $HscLang eq 'asm' )  ? "s" : 
+                            ( $HscLang eq 'java' ) ? "java" : 
+                               "" ;
+    
+    local($hsc_out)       = "$Tmp_prefix.$hsc_out_suffix" ;
+    local($hsc_out_c_stub) = "${Tmp_prefix}_stb.c";
+    local($hsc_out_h_stub) = "${Tmp_prefix}_stb.h";
 
     if ($Only_preprocess_hc) { # stop after having run $Cc -E
        $do_as=0;
@@ -1446,20 +1460,20 @@ 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';
+    local($going_interactive) = $HscLang eq 'none' || $ifile_root eq '_stdin';
 
     #
     # Warning issued if -keep-hc-file-too is used without
     # -fvia-C (or the equivalent)
     #
-    if ( $HscOut ne '-C=' && $Keep_hc_file_too ) {
+    if ( $HscLang ne 'C' && $Keep_hc_file_too ) {
        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
        $hsc_out = ($Specific_output_file ne '')
                 ? $Specific_output_file
-                : &odir_ify($ifile_root, ($HscOut eq '-C=') ? 'hc' : 's');
+                : &odir_ify($ifile_root, $hsc_out_suffix);
 
        $ofile_target = $hsc_out; # reset
     }
@@ -1489,17 +1503,6 @@ Now the Haskell compiler, C compiler, and assembler
     }
 
     if (-f $hsc_out_c_stub) {
-       &run_something("rm -f $ofile_c_stub_target && echo '#include \"${ofile_h_stub_target}\"' > $ofile_c_stub_target && cat $hsc_out_c_stub >> $ofile_c_stub_target", 'Copy foreign export C stubs');
-       local ($hsc_out_s_stub);
-       local ($hsc_out_o_stub);
-       ($ofile_s_stub_target = $ofile_c_stub_target) =~ s/\.(.*)$/\.s/;
-       ($ofile_o_stub_target = $ofile_c_stub_target) =~ s/\.(.*)$//;
-
-        $ofile_o_stub_target = &osuf_ify($ofile_o_stub_target, "o");
-       if ($do_cc) {
-         &runGcc    (0, $ofile_c_stub_target, $ofile_s_stub_target);
-          &runAs     ($ofile_o_stub_target, $ofile_s_stub_target);
-       }
        #
        # Bring the C stub protos into scope when compiling the .hc file.
        #
@@ -1507,7 +1510,6 @@ Now the Haskell compiler, C compiler, and assembler
        # Hack - ensure that the stub .h file is included in the OPTIONS section
        #        if the .hc file is saved.
        push (@File_options, "-#include \"${ofile_h_stub_target}\"\n");
-       
     }
 
     if ($do_cc) {
@@ -1520,6 +1522,21 @@ Now the Haskell compiler, C compiler, and assembler
     # 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;
+
+    if (-f $hsc_out_c_stub) {
+       &run_something("rm -f $ofile_c_stub_target && echo '#include \"${ofile_h_stub_target}\"' > $ofile_c_stub_target && cat $hsc_out_c_stub >> $ofile_c_stub_target", 'Copy foreign export C stubs');
+       local ($hsc_out_s_stub);
+       local ($hsc_out_o_stub);
+       ($ofile_s_stub_target = $ofile_c_stub_target) =~ s/\.(.*)$/\.s/;
+       ($ofile_o_stub_target = $ofile_c_stub_target) =~ s/\.(.*)$//;
+
+        $ofile_o_stub_target = &osuf_ify($ofile_o_stub_target, "o");
+       if ($do_cc || $do_as) {  # might be using NCG, so check $do_as
+         &runGcc    (0, $ofile_c_stub_target, $ofile_s_stub_target);
+          &runAs     ($ofile_o_stub_target, $ofile_s_stub_target);
+       }
+    }
+
 \end{code}
 
 Finally, decide what to queue up for linker input.
@@ -1669,23 +1686,12 @@ sub runHscAndProcessInterfaces {
        # Tell the C compiler and assembler not to run
        $do_cc = 0; $do_as = 0;
 
-       # Update dependency info, touch both object file and 
-       # interface file, so that the following invariant is
-        # maintained:
-       #
-       #   a dependent module's interface file should after recompilation
-        #   checking be newer than the interface files of its imports. 
-        #
-       # That is, if module A's interface file changes, then module B
-       # (which import from A) needs to be checked.
-        # If A's change does not affect B, which causes the compiler to bail
-       # out early, we still need to touch the interface file of B. The reason
-        # for this is that B may export A's interface.
+       # Update dependency info, by touching the object file
+       # This records in the file system that the work of
+       # recompiling this module has been done
        #
        &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=/ ;
+                      "Touch $ofile_target,  to propagate dependencies") if $HscLang ne 'none';
 
     } else {   
 
@@ -1694,18 +1700,20 @@ sub runHscAndProcessInterfaces {
        # If non-interactive, heave in the consistency info at the end
        # NB: pretty hackish (depends on how $output is set)
        if ( ! $going_interactive ) {
-           if ( $HscOut eq '-C=' ) {
-           $to_do = "echo 'static char ghc_hsc_ID[] = \"\@(#)hsc $ifile\t$HsC_major_version.$HsC_minor_version,$HsC_consist_options\";' >> $hsc_out";
+           if ( $HscLang eq 'C' ) {
+                $to_do = "echo 'static char ghc_hsc_ID[] = \"\@(#)hsc $ifile\t$HsC_major_version.$HsC_minor_version,$HsC_consist_options\";' >> $hsc_out";
     
-           } elsif ( $HscOut eq '-S=' ) {
+               &run_something($to_do, 'Pin on Haskell consistency info');      
+           } elsif ( $HscLang eq 'asm' ) {
                local($consist) = "hsc.$ifile.$HsC_major_version.$HsC_minor_version.$HsC_consist_options";
                $consist =~ s/,/./g;
                $consist =~ s/\//./g;
                $consist =~ s/-/_/g;
                $consist =~ s/[^A-Za-z0-9_.]/ZZ/g; # ToDo: properly?
                $to_do = "echo '\n\t.text\n$consist:' >> $hsc_out";
+               &run_something($to_do, 'Pin on Haskell consistency info');      
            }
-           &run_something($to_do, 'Pin on Haskell consistency info');  
+           # no consistency info for Java output files
        }   
 
 
@@ -1716,12 +1724,12 @@ sub runHscAndProcessInterfaces {
        }
        # if we're going to split up object files,
        # we inject split markers into the .hc file now
-       if ( $HscOut eq '-C=' && $SplitObjFiles ) {
+       if ( $HscLang 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) {
+       if ($HscLang eq 'C' && $do_cc && $Keep_hc_file_too) {
             &saveIntermediate($ifile_root , "hc" , $hsc_out);
        }
 
@@ -1750,7 +1758,8 @@ 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 -F=$hsc_out_c_stub -FH=$hsc_out_h_stub";
+    $oflags = ( $HscLang eq 'none' ? "" : "-olang=$HscLang -ofile=$hsc_out" ) ;
+    $output = "$ProduceHi$hsc_hi $oflags -F=$hsc_out_c_stub -FH=$hsc_out_h_stub";
     push(@Files_to_tidy, $hsc_hi, $hsc_out, $hsc_out_c_stub, $hsc_out_h_stub );
 
     # if we're compiling foo.hs, we want the GC stats to end up in foo.stat
@@ -2540,7 +2549,7 @@ sub add_syslib {
               : "$TopPwd/hslibs/concurrent"
          )
        , '' # where to find the cbits archive to use when linking
-       , '' # Syslib dependencies
+       , 'lang' # Syslib dependencies
        , '' # extra ghc opts
        , '' # extra cc opts
        , '' # extra ld opts
@@ -2646,10 +2655,10 @@ sub add_syslib {
               ? "$InstLibDirGhc"
               : "$TopPwd/hslibs/util/cbits"
          )
-       , 'lang concurrent' # Syslib dependencies
+       , 'lang concurrent posix' # Syslib dependencies
        , ''     # extra ghc opts
        , ''     # extra cc opts
-       , ''     # extra ld opts
+       , "$LibsReadline"     # extra ld opts
        ],
 
        win32,
@@ -2801,7 +2810,7 @@ sub splitCmdLine {
 arg: while($_ = $args[0]) {
     shift(@args);
     # sigh, we have to deal with these -option arg specially here.
-    /^-(tmpdir|odir|ohi|o|isuf|osuf|hisuf|odump|syslib)$/ && 
+    /^-(tmpdir|odir|ohi|o|isuf|osuf|hisuf|odump|syslib|package|package-name)$/ && 
        do { push(@Cmd_opts, $_); push(@Cmd_opts,$args[0]); shift(@args); next arg; };
     /^--?./  && do { push(@Cmd_opts, $_); next arg; };
 
@@ -2892,11 +2901,15 @@ arg: while($_ = $Args[0]) {
     # change the global default:
     # we won't run cat; we'll run the real thing
        
-    /^-C$/         && do { $Do_cc = 0; $Do_as = 0; $Do_lnkr = 0; $HscOut = '-C=';
+    /^-C$/         && do { $Do_cc = 0; $Do_as = 0; $Do_lnkr = 0; $HscLang = 'C';
                            next arg; };
     # stop after generating C
        
-    /^-noC$/       && do { $HscOut = '-N='; $ProduceHi = '-nohifile=';
+    /^-J$/         && do { $Do_cc = 0; $Do_as = 0; $Do_lnkr = 0; $HscLang = 'java';
+                           next arg; };
+    # stop after generating Java
+       
+    /^-noC$/       && do { $HscLang = 'none'; $ProduceHi = '-nohifile=';
                            $Do_cc = 0; $Do_as = 0; $Do_lnkr = 0;
                            next arg; };
     # leave out actual C generation (debugging) [also turns off interface gen]
@@ -3094,10 +3107,21 @@ arg: while($_ = $Args[0]) {
     /^-L(.*)/      && do { push(@UserLibrary_dir, &grab_arg_arg(*Args,'-L', $1)); next arg; };
     /^-l(.*)/      && do { push(@UserLibrary,'-l'.&grab_arg_arg(*Args,'-l', $1)); next arg; };
 
+       # DEPRECATED: use -package instead
     /^-syslib(.*)/  && do { local($syslib) = &grab_arg_arg(*Args,'-syslib',$1);
                            &add_syslib($syslib);
                            next arg; };
 
+    /^-package-name(.*)/ && do 
+                          { local($package) = &grab_arg_arg(*Args,'-package-name',$1);
+                            push(@HsC_flags,"-inpackage=$package"); 
+                            next arg; 
+                          };
+
+    /^-package(.*)/ && do { local($package) = &grab_arg_arg(*Args,'-package',$1);
+                           &add_syslib($package);
+                           next arg; };
+
     #=======================================================================
     # various flags that we can harmlessly send to one program or another
     # (we will later "reclaim" some of the compiler ones now sent to gcc)
@@ -3163,7 +3187,7 @@ arg: while($_ = $Args[0]) {
                            print STDERR "WARNING: don't know how to split objects on this platform: $TargetPlatform\n`-split-objs' option ignored\n";
                        } else {
                            $SplitObjFiles = 1;
-                           $HscOut = '-C=';
+                           $HscLang = 'C';
 
                            push(@HsC_flags, "-fglobalise-toplev-names"); 
                            push(@CcBoth_flags, '-DUSE_SPLIT_MARKERS');
@@ -3219,8 +3243,8 @@ arg: while($_ = $Args[0]) {
 
     # ---------------
 
-    /^-fasm-(.*)$/  && do { $HscOut = '-S='; next arg; }; # force using nativeGen
-    /^-fvia-[cC]$/         && do { $HscOut = '-C='; next arg; }; # force using C compiler
+    /^-fasm-(.*)$/     && do { $HscLang = 'asm'; next arg; }; # force using nativeGen
+    /^-fvia-[cC]$/     && do { $HscLang = 'C';   next arg; }; # force using C compiler
 
     # ---------------
 
@@ -3392,7 +3416,7 @@ arg: while($_ = $Args[0]) {
                local($opt_lev) = ( /^-O2$/ ) ? 2 : 1; # max 'em
                $OptLevel = ( $opt_lev > $OptLevel ) ? $opt_lev : $OptLevel;
 
-               $HscOut = '-C=' if $OptLevel == 2; # force use of C compiler
+               $HscLang = 'C';  # force use of C compiler
                next arg; };
 
     /^-Onot$/  && do { $OptLevel = 0; next arg; }; # # set it to <no opt>