- ++ [ SysTools.Option "-c"
- , SysTools.FileOption "" input_fn
- , SysTools.Option "-o"
- , SysTools.FileOption "" output_fn
- ])
-
- return (StopLn, dflags, maybe_loc, output_fn)
-
-
-runPhase SplitAs stop dflags basename _suff _input_fn get_output_fn maybe_loc
- = do
- output_fn <- get_output_fn dflags StopLn maybe_loc
-
- let (base_o, _) = splitFilename output_fn
- split_odir = base_o ++ "_split"
- osuf = objectSuf dflags
-
- createDirectoryHierarchy split_odir
-
- -- remove M_split/ *.o, because we're going to archive M_split/ *.o
- -- later and we don't want to pick up any old objects.
- fs <- getDirectoryContents split_odir
- mapM_ removeFile $ map (split_odir `joinFileName`)
- $ filter (osuf `isSuffixOf`) fs
-
- let as_opts = getOpts dflags opt_a
-
- (split_s_prefix, n) <- readIORef v_Split_info
-
- let split_s n = split_s_prefix ++ "__" ++ show n `joinFileExt` "s"
- split_obj n = split_odir `joinFileName`
- filenameOf base_o ++ "__" ++ show n
- `joinFileExt` osuf
-
- let assemble_file n
- = SysTools.runAs dflags
- (map SysTools.Option as_opts ++
- [ SysTools.Option "-c"
- , SysTools.Option "-o"
- , SysTools.FileOption "" (split_obj n)
- , SysTools.FileOption "" (split_s n)
- ])
-
- mapM_ assemble_file [1..n]
-
- -- and join the split objects into a single object file:
- let ld_r args = SysTools.runLink dflags ([
- SysTools.Option "-nostdlib",
- SysTools.Option "-nodefaultlibs",
- SysTools.Option "-Wl,-r",
- SysTools.Option ld_x_flag,
- SysTools.Option "-o",
- SysTools.FileOption "" output_fn ] ++ args)
- ld_x_flag | null cLD_X = ""
- | otherwise = "-Wl,-x"
-
- if cLdIsGNULd == "YES"
- then do
- let script = split_odir `joinFileName` "ld.script"
- writeFile script $
- "INPUT(" ++ unwords (map split_obj [1..n]) ++ ")"
- ld_r [SysTools.FileOption "" script]
- else do
- ld_r (map (SysTools.FileOption "" . split_obj) [1..n])
-
- return (StopLn, dflags, maybe_loc, output_fn)
+ ++ [ SysTools.Option "-c"
+ , SysTools.FileOption "" input_fn
+ , SysTools.Option "-o"
+ , SysTools.FileOption "" output_fn
+ ]
+ ++ map SysTools.Option md_c_flags)
+
+ return (next_phase, output_fn)
+
+
+runPhase SplitAs _input_fn dflags
+ = do
+ -- we'll handle the stub_o file in this phase, so don't MergeStub,
+ -- just jump straight to StopLn afterwards.
+ let next_phase = StopLn
+ output_fn <- phaseOutputFilename next_phase
+
+ let base_o = dropExtension output_fn
+ osuf = objectSuf dflags
+ split_odir = base_o ++ "_" ++ osuf ++ "_split"
+
+ io $ createDirectoryHierarchy split_odir
+
+ -- remove M_split/ *.o, because we're going to archive M_split/ *.o
+ -- later and we don't want to pick up any old objects.
+ fs <- io $ getDirectoryContents split_odir
+ io $ mapM_ removeFile $
+ map (split_odir </>) $ filter (osuf `isSuffixOf`) fs
+
+ let as_opts = getOpts dflags opt_a
+
+ let (split_s_prefix, n) = case splitInfo dflags of
+ Nothing -> panic "No split info"
+ Just x -> x
+
+ let split_s n = split_s_prefix ++ "__" ++ show n <.> "s"
+ split_obj n = split_odir </>
+ takeFileName base_o ++ "__" ++ show n <.> osuf
+
+ let md_c_flags = machdepCCOpts dflags
+ let assemble_file n
+ = SysTools.runAs dflags
+ (map SysTools.Option as_opts ++
+#ifdef sparc_TARGET_ARCH
+ -- We only support SparcV9 and better because V8 lacks an atomic CAS
+ -- instruction so we have to make sure that the assembler accepts the
+ -- instruction set. Note that the user can still override this
+ -- (e.g., -mcpu=ultrasparc). GCC picks the "best" -mcpu flag
+ -- regardless of the ordering.
+ --
+ -- This is a temporary hack.
+ [ SysTools.Option "-mcpu=v9" ] ++
+#endif
+ [ SysTools.Option "-c"
+ , SysTools.Option "-o"
+ , SysTools.FileOption "" (split_obj n)
+ , SysTools.FileOption "" (split_s n)
+ ]
+ ++ map SysTools.Option md_c_flags)
+
+ io $ mapM_ assemble_file [1..n]
+
+ -- If there's a stub_o file, then we make it the n+1th split object.
+ PipeState{maybe_stub_o} <- getPipeState
+ n' <- case maybe_stub_o of
+ Nothing -> return n
+ Just stub_o -> do io $ copyFile stub_o (split_obj (n+1))
+ return (n+1)
+
+ -- join them into a single .o file
+ io $ joinObjectFiles dflags (map split_obj [1..n']) output_fn
+
+ return (next_phase, output_fn)
+
+-----------------------------------------------------------------------------
+-- LlvmOpt phase
+
+runPhase LlvmOpt input_fn dflags
+ = do
+ let lo_opts = getOpts dflags opt_lo
+ let opt_lvl = max 0 (min 2 $ optLevel dflags)
+ -- don't specify anything if user has specified commands. We do this for
+ -- opt but not llc since opt is very specifically for optimisation passes
+ -- only, so if the user is passing us extra options we assume they know
+ -- what they are doing and don't get in the way.
+ let optFlag = if null lo_opts
+ then [SysTools.Option (llvmOpts !! opt_lvl)]
+ else []
+
+ output_fn <- phaseOutputFilename LlvmLlc
+
+ io $ SysTools.runLlvmOpt dflags
+ ([ SysTools.FileOption "" input_fn,
+ SysTools.Option "-o",
+ SysTools.FileOption "" output_fn]
+ ++ optFlag
+ ++ map SysTools.Option lo_opts)
+
+ return (LlvmLlc, output_fn)
+ where
+ -- we always (unless -optlo specified) run Opt since we rely on it to
+ -- fix up some pretty big deficiencies in the code we generate
+ llvmOpts = ["-mem2reg", "-O1", "-O2"]