diff options
author | Michael Sloan <mgsloan@gmail.com> | 2019-03-13 23:04:41 -0700 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-05-22 16:37:57 -0400 |
commit | 21272670581608b96a85cfb942af81ada3cfd450 (patch) | |
tree | 703a1256e31868e0878706b9b60781add68ed2c0 /compiler/main | |
parent | 0dc7985663efa1739aafb480759e2e2e7fca2a36 (diff) | |
download | haskell-21272670581608b96a85cfb942af81ada3cfd450.tar.gz |
Have GHCi use object code for UnboxedTuples modules #15454
The idea is to automatically enable -fobject-code for modules that use
UnboxedTuples, along with all the modules they depend on. When looking
into how to solve this, I was pleased to find that there was already
highly similar logic for enabling code generation when -fno-code is
specified but TemplateHaskell is used.
The state before this patch was that if you used unboxed tuples then you
had to enable `-fobject-code` globally rather than on a per module
basis.
Diffstat (limited to 'compiler/main')
-rw-r--r-- | compiler/main/GhcMake.hs | 65 |
1 files changed, 55 insertions, 10 deletions
diff --git a/compiler/main/GhcMake.hs b/compiler/main/GhcMake.hs index fe4c9781e2..ac92f3b42b 100644 --- a/compiler/main/GhcMake.hs +++ b/compiler/main/GhcMake.hs @@ -1430,6 +1430,7 @@ upsweep_mod hsc_env mHscMessage old_hpt (stable_obj, stable_bco) summary mod_ind && (not (isObjectTarget prevailing_target) || not (isObjectTarget local_target)) && not (prevailing_target == HscNothing) + && not (prevailing_target == HscInterpreted) then prevailing_target else local_target @@ -1955,7 +1956,11 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots then enableCodeGenForTH (defaultObjectTarget (settings dflags)) map0 - else return map0 + else if hscTarget dflags == HscInterpreted + then enableCodeGenForUnboxedTuples + (defaultObjectTarget (settings dflags)) + map0 + else return map0 return $ concat $ nodeMapElts map1 where calcDeps = msDeps @@ -2034,7 +2039,50 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots enableCodeGenForTH :: HscTarget -> NodeMap [Either ErrMsg ModSummary] -> IO (NodeMap [Either ErrMsg ModSummary]) -enableCodeGenForTH target nodemap = +enableCodeGenForTH = + enableCodeGenWhen condition should_modify TFL_CurrentModule TFL_GhcSession + where + condition = isTemplateHaskellOrQQNonBoot + should_modify (ModSummary { ms_hspp_opts = dflags }) = + hscTarget dflags == HscNothing && + -- Don't enable codegen for TH on indefinite packages; we + -- can't compile anything anyway! See #16219. + not (isIndefinite dflags) + +-- | Update the every ModSummary that is depended on +-- by a module that needs unboxed tuples. We enable codegen to +-- the specified target, disable optimization and change the .hi +-- and .o file locations to be temporary files. +-- +-- This is used used in order to load code that uses unboxed tuples +-- into GHCi while still allowing some code to be interpreted. +enableCodeGenForUnboxedTuples :: HscTarget + -> NodeMap [Either ErrMsg ModSummary] + -> IO (NodeMap [Either ErrMsg ModSummary]) +enableCodeGenForUnboxedTuples = + enableCodeGenWhen condition should_modify TFL_GhcSession TFL_CurrentModule + where + condition ms = + xopt LangExt.UnboxedTuples (ms_hspp_opts ms) && + not (isBootSummary ms) + should_modify (ModSummary { ms_hspp_opts = dflags }) = + hscTarget dflags == HscInterpreted + +-- | Helper used to implement 'enableCodeGenForTH' and +-- 'enableCodeGenForUnboxedTuples'. In particular, this enables +-- unoptimized code generation for all modules that meet some +-- condition (first parameter), or are dependencies of those +-- modules. The second parameter is a condition to check before +-- marking modules for code generation. +enableCodeGenWhen + :: (ModSummary -> Bool) + -> (ModSummary -> Bool) + -> TempFileLifetime + -> TempFileLifetime + -> HscTarget + -> NodeMap [Either ErrMsg ModSummary] + -> IO (NodeMap [Either ErrMsg ModSummary]) +enableCodeGenWhen condition should_modify staticLife dynLife target nodemap = traverse (traverse (traverse enable_code_gen)) nodemap where enable_code_gen ms @@ -2042,18 +2090,15 @@ enableCodeGenForTH target nodemap = { ms_mod = ms_mod , ms_location = ms_location , ms_hsc_src = HsSrcFile - , ms_hspp_opts = dflags@DynFlags - {hscTarget = HscNothing} + , ms_hspp_opts = dflags } <- ms - -- Don't enable codegen for TH on indefinite packages; we - -- can't compile anything anyway! See #16219. - , not (isIndefinite dflags) + , should_modify ms , ms_mod `Set.member` needs_codegen_set = do let new_temp_file suf dynsuf = do - tn <- newTempName dflags TFL_CurrentModule suf + tn <- newTempName dflags staticLife suf let dyn_tn = tn -<.> dynsuf - addFilesToClean dflags TFL_GhcSession [dyn_tn] + addFilesToClean dflags dynLife [dyn_tn] return tn -- We don't want to create .o or .hi files unless we have been asked -- to by the user. But we need them, so we patch their locations in @@ -2076,7 +2121,7 @@ enableCodeGenForTH target nodemap = [ ms | mss <- Map.elems nodemap , Right ms <- mss - , isTemplateHaskellOrQQNonBoot ms + , condition ms ] -- find the set of all transitive dependencies of a list of modules. |