[Git][ghc/ghc][wip/9.14.2-backports] 39 commits: fixup! driver: don't expect nodes to exist when checking paths between them
by Zubin (@wz1000) 10 Jun '26
by Zubin (@wz1000) 10 Jun '26
10 Jun '26
Zubin pushed to branch wip/9.14.2-backports at Glasgow Haskell Compiler / GHC
Commits:
e92adeb3 by Zubin Duggal at 2026-06-01T13:26:55+05:30
fixup! driver: don't expect nodes to exist when checking paths between them
- - - - -
88b8012b by Zubin Duggal at 2026-06-01T13:27:13+05:30
fixup! Add optional `SrcLoc` to `StackAnnotation` class
- - - - -
5c2c77cb by Zubin Duggal at 2026-06-01T13:27:37+05:30
fixup! Evaluate backtraces for "error" exceptions at the moment they are thrown
- - - - -
782e68f0 by Zubin Duggal at 2026-06-09T11:56:45+05:30
fixup! Introduce `-fimport-loaded-targets` GHCi flag
- - - - -
e71ce768 by Zubin Duggal at 2026-06-09T12:04:40+05:30
fixup! Avoid infinite loop in deep subsumption
- - - - -
27851522 by Zubin Duggal at 2026-06-09T12:10:39+05:30
fixup! Use home unit package db stacks in GHCi prompt and session unit
- - - - -
a94fa7cb by sheaf at 2026-06-09T13:58:17+05:30
Improve incomplete record selector warnings
This commit stops GHC from emitting spurious incomplete record selector
warnings for bare selectors/projections such as .fld
There are two places we currently emit incomplete record selector
warnings:
1. In the desugarer, when we see a record selector or an occurrence
of 'getField'. Here, we can use pattern matching information to
ensure we don't give false positives.
2. In the typechecker, which might sometimes give false positives but
can emit warnings in cases that the pattern match checker would
otherwise miss.
This is explained in Note [Detecting incomplete record selectors]
in GHC.HsToCore.Pmc.
Now, we obviously don't want to emit the same error twice, and generally
we prefer (1), as those messages contain fewer false positives. So we
suppress (2) when we are sure we are going to emit (1); the logic for
doing so is in GHC.Tc.Instance.Class.warnIncompleteRecSel,
and works by looking at the CtOrigin.
Now, the issue was that this logic handled explicit record selectors as
well as overloaded record field selectors such as "x.r" (which turns
into a simple GetFieldOrigin CtOrigin), but it didn't properly handle
record projectors like ".fld" or ".fld1.fld2" (which result in other
CtOrigins such as 'RecordFieldProjectionOrigin').
To solve this problem, we re-use the 'isHasFieldOrigin' introduced in
fbdc623a (slightly adjusted).
On the way, we also had to update the desugarer with special handling
for the 'ExpandedThingTc' case in 'ds_app', to make sure that
'ds_app_var' sees all the type arguments to 'getField' in order for it
to indeed emit warnings like in (1).
Fixes #26686
(cherry picked from commit 52c3e6ba9f03d19a4fa85aee6a4c417b538160f7)
- - - - -
aa2b14f6 by sheaf at 2026-06-09T15:09:29+05:30
Only use active rules when simplifying rule RHSs
When we are simplifying the RHS of a rule, we make sure to only apply
rewrites from rules that are active throughout the original rule's
range of active phases.
For example, if a rule is always active, we only fire rules that are
themselves always active when simplifying the RHS. Ditto for inline
activations.
This is achieved by setting the simplifier phase to a range of phases,
using the new SimplPhaseRange constructor. Then:
1. When simplifying the RHS of a rule, or of a stable unfolding,
we set the simplifier phase to a range of phases, computed from
the activation of the RULE/unfolding activation, using the
function 'phaseFromActivation'.
The details are explained in Note [What is active in the RHS of a RULE?]
in GHC.Core.Opt.Simplify.Utils.
2. The activation check for other rules and inlinings is then:
does the activation of the other rule/inlining cover the whole
phase range set in sm_phase? This continues to use the 'isActive'
function, which now accounts for phase ranges.
On the way, this commit also moves the exact-print SourceText annotation
from the Activation datatype to the ActivationAnn type. This keeps the
main Activation datatype free of any extra cruft.
Fixes #26323
(cherry picked from commit 2da84b7a83f723dc6531cdad5ef3c7e624fda2fe)
- - - - -
98b91517 by Simon Peyton Jones at 2026-06-09T15:15:26+05:30
Include current phase in the range for rule/unfoldings
This MR fixes a bad loop in the compiler: #26826.
The fix is to add (WAR2) to
Note [What is active in the RHS of a RULE or unfolding?]
in GHC.Core.Opt.Simplify.Utils
(cherry picked from commit 269c4087979ff9d675cd1a59076157211d1c555d)
- - - - -
88eec6e6 by Zubin Duggal at 2026-06-09T15:20:13+05:30
fixup! Only use active rules when simplifying rule RHSs
- - - - -
127626c2 by Zubin Duggal at 2026-06-09T16:01:02+05:30
fixup! Include current phase in the range for rule/unfoldings
- - - - -
1f7b7eb6 by Zubin Duggal at 2026-06-09T16:44:23+05:30
fixup! Improve incomplete record selector warnings
- - - - -
dce69b47 by Simon Peyton Jones at 2026-06-09T18:13:37+05:30
QuickLook's tcInstFun should make instantiation variables directly
tcInstFun must make "instantiation variables", not regular
unification variables, when instantiating function types. That was
previously implemented by a hack: set the /ambient/ level to QLInstTyVar.
But the hack finally bit me, when I was refactoring WhatUnifications.
And it was always wrong: see the now-expunged (TCAPP2) note.
This commit does it right, by making tcInstFun call its own
instantiation functions. That entails a small bit of duplication,
but the result is much, much cleaner.
(cherry picked from commit 231adc30be97ae51650aff7a40e00e05f4876af6)
- - - - -
f5bb4c7a by Zubin Duggal at 2026-06-09T18:15:31+05:30
Revert "docs: note #26543 in known bugs"
This reverts commit ebc6d49bd309bb843bc58e8c712ade767818e9ac.
Obsolete now that the fix from MR 14474 (commit 231adc30) is backported.
- - - - -
8bb2dbd9 by Luite Stegeman at 2026-06-09T18:50:23+05:30
Fix assert in Interpreter.c
If we skip exactly the number of words on the stack we end up on
the first word in the next chunk.
(cherry picked from commit 404b71c181bde4256565307d495cd2fa124d02f1)
- - - - -
d3d880e8 by Ben Gamari at 2026-06-10T10:05:38+05:30
rts/Interpreter: Factor out ctoi tuple info tables into data
Instead of a massive case let's put this into data which we can reuse
elsewhere.
(cherry picked from commit d2b89603425b6d08df199deb7b84cfdbd711869a)
- - - - -
983a67a7 by Luite Stegeman at 2026-06-10T10:06:23+05:30
Support arbitrary size unboxed tuples in bytecode
This stores the size (number of words on the stack) of the next
expected tuple in the TSO, ctoi_spill_size field, eliminating
the need of stg_ctoi_tN frames for each size.
Note: On 32 bit platform there is still a bytecode tuple size
limit of 255 words on the stack.
Fixes #26946
(cherry picked from commit a85bd503a480cfa31f5afa09eb38f56c85c237de)
- - - - -
55f8acd1 by Luite Stegeman at 2026-06-10T10:06:51+05:30
Add specialized frames for small tuples
Small tuples are now returned more efficiently to the interpreter.
They use one less word of stack space and don't need manipulation
of the TSO anymore.
(cherry picked from commit e2209031734770a51f04883e5b538b562449cba1)
- - - - -
89bffe08 by Luite Stegeman at 2026-06-10T10:07:19+05:30
rts: add a few missing i386 relocations in the rts linker
(cherry picked from commit 04d143c02e82e9ca03eb75849959d369d07fb81a)
- - - - -
868b341c by Luite Stegeman at 2026-06-10T10:08:50+05:30
CodeOutput: Fix finalizers on multiple platforms
- ELF platforms: emit .fini_array section
- wasm32/Darwin: emit initializer with __cxa_atexit call
- Windows: use -Wl,--whole-archive to prevent dropping finalizer symbols
- rts linker: fix crash/assertion failure unloading objects with finalizers
fixes #27072
(cherry picked from commit 014087e7a5753687161a24a1b2bc55c7bf7273fd)
- - - - -
ddc0fb98 by Ben Gamari at 2026-06-10T11:00:27+05:30
ghc-internal: Move STM utilities out of GHC.Internal.Conc.Sync
This is necessary to avoid an import cycle on Windows when importing
`GHC.Internal.Exception.Context` in `GHC.Internal.Conc.Sync`.
On the road to address #25365.
(cherry picked from commit 039bac4cf9590a6a09aa302b99fa2a0993cc0a32)
- - - - -
5cb91d72 by Ben Gamari at 2026-06-10T11:03:13+05:30
base: Capture backtrace from throwSTM
Implements core-libraries-committee#297.
Fixes #25365.
(cherry picked from commit 8c389e8ce9a536da8e396a1df8c726583d0bcc14)
- - - - -
54353c41 by Ben Gamari at 2026-06-10T11:04:10+05:30
base: Annotate rethrown exceptions in catchSTM with WhileHandling
Implements core-libraries-committee#298
(cherry picked from commit e1ce1fc3ad38d192cd3b6a38cb42051f4b115e95)
- - - - -
10a2589e by fendor at 2026-06-10T11:05:50+05:30
Hide implementation details from base exception stack traces
Ensure we hide the implementation details of the exception throwing mechanisms:
* `undefined`
* `throwSTM`
* `throw`
* `throwIO`
* `error`
The `HasCallStackBacktrace` should always have a length of exactly 1,
not showing internal implementation details in the stack trace, as these
are vastly distracting to end users.
CLC proposal [#387](https://github.com/haskell/core-libraries-committee/issues/387)
(cherry picked from commit 016f79d54d482de01dd396bd9bf79f958d7c4922)
- - - - -
659c4bcd by Zubin Duggal at 2026-06-10T11:54:28+05:30
fixup! Hide implementation details from base exception stack traces
fixup\! Hide implementation details from base exception stack traces
Two test-output updates required after the \!15395 chain (rows #143-146)
lands:
- T26806b.stderr: the 2 internal-frame lines added by the workaround
fixup 88b8012b335 (collectExceptionAnnotation + toExceptionWithBacktrace)
are no longer produced now that withFrozenCallStack wraps the throw
call. Restore the original 10-line stderr matching eb4d84a8d94's
initial expected output.
- ann_frame005.stdout: the throwSTM section's IPE backtrace entries
acquire the long-form 'called at ann_frame005.hs:N:M in main:Main'
suffix because the SrcLoc-on-StringAnnotation cherry-pick eb4d84a8d94
is on the branch but the master \!15395 baseline did not yet have it.
The actual line/col numbers (52:3 and 27:5) are determined by the
ann_frame005.hs source structure on the branch.
- - - - -
1e6624c3 by sheaf at 2026-06-10T12:06:53+05:30
Relax acceptance threshold for T10421
As seen in #27289, the 1% acceptance threshold for this text was
overly narrow, resulting in spurious test failures. This commit widens
the acceptance threshold to 2%. Fixes #27289.
(cherry picked from commit b0233814d63c2802a521dfc7dae08b1ecf494c50)
- - - - -
d5cae504 by mangoiv at 2026-06-10T12:08:15+05:30
libraries/process: bump submodule to v1.6.29.0
This submodule bump resolves a segfault on macos 15.
Fixes #27144
(cherry picked from commit 277a3687c4b729e4d1ff4d4503a5673deba5eda7)
- - - - -
2a001e72 by mangoiv at 2026-06-10T12:09:25+05:30
libraries/unix: in submodule, don't pick branch 2.7
The 2.7 branch is outdated and the module has been advanced far beyond
it anyway, so remove that line.
(cherry picked from commit 6779bb0c2d2784182465337ba5e94b7cd8810f2b)
- - - - -
831a8e7d by Luite Stegeman at 2026-06-10T12:09:55+05:30
Fixes for black holes
- suspend duplicate work for eager black holes
- detect eager black holes in checkBlockingQueues
- don't overwrite existing black holes even if they're not
in an eager blackhole frame
- don't deadlock on self when thunk is already blackholed
Fixes #26936
(cherry picked from commit 63ce5770da1712f0da54665d8755772bf38ba51e)
- - - - -
3d16a3c1 by Tom McLaughlin at 2026-06-10T12:10:18+05:30
Event/Windows.hsc: rethrow exceptions in overlapped IO
This prevents the WinIO manager from swallowing exceptions in overlapped IO. It
was added to make WinIO support possible in the `network` library. See
https://gitlab.haskell.org/ghc/ghc/-/issues/27283.
We also bump __IO_MANAGER_WINIO__ to 2 so libraries can gate on this using CPP.
(cherry picked from commit 037a80dc65d3975adf4a35d46876850e644bc80e)
- - - - -
2d4941cd by Simon Peyton Jones at 2026-06-10T12:11:10+05:30
Add a deprecation warning for static forms
The accepted
GHC proposal 732: Simplify static forms
https://github.com/ghc-proposals/ghc-proposals/pull/732
needs a deprecation warning added to GHC 9.14, to warn about static
forms that mention nested free variables; see #26718.
This MR adds that warning, with test T26718 to check it.
There is no flag to switch the warning off.
(cherry picked from commit 6b7d6287c6ff4fd1b0d3aa2abfdaf73d43c4a9a0)
- - - - -
ad9f2143 by Simon Peyton Jones at 2026-06-10T12:13:17+05:30
Trim the continuation in mkDupableContWithDmds
When there are no remaining argument demands, it means the application
is bottoming. In this case, we can trim the continuation to avoid the
panic that was observed in #27261.
See Note [Trimming the continuation for bottoming functions] in
GHC.Core.Opt.Simplify.Iteration.
(cherry picked from commit 4a645683ee0bd4421a88cd6ec49b40c6046b041d)
- - - - -
d9745566 by Zubin Duggal at 2026-06-10T12:25:25+05:30
Update to semaphore-compat 2.0.0 using v2 of the protocol
On Linux and other POSIX platforms, GHC's -jsem jobserver client now
speaks v2 of the semaphore-compat protocol, which uses Unix domain
sockets in place of POSIX named semaphores. This avoids the libc-ABI
issues that affected the old implementation. Windows is unaffected
and continues to use the v1 protocol (Win32 named semaphores); its
reported protocol version remains v1.
When GHC receives a -jsem name whose protocol version it does not
support, it emits a -Wsemaphore-version-mismatch warning and falls
back to -j<N> rather than crashing. ghc --info exposes the supported
version in a new "Semaphore version" entry so cabal-install can detect
a mismatch before invoking GHC.
Users on a cabal-install that predates the v2 update will continue to
build successfully on Linux/POSIX, but will lose the cross-process
-jsem coordination and fall back to -j<N> per GHC invocation. Users
must upgrade to a cabal-install that supports protocol v2 to recover
full parallelism.
Also fix a leak in cleanupSem (#27253): cleanupSem used to snapshot
heldTokens and release them before killing the loop, while the loop's
in-flight acquire/release children could still be mutating it.
Cleanup now runs inside the loop's own exit handler, after draining
the active child via a new activeChild TVar, so the snapshot has no
concurrent mutator.
See also:
- GHC proposal amendment: https://github.com/ghc-proposals/ghc-proposals/pull/673
- cabal-install patch: https://github.com/haskell/cabal/pull/11628
- semaphore-compat MR: https://gitlab.haskell.org/ghc/semaphore-compat/-/merge_requests/8
Bump semaphore-compat submodule to 2.0.0
Fixes #25087 and #27253
(cherry picked from commit 8db331a381ae47ad9ad5c8613f5d3e2588d5dd55)
- - - - -
824704e8 by Zubin Duggal at 2026-06-10T12:35:51+05:30
Revert "Trim the continuation in mkDupableContWithDmds"
This reverts commit ad9f21431c61ccc3ddebd831286f895c46aa4f1c.
- - - - -
c793858d by mangoiv at 2026-06-10T12:45:08+05:30
Trim the continuation in mkDupableContWithDmds
When there are no remaining argument demands, it means the application
is bottoming. In this case, we can trim the continuation to avoid the
panic that was observed in #27261.
See Note [Trimming the continuation for bottoming functions] in
GHC.Core.Opt.Simplify.Iteration.
This patch was rewritten to avoid pulling in a refactor.
The original patch is included in master as 4a645683
(cherry picked from commit 53f74985860b35a879bfd0dc642e7fcafffcf5e4)
- - - - -
a7b1120c by Zubin Duggal at 2026-06-10T13:20:46+05:30
fixup! Trim the continuation in mkDupableContWithDmds
fixup\! Trim the continuation in mkDupableContWithDmds
Remove unused 'castBottomExpr' from the 'GHC.Core.Make' import in
Iteration.hs. The only call site (in the Bottoming applications case)
was replaced by 'mkBottomCont' by the previous commit; the import was
left behind by the conflict resolution, which mistakenly believed there
was a second call site.
- - - - -
6798519c by mangoiv at 2026-06-10T14:16:22+05:30
profiling: partial backport of 2dadf3b0 to fix #27121
This backports fix and test for #27121 from 2dadf3b0 since the entirety
of the patch is not backportable without also backporting two larger
refactorings.
(cherry picked from commit 0ccecfc5b5a118c2c850f876709c21162d35d972)
- - - - -
f8369bfd by Teo Camarasu at 2026-06-10T14:26:55+05:30
Add explicit export list to GHC.Num
Let's make clear what this module exports to allow us to easily deprecate and remove some of these in the future. Resolves https://gitlab.haskell.org/ghc/ghc/-/issues/26625
(cherry picked from commit b14bdd59202e0c32df8e5cc1923677f59c8f16e7)
- - - - -
7ba88e0d by Teo Camarasu at 2026-06-10T14:27:27+05:30
base: deprecate GHC internals in GHC.Num
Implements CLC proposal: https://github.com/haskell/core-libraries-committee/issues/360
(cherry picked from commit 75a9053d26183e71b48de4c603b04af2fa4a732d)
- - - - -
177 changed files:
- .gitmodules
- + changelog.d/bump-process
- + changelog.d/fix-blackhole-handling
- + changelog.d/fix-finalizers-27072
- + changelog.d/jobserver-leak-fix
- + changelog.d/semaphore-v2
- + changelog.d/windows-rethrow-overlapped-exception
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Pipeline/Types.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Inline.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/Config/Core/Opt/Simplify.hs
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Errors/Types.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/MakeAction.hs
- compiler/GHC/Driver/MakeSem.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Pmc.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Linker/Static.hs
- compiler/GHC/Parser.y
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/GHC/Tc/Deriv/Generics.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/ForeignStubs.hs
- compiler/GHC/Types/Hint.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Utils/Binary.hs
- docs/users_guide/bugs.rst
- docs/users_guide/using-warnings.rst
- docs/users_guide/using.rst
- hadrian/src/Flavour.hs
- hie.yaml
- libraries/base/src/GHC/Conc.hs
- libraries/base/src/GHC/Conc/Sync.hs
- libraries/base/src/GHC/Num.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Conc/IO.hs
- libraries/ghc-internal/src/GHC/Internal/Conc/POSIX.hs
- libraries/ghc-internal/src/GHC/Internal/Conc/Sync.hs
- libraries/ghc-internal/src/GHC/Internal/Conc/Sync.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Conc/Windows.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Thread.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/Thread.hs
- libraries/ghc-internal/src/GHC/Internal/Exception.hs
- + libraries/ghc-internal/src/GHC/Internal/STM.hs
- + libraries/ghc-internal/tests/backtraces/T15395.hs
- + libraries/ghc-internal/tests/backtraces/T15395.stdout
- libraries/ghc-internal/tests/backtraces/all.T
- libraries/ghc-internal/tests/stack-annotation/ann_frame005.stdout
- libraries/process
- libraries/semaphore-compat
- rts/Apply.cmm
- rts/Continuation.c
- rts/ContinuationOps.cmm
- rts/Interpreter.c
- rts/Linker.c
- rts/LinkerInternals.h
- rts/Messages.c
- rts/Printer.c
- rts/RaiseAsync.c
- rts/RtsSymbols.c
- rts/Schedule.c
- rts/StgMiscClosures.cmm
- rts/ThreadPaused.c
- rts/Threads.c
- rts/Threads.h
- rts/Updates.h
- rts/include/rts/Bytecodes.h
- rts/include/rts/storage/ClosureMacros.h
- rts/include/rts/storage/TSO.h
- rts/include/stg/MiscClosures.h
- rts/linker/Elf.c
- testsuite/mk/boilerplate.mk
- testsuite/tests/arrows/should_compile/T21301.stderr
- + testsuite/tests/bytecode/tuplestress/ByteCode.hs
- + testsuite/tests/bytecode/tuplestress/Common.hs-incl
- + testsuite/tests/bytecode/tuplestress/Obj.hs
- + testsuite/tests/bytecode/tuplestress/TupleStress.hs
- + testsuite/tests/bytecode/tuplestress/TupleStress.stdout
- + testsuite/tests/bytecode/tuplestress/all.T
- + testsuite/tests/codeGen/should_run/T27072d.hs
- + testsuite/tests/codeGen/should_run/T27072d.stdout
- + testsuite/tests/codeGen/should_run/T27072d_c.c
- + testsuite/tests/codeGen/should_run/T27072d_check.c
- + testsuite/tests/codeGen/should_run/T27072w.hs
- + testsuite/tests/codeGen/should_run/T27072w.stdout
- + testsuite/tests/codeGen/should_run/T27072w_c.c
- testsuite/tests/codeGen/should_run/all.T
- testsuite/tests/deSugar/should_fail/DsStrictFail.stderr
- testsuite/tests/deSugar/should_run/T20024.stderr
- testsuite/tests/deSugar/should_run/dsrun005.stderr
- testsuite/tests/deSugar/should_run/dsrun007.stderr
- testsuite/tests/deSugar/should_run/dsrun008.stderr
- testsuite/tests/deriving/should_run/T9576.stderr
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/ghci/prog-mhu005/prog-mhu005d.stdout
- testsuite/tests/ghci/prog-mhu005/prog-mhu005e.stdout
- testsuite/tests/ghci/prog-mhu005/prog-mhu005g.stdout
- testsuite/tests/ghci/prog022/ghci.prog022e.stdout
- testsuite/tests/ghci/prog022/ghci.prog022f.stdout
- testsuite/tests/ghci/scripts/Defer02.stderr
- testsuite/tests/ghci/scripts/T15325.stderr
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- + testsuite/tests/overloadedrecflds/should_compile/T26686.hs
- + testsuite/tests/overloadedrecflds/should_compile/T26686.stderr
- testsuite/tests/overloadedrecflds/should_compile/all.T
- testsuite/tests/patsyn/should_run/ghci.stderr
- testsuite/tests/perf/compiler/T4007.stdout
- testsuite/tests/perf/compiler/all.T
- + testsuite/tests/profiling/should_compile/T27121.hs
- + testsuite/tests/profiling/should_compile/T27121_aux.hs
- testsuite/tests/profiling/should_compile/all.T
- testsuite/tests/quotes/LiftErrMsgDefer.stderr
- + testsuite/tests/rts/linker/T27072/Lib.c
- + testsuite/tests/rts/linker/T27072/Makefile
- + testsuite/tests/rts/linker/T27072/T27072.stdout
- + testsuite/tests/rts/linker/T27072/all.T
- + testsuite/tests/rts/linker/T27072/main.c
- testsuite/tests/safeHaskell/safeLanguage/SafeLang15.stderr
- testsuite/tests/simplCore/should_compile/T15056.stderr
- testsuite/tests/simplCore/should_compile/T15445.stderr
- + testsuite/tests/simplCore/should_compile/T26323b.hs
- + testsuite/tests/simplCore/should_compile/T26826.hs
- + testsuite/tests/simplCore/should_compile/T27261.hs
- + testsuite/tests/simplCore/should_compile/T27261_aux.hs
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/simplCore/should_run/T26323.hs
- + testsuite/tests/simplCore/should_run/T26323.stdout
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/th/T26568.stderr
- testsuite/tests/th/all.T
- testsuite/tests/type-data/should_run/T22332a.stderr
- + testsuite/tests/typecheck/should_compile/T26718.hs
- + testsuite/tests/typecheck/should_compile/T26718.stderr
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T26823.stderr
- testsuite/tests/typecheck/should_run/T10284.stderr
- testsuite/tests/typecheck/should_run/T13838.stderr
- testsuite/tests/typecheck/should_run/T9497a-run.stderr
- testsuite/tests/typecheck/should_run/T9497b-run.stderr
- testsuite/tests/typecheck/should_run/T9497c-run.stderr
- testsuite/tests/unsatisfiable/T23816.stderr
- testsuite/tests/unsatisfiable/UnsatDefer.stderr
- utils/check-exact/ExactPrint.hs
- utils/deriveConstants/Main.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aec5364bc2a3b1db0cff6c6842990e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aec5364bc2a3b1db0cff6c6842990e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] testsuite: Add regression test for #4081
by Marge Bot (@marge-bot) 10 Jun '26
by Marge Bot (@marge-bot) 10 Jun '26
10 Jun '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
d311c4f1 by Simon Jakobi at 2026-06-10T05:09:32-04:00
testsuite: Add regression test for #4081
Check that a strict constructor field is unboxed once outside an
enclosing loop, not re-inspected each iteration (the float-out
case-floating from 9cb20b488). Uses simonpj's `data T a = T !a` example
from the ticket; T4081.stderr captures the expected Core.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
3 changed files:
- + testsuite/tests/simplCore/should_compile/T4081.hs
- + testsuite/tests/simplCore/should_compile/T4081.stderr
- testsuite/tests/simplCore/should_compile/all.T
Changes:
=====================================
testsuite/tests/simplCore/should_compile/T4081.hs
=====================================
@@ -0,0 +1,11 @@
+-- #4081: the strict field of T should be unboxed once, outside the blah loop,
+-- not re-inspected on every iteration. See the expected Core in T4081.stderr.
+
+module T4081 (foo) where
+
+data T a = T !a
+
+foo :: T Int -> Int -> Int
+foo (T x) y = let blah 0 = 0
+ blah n = x + blah (n-1)
+ in blah y
=====================================
testsuite/tests/simplCore/should_compile/T4081.stderr
=====================================
@@ -0,0 +1,29 @@
+
+==================== Tidy Core ====================
+Result size of Tidy Core
+ = {terms: 40, types: 25, coercions: 0, joins: 0/1}
+
+$wfoo
+ = \ ww ww1 ->
+ letrec {
+ $wblah
+ = \ ww2 ->
+ case ww2 of ds {
+ __DEFAULT ->
+ case $wblah (-# ds 1#) of ww3 { __DEFAULT -> +# ww ww3 };
+ 0# -> 0#
+ }; } in
+ $wblah ww1
+
+foo
+ = \ ds y ->
+ case ds of { T ww ->
+ case ww of { I# ww1 ->
+ case y of { I# ww2 ->
+ case $wfoo ww1 ww2 of ww3 { __DEFAULT -> I# ww3 }
+ }
+ }
+ }
+
+
+
=====================================
testsuite/tests/simplCore/should_compile/all.T
=====================================
@@ -601,4 +601,6 @@ test('T25718a', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress
test('T25718b', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-all -dno-typeable-binds'])
test('T25718c', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-all -dno-typeable-binds'])
test('T19166', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-all -dno-typeable-binds'])
+# #4081: the strict field of T should be unboxed once, outside the loop.
+test('T4081', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-all -dno-typeable-binds'])
test('T27261', [extra_files(['T27261_aux.hs'])], multimod_compile, ['T27261', '-v0 -O'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d311c4f10bf5b32a979be3ac7e7ab1d…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d311c4f10bf5b32a979be3ac7e7ab1d…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] Don't drop ticks around variables of type `IO ()`
by Marge Bot (@marge-bot) 10 Jun '26
by Marge Bot (@marge-bot) 10 Jun '26
10 Jun '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
ce01ccb6 by sheaf at 2026-06-10T05:08:48-04:00
Don't drop ticks around variables of type `IO ()`
GHC.Core.Utils.mkTick is responsible for placing a tick on a Core
expression. It contains logic for dropping SCCs (non-counting profiling
ticks) around non-function variables, as such variables cannot
meaningfully contribute to profiles. However, the logic for what counts
as a function was incorrect: it used `isFunTy` which returns 'False' for
types such as 'IO ()' where the function arrow is hidden under a
newtype.
We now use 'mightBeFunTy' instead of 'isFunTy'. This ensures we don't
drop ticks in cases we aren't sure.
On the way, we improve the documentation of 'isFunTy', 'isPiTy' and
'mightBeFunTy', and update the latter's implementation to consistently
handle unary classes.
Fixes #27225
-------------------------
Metric Decrease:
T5642
-------------------------
- - - - -
14 changed files:
- + changelog.d/T27225
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Types/RepType.hs
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/profiling/should_run/T27225.hs
- + testsuite/tests/profiling/should_run/T27225.stdout
- + testsuite/tests/profiling/should_run/T27225b.hs
- + testsuite/tests/profiling/should_run/T27225b.stdout
- testsuite/tests/profiling/should_run/all.T
- testsuite/tests/profiling/should_run/caller-cc/CallerCc1.prof.sample
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/profiling/should_run/scc001.prof.sample
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ce01ccb625514a09e76aded549691da…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ce01ccb625514a09e76aded549691da…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/romes/hadrian-cross-stage2-rebase_SVEN_FINAL] 16 commits: testsuite: detect fast bignum via ghc-internal, not removed ghc-bignum
by Sven Tennie (@supersven) 10 Jun '26
by Sven Tennie (@supersven) 10 Jun '26
10 Jun '26
Sven Tennie pushed to branch wip/romes/hadrian-cross-stage2-rebase_SVEN_FINAL at Glasgow Haskell Compiler / GHC
Commits:
2f3cc9ff by Simon Jakobi at 2026-06-08T07:55:49-04:00
testsuite: detect fast bignum via ghc-internal, not removed ghc-bignum
The ghc-bignum package was merged into ghc-internal, so the BIGNUM_GMP
probe in test.mk ran `ghc-pkg field ghc-bignum exposed-modules`, which
fails with "cannot find package ghc-bignum". That error went to stderr
and leaked into the captured stderr of every makefile_test, causing
spurious [bad stderr] failures across the suite. The probe also silently
returned empty, so config.have_fast_bignum was wrongly False even on GMP
builds.
Probe ghc-internal's extra-libraries for the gmp library instead: the
GMP backend module is an other-module (not exposed), but GMP_LIBS adds
gmp to extra-libraries only on a GMP build, so this distinguishes the
backends. Redirect stderr to keep any future missing-package error off
the harness's stderr.
This also removes a stale comment as per suggestion from hsyl20.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
eb3bf6e7 by Alan Zimmerman at 2026-06-08T07:56:32-04:00
EPA: Rename Transform.anchorEof to addModuleCommentOrigDeltas
This now matches what it actually does.
- - - - -
498bb21a by David Eichmann at 2026-06-09T18:02:39-04:00
Hadrian: avoid response files when command line is short enough
This replaces the logic of always using response files on Windows.
With the new condition based on command line lenght, reponse files
can be avoided in many more cases (on windows).
Now that response files are only used in a small number of cases,
response files are always kept and the -r / --keep-response-files
command line options have been removed
The response file paths are nolonger randomized. They are placed in the
`_build/rsp` directory. This ensures they are ignored by git and we
that Hadrian reuses response file paths when rebuilding rather than
leaving stale response files around.
Update user guide putting response files in its own section
- - - - -
87f510a5 by Simon Hengel at 2026-06-09T18:03:25-04:00
Don't use non-breaking spaces
- - - - -
41a19379 by David Eichmann at 2026-06-09T18:04:11-04:00
Hadrian: remove unused wrapper scripts from windows bindist
These wrapper scripts are only installed on non-relocatable builds
which are not generally supported on windows.
- - - - -
5e1f97fd by Matthew Pickering at 2026-06-10T06:19:52+02:00
Add missing req_interp modifier to T18441fail3 and T18441fail19
These tests require the interpreter but they were failing in a different
way with the javascript backend because the interpreter was disabled and
stderr is ignored by the test.
- - - - -
913cb046 by Matthew Pickering at 2026-06-10T06:19:52+02:00
hadrian: Fill in more of the default.host toolchain file
When you are building a cross compiler this file will be used to build
stage1 and it's libraries, so we need enough information here to work
accurately. There is still more work to be done (see for example, word
size is still fixed).
- - - - -
b2c99f83 by Matthew Pickering at 2026-06-10T06:19:52+02:00
hadrian: Disable docs when cross compiling
Before there were a variety of ad-hoc places where doc building was
disabled when cross compiling.
* Some CI jobs sets --docs=none in gen_ci.hs
* Some CI jobs set --docs=none in .gitlab/ci.sh
* There was some logic in hadrian to not need the ["docs"] target when
making a bindist.
Now the situation is simple:
* If you are cross compiling then defaultDocsTargets is empty by
default.
In theory, there is no reason why we can't build documentation for cross
compiler bindists, but this is left to future work to generalise the
documentation building rules to allow this (#24289)
- - - - -
4e6a75dc by Matthew Pickering at 2026-06-10T06:36:33+02:00
hadrian: Build stage 2 cross compilers
* Most of hadrian is abstracted over the stage in order to remove the
assumption that the target of all stages is the same platform. This
allows the RTS to be built for two different targets for example.
* Abstracts the bindist creation logic to allow building either normal
or cross bindists. Normal bindists use stage 1 libraries and a stage 2
compiler. Cross bindists use stage 2 libararies and a stage 2
compiler.
* hadrian: Make binary-dist-dir the default build target. This allows us
to have the logic in one place about which libraries/stages to build
with cross compilers. Fixes #24192
New hadrian target:
* `binary-dist-dir-cross`: Build a cross compiler bindist (compiler =
stage 1, libraries = stage 2)
This commit also contains various changes to make stage2 compilers
feasible.
-------------------------
Metric Decrease:
LinkableUsage02
ManyAlternatives
ManyConstructors
MultiComponentModulesRecomp
MultiLayerModulesRecomp
RecordUpdPerf
T10421
T12150
T12227
T12425
T12707
T13035
T13379
T13820
T15703
T16577
T18140
T18282
T18698a
T18698b
T18923
T1969
T20049
T21839c
T3294
T4801
T5030
T5321FD
T5321Fun
T5631
T5642
T6048
T783
T9020
T9198
T9233
T9630
T9872d
T9961
parsing001
Metric Increase:
T26989
hard_hole_fits
-------------------------
Co-authored-by: Sven Tennie <sven.tennie(a)gmail.com>
- - - - -
7c7d8a25 by Matthew Pickering at 2026-06-10T06:36:33+02:00
ci: Test cross bindists
We remove the special logic for testing in-tree cross
compilers and instead test cross compiler bindists, like we do for all
other platforms.
- - - - -
374b8625 by Matthew Pickering at 2026-06-10T06:36:33+02:00
ci: Introduce CROSS_STAGE variable
In preparation for building and testing stage3 bindists we introduce the
CROSS_STAGE variable which is used by a CI job to determine what kind of
bindist the CI job should produce.
At the moment we are only using CROSS_STAGE=2 but in the future we will
have some jobs which set CROSS_STAGE=3 to produce native bindists for a
target, but produced by a cross compiler, which can be tested on by
another CI job on the native platform.
CROSS_STAGE=2: Build a normal cross compiler bindist
CROSS_STAGE=3: Build a stage 3 bindist, one which is a native compiler and library for the target
- - - - -
57574c94 by Sven Tennie at 2026-06-10T06:36:33+02:00
ci: Increase timeout for emulators
Test runs with emulators naturally take longer than on native machines.
Generate jobs.yml
- - - - -
f992303a by Matthew Pickering at 2026-06-10T06:36:33+02:00
ci: Javascript don't set CROSS_EMULATOR
There is no CROSS_EMULATOR needed to run javascript binaries, so we
don't set the CROSS_EMULATOR to some dummy value.
- - - - -
3db0897f by Sven Tennie at 2026-06-10T06:36:33+02:00
Javascript skip T23697
See #22355 about how HSC2HS and the Javascript target don't play well
together.
- - - - -
9b0c4d23 by Sven Tennie at 2026-06-10T06:36:33+02:00
Mark T24602 as fragile
It was skipped before (due to CROSS_EMULATOR being set, which changed
for JS), so we don't make things worse by marking it as fragile.
- - - - -
191a58db by Sven Tennie at 2026-06-10T06:36:33+02:00
Fix T22744 for GHCJS
In fact, this test needs Template Haskell, not necessarily an
interpreter.
- - - - -
80 changed files:
- .gitlab/ci.sh
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- changelog.d/hadrian-response-files.md
- + changelog.d/stage2-cross-compilers
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval/Types.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Utils/Logger.hs
- configure.ac
- distrib/configure.ac.in
- docs/users_guide/using.rst
- hadrian/README.md
- hadrian/bindist/config.mk.in
- hadrian/cfg/default.host.target.in
- + hadrian/cfg/system.config.host.in
- hadrian/cfg/system.config.in
- + hadrian/cfg/system.config.target.in
- hadrian/hadrian.cabal
- hadrian/src/Base.hs
- + hadrian/src/BindistConfig.hs
- hadrian/src/Builder.hs
- hadrian/src/CommandLine.hs
- hadrian/src/Context.hs
- hadrian/src/Expression.hs
- hadrian/src/Flavour.hs
- hadrian/src/Flavour/Type.hs
- hadrian/src/Hadrian/Builder.hs
- hadrian/src/Hadrian/Builder/Ar.hs
- hadrian/src/Hadrian/Haskell/Hash.hs
- hadrian/src/Hadrian/Oracles/TextFile.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Main.hs
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Oracles/Flavour.hs
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Oracles/TestSettings.hs
- hadrian/src/Packages.hs
- hadrian/src/Rules.hs
- hadrian/src/Rules/BinaryDist.hs
- hadrian/src/Rules/CabalReinstall.hs
- hadrian/src/Rules/Changelog.hs
- hadrian/src/Rules/Compile.hs
- hadrian/src/Rules/Documentation.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Rules/Library.hs
- hadrian/src/Rules/Program.hs
- hadrian/src/Rules/Register.hs
- hadrian/src/Rules/Rts.hs
- hadrian/src/Rules/Test.hs
- hadrian/src/Settings.hs
- hadrian/src/Settings/Builders/Cabal.hs
- hadrian/src/Settings/Builders/Common.hs
- hadrian/src/Settings/Builders/Configure.hs
- hadrian/src/Settings/Builders/DeriveConstants.hs
- hadrian/src/Settings/Builders/Ghc.hs
- hadrian/src/Settings/Builders/Hsc2Hs.hs
- hadrian/src/Settings/Builders/RunTest.hs
- hadrian/src/Settings/Builders/SplitSections.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Flavours/GhcInGhci.hs
- hadrian/src/Settings/Flavours/Performance.hs
- hadrian/src/Settings/Flavours/QuickCross.hs
- hadrian/src/Settings/Packages.hs
- hadrian/src/Settings/Program.hs
- hadrian/src/Settings/Warnings.hs
- libraries/base/tests/all.T
- libraries/ghc-internal/src/GHC/Internal/Lexeme.hs
- m4/fp_find_nm.m4
- m4/prep_target_file.m4
- testsuite/ghc-config/ghc-config.hs
- testsuite/mk/test.mk
- testsuite/tests/ghc-e/should_fail/all.T
- testsuite/tests/javascript/closure/all.T
- testsuite/tests/perf/compiler/all.T
- utils/check-exact/Main.hs
- utils/check-exact/Transform.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2e6dda8a9718a8f59a0900bc8101e3…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2e6dda8a9718a8f59a0900bc8101e3…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Don't drop ticks around variables of type `IO ()`
by Marge Bot (@marge-bot) 10 Jun '26
by Marge Bot (@marge-bot) 10 Jun '26
10 Jun '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
1c9ee79a by sheaf at 2026-06-10T00:18:02-04:00
Don't drop ticks around variables of type `IO ()`
GHC.Core.Utils.mkTick is responsible for placing a tick on a Core
expression. It contains logic for dropping SCCs (non-counting profiling
ticks) around non-function variables, as such variables cannot
meaningfully contribute to profiles. However, the logic for what counts
as a function was incorrect: it used `isFunTy` which returns 'False' for
types such as 'IO ()' where the function arrow is hidden under a
newtype.
We now use 'mightBeFunTy' instead of 'isFunTy'. This ensures we don't
drop ticks in cases we aren't sure.
On the way, we improve the documentation of 'isFunTy', 'isPiTy' and
'mightBeFunTy', and update the latter's implementation to consistently
handle unary classes.
Fixes #27225
-------------------------
Metric Decrease:
T5642
-------------------------
- - - - -
76662edd by Simon Jakobi at 2026-06-10T00:18:03-04:00
testsuite: Add regression test for #4081
Check that a strict constructor field is unboxed once outside an
enclosing loop, not re-inspected each iteration (the float-out
case-floating from 9cb20b488). Uses simonpj's `data T a = T !a` example
from the ticket; T4081.stderr captures the expected Core.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
ad18f39f by sheaf at 2026-06-10T00:18:08-04:00
Check for cabal-install >= 3.12 upfront
Starting with commit 8cb99552f607f6bc4000e45ab32532d50c8bb996, Hadrian
requires cabal-install >= 3.12 in order to use the 'cabal path' command
that was introduced in version 3.12, as per
https://github.com/haskell/cabal/blob/a51c4ee1556d816ad86e90db7e6330dd51b0b…
This was not reflected in the Hadrian build script, causing a delayed
build failure instead of enforcing the version requirement upfront,
which this patch does.
Fixes #27317
- - - - -
aded8774 by sheaf at 2026-06-10T00:18:09-04:00
Fix crash in Data.Data instance for HsCtxt
The Data.Data instance for HsCtxt contained an error for the 'toConstr'
method, which could trigger for example when looking at -ddump-tc-ast
traces. Replace it with the 'abstractConstr' pattern used in the rest of
the codebase.
- - - - -
21 changed files:
- + changelog.d/T27225
- + changelog.d/T27317
- + changelog.d/T27359
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Types/RepType.hs
- hadrian/build-cabal
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/profiling/should_run/T27225.hs
- + testsuite/tests/profiling/should_run/T27225.stdout
- + testsuite/tests/profiling/should_run/T27225b.hs
- + testsuite/tests/profiling/should_run/T27225b.stdout
- testsuite/tests/profiling/should_run/all.T
- testsuite/tests/profiling/should_run/caller-cc/CallerCc1.prof.sample
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/profiling/should_run/scc001.prof.sample
- + testsuite/tests/simplCore/should_compile/T4081.hs
- + testsuite/tests/simplCore/should_compile/T4081.stderr
- testsuite/tests/simplCore/should_compile/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/085e8e31486ecdd6a08f47fa46acab…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/085e8e31486ecdd6a08f47fa46acab…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/sjakobi/T25450-march-native] Vendor x86 CPU feature detection from LLVM's compiler-rt
by Simon Jakobi (@sjakobi2) 10 Jun '26
by Simon Jakobi (@sjakobi2) 10 Jun '26
10 Jun '26
Simon Jakobi pushed to branch wip/sjakobi/T25450-march-native at Glasgow Haskell Compiler / GHC
Commits:
7bab9752 by Simon Jakobi at 2026-06-10T02:05:57+02:00
Vendor x86 CPU feature detection from LLVM's compiler-rt
Following review feedback, replace the hand-rolled CPUID/XGETBV probe in
cpu_features_x86.c with code vendored from compiler-rt's plain-C CPU
model implementation:
compiler-rt/lib/builtins/cpu_model/x86.c at tag llvmorg-20.1.0
This is the runtime behind clang's __builtin_cpu_supports and
__builtin_cpu_is; upstream notes it is a copy of
llvm/lib/TargetParser/Host.cpp (the code behind clang -march=native) and
that the two files are kept in sync. The file header references the
upstream source so the code can be diffed against it when debugging or
updating.
The vendored code is byte-for-byte upstream: enum ProcessorFeatures, the
CPUID/XGETBV helpers (getX86CpuIDAndInfo, getX86CpuIDAndInfoEx,
getX86XCR0) and the entire getAvailableFeatures function are verbatim.
The single GHC deviation is a separate marked block that clears
FEATURE_FMA again when OS AVX-state support is missing -- FMA
instructions are VEX-encoded and unusable without it -- matching
Host.cpp and GCC's cpuinfo.h, where upstream x86.c uses the raw CPUID
bit alone.
To make this possible, cpuFeatureBitLayout in GHC.Driver.CpuFeatures
adopts LLVM/GCC's stable __builtin_cpu_supports feature numbering
(BMI1 = upstream's FEATURE_BMI). ghc_detect_x86_cpu_features stands in
for __cpu_indicator_init as the driver, returning the first 64 feature
bits of that numbering as a mask (every feature GHC decodes is below
bit 64; GFNI is the highest at 32). Features decoded by upstream code
beyond GHC's set are simply ignored on the Haskell side, so updating
the vendored code is a pure copy-paste and adding a new feature to GHC
only requires a Haskell-side change.
Behavioural changes from adopting LLVM's logic:
* On x86_64 macOS we no longer query sysctl(hw.optional.avx512f) to work
around the kernel's lazy AVX-512 XSAVE enablement. Like LLVM, we trust
that Darwin will save the AVX-512 context on first use and rely on the
CPUID leaf-7 bits alone (HasAVX512Save = true on __APPLE__). This also
drops the sys/sysctl.h dependency.
* The AVX-512 sub-features (BW/CD/DQ/VL) are each gated individually on
OS support for the AVX-512 context save, instead of being nested under
an AVX512F check.
Co-Authored-By: Claude Fable 5 <noreply(a)anthropic.com>
- - - - -
2 changed files:
- compiler/GHC/Driver/CpuFeatures.hs
- compiler/cbits/cpu_features_x86.c
Changes:
=====================================
compiler/GHC/Driver/CpuFeatures.hs
=====================================
@@ -32,7 +32,10 @@ data X86CpuFeature
-- | Decode the bitmask returned by 'ghc_detect_x86_cpu_features'.
--
--- NOTE: Bit positions must match the enum in @compiler/cbits/cpu_features_x86.c@.
+-- NOTE: Bit positions are LLVM\/GCC's @__builtin_cpu_supports@ feature
+-- numbering, i.e. @enum ProcessorFeatures@ vendored in
+-- @compiler/cbits/cpu_features_x86.c@. The C side returns the first 64
+-- feature bits of that numbering.
decodeX86CpuFeatureMask :: Word64 -> [X86CpuFeature]
decodeX86CpuFeatureMask mask =
[ feat
@@ -61,24 +64,27 @@ cachedX86CpuFeatures :: [X86CpuFeature]
cachedX86CpuFeatures = unsafePerformIO detectX86CpuFeatures
{-# NOINLINE cachedX86CpuFeatures #-}
+-- | See the NOTE on 'decodeX86CpuFeatureMask' for where these bit positions
+-- come from. The constant names on the C side are upstream's: @FEATURE_SSE2@,
+-- @FEATURE_BMI@ (= 'BMI1'), etc.
cpuFeatureBitLayout :: [(Int, X86CpuFeature)]
cpuFeatureBitLayout =
- [ (0, SSE2)
- , (1, SSE3)
- , (2, SSSE3)
- , (3, SSE4_1)
- , (4, SSE4_2)
- , (5, AVX)
- , (6, AVX2)
- , (7, AVX512F)
- , (8, AVX512BW)
- , (9, AVX512CD)
- , (10, AVX512DQ)
- , (11, AVX512VL)
- , (12, BMI1)
- , (13, BMI2)
- , (14, FMA)
- , (15, GFNI)
+ [ (4, SSE2) -- FEATURE_SSE2
+ , (5, SSE3) -- FEATURE_SSE3
+ , (6, SSSE3) -- FEATURE_SSSE3
+ , (7, SSE4_1) -- FEATURE_SSE4_1
+ , (8, SSE4_2) -- FEATURE_SSE4_2
+ , (9, AVX) -- FEATURE_AVX
+ , (10, AVX2) -- FEATURE_AVX2
+ , (14, FMA) -- FEATURE_FMA
+ , (15, AVX512F) -- FEATURE_AVX512F
+ , (16, BMI1) -- FEATURE_BMI
+ , (17, BMI2) -- FEATURE_BMI2
+ , (20, AVX512VL) -- FEATURE_AVX512VL
+ , (21, AVX512BW) -- FEATURE_AVX512BW
+ , (22, AVX512DQ) -- FEATURE_AVX512DQ
+ , (23, AVX512CD) -- FEATURE_AVX512CD
+ , (32, GFNI) -- FEATURE_GFNI
]
#if !defined(javascript_HOST_ARCH)
=====================================
compiler/cbits/cpu_features_x86.c
=====================================
@@ -1,208 +1,586 @@
+/* Host x86 CPU feature detection, used to implement -march=native.
+ *
+ * The detection code is vendored from LLVM's compiler-rt, where it implements
+ * the runtime support for __builtin_cpu_supports/__builtin_cpu_is
+ * (__cpu_model, __cpu_indicator_init):
+ *
+ * compiler-rt/lib/builtins/cpu_model/x86.c
+ * at tag llvmorg-20.1.0 (LLVM 20.1.0)
+ * https://github.com/llvm/llvm-project/blob/llvmorg-20.1.0/compiler-rt/lib/bu…
+ *
+ * LLVM is licensed under Apache-2.0 WITH LLVM-exception. Upstream notes that
+ * this file is itself a copy of llvm/lib/TargetParser/Host.cpp -- the code
+ * behind clang's -march=native -- and that the two are kept in sync.
+ *
+ * Vendored verbatim: enum ProcessorFeatures, getX86CpuIDAndInfo,
+ * getX86CpuIDAndInfoEx, getX86XCR0 and getAvailableFeatures, the latter with
+ * a single marked GHC deviation that additionally gates FEATURE_FMA on OS
+ * support for saving the AVX register state.
+ *
+ * Adaptations around the vendored code:
+ *
+ * - ghc_detect_x86_cpu_features stands in for __cpu_indicator_init as the
+ * driver: it performs the same CPUID call sequence, but returns the first
+ * 64 feature bits as a mask -- which covers every feature GHC decodes,
+ * see GHC.Driver.CpuFeatures -- instead of filling in the __cpu_model
+ * globals.
+ * - On non-x86 hosts the driver compiles to a stub returning 0 instead of
+ * upstream's "#error This file is intended only for x86-based targets".
+ */
+
#include <HsFFI.h>
-#include <stdint.h>
+#include <stdbool.h>
-#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
-#include <immintrin.h>
-#include <intrin.h>
+#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \
+ defined(_M_X64)
+#define GHC_HOST_IS_X86 1
#endif
-#if !defined(_MSC_VER) && (defined(__i386__) || defined(__x86_64__))
+#if defined(GHC_HOST_IS_X86)
+
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(_MSC_VER)
#include <cpuid.h>
#endif
-#if defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__))
-#include <sys/sysctl.h>
+#ifdef _MSC_VER
+#include <intrin.h>
#endif
-enum {
- GHC_X86_FEAT_SSE2 = 0,
- GHC_X86_FEAT_SSE3,
- GHC_X86_FEAT_SSSE3,
- GHC_X86_FEAT_SSE4_1,
- GHC_X86_FEAT_SSE4_2,
- GHC_X86_FEAT_AVX,
- GHC_X86_FEAT_AVX2,
- GHC_X86_FEAT_AVX512F,
- GHC_X86_FEAT_AVX512BW,
- GHC_X86_FEAT_AVX512CD,
- GHC_X86_FEAT_AVX512DQ,
- GHC_X86_FEAT_AVX512VL,
- GHC_X86_FEAT_BMI1,
- GHC_X86_FEAT_BMI2,
- GHC_X86_FEAT_FMA,
- GHC_X86_FEAT_GFNI
+/* NOTE: The feature bit positions below are LLVM/GCC's stable
+ * __builtin_cpu_supports feature numbering. cpuFeatureBitLayout in
+ * GHC.Driver.CpuFeatures must use the same values. */
+enum ProcessorFeatures {
+ FEATURE_CMOV = 0,
+ FEATURE_MMX,
+ FEATURE_POPCNT,
+ FEATURE_SSE,
+ FEATURE_SSE2,
+ FEATURE_SSE3,
+ FEATURE_SSSE3,
+ FEATURE_SSE4_1,
+ FEATURE_SSE4_2,
+ FEATURE_AVX,
+ FEATURE_AVX2,
+ FEATURE_SSE4_A,
+ FEATURE_FMA4,
+ FEATURE_XOP,
+ FEATURE_FMA,
+ FEATURE_AVX512F,
+ FEATURE_BMI,
+ FEATURE_BMI2,
+ FEATURE_AES,
+ FEATURE_PCLMUL,
+ FEATURE_AVX512VL,
+ FEATURE_AVX512BW,
+ FEATURE_AVX512DQ,
+ FEATURE_AVX512CD,
+ FEATURE_AVX512ER,
+ FEATURE_AVX512PF,
+ FEATURE_AVX512VBMI,
+ FEATURE_AVX512IFMA,
+ FEATURE_AVX5124VNNIW,
+ FEATURE_AVX5124FMAPS,
+ FEATURE_AVX512VPOPCNTDQ,
+ FEATURE_AVX512VBMI2,
+ FEATURE_GFNI,
+ FEATURE_VPCLMULQDQ,
+ FEATURE_AVX512VNNI,
+ FEATURE_AVX512BITALG,
+ FEATURE_AVX512BF16,
+ FEATURE_AVX512VP2INTERSECT,
+ // FIXME: Below Features has some missings comparing to gcc, it's because gcc
+ // has some not one-to-one mapped in llvm.
+ // FEATURE_3DNOW,
+ // FEATURE_3DNOWP,
+ FEATURE_ADX = 40,
+ // FEATURE_ABM,
+ FEATURE_CLDEMOTE = 42,
+ FEATURE_CLFLUSHOPT,
+ FEATURE_CLWB,
+ FEATURE_CLZERO,
+ FEATURE_CMPXCHG16B,
+ // FIXME: Not adding FEATURE_CMPXCHG8B is a workaround to make 'generic' as
+ // a cpu string with no X86_FEATURE_COMPAT features, which is required in
+ // current implementantion of cpu_specific/cpu_dispatch FMV feature.
+ // FEATURE_CMPXCHG8B,
+ FEATURE_ENQCMD = 48,
+ FEATURE_F16C,
+ FEATURE_FSGSBASE,
+ // FEATURE_FXSAVE,
+ // FEATURE_HLE,
+ // FEATURE_IBT,
+ FEATURE_LAHF_LM = 54,
+ FEATURE_LM,
+ FEATURE_LWP,
+ FEATURE_LZCNT,
+ FEATURE_MOVBE,
+ FEATURE_MOVDIR64B,
+ FEATURE_MOVDIRI,
+ FEATURE_MWAITX,
+ // FEATURE_OSXSAVE,
+ FEATURE_PCONFIG = 63,
+ FEATURE_PKU,
+ FEATURE_PREFETCHWT1,
+ FEATURE_PRFCHW,
+ FEATURE_PTWRITE,
+ FEATURE_RDPID,
+ FEATURE_RDRND,
+ FEATURE_RDSEED,
+ FEATURE_RTM,
+ FEATURE_SERIALIZE,
+ FEATURE_SGX,
+ FEATURE_SHA,
+ FEATURE_SHSTK,
+ FEATURE_TBM,
+ FEATURE_TSXLDTRK,
+ FEATURE_VAES,
+ FEATURE_WAITPKG,
+ FEATURE_WBNOINVD,
+ FEATURE_XSAVE,
+ FEATURE_XSAVEC,
+ FEATURE_XSAVEOPT,
+ FEATURE_XSAVES,
+ FEATURE_AMX_TILE,
+ FEATURE_AMX_INT8,
+ FEATURE_AMX_BF16,
+ FEATURE_UINTR,
+ FEATURE_HRESET,
+ FEATURE_KL,
+ // FEATURE_AESKLE,
+ FEATURE_WIDEKL = 92,
+ FEATURE_AVXVNNI,
+ FEATURE_AVX512FP16,
+ FEATURE_X86_64_BASELINE,
+ FEATURE_X86_64_V2,
+ FEATURE_X86_64_V3,
+ FEATURE_X86_64_V4,
+ FEATURE_AVXIFMA,
+ FEATURE_AVXVNNIINT8,
+ FEATURE_AVXNECONVERT,
+ FEATURE_CMPCCXADD,
+ FEATURE_AMX_FP16,
+ FEATURE_PREFETCHI,
+ FEATURE_RAOINT,
+ FEATURE_AMX_COMPLEX,
+ FEATURE_AVXVNNIINT16,
+ FEATURE_SM3,
+ FEATURE_SHA512,
+ FEATURE_SM4,
+ FEATURE_APXF,
+ FEATURE_USERMSR,
+ FEATURE_AVX10_1_256,
+ FEATURE_AVX10_1_512,
+ FEATURE_AVX10_2_256,
+ FEATURE_AVX10_2_512,
+ FEATURE_MOVRS,
+ CPU_FEATURE_MAX
};
-#define SET_FEAT(mask, bit) ((mask) |= ((HsWord64)1ULL << (bit)))
+// This code is copied from lib/Support/Host.cpp.
+// Changes to either file should be mirrored in the other.
-static int ghc_cpuid_count(uint32_t leaf, uint32_t subleaf,
- uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
-{
-#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
- int regs[4];
- __cpuidex(regs, (int)leaf, (int)subleaf);
- *a = (uint32_t)regs[0];
- *b = (uint32_t)regs[1];
- *c = (uint32_t)regs[2];
- *d = (uint32_t)regs[3];
- return 1;
-#elif defined(__i386__) || defined(__x86_64__)
- return __get_cpuid_count(leaf, subleaf, a, b, c, d);
+/// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
+/// the specified arguments. If we can't run cpuid on the host, return true.
+static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
+ unsigned *rECX, unsigned *rEDX) {
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(_MSC_VER)
+ return !__get_cpuid(value, rEAX, rEBX, rECX, rEDX);
+#elif defined(_MSC_VER)
+ // The MSVC intrinsic is portable across x86 and x64.
+ int registers[4];
+ __cpuid(registers, value);
+ *rEAX = registers[0];
+ *rEBX = registers[1];
+ *rECX = registers[2];
+ *rEDX = registers[3];
+ return false;
#else
- (void)leaf;
- (void)subleaf;
- (void)a;
- (void)b;
- (void)c;
- (void)d;
- return 0;
+ return true;
#endif
}
-static uint64_t ghc_xgetbv0(void)
-{
-#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
- return (uint64_t)_xgetbv(0);
-#elif defined(__i386__) || defined(__x86_64__)
- uint32_t eax, edx;
- __asm__ volatile(".byte 0x0f, 0x01, 0xd0" /* xgetbv */
- : "=a"(eax), "=d"(edx)
- : "c"(0));
- return ((uint64_t)edx << 32) | (uint64_t)eax;
+/// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
+/// the 4 values in the specified arguments. If we can't run cpuid on the host,
+/// return true.
+static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
+ unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
+ unsigned *rEDX) {
+ // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang
+ // are such that __cpuidex is defined within cpuid.h for both, we can remove
+ // the __get_cpuid_count function and share the MSVC implementation between
+ // all three.
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(_MSC_VER)
+ return !__get_cpuid_count(value, subleaf, rEAX, rEBX, rECX, rEDX);
+#elif defined(_MSC_VER)
+ int registers[4];
+ __cpuidex(registers, value, subleaf);
+ *rEAX = registers[0];
+ *rEBX = registers[1];
+ *rECX = registers[2];
+ *rEDX = registers[3];
+ return false;
#else
- return 0;
+ return true;
#endif
}
-#if defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__))
-/* Query a macOS CPU-capability sysctl, e.g. "hw.optional.avx512f". */
-static int ghc_macos_sysctl_flag(const char *name)
-{
- int result = 0;
- size_t len = sizeof(result);
- if (sysctlbyname(name, &result, &len, NULL, 0) != 0) {
- return 0;
- }
- return result != 0;
-}
+// Read control register 0 (XCR0). Used to detect features such as AVX.
+static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {
+ // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang
+ // are such that _xgetbv is supported by both, we can unify the implementation
+ // with MSVC and remove all inline assembly.
+#if defined(__GNUC__) || defined(__clang__)
+ // Check xgetbv; this uses a .byte sequence instead of the instruction
+ // directly because older assemblers do not include support for xgetbv and
+ // there is no easy way to conditionally compile based on the assembler used.
+ __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0));
+ return false;
+#elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
+ unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
+ *rEAX = Result;
+ *rEDX = Result >> 32;
+ return false;
+#else
+ return true;
#endif
+}
-HsWord64 ghc_detect_x86_cpu_features(void)
-{
- HsWord64 feats = 0;
+static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
+ unsigned *Features) {
+ unsigned EAX = 0, EBX = 0;
-#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__)
- uint32_t a, b, c, d;
- uint32_t max_basic = 0;
+#define hasFeature(F) ((Features[F / 32] >> (F % 32)) & 1)
+#define setFeature(F) Features[F / 32] |= 1U << (F % 32)
- if (!ghc_cpuid_count(0, 0, &a, &b, &c, &d)) {
- return 0;
- }
- max_basic = a;
- if (max_basic < 1) {
- return 0;
- }
+ if ((EDX >> 15) & 1)
+ setFeature(FEATURE_CMOV);
+ if ((EDX >> 23) & 1)
+ setFeature(FEATURE_MMX);
+ if ((EDX >> 25) & 1)
+ setFeature(FEATURE_SSE);
+ if ((EDX >> 26) & 1)
+ setFeature(FEATURE_SSE2);
- ghc_cpuid_count(1, 0, &a, &b, &c, &d);
-
- {
- int has_sse2 = !!(d & (1u << 26));
- int has_sse3 = !!(c & (1u << 0));
- int has_ssse3 = !!(c & (1u << 9));
- int has_sse4_1 = !!(c & (1u << 19));
- int has_sse4_2 = !!(c & (1u << 20));
- int has_fma_hw = !!(c & (1u << 12));
- int has_avx_hw = !!(c & (1u << 28));
- int has_osxsave = !!(c & (1u << 27));
-
- int avx_usable = 0;
- int avx512_usable = 0;
-
- if (has_osxsave) {
- uint64_t xcr0 = ghc_xgetbv0();
- avx_usable = ((xcr0 & 0x6u) == 0x6u); /* XMM + YMM state */
- avx512_usable = ((xcr0 & 0xE6u) == 0xE6u); /* XMM+YMM+opmask+ZMM */
- }
+ if ((ECX >> 0) & 1)
+ setFeature(FEATURE_SSE3);
+ if ((ECX >> 1) & 1)
+ setFeature(FEATURE_PCLMUL);
+ if ((ECX >> 9) & 1)
+ setFeature(FEATURE_SSSE3);
+ if ((ECX >> 12) & 1)
+ setFeature(FEATURE_FMA);
+ if ((ECX >> 13) & 1)
+ setFeature(FEATURE_CMPXCHG16B);
+ if ((ECX >> 19) & 1)
+ setFeature(FEATURE_SSE4_1);
+ if ((ECX >> 20) & 1)
+ setFeature(FEATURE_SSE4_2);
+ if ((ECX >> 22) & 1)
+ setFeature(FEATURE_MOVBE);
+ if ((ECX >> 23) & 1)
+ setFeature(FEATURE_POPCNT);
+ if ((ECX >> 25) & 1)
+ setFeature(FEATURE_AES);
+ if ((ECX >> 29) & 1)
+ setFeature(FEATURE_F16C);
+ if ((ECX >> 30) & 1)
+ setFeature(FEATURE_RDRND);
+ // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
+ // indicates that the AVX registers will be saved and restored on context
+ // switch, then we have full AVX support.
+ const unsigned AVXBits = (1 << 27) | (1 << 28);
+ bool HasAVXSave = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
+ ((EAX & 0x6) == 0x6);
#if defined(__APPLE__)
- /* On x86_64 macOS the kernel enables AVX-512 XSAVE state lazily: XCR0
- reads back with the opmask/ZMM bits clear until a process first faults
- on an AVX-512 instruction, so the XCR0 check above is a false negative
- on AVX-512-capable Macs. Use the OS feature query instead. Checking
- AVX512F alone suffices here; the AVX-512 sub-features (BW/CD/DQ/VL) are
- still decoded from CPUID leaf 7 below.
-
- Refs:
- https://zenn.dev/mod_poppo/articles/detect-processor-features-x86?locale=en…
- https://github.com/minoki/haskell-cpu-features */
- avx512_usable = ghc_macos_sysctl_flag("hw.optional.avx512f");
+ // Darwin lazily saves the AVX512 context on first use: trust that the OS will
+ // save the AVX512 context if we use AVX512 instructions, even the bit is not
+ // set right now.
+ bool HasAVX512Save = true;
+#else
+ // AVX512 requires additional context to be saved by the OS.
+ bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
#endif
+ // AMX requires additional context to be saved by the OS.
+ const unsigned AMXBits = (1 << 17) | (1 << 18);
+ bool HasXSave = ((ECX >> 27) & 1) && !getX86XCR0(&EAX, &EDX);
+ bool HasAMXSave = HasXSave && ((EAX & AMXBits) == AMXBits);
- if (has_sse2) {
- SET_FEAT(feats, GHC_X86_FEAT_SSE2);
- }
- if (has_sse3) {
- SET_FEAT(feats, GHC_X86_FEAT_SSE3);
- }
- if (has_ssse3) {
- SET_FEAT(feats, GHC_X86_FEAT_SSSE3);
- }
- if (has_sse4_1) {
- SET_FEAT(feats, GHC_X86_FEAT_SSE4_1);
- }
- if (has_sse4_2) {
- SET_FEAT(feats, GHC_X86_FEAT_SSE4_2);
- }
- if (has_avx_hw && avx_usable) {
- SET_FEAT(feats, GHC_X86_FEAT_AVX);
+ // GHC deviation from upstream: FMA instructions are VEX-encoded and
+ // unusable unless the OS saves the AVX register state, so FEATURE_FMA (set
+ // from the raw CPUID bit above) is cleared again when full AVX support is
+ // missing. This matches llvm/lib/TargetParser/Host.cpp ("fma") and GCC's
+ // gcc/common/config/i386/cpuinfo.h (FEATURE_FMA under avx_usable).
+ if (!HasAVXSave)
+ Features[FEATURE_FMA / 32] &= ~(1U << (FEATURE_FMA % 32));
+
+ if (HasAVXSave)
+ setFeature(FEATURE_AVX);
+
+ if (((ECX >> 26) & 1) && HasAVXSave)
+ setFeature(FEATURE_XSAVE);
+
+ bool HasLeaf7 =
+ MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
+
+ if (HasLeaf7 && ((EBX >> 0) & 1))
+ setFeature(FEATURE_FSGSBASE);
+ if (HasLeaf7 && ((EBX >> 2) & 1))
+ setFeature(FEATURE_SGX);
+ if (HasLeaf7 && ((EBX >> 3) & 1))
+ setFeature(FEATURE_BMI);
+ if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave)
+ setFeature(FEATURE_AVX2);
+ if (HasLeaf7 && ((EBX >> 8) & 1))
+ setFeature(FEATURE_BMI2);
+ if (HasLeaf7 && ((EBX >> 11) & 1))
+ setFeature(FEATURE_RTM);
+ if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512F);
+ if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512DQ);
+ if (HasLeaf7 && ((EBX >> 18) & 1))
+ setFeature(FEATURE_RDSEED);
+ if (HasLeaf7 && ((EBX >> 19) & 1))
+ setFeature(FEATURE_ADX);
+ if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512IFMA);
+ if (HasLeaf7 && ((EBX >> 24) & 1))
+ setFeature(FEATURE_CLWB);
+ if (HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512PF);
+ if (HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512ER);
+ if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512CD);
+ if (HasLeaf7 && ((EBX >> 29) & 1))
+ setFeature(FEATURE_SHA);
+ if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512BW);
+ if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512VL);
+
+ if (HasLeaf7 && ((ECX >> 0) & 1))
+ setFeature(FEATURE_PREFETCHWT1);
+ if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512VBMI);
+ if (HasLeaf7 && ((ECX >> 4) & 1))
+ setFeature(FEATURE_PKU);
+ if (HasLeaf7 && ((ECX >> 5) & 1))
+ setFeature(FEATURE_WAITPKG);
+ if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512VBMI2);
+ if (HasLeaf7 && ((ECX >> 7) & 1))
+ setFeature(FEATURE_SHSTK);
+ if (HasLeaf7 && ((ECX >> 8) & 1))
+ setFeature(FEATURE_GFNI);
+ if (HasLeaf7 && ((ECX >> 9) & 1) && HasAVXSave)
+ setFeature(FEATURE_VAES);
+ if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave)
+ setFeature(FEATURE_VPCLMULQDQ);
+ if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512VNNI);
+ if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512BITALG);
+ if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512VPOPCNTDQ);
+ if (HasLeaf7 && ((ECX >> 22) & 1))
+ setFeature(FEATURE_RDPID);
+ if (HasLeaf7 && ((ECX >> 23) & 1))
+ setFeature(FEATURE_KL);
+ if (HasLeaf7 && ((ECX >> 25) & 1))
+ setFeature(FEATURE_CLDEMOTE);
+ if (HasLeaf7 && ((ECX >> 27) & 1))
+ setFeature(FEATURE_MOVDIRI);
+ if (HasLeaf7 && ((ECX >> 28) & 1))
+ setFeature(FEATURE_MOVDIR64B);
+ if (HasLeaf7 && ((ECX >> 29) & 1))
+ setFeature(FEATURE_ENQCMD);
+
+ if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX5124VNNIW);
+ if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX5124FMAPS);
+ if (HasLeaf7 && ((EDX >> 5) & 1))
+ setFeature(FEATURE_UINTR);
+ if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512VP2INTERSECT);
+ if (HasLeaf7 && ((EDX >> 14) & 1))
+ setFeature(FEATURE_SERIALIZE);
+ if (HasLeaf7 && ((EDX >> 16) & 1))
+ setFeature(FEATURE_TSXLDTRK);
+ if (HasLeaf7 && ((EDX >> 18) & 1))
+ setFeature(FEATURE_PCONFIG);
+ if (HasLeaf7 && ((EDX >> 22) & 1) && HasAMXSave)
+ setFeature(FEATURE_AMX_BF16);
+ if (HasLeaf7 && ((EDX >> 23) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512FP16);
+ if (HasLeaf7 && ((EDX >> 24) & 1) && HasAMXSave)
+ setFeature(FEATURE_AMX_TILE);
+ if (HasLeaf7 && ((EDX >> 25) & 1) && HasAMXSave)
+ setFeature(FEATURE_AMX_INT8);
+
+ // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
+ // return all 0s for invalid subleaves so check the limit.
+ bool HasLeaf7Subleaf1 =
+ HasLeaf7 && EAX >= 1 &&
+ !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
+ if (HasLeaf7Subleaf1 && ((EAX >> 0) & 1))
+ setFeature(FEATURE_SHA512);
+ if (HasLeaf7Subleaf1 && ((EAX >> 1) & 1))
+ setFeature(FEATURE_SM3);
+ if (HasLeaf7Subleaf1 && ((EAX >> 2) & 1))
+ setFeature(FEATURE_SM4);
+ if (HasLeaf7Subleaf1 && ((EAX >> 3) & 1))
+ setFeature(FEATURE_RAOINT);
+ if (HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave)
+ setFeature(FEATURE_AVXVNNI);
+ if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save)
+ setFeature(FEATURE_AVX512BF16);
+ if (HasLeaf7Subleaf1 && ((EAX >> 7) & 1))
+ setFeature(FEATURE_CMPCCXADD);
+ if (HasLeaf7Subleaf1 && ((EAX >> 21) & 1) && HasAMXSave)
+ setFeature(FEATURE_AMX_FP16);
+ if (HasLeaf7Subleaf1 && ((EAX >> 22) & 1))
+ setFeature(FEATURE_HRESET);
+ if (HasLeaf7Subleaf1 && ((EAX >> 23) & 1) && HasAVXSave)
+ setFeature(FEATURE_AVXIFMA);
+ if (HasLeaf7Subleaf1 && ((EAX >> 31) & 1))
+ setFeature(FEATURE_MOVRS);
+
+ if (HasLeaf7Subleaf1 && ((EDX >> 4) & 1) && HasAVXSave)
+ setFeature(FEATURE_AVXVNNIINT8);
+ if (HasLeaf7Subleaf1 && ((EDX >> 5) & 1) && HasAVXSave)
+ setFeature(FEATURE_AVXNECONVERT);
+ if (HasLeaf7Subleaf1 && ((EDX >> 8) & 1) && HasAMXSave)
+ setFeature(FEATURE_AMX_COMPLEX);
+ if (HasLeaf7Subleaf1 && ((EDX >> 10) & 1) && HasAVXSave)
+ setFeature(FEATURE_AVXVNNIINT16);
+ if (HasLeaf7Subleaf1 && ((EDX >> 14) & 1))
+ setFeature(FEATURE_PREFETCHI);
+ if (HasLeaf7Subleaf1 && ((EDX >> 15) & 1))
+ setFeature(FEATURE_USERMSR);
+ if (HasLeaf7Subleaf1 && ((EDX >> 21) & 1))
+ setFeature(FEATURE_APXF);
+
+ unsigned MaxLevel = 0;
+ getX86CpuIDAndInfo(0, &MaxLevel, &EBX, &ECX, &EDX);
+ bool HasLeafD = MaxLevel >= 0xd &&
+ !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
+ if (HasLeafD && ((EAX >> 0) & 1) && HasAVXSave)
+ setFeature(FEATURE_XSAVEOPT);
+ if (HasLeafD && ((EAX >> 1) & 1) && HasAVXSave)
+ setFeature(FEATURE_XSAVEC);
+ if (HasLeafD && ((EAX >> 3) & 1) && HasAVXSave)
+ setFeature(FEATURE_XSAVES);
+
+ bool HasLeaf24 =
+ MaxLevel >= 0x24 && !getX86CpuIDAndInfo(0x24, &EAX, &EBX, &ECX, &EDX);
+ if (HasLeaf7Subleaf1 && ((EDX >> 19) & 1) && HasLeaf24) {
+ bool Has512Len = (EBX >> 18) & 1;
+ int AVX10Ver = EBX & 0xff;
+ if (AVX10Ver >= 2) {
+ setFeature(FEATURE_AVX10_2_256);
+ if (Has512Len)
+ setFeature(FEATURE_AVX10_2_512);
}
- if (has_fma_hw && avx_usable) {
- SET_FEAT(feats, GHC_X86_FEAT_FMA);
+ if (AVX10Ver >= 1) {
+ setFeature(FEATURE_AVX10_1_256);
+ if (Has512Len)
+ setFeature(FEATURE_AVX10_1_512);
}
+ }
- if (max_basic >= 7 && ghc_cpuid_count(7, 0, &a, &b, &c, &d)) {
- int has_bmi1 = !!(b & (1u << 3));
- int has_avx2_hw = !!(b & (1u << 5));
- int has_bmi2 = !!(b & (1u << 8));
- int has_avx512f = !!(b & (1u << 16));
- int has_avx512dq = !!(b & (1u << 17));
- int has_avx512cd = !!(b & (1u << 28));
- int has_avx512bw = !!(b & (1u << 30));
- int has_avx512vl = !!(b & (1u << 31));
- int has_gfni = !!(c & (1u << 8));
-
- if (has_bmi1) {
- SET_FEAT(feats, GHC_X86_FEAT_BMI1);
- }
- if (has_bmi2) {
- SET_FEAT(feats, GHC_X86_FEAT_BMI2);
- }
- if (avx_usable && has_avx2_hw) {
- SET_FEAT(feats, GHC_X86_FEAT_AVX2);
- }
+ unsigned MaxExtLevel = 0;
+ getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
- if (avx512_usable && has_avx512f) {
- SET_FEAT(feats, GHC_X86_FEAT_AVX512F);
- if (has_avx512bw) {
- SET_FEAT(feats, GHC_X86_FEAT_AVX512BW);
- }
- if (has_avx512cd) {
- SET_FEAT(feats, GHC_X86_FEAT_AVX512CD);
- }
- if (has_avx512dq) {
- SET_FEAT(feats, GHC_X86_FEAT_AVX512DQ);
- }
- if (has_avx512vl) {
- SET_FEAT(feats, GHC_X86_FEAT_AVX512VL);
- }
- }
+ bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
+ !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
+ if (HasExtLeaf1) {
+ if (ECX & 1)
+ setFeature(FEATURE_LAHF_LM);
+ if ((ECX >> 5) & 1)
+ setFeature(FEATURE_LZCNT);
+ if (((ECX >> 6) & 1))
+ setFeature(FEATURE_SSE4_A);
+ if (((ECX >> 8) & 1))
+ setFeature(FEATURE_PRFCHW);
+ if (((ECX >> 11) & 1))
+ setFeature(FEATURE_XOP);
+ if (((ECX >> 15) & 1))
+ setFeature(FEATURE_LWP);
+ if (((ECX >> 16) & 1))
+ setFeature(FEATURE_FMA4);
+ if (((ECX >> 21) & 1))
+ setFeature(FEATURE_TBM);
+ if (((ECX >> 29) & 1))
+ setFeature(FEATURE_MWAITX);
+
+ if (((EDX >> 29) & 1))
+ setFeature(FEATURE_LM);
+ }
+
+ bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 &&
+ !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX);
+ if (HasExtLeaf8 && ((EBX >> 0) & 1))
+ setFeature(FEATURE_CLZERO);
+ if (HasExtLeaf8 && ((EBX >> 9) & 1))
+ setFeature(FEATURE_WBNOINVD);
+
+ bool HasLeaf14 = MaxLevel >= 0x14 &&
+ !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX);
+ if (HasLeaf14 && ((EBX >> 4) & 1))
+ setFeature(FEATURE_PTWRITE);
- if (has_gfni) {
- SET_FEAT(feats, GHC_X86_FEAT_GFNI);
+ bool HasLeaf19 =
+ MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX);
+ if (HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1))
+ setFeature(FEATURE_WIDEKL);
+
+ if (hasFeature(FEATURE_LM) && hasFeature(FEATURE_SSE2)) {
+ setFeature(FEATURE_X86_64_BASELINE);
+ if (hasFeature(FEATURE_CMPXCHG16B) && hasFeature(FEATURE_POPCNT) &&
+ hasFeature(FEATURE_LAHF_LM) && hasFeature(FEATURE_SSE4_2)) {
+ setFeature(FEATURE_X86_64_V2);
+ if (hasFeature(FEATURE_AVX2) && hasFeature(FEATURE_BMI) &&
+ hasFeature(FEATURE_BMI2) && hasFeature(FEATURE_F16C) &&
+ hasFeature(FEATURE_FMA) && hasFeature(FEATURE_LZCNT) &&
+ hasFeature(FEATURE_MOVBE)) {
+ setFeature(FEATURE_X86_64_V3);
+ if (hasFeature(FEATURE_AVX512BW) && hasFeature(FEATURE_AVX512CD) &&
+ hasFeature(FEATURE_AVX512DQ) && hasFeature(FEATURE_AVX512VL))
+ setFeature(FEATURE_X86_64_V4);
}
}
}
-#endif
- return feats;
+#undef hasFeature
+#undef setFeature
+}
+
+#endif /* GHC_HOST_IS_X86 */
+
+/* The driver, modeled on upstream's __cpu_indicator_init: same CPUID call
+ * sequence, but the first 64 feature bits are returned to the caller (see
+ * GHC.Driver.CpuFeatures) instead of being stored in the __cpu_model
+ * globals. */
+HsWord64 ghc_detect_x86_cpu_features(void)
+{
+#if defined(GHC_HOST_IS_X86)
+ unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
+ unsigned MaxLeaf = 5;
+ unsigned Features[(CPU_FEATURE_MAX + 31) / 32] = {0};
+
+ if (getX86CpuIDAndInfo(0, &MaxLeaf, &EBX, &ECX, &EDX) || MaxLeaf < 1)
+ return 0;
+
+ getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
+
+ // Find available features.
+ getAvailableFeatures(ECX, EDX, MaxLeaf, &Features[0]);
+
+ return ((HsWord64)Features[1] << 32) | (HsWord64)Features[0];
+#else
+ return 0;
+#endif
}
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7bab9752985efd921aa0198e2c3cd2a…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7bab9752985efd921aa0198e2c3cd2a…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Hadrian: avoid response files when command line is short enough
by Marge Bot (@marge-bot) 10 Jun '26
by Marge Bot (@marge-bot) 10 Jun '26
10 Jun '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
498bb21a by David Eichmann at 2026-06-09T18:02:39-04:00
Hadrian: avoid response files when command line is short enough
This replaces the logic of always using response files on Windows.
With the new condition based on command line lenght, reponse files
can be avoided in many more cases (on windows).
Now that response files are only used in a small number of cases,
response files are always kept and the -r / --keep-response-files
command line options have been removed
The response file paths are nolonger randomized. They are placed in the
`_build/rsp` directory. This ensures they are ignored by git and we
that Hadrian reuses response file paths when rebuilding rather than
leaving stale response files around.
Update user guide putting response files in its own section
- - - - -
87f510a5 by Simon Hengel at 2026-06-09T18:03:25-04:00
Don't use non-breaking spaces
- - - - -
41a19379 by David Eichmann at 2026-06-09T18:04:11-04:00
Hadrian: remove unused wrapper scripts from windows bindist
These wrapper scripts are only installed on non-relocatable builds
which are not generally supported on windows.
- - - - -
947a7f91 by sheaf at 2026-06-09T18:36:45-04:00
Don't drop ticks around variables of type `IO ()`
GHC.Core.Utils.mkTick is responsible for placing a tick on a Core
expression. It contains logic for dropping SCCs (non-counting profiling
ticks) around non-function variables, as such variables cannot
meaningfully contribute to profiles. However, the logic for what counts
as a function was incorrect: it used `isFunTy` which returns 'False' for
types such as 'IO ()' where the function arrow is hidden under a
newtype.
We now use 'mightBeFunTy' instead of 'isFunTy'. This ensures we don't
drop ticks in cases we aren't sure.
On the way, we improve the documentation of 'isFunTy', 'isPiTy' and
'mightBeFunTy', and update the latter's implementation to consistently
handle unary classes.
Fixes #27225
-------------------------
Metric Decrease:
T5642
-------------------------
- - - - -
1d1f248b by Simon Jakobi at 2026-06-09T18:36:46-04:00
testsuite: Add regression test for #4081
Check that a strict constructor field is unboxed once outside an
enclosing loop, not re-inspected each iteration (the float-out
case-floating from 9cb20b488). Uses simonpj's `data T a = T !a` example
from the ticket; T4081.stderr captures the expected Core.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
a562349b by sheaf at 2026-06-09T18:36:50-04:00
Check for cabal-install >= 3.12 upfront
Starting with commit 8cb99552f607f6bc4000e45ab32532d50c8bb996, Hadrian
requires cabal-install >= 3.12 in order to use the 'cabal path' command
that was introduced in version 3.12, as per
https://github.com/haskell/cabal/blob/a51c4ee1556d816ad86e90db7e6330dd51b0b…
This was not reflected in the Hadrian build script, causing a delayed
build failure instead of enforcing the version requirement upfront,
which this patch does.
Fixes #27317
- - - - -
085e8e31 by sheaf at 2026-06-09T18:36:51-04:00
Fix crash in Data.Data instance for HsCtxt
The Data.Data instance for HsCtxt contained an error for the 'toConstr'
method, which could trigger for example when looking at -ddump-tc-ast
traces. Replace it with the 'abstractConstr' pattern used in the rest of
the codebase.
- - - - -
35 changed files:
- + changelog.d/T27225
- + changelog.d/T27317
- + changelog.d/T27359
- changelog.d/hadrian-response-files.md
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval/Types.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Utils/Logger.hs
- docs/users_guide/using.rst
- hadrian/build-cabal
- hadrian/src/Builder.hs
- hadrian/src/CommandLine.hs
- hadrian/src/Hadrian/Builder/Ar.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Rules/BinaryDist.hs
- libraries/ghc-internal/src/GHC/Internal/Lexeme.hs
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/profiling/should_run/T27225.hs
- + testsuite/tests/profiling/should_run/T27225.stdout
- + testsuite/tests/profiling/should_run/T27225b.hs
- + testsuite/tests/profiling/should_run/T27225b.stdout
- testsuite/tests/profiling/should_run/all.T
- testsuite/tests/profiling/should_run/caller-cc/CallerCc1.prof.sample
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/profiling/should_run/scc001.prof.sample
- + testsuite/tests/simplCore/should_compile/T4081.hs
- + testsuite/tests/simplCore/should_compile/T4081.stderr
- testsuite/tests/simplCore/should_compile/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d75f13ca133594386b4366aae2063…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d75f13ca133594386b4366aae2063…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] Hadrian: remove unused wrapper scripts from windows bindist
by Marge Bot (@marge-bot) 10 Jun '26
by Marge Bot (@marge-bot) 10 Jun '26
10 Jun '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
41a19379 by David Eichmann at 2026-06-09T18:04:11-04:00
Hadrian: remove unused wrapper scripts from windows bindist
These wrapper scripts are only installed on non-relocatable builds
which are not generally supported on windows.
- - - - -
1 changed file:
- hadrian/src/Rules/BinaryDist.hs
Changes:
=====================================
hadrian/src/Rules/BinaryDist.hs
=====================================
@@ -290,23 +290,25 @@ bindistRules = do
copyFile ("hadrian" -/- "cfg" -/- "default.target.in") (bindistFilesDir -/- "default.target.in")
copyFile ("hadrian" -/- "cfg" -/- "default.host.target.in") (bindistFilesDir -/- "default.host.target.in")
- -- todo: do we need these wrappers on windows
- forM_ bin_targets $ \(pkg, _) -> do
- needed_wrappers <- pkgToWrappers pkg
- forM_ needed_wrappers $ \wrapper_name -> do
- let suffix = if useGhcPrefix pkg
- then "ghc-" ++ version
- else version
- wrapper_content <- wrapper wrapper_name
- let unversioned_wrapper_path = bindistFilesDir -/- "wrappers" -/- wrapper_name
- versioned_wrapper = wrapper_name ++ "-" ++ suffix
- versioned_wrapper_path = bindistFilesDir -/- "wrappers" -/- versioned_wrapper
- -- Write the wrapper to the versioned path
- writeFile' versioned_wrapper_path wrapper_content
- -- Create a symlink from the non-versioned to the versioned.
- liftIO $ do
- IO.removeFile unversioned_wrapper_path <|> return ()
- IO.createFileLink versioned_wrapper unversioned_wrapper_path
+ -- These wrapper scripts are only necessary in the configure/install
+ -- workflow which is not supported on windows.
+ unless windowsHost $ do
+ forM_ bin_targets $ \(pkg, _) -> do
+ needed_wrappers <- pkgToWrappers pkg
+ forM_ needed_wrappers $ \wrapper_name -> do
+ let suffix = if useGhcPrefix pkg
+ then "ghc-" ++ version
+ else version
+ wrapper_content <- wrapper wrapper_name
+ let unversioned_wrapper_path = bindistFilesDir -/- "wrappers" -/- wrapper_name
+ versioned_wrapper = wrapper_name ++ "-" ++ suffix
+ versioned_wrapper_path = bindistFilesDir -/- "wrappers" -/- versioned_wrapper
+ -- Write the wrapper to the versioned path
+ writeFile' versioned_wrapper_path wrapper_content
+ -- Create a symlink from the non-versioned to the versioned.
+ liftIO $ do
+ IO.removeFile unversioned_wrapper_path <|> return ()
+ IO.createFileLink versioned_wrapper unversioned_wrapper_path
let buildBinDist compressor = do
win_target <- isWinTarget
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/41a19379fa97bc6c944526814fd644e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/41a19379fa97bc6c944526814fd644e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
10 Jun '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
87f510a5 by Simon Hengel at 2026-06-09T18:03:25-04:00
Don't use non-breaking spaces
- - - - -
7 changed files:
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval/Types.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Utils/Logger.hs
- libraries/ghc-internal/src/GHC/Internal/Lexeme.hs
Changes:
=====================================
compiler/GHC/Driver/Backend.hs
=====================================
@@ -184,7 +184,7 @@ import GHC.Platform
-- about enumerating them. Just one set of error messages has been
-- ported to have an open-world assumption: these are the error
-- messages associated with type checking of foreign imports and
--- exports. To allow other errors to be issued with an open-world
+-- exports. To allow other errors to be issued with an open-world
-- assumption, use functions `backendValidityOfCImport` and
-- `backendValidityOfCExport` as models, and have a look at how the
-- 'expected back ends' are used in modules "GHC.Tc.Gen.Foreign" and
@@ -225,11 +225,11 @@ platformJSSupported platform
| otherwise = False
--- | A value of type @Backend@ represents one of GHC's back ends.
+-- | A value of type @Backend@ represents one of GHC's back ends.
-- The set of back ends cannot be extended except by modifying the
-- definition of @Backend@ in this module.
--
--- The @Backend@ type is abstract; that is, its value constructors are
+-- The @Backend@ type is abstract; that is, its value constructors are
-- not exported. It's crucial that they not be exported, because a
-- value of type @Backend@ carries only the back end's /name/, not its
-- behavior or properties. If @Backend@ were not abstract, then code
=====================================
compiler/GHC/Parser/PostProcess/Haddock.hs
=====================================
@@ -289,7 +289,7 @@ instance HasHaddock (Located (HsModule GhcPs)) where
pure $ L l_mod $
mod { hsmodExports = hsmodExports'
, hsmodDecls = hsmodDecls'
- , hsmodExt = (hsmodExt mod) { hsmodHaddockModHeader = headerDocs } }
+ , hsmodExt = (hsmodExt mod) { hsmodHaddockModHeader = headerDocs } }
lexHsDocString :: HsDocString -> HsDoc GhcPs
lexHsDocString = lexHsDoc parseIdentifier
=====================================
compiler/GHC/Runtime/Debugger/Breakpoints.hs
=====================================
@@ -177,7 +177,7 @@ resolveFunctionBreakpoint inp = do
-- for
-- (a) this binder only (it maybe a top-level or a nested declaration)
-- (b) that do not have an enclosing breakpoint
-findBreakForBind :: String {-^ Name of bind to break at -} -> ModBreaks -> [(BreakTickIndex, RealSrcSpan)]
+findBreakForBind :: String {-^ Name of bind to break at -} -> ModBreaks -> [(BreakTickIndex, RealSrcSpan)]
findBreakForBind str_name modbreaks = filter (not . enclosed) ticks
where
ticks = [ (index, span)
@@ -226,7 +226,7 @@ getModBreak m = do
-- source breakpoint, it means all *ocurrences* of that breakpoint across
-- modules should be stopped at -- hence we keep a trie from BreakpointId to
-- the list of internal break ids using it.
--- See also Note [Breakpoint identifiers]
+-- See also Note [Breakpoint identifiers]
type BreakpointOccurrences = ModuleEnv (IntMap.IntMap [InternalBreakpointId])
-- | Lookup all InternalBreakpointIds matching the given BreakpointId
=====================================
compiler/GHC/Runtime/Eval/Types.hs
=====================================
@@ -75,7 +75,7 @@ enableGhcStepMode _ = EvalStepSingle
-- and the SrcSpan of a breakpoint we hit, return @True@ if we should stop at
-- this breakpoint.
--
--- In particular, this will always be @False@ for @'RunToCompletion'@ and
+-- In particular, this will always be @False@ for @'RunToCompletion'@ and
-- @'RunAndLogSteps'@. We'd need further information e.g. about the user
-- breakpoints to determine whether to break in those modes.
breakHere :: Bool -- ^ Was this breakpoint explicitly active (in the @BreakArray@s)?
=====================================
compiler/GHC/Runtime/Heap/Inspect.hs
=====================================
@@ -293,22 +293,22 @@ ppr_termM1 Prim{valRaw=words, ty=ty} =
return $ repPrim (tyConAppTyCon ty) words
ppr_termM1 Suspension{ty=ty, bound_to=Nothing, infoprov=mipe} =
return $ hcat $
- [ char '_'
- , whenPprDebug $
+ [ char '_'
+ , whenPprDebug $
space <>
dcolon <>
pprSigmaType ty
- ] ++
- [ whenPprDebug $
+ ] ++
+ [ whenPprDebug $
space <>
char '<' <>
text (ipSrcFile ipe) <>
char ':' <>
text (ipSrcSpan ipe) <>
char '>'
- | Just ipe <- [mipe]
+ | Just ipe <- [mipe]
, not $ null $ ipSrcFile ipe
- ]
+ ]
ppr_termM1 Suspension{ty=ty, bound_to=Just n}
| otherwise = return$ parens$ ppr n <> dcolon <> pprSigmaType ty
ppr_termM1 Term{} = panic "ppr_termM1 - Term"
=====================================
compiler/GHC/Utils/Logger.hs
=====================================
@@ -413,7 +413,7 @@ defaultLogAction = defaultLogActionWithHandles stdout stderr
-- | The default 'LogAction' parametrized over the standard output and standard error handles.
-- Allows clients to replicate the log message formatting of GHC with custom handles.
-defaultLogActionWithHandles :: Handle {-^ Handle for standard output -} -> Handle {-^ Handle for standard errors -} -> LogAction
+defaultLogActionWithHandles :: Handle {-^ Handle for standard output -} -> Handle {-^ Handle for standard errors -} -> LogAction
defaultLogActionWithHandles out err logflags msg_class srcSpan msg
| log_dopt Opt_D_dump_json logflags = jsonLogActionWithHandle out logflags msg_class srcSpan msg
| otherwise = case msg_class of
=====================================
libraries/ghc-internal/src/GHC/Internal/Lexeme.hs
=====================================
@@ -44,7 +44,7 @@ okSymChar c
_ -> False
startsVarSym, startsVarId, startsConSym, startsConId :: Char -> Bool
-startsVarSym c = okSymChar c && c /= ':' -- Infix Ids
+startsVarSym c = okSymChar c && c /= ':' -- Infix Ids
startsConSym c = c == ':' -- Infix data constructors
startsVarId c = c == '_' || case generalCategory c of -- Ordinary Ids
LowercaseLetter -> True
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87f510a5ee1f7f08baceebfcd79c3e3…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87f510a5ee1f7f08baceebfcd79c3e3…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] Hadrian: avoid response files when command line is short enough
by Marge Bot (@marge-bot) 10 Jun '26
by Marge Bot (@marge-bot) 10 Jun '26
10 Jun '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
498bb21a by David Eichmann at 2026-06-09T18:02:39-04:00
Hadrian: avoid response files when command line is short enough
This replaces the logic of always using response files on Windows.
With the new condition based on command line lenght, reponse files
can be avoided in many more cases (on windows).
Now that response files are only used in a small number of cases,
response files are always kept and the -r / --keep-response-files
command line options have been removed
The response file paths are nolonger randomized. They are placed in the
`_build/rsp` directory. This ensures they are ignored by git and we
that Hadrian reuses response file paths when rebuilding rather than
leaving stale response files around.
Update user guide putting response files in its own section
- - - - -
6 changed files:
- changelog.d/hadrian-response-files.md
- docs/users_guide/using.rst
- hadrian/src/Builder.hs
- hadrian/src/CommandLine.hs
- hadrian/src/Hadrian/Builder/Ar.hs
- hadrian/src/Hadrian/Utilities.hs
Changes:
=====================================
changelog.d/hadrian-response-files.md
=====================================
@@ -1,9 +1,15 @@
section: packaging
-synopsis: Add a flag to tell Hadrian to keep response files
-issues: #27184
-mrs: !15906
+synopsis: Improved Hadrian's use of response files
+issues: #27230
+mrs: !15906 !16134
description:
- Hadrian can now be instructed to keep response files with the new
- --keep-response-files command line flag. This is helpful when debugging a
- build failure, as it allows re-running the failing command line invocation
- without an error due to a missing response file.
+ Response files are files that contain command-line arguments. Hadrian uses
+ response files to shorten command-line lengths. This is important on Windows
+ where command-line lengths are limited.
+
+ Hadrian now supports response files when invoking GHC. In order to support
+ manually rerunning commands issued by Hadrian, response files are no longer
+ deleted. Instead they are stored under `_build/rsp`. Response files are now
+ only used when the corresponding command-line is too long for the host
+ platform. This greatly reduces the use of response files and avoids excessive
+ file usage. Response files are overwritten on subsequent Hadrian builds.
=====================================
docs/users_guide/using.rst
=====================================
@@ -85,17 +85,6 @@ all files; you cannot, for example, invoke
``ghc -c -O1 Foo.hs -O2 Bar.hs`` to apply different optimisation levels
to the files ``Foo.hs`` and ``Bar.hs``.
-In addition to passing arguments via the command-line, arguments can be passed
-via GNU-style response files. For instance,
-
-.. code-block:: bash
-
- $ cat response-file
- -O1
- Hello.hs
- -o Hello
- $ ghc @response-file
-
.. note::
.. index::
@@ -118,9 +107,24 @@ via GNU-style response files. For instance,
``-fspecialise`` will not be enabled, since the ``-fno-specialise``
overrides the ``-fspecialise`` implied by ``-O1``.
+
+Command-line arguments in response files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In addition to passing arguments via the command-line, arguments can be passed
+via GNU-style response files. For instance,
+
+.. code-block:: bash
+
+ $ cat response-file
+ -O1
+ Hello.hs
+ -o Hello
+ $ ghc @response-file
+
.. _source-file-options:
-Command line options in source files
+Command-line options in source files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. index::
=====================================
hadrian/src/Builder.hs
=====================================
@@ -304,7 +304,7 @@ instance H.Builder Builder where
case builder of
Ar Pack stg -> do
useTempFile <- arSupportsAtFile stg
- if useTempFile then runAr path buildArgs buildInputs buildOptions
+ if useTempFile then runAr output path buildArgs buildInputs buildOptions
else runArWithoutTempFile path buildArgs buildInputs buildOptions
Ar Unpack _ -> cmd' [Cwd output] [path] buildArgs buildOptions
@@ -343,7 +343,7 @@ instance H.Builder Builder where
Exit _ <- cmd' [path] (buildArgs ++ [input]) buildOptions
return ()
- Haddock BuildPackage -> runHaddock path buildArgs buildInputs
+ Haddock BuildPackage -> runHaddock output path buildArgs buildInputs
Ghc _ _ ->
-- Use a response file for ghc invocations to avoid issues with command line
@@ -351,9 +351,11 @@ instance H.Builder Builder where
-- NB: we can't put the buildArgs in a response file, because some flags require
-- empty arguments (such as the -dep-suffix flag), but that isn't supported
-- yet due to #26560.
- withResponseFileOnWindows
- (\buildInputs' -> cmd [path] buildArgs buildInputs' buildOptions)
+ withResponseFileIfLongCmd
+ output
+ (toCmdArgument [path] <> toCmdArgument buildArgs)
buildInputs
+ (toCmdArgument buildOptions)
HsCpp -> captureStdout
@@ -389,13 +391,16 @@ instance H.Builder Builder where
-- | Invoke @haddock@ given a path to it and a list of arguments. On Windows,
-- the input file arguments are passed as a response file.
-runHaddock :: FilePath -- ^ path to @haddock@
+runHaddock :: FilePath -- ^ base name to use for response file
+ -> FilePath -- ^ path to @haddock@
-> [String]
-> [FilePath] -- ^ input file paths
-> Action ()
-runHaddock haddockPath flagArgs fileInputs = withResponseFileOnWindows
- (cmd [haddockPath] flagArgs)
+runHaddock outputFilePath haddockPath flagArgs fileInputs = withResponseFileIfLongCmd
+ outputFilePath
+ (toCmdArgument [haddockPath] <> toCmdArgument flagArgs)
fileInputs
+ (CmdArgument [])
-- TODO: Some builders are required only on certain platforms. For example,
-- 'Objdump' is only required on OpenBSD and AIX. Add support for platform
=====================================
hadrian/src/CommandLine.hs
=====================================
@@ -3,8 +3,7 @@ module CommandLine (
lookupBignum,
cmdBignum, cmdProgressInfo, cmdCompleteSetting,
cmdDocsArgs, cmdUnitIdHash, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs,
- cmdPrefix, cmdChangelogVersion, DocArgs(..), defaultDocArgs,
- cmdKeepResponseFiles
+ cmdPrefix, cmdChangelogVersion, DocArgs(..), defaultDocArgs
) where
import Data.Either
@@ -12,7 +11,7 @@ import qualified Data.HashMap.Strict as Map
import Data.List.Extra
import Development.Shake hiding (Normal)
import Flavour (DocTargets, DocTarget(..))
-import Hadrian.Utilities hiding (buildRoot, keepResponseFiles)
+import Hadrian.Utilities hiding (buildRoot)
import Settings.Parser
import System.Console.GetOpt
import System.Environment
@@ -37,7 +36,6 @@ data CommandLineArgs = CommandLineArgs
, testArgs :: TestArgs
, docsArgs :: DocArgs
, docTargets :: DocTargets
- , keepResponseFiles :: Bool
, prefix :: Maybe FilePath
, changelogVersion :: Maybe String
, completeStg :: Maybe String }
@@ -58,7 +56,6 @@ defaultCommandLineArgs = CommandLineArgs
, testArgs = defaultTestArgs
, docsArgs = defaultDocArgs
, docTargets = Set.fromList [minBound..maxBound]
- , keepResponseFiles = False
, prefix = Nothing
, changelogVersion = Nothing
, completeStg = Nothing }
@@ -141,9 +138,6 @@ readFreeze1 = Right $ \flags -> flags { freeze1 = True }
readFreeze2 = Right $ \flags -> flags { freeze1 = True, freeze2 = True }
readSkipDepends = Right $ \flags -> flags { skipDepends = True }
-readKeepResponseFiles :: Either String (CommandLineArgs -> CommandLineArgs)
-readKeepResponseFiles = Right $ \flags -> flags { keepResponseFiles = True }
-
readUnitIdHash :: Either String (CommandLineArgs -> CommandLineArgs)
readUnitIdHash = Right $ \flags ->
trace "--hash-unit-ids is deprecated. It is enabled by release flavour or +hash_unit_ids flavour transformer" $
@@ -302,8 +296,6 @@ optDescrs =
"Progress info style (None, Brief, Normal or Unicorn)."
, Option [] ["docs"] (ReqArg readDocsArg "TARGET")
"Strip down docs targets (none, no-haddocks, no-sphinx[-{html, pdfs, man}]."
- , Option ['r'] ["keep-response-files"] (NoArg readKeepResponseFiles)
- "Keep response files created during the build (for debugging)."
, Option ['k'] ["keep-test-files"] (NoArg readTestKeepFiles)
"Keep all the files generated when running the testsuite."
, Option [] ["test-compiler"] (ReqArg readTestCompiler "TEST_COMPILER")
@@ -382,7 +374,6 @@ cmdLineArgsMap = do
return $ insertExtra (progressInfo args) -- Accessed by Hadrian.Utilities
$ insertExtra (buildRoot args) -- Accessed by Hadrian.Utilities
- $ insertExtra (KeepResponseFiles $ keepResponseFiles args) -- Accessed by Hadrian.Utilities
$ insertExtra (testArgs args) -- Accessed by Settings.Builders.RunTest
$ insertExtra (docsArgs args) -- Accessed by Rules.Documentation
$ insertExtra allSettings -- Accessed by Settings
@@ -424,9 +415,6 @@ cmdUnitIdHash = unitIdHash <$> cmdLineArgs
cmdBignum :: Action (Maybe String)
cmdBignum = bignum <$> cmdLineArgs
-cmdKeepResponseFiles :: Action Bool
-cmdKeepResponseFiles = keepResponseFiles <$> cmdLineArgs
-
cmdProgressInfo :: Action ProgressInfo
cmdProgressInfo = progressInfo <$> cmdLineArgs
=====================================
hadrian/src/Hadrian/Builder/Ar.hs
=====================================
@@ -35,14 +35,16 @@ instance NFData ArMode
-- to be archived is passed via a temporary response file. Passing arguments
-- via a response file is not supported by some versions of @ar@, in which
-- case you should use 'runArWithoutTempFile' instead.
-runAr :: FilePath -- ^ path to @ar@
+runAr :: FilePath -- ^ base name to use for response files
+ -> FilePath -- ^ path to @ar@
-> [String] -- ^ other arguments
-> [FilePath] -- ^ input file paths
-> [CmdOption] -- ^ Additional options
-> Action ()
-runAr arPath flagArgs fileArgs buildOptions = withResponseFile $ \tmp -> do
- writeFile' tmp $ unwords fileArgs
- cmd [arPath] flagArgs ('@' : tmp) buildOptions
+runAr outputFilePath arPath flagArgs fileArgs buildOptions = do
+ rspFile <- responseFilePath outputFilePath
+ writeFile' rspFile $ unwords fileArgs
+ cmd [arPath] flagArgs ('@' : rspFile) buildOptions
-- | Invoke @ar@ given a path to it and a list of arguments. Note that @ar@
-- will be called multiple times if the list of files to be archived is too
=====================================
hadrian/src/Hadrian/Utilities.hs
=====================================
@@ -1,4 +1,6 @@
+{-# LANGUAGE ImpredicativeTypes #-}
{-# LANGUAGE TypeFamilies #-}
+
module Hadrian.Utilities (
-- * List manipulation
fromSingleton, replaceEq, minusOrd, intersectOrd, lookupAll, chunksOfSize,
@@ -14,7 +16,7 @@ module Hadrian.Utilities (
-- * Paths
BuildRoot (..), buildRoot, buildRootRules, isGeneratedSource,
- KeepResponseFiles (..), keepResponseFiles, withResponseFile, withResponseFileOnWindows,
+ withResponseFileIfLongCmd, responseFilePath,
-- * File system operations
copyFile, copyFileUntracked, createFileLink, fixFile,
@@ -47,11 +49,10 @@ import Data.Maybe
import Data.Typeable (TypeRep, typeOf)
import Development.Shake hiding (Normal)
import Development.Shake.Classes
+import Development.Shake.Command (CmdArgument (..), IsCmdArgument (toCmdArgument))
import Development.Shake.FilePath
import GHC.ResponseFile (escapeArgs)
import System.Environment (lookupEnv)
-import System.Info.Extra (isWindows)
-import System.IO (hClose, openTempFile)
import System.IO.Error (isPermissionError)
import qualified Data.ByteString as BS
@@ -255,13 +256,13 @@ infix 1 %%>
-- library, they can reach 2MB! Some operating systems do not support command
-- lines of such length, and this function can be used to obtain a reasonable
-- approximation of the limit. On Windows, it is theoretically 32768 characters
--- (since Windows 7). In practice we use 31000 to leave some breathing space for
+-- (since Windows 7). In practice we use 30000 to leave some breathing space for
-- the builder path & name, auxiliary flags, and other overheads. On Mac OS X,
-- ARG_MAX is 262144, yet when using @xargs@ on OSX this is reduced by over
-- 20000. Hence, 200000 seems like a sensible limit. On other operating systems
-- we currently use the 4194304 setting.
cmdLineLengthLimit :: Int
-cmdLineLengthLimit | IO.isWindows = 31000
+cmdLineLengthLimit | IO.isWindows = 30000
| IO.isMac = 200000
| otherwise = 4194304
@@ -321,53 +322,35 @@ buildRootRules = do
isGeneratedSource :: FilePath -> Action Bool
isGeneratedSource file = buildRoot <&> (`isPrefixOf` file)
-newtype KeepResponseFiles = KeepResponseFiles Bool deriving (Eq, Show)
-
--- | Whether to retain response files after the build action that created them
--- completes. Mainly useful for debugging.
-keepResponseFiles :: Action Bool
-keepResponseFiles = do
- KeepResponseFiles keep <- userSetting (KeepResponseFiles False)
- return keep
-
--- | Run an action either with command arguments direcly or by, on Windows,
--- placing those arguments into a response file escaped with @GHC.ResponseFile.escapeArgs@.
---
--- With @--keep-response-files@, the file is left on disk (if used)
-withResponseFileOnWindows ::
- ([String] -> Action a) -- ^ Action to perform given arguments (of the form @["\@reponseFilePath"]@ on Windows)
- -> [String] -- ^ Command arguments
- -> Action a
-withResponseFileOnWindows action commandArgs = do
- if isWindows
- then withResponseFile $ \tmp -> do
- writeFile' tmp (escapeArgs commandArgs)
- action ['@' : tmp]
- else action commandArgs
-
--- | Run an action with a response file path.
---
--- With @--keep-response-files@, the file is left on disk.
-withResponseFile :: (FilePath -> Action a) -> Action a
-withResponseFile action = do
- keep <- keepResponseFiles
- let putVerboseResponseFile tmp = do
- verbosity <- getVerbosity
- when (verbosity >= Verbose) $ do
- tmpContent <- liftIO (readFile tmp)
- putVerbose (tmp <> " (use hadrian flag --keep-response-files to keep this file):\n" <> tmpContent)
- if keep
- then do
- (tmp, h) <- liftIO $ openTempFile "." "hadrian-rsp"
- liftIO $ hClose h
- putInfo $ "Keeping response file: " ++ tmp
- result <- action tmp
- putVerboseResponseFile tmp
- return result
- else withTempFile $ \tmp -> do
- result <- action tmp
- putVerboseResponseFile tmp
- return result
+-- | Run an command with the given arguments. If the command is too long then the
+-- response file arguments are placed into a response file and escaped with @GHC.ResponseFile.escapeArgs@.
+withResponseFileIfLongCmd ::
+ CmdResult c
+ => FilePath -- ^ Response base name. The reponse file is placed in @_build/rsp/\<Response base name\>@.
+ -> CmdArgument -- ^ Command and arguments before the response file arguments.
+ -> [String] -- ^ Response file aruguments.
+ -> CmdArgument -- ^ Command arguments after the response file arguments.
+ -> Action c
+withResponseFileIfLongCmd outputFilePath argsPre argsResp argsPost = do
+ let cmdLineLengh = sum
+ [ 1 + length arg -- add one to account for space inbetween arguments
+ | let CmdArgument args = argsPre <> toCmdArgument argsResp <> argsPost
+ , Right arg <- args
+ ]
+ if cmdLineLengh < cmdLineLengthLimit
+ then cmd argsPre argsResp argsPost
+ else do
+ rspFile <- responseFilePath outputFilePath
+ writeFile' rspFile (escapeArgs argsResp)
+ cmd argsPre ['@' : rspFile] argsPost
+
+-- | Convert a command's output file path to a response file path to be used for that command.
+-- Response files are placed in a dedicated @rps@ directory under the build directory. This avoids
+-- clutering the work tree or interfearing with other build directories.
+responseFilePath :: FilePath -> Action FilePath
+responseFilePath outputFilePath = do
+ buildDir <- buildRoot
+ return $ buildDir </> "rsp" </> outputFilePath
-- | Link a file tracking the link target. Create the target directory if
-- missing.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/498bb21afd3852bd99d001ac5b20eeb…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/498bb21afd3852bd99d001ac5b20eeb…
You're receiving this email because of your account on gitlab.haskell.org.
1
0