07 Jan '26
Simon Peyton Jones pushed new branch wip/T26679-part1 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T26679-part1
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/spj-try-opt-coercion] 2 commits: Fix expression-equality for (Coercion co)
by Simon Peyton Jones (@simonpj) 07 Jan '26
by Simon Peyton Jones (@simonpj) 07 Jan '26
07 Jan '26
Simon Peyton Jones pushed to branch wip/spj-try-opt-coercion at Glasgow Haskell Compiler / GHC
Commits:
f4eea9ba by Simon Peyton Jones at 2026-01-07T11:40:17+00:00
Fix expression-equality for (Coercion co)
We were just saying "True" which is utterly wrong.
See Note [Equality for coercions] in GHC.Core.Map.Type
- - - - -
68e18fc9 by Simon Peyton Jones at 2026-01-07T11:41:27+00:00
Wibbles on coercion bindings
- - - - -
9 changed files:
- compiler/GHC/Core/Map/Expr.hs
- compiler/GHC/Core/Map/Type.hs
- compiler/GHC/Core/Opt/CSE.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Data/TrieMap.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Types/Id.hs
Changes:
=====================================
compiler/GHC/Core/Map/Expr.hs
=====================================
@@ -26,6 +26,7 @@ import GHC.Prelude
import GHC.Data.TrieMap
import GHC.Core.Map.Type
import GHC.Core
+import GHC.Core.Coercion( coercionRKind )
import GHC.Core.Type
import GHC.Types.Tickish
import GHC.Types.Var
@@ -150,13 +151,16 @@ instance Eq (DeBruijn CoreExpr) where
eqDeBruijnExpr :: DeBruijn CoreExpr -> DeBruijn CoreExpr -> Bool
eqDeBruijnExpr (D env1 e1) (D env2 e2) = go e1 e2 where
- go (Var v1) (Var v2) = eqDeBruijnVar (D env1 v1) (D env2 v2)
- go (Lit lit1) (Lit lit2) = lit1 == lit2
- go (Type t1) (Type t2) = eqDeBruijnType (D env1 t1) (D env2 t2)
- -- See Note [Alpha-equality for Coercion arguments]
- go (Coercion {}) (Coercion {}) = True
- go (Cast e1 co1) (Cast e2 co2) = D env1 co1 == D env2 co2 && go e1 e2
- go (App f1 a1) (App f2 a2) = go f1 f2 && go a1 a2
+ go (Var v1) (Var v2) = eqDeBruijnVar (D env1 v1) (D env2 v2)
+ go (Lit lit1) (Lit lit2) = lit1 == lit2
+ go (Type t1) (Type t2) = eqDeBruijnType (D env1 t1) (D env2 t2)
+ go (Coercion co1) (Coercion co2) = eqDeBruijnCoercion (D env1 co1) (D env2 co2)
+ go (Cast e1 co1) (Cast e2 co2) = go e1 e2 && eqDeBruijnType (D env1 (coercionRKind co1))
+ (D env2 (coercionRKind co2))
+ go (App f1 a1) (App f2 a2)
+ | isCoArg a1, isCoArg a2 = go f1 f2
+ | otherwise = go f1 f2 && go a1 a2
+ -- isCoArg: see Note [Coercions in expressions]
go (Tick n1 e1) (Tick n2 e2)
= eqDeBruijnTickish (D env1 n1) (D env2 n2)
&& go e1 e2
@@ -204,12 +208,17 @@ eqDeBruijnTickish (D env1 t1) (D env2 t2) = go t1 t2 where
eqCoreExpr :: CoreExpr -> CoreExpr -> Bool
eqCoreExpr e1 e2 = eqDeBruijnExpr (deBruijnize e1) (deBruijnize e2)
-{- Note [Alpha-equality for Coercion arguments]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The 'Coercion' constructor only appears in argument positions, and so, if the
-functions are equal, then the arguments must have equal types. Because the
-comparison for coercions (correctly) checks only their types, checking for
-alpha-equality of the coercions is redundant.
+{- Note [Coercions in expressions]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+When a coercion appears in an expression, we mainly use `eqDeBruijnCoercion`
+(see Note [Equality for coercions] in GHC.Core.Map.Type). But we can optimise
+ * Applications: f1 (CO: co1) = f2 (CO: co2)
+ If the two functions are equal their argument coercions must have equal
+ types, so no need to compare the coercions at all.
+
+ * Casts: e1 |> co1 = e2 |> co2
+ If e1 and e2 are equal, the coercionLKinds of the coercions are equal;
+ so we only need to compare the coercionRKinds
-}
{- Note [Alpha-equality for let-bindings]
=====================================
compiler/GHC/Core/Map/Type.hs
=====================================
@@ -20,6 +20,7 @@ module GHC.Core.Map.Type (
TypeMapG, CoercionMapG,
DeBruijn(..), deBruijnize, eqDeBruijnType, eqDeBruijnVar,
+ eqDeBruijnCoercion,
BndrMap, xtBndr, lkBndr,
VarMap, xtVar, lkVar, lkDFreeVar, xtDFreeVar,
@@ -78,9 +79,14 @@ import Control.Monad ( (>=>) )
************************************************************************
-}
--- We should really never care about the contents of a coercion. Instead,
--- just look up the coercion's type.
+{- Note [Equality for coercions]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+A coercion is a proof, and any one proof is as good as any other.
+So to compare coercions we just compare their types.
+-}
+
newtype CoercionMap a = CoercionMap (CoercionMapG a)
+ -- See [Equality for coercions]
-- TODO(22292): derive
instance Functor CoercionMap where
@@ -98,6 +104,9 @@ instance TrieMap CoercionMap where
type CoercionMapG = GenMap CoercionMapX
newtype CoercionMapX a = CoercionMapX (TypeMapX a)
+-- CoercionMapX key point: two coercions are considered equal if
+-- their coercionTypes are the same; so we just defer to TypeMap
+
-- TODO(22292): derive
instance Functor CoercionMapX where
@@ -113,11 +122,6 @@ instance TrieMap CoercionMapX where
filterTM f (CoercionMapX core_tm) = CoercionMapX (filterTM f core_tm)
mapMaybeTM f (CoercionMapX core_tm) = CoercionMapX (mapMaybeTM f core_tm)
-instance Eq (DeBruijn Coercion) where
- D env1 co1 == D env2 co2
- = D env1 (coercionType co1) ==
- D env2 (coercionType co2)
-
lkC :: DeBruijn Coercion -> CoercionMapX a -> Maybe a
lkC (D env co) (CoercionMapX core_tm) = lkT (D env $ coercionType co)
core_tm
@@ -126,6 +130,16 @@ xtC :: DeBruijn Coercion -> XT a -> CoercionMapX a -> CoercionMapX a
xtC (D env co) f (CoercionMapX m)
= CoercionMapX (xtT (D env $ coercionType co) f m)
+-- This equality instance is needed for the equality test in leaf compression;
+-- see GenMap and Note [Compressed TrieMap] in GHC.Data.TrieMap
+instance Eq (DeBruijn Coercion) where
+ (==) = eqDeBruijnCoercion
+
+eqDeBruijnCoercion :: DeBruijn Coercion -> DeBruijn Coercion -> Bool
+eqDeBruijnCoercion (D env1 co1) (D env2 co2)
+ = eqDeBruijnType (D env1 (coercionType co1)) (D env2 (coercionType co2))
+
+
{-
************************************************************************
* *
@@ -139,9 +153,7 @@ xtC (D env co) f (CoercionMapX m)
-- but it is strictly internal to this module. If you are including a 'TypeMap'
-- inside another 'TrieMap', this is the type you want. Note that this
-- lookup does not do a kind-check. Thus, all keys in this map must have
--- the same kind. Also note that this map respects the distinction between
--- @Type@ and @Constraint@, despite the fact that they are equivalent type
--- synonyms in Core.
+-- the same kind.
type TypeMapG = GenMap TypeMapX
-- | @TypeMapX a@ is the base map from @DeBruijn Type@ to @a@, but without the
@@ -191,9 +203,6 @@ instance TrieMap TypeMapX where
filterTM = filterT
mapMaybeTM = mpT
-instance Eq (DeBruijn Type) where
- (==) = eqDeBruijnType
-
-- | An equality relation between two 'Type's (known below as @t1 :: k2@
-- and @t2 :: k2@)
data TypeEquality = TNEQ -- ^ @t1 /= t2@
@@ -219,7 +228,7 @@ eqDeBruijnType env_t1@(D env1 t1) env_t2@(D env2 t2) =
liftEquality :: Bool -> TypeEquality
liftEquality False = TNEQ
- liftEquality _ = TEQ
+ liftEquality True = TEQ
hasCast :: TypeEquality -> TypeEquality
hasCast TEQ = TEQX
@@ -272,7 +281,7 @@ eqDeBruijnType env_t1@(D env1 t1) env_t2@(D env2 t2) =
go (D (extendCME env tv) ty) (D (extendCME env' tv') ty')
(CoercionTy {}, CoercionTy {})
-> TEQ
- _ -> TNEQ
+ _ -> TNEQ
-- These bangs make 'gos' strict in the CMEnv, which in turn
-- keeps the CMEnv unboxed across the go/gos mutual recursion
@@ -282,9 +291,6 @@ eqDeBruijnType env_t1@(D env1 t1) env_t2@(D env2 t2) =
gos e1 e2 tys1 tys2
gos _ _ _ _ = TNEQ
-instance Eq (DeBruijn Var) where
- (==) = eqDeBruijnVar
-
eqDeBruijnVar :: DeBruijn Var -> DeBruijn Var -> Bool
eqDeBruijnVar (D env1 v1) (D env2 v2) =
case (lookupCME env1 v1, lookupCME env2 v2) of
@@ -292,6 +298,14 @@ eqDeBruijnVar (D env1 v1) (D env2 v2) =
(Nothing, Nothing) -> v1 == v2
_ -> False
+-- This equality instance is needed for the equality test in leaf compression;
+-- see GenMap and Note [Compressed TrieMap] in GHC.Data.TrieMap
+instance Eq (DeBruijn Type) where
+ (==) = eqDeBruijnType
+
+instance Eq (DeBruijn Var) where
+ (==) = eqDeBruijnVar
+
instance {-# OVERLAPPING #-}
Outputable a => Outputable (TypeMapG a) where
ppr m = text "TypeMap elts" <+> ppr (foldTM (:) m [])
@@ -488,6 +502,7 @@ instance TrieMap LooseTypeMap where
filterTM f (LooseTypeMap m) = LooseTypeMap (filterTM f m)
mapMaybeTM f (LooseTypeMap m) = LooseTypeMap (mapMaybeTM f m)
+
{-
************************************************************************
* *
=====================================
compiler/GHC/Core/Opt/CSE.hs
=====================================
@@ -450,7 +450,7 @@ cse_bind toplevel env_rhs env_body (in_id, in_rhs) out_id
| otherwise
= (env_body', (out_id'', out_rhs))
where
- (env_body', out_id') = extendCSEnvWithBinding env_body in_id out_id out_rhs cse_done
+ (env_body', out_id') = extendCSEnvWithBinding env_body in_id out_id out_rhs cse_done
(cse_done, out_rhs) = try_for_cse env_rhs in_rhs
out_id'' | cse_done = zapStableUnfolding $
delayInlining toplevel out_id'
=====================================
compiler/GHC/Core/Opt/Simplify/Env.hs
=====================================
@@ -422,11 +422,12 @@ data SimplFloats
}
instance Outputable SimplFloats where
- ppr (SimplFloats { sfLetFloats = lf, sfJoinFloats = jf, sfInScope = is })
+ ppr (SimplFloats { sfLetFloats = lf, sfJoinFloats = jf, sfInScope = _is })
= text "SimplFloats"
<+> braces (vcat [ text "lets: " <+> ppr lf
, text "joins:" <+> ppr jf
- , text "in_scope:" <+> ppr is ])
+-- , text "in_scope:" <+> ppr _is
+ ])
emptyFloats :: SimplEnv -> SimplFloats
emptyFloats env
=====================================
compiler/GHC/Core/TyCo/Rep.hs
=====================================
@@ -2098,8 +2098,9 @@ coercionIsSmall :: Coercion -> Bool
-- This function is called inside `exprIsTrivial` so it needs to be
-- pretty efficient. It should return False quickly on a big coercion;
-- it should /not/ traverse the big coercion!
+-- The literal constant 40# is pretty arbitrary
coercionIsSmall co
- = not (isTrue# ((coercion_is_small co 100#) <# 0#))
+ = not (isTrue# ((coercion_is_small co 40#) <# 0#))
coercion_is_small :: Coercion -> Int# -> Int#
coercion_is_small co n = go co n
=====================================
compiler/GHC/Data/TrieMap.hs
=====================================
@@ -359,7 +359,6 @@ mpList f (LM { lm_nil = mnil, lm_cons = mcons })
Note [Compressed TrieMap]
~~~~~~~~~~~~~~~~~~~~~~~~~
-
The GenMap constructor augments TrieMaps with leaf compression. This helps
solve the performance problem detailed in #9960: suppose we have a handful
H of entries in a TrieMap, each with a very large key, size K. If you fold over
=====================================
compiler/GHC/Iface/Make.hs
=====================================
@@ -199,7 +199,11 @@ updateDecl decls m_stg_infos m_cmm_infos
m_cmm_infos
tag_sigs = fromMaybe mempty m_stg_infos
- update_decl (IfaceId nm ty details infos)
+ update_decl decl@(IfaceId nm ty details infos)
+ | IfCoVarId <- details
+ = decl -- Coercions can appear at top level in interface files
+ -- but we generate no code for them and they have no LFInfo
+
| let not_caffy = elemNameSet nm non_cafs
, let mb_lf_info = lookupNameEnv lf_infos nm
, let sig = lookupNameEnv tag_sigs nm
=====================================
compiler/GHC/IfaceToCore.hs
=====================================
@@ -1698,12 +1698,21 @@ tcIfaceExpr (IfaceCase scrut case_bndr alts) = do
return (Case scrut' case_bndr' (coreAltsType alts') alts')
tcIfaceExpr (IfaceLet (IfaceNonRec (IfLetBndr fs ty info ji) rhs) body)
+ | IfaceCo co <- rhs
+ = -- For CoVars we ignore `info` and `ji`
+ do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs))
+ ; ty' <- tcIfaceType ty
+ ; let covar = mkLocalCoVar name ty'
+ ; co' <- tcIfaceCo co
+ ; body' <- extendIfaceIdEnv [covar] (tcIfaceExpr body)
+ ; return (Let (NonRec covar (Coercion co')) body') }
+ | otherwise
= do { name <- newIfaceName (mkVarOccFS (ifLclNameFS fs))
; ty' <- tcIfaceType ty
; id_info <- tcIdInfo False {- Don't ignore prags; we are inside one! -}
NotTopLevel name ty' info
; let id = mkLocalIdWithInfo name ManyTy ty' id_info
- `asJoinId_maybe` ji
+ `asJoinId_maybe` ji
; rhs' <- tcIfaceExpr rhs
; body' <- extendIfaceIdEnv [id] (tcIfaceExpr body)
; return (Let (NonRec id rhs') body') }
=====================================
compiler/GHC/Types/Id.hs
=====================================
@@ -329,8 +329,8 @@ mkLocalIdOrCoVar name w ty
| isCoVarType ty = mkLocalCoVar name ty
| otherwise = mkLocalId name w ty
- -- proper ids only; no covars!
mkLocalIdWithInfo :: HasDebugCallStack => Name -> Mult -> Type -> IdInfo -> Id
+-- Used for proper ids only; no covars!
mkLocalIdWithInfo name w ty info =
Var.mkLocalVar VanillaId name w (assert (not (isCoVarType ty)) ty) info
-- Note [Free type variables]
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/528c804fa394c2b7eb421078f95373…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/528c804fa394c2b7eb421078f95373…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26724] 14 commits: Improved fundeps for closed type families
by Simon Peyton Jones (@simonpj) 07 Jan '26
by Simon Peyton Jones (@simonpj) 07 Jan '26
07 Jan '26
Simon Peyton Jones pushed to branch wip/T26724 at Glasgow Haskell Compiler / GHC
Commits:
0b7df6db by Simon Peyton Jones at 2026-01-06T09:32:23-05:00
Improved fundeps for closed type families
The big payload of this commit is to execute the plan suggested
in #23162, by improving the way that we generate functional
dependencies for closed type families.
It is all described in Note [Exploiting closed type families]
Most of the changes are in GHC.Tc.Solver.FunDeps
Other small changes
* GHC.Tc.Solver.bumpReductionDepth. This function brings together the code that
* Bumps the depth
* Checks for overflow
Previously the two were separated, sometimes quite widely.
* GHC.Core.Unify.niFixSubst: minor improvement, removing an unnecessary
itraetion in the base case.
* GHC.Core.Unify: no need to pass an InScopeSet to
tcUnifyTysForInjectivity. It can calculate one for itself; and it is
never inspected anyway so it's free to do so.
* GHC.Tc.Errors.Ppr: slight impovement to the error message for
reduction-stack overflow, when a constraint (rather than a type) is
involved.
* GHC.Tc.Solver.Monad.wrapUnifier: small change to the API
- - - - -
fde8bd88 by Simon Peyton Jones at 2026-01-06T09:32:23-05:00
Add missing (KK4) to kick-out criteria
There was a missing case in kick-out that meant we could fail
to solve an eminently-solvable constraint.
See the new notes about (KK4)
- - - - -
00082844 by Simon Peyton Jones at 2026-01-06T09:32:23-05:00
Some small refactorings of error reporting in the typechecker
This is just a tidy-up commit.
* Add ei_insoluble to ErrorItem, to cache insolubility.
Small tidy-up.
* Remove `is_ip` and `mkIPErr` from GHC.Tc.Errors; instead enhance mkDictErr
to handle implicit parameters. Small refactor.
- - - - -
fe4cb252 by Simon Peyton Jones at 2026-01-06T09:32:24-05:00
Improve recording of insolubility for fundeps
This commit addresses #22652, by recording when the fundeps for
a constraint are definitely insoluble. That in turn improves the
perspicacity of the pattern-match overlap checker.
See Note [Insoluble fundeps]
- - - - -
df0ffaa5 by Simon Peyton Jones at 2026-01-06T09:32:24-05:00
Fix a buglet in niFixSubst
The MR of which this is part failed an assertion check extendTvSubst
because we extended the TvSubst with a CoVar. Boo.
This tiny patch fixes it, and adds the regression test from #13882
that showed it up.
- - - - -
3d6aba77 by konsumlamm at 2026-01-06T09:33:16-05:00
Fix changelog formatting
- - - - -
69e0ab59 by Cheng Shao at 2026-01-06T19:37:56-05:00
compiler: add targetHasRTSWays function
This commit adds a `targetHasRTSWays` util function in
`GHC.Driver.Session` to query if the target RTS has a given Ways (e.g.
WayThreaded).
- - - - -
25a0ab94 by Cheng Shao at 2026-01-06T19:37:56-05:00
compiler: link on-demand external interpreter with threaded RTS
This commit makes the compiler link the on-demand external interpreter
program with threaded RTS if it is available in the target RTS ways.
This is a better default than the previous single-threaded RTS, and it
enables the external interpreter to benefit from parallelism when
deserializing CreateBCOs messages.
- - - - -
92404a2b by Cheng Shao at 2026-01-06T19:37:56-05:00
hadrian: link iserv with threaded RTS
This commit makes hadrian link iserv with threaded RTS if it's
available in the RTS ways. Also cleans up the iserv main C program
which can be replaced by the `-fkeep-cafs` link-time option.
- - - - -
a20542d2 by Cheng Shao at 2026-01-06T19:38:38-05:00
ghc-internal: remove unused GMP macros
This patch removes unused GMP related macros from `ghc-internal`. The
in-tree GMP version was hard coded and outdated, but it was not used
anywhere anyway.
- - - - -
4079dcd6 by Cheng Shao at 2026-01-06T19:38:38-05:00
hadrian: fix in-tree gmp configure error on newer c compilers
Building in-tree gmp on newer c compilers that default to c23 fails at
configure stage, this patch fixes it, see added comment for
explanation.
- - - - -
414d1fe1 by Cheng Shao at 2026-01-06T19:39:20-05:00
compiler: fix LLVM backend pdep/pext handling for i386 target
This patch fixes LLVM backend's pdep/pext handling for i386 target,
and also removes non-existent 128/256/512 bit hs_pdep/hs_pext callees.
See amended note for more explanation. Fixes #26450.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
c7f6fba3 by Cheng Shao at 2026-01-06T19:39:20-05:00
ci: remove allow_failure flag for i386 alpine job
The LLVM codegen issue for i386 has been fixed, and the i386 alpine
job should pass now. This commit removes the allow_failure flag so
that other i386 regressions in the future are signaled more timely.
- - - - -
edf9ed5f by Simon Peyton Jones at 2026-01-07T09:35:26+00:00
Try harder to keep the substitution empty
Avoid unnecessary cloning of varaibles in the Simplifier.
Addresses #26724,
See Note [Keeping the substitution empty]
- - - - -
85 changed files:
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/GHC.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Core/FamInstEnv.hs
- compiler/GHC/Core/Subst.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/Runtime/Interpreter/C.hs
- compiler/GHC/Runtime/Interpreter/Init.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Rewrite.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/CtLoc.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Types/TyThing.hs
- docs/users_guide/9.16.1-notes.rst
- hadrian/src/Packages.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Settings/Packages.hs
- libraries/base/changelog.md
- libraries/ghc-internal/configure.ac
- libraries/ghc-internal/include/HsIntegerGmp.h.in
- linters/lint-codes/LintCodes/Static.hs
- testsuite/tests/indexed-types/should_compile/CEqCanOccursCheck.hs
- testsuite/tests/indexed-types/should_fail/T12522a.hs
- testsuite/tests/indexed-types/should_fail/T26176.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail10.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail13.stderr
- testsuite/tests/parser/should_fail/T20654a.stderr
- testsuite/tests/pmcheck/should_compile/T15753c.hs
- + testsuite/tests/pmcheck/should_compile/T15753c.stderr
- testsuite/tests/pmcheck/should_compile/T15753d.hs
- + testsuite/tests/pmcheck/should_compile/T15753d.stderr
- + testsuite/tests/pmcheck/should_compile/T22652.hs
- + testsuite/tests/pmcheck/should_compile/T22652a.hs
- testsuite/tests/pmcheck/should_compile/all.T
- + testsuite/tests/polykinds/T13882.hs
- testsuite/tests/polykinds/all.T
- testsuite/tests/quantified-constraints/T15316A.stderr
- testsuite/tests/quantified-constraints/T17267.stderr
- testsuite/tests/quantified-constraints/T17267a.stderr
- testsuite/tests/quantified-constraints/T17267b.stderr
- testsuite/tests/quantified-constraints/T17267c.stderr
- testsuite/tests/quantified-constraints/T17267e.stderr
- testsuite/tests/quantified-constraints/T17458.stderr
- testsuite/tests/typecheck/should_compile/T16188.hs
- testsuite/tests/typecheck/should_fail/ContextStack1.stderr
- testsuite/tests/typecheck/should_fail/FD3.stderr
- testsuite/tests/typecheck/should_fail/FDsFromGivens2.stderr
- testsuite/tests/typecheck/should_fail/FunDepOrigin1b.stderr
- testsuite/tests/typecheck/should_fail/T13506.stderr
- testsuite/tests/typecheck/should_fail/T15767.stderr
- testsuite/tests/typecheck/should_fail/T19415.stderr
- testsuite/tests/typecheck/should_fail/T19415b.stderr
- testsuite/tests/typecheck/should_fail/T22924b.stderr
- + testsuite/tests/typecheck/should_fail/T23162b.hs
- + testsuite/tests/typecheck/should_fail/T23162b.stderr
- + testsuite/tests/typecheck/should_fail/T23162c.hs
- + testsuite/tests/typecheck/should_fail/T23162d.hs
- testsuite/tests/typecheck/should_fail/T25325.stderr
- testsuite/tests/typecheck/should_fail/T5236.stderr
- testsuite/tests/typecheck/should_fail/T5246.stderr
- testsuite/tests/typecheck/should_fail/T5978.stderr
- testsuite/tests/typecheck/should_fail/T9612.stderr
- testsuite/tests/typecheck/should_fail/TcCoercibleFail.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_fail/tcfail143.stderr
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- − utils/iserv/cbits/iservmain.c
- utils/iserv/iserv.cabal.in
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e4cb149447bfdcab7d5cfaa0d8f806…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e4cb149447bfdcab7d5cfaa0d8f806…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: Add missing InVar->OutVar lookup in SetLevels
by Marge Bot (@marge-bot) 07 Jan '26
by Marge Bot (@marge-bot) 07 Jan '26
07 Jan '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
5c6bc060 by Simon Peyton Jones at 2026-01-07T00:22:53-05:00
Add missing InVar->OutVar lookup in SetLevels
As #26681 showed, the SetLevels pass was failing to map an InVar to
an OutVar. Very silly! I'm amazed it hasn't broken before now.
I have improved the type singatures (to mention InVar and OutVar)
so it's more obvious what needs to happen.
- - - - -
0c744eed by Cheng Shao at 2026-01-07T00:22:54-05:00
hadrian: drop deprecated pkgHashSplitObjs code path
This patch drops deprecated `pkgHashSplitObjs` code path from hadrian,
since GHC itself has removed split objs support many versions ago and
this code path is unused.
- - - - -
5a37aec8 by Cheng Shao at 2026-01-07T00:22:55-05:00
hadrian: remove linting/assertion in quick-validate flavour
The `quick-validate` flavour is meant for testing ghc and passing the
testsuite locally with similar settings to `validate` but faster. This
patch removes the linting/assertion overhead in `quick-validate` to
improve developer experience. I also took the chance to simplify
redundant logic of rts/library way definition in `validate` flavour.
- - - - -
776bf043 by Cheng Shao at 2026-01-07T00:22:56-05:00
deriveConstants: clean up unused constants
This patch cleans up unused constants from `deriveConstants`, they are
not used by C/Cmm code in the RTS, nor compiler-generated code.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
cf6e7993 by Cheng Shao at 2026-01-07T00:22:58-05:00
hadrian: pass -fno-omit-frame-pointer with +debug_info
This patch adds `-fno-omit-frame-pointer` as C/C++ compilation flag
when compiling with `+debug_info` flavour transformer. It's a sane
default when you care about debugging and reliable backtraces, and
makes debugging/profiling with bpf easier.
- - - - -
4fe96991 by Aaron Allen at 2026-01-07T00:23:07-05:00
[26705] Include TyCl instances in data fam iface entry
Ensures dependent modules are recompiled when the class instances for a
data family instance change.
resolves #26705
- - - - -
bb6e6cc8 by Cheng Shao at 2026-01-07T00:23:08-05:00
hadrian: remove unused Hp2Ps/Hpc builders
This patch removes the Hp2Ps/Hpc builders from hadrian, they are
unused in the build system. Note that the hp2ps/hpc programs are still
built and not affected.
- - - - -
31d109e6 by Cheng Shao at 2026-01-07T00:23:08-05:00
hadrian: only install js files to libdir for wasm/js targets
There are certain js files required for wasm/js targets to work, and
previously hadrian would install those js files to libdir
unconditionally on other targets as well. This could be a minor
annoyance for packagers especially when the unused js files contain
shebangs that interfere with the packaging process. This patch makes
hadrian only selectively install the right js files for the right
targets.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
0cf59582 by Simon Peyton Jones at 2026-01-07T00:23:09-05:00
Add flavour transformer assertions_stage1
This allows us to enable -DDEBUG assertions in the stage1 compiler
- - - - -
19 changed files:
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Iface/Recomp.hs
- hadrian/doc/flavours.md
- hadrian/src/Base.hs
- hadrian/src/Builder.hs
- hadrian/src/Flavour.hs
- hadrian/src/Hadrian/Haskell/Hash.hs
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Rules/Register.hs
- hadrian/src/Settings/Flavours/Validate.hs
- + testsuite/tests/driver/recomp26705/M.hs
- + testsuite/tests/driver/recomp26705/M2A.hs
- + testsuite/tests/driver/recomp26705/M2B.hs
- + testsuite/tests/driver/recomp26705/Makefile
- + testsuite/tests/driver/recomp26705/all.T
- + testsuite/tests/driver/recomp26705/recomp26705.stderr
- + testsuite/tests/simplCore/should_compile/T26681.hs
- testsuite/tests/simplCore/should_compile/all.T
- utils/deriveConstants/Main.hs
Changes:
=====================================
compiler/GHC/Core/Opt/SetLevels.hs
=====================================
@@ -91,6 +91,7 @@ import GHC.Core.Utils
import GHC.Core.Opt.Arity ( exprBotStrictness_maybe, isOneShotBndr )
import GHC.Core.FVs -- all of it
import GHC.Core.Subst
+import GHC.Core.TyCo.Subst( lookupTyVar )
import GHC.Core.Make ( sortQuantVars )
import GHC.Core.Type ( Type, tyCoVarsOfType
, mightBeUnliftedType, closeOverKindsDSet
@@ -466,8 +467,8 @@ lvlCase env scrut_fvs scrut' case_bndr ty alts
ty' = substTyUnchecked (le_subst env) ty
incd_lvl = incMinorLvl (le_ctxt_lvl env)
- dest_lvl = maxFvLevel (const True) env scrut_fvs
- -- Don't abstract over type variables, hence const True
+ dest_lvl = maxFvLevel includeTyVars env scrut_fvs
+ -- Don't abstract over type variables, hence includeTyVars
lvl_alt alts_env (AnnAlt con bs rhs)
= do { rhs' <- lvlMFE new_env True rhs
@@ -719,8 +720,11 @@ hasFreeJoin :: LevelEnv -> DVarSet -> Bool
-- (In the latter case it won't be a join point any more.)
-- Not treating top-level ones specially had a massive effect
-- on nofib/minimax/Prog.prog
-hasFreeJoin env fvs
- = not (maxFvLevel isJoinId env fvs == tOP_LEVEL)
+hasFreeJoin env fvs = anyDVarSet bad_join fvs
+ where
+ bad_join v = isJoinId v &&
+ maxIn True env v tOP_LEVEL /= tOP_LEVEL
+
{- Note [Saving work]
~~~~~~~~~~~~~~~~~~~~~
@@ -1607,10 +1611,10 @@ destLevel env fvs fvs_ty is_function is_bot
| otherwise = max_fv_id_level
where
- max_fv_id_level = maxFvLevel isId env fvs -- Max over Ids only; the
- -- tyvars will be abstracted
+ max_fv_id_level = maxFvLevel idsOnly env fvs -- Max over Ids only; the
+ -- tyvars will be abstracted
- as_far_as_poss = maxFvLevel' isId env fvs_ty
+ as_far_as_poss = maxFvLevel' idsOnly env fvs_ty
-- See Note [Floating and kind casts]
{- Note [Floating and kind casts]
@@ -1768,28 +1772,47 @@ extendCaseBndrEnv le@(LE { le_subst = subst, le_env = id_env })
, le_env = add_id id_env (case_bndr, scrut_var) }
extendCaseBndrEnv env _ _ = env
-maxFvLevel :: (Var -> Bool) -> LevelEnv -> DVarSet -> Level
-maxFvLevel max_me env var_set
- = nonDetStrictFoldDVarSet (maxIn max_me env) tOP_LEVEL var_set
+includeTyVars, idsOnly :: Bool
+idsOnly = False
+includeTyVars = True
+
+maxFvLevel :: Bool -> LevelEnv -> DVarSet -> Level
+maxFvLevel include_tyvars env var_set
+ = nonDetStrictFoldDVarSet (maxIn include_tyvars env) tOP_LEVEL var_set
-- It's OK to use a non-deterministic fold here because maxIn commutes.
-maxFvLevel' :: (Var -> Bool) -> LevelEnv -> TyCoVarSet -> Level
+maxFvLevel' :: Bool -> LevelEnv -> TyCoVarSet -> Level
-- Same but for TyCoVarSet
-maxFvLevel' max_me env var_set
- = nonDetStrictFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set
+maxFvLevel' include_tyvars env var_set
+ = nonDetStrictFoldUniqSet (maxIn include_tyvars env) tOP_LEVEL var_set
-- It's OK to use a non-deterministic fold here because maxIn commutes.
-maxIn :: (Var -> Bool) -> LevelEnv -> InVar -> Level -> Level
-maxIn max_me (LE { le_lvl_env = lvl_env, le_env = id_env }) in_var lvl
+maxIn :: Bool -> LevelEnv -> InVar -> Level -> Level
+-- True <=> include tyvars
+maxIn include_tyvars env@(LE { le_subst = subst, le_env = id_env }) in_var lvl
+ | isId in_var
= case lookupVarEnv id_env in_var of
+ Nothing -> maxOut env in_var lvl
Just (abs_vars, _) -> foldr max_out lvl abs_vars
- Nothing -> max_out in_var lvl
- where
- max_out out_var lvl
- | max_me out_var = case lookupVarEnv lvl_env out_var of
- Just lvl' -> maxLvl lvl' lvl
- Nothing -> lvl
- | otherwise = lvl -- Ignore some vars depending on max_me
+ where
+ max_out out_var lvl
+ | isTyVar out_var && not include_tyvars
+ = lvl
+ | otherwise = maxOut env out_var lvl
+
+ | include_tyvars -- TyVars
+ = case lookupTyVar subst in_var of
+ Just ty -> nonDetStrictFoldVarSet (maxOut env) lvl (tyCoVarsOfType ty)
+ Nothing -> maxOut env in_var lvl
+
+ | otherwise -- Ignore free tyvars
+ = lvl
+
+maxOut :: LevelEnv -> OutVar -> Level -> Level
+maxOut (LE { le_lvl_env = lvl_env }) out_var lvl
+ = case lookupVarEnv lvl_env out_var of
+ Just lvl' -> maxLvl lvl' lvl
+ Nothing -> lvl
lookupVar :: LevelEnv -> Id -> LevelledExpr
lookupVar le v = case lookupVarEnv (le_env le) v of
=====================================
compiler/GHC/Iface/Recomp.hs
=====================================
@@ -1797,7 +1797,9 @@ declExtras fix_fn ann_fn rule_env inst_env fi_env dm_env complete_env decl
IfaceSynonym{} -> IfaceSynonymExtras (fix_fn n)
(ann_fn (AnnOccName n))
IfaceFamily{} -> IfaceFamilyExtras (fix_fn n)
- (map ifFamInstAxiom (lookupOccEnvL fi_env n))
+ (map ifFamInstAxiom (lookupOccEnvL fi_env n)
+ ++ map ifDFun (lookupOccEnvL inst_env n)
+ )
(ann_fn (AnnOccName n))
IfacePatSyn{} -> IfacePatSynExtras (fix_fn n) (lookup_complete_match n)
_other -> IfaceOtherDeclExtras
=====================================
hadrian/doc/flavours.md
=====================================
@@ -297,7 +297,11 @@ The supported transformers are listed below:
</tr>
<tr>
<td><code>assertions</code></td>
- <td>Build the stage2 compiler with assertions enabled. </td>
+ <td>Build the stage2 compiler with <code>-DDEBUG</code> assertions enabled. </td>
+ </tr>
+ <tr>
+ <td><code>assertions_stage1</code></td>
+ <td>Build the stage1 compiler with <code>-DDEBUG</code> assertions enabled. </td>
</tr>
<tr>
<td><code>fully_static</code></td>
=====================================
hadrian/src/Base.hs
=====================================
@@ -149,14 +149,10 @@ ghcLibDeps stage iplace = do
ps <- mapM (\f -> stageLibPath stage <&> (-/- f))
[ "llvm-targets"
, "llvm-passes"
- , "ghc-interp.js"
, "settings"
, "targets" -/- "default.target"
, "ghc-usage.txt"
, "ghci-usage.txt"
- , "dyld.mjs"
- , "post-link.mjs"
- , "prelude.mjs"
]
cxxStdLib <- systemCxxStdLibConfPath (PackageDbLoc stage iplace)
return (cxxStdLib : ps)
=====================================
hadrian/src/Builder.hs
=====================================
@@ -170,8 +170,6 @@ data Builder = Alex
| GhcPkg GhcPkgMode Stage
| Haddock HaddockMode
| Happy
- | Hp2Ps
- | Hpc
| HsCpp
| JsCpp
| Hsc2Hs Stage
@@ -211,10 +209,6 @@ builderProvenance = \case
Haddock _ -> context Stage1 haddock
Hsc2Hs _ -> context stage0Boot hsc2hs
Unlit -> context stage0Boot unlit
-
- -- Never used
- Hpc -> context Stage1 hpcBin
- Hp2Ps -> context stage0Boot hp2ps
_ -> Nothing
where
context s p = Just $ vanillaContext s p
=====================================
hadrian/src/Flavour.hs
=====================================
@@ -70,7 +70,8 @@ flavourTransformers = M.fromList
, "fully_static" =: fullyStatic
, "host_fully_static" =: hostFullyStatic
, "collect_timings" =: collectTimings
- , "assertions" =: enableAssertions
+ , "assertions" =: enableAssertions Stage2
+ , "assertions_stage1" =: enableAssertions Stage1
, "debug_ghc" =: debugGhc Stage2
, "debug_stage1_ghc" =: debugGhc Stage1
, "lint" =: enableLinting
@@ -169,10 +170,10 @@ werror =
-- | Build C and Haskell objects with debugging information.
enableDebugInfo :: Flavour -> Flavour
enableDebugInfo = addArgs $ notStage0 ? mconcat
- [ builder (Ghc CompileHs) ? pure ["-g3"]
- , builder (Ghc CompileCWithGhc) ? pure ["-optc-g3"]
- , builder (Ghc CompileCppWithGhc) ? pure ["-optcxx-g3"]
- , builder (Cc CompileC) ? arg "-g3"
+ [ builder (Ghc CompileHs) ? pure ["-g3", "-optc-fno-omit-frame-pointer"]
+ , builder (Ghc CompileCWithGhc) ? pure ["-optc-g3", "-optc-fno-omit-frame-pointer"]
+ , builder (Ghc CompileCppWithGhc) ? pure ["-optcxx-g3", "-optcxx-fno-omit-frame-pointer"]
+ , builder (Cc CompileC) ? pure ["-g3", "-fno-omit-frame-pointer"]
, builder (Cabal Setup) ? arg "--disable-library-stripping"
, builder (Cabal Setup) ? arg "--disable-executable-stripping"
]
@@ -393,12 +394,12 @@ enableLateCCS = addArgs
? ((Profiling `wayUnit`) <$> getWay)
? arg "-fprof-late"
--- | Enable assertions for the stage2 compiler
-enableAssertions :: Flavour -> Flavour
-enableAssertions flav = flav { ghcDebugAssertions = f }
+-- | Enable -DDEBUG assertions in the compiler, at a specified stage
+enableAssertions :: Stage -> Flavour -> Flavour
+enableAssertions stage flav = flav { ghcDebugAssertions = f }
where
- f Stage2 = True
- f st = ghcDebugAssertions flav st
+ f s | s == stage = True
+ | otherwise = ghcDebugAssertions flav s
-- | Build the stage3 compiler using the non-moving GC.
enableBootNonmovingGc :: Flavour -> Flavour
=====================================
hadrian/src/Hadrian/Haskell/Hash.hs
=====================================
@@ -84,7 +84,6 @@ data PackageHashConfigInputs = PackageHashConfigInputs {
pkgHashDynExe :: Bool,
pkgHashProfLib :: Bool,
pkgHashProfExe :: Bool,
- pkgHashSplitObjs :: Bool,
pkgHashSplitSections :: Bool,
pkgHashStripLibs :: Bool,
pkgHashStripExes :: Bool,
@@ -140,7 +139,6 @@ pkgHashOracle = void $ addOracleCache $ \(PkgHashKey (stag, pkg)) -> do
pkgHashDynExe = dyn_ghc
pkgHashProfLib = profiling `Set.member` libWays
pkgHashProfExe = pkg == ghc && ghcProfiled flav stag
- pkgHashSplitObjs = False -- Deprecated
pkgHashSplitSections = ghcSplitSections flav
pkgHashStripExes = False
pkgHashStripLibs = False
@@ -239,7 +237,6 @@ renderPackageHashInputs PackageHashInputs{
, opt "dynamic-exe" False show pkgHashDynExe
, opt "prof-lib" False show pkgHashProfLib
, opt "prof-exe" False show pkgHashProfExe
- , opt "split-objs" False show pkgHashSplitObjs
, opt "split-sections" False show pkgHashSplitSections
, opt "stripped-lib" False show pkgHashStripLibs
, opt "stripped-exe" True show pkgHashStripExes
=====================================
hadrian/src/Oracles/Setting.hs
=====================================
@@ -9,7 +9,7 @@ module Oracles.Setting (
-- ** Target platform things
anyTargetOs, anyTargetArch, anyHostOs,
- isElfTarget, isOsxTarget, isWinTarget, isJsTarget, isArmTarget,
+ isElfTarget, isOsxTarget, isWinTarget, isJsTarget, isWasmTarget, isArmTarget,
isWinHost,
targetArmVersion
) where
@@ -128,6 +128,9 @@ isWinTarget = anyTargetOs [OSMinGW32]
isJsTarget :: Action Bool
isJsTarget = anyTargetArch [ArchJavaScript]
+isWasmTarget :: Action Bool
+isWasmTarget = anyTargetArch [ArchWasm32]
+
isOsxTarget :: Action Bool
isOsxTarget = anyTargetOs [OSDarwin]
=====================================
hadrian/src/Rules/Register.hs
=====================================
@@ -118,7 +118,18 @@ registerPackageRules rs stage iplace = do
pkgName <- getPackageNameFromConfFile conf
let pkg = unsafeFindPackageByName pkgName
- when (pkg == compiler) $ need =<< ghcLibDeps stage iplace
+ when (pkg == compiler) $ do
+ baseDeps <- ghcLibDeps stage iplace
+ jsTarget <- isJsTarget
+ wasmTarget <- isWasmTarget
+ libPath <- stageLibPath stage
+ let jsDeps
+ | jsTarget = ["ghc-interp.js"]
+ | otherwise = []
+ wasmDeps
+ | wasmTarget = ["dyld.mjs", "post-link.mjs", "prelude.mjs"]
+ | otherwise = []
+ need (baseDeps ++ map (libPath -/-) (jsDeps ++ wasmDeps))
-- Only used in guard when Stage0 {} but can be GlobalLibs or InTreeLibs
isBoot <- (pkg `notElem`) <$> stagePackages stage
=====================================
hadrian/src/Settings/Flavours/Validate.hs
=====================================
@@ -1,31 +1,16 @@
module Settings.Flavours.Validate (validateFlavour, slowValidateFlavour,
quickValidateFlavour) where
-import qualified Data.Set as Set
import Expression
import Flavour
-import Oracles.Flag
import {-# SOURCE #-} Settings.Default
-- Please update doc/flavours.md when changing this file.
validateFlavour :: Flavour
-validateFlavour = enableLinting $ werror $ defaultFlavour
+validateFlavour = enableLinting $ quickValidateFlavour
{ name = "validate"
, extraArgs = validateArgs <> defaultHaddockExtraArgs
- , libraryWays = Set.fromList <$>
- mconcat [ pure [vanilla]
- , notStage0 ? platformSupportsSharedLibs ? pure [dynamic]
- ]
- , rtsWays = Set.fromList <$>
- mconcat [ pure [vanilla, debug]
- , targetSupportsThreadedRts ? pure [threaded, threadedDebug]
- , notStage0 ? platformSupportsSharedLibs ? pure
- [ dynamic, debugDynamic
- ]
- , notStage0 ? platformSupportsSharedLibs ? targetSupportsThreadedRts ? pure
- [ threadedDynamic, threadedDebugDynamic ]
- ]
, ghcDebugAssertions = (<= Stage1)
}
@@ -59,6 +44,6 @@ quickValidateArgs = sourceArgs SourceArgs
}
quickValidateFlavour :: Flavour
-quickValidateFlavour = werror $ validateFlavour
+quickValidateFlavour = werror $ disableProfiledLibs $ defaultFlavour
{ name = "quick-validate"
, extraArgs = quickValidateArgs }
=====================================
testsuite/tests/driver/recomp26705/M.hs
=====================================
@@ -0,0 +1,5 @@
+module M where
+import M2
+
+x :: TD () -> String
+x = show
=====================================
testsuite/tests/driver/recomp26705/M2A.hs
=====================================
@@ -0,0 +1,7 @@
+{-# LANGUAGE TypeFamilies #-}
+module M2 where
+
+data family TD a
+
+data instance TD () = TDI
+ deriving Show
=====================================
testsuite/tests/driver/recomp26705/M2B.hs
=====================================
@@ -0,0 +1,6 @@
+{-# LANGUAGE TypeFamilies #-}
+module M2 where
+
+data family TD a
+
+data instance TD () = TDI
=====================================
testsuite/tests/driver/recomp26705/Makefile
=====================================
@@ -0,0 +1,13 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+# Recompilation tests
+
+recomp26705:
+ cp M2A.hs M2.hs
+ '$(TEST_HC)' $(TEST_HC_OPTS) --make M.hs
+ sleep 1
+ cp M2B.hs M2.hs
+ # This should fail
+ if '$(TEST_HC)' $(TEST_HC_OPTS) --make M.hs; then false; fi
=====================================
testsuite/tests/driver/recomp26705/all.T
=====================================
@@ -0,0 +1,3 @@
+test('recomp26705', [extra_files(['M2A.hs', 'M.hs', 'M2B.hs']),
+ when(fast(), skip), ignore_stdout],
+ makefile_test, [])
=====================================
testsuite/tests/driver/recomp26705/recomp26705.stderr
=====================================
@@ -0,0 +1,5 @@
+M.hs:5:5: error: [GHC-39999]
+ • No instance for ‘Show (TD ())’ arising from a use of ‘show’
+ • In the expression: show
+ In an equation for ‘x’: x = show
+
=====================================
testsuite/tests/simplCore/should_compile/T26681.hs
=====================================
@@ -0,0 +1,47 @@
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE StandaloneKindSignatures #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+
+module T26681 where
+
+import Data.Kind (Type)
+import Data.Type.Equality
+import GHC.TypeLits
+import qualified Unsafe.Coerce
+
+
+{-# NOINLINE unsafeCoerceRefl #-}
+unsafeCoerceRefl :: a :~: b
+unsafeCoerceRefl = Unsafe.Coerce.unsafeCoerce Refl
+
+type family MapJust l where
+ MapJust '[] = '[]
+ MapJust (x : xs) = Just x : MapJust xs
+
+type family Tail l where
+ Tail (_ : xs) = xs
+
+lemMapJustCons :: MapJust sh :~: Just n : sh' -> sh :~: n : Tail sh
+lemMapJustCons Refl = unsafeCoerceRefl
+
+
+type ListX :: [Maybe Nat] -> (Maybe Nat -> Type) -> Type
+data ListX sh f where
+ ConsX :: !(f n) -> ListX (n : sh) f
+
+
+data JustN n where
+ JustN :: JustN (Just n)
+
+data UnconsListSRes f sh1 = forall n sh. (n : sh ~ sh1) => UnconsListSRes
+
+listsUncons :: forall sh1 f. ListX (MapJust sh1) JustN -> UnconsListSRes f sh1
+listsUncons (ConsX JustN)
+ | Refl <- lemMapJustCons @sh1 Refl
+ = UnconsListSRes
=====================================
testsuite/tests/simplCore/should_compile/all.T
=====================================
@@ -563,3 +563,4 @@ test('T26115', [grep_errmsg(r'DFun')], compile, ['-O -ddump-simpl -dsuppress-uni
test('T26116', normal, compile, ['-O -ddump-rules'])
test('T26117', [grep_errmsg(r'==')], compile, ['-O -ddump-simpl -dsuppress-uniques'])
test('T26349', normal, compile, ['-O -ddump-rules'])
+test('T26681', normal, compile, ['-O'])
=====================================
utils/deriveConstants/Main.hs
=====================================
@@ -397,7 +397,6 @@ wanteds os = concat
,fieldOffset Both "StgRegTable" "rHpAlloc"
,structField C "StgRegTable" "rCurrentAlloc"
,structField C "StgRegTable" "rRet"
- ,structField C "StgRegTable" "rNursery"
,defIntOffset Both "stgEagerBlackholeInfo"
"FUN_OFFSET(stgEagerBlackholeInfo)"
@@ -405,7 +404,6 @@ wanteds os = concat
,defIntOffset Both "stgGCFun" "FUN_OFFSET(stgGCFun)"
,fieldOffset Both "Capability" "r"
- ,fieldOffset C "Capability" "lock"
,structField C "Capability" "no"
,structField C "Capability" "mut_lists"
,structField C "Capability" "context_switch"
@@ -424,18 +422,11 @@ wanteds os = concat
,structField C "bdescr" "link"
,structField Both "bdescr" "flags"
- ,structSize C "generation"
,structField C "generation" "n_new_large_words"
- ,structField C "generation" "weak_ptr_list"
,structSize Both "CostCentreStack"
- ,structField C "CostCentreStack" "ccsID"
,structFieldH Both "CostCentreStack" "mem_alloc"
,structFieldH Both "CostCentreStack" "scc_count"
- ,structField C "CostCentreStack" "prevStack"
-
- ,structField C "CostCentre" "ccID"
- ,structField C "CostCentre" "link"
,structField C "StgHeader" "info"
,structField_ Both "StgHeader_ccs" "StgHeader" "prof.ccs"
@@ -472,18 +463,14 @@ wanteds os = concat
,closurePayload C "StgArrBytes" "payload"
,closureField C "StgTSO" "_link"
- ,closureField C "StgTSO" "global_link"
,closureField C "StgTSO" "what_next"
,closureField C "StgTSO" "why_blocked"
,closureField C "StgTSO" "block_info"
,closureField C "StgTSO" "blocked_exceptions"
,closureField C "StgTSO" "id"
,closureField C "StgTSO" "cap"
- ,closureField C "StgTSO" "saved_errno"
,closureField C "StgTSO" "trec"
,closureField C "StgTSO" "flags"
- ,closureField C "StgTSO" "dirty"
- ,closureField C "StgTSO" "bq"
,closureField C "StgTSO" "label"
,closureField C "StgTSO" "bound"
,closureField Both "StgTSO" "alloc_limit"
@@ -496,8 +483,6 @@ wanteds os = concat
,closureField C "StgStack" "dirty"
,closureField C "StgStack" "marking"
- ,structSize C "StgTSOProfInfo"
-
,closureField Both "StgUpdateFrame" "updatee"
,closureField Both "StgOrigThunkInfoFrame" "info_ptr"
@@ -519,19 +504,15 @@ wanteds os = concat
,closureFieldGcptr C "StgAP" "fun"
,closurePayload C "StgAP" "payload"
- ,thunkSize C "StgAP_STACK"
,closureField C "StgAP_STACK" "size"
,closureFieldGcptr C "StgAP_STACK" "fun"
,closurePayload C "StgAP_STACK" "payload"
- ,closureSize C "StgContinuation"
,closureField C "StgContinuation" "apply_mask_frame"
,closureField C "StgContinuation" "mask_frame_offset"
,closureField C "StgContinuation" "stack_size"
,closurePayload C "StgContinuation" "stack"
- ,thunkSize C "StgSelector"
-
,closureFieldGcptr C "StgInd" "indirectee"
,closureSize C "StgMutVar"
@@ -552,10 +533,6 @@ wanteds os = concat
,closureField C "StgCatchRetryFrame" "first_code"
,closureField C "StgCatchRetryFrame" "alt_code"
- ,closureField C "StgTVarWatchQueue" "closure"
- ,closureField C "StgTVarWatchQueue" "next_queue_entry"
- ,closureField C "StgTVarWatchQueue" "prev_queue_entry"
-
,closureSize C "StgTVar"
,closureField C "StgTVar" "current_value"
,closureField C "StgTVar" "first_watch_queue_entry"
@@ -595,29 +572,19 @@ wanteds os = concat
,closureSize C "StgStableName"
,closureField C "StgStableName" "sn"
- ,closureSize C "StgBlockingQueue"
- ,closureField C "StgBlockingQueue" "bh"
- ,closureField C "StgBlockingQueue" "owner"
- ,closureField C "StgBlockingQueue" "queue"
- ,closureField C "StgBlockingQueue" "link"
-
,closureSize C "MessageBlackHole"
,closureField C "MessageBlackHole" "link"
,closureField C "MessageBlackHole" "tso"
,closureField C "MessageBlackHole" "bh"
- ,closureSize C "StgCompactNFData"
,closureField C "StgCompactNFData" "totalW"
- ,closureField C "StgCompactNFData" "autoBlockW"
,closureField C "StgCompactNFData" "nursery"
- ,closureField C "StgCompactNFData" "last"
,closureField C "StgCompactNFData" "hp"
,closureField C "StgCompactNFData" "hpLim"
,closureField C "StgCompactNFData" "hash"
,closureField C "StgCompactNFData" "result"
,structSize C "StgCompactNFDataBlock"
- ,structField C "StgCompactNFDataBlock" "self"
,structField C "StgCompactNFDataBlock" "owner"
,structField C "StgCompactNFDataBlock" "next"
@@ -635,10 +602,7 @@ wanteds os = concat
"RTS_FLAGS" "DebugFlags.zero_on_gc"
,structField_ C "RtsFlags_GcFlags_initialStkSize"
"RTS_FLAGS" "GcFlags.initialStkSize"
- ,structField_ C "RtsFlags_MiscFlags_tickInterval"
- "RTS_FLAGS" "MiscFlags.tickInterval"
- ,structSize C "StgFunInfoExtraFwd"
,structField C "StgFunInfoExtraFwd" "slow_apply"
,structField C "StgFunInfoExtraFwd" "fun_type"
,structFieldH Both "StgFunInfoExtraFwd" "arity"
@@ -652,11 +616,9 @@ wanteds os = concat
,structField_ C "StgFunInfoExtraRev_bitmap_offset" "StgFunInfoExtraRev" "b.bitmap_offset"
,structField C "StgLargeBitmap" "size"
- ,fieldOffset C "StgLargeBitmap" "bitmap"
,structSize C "snEntry"
,structField C "snEntry" "sn_obj"
- ,structField C "snEntry" "addr"
,structSize C "spEntry"
,structField C "spEntry" "addr"
@@ -672,51 +634,15 @@ wanteds os = concat
else []
-- struct HsIface
- ,structField C "HsIface" "processRemoteCompletion_closure"
- ,structField C "HsIface" "runIO_closure"
- ,structField C "HsIface" "runNonIO_closure"
,structField C "HsIface" "Z0T_closure"
,structField C "HsIface" "True_closure"
,structField C "HsIface" "False_closure"
- ,structField C "HsIface" "unpackCString_closure"
- ,structField C "HsIface" "runFinalizzerBatch_closure"
- ,structField C "HsIface" "stackOverflow_closure"
,structField C "HsIface" "heapOverflow_closure"
- ,structField C "HsIface" "allocationLimitExceeded_closure"
- ,structField C "HsIface" "blockedIndefinitelyOnMVar_closure"
- ,structField C "HsIface" "blockedIndefinitelyOnSTM_closure"
,structField C "HsIface" "cannotCompactFunction_closure"
,structField C "HsIface" "cannotCompactPinned_closure"
,structField C "HsIface" "cannotCompactMutable_closure"
- ,structField C "HsIface" "nonTermination_closure"
,structField C "HsIface" "nestedAtomically_closure"
,structField C "HsIface" "noMatchingContinuationPrompt_closure"
- ,structField C "HsIface" "blockedOnBadFD_closure"
- ,structField C "HsIface" "runSparks_closure"
- ,structField C "HsIface" "ensureIOManagerIsRunning_closure"
- ,structField C "HsIface" "interruptIOManager_closure"
- ,structField C "HsIface" "ioManagerCapabilitiesChanged_closure"
- ,structField C "HsIface" "runHandlersPtr_closure"
- ,structField C "HsIface" "flushStdHandles_closure"
- ,structField C "HsIface" "runMainIO_closure"
- ,structField C "HsIface" "Czh_con_info"
- ,structField C "HsIface" "Izh_con_info"
- ,structField C "HsIface" "Fzh_con_info"
- ,structField C "HsIface" "Dzh_con_info"
- ,structField C "HsIface" "Wzh_con_info"
- ,structField C "HsIface" "runAllocationLimitHandler_closure"
- ,structField C "HsIface" "Ptr_con_info"
- ,structField C "HsIface" "FunPtr_con_info"
- ,structField C "HsIface" "I8zh_con_info"
- ,structField C "HsIface" "I16zh_con_info"
- ,structField C "HsIface" "I32zh_con_info"
- ,structField C "HsIface" "I64zh_con_info"
- ,structField C "HsIface" "W8zh_con_info"
- ,structField C "HsIface" "W16zh_con_info"
- ,structField C "HsIface" "W32zh_con_info"
- ,structField C "HsIface" "W64zh_con_info"
- ,structField C "HsIface" "StablePtr_con_info"
- ,structField C "HsIface" "StackSnapshot_closure"
,structField C "HsIface" "divZZeroException_closure"
,structField C "HsIface" "underflowException_closure"
,structField C "HsIface" "overflowException_closure"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4eb374f50b8915dc464a7e8e1add28…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4eb374f50b8915dc464a7e8e1add28…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fix-clang64-split-sections] 10 commits: compiler: add targetHasRTSWays function
by Cheng Shao (@TerrorJack) 07 Jan '26
by Cheng Shao (@TerrorJack) 07 Jan '26
07 Jan '26
Cheng Shao pushed to branch wip/fix-clang64-split-sections at Glasgow Haskell Compiler / GHC
Commits:
69e0ab59 by Cheng Shao at 2026-01-06T19:37:56-05:00
compiler: add targetHasRTSWays function
This commit adds a `targetHasRTSWays` util function in
`GHC.Driver.Session` to query if the target RTS has a given Ways (e.g.
WayThreaded).
- - - - -
25a0ab94 by Cheng Shao at 2026-01-06T19:37:56-05:00
compiler: link on-demand external interpreter with threaded RTS
This commit makes the compiler link the on-demand external interpreter
program with threaded RTS if it is available in the target RTS ways.
This is a better default than the previous single-threaded RTS, and it
enables the external interpreter to benefit from parallelism when
deserializing CreateBCOs messages.
- - - - -
92404a2b by Cheng Shao at 2026-01-06T19:37:56-05:00
hadrian: link iserv with threaded RTS
This commit makes hadrian link iserv with threaded RTS if it's
available in the RTS ways. Also cleans up the iserv main C program
which can be replaced by the `-fkeep-cafs` link-time option.
- - - - -
a20542d2 by Cheng Shao at 2026-01-06T19:38:38-05:00
ghc-internal: remove unused GMP macros
This patch removes unused GMP related macros from `ghc-internal`. The
in-tree GMP version was hard coded and outdated, but it was not used
anywhere anyway.
- - - - -
4079dcd6 by Cheng Shao at 2026-01-06T19:38:38-05:00
hadrian: fix in-tree gmp configure error on newer c compilers
Building in-tree gmp on newer c compilers that default to c23 fails at
configure stage, this patch fixes it, see added comment for
explanation.
- - - - -
414d1fe1 by Cheng Shao at 2026-01-06T19:39:20-05:00
compiler: fix LLVM backend pdep/pext handling for i386 target
This patch fixes LLVM backend's pdep/pext handling for i386 target,
and also removes non-existent 128/256/512 bit hs_pdep/hs_pext callees.
See amended note for more explanation. Fixes #26450.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
c7f6fba3 by Cheng Shao at 2026-01-06T19:39:20-05:00
ci: remove allow_failure flag for i386 alpine job
The LLVM codegen issue for i386 has been fixed, and the i386 alpine
job should pass now. This commit removes the allow_failure flag so
that other i386 regressions in the future are signaled more timely.
- - - - -
50907ded by Cheng Shao at 2026-01-07T03:17:55+01:00
compiler: change sectionProtection to take SectionType argument
This commit changes `sectionProtection` to only take `SectionType`
argument instead of whole `Section`, since it doesn't need the Cmm
section content anyway, and it can then be called in parts of NCG
where we only have a `SectionType` in scope.
- - - - -
789205de by Cheng Shao at 2026-01-07T03:17:55+01:00
compiler: change isInitOrFiniSection to take SectionType argument
This commit changes `isInitOrFiniSection` to only take `SectionType`
argument instead of whole `Section`, since it doesn't need the Cmm
section content anyway, and it can then be called in parts of NCG
where we only have a `SectionType` in scope. Also marks it as
exported.
- - - - -
b31eb436 by Cheng Shao at 2026-01-07T03:17:58+01:00
compiler: fix split sections on windows
This patch fixes split sections on windows by emitting the right
COMDAT section header in NCG, see added comment for more explanation.
Fix #26696 #26494.
-------------------------
Metric Decrease:
LargeRecord
T9675
size_hello_artifact
size_hello_artifact_gzip
size_hello_unicode
size_hello_unicode_gzip
Metric Increase:
T13035
-------------------------
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
22 changed files:
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/GHC.hs
- compiler/GHC/Cmm.hs
- compiler/GHC/Cmm/InitFini.hs
- compiler/GHC/CmmToAsm/AArch64/Ppr.hs
- compiler/GHC/CmmToAsm/Ppr.hs
- compiler/GHC/CmmToAsm/Wasm/FromCmm.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToC.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/CmmToLlvm/Data.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Runtime/Interpreter/C.hs
- compiler/GHC/Runtime/Interpreter/Init.hs
- hadrian/src/Packages.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Settings/Packages.hs
- libraries/ghc-internal/configure.ac
- libraries/ghc-internal/include/HsIntegerGmp.h.in
- − utils/iserv/cbits/iservmain.c
- utils/iserv/iserv.cabal.in
Changes:
=====================================
.gitlab/generate-ci/gen_ci.hs
=====================================
@@ -1250,7 +1250,7 @@ alpine_x86 =
, fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt)))
-- Dynamically linked build, suitable for building your own static executables on alpine
, disableValidate (standardBuildsWithConfig Amd64 (Linux Alpine323) (splitSectionsBroken vanilla))
- , allowFailureGroup (standardBuildsWithConfig I386 (Linux Alpine323) (splitSectionsBroken vanilla))
+ , standardBuildsWithConfig I386 (Linux Alpine323) (splitSectionsBroken vanilla)
]
where
-- ghcilink002 broken due to #17869
=====================================
.gitlab/jobs.yaml
=====================================
@@ -484,7 +484,7 @@
".gitlab/ci.sh clean",
"cat ci_timings.txt"
],
- "allow_failure": true,
+ "allow_failure": false,
"artifacts": {
"expire_in": "2 weeks",
"paths": [
@@ -1155,7 +1155,7 @@
".gitlab/ci.sh clean",
"cat ci_timings.txt"
],
- "allow_failure": true,
+ "allow_failure": false,
"artifacts": {
"expire_in": "8 weeks",
"paths": [
@@ -4034,7 +4034,7 @@
".gitlab/ci.sh clean",
"cat ci_timings.txt"
],
- "allow_failure": true,
+ "allow_failure": false,
"artifacts": {
"expire_in": "1 year",
"paths": [
=====================================
compiler/GHC.hs
=====================================
@@ -719,7 +719,7 @@ setTopSessionDynFlags dflags = do
{ interpCreateProcess = createIservProcessHook (hsc_hooks hsc_env)
}
- interp <- liftIO $ initInterpreter tmpfs logger platform finder_cache unit_env interp_opts
+ interp <- liftIO $ initInterpreter dflags tmpfs logger platform finder_cache unit_env interp_opts
modifySession $ \h -> hscSetFlags dflags
h{ hsc_IC = (hsc_IC h){ ic_dflags = dflags }
=====================================
compiler/GHC/Cmm.hs
=====================================
@@ -278,8 +278,8 @@ data SectionProtection
deriving (Eq)
-- | Should a data in this section be considered constant at runtime
-sectionProtection :: Section -> SectionProtection
-sectionProtection (Section t _) = case t of
+sectionProtection :: SectionType -> SectionProtection
+sectionProtection t = case t of
Text -> ReadOnlySection
ReadOnlyData -> ReadOnlySection
RelocatableReadOnlyData -> WriteProtectedSection
=====================================
compiler/GHC/Cmm/InitFini.hs
=====================================
@@ -2,6 +2,7 @@
module GHC.Cmm.InitFini
( InitOrFini(..)
, isInitOrFiniArray
+ , isInitOrFiniSection
) where
import GHC.Prelude
@@ -63,8 +64,8 @@ finalizer CmmDecl will be emitted per module.
data InitOrFini = IsInitArray | IsFiniArray
isInitOrFiniArray :: RawCmmDecl -> Maybe (InitOrFini, [CLabel])
-isInitOrFiniArray (CmmData sect (CmmStaticsRaw _ lits))
- | Just initOrFini <- isInitOrFiniSection sect
+isInitOrFiniArray (CmmData (Section t _) (CmmStaticsRaw _ lits))
+ | Just initOrFini <- isInitOrFiniSection t
= Just (initOrFini, map get_label lits)
where
get_label :: CmmStatic -> CLabel
@@ -72,7 +73,7 @@ isInitOrFiniArray (CmmData sect (CmmStaticsRaw _ lits))
get_label static = pprPanic "isInitOrFiniArray: invalid entry" (ppr static)
isInitOrFiniArray _ = Nothing
-isInitOrFiniSection :: Section -> Maybe InitOrFini
-isInitOrFiniSection (Section InitArray _) = Just IsInitArray
-isInitOrFiniSection (Section FiniArray _) = Just IsFiniArray
+isInitOrFiniSection :: SectionType -> Maybe InitOrFini
+isInitOrFiniSection InitArray = Just IsInitArray
+isInitOrFiniSection FiniArray = Just IsFiniArray
isInitOrFiniSection _ = Nothing
=====================================
compiler/GHC/CmmToAsm/AArch64/Ppr.hs
=====================================
@@ -19,6 +19,7 @@ import GHC.Cmm.Dataflow.Label
import GHC.Cmm.BlockId
import GHC.Cmm.CLabel
+import GHC.Cmm.InitFini
import GHC.Types.Unique ( pprUniqueAlways, getUnique )
import GHC.Platform
@@ -28,9 +29,7 @@ import GHC.Utils.Panic
pprNatCmmDecl :: IsDoc doc => NCGConfig -> NatCmmDecl RawCmmStatics Instr -> doc
pprNatCmmDecl config (CmmData section dats) =
- let platform = ncgPlatform config
- in
- pprSectionAlign config section $$ pprDatas platform dats
+ pprSectionAlign config section $$ pprDatas config dats
pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) =
let platform = ncgPlatform config
@@ -91,9 +90,20 @@ pprAlignForSection _platform _seg
-- .balign 8
--
pprSectionAlign :: IsDoc doc => NCGConfig -> Section -> doc
-pprSectionAlign config sec@(Section seg _) =
+pprSectionAlign config sec@(Section seg suffix) =
line (pprSectionHeader config sec)
+ $$ coffSplitSectionComdatKey
$$ pprAlignForSection (ncgPlatform config) seg
+ where
+ platform = ncgPlatform config
+ -- See Note [Split sections on COFF objects]
+ coffSplitSectionComdatKey
+ | OSMinGW32 <- platformOS platform
+ , ncgSplitSections config
+ , Nothing <- isInitOrFiniSection seg
+ = line (pprCOFFComdatKey platform suffix <> colon)
+ | otherwise
+ = empty
-- | Output the ELF .size directive.
pprSizeDecl :: IsDoc doc => Platform -> CLabel -> doc
@@ -136,20 +146,26 @@ pprBasicBlock platform with_dwarf info_env (BasicBlock blockid instrs)
(l@LOCATION{} : _) -> pprInstr platform l
_other -> empty
-pprDatas :: IsDoc doc => Platform -> RawCmmStatics -> doc
+pprDatas :: IsDoc doc => NCGConfig -> RawCmmStatics -> doc
-- See Note [emit-time elimination of static indirections] in "GHC.Cmm.CLabel".
-pprDatas platform (CmmStaticsRaw alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _])
+pprDatas config (CmmStaticsRaw alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _])
| lbl == mkIndStaticInfoLabel
, let labelInd (CmmLabelOff l _) = Just l
labelInd (CmmLabel l) = Just l
labelInd _ = Nothing
, Just ind' <- labelInd ind
, alias `mayRedirectTo` ind'
+ -- See Note [Split sections on COFF objects]
+ , not $ platformOS platform == OSMinGW32 && ncgSplitSections config
= pprGloblDecl platform alias
$$ line (text ".equiv" <+> pprAsmLabel platform alias <> comma <> pprAsmLabel platform ind')
+ where
+ platform = ncgPlatform config
-pprDatas platform (CmmStaticsRaw lbl dats)
+pprDatas config (CmmStaticsRaw lbl dats)
= vcat (pprLabel platform lbl : map (pprData platform) dats)
+ where
+ platform = ncgPlatform config
pprData :: IsDoc doc => Platform -> CmmStatic -> doc
pprData _platform (CmmString str) = line (pprString str)
=====================================
compiler/GHC/CmmToAsm/Ppr.hs
=====================================
@@ -1,4 +1,5 @@
{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiWayIf #-}
-----------------------------------------------------------------------------
--
@@ -14,6 +15,7 @@ module GHC.CmmToAsm.Ppr (
pprASCII,
pprString,
pprFileEmbed,
+ pprCOFFComdatKey,
pprSectionHeader
)
@@ -23,6 +25,7 @@ import GHC.Prelude
import GHC.Utils.Asm
import GHC.Cmm.CLabel
+import GHC.Cmm.InitFini
import GHC.Cmm
import GHC.CmmToAsm.Config
import GHC.Utils.Outputable as SDoc
@@ -220,8 +223,8 @@ pprGNUSectionHeader config t suffix =
| otherwise -> text ".rodata"
RelocatableReadOnlyData | OSMinGW32 <- platformOS platform
-- Concept does not exist on Windows,
- -- So map these to R/O data.
- -> text ".rdata$rel.ro"
+ -- So map these to data.
+ -> text ".data"
| otherwise -> text ".data.rel.ro"
UninitialisedData -> text ".bss"
InitArray
@@ -240,24 +243,79 @@ pprGNUSectionHeader config t suffix =
| OSMinGW32 <- platformOS platform
-> text ".rdata"
| otherwise -> text ".ipe"
- flags = case t of
- Text
- | OSMinGW32 <- platformOS platform, splitSections
- -> text ",\"xr\""
- | splitSections
- -> text ",\"ax\"," <> sectionType platform "progbits"
- CString
- | OSMinGW32 <- platformOS platform
- -> empty
- | otherwise -> text ",\"aMS\"," <> sectionType platform "progbits" <> text ",1"
- IPE
- | OSMinGW32 <- platformOS platform
- -> empty
- | otherwise -> text ",\"a\"," <> sectionType platform "progbits"
- _ -> empty
+ flags
+ -- See
+ -- https://github.com/llvm/llvm-project/blob/llvmorg-21.1.8/lld/COFF/Chunks.cp…
+ -- and https://llvm.org/docs/Extensions.html#section-directive.
+ -- LLD COFF backend gc-sections only work on COMDAT sections so
+ -- we need to mark it as a COMDAT section. You can use clang64
+ -- toolchain to compile small examples with
+ -- `-ffunction-sections -fdata-sections -S` to see these section
+ -- headers in the wild. Also see Note [Split sections on COFF objects]
+ -- below.
+ | OSMinGW32 <- platformOS platform,
+ splitSections =
+ if
+ | Just _ <- isInitOrFiniSection t -> text ",\"dw\""
+ | otherwise ->
+ let coff_section_flags
+ | Text <- t = "xr"
+ | UninitialisedData <- t = "bw"
+ | ReadOnlySection <- sectionProtection t = "dr"
+ | otherwise = "dw"
+ in hcat
+ [ text ",\"",
+ text coff_section_flags,
+ text "\",one_only,",
+ pprCOFFComdatKey platform suffix
+ ]
+ | otherwise =
+ case t of
+ Text
+ | splitSections
+ -> text ",\"ax\"," <> sectionType platform "progbits"
+ CString
+ | OSMinGW32 <- platformOS platform
+ -> empty
+ | otherwise -> text ",\"aMS\"," <> sectionType platform "progbits" <> text ",1"
+ IPE
+ | OSMinGW32 <- platformOS platform
+ -> empty
+ | otherwise -> text ",\"a\"," <> sectionType platform "progbits"
+ _ -> empty
{-# SPECIALIZE pprGNUSectionHeader :: NCGConfig -> SectionType -> CLabel -> SDoc #-}
{-# SPECIALIZE pprGNUSectionHeader :: NCGConfig -> SectionType -> CLabel -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable
+-- | Note [Split sections on COFF objects]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--
+-- On Windows/COFF, LLD's gc-sections only works on COMDAT sections,
+-- so we mark split sections as COMDAT and need to provide a unique
+-- "key" symbol.
+--
+-- Important: We must not use a dot-prefixed local label (e.g.
+-- @.L...@) as the COMDAT key symbol, because LLVM's COFF assembler
+-- treats dot-prefixed COMDAT key symbols specially and forces them to
+-- have value 0 (the beginning of the section). That breaks
+-- @tablesNextToCode@, where the info label is intentionally placed
+-- after the info table data (at a non-zero offset).
+--
+-- Therefore we generate a non-dot-prefixed key symbol derived from
+-- the section suffix, and (see arch-specific 'pprSectionAlign') we
+-- emit a label definition for it at the beginning of the section.
+--
+-- ctor/dtor sections are specially treated; they must be emitted as
+-- regular data sections, otherwise LLD will drop them.
+--
+-- Note that we must not emit .equiv directives for COMDAT sections in
+-- COFF objects, they seriously confuse LLD and we end up with access
+-- violations at runtimes.
+pprCOFFComdatKey :: IsLine doc => Platform -> CLabel -> doc
+pprCOFFComdatKey platform suffix =
+ text "__ghc_coff_comdat_" <> pprAsmLabel platform suffix
+{-# SPECIALIZE pprCOFFComdatKey :: Platform -> CLabel -> SDoc #-}
+{-# SPECIALIZE pprCOFFComdatKey :: Platform -> CLabel -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable
+
-- XCOFF doesn't support relocating label-differences, so we place all
-- RO sections into .text[PR] sections
pprXcoffSectionHeader :: IsLine doc => SectionType -> doc
=====================================
compiler/GHC/CmmToAsm/Wasm/FromCmm.hs
=====================================
@@ -107,7 +107,7 @@ symKindFromCLabel lbl
-- | Calculate a data section's kind, see haddock docs of
-- 'DataSectionKind' for more explanation.
dataSectionKindFromCmmSection :: Section -> DataSectionKind
-dataSectionKindFromCmmSection s = case sectionProtection s of
+dataSectionKindFromCmmSection (Section t _) = case sectionProtection t of
ReadWriteSection -> SectionData
_ -> SectionROData
=====================================
compiler/GHC/CmmToAsm/X86/Ppr.hs
=====================================
@@ -31,6 +31,7 @@ import GHC.Cmm hiding (topInfoTable)
import GHC.Cmm.Dataflow.Label
import GHC.Cmm.BlockId
import GHC.Cmm.CLabel
+import GHC.Cmm.InitFini
import GHC.Cmm.DebugBlock (pprUnwindTable)
import GHC.Types.Basic (Alignment, mkAlignment, alignmentBytes)
@@ -195,8 +196,12 @@ pprDatas config (_, CmmStaticsRaw alias [CmmStaticLit (CmmLabel lbl), CmmStaticL
labelInd _ = Nothing
, Just ind' <- labelInd ind
, alias `mayRedirectTo` ind'
+ -- See Note [Split sections on COFF objects]
+ , not $ platformOS platform == OSMinGW32 && ncgSplitSections config
= pprGloblDecl (ncgPlatform config) alias
$$ line (text ".equiv" <+> pprAsmLabel (ncgPlatform config) alias <> comma <> pprAsmLabel (ncgPlatform config) ind')
+ where
+ platform = ncgPlatform config
pprDatas config (align, (CmmStaticsRaw lbl dats))
= vcat (pprAlign platform align : pprLabel platform lbl : map (pprData config) dats)
@@ -526,9 +531,20 @@ pprAddr platform (AddrBaseIndex base index displacement)
-- | Print section header and appropriate alignment for that section.
pprSectionAlign :: IsDoc doc => NCGConfig -> Section -> doc
-pprSectionAlign config sec@(Section seg _) =
+pprSectionAlign config sec@(Section seg suffix) =
line (pprSectionHeader config sec) $$
+ coffSplitSectionComdatKey $$
pprAlignForSection (ncgPlatform config) seg
+ where
+ platform = ncgPlatform config
+ -- See Note [Split sections on COFF objects]
+ coffSplitSectionComdatKey
+ | OSMinGW32 <- platformOS platform
+ , ncgSplitSections config
+ , Nothing <- isInitOrFiniSection seg
+ = line (pprCOFFComdatKey platform suffix <> colon)
+ | otherwise
+ = empty
-- | Print appropriate alignment for the given section type.
pprAlignForSection :: IsDoc doc => Platform -> SectionType -> doc
=====================================
compiler/GHC/CmmToC.hs
=====================================
@@ -121,7 +121,7 @@ pprTop platform = \case
pprDataExterns platform lits $$
pprWordArray platform (isSecConstant section) lbl lits
where
- isSecConstant section = case sectionProtection section of
+ isSecConstant (Section t _) = case sectionProtection t of
ReadOnlySection -> True
WriteProtectedSection -> True
_ -> False
=====================================
compiler/GHC/CmmToLlvm/CodeGen.hs
=====================================
@@ -248,6 +248,14 @@ Since x86 PDep/PExt instructions only exist for 32/64 bit widths
we use the 32bit variant to compute the 8/16bit primops.
To do so we extend/truncate the argument/result around the
call.
+
+Note that the 64-bit intrinsics (`llvm.x86.bmi.pdep.64` and
+`llvm.x86.bmi.pext.64`) are only legal on 64-bit x86 targets, not on
+i386. Therefore on i386 we must fall back to the runtime helper
+(`hs_pdep64`/`hs_pext64`) for the 64-bit primops.
+
+See https://github.com/llvm/llvm-project/issues/172857 for upstream
+discussion about portable pdep/pext intrinsics.
-}
genCall (PrimTarget op@(MO_Pdep w)) [dst] args = do
cfg <- getConfig
@@ -970,36 +978,34 @@ cmmPrimOpFunctions mop = do
W8 -> fsLit "llvm.x86.bmi.pdep.32"
W16 -> fsLit "llvm.x86.bmi.pdep.32"
W32 -> fsLit "llvm.x86.bmi.pdep.32"
- W64 -> fsLit "llvm.x86.bmi.pdep.64"
- W128 -> fsLit "llvm.x86.bmi.pdep.128"
- W256 -> fsLit "llvm.x86.bmi.pdep.256"
- W512 -> fsLit "llvm.x86.bmi.pdep.512"
+ W64
+ | is32bit -> fsLit "hs_pdep64"
+ | otherwise -> fsLit "llvm.x86.bmi.pdep.64"
+ -- LLVM only provides x86 PDep/PExt intrinsics for 32/64 bits
+ _ -> unsupported
| otherwise -> case w of
W8 -> fsLit "hs_pdep8"
W16 -> fsLit "hs_pdep16"
W32 -> fsLit "hs_pdep32"
W64 -> fsLit "hs_pdep64"
- W128 -> fsLit "hs_pdep128"
- W256 -> fsLit "hs_pdep256"
- W512 -> fsLit "hs_pdep512"
+ _ -> unsupported
MO_Pext w
| isBmi2Enabled -> case w of
-- See Note [LLVM PDep/PExt intrinsics]
W8 -> fsLit "llvm.x86.bmi.pext.32"
W16 -> fsLit "llvm.x86.bmi.pext.32"
W32 -> fsLit "llvm.x86.bmi.pext.32"
- W64 -> fsLit "llvm.x86.bmi.pext.64"
- W128 -> fsLit "llvm.x86.bmi.pext.128"
- W256 -> fsLit "llvm.x86.bmi.pext.256"
- W512 -> fsLit "llvm.x86.bmi.pext.512"
+ W64
+ | is32bit -> fsLit "hs_pext64"
+ | otherwise -> fsLit "llvm.x86.bmi.pext.64"
+ -- LLVM only provides x86 PDep/PExt intrinsics for 32/64 bits
+ _ -> unsupported
| otherwise -> case w of
W8 -> fsLit "hs_pext8"
W16 -> fsLit "hs_pext16"
W32 -> fsLit "hs_pext32"
W64 -> fsLit "hs_pext64"
- W128 -> fsLit "hs_pext128"
- W256 -> fsLit "hs_pext256"
- W512 -> fsLit "hs_pext512"
+ _ -> unsupported
MO_AddIntC w -> case w of
W8 -> fsLit "llvm.sadd.with.overflow.i8"
=====================================
compiler/GHC/CmmToLlvm/Data.hs
=====================================
@@ -75,7 +75,7 @@ genLlvmData (sect, statics)
IsFiniArray -> fsLit "llvm.global_dtors"
in genGlobalLabelArray var clbls
-genLlvmData (sec, CmmStaticsRaw lbl xs) = do
+genLlvmData (sec@(Section t _), CmmStaticsRaw lbl xs) = do
label <- strCLabel_llvm lbl
static <- mapM genData xs
lmsec <- llvmSection sec
@@ -92,7 +92,7 @@ genLlvmData (sec, CmmStaticsRaw lbl xs) = do
then Just 2 else Just 1
Section Data _ -> Just $ platformWordSizeInBytes platform
_ -> Nothing
- const = if sectionProtection sec == ReadOnlySection
+ const = if sectionProtection t == ReadOnlySection
then Constant else Global
varDef = LMGlobalVar label tyAlias link lmsec align const
globDef = LMGlobal varDef struct
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -197,6 +197,8 @@ module GHC.Driver.Session (
-- * Compiler configuration suitable for display to the user
compilerInfo,
+ targetHasRTSWays,
+
wordAlignment,
setUnsafeGlobalDynFlags,
@@ -3635,6 +3637,15 @@ compilerInfo dflags
queryCmdMaybe p f = expandDirectories (query (maybe "" (prgPath . p) . f))
queryFlagsMaybe p f = query (maybe "" (unwords . map escapeArg . prgFlags . p) . f)
+-- | Query if the target RTS has the given 'Ways'. It's computed from
+-- the @"RTS ways"@ field in the settings file.
+targetHasRTSWays :: DynFlags -> Ways -> Bool
+targetHasRTSWays dflags ways
+ | Just ws <- lookup "RTS ways" $ compilerInfo dflags =
+ waysTag ways
+ `elem` words ws
+ | otherwise = panic "RTS ways not found in settings"
+
-- Note [Special unit-ids]
-- ~~~~~~~~~~~~~~~~~~~~~~~
-- Certain units are special to the compiler:
=====================================
compiler/GHC/Runtime/Interpreter/C.hs
=====================================
@@ -8,7 +8,9 @@ where
import GHC.Prelude
import GHC.Platform
+import GHC.Platform.Ways
import GHC.Data.FastString
+import GHC.Driver.Session
import GHC.Utils.Logger
import GHC.Utils.TmpFs
import GHC.Unit.Types
@@ -18,11 +20,10 @@ import GHC.Unit.State
import GHC.Utils.Panic.Plain
import GHC.Linker.Executable
import GHC.Linker.Config
-import GHC.Utils.CliOption
-- | Generate iserv program for the target
-generateIservC :: Logger -> TmpFs -> ExecutableLinkOpts -> UnitEnv -> IO FilePath
-generateIservC logger tmpfs opts unit_env = do
+generateIservC :: DynFlags -> Logger -> TmpFs -> ExecutableLinkOpts -> UnitEnv -> IO FilePath
+generateIservC dflags logger tmpfs opts unit_env = do
-- get the unit-id of the ghci package. We need this to load the
-- interpreter code.
let unit_state = ue_homeUnitState unit_env
@@ -60,6 +61,12 @@ generateIservC logger tmpfs opts unit_env = do
-- must retain CAFs for running interpreted code.
, leKeepCafs = True
+ -- link with -threaded if target has threaded RTS
+ , leWays =
+ let ways = leWays opts
+ ways' = addWay WayThreaded ways
+ in if targetHasRTSWays dflags ways' then ways' else ways
+
-- enable all rts options
, leRtsOptsEnabled = RtsOptsAll
=====================================
compiler/GHC/Runtime/Interpreter/Init.hs
=====================================
@@ -9,6 +9,7 @@ where
import GHC.Prelude
+import GHC.Driver.DynFlags
import GHC.Platform
import GHC.Platform.Ways
import GHC.Settings
@@ -57,14 +58,15 @@ data InterpOpts = InterpOpts
-- | Initialize code interpreter
initInterpreter
- :: TmpFs
+ :: DynFlags
+ -> TmpFs
-> Logger
-> Platform
-> FinderCache
-> UnitEnv
-> InterpOpts
-> IO (Maybe Interp)
-initInterpreter tmpfs logger platform finder_cache unit_env opts = do
+initInterpreter dflags tmpfs logger platform finder_cache unit_env opts = do
lookup_cache <- liftIO $ mkInterpSymbolCache
@@ -125,7 +127,7 @@ initInterpreter tmpfs logger platform finder_cache unit_env opts = do
dynamic = interpWays opts `hasWay` WayDyn
prog <- case interpProg opts of
-- build iserv program if none specified
- "" -> generateIservC logger tmpfs (interpExecutableLinkOpts opts) unit_env
+ "" -> generateIservC dflags logger tmpfs (interpExecutableLinkOpts opts) unit_env
_ -> pure (interpProg opts ++ flavour)
where
flavour
=====================================
hadrian/src/Packages.hs
=====================================
@@ -217,7 +217,7 @@ timeoutPath = "testsuite/timeout/install-inplace/bin/timeout" <.> exe
-- TODO: Can we extract this information from Cabal files?
-- | Some program packages should not be linked with Haskell main function.
nonHsMainPackage :: Package -> Bool
-nonHsMainPackage = (`elem` [hp2ps, iserv, unlit, ghciWrapper])
+nonHsMainPackage = (`elem` [hp2ps, unlit, ghciWrapper])
{-
=====================================
hadrian/src/Rules/Gmp.hs
=====================================
@@ -126,6 +126,12 @@ gmpRules = do
interpretInContext ctx $
mconcat
[ getStagedCCFlags
+ -- gmp fails to configure with newer compilers
+ -- that default to c23:
+ -- https://gmplib.org/list-archives/gmp-devel/2025-January/006279.html.
+ -- for now just manually specify -std=gnu11 until
+ -- next upstream release.
+ , arg "-std=gnu11"
-- gmp symbols are only used by bignum logic in
-- ghc-internal and shouldn't be exported by the
-- ghc-internal shared library.
=====================================
hadrian/src/Settings/Packages.hs
=====================================
@@ -41,6 +41,8 @@ packageArgs = do
libzstdLibraryDir <- getSetting LibZstdLibDir
stageVersion <- readVersion <$> (expr $ ghcVersionStage stage)
+ rtsWays <- getRtsWays
+
mconcat
--------------------------------- base ---------------------------------
[ package base ? mconcat
@@ -185,11 +187,15 @@ packageArgs = do
--
-- The Solaris linker does not support --export-dynamic option. It also
-- does not need it since it exports all dynamic symbols by default
- , package iserv
- ? expr isElfTarget
+ , package iserv ? mconcat [
+ expr isElfTarget
? notM (expr $ anyTargetOs [OSFreeBSD, OSSolaris2])? mconcat
[ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ]
+ -- Link iserv with -threaded if possible
+ , builder (Cabal Flags) ? any (wayUnit Threaded) rtsWays `cabalFlag` "threaded"
+ ]
+
-------------------------------- haddock -------------------------------
, package haddockApi ?
builder (Cabal Flags) ? arg "in-ghc-tree"
=====================================
libraries/ghc-internal/configure.ac
=====================================
@@ -195,28 +195,10 @@ dnl--------------------------------------------------------------------
if test "$HaveFrameworkGMP" = "YES" || test "$HaveLibGmp" = "YES"
then
AC_MSG_RESULT([no])
- UseIntreeGmp=0
AC_CHECK_HEADER([gmp.h], , [AC_MSG_ERROR([Cannot find gmp.h])])
-
- AC_MSG_CHECKING([GMP version])
- AC_COMPUTE_INT(GhcGmpVerMj, __GNU_MP_VERSION, [#include <gmp.h>],
- AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION]))
- AC_COMPUTE_INT(GhcGmpVerMi, __GNU_MP_VERSION_MINOR, [#include <gmp.h>],
- AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION_MINOR]))
- AC_COMPUTE_INT(GhcGmpVerPl, __GNU_MP_VERSION_PATCHLEVEL, [#include <gmp.h>],
- AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION_PATCHLEVEL]))
- AC_MSG_RESULT([$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl])
-
else
AC_MSG_RESULT([yes])
- UseIntreeGmp=1
HaveSecurePowm=1
-
- AC_MSG_CHECKING([GMP version])
- GhcGmpVerMj=6
- GhcGmpVerMi=1
- GhcGmpVerPl=2
- AC_MSG_RESULT([$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl])
fi
GMP_INSTALL_INCLUDES="HsIntegerGmp.h ghc-gmp.h"
@@ -231,10 +213,6 @@ AC_SUBST(GMP_INSTALL_INCLUDES)
AC_SUBST(HaveLibGmp)
AC_SUBST(HaveFrameworkGMP)
AC_SUBST(HaveSecurePowm)
-AC_SUBST(UseIntreeGmp)
-AC_SUBST(GhcGmpVerMj)
-AC_SUBST(GhcGmpVerMi)
-AC_SUBST(GhcGmpVerPl)
# Compute offsets/sizes used by jsbits/base.js
if test "$host" = "javascript-ghcjs"
=====================================
libraries/ghc-internal/include/HsIntegerGmp.h.in
=====================================
@@ -1,14 +1,4 @@
#pragma once
-/* Whether GMP is embedded into ghc-internal */
-#define GHC_GMP_INTREE @UseIntreeGmp@
-
-/* The following values denote the GMP version used during GHC build-time */
-#define GHC_GMP_VERSION_MJ @GhcGmpVerMj@
-#define GHC_GMP_VERSION_MI @GhcGmpVerMi@
-#define GHC_GMP_VERSION_PL @GhcGmpVerPl@
-#define GHC_GMP_VERSION \
- (@GhcGmpVerMj@ * 10000 + @GhcGmpVerMi@ * 100 + @GhcGmpVerPl@)
-
/* Whether GMP supports mpz_powm_sec */
#define HAVE_SECURE_POWM @HaveSecurePowm@
=====================================
utils/iserv/cbits/iservmain.c deleted
=====================================
@@ -1,18 +0,0 @@
-#include <ghcversion.h>
-# include <rts/PosixSource.h>
-#include <Rts.h>
-
-#include <HsFFI.h>
-
-int main (int argc, char *argv[])
-{
- RtsConfig conf = defaultRtsConfig;
-
- // We never know what symbols GHC will look up in the future, so
- // we must retain CAFs for running interpreted code.
- conf.keep_cafs = 1;
-
- conf.rts_opts_enabled = RtsOptsAll;
- extern StgClosure ZCMain_main_closure;
- hs_main(argc, argv, &ZCMain_main_closure, conf);
-}
=====================================
utils/iserv/iserv.cabal.in
=====================================
@@ -23,11 +23,17 @@ Category: Development
build-type: Simple
cabal-version: >=1.10
+Flag threaded
+ Description: Link the iserv executable against the threaded RTS
+ Default: True
+ Manual: True
+
Executable iserv
Default-Language: Haskell2010
- ghc-options: -no-hs-main
+ ghc-options: -fkeep-cafs -rtsopts
+ if flag(threaded)
+ ghc-options: -threaded
Main-Is: Main.hs
- C-Sources: cbits/iservmain.c
Hs-Source-Dirs: src
include-dirs: .
Build-Depends:
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b70bcb0efc69e7f5df969f27d8e998…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b70bcb0efc69e7f5df969f27d8e998…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 16 commits: compiler: add targetHasRTSWays function
by Marge Bot (@marge-bot) 07 Jan '26
by Marge Bot (@marge-bot) 07 Jan '26
07 Jan '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
69e0ab59 by Cheng Shao at 2026-01-06T19:37:56-05:00
compiler: add targetHasRTSWays function
This commit adds a `targetHasRTSWays` util function in
`GHC.Driver.Session` to query if the target RTS has a given Ways (e.g.
WayThreaded).
- - - - -
25a0ab94 by Cheng Shao at 2026-01-06T19:37:56-05:00
compiler: link on-demand external interpreter with threaded RTS
This commit makes the compiler link the on-demand external interpreter
program with threaded RTS if it is available in the target RTS ways.
This is a better default than the previous single-threaded RTS, and it
enables the external interpreter to benefit from parallelism when
deserializing CreateBCOs messages.
- - - - -
92404a2b by Cheng Shao at 2026-01-06T19:37:56-05:00
hadrian: link iserv with threaded RTS
This commit makes hadrian link iserv with threaded RTS if it's
available in the RTS ways. Also cleans up the iserv main C program
which can be replaced by the `-fkeep-cafs` link-time option.
- - - - -
a20542d2 by Cheng Shao at 2026-01-06T19:38:38-05:00
ghc-internal: remove unused GMP macros
This patch removes unused GMP related macros from `ghc-internal`. The
in-tree GMP version was hard coded and outdated, but it was not used
anywhere anyway.
- - - - -
4079dcd6 by Cheng Shao at 2026-01-06T19:38:38-05:00
hadrian: fix in-tree gmp configure error on newer c compilers
Building in-tree gmp on newer c compilers that default to c23 fails at
configure stage, this patch fixes it, see added comment for
explanation.
- - - - -
414d1fe1 by Cheng Shao at 2026-01-06T19:39:20-05:00
compiler: fix LLVM backend pdep/pext handling for i386 target
This patch fixes LLVM backend's pdep/pext handling for i386 target,
and also removes non-existent 128/256/512 bit hs_pdep/hs_pext callees.
See amended note for more explanation. Fixes #26450.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
c7f6fba3 by Cheng Shao at 2026-01-06T19:39:20-05:00
ci: remove allow_failure flag for i386 alpine job
The LLVM codegen issue for i386 has been fixed, and the i386 alpine
job should pass now. This commit removes the allow_failure flag so
that other i386 regressions in the future are signaled more timely.
- - - - -
4930a1fb by Simon Peyton Jones at 2026-01-06T20:12:18-05:00
Add missing InVar->OutVar lookup in SetLevels
As #26681 showed, the SetLevels pass was failing to map an InVar to
an OutVar. Very silly! I'm amazed it hasn't broken before now.
I have improved the type singatures (to mention InVar and OutVar)
so it's more obvious what needs to happen.
- - - - -
591c9473 by Cheng Shao at 2026-01-06T20:12:19-05:00
hadrian: drop deprecated pkgHashSplitObjs code path
This patch drops deprecated `pkgHashSplitObjs` code path from hadrian,
since GHC itself has removed split objs support many versions ago and
this code path is unused.
- - - - -
0702c070 by Cheng Shao at 2026-01-06T20:12:20-05:00
hadrian: remove linting/assertion in quick-validate flavour
The `quick-validate` flavour is meant for testing ghc and passing the
testsuite locally with similar settings to `validate` but faster. This
patch removes the linting/assertion overhead in `quick-validate` to
improve developer experience. I also took the chance to simplify
redundant logic of rts/library way definition in `validate` flavour.
- - - - -
eefb22a2 by Cheng Shao at 2026-01-06T20:12:21-05:00
deriveConstants: clean up unused constants
This patch cleans up unused constants from `deriveConstants`, they are
not used by C/Cmm code in the RTS, nor compiler-generated code.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
783fa750 by Cheng Shao at 2026-01-06T20:12:22-05:00
hadrian: pass -fno-omit-frame-pointer with +debug_info
This patch adds `-fno-omit-frame-pointer` as C/C++ compilation flag
when compiling with `+debug_info` flavour transformer. It's a sane
default when you care about debugging and reliable backtraces, and
makes debugging/profiling with bpf easier.
- - - - -
d2b599e6 by Aaron Allen at 2026-01-06T20:12:34-05:00
[26705] Include TyCl instances in data fam iface entry
Ensures dependent modules are recompiled when the class instances for a
data family instance change.
resolves #26705
- - - - -
2668b24a by Cheng Shao at 2026-01-06T20:12:35-05:00
hadrian: remove unused Hp2Ps/Hpc builders
This patch removes the Hp2Ps/Hpc builders from hadrian, they are
unused in the build system. Note that the hp2ps/hpc programs are still
built and not affected.
- - - - -
61996985 by Cheng Shao at 2026-01-06T20:12:36-05:00
hadrian: only install js files to libdir for wasm/js targets
There are certain js files required for wasm/js targets to work, and
previously hadrian would install those js files to libdir
unconditionally on other targets as well. This could be a minor
annoyance for packagers especially when the unused js files contain
shebangs that interfere with the packaging process. This patch makes
hadrian only selectively install the right js files for the right
targets.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
4eb374f5 by Simon Peyton Jones at 2026-01-06T20:12:37-05:00
Add flavour transformer assertions_stage1
This allows us to enable -DDEBUG assertions in the stage1 compiler
- - - - -
33 changed files:
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/GHC.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Runtime/Interpreter/C.hs
- compiler/GHC/Runtime/Interpreter/Init.hs
- hadrian/doc/flavours.md
- hadrian/src/Base.hs
- hadrian/src/Builder.hs
- hadrian/src/Flavour.hs
- hadrian/src/Hadrian/Haskell/Hash.hs
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Packages.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Rules/Register.hs
- hadrian/src/Settings/Flavours/Validate.hs
- hadrian/src/Settings/Packages.hs
- libraries/ghc-internal/configure.ac
- libraries/ghc-internal/include/HsIntegerGmp.h.in
- + testsuite/tests/driver/recomp26705/M.hs
- + testsuite/tests/driver/recomp26705/M2A.hs
- + testsuite/tests/driver/recomp26705/M2B.hs
- + testsuite/tests/driver/recomp26705/Makefile
- + testsuite/tests/driver/recomp26705/all.T
- + testsuite/tests/driver/recomp26705/recomp26705.stderr
- + testsuite/tests/simplCore/should_compile/T26681.hs
- testsuite/tests/simplCore/should_compile/all.T
- utils/deriveConstants/Main.hs
- − utils/iserv/cbits/iservmain.c
- utils/iserv/iserv.cabal.in
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b15b142370617f4f89bf70e61c1754…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b15b142370617f4f89bf70e61c1754…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 2 commits: compiler: fix LLVM backend pdep/pext handling for i386 target
by Marge Bot (@marge-bot) 07 Jan '26
by Marge Bot (@marge-bot) 07 Jan '26
07 Jan '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
414d1fe1 by Cheng Shao at 2026-01-06T19:39:20-05:00
compiler: fix LLVM backend pdep/pext handling for i386 target
This patch fixes LLVM backend's pdep/pext handling for i386 target,
and also removes non-existent 128/256/512 bit hs_pdep/hs_pext callees.
See amended note for more explanation. Fixes #26450.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
c7f6fba3 by Cheng Shao at 2026-01-06T19:39:20-05:00
ci: remove allow_failure flag for i386 alpine job
The LLVM codegen issue for i386 has been fixed, and the i386 alpine
job should pass now. This commit removes the allow_failure flag so
that other i386 regressions in the future are signaled more timely.
- - - - -
3 changed files:
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/GHC/CmmToLlvm/CodeGen.hs
Changes:
=====================================
.gitlab/generate-ci/gen_ci.hs
=====================================
@@ -1250,7 +1250,7 @@ alpine_x86 =
, fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt)))
-- Dynamically linked build, suitable for building your own static executables on alpine
, disableValidate (standardBuildsWithConfig Amd64 (Linux Alpine323) (splitSectionsBroken vanilla))
- , allowFailureGroup (standardBuildsWithConfig I386 (Linux Alpine323) (splitSectionsBroken vanilla))
+ , standardBuildsWithConfig I386 (Linux Alpine323) (splitSectionsBroken vanilla)
]
where
-- ghcilink002 broken due to #17869
=====================================
.gitlab/jobs.yaml
=====================================
@@ -484,7 +484,7 @@
".gitlab/ci.sh clean",
"cat ci_timings.txt"
],
- "allow_failure": true,
+ "allow_failure": false,
"artifacts": {
"expire_in": "2 weeks",
"paths": [
@@ -1155,7 +1155,7 @@
".gitlab/ci.sh clean",
"cat ci_timings.txt"
],
- "allow_failure": true,
+ "allow_failure": false,
"artifacts": {
"expire_in": "8 weeks",
"paths": [
@@ -4034,7 +4034,7 @@
".gitlab/ci.sh clean",
"cat ci_timings.txt"
],
- "allow_failure": true,
+ "allow_failure": false,
"artifacts": {
"expire_in": "1 year",
"paths": [
=====================================
compiler/GHC/CmmToLlvm/CodeGen.hs
=====================================
@@ -248,6 +248,14 @@ Since x86 PDep/PExt instructions only exist for 32/64 bit widths
we use the 32bit variant to compute the 8/16bit primops.
To do so we extend/truncate the argument/result around the
call.
+
+Note that the 64-bit intrinsics (`llvm.x86.bmi.pdep.64` and
+`llvm.x86.bmi.pext.64`) are only legal on 64-bit x86 targets, not on
+i386. Therefore on i386 we must fall back to the runtime helper
+(`hs_pdep64`/`hs_pext64`) for the 64-bit primops.
+
+See https://github.com/llvm/llvm-project/issues/172857 for upstream
+discussion about portable pdep/pext intrinsics.
-}
genCall (PrimTarget op@(MO_Pdep w)) [dst] args = do
cfg <- getConfig
@@ -970,36 +978,34 @@ cmmPrimOpFunctions mop = do
W8 -> fsLit "llvm.x86.bmi.pdep.32"
W16 -> fsLit "llvm.x86.bmi.pdep.32"
W32 -> fsLit "llvm.x86.bmi.pdep.32"
- W64 -> fsLit "llvm.x86.bmi.pdep.64"
- W128 -> fsLit "llvm.x86.bmi.pdep.128"
- W256 -> fsLit "llvm.x86.bmi.pdep.256"
- W512 -> fsLit "llvm.x86.bmi.pdep.512"
+ W64
+ | is32bit -> fsLit "hs_pdep64"
+ | otherwise -> fsLit "llvm.x86.bmi.pdep.64"
+ -- LLVM only provides x86 PDep/PExt intrinsics for 32/64 bits
+ _ -> unsupported
| otherwise -> case w of
W8 -> fsLit "hs_pdep8"
W16 -> fsLit "hs_pdep16"
W32 -> fsLit "hs_pdep32"
W64 -> fsLit "hs_pdep64"
- W128 -> fsLit "hs_pdep128"
- W256 -> fsLit "hs_pdep256"
- W512 -> fsLit "hs_pdep512"
+ _ -> unsupported
MO_Pext w
| isBmi2Enabled -> case w of
-- See Note [LLVM PDep/PExt intrinsics]
W8 -> fsLit "llvm.x86.bmi.pext.32"
W16 -> fsLit "llvm.x86.bmi.pext.32"
W32 -> fsLit "llvm.x86.bmi.pext.32"
- W64 -> fsLit "llvm.x86.bmi.pext.64"
- W128 -> fsLit "llvm.x86.bmi.pext.128"
- W256 -> fsLit "llvm.x86.bmi.pext.256"
- W512 -> fsLit "llvm.x86.bmi.pext.512"
+ W64
+ | is32bit -> fsLit "hs_pext64"
+ | otherwise -> fsLit "llvm.x86.bmi.pext.64"
+ -- LLVM only provides x86 PDep/PExt intrinsics for 32/64 bits
+ _ -> unsupported
| otherwise -> case w of
W8 -> fsLit "hs_pext8"
W16 -> fsLit "hs_pext16"
W32 -> fsLit "hs_pext32"
W64 -> fsLit "hs_pext64"
- W128 -> fsLit "hs_pext128"
- W256 -> fsLit "hs_pext256"
- W512 -> fsLit "hs_pext512"
+ _ -> unsupported
MO_AddIntC w -> case w of
W8 -> fsLit "llvm.sadd.with.overflow.i8"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4079dcd6418763f0a7b255d834c035…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4079dcd6418763f0a7b255d834c035…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fix-darwin-toolchain-cruft] 8 commits: compiler: add targetHasRTSWays function
by Cheng Shao (@TerrorJack) 07 Jan '26
by Cheng Shao (@TerrorJack) 07 Jan '26
07 Jan '26
Cheng Shao pushed to branch wip/fix-darwin-toolchain-cruft at Glasgow Haskell Compiler / GHC
Commits:
69e0ab59 by Cheng Shao at 2026-01-06T19:37:56-05:00
compiler: add targetHasRTSWays function
This commit adds a `targetHasRTSWays` util function in
`GHC.Driver.Session` to query if the target RTS has a given Ways (e.g.
WayThreaded).
- - - - -
25a0ab94 by Cheng Shao at 2026-01-06T19:37:56-05:00
compiler: link on-demand external interpreter with threaded RTS
This commit makes the compiler link the on-demand external interpreter
program with threaded RTS if it is available in the target RTS ways.
This is a better default than the previous single-threaded RTS, and it
enables the external interpreter to benefit from parallelism when
deserializing CreateBCOs messages.
- - - - -
92404a2b by Cheng Shao at 2026-01-06T19:37:56-05:00
hadrian: link iserv with threaded RTS
This commit makes hadrian link iserv with threaded RTS if it's
available in the RTS ways. Also cleans up the iserv main C program
which can be replaced by the `-fkeep-cafs` link-time option.
- - - - -
a20542d2 by Cheng Shao at 2026-01-06T19:38:38-05:00
ghc-internal: remove unused GMP macros
This patch removes unused GMP related macros from `ghc-internal`. The
in-tree GMP version was hard coded and outdated, but it was not used
anywhere anyway.
- - - - -
4079dcd6 by Cheng Shao at 2026-01-06T19:38:38-05:00
hadrian: fix in-tree gmp configure error on newer c compilers
Building in-tree gmp on newer c compilers that default to c23 fails at
configure stage, this patch fixes it, see added comment for
explanation.
- - - - -
414d1fe1 by Cheng Shao at 2026-01-06T19:39:20-05:00
compiler: fix LLVM backend pdep/pext handling for i386 target
This patch fixes LLVM backend's pdep/pext handling for i386 target,
and also removes non-existent 128/256/512 bit hs_pdep/hs_pext callees.
See amended note for more explanation. Fixes #26450.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
c7f6fba3 by Cheng Shao at 2026-01-06T19:39:20-05:00
ci: remove allow_failure flag for i386 alpine job
The LLVM codegen issue for i386 has been fixed, and the i386 alpine
job should pass now. This commit removes the allow_failure flag so
that other i386 regressions in the future are signaled more timely.
- - - - -
e4c20ab7 by Cheng Shao at 2026-01-07T01:40:15+01:00
ci: update darwin boot ghc to 9.10.3
This patch updates darwin boot ghc to 9.10.3, along with other related
updates, and pays off some technical debt here:
- Update `nixpkgs` and use the `nixpkgs-25.05-darwin` channel.
- Update the `niv` template.
- Update LLVM to 21.
- Use `stdenvNoCC` to prevent nix packaged apple sdk from being used
by boot ghc, and manually set `DEVELOPER_DIR`/`SDKROOT` to enforce
the usage of system-wide command line sdk for macos.
- When building nix derivation for boot ghc, run `configure` via the
`arch` command so that `configure` and its subprocesses pick up the
manually specified architecture.
- Remove the previous horrible hack that obliterates `configure` to
make every autoconf test result in true. `configure` now properly
does its job.
- Remove the now obsolete configure args and post install settings
file patching logic.
- Use `scheme-small` for texlive to avoid build failures in certain
unused texlive packages, especially on x86_64-darwin.
- - - - -
17 changed files:
- .gitlab/darwin/nix/sources.json
- .gitlab/darwin/nix/sources.nix
- .gitlab/darwin/toolchain.nix
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/GHC.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Runtime/Interpreter/C.hs
- compiler/GHC/Runtime/Interpreter/Init.hs
- hadrian/src/Packages.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Settings/Packages.hs
- libraries/ghc-internal/configure.ac
- libraries/ghc-internal/include/HsIntegerGmp.h.in
- − utils/iserv/cbits/iservmain.c
- utils/iserv/iserv.cabal.in
Changes:
=====================================
.gitlab/darwin/nix/sources.json
=====================================
@@ -1,26 +1,14 @@
{
- "niv": {
- "branch": "master",
- "description": "Easy dependency management for Nix projects",
- "homepage": "https://github.com/nmattia/niv",
- "owner": "nmattia",
- "repo": "niv",
- "rev": "e0ca65c81a2d7a4d82a189f1e23a48d59ad42070",
- "sha256": "1pq9nh1d8nn3xvbdny8fafzw87mj7gsmp6pxkdl65w2g18rmcmzx",
- "type": "tarball",
- "url": "https://github.com/nmattia/niv/archive/e0ca65c81a2d7a4d82a189f1e23a48d59ad4…",
- "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
- },
"nixpkgs": {
- "branch": "nixos-unstable",
+ "branch": "nixpkgs-25.05-darwin",
"description": "Nix Packages collection",
"homepage": "",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "2893f56de08021cffd9b6b6dfc70fd9ccd51eb60",
- "sha256": "1anwxmjpm21msnnlrjdz19w31bxnbpn4kgf93sn3npihi7wf4a8h",
+ "rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d",
+ "sha256": "0v6bd1xk8a2aal83karlvc853x44dg1n4nk08jg3dajqyy0s98np",
"type": "tarball",
- "url": "https://github.com/nixos/nixpkgs/archive/2893f56de08021cffd9b6b6dfc70fd9ccd…",
+ "url": "https://github.com/nixos/nixpkgs/archive/ac62194c3917d5f474c1a844b6fd6da2db…",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}
}
=====================================
.gitlab/darwin/nix/sources.nix
=====================================
@@ -10,29 +10,50 @@ let
let
name' = sanitizeName name + "-src";
in
- if spec.builtin or true then
- builtins_fetchurl { inherit (spec) url sha256; name = name'; }
- else
- pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
+ if spec.builtin or true then
+ builtins_fetchurl { inherit (spec) url sha256; name = name'; }
+ else
+ pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
fetch_tarball = pkgs: name: spec:
let
name' = sanitizeName name + "-src";
in
- if spec.builtin or true then
- builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
- else
- pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
+ if spec.builtin or true then
+ builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
+ else
+ pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
fetch_git = name: spec:
let
ref =
- if spec ? ref then spec.ref else
+ spec.ref or (
if spec ? branch then "refs/heads/${spec.branch}" else
- if spec ? tag then "refs/tags/${spec.tag}" else
- abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!";
+ if spec ? tag then "refs/tags/${spec.tag}" else
+ abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!"
+ );
+ submodules = spec.submodules or false;
+ submoduleArg =
+ let
+ nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0;
+ emptyArgWithWarning =
+ if submodules
+ then
+ builtins.trace
+ (
+ "The niv input \"${name}\" uses submodules "
+ + "but your nix's (${builtins.nixVersion}) builtins.fetchGit "
+ + "does not support them"
+ )
+ { }
+ else { };
+ in
+ if nixSupportsSubmodules
+ then { inherit submodules; }
+ else emptyArgWithWarning;
in
- builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; };
+ builtins.fetchGit
+ ({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg);
fetch_local = spec: spec.path;
@@ -66,16 +87,16 @@ let
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
hasThisAsNixpkgsPath = <nixpkgs> == ./.;
in
- if builtins.hasAttr "nixpkgs" sources
- then sourcesNixpkgs
- else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then
- import <nixpkgs> {}
- else
- abort
- ''
- Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or
- add a package called "nixpkgs" to your sources.json.
- '';
+ if builtins.hasAttr "nixpkgs" sources
+ then sourcesNixpkgs
+ else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then
+ import <nixpkgs> { }
+ else
+ abort
+ ''
+ Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or
+ add a package called "nixpkgs" to your sources.json.
+ '';
# The actual fetching function.
fetch = pkgs: name: spec:
@@ -95,13 +116,13 @@ let
# the path directly as opposed to the fetched source.
replace = name: drv:
let
- saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name;
+ saneName = stringAsChars (c: if (builtins.match "[a-zA-Z0-9]" c) == null then "_" else c) name;
ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}";
in
- if ersatz == "" then drv else
- # this turns the string into an actual Nix path (for both absolute and
- # relative paths)
- if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}";
+ if ersatz == "" then drv else
+ # this turns the string into an actual Nix path (for both absolute and
+ # relative paths)
+ if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}";
# Ports of functions for older nix versions
@@ -112,7 +133,7 @@ let
);
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fece…
- range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1);
+ range = first: last: if first > last then [ ] else builtins.genList (n: first + n) (last - first + 1);
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fece…
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
@@ -123,43 +144,46 @@ let
concatStrings = builtins.concatStringsSep "";
# https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d…
- optionalAttrs = cond: as: if cond then as else {};
+ optionalAttrs = cond: as: if cond then as else { };
# fetchTarball version that is compatible between all the versions of Nix
builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchTarball;
in
- if lessThan nixVersion "1.12" then
- fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
- else
- fetchTarball attrs;
+ if lessThan nixVersion "1.12" then
+ fetchTarball ({ inherit url; } // (optionalAttrs (name != null) { inherit name; }))
+ else
+ fetchTarball attrs;
# fetchurl version that is compatible between all the versions of Nix
builtins_fetchurl = { url, name ? null, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchurl;
in
- if lessThan nixVersion "1.12" then
- fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
- else
- fetchurl attrs;
+ if lessThan nixVersion "1.12" then
+ fetchurl ({ inherit url; } // (optionalAttrs (name != null) { inherit name; }))
+ else
+ fetchurl attrs;
# Create the final "sources" from the config
mkSources = config:
- mapAttrs (
- name: spec:
- if builtins.hasAttr "outPath" spec
- then abort
- "The values in sources.json should not have an 'outPath' attribute"
- else
- spec // { outPath = replace name (fetch config.pkgs name spec); }
- ) config.sources;
+ mapAttrs
+ (
+ name: spec:
+ if builtins.hasAttr "outPath" spec
+ then
+ abort
+ "The values in sources.json should not have an 'outPath' attribute"
+ else
+ spec // { outPath = replace name (fetch config.pkgs name spec); }
+ )
+ config.sources;
# The "config" used by the fetchers
mkConfig =
{ sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
- , sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile)
+ , sources ? if sourcesFile == null then { } else builtins.fromJSON (builtins.readFile sourcesFile)
, system ? builtins.currentSystem
, pkgs ? mkPkgs sources system
}: rec {
@@ -171,4 +195,4 @@ let
};
in
-mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); }
+mkSources (mkConfig { }) // { __functor = _: settings: mkSources (mkConfig settings); }
=====================================
.gitlab/darwin/toolchain.nix
=====================================
@@ -11,69 +11,67 @@ let
hsPkgs = pkgs.haskellPackages;
alex = hsPkgs.alex;
happy = hsPkgs.happy;
- targetTriple = pkgs.stdenv.targetPlatform.config;
+ targetTriple = pkgs.stdenvNoCC.targetPlatform.config;
ghcBindists = let version = ghc.version; in {
- aarch64-darwin = hostPkgs.fetchurl {
+ aarch64-darwin = hostPkgs.fetchzip {
url = "https://downloads.haskell.org/ghc/${version}/ghc-${version}-aarch64-apple-d…";
- sha256 = "sha256-/6+DtdeossBJIMbjkJwL4h3eJ7rzgNCV+ifoQKOi6AQ=";
+ hash = "sha512-xUlt7zc/OT3a1SR0BxmFFgrabPkWUENATdw4NbQwEi5+nH5yPau+HSrGI5UUoKdO4gdpgZlPaxtI7eSk0fx1+g==";
};
- x86_64-darwin = hostPkgs.fetchurl {
+ x86_64-darwin = hostPkgs.fetchzip {
url = "https://downloads.haskell.org/ghc/${version}/ghc-${version}-x86_64-apple-da…";
- sha256 = "sha256-jPIhiJMOENesUnDUJeIaPatgavc6ZVSTY5NFIAxlC+k=";
+ hash = "sha512-4/INeJwPPGbOj9MepwnIvIg2lvFkqS8w/3U/I8f6gCsoNlgwPr78iyY9vd6vfMONR1GxNQU3L/lxE07F3P0Qag==";
};
-
};
- ghc = pkgs.stdenv.mkDerivation rec {
- version = "9.10.1";
+ ghc = pkgs.stdenvNoCC.mkDerivation rec {
+ version = "9.10.3";
name = "ghc";
- src = ghcBindists.${pkgs.stdenv.hostPlatform.system};
+ src = ghcBindists.${pkgs.stdenvNoCC.hostPlatform.system};
+
+ dontUpdateAutotoolsGnuConfigScripts = true;
+
configureFlags = [
- "CC=/usr/bin/clang"
- "CLANG=/usr/bin/clang"
"AR=/usr/bin/ar"
- "LLC=${llvm}/bin/llc"
- "OPT=${llvm}/bin/opt"
- "LLVMAS=${llvm_clang}/bin/clang"
- "CONF_CC_OPTS_STAGE2=--target=${targetTriple}"
- "CONF_CXX_OPTS_STAGE2=--target=${targetTriple}"
- "CONF_GCC_LINKER_OPTS_STAGE2=--target=${targetTriple}"
+ "CC=/usr/bin/clang"
+ "CXX=/usr/bin/clang++"
+ "INSTALL=/usr/bin/install"
+ "INSTALL_NAME_TOOL=/usr/bin/install_name_tool"
+ "MergeObjsCmd=/usr/bin/ld"
+ "NM=/usr/bin/nm"
+ "OTOOL=/usr/bin/otool"
+ "RANLIB=/usr/bin/ranlib"
];
- buildPhase = "true";
-
- # This is a horrible hack because the configure script invokes /usr/bin/clang
- # without a `--target` flag. Then depending on whether the `nix` binary itself is
- # a native x86 or arm64 binary means that /usr/bin/clang thinks it needs to run in
- # x86 or arm64 mode.
-
- # The correct answer for the check in question is the first one we try, so by replacing
- # the condition to true; we select the right C++ standard library still.
- preConfigure = ''
- sed "s/\"\$CC\" -o actest actest.o \''${1} 2>\/dev\/null/true/i" configure > configure.new
- mv configure.new configure
- chmod +x configure
- cat configure
+ # Use the arch command to explicitly specify architecture, so that
+ # configure and its subprocesses would pick up the architecture we
+ # choose via the system argument.
+ preConfigure = pkgs.lib.optionalString (system == "aarch64-darwin") ''
+ substituteInPlace configure \
+ --replace-fail "#! /bin/sh" "#!/usr/bin/env -S /usr/bin/arch -arm64 /bin/sh"
+ '' + pkgs.lib.optionalString (system == "x86_64-darwin") ''
+ substituteInPlace configure \
+ --replace-fail "#! /bin/sh" "#!/usr/bin/env -S /usr/bin/arch -x86_64 /bin/sh"
+ '' + ''
+ unset DEVELOPER_DIR SDKROOT
+ export DEVELOPER_DIR="$(/usr/bin/xcode-select --print-path)"
+ export SDKROOT="$(/usr/bin/xcrun --sdk macosx --show-sdk-path)"
'';
+ dontPatchShebangsInConfigure = true;
+
# N.B. Work around #20253.
nativeBuildInputs = [ pkgs.gnused ];
- postInstallPhase = ''
- settings="$out/lib/ghc-${version}/settings"
- sed -i -e "s%\"llc\"%\"${llvm}/bin/llc\"%" $settings
- sed -i -e "s%\"opt\"%\"${llvm}/bin/opt\"%" $settings
- sed -i -e "s%\"clang\"%\"/usr/bin/clang\"%" $settings
- sed -i -e 's%("C compiler command", "")%("C compiler command", "/usr/bin/clang")%' $settings
- sed -i -e 's%("C compiler flags", "")%("C compiler flags", "--target=${targetTriple}")%' $settings
- sed -i -e 's%("C++ compiler flags", "")%("C++ compiler flags", "--target=${targetTriple}")%' $settings
- sed -i -e 's%("C compiler link flags", "")%("C compiler link flags", "--target=${targetTriple}")%' $settings
- '';
+
+ dontBuild = true;
+
+ enableParallelInstalling = true;
+
+ dontFixup = true;
# Sanity check: verify that we can compile hello world.
doInstallCheck = true;
installCheckPhase = ''
- unset DYLD_LIBRARY_PATH
$out/bin/ghc --info
cd $TMP
mkdir test-ghc; cd test-ghc
@@ -91,13 +89,13 @@ let
ourtexlive = with pkgs;
texlive.combine {
inherit (texlive)
- scheme-medium collection-xetex fncychap titlesec tabulary varwidth
+ scheme-small collection-xetex fncychap tex-gyre titlesec tabulary varwidth
framed capt-of wrapfig needspace dejavu-otf helvetic upquote;
};
fonts = with pkgs; makeFontsConf { fontDirectories = [ dejavu_fonts ]; };
- llvm = pkgs.llvm_15;
- llvm_clang = pkgs.llvmPackages_15.clang-unwrapped;
+ llvm = pkgs.llvm_21;
+ llvm_clang = pkgs.llvmPackages_21.clang-unwrapped;
in
pkgs.writeTextFile {
name = "toolchain";
=====================================
.gitlab/generate-ci/gen_ci.hs
=====================================
@@ -1250,7 +1250,7 @@ alpine_x86 =
, fullyStaticBrokenTests (disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine312) staticNativeInt)))
-- Dynamically linked build, suitable for building your own static executables on alpine
, disableValidate (standardBuildsWithConfig Amd64 (Linux Alpine323) (splitSectionsBroken vanilla))
- , allowFailureGroup (standardBuildsWithConfig I386 (Linux Alpine323) (splitSectionsBroken vanilla))
+ , standardBuildsWithConfig I386 (Linux Alpine323) (splitSectionsBroken vanilla)
]
where
-- ghcilink002 broken due to #17869
=====================================
.gitlab/jobs.yaml
=====================================
@@ -484,7 +484,7 @@
".gitlab/ci.sh clean",
"cat ci_timings.txt"
],
- "allow_failure": true,
+ "allow_failure": false,
"artifacts": {
"expire_in": "2 weeks",
"paths": [
@@ -1155,7 +1155,7 @@
".gitlab/ci.sh clean",
"cat ci_timings.txt"
],
- "allow_failure": true,
+ "allow_failure": false,
"artifacts": {
"expire_in": "8 weeks",
"paths": [
@@ -4034,7 +4034,7 @@
".gitlab/ci.sh clean",
"cat ci_timings.txt"
],
- "allow_failure": true,
+ "allow_failure": false,
"artifacts": {
"expire_in": "1 year",
"paths": [
=====================================
compiler/GHC.hs
=====================================
@@ -719,7 +719,7 @@ setTopSessionDynFlags dflags = do
{ interpCreateProcess = createIservProcessHook (hsc_hooks hsc_env)
}
- interp <- liftIO $ initInterpreter tmpfs logger platform finder_cache unit_env interp_opts
+ interp <- liftIO $ initInterpreter dflags tmpfs logger platform finder_cache unit_env interp_opts
modifySession $ \h -> hscSetFlags dflags
h{ hsc_IC = (hsc_IC h){ ic_dflags = dflags }
=====================================
compiler/GHC/CmmToLlvm/CodeGen.hs
=====================================
@@ -248,6 +248,14 @@ Since x86 PDep/PExt instructions only exist for 32/64 bit widths
we use the 32bit variant to compute the 8/16bit primops.
To do so we extend/truncate the argument/result around the
call.
+
+Note that the 64-bit intrinsics (`llvm.x86.bmi.pdep.64` and
+`llvm.x86.bmi.pext.64`) are only legal on 64-bit x86 targets, not on
+i386. Therefore on i386 we must fall back to the runtime helper
+(`hs_pdep64`/`hs_pext64`) for the 64-bit primops.
+
+See https://github.com/llvm/llvm-project/issues/172857 for upstream
+discussion about portable pdep/pext intrinsics.
-}
genCall (PrimTarget op@(MO_Pdep w)) [dst] args = do
cfg <- getConfig
@@ -970,36 +978,34 @@ cmmPrimOpFunctions mop = do
W8 -> fsLit "llvm.x86.bmi.pdep.32"
W16 -> fsLit "llvm.x86.bmi.pdep.32"
W32 -> fsLit "llvm.x86.bmi.pdep.32"
- W64 -> fsLit "llvm.x86.bmi.pdep.64"
- W128 -> fsLit "llvm.x86.bmi.pdep.128"
- W256 -> fsLit "llvm.x86.bmi.pdep.256"
- W512 -> fsLit "llvm.x86.bmi.pdep.512"
+ W64
+ | is32bit -> fsLit "hs_pdep64"
+ | otherwise -> fsLit "llvm.x86.bmi.pdep.64"
+ -- LLVM only provides x86 PDep/PExt intrinsics for 32/64 bits
+ _ -> unsupported
| otherwise -> case w of
W8 -> fsLit "hs_pdep8"
W16 -> fsLit "hs_pdep16"
W32 -> fsLit "hs_pdep32"
W64 -> fsLit "hs_pdep64"
- W128 -> fsLit "hs_pdep128"
- W256 -> fsLit "hs_pdep256"
- W512 -> fsLit "hs_pdep512"
+ _ -> unsupported
MO_Pext w
| isBmi2Enabled -> case w of
-- See Note [LLVM PDep/PExt intrinsics]
W8 -> fsLit "llvm.x86.bmi.pext.32"
W16 -> fsLit "llvm.x86.bmi.pext.32"
W32 -> fsLit "llvm.x86.bmi.pext.32"
- W64 -> fsLit "llvm.x86.bmi.pext.64"
- W128 -> fsLit "llvm.x86.bmi.pext.128"
- W256 -> fsLit "llvm.x86.bmi.pext.256"
- W512 -> fsLit "llvm.x86.bmi.pext.512"
+ W64
+ | is32bit -> fsLit "hs_pext64"
+ | otherwise -> fsLit "llvm.x86.bmi.pext.64"
+ -- LLVM only provides x86 PDep/PExt intrinsics for 32/64 bits
+ _ -> unsupported
| otherwise -> case w of
W8 -> fsLit "hs_pext8"
W16 -> fsLit "hs_pext16"
W32 -> fsLit "hs_pext32"
W64 -> fsLit "hs_pext64"
- W128 -> fsLit "hs_pext128"
- W256 -> fsLit "hs_pext256"
- W512 -> fsLit "hs_pext512"
+ _ -> unsupported
MO_AddIntC w -> case w of
W8 -> fsLit "llvm.sadd.with.overflow.i8"
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -197,6 +197,8 @@ module GHC.Driver.Session (
-- * Compiler configuration suitable for display to the user
compilerInfo,
+ targetHasRTSWays,
+
wordAlignment,
setUnsafeGlobalDynFlags,
@@ -3635,6 +3637,15 @@ compilerInfo dflags
queryCmdMaybe p f = expandDirectories (query (maybe "" (prgPath . p) . f))
queryFlagsMaybe p f = query (maybe "" (unwords . map escapeArg . prgFlags . p) . f)
+-- | Query if the target RTS has the given 'Ways'. It's computed from
+-- the @"RTS ways"@ field in the settings file.
+targetHasRTSWays :: DynFlags -> Ways -> Bool
+targetHasRTSWays dflags ways
+ | Just ws <- lookup "RTS ways" $ compilerInfo dflags =
+ waysTag ways
+ `elem` words ws
+ | otherwise = panic "RTS ways not found in settings"
+
-- Note [Special unit-ids]
-- ~~~~~~~~~~~~~~~~~~~~~~~
-- Certain units are special to the compiler:
=====================================
compiler/GHC/Runtime/Interpreter/C.hs
=====================================
@@ -8,7 +8,9 @@ where
import GHC.Prelude
import GHC.Platform
+import GHC.Platform.Ways
import GHC.Data.FastString
+import GHC.Driver.Session
import GHC.Utils.Logger
import GHC.Utils.TmpFs
import GHC.Unit.Types
@@ -18,11 +20,10 @@ import GHC.Unit.State
import GHC.Utils.Panic.Plain
import GHC.Linker.Executable
import GHC.Linker.Config
-import GHC.Utils.CliOption
-- | Generate iserv program for the target
-generateIservC :: Logger -> TmpFs -> ExecutableLinkOpts -> UnitEnv -> IO FilePath
-generateIservC logger tmpfs opts unit_env = do
+generateIservC :: DynFlags -> Logger -> TmpFs -> ExecutableLinkOpts -> UnitEnv -> IO FilePath
+generateIservC dflags logger tmpfs opts unit_env = do
-- get the unit-id of the ghci package. We need this to load the
-- interpreter code.
let unit_state = ue_homeUnitState unit_env
@@ -60,6 +61,12 @@ generateIservC logger tmpfs opts unit_env = do
-- must retain CAFs for running interpreted code.
, leKeepCafs = True
+ -- link with -threaded if target has threaded RTS
+ , leWays =
+ let ways = leWays opts
+ ways' = addWay WayThreaded ways
+ in if targetHasRTSWays dflags ways' then ways' else ways
+
-- enable all rts options
, leRtsOptsEnabled = RtsOptsAll
=====================================
compiler/GHC/Runtime/Interpreter/Init.hs
=====================================
@@ -9,6 +9,7 @@ where
import GHC.Prelude
+import GHC.Driver.DynFlags
import GHC.Platform
import GHC.Platform.Ways
import GHC.Settings
@@ -57,14 +58,15 @@ data InterpOpts = InterpOpts
-- | Initialize code interpreter
initInterpreter
- :: TmpFs
+ :: DynFlags
+ -> TmpFs
-> Logger
-> Platform
-> FinderCache
-> UnitEnv
-> InterpOpts
-> IO (Maybe Interp)
-initInterpreter tmpfs logger platform finder_cache unit_env opts = do
+initInterpreter dflags tmpfs logger platform finder_cache unit_env opts = do
lookup_cache <- liftIO $ mkInterpSymbolCache
@@ -125,7 +127,7 @@ initInterpreter tmpfs logger platform finder_cache unit_env opts = do
dynamic = interpWays opts `hasWay` WayDyn
prog <- case interpProg opts of
-- build iserv program if none specified
- "" -> generateIservC logger tmpfs (interpExecutableLinkOpts opts) unit_env
+ "" -> generateIservC dflags logger tmpfs (interpExecutableLinkOpts opts) unit_env
_ -> pure (interpProg opts ++ flavour)
where
flavour
=====================================
hadrian/src/Packages.hs
=====================================
@@ -217,7 +217,7 @@ timeoutPath = "testsuite/timeout/install-inplace/bin/timeout" <.> exe
-- TODO: Can we extract this information from Cabal files?
-- | Some program packages should not be linked with Haskell main function.
nonHsMainPackage :: Package -> Bool
-nonHsMainPackage = (`elem` [hp2ps, iserv, unlit, ghciWrapper])
+nonHsMainPackage = (`elem` [hp2ps, unlit, ghciWrapper])
{-
=====================================
hadrian/src/Rules/Gmp.hs
=====================================
@@ -126,6 +126,12 @@ gmpRules = do
interpretInContext ctx $
mconcat
[ getStagedCCFlags
+ -- gmp fails to configure with newer compilers
+ -- that default to c23:
+ -- https://gmplib.org/list-archives/gmp-devel/2025-January/006279.html.
+ -- for now just manually specify -std=gnu11 until
+ -- next upstream release.
+ , arg "-std=gnu11"
-- gmp symbols are only used by bignum logic in
-- ghc-internal and shouldn't be exported by the
-- ghc-internal shared library.
=====================================
hadrian/src/Settings/Packages.hs
=====================================
@@ -41,6 +41,8 @@ packageArgs = do
libzstdLibraryDir <- getSetting LibZstdLibDir
stageVersion <- readVersion <$> (expr $ ghcVersionStage stage)
+ rtsWays <- getRtsWays
+
mconcat
--------------------------------- base ---------------------------------
[ package base ? mconcat
@@ -185,11 +187,15 @@ packageArgs = do
--
-- The Solaris linker does not support --export-dynamic option. It also
-- does not need it since it exports all dynamic symbols by default
- , package iserv
- ? expr isElfTarget
+ , package iserv ? mconcat [
+ expr isElfTarget
? notM (expr $ anyTargetOs [OSFreeBSD, OSSolaris2])? mconcat
[ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ]
+ -- Link iserv with -threaded if possible
+ , builder (Cabal Flags) ? any (wayUnit Threaded) rtsWays `cabalFlag` "threaded"
+ ]
+
-------------------------------- haddock -------------------------------
, package haddockApi ?
builder (Cabal Flags) ? arg "in-ghc-tree"
=====================================
libraries/ghc-internal/configure.ac
=====================================
@@ -195,28 +195,10 @@ dnl--------------------------------------------------------------------
if test "$HaveFrameworkGMP" = "YES" || test "$HaveLibGmp" = "YES"
then
AC_MSG_RESULT([no])
- UseIntreeGmp=0
AC_CHECK_HEADER([gmp.h], , [AC_MSG_ERROR([Cannot find gmp.h])])
-
- AC_MSG_CHECKING([GMP version])
- AC_COMPUTE_INT(GhcGmpVerMj, __GNU_MP_VERSION, [#include <gmp.h>],
- AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION]))
- AC_COMPUTE_INT(GhcGmpVerMi, __GNU_MP_VERSION_MINOR, [#include <gmp.h>],
- AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION_MINOR]))
- AC_COMPUTE_INT(GhcGmpVerPl, __GNU_MP_VERSION_PATCHLEVEL, [#include <gmp.h>],
- AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION_PATCHLEVEL]))
- AC_MSG_RESULT([$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl])
-
else
AC_MSG_RESULT([yes])
- UseIntreeGmp=1
HaveSecurePowm=1
-
- AC_MSG_CHECKING([GMP version])
- GhcGmpVerMj=6
- GhcGmpVerMi=1
- GhcGmpVerPl=2
- AC_MSG_RESULT([$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl])
fi
GMP_INSTALL_INCLUDES="HsIntegerGmp.h ghc-gmp.h"
@@ -231,10 +213,6 @@ AC_SUBST(GMP_INSTALL_INCLUDES)
AC_SUBST(HaveLibGmp)
AC_SUBST(HaveFrameworkGMP)
AC_SUBST(HaveSecurePowm)
-AC_SUBST(UseIntreeGmp)
-AC_SUBST(GhcGmpVerMj)
-AC_SUBST(GhcGmpVerMi)
-AC_SUBST(GhcGmpVerPl)
# Compute offsets/sizes used by jsbits/base.js
if test "$host" = "javascript-ghcjs"
=====================================
libraries/ghc-internal/include/HsIntegerGmp.h.in
=====================================
@@ -1,14 +1,4 @@
#pragma once
-/* Whether GMP is embedded into ghc-internal */
-#define GHC_GMP_INTREE @UseIntreeGmp@
-
-/* The following values denote the GMP version used during GHC build-time */
-#define GHC_GMP_VERSION_MJ @GhcGmpVerMj@
-#define GHC_GMP_VERSION_MI @GhcGmpVerMi@
-#define GHC_GMP_VERSION_PL @GhcGmpVerPl@
-#define GHC_GMP_VERSION \
- (@GhcGmpVerMj@ * 10000 + @GhcGmpVerMi@ * 100 + @GhcGmpVerPl@)
-
/* Whether GMP supports mpz_powm_sec */
#define HAVE_SECURE_POWM @HaveSecurePowm@
=====================================
utils/iserv/cbits/iservmain.c deleted
=====================================
@@ -1,18 +0,0 @@
-#include <ghcversion.h>
-# include <rts/PosixSource.h>
-#include <Rts.h>
-
-#include <HsFFI.h>
-
-int main (int argc, char *argv[])
-{
- RtsConfig conf = defaultRtsConfig;
-
- // We never know what symbols GHC will look up in the future, so
- // we must retain CAFs for running interpreted code.
- conf.keep_cafs = 1;
-
- conf.rts_opts_enabled = RtsOptsAll;
- extern StgClosure ZCMain_main_closure;
- hs_main(argc, argv, &ZCMain_main_closure, conf);
-}
=====================================
utils/iserv/iserv.cabal.in
=====================================
@@ -23,11 +23,17 @@ Category: Development
build-type: Simple
cabal-version: >=1.10
+Flag threaded
+ Description: Link the iserv executable against the threaded RTS
+ Default: True
+ Manual: True
+
Executable iserv
Default-Language: Haskell2010
- ghc-options: -no-hs-main
+ ghc-options: -fkeep-cafs -rtsopts
+ if flag(threaded)
+ ghc-options: -threaded
Main-Is: Main.hs
- C-Sources: cbits/iservmain.c
Hs-Source-Dirs: src
include-dirs: .
Build-Depends:
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4c9d0e22cff41bcd77ae4216f3cbee…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4c9d0e22cff41bcd77ae4216f3cbee…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 2 commits: ghc-internal: remove unused GMP macros
by Marge Bot (@marge-bot) 07 Jan '26
by Marge Bot (@marge-bot) 07 Jan '26
07 Jan '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
a20542d2 by Cheng Shao at 2026-01-06T19:38:38-05:00
ghc-internal: remove unused GMP macros
This patch removes unused GMP related macros from `ghc-internal`. The
in-tree GMP version was hard coded and outdated, but it was not used
anywhere anyway.
- - - - -
4079dcd6 by Cheng Shao at 2026-01-06T19:38:38-05:00
hadrian: fix in-tree gmp configure error on newer c compilers
Building in-tree gmp on newer c compilers that default to c23 fails at
configure stage, this patch fixes it, see added comment for
explanation.
- - - - -
3 changed files:
- hadrian/src/Rules/Gmp.hs
- libraries/ghc-internal/configure.ac
- libraries/ghc-internal/include/HsIntegerGmp.h.in
Changes:
=====================================
hadrian/src/Rules/Gmp.hs
=====================================
@@ -126,6 +126,12 @@ gmpRules = do
interpretInContext ctx $
mconcat
[ getStagedCCFlags
+ -- gmp fails to configure with newer compilers
+ -- that default to c23:
+ -- https://gmplib.org/list-archives/gmp-devel/2025-January/006279.html.
+ -- for now just manually specify -std=gnu11 until
+ -- next upstream release.
+ , arg "-std=gnu11"
-- gmp symbols are only used by bignum logic in
-- ghc-internal and shouldn't be exported by the
-- ghc-internal shared library.
=====================================
libraries/ghc-internal/configure.ac
=====================================
@@ -195,28 +195,10 @@ dnl--------------------------------------------------------------------
if test "$HaveFrameworkGMP" = "YES" || test "$HaveLibGmp" = "YES"
then
AC_MSG_RESULT([no])
- UseIntreeGmp=0
AC_CHECK_HEADER([gmp.h], , [AC_MSG_ERROR([Cannot find gmp.h])])
-
- AC_MSG_CHECKING([GMP version])
- AC_COMPUTE_INT(GhcGmpVerMj, __GNU_MP_VERSION, [#include <gmp.h>],
- AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION]))
- AC_COMPUTE_INT(GhcGmpVerMi, __GNU_MP_VERSION_MINOR, [#include <gmp.h>],
- AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION_MINOR]))
- AC_COMPUTE_INT(GhcGmpVerPl, __GNU_MP_VERSION_PATCHLEVEL, [#include <gmp.h>],
- AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION_PATCHLEVEL]))
- AC_MSG_RESULT([$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl])
-
else
AC_MSG_RESULT([yes])
- UseIntreeGmp=1
HaveSecurePowm=1
-
- AC_MSG_CHECKING([GMP version])
- GhcGmpVerMj=6
- GhcGmpVerMi=1
- GhcGmpVerPl=2
- AC_MSG_RESULT([$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl])
fi
GMP_INSTALL_INCLUDES="HsIntegerGmp.h ghc-gmp.h"
@@ -231,10 +213,6 @@ AC_SUBST(GMP_INSTALL_INCLUDES)
AC_SUBST(HaveLibGmp)
AC_SUBST(HaveFrameworkGMP)
AC_SUBST(HaveSecurePowm)
-AC_SUBST(UseIntreeGmp)
-AC_SUBST(GhcGmpVerMj)
-AC_SUBST(GhcGmpVerMi)
-AC_SUBST(GhcGmpVerPl)
# Compute offsets/sizes used by jsbits/base.js
if test "$host" = "javascript-ghcjs"
=====================================
libraries/ghc-internal/include/HsIntegerGmp.h.in
=====================================
@@ -1,14 +1,4 @@
#pragma once
-/* Whether GMP is embedded into ghc-internal */
-#define GHC_GMP_INTREE @UseIntreeGmp@
-
-/* The following values denote the GMP version used during GHC build-time */
-#define GHC_GMP_VERSION_MJ @GhcGmpVerMj@
-#define GHC_GMP_VERSION_MI @GhcGmpVerMi@
-#define GHC_GMP_VERSION_PL @GhcGmpVerPl@
-#define GHC_GMP_VERSION \
- (@GhcGmpVerMj@ * 10000 + @GhcGmpVerMi@ * 100 + @GhcGmpVerPl@)
-
/* Whether GMP supports mpz_powm_sec */
#define HAVE_SECURE_POWM @HaveSecurePowm@
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/92404a2b08d67a79d939cc916c4ba3…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/92404a2b08d67a79d939cc916c4ba3…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 3 commits: compiler: add targetHasRTSWays function
by Marge Bot (@marge-bot) 07 Jan '26
by Marge Bot (@marge-bot) 07 Jan '26
07 Jan '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
69e0ab59 by Cheng Shao at 2026-01-06T19:37:56-05:00
compiler: add targetHasRTSWays function
This commit adds a `targetHasRTSWays` util function in
`GHC.Driver.Session` to query if the target RTS has a given Ways (e.g.
WayThreaded).
- - - - -
25a0ab94 by Cheng Shao at 2026-01-06T19:37:56-05:00
compiler: link on-demand external interpreter with threaded RTS
This commit makes the compiler link the on-demand external interpreter
program with threaded RTS if it is available in the target RTS ways.
This is a better default than the previous single-threaded RTS, and it
enables the external interpreter to benefit from parallelism when
deserializing CreateBCOs messages.
- - - - -
92404a2b by Cheng Shao at 2026-01-06T19:37:56-05:00
hadrian: link iserv with threaded RTS
This commit makes hadrian link iserv with threaded RTS if it's
available in the RTS ways. Also cleans up the iserv main C program
which can be replaced by the `-fkeep-cafs` link-time option.
- - - - -
8 changed files:
- compiler/GHC.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Runtime/Interpreter/C.hs
- compiler/GHC/Runtime/Interpreter/Init.hs
- hadrian/src/Packages.hs
- hadrian/src/Settings/Packages.hs
- − utils/iserv/cbits/iservmain.c
- utils/iserv/iserv.cabal.in
Changes:
=====================================
compiler/GHC.hs
=====================================
@@ -719,7 +719,7 @@ setTopSessionDynFlags dflags = do
{ interpCreateProcess = createIservProcessHook (hsc_hooks hsc_env)
}
- interp <- liftIO $ initInterpreter tmpfs logger platform finder_cache unit_env interp_opts
+ interp <- liftIO $ initInterpreter dflags tmpfs logger platform finder_cache unit_env interp_opts
modifySession $ \h -> hscSetFlags dflags
h{ hsc_IC = (hsc_IC h){ ic_dflags = dflags }
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -197,6 +197,8 @@ module GHC.Driver.Session (
-- * Compiler configuration suitable for display to the user
compilerInfo,
+ targetHasRTSWays,
+
wordAlignment,
setUnsafeGlobalDynFlags,
@@ -3635,6 +3637,15 @@ compilerInfo dflags
queryCmdMaybe p f = expandDirectories (query (maybe "" (prgPath . p) . f))
queryFlagsMaybe p f = query (maybe "" (unwords . map escapeArg . prgFlags . p) . f)
+-- | Query if the target RTS has the given 'Ways'. It's computed from
+-- the @"RTS ways"@ field in the settings file.
+targetHasRTSWays :: DynFlags -> Ways -> Bool
+targetHasRTSWays dflags ways
+ | Just ws <- lookup "RTS ways" $ compilerInfo dflags =
+ waysTag ways
+ `elem` words ws
+ | otherwise = panic "RTS ways not found in settings"
+
-- Note [Special unit-ids]
-- ~~~~~~~~~~~~~~~~~~~~~~~
-- Certain units are special to the compiler:
=====================================
compiler/GHC/Runtime/Interpreter/C.hs
=====================================
@@ -8,7 +8,9 @@ where
import GHC.Prelude
import GHC.Platform
+import GHC.Platform.Ways
import GHC.Data.FastString
+import GHC.Driver.Session
import GHC.Utils.Logger
import GHC.Utils.TmpFs
import GHC.Unit.Types
@@ -18,11 +20,10 @@ import GHC.Unit.State
import GHC.Utils.Panic.Plain
import GHC.Linker.Executable
import GHC.Linker.Config
-import GHC.Utils.CliOption
-- | Generate iserv program for the target
-generateIservC :: Logger -> TmpFs -> ExecutableLinkOpts -> UnitEnv -> IO FilePath
-generateIservC logger tmpfs opts unit_env = do
+generateIservC :: DynFlags -> Logger -> TmpFs -> ExecutableLinkOpts -> UnitEnv -> IO FilePath
+generateIservC dflags logger tmpfs opts unit_env = do
-- get the unit-id of the ghci package. We need this to load the
-- interpreter code.
let unit_state = ue_homeUnitState unit_env
@@ -60,6 +61,12 @@ generateIservC logger tmpfs opts unit_env = do
-- must retain CAFs for running interpreted code.
, leKeepCafs = True
+ -- link with -threaded if target has threaded RTS
+ , leWays =
+ let ways = leWays opts
+ ways' = addWay WayThreaded ways
+ in if targetHasRTSWays dflags ways' then ways' else ways
+
-- enable all rts options
, leRtsOptsEnabled = RtsOptsAll
=====================================
compiler/GHC/Runtime/Interpreter/Init.hs
=====================================
@@ -9,6 +9,7 @@ where
import GHC.Prelude
+import GHC.Driver.DynFlags
import GHC.Platform
import GHC.Platform.Ways
import GHC.Settings
@@ -57,14 +58,15 @@ data InterpOpts = InterpOpts
-- | Initialize code interpreter
initInterpreter
- :: TmpFs
+ :: DynFlags
+ -> TmpFs
-> Logger
-> Platform
-> FinderCache
-> UnitEnv
-> InterpOpts
-> IO (Maybe Interp)
-initInterpreter tmpfs logger platform finder_cache unit_env opts = do
+initInterpreter dflags tmpfs logger platform finder_cache unit_env opts = do
lookup_cache <- liftIO $ mkInterpSymbolCache
@@ -125,7 +127,7 @@ initInterpreter tmpfs logger platform finder_cache unit_env opts = do
dynamic = interpWays opts `hasWay` WayDyn
prog <- case interpProg opts of
-- build iserv program if none specified
- "" -> generateIservC logger tmpfs (interpExecutableLinkOpts opts) unit_env
+ "" -> generateIservC dflags logger tmpfs (interpExecutableLinkOpts opts) unit_env
_ -> pure (interpProg opts ++ flavour)
where
flavour
=====================================
hadrian/src/Packages.hs
=====================================
@@ -217,7 +217,7 @@ timeoutPath = "testsuite/timeout/install-inplace/bin/timeout" <.> exe
-- TODO: Can we extract this information from Cabal files?
-- | Some program packages should not be linked with Haskell main function.
nonHsMainPackage :: Package -> Bool
-nonHsMainPackage = (`elem` [hp2ps, iserv, unlit, ghciWrapper])
+nonHsMainPackage = (`elem` [hp2ps, unlit, ghciWrapper])
{-
=====================================
hadrian/src/Settings/Packages.hs
=====================================
@@ -41,6 +41,8 @@ packageArgs = do
libzstdLibraryDir <- getSetting LibZstdLibDir
stageVersion <- readVersion <$> (expr $ ghcVersionStage stage)
+ rtsWays <- getRtsWays
+
mconcat
--------------------------------- base ---------------------------------
[ package base ? mconcat
@@ -185,11 +187,15 @@ packageArgs = do
--
-- The Solaris linker does not support --export-dynamic option. It also
-- does not need it since it exports all dynamic symbols by default
- , package iserv
- ? expr isElfTarget
+ , package iserv ? mconcat [
+ expr isElfTarget
? notM (expr $ anyTargetOs [OSFreeBSD, OSSolaris2])? mconcat
[ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ]
+ -- Link iserv with -threaded if possible
+ , builder (Cabal Flags) ? any (wayUnit Threaded) rtsWays `cabalFlag` "threaded"
+ ]
+
-------------------------------- haddock -------------------------------
, package haddockApi ?
builder (Cabal Flags) ? arg "in-ghc-tree"
=====================================
utils/iserv/cbits/iservmain.c deleted
=====================================
@@ -1,18 +0,0 @@
-#include <ghcversion.h>
-# include <rts/PosixSource.h>
-#include <Rts.h>
-
-#include <HsFFI.h>
-
-int main (int argc, char *argv[])
-{
- RtsConfig conf = defaultRtsConfig;
-
- // We never know what symbols GHC will look up in the future, so
- // we must retain CAFs for running interpreted code.
- conf.keep_cafs = 1;
-
- conf.rts_opts_enabled = RtsOptsAll;
- extern StgClosure ZCMain_main_closure;
- hs_main(argc, argv, &ZCMain_main_closure, conf);
-}
=====================================
utils/iserv/iserv.cabal.in
=====================================
@@ -23,11 +23,17 @@ Category: Development
build-type: Simple
cabal-version: >=1.10
+Flag threaded
+ Description: Link the iserv executable against the threaded RTS
+ Default: True
+ Manual: True
+
Executable iserv
Default-Language: Haskell2010
- ghc-options: -no-hs-main
+ ghc-options: -fkeep-cafs -rtsopts
+ if flag(threaded)
+ ghc-options: -threaded
Main-Is: Main.hs
- C-Sources: cbits/iservmain.c
Hs-Source-Dirs: src
include-dirs: .
Build-Depends:
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3d6aba778f7628deef0141d9e8effc…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3d6aba778f7628deef0141d9e8effc…
You're receiving this email because of your account on gitlab.haskell.org.
1
0