[Git][ghc/ghc][wip/bump-images-9.6] Use specific clang assembler when compiling with -fllvm
Matthew Pickering (@mpickering)
gitlab at gitlab.haskell.org
Fri Jan 26 14:42:27 UTC 2024
Matthew Pickering pushed to branch wip/bump-images-9.6 at Glasgow Haskell Compiler / GHC
Commits:
f8fa5b33 by Matthew Pickering at 2024-01-26T14:42:12+00:00
Use specific clang assembler when compiling with -fllvm
There are situations where LLVM will produce assembly which older gcc
toolchains can't handle. For example on Deb10, it seems that LLVM >= 13
produces assembly which the default gcc doesn't support.
A more robust solution in the long term is to require a specific LLVM
compatible assembler when using -fllvm.
- - - - -
14 changed files:
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Pipeline/Phases.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Settings.hs
- compiler/GHC/Settings/IO.hs
- compiler/GHC/SysTools/Tasks.hs
- configure.ac
- hadrian/bindist/Makefile
- hadrian/bindist/config.mk.in
- hadrian/cfg/system.config.in
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Rules/Generate.hs
- m4/fp_settings.m4
Changes:
=====================================
compiler/GHC/Driver/Pipeline.hs
=====================================
@@ -830,6 +830,12 @@ asPipeline use_cpp pipe_env hsc_env location input_fn =
StopAs -> return Nothing
_ -> Just <$> use (T_As use_cpp pipe_env hsc_env location input_fn)
+lasPipeline :: P m => Bool -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> m (Maybe ObjFile)
+lasPipeline use_cpp pipe_env hsc_env location input_fn =
+ case stop_phase pipe_env of
+ StopAs -> return Nothing
+ _ -> Just <$> use (T_LlvmAs use_cpp pipe_env hsc_env location input_fn)
+
viaCPipeline :: P m => Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> m (Maybe FilePath)
viaCPipeline c_phase pipe_env hsc_env location input_fn = do
out_fn <- use (T_Cc c_phase pipe_env hsc_env location input_fn)
@@ -853,7 +859,7 @@ llvmManglePipeline pipe_env hsc_env location llc_fn = do
if gopt Opt_NoLlvmMangler (hsc_dflags hsc_env)
then return llc_fn
else use (T_LlvmMangle pipe_env hsc_env llc_fn)
- asPipeline False pipe_env hsc_env location mangled_fn
+ lasPipeline False pipe_env hsc_env location mangled_fn
cmmCppPipeline :: P m => PipeEnv -> HscEnv -> FilePath -> m (Maybe FilePath)
cmmCppPipeline pipe_env hsc_env input_fn = do
=====================================
compiler/GHC/Driver/Pipeline/Execute.hs
=====================================
@@ -145,6 +145,8 @@ runPhase (T_LlvmOpt pipe_env hsc_env input_fn) =
runLlvmOptPhase pipe_env hsc_env input_fn
runPhase (T_LlvmLlc pipe_env hsc_env input_fn) =
runLlvmLlcPhase pipe_env hsc_env input_fn
+runPhase (T_LlvmAs cpp pipe_env hsc_env location input_fn) = do
+ runLlvmAsPhase cpp pipe_env hsc_env location input_fn
runPhase (T_LlvmMangle pipe_env hsc_env input_fn) =
runLlvmManglePhase pipe_env hsc_env input_fn
runPhase (T_MergeForeign pipe_env hsc_env input_fn fos) =
@@ -281,6 +283,58 @@ runLlvmOptPhase pipe_env hsc_env input_fn = do
return output_fn
+-- Invoke `clang` to assemble a .S file produced by LLvm toolchain
+runLlvmAsPhase :: Bool -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> IO FilePath
+runLlvmAsPhase with_cpp pipe_env hsc_env location input_fn = do
+ let dflags = hsc_dflags hsc_env
+ let logger = hsc_logger hsc_env
+
+ let cmdline_include_paths = includePaths dflags
+ let pic_c_flags = picCCOpts dflags
+
+ output_fn <- phaseOutputFilenameNew StopLn pipe_env hsc_env location
+
+ -- we create directories for the object file, because it
+ -- might be a hierarchical module.
+ createDirectoryIfMissing True (takeDirectory output_fn)
+
+ let global_includes = [ GHC.SysTools.Option ("-I" ++ p)
+ | p <- includePathsGlobal cmdline_include_paths ]
+ let local_includes = [ GHC.SysTools.Option ("-iquote" ++ p)
+ | p <- includePathsQuote cmdline_include_paths ++
+ includePathsQuoteImplicit cmdline_include_paths]
+ let runAssembler inputFilename outputFilename
+ = withAtomicRename outputFilename $ \temp_outputFilename ->
+ runLlvmAs
+ logger dflags
+ (local_includes ++ global_includes
+ -- See Note [-fPIC for assembler]
+ ++ map GHC.SysTools.Option pic_c_flags
+ -- See Note [Produce big objects on Windows]
+ ++ [ GHC.SysTools.Option "-Wa,-mbig-obj"
+ | platformOS (targetPlatform dflags) == OSMinGW32
+ , not $ target32Bit (targetPlatform dflags)
+ ]
+
+ -- See Note [-Wa,--no-type-check on wasm32]
+ ++ [ GHC.SysTools.Option "-Wa,--no-type-check"
+ | platformArch (targetPlatform dflags) == ArchWasm32]
+
+ ++ [ GHC.SysTools.Option "-x"
+ , if with_cpp
+ then GHC.SysTools.Option "assembler-with-cpp"
+ else GHC.SysTools.Option "assembler"
+ , GHC.SysTools.Option "-c"
+ , GHC.SysTools.FileOption "" inputFilename
+ , GHC.SysTools.Option "-o"
+ , GHC.SysTools.FileOption "" temp_outputFilename
+ , GHC.SysTools.Option "-Wno-unused-command-line-argument"
+ ])
+
+ debugTraceMsg logger 4 (text "Running the assembler")
+ runAssembler input_fn output_fn
+
+ return output_fn
runAsPhase :: Bool -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> IO FilePath
runAsPhase with_cpp pipe_env hsc_env location input_fn = do
=====================================
compiler/GHC/Driver/Pipeline/Phases.hs
=====================================
@@ -47,6 +47,7 @@ data TPhase res where
T_ForeignJs :: PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> TPhase FilePath
T_LlvmOpt :: PipeEnv -> HscEnv -> FilePath -> TPhase FilePath
T_LlvmLlc :: PipeEnv -> HscEnv -> FilePath -> TPhase FilePath
+ T_LlvmAs :: Bool -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> TPhase FilePath
T_LlvmMangle :: PipeEnv -> HscEnv -> FilePath -> TPhase FilePath
T_MergeForeign :: PipeEnv -> HscEnv -> FilePath -> [FilePath] -> TPhase FilePath
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -108,6 +108,7 @@ module GHC.Driver.Session (
sPgm_ranlib,
sPgm_lo,
sPgm_lc,
+ sPgm_las,
sPgm_i,
sOpt_L,
sOpt_P,
@@ -136,10 +137,10 @@ module GHC.Driver.Session (
extraGccViaCFlags, globalPackageDatabasePath,
pgm_L, pgm_P, pgm_F, pgm_c, pgm_cxx, pgm_cpp, pgm_a, pgm_l, pgm_lm,
pgm_T, pgm_windres, pgm_ar,
- pgm_ranlib, pgm_lo, pgm_lc, pgm_i,
+ pgm_ranlib, pgm_lo, pgm_lc, pgm_las, pgm_i,
opt_L, opt_P, opt_F, opt_c, opt_cxx, opt_a, opt_l, opt_lm, opt_i,
opt_P_signature,
- opt_windres, opt_lo, opt_lc,
+ opt_windres, opt_lo, opt_lc, opt_las,
updatePlatformConstants,
-- ** Manipulating DynFlags
@@ -416,6 +417,8 @@ pgm_lo :: DynFlags -> (String,[Option])
pgm_lo dflags = toolSettings_pgm_lo $ toolSettings dflags
pgm_lc :: DynFlags -> (String,[Option])
pgm_lc dflags = toolSettings_pgm_lc $ toolSettings dflags
+pgm_las :: DynFlags -> (String,[Option])
+pgm_las dflags = toolSettings_pgm_las $ toolSettings dflags
pgm_i :: DynFlags -> String
pgm_i dflags = toolSettings_pgm_i $ toolSettings dflags
opt_L :: DynFlags -> [String]
@@ -453,6 +456,8 @@ opt_lo :: DynFlags -> [String]
opt_lo dflags= toolSettings_opt_lo $ toolSettings dflags
opt_lc :: DynFlags -> [String]
opt_lc dflags= toolSettings_opt_lc $ toolSettings dflags
+opt_las :: DynFlags -> [String]
+opt_las dflags = toolSettings_opt_las $ toolSettings dflags
opt_i :: DynFlags -> [String]
opt_i dflags= toolSettings_opt_i $ toolSettings dflags
@@ -1057,6 +1062,8 @@ dynamic_flags_deps = [
$ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_pgm_lo = (f,[]) }
, make_ord_flag defFlag "pgmlc"
$ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_pgm_lc = (f,[]) }
+ , make_ord_flag defFlag "pgmlas"
+ $ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_pgm_las = (f,[]) }
, make_ord_flag defFlag "pgmlm"
$ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_pgm_lm =
if null f then Nothing else Just (f,[]) }
@@ -1112,6 +1119,8 @@ dynamic_flags_deps = [
$ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_opt_lo = f : toolSettings_opt_lo s }
, make_ord_flag defFlag "optlc"
$ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_opt_lc = f : toolSettings_opt_lc s }
+ , make_ord_flag defFlag "optlas"
+ $ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_opt_las = f : toolSettings_opt_las s }
, make_ord_flag defFlag "opti"
$ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_opt_i = f : toolSettings_opt_i s }
, make_ord_flag defFlag "optL"
=====================================
compiler/GHC/Settings.hs
=====================================
@@ -41,6 +41,7 @@ module GHC.Settings
, sPgm_ranlib
, sPgm_lo
, sPgm_lc
+ , sPgm_las
, sPgm_i
, sOpt_L
, sOpt_P
@@ -118,6 +119,8 @@ data ToolSettings = ToolSettings
toolSettings_pgm_lo :: (String, [Option])
, -- | LLVM: llc static compiler
toolSettings_pgm_lc :: (String, [Option])
+ -- | LLVM: assembler
+ , toolSettings_pgm_las :: (String, [Option])
, toolSettings_pgm_i :: String
-- options for particular phases
@@ -137,6 +140,7 @@ data ToolSettings = ToolSettings
toolSettings_opt_lo :: [String]
, -- | LLVM: llc static compiler
toolSettings_opt_lc :: [String]
+ , toolSettings_opt_las :: [String]
, -- | iserv options
toolSettings_opt_i :: [String]
@@ -233,6 +237,8 @@ sPgm_lo :: Settings -> (String, [Option])
sPgm_lo = toolSettings_pgm_lo . sToolSettings
sPgm_lc :: Settings -> (String, [Option])
sPgm_lc = toolSettings_pgm_lc . sToolSettings
+sPgm_las :: Settings -> (String, [Option])
+sPgm_las = toolSettings_pgm_las . sToolSettings
sPgm_i :: Settings -> String
sPgm_i = toolSettings_pgm_i . sToolSettings
sOpt_L :: Settings -> [String]
=====================================
compiler/GHC/Settings/IO.hs
=====================================
@@ -149,6 +149,7 @@ initSettings top_dir = do
-- We just assume on command line
lc_prog <- getSetting "LLVM llc command"
lo_prog <- getSetting "LLVM opt command"
+ las_prog <- getSetting "LLVM llvm-as command"
let iserv_prog = libexec "ghc-iserv"
@@ -196,6 +197,7 @@ initSettings top_dir = do
, toolSettings_pgm_ranlib = ranlib_path
, toolSettings_pgm_lo = (lo_prog,[])
, toolSettings_pgm_lc = (lc_prog,[])
+ , toolSettings_pgm_las = (las_prog, [])
, toolSettings_pgm_i = iserv_prog
, toolSettings_opt_L = []
, toolSettings_opt_P = []
@@ -209,6 +211,7 @@ initSettings top_dir = do
, toolSettings_opt_windres = []
, toolSettings_opt_lo = []
, toolSettings_opt_lc = []
+ , toolSettings_opt_las = []
, toolSettings_opt_i = []
, toolSettings_extraGccViaCFlags = extraGccViaCFlags
=====================================
compiler/GHC/SysTools/Tasks.hs
=====================================
@@ -215,6 +215,14 @@ runLlvmLlc logger dflags args = traceSystoolCommand logger "llc" $ do
args1 = map Option (getOpts dflags opt_lc)
runSomething logger "LLVM Compiler" p (args0 ++ args1 ++ args)
+-- | Run the LLVM Assembler
+runLlvmAs :: Logger -> DynFlags -> [Option] -> IO ()
+runLlvmAs logger dflags args = traceSystoolCommand logger "llvm-as" $ do
+ let (p,args0) = pgm_las dflags
+ args1 = map Option (getOpts dflags opt_las)
+ runSomething logger "LLVM assembler" p (args0 ++ args1 ++ args)
+
+
runEmscripten :: Logger -> DynFlags -> [Option] -> IO ()
runEmscripten logger dflags args = traceSystoolCommand logger "emcc" $ do
let (p,args0) = pgm_a dflags
=====================================
configure.ac
=====================================
@@ -526,6 +526,13 @@ FIND_LLVM_PROG([OPT], [opt], [$LlvmMinVersion], [$LlvmMaxVersion])
OptCmd="$OPT"
AC_SUBST([OptCmd])
+dnl ** Which LLVM assembler to use?
+dnl --------------------------------------------------------------
+AC_ARG_VAR(LLVMAS,[Use as the path to LLVM's llvm-as [default=autodetect]])
+FIND_LLVM_PROG([LLVMAS], [clang], [$LlvmMinVersion], [$LlvmMaxVersion])
+LlvmAsCmd="$LLVMAS"
+AC_SUBST([LlvmAsCmd])
+
dnl --------------------------------------------------------------
dnl End of configure script option section
dnl --------------------------------------------------------------
=====================================
hadrian/bindist/Makefile
=====================================
@@ -133,6 +133,7 @@ lib/settings : config.mk
@echo ',("LLVM target", "$(LLVMTarget_CPP)")' >> $@
@echo ',("LLVM llc command", "$(SettingsLlcCommand)")' >> $@
@echo ',("LLVM opt command", "$(SettingsOptCommand)")' >> $@
+ @echo ',("LLVM llvm-as command", "$(SettingsLlvmAsCommand)")' >> $@
@echo ',("Use inplace MinGW toolchain", "$(SettingsUseDistroMINGW)")' >> $@
@echo
@echo ',("Use interpreter", "$(GhcWithInterpreter)")' >> $@
=====================================
hadrian/bindist/config.mk.in
=====================================
@@ -230,5 +230,6 @@ SettingsLibtoolCommand = @SettingsLibtoolCommand@
SettingsTouchCommand = @SettingsTouchCommand@
SettingsLlcCommand = @SettingsLlcCommand@
SettingsOptCommand = @SettingsOptCommand@
+SettingsLlvmAsCommand = @SettingsLlvmAsCommand@
SettingsUseDistroMINGW = @SettingsUseDistroMINGW@
=====================================
hadrian/cfg/system.config.in
=====================================
@@ -85,6 +85,7 @@ settings-install_name_tool-command = @SettingsInstallNameToolCommand@
settings-touch-command = @SettingsTouchCommand@
settings-llc-command = @SettingsLlcCommand@
settings-opt-command = @SettingsOptCommand@
+settings-llvm-as-command = @SettingsLlvmAsCommand@
settings-use-distro-mingw = @SettingsUseDistroMINGW@
target-has-libm = @TargetHasLibm@
=====================================
hadrian/src/Oracles/Setting.hs
=====================================
@@ -89,6 +89,7 @@ data ToolchainSetting
| ToolchainSetting_TouchCommand
| ToolchainSetting_LlcCommand
| ToolchainSetting_OptCommand
+ | ToolchainSetting_LlvmAsCommand
| ToolchainSetting_DistroMinGW
-- | Look up the value of a 'Setting' in @cfg/system.config@, tracking the
@@ -140,6 +141,7 @@ settingsFileSetting key = lookupSystemConfig $ case key of
ToolchainSetting_TouchCommand -> "settings-touch-command"
ToolchainSetting_LlcCommand -> "settings-llc-command"
ToolchainSetting_OptCommand -> "settings-opt-command"
+ ToolchainSetting_LlvmAsCommand -> "settings-llvm-as-command"
ToolchainSetting_DistroMinGW -> "settings-use-distro-mingw" -- ROMES:TODO: This option doesn't seem to be in ghc-toolchain yet. It corresponds to EnableDistroToolchain
-- | An expression that looks up the value of a 'Setting' in @cfg/system.config@,
=====================================
hadrian/src/Rules/Generate.hs
=====================================
@@ -398,6 +398,7 @@ generateSettings = do
, ("LLVM target", queryTarget tgtLlvmTarget)
, ("LLVM llc command", expr $ settingsFileSetting ToolchainSetting_LlcCommand)
, ("LLVM opt command", expr $ settingsFileSetting ToolchainSetting_OptCommand)
+ , ("LLVM llvm-as command", expr $ settingsFileSetting ToolchainSetting_LlvmAsCommand)
, ("Use inplace MinGW toolchain", expr $ settingsFileSetting ToolchainSetting_DistroMinGW)
, ("Use interpreter", expr $ yesNo <$> ghcWithInterpreter)
=====================================
m4/fp_settings.m4
=====================================
@@ -123,6 +123,41 @@ AC_DEFUN([FP_SETTINGS],
fi
SettingsOptCommand="$OptCmd"
+ if test -z "$LlvmAsCmd"; then
+ LlvmAsCmd="llvm-as"
+ fi
+ SettingsLlvmAsCommand="$LlvmAsCmd"
+
+ # Mac-only tools
+ if test -z "$OtoolCmd"; then
+ OtoolCmd="otool"
+ fi
+ SettingsOtoolCommand="$OtoolCmd"
+
+ if test -z "$InstallNameToolCmd"; then
+ InstallNameToolCmd="install_name_tool"
+ fi
+ SettingsInstallNameToolCommand="$InstallNameToolCmd"
+
+ SettingsCCompilerSupportsNoPie="$CONF_GCC_SUPPORTS_NO_PIE"
+
+ AC_SUBST(SettingsCCompilerCommand)
+ AC_SUBST(SettingsCxxCompilerCommand)
+ AC_SUBST(SettingsCPPCommand)
+ AC_SUBST(SettingsCPPFlags)
+ AC_SUBST(SettingsHaskellCPPCommand)
+ AC_SUBST(SettingsHaskellCPPFlags)
+ AC_SUBST(SettingsCCompilerFlags)
+ AC_SUBST(SettingsCxxCompilerFlags)
+ AC_SUBST(SettingsCCompilerLinkFlags)
+ AC_SUBST(SettingsCCompilerSupportsNoPie)
+ AC_SUBST(SettingsMergeObjectsCommand)
+ AC_SUBST(SettingsMergeObjectsFlags)
+ AC_SUBST(SettingsArCommand)
+ AC_SUBST(SettingsRanlibCommand)
+ AC_SUBST(SettingsOtoolCommand)
+ AC_SUBST(SettingsInstallNameToolCommand)
+
# Mac-only tools
if test -z "$OtoolCmd"; then
OtoolCmd="otool"
@@ -156,5 +191,6 @@ AC_DEFUN([FP_SETTINGS],
AC_SUBST(SettingsTouchCommand)
AC_SUBST(SettingsLlcCommand)
AC_SUBST(SettingsOptCommand)
+ AC_SUBST(SettingsLlvmAsCommand)
AC_SUBST(SettingsUseDistroMINGW)
])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f8fa5b33624384c153807fbc64ed5bc43cc061d9
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f8fa5b33624384c153807fbc64ed5bc43cc061d9
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20240126/2f18da03/attachment-0001.html>
More information about the ghc-commits
mailing list