[Git][ghc/ghc][master] llvm: fix split sections for llvm backend
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b18b2c42 by Cheng Shao at 2026-01-17T06:03:44-05:00 llvm: fix split sections for llvm backend This patch fixes split sections for llvm backend: - Pass missing `--data-sections`/`--function-sections` flags to llc/opt. - Use `@llvm.compiler.used` instead of `@llvm.used` to avoid sections being unnecessarily retained at link-time. Fixes #26770. ------------------------- Metric Decrease: libdir size_hello_artifact size_hello_unicode ------------------------- Co-authored-by: Codex <codex@openai.com> - - - - - 3 changed files: - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Driver/Pipeline/Execute.hs Changes: ===================================== compiler/GHC/CmmToLlvm.hs ===================================== @@ -271,15 +271,23 @@ cmmUsedLlvmGens = do -- used if we didn't provide these hints. This will generate a -- definition of the form -- - -- @llvm.used = appending global [42 x i8*] [i8* bitcast <var> to i8*, ...] + -- @llvm.compiler.used = appending global [42 x i8*] [i8* bitcast <var> to i8*, ...] -- -- Which is the LLVM way of protecting them against getting removed. + -- + -- We used to emit @llvm.used, but it's too strong and results in + -- SHF_GNU_RETAIN section flag in the object, which prevents linker + -- gc-sections from working properly for LLVM backend (#26770). + -- @llvm.compiler.used serves a similar purpose that protects the + -- variable from being dropped by llc/opt, but it allows linker + -- gc-sections to work. See + -- https://llvm.org/docs/LangRef.html#the-llvm-compiler-used-global-variable ivars <- getUsedVars let cast x = LMBitc (LMStaticPointer (pVarLift x)) i8Ptr ty = LMArray (length ivars) i8Ptr usedArray = LMStaticArray (map cast ivars) ty sectName = Just $ fsLit "llvm.metadata" - lmUsedVar = LMGlobalVar (fsLit "llvm.used") ty Appending sectName Nothing Constant + lmUsedVar = LMGlobalVar (fsLit "llvm.compiler.used") ty Appending sectName Nothing Constant lmUsed = LMGlobal lmUsedVar (Just usedArray) if null ivars then return () ===================================== compiler/GHC/CmmToLlvm/Base.hs ===================================== @@ -286,7 +286,7 @@ data LlvmEnv = LlvmEnv , envUniqMeta :: UniqFM Unique MetaId -- ^ Global metadata nodes , envFunMap :: LlvmEnvMap -- ^ Global functions so far, with type , envAliases :: UniqSet LMString -- ^ Globals that we had to alias, see [Llvm Forward References] - , envUsedVars :: [LlvmVar] -- ^ Pointers to be added to llvm.used (see @cmmUsedLlvmGens@) + , envUsedVars :: [LlvmVar] -- ^ Pointers to be added to llvm.compiler.used (see @cmmUsedLlvmGens@) -- the following get cleared for every function (see @withClearVars@) , envVarMap :: LlvmEnvMap -- ^ Local variables so far, with type ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -934,6 +934,14 @@ llvmOptions llvm_config llvm_version dflags = [("-relocation-model=" ++ rmodel ,"-relocation-model=" ++ rmodel) | not (null rmodel)] + -- Both llc/opt need these flags for split sections + ++ [ ("--data-sections", "--data-sections") + | gopt Opt_SplitSections dflags + ] + ++ [ ("--function-sections", "--function-sections") + | gopt Opt_SplitSections dflags + ] + -- Additional llc flags ++ [("", "-mcpu=" ++ mcpu) | not (null mcpu) , not (any (isInfixOf "-mcpu") (getOpts dflags opt_lc)) ] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b18b2c42c32488ad6d3480a56a1fcd75... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b18b2c42c32488ad6d3480a56a1fcd75... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Marge Bot (@marge-bot)