summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2021-10-06 10:45:55 +0100
committerMatthew Pickering <matthewtpickering@gmail.com>2021-10-08 11:55:06 +0100
commitdc715e59511e8a5ddd1922af1ea72c0cfcea0b33 (patch)
tree4ef6be83448139c04b08bf90d58c36484434c22e
parent298df16d7005a3cead2df1cc7280509ddf7c6c76 (diff)
downloadhaskell-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.hs4
-rw-r--r--compiler/GHC/CmmToAsm/Config.hs1
-rw-r--r--compiler/GHC/Driver/Config/CmmToAsm.hs5
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
}