diff options
author | Matthew Pickering <matthewtpickering@gmail.com> | 2021-10-06 10:45:55 +0100 |
---|---|---|
committer | Matthew Pickering <matthewtpickering@gmail.com> | 2021-10-08 11:55:06 +0100 |
commit | dc715e59511e8a5ddd1922af1ea72c0cfcea0b33 (patch) | |
tree | 4ef6be83448139c04b08bf90d58c36484434c22e | |
parent | 298df16d7005a3cead2df1cc7280509ddf7c6c76 (diff) | |
download | haskell-wip/t20428.tar.gz |
code gen: Disable dead code elimination when -finfo-table-map is enabledwip/t20428
It's important that when -finfo-table-map is enabled that we generate
IPE entries just for those info tables which are actually used. To this
end, the info tables which are used are collected just before code
generation starts and entries only created for those tables.
Not accounted for in this scheme was the dead code elimination in the
native code generator. When compiling GHC this optimisation removed an
info table which had an IPE entry which resulting in the following kind
of linker error:
```
/home/matt/ghc-with-debug/_build/stage1/lib/../lib/x86_64-linux-ghc-9.3.20210928/libHSCabal-3.5.0.0-ghc9.3.20210928.so: error: undefined reference to '.Lc5sS_info'
/home/matt/ghc-with-debug/_build/stage1/lib/../lib/x86_64-linux-ghc-9.3.20210928/libHSCabal-3.5.0.0-ghc9.3.20210928.so: error: undefined reference to '.Lc5sH_info'
/home/matt/ghc-with-debug/_build/stage1/lib/../lib/x86_64-linux-ghc-9.3.20210928/libHSCabal-3.5.0.0-ghc9.3.20210928.so: error: undefined reference to '.Lc5sm_info'
collect2: error: ld returned 1 exit status
`cc' failed in phase `Linker'. (Exit code: 1)
Development.Shake.cmd, system command failed
```
Unfortunately, by the time this optimisation happens the structure of
the CmmInfoTable has been lost, we only have the generated code for the
info table to play with so we can no longer just collect all the used
info tables and generate the IPE map.
This leaves us with two options:
1. Return a list of the names of the discarded info tables and then
remove them from the map. This is awkward because we need to do code
generation for the map as well.
2. Just disable this small code size optimisation when -finfo-table-map
is enabled. The option produces very big object files anyway.
Option 2 is much easier to implement and means we don't have to thread
information around awkwardly. It's at the cost of slightly larger object
files (as dead code is not eliminated).
Disabling this optimisation allows an IPE build of GHC to complete
successfully.
Fixes #20428
-rw-r--r-- | compiler/GHC/CmmToAsm.hs | 4 | ||||
-rw-r--r-- | compiler/GHC/CmmToAsm/Config.hs | 1 | ||||
-rw-r--r-- | compiler/GHC/Driver/Config/CmmToAsm.hs | 5 |
3 files changed, 8 insertions, 2 deletions
diff --git a/compiler/GHC/CmmToAsm.hs b/compiler/GHC/CmmToAsm.hs index f28403e9b8..13b168db37 100644 --- a/compiler/GHC/CmmToAsm.hs +++ b/compiler/GHC/CmmToAsm.hs @@ -496,7 +496,7 @@ cmmNativeGen logger modLoc ncgImpl us fileIds dbgMap cmm count -- tag instructions with register liveness information -- also drops dead code. We don't keep the cfg in sync on -- some backends, so don't use it there. - let livenessCfg = if backendMaintainsCfg platform + let livenessCfg = if ncgEnableDeadCodeElimination config then Just nativeCfgWeights else Nothing let (withLiveness, usLive) = @@ -643,7 +643,7 @@ cmmNativeGen logger modLoc ncgImpl us fileIds dbgMap cmm count let getBlks (CmmProc _info _lbl _live (ListGraph blocks)) = blocks getBlks _ = [] - when ( backendMaintainsCfg platform && + when ( ncgEnableDeadCodeElimination config && (ncgAsmLinting config || debugIsOn )) $ do let blocks = concatMap getBlks shorted let labels = setFromList $ fmap blockId blocks :: LabelSet diff --git a/compiler/GHC/CmmToAsm/Config.hs b/compiler/GHC/CmmToAsm/Config.hs index e981305845..ec4475ea14 100644 --- a/compiler/GHC/CmmToAsm/Config.hs +++ b/compiler/GHC/CmmToAsm/Config.hs @@ -45,6 +45,7 @@ data NCGConfig = NCGConfig , ncgCmmStaticPred :: !Bool -- ^ Enable static control-flow prediction , ncgEnableShortcutting :: !Bool -- ^ Enable shortcutting (don't jump to blocks only containing a jump) , ncgComputeUnwinding :: !Bool -- ^ Compute block unwinding tables + , ncgEnableDeadCodeElimination :: !Bool -- ^ Whether to enable the dead-code elimination } -- | Return Word size diff --git a/compiler/GHC/Driver/Config/CmmToAsm.hs b/compiler/GHC/Driver/Config/CmmToAsm.hs index 91be35832a..3e075ee049 100644 --- a/compiler/GHC/Driver/Config/CmmToAsm.hs +++ b/compiler/GHC/Driver/Config/CmmToAsm.hs @@ -11,6 +11,7 @@ import GHC.Platform import GHC.Unit.Types (Module) import GHC.CmmToAsm.Config import GHC.Utils.Outputable +import GHC.CmmToAsm.BlockLayout -- | Initialize the native code generator configuration from the DynFlags initNCGConfig :: DynFlags -> Module -> NCGConfig @@ -67,4 +68,8 @@ initNCGConfig dflags this_mod = NCGConfig , ncgCmmStaticPred = gopt Opt_CmmStaticPred dflags , ncgEnableShortcutting = gopt Opt_AsmShortcutting dflags , ncgComputeUnwinding = debugLevel dflags > 0 + , ncgEnableDeadCodeElimination = not (gopt Opt_InfoTableMap dflags) + -- Disable when -finfo-table-map is on (#20428) + && backendMaintainsCfg (targetPlatform dflags) + -- Enable if the platform maintains the CFG } |