-
ca27a516
by Jannis at 2026-07-08T18:21:35+02:00
Division by constants optimization
-
1f32959f
by Rodrigo Mesquita at 2026-07-08T18:21:35+02:00
determinism: Sampling uniques in the CG
To achieve object determinism, the passes processing Cmm and the rest of
the code generation pipeline musn't create new uniques which are
non-deterministic.
This commit changes occurrences of non-deterministic unique sampling
within these code generation passes by a deterministic unique sampling
strategy by propagating and threading through a deterministic
incrementing counter in them. The threading is done implicitly with
`UniqDSM` and `UniqDSMT`.
Secondly, the `DUniqSupply` used to run a `UniqDSM` must be threaded
through all passes to guarantee uniques in different passes are unique
amongst them altogether. Specifically, the same `DUniqSupply` must be
threaded through the CG Streaming pipeline, starting with Driver.Main
calling `StgToCmm.codeGen`, `cmmPipeline`, `cmmToRawCmm`, and
`codeOutput` in sequence.
To thread resources through the `Stream` abstraction, we use the `UniqDSMT`
transformer on top of `IO` as the Monad underlying the Stream. `UniqDSMT` will
thread the `DUniqSupply` through every pass applied to the `Stream`, for every
element. We use @type CgStream = Stream (UniqDSMT IO)@ for the Stream used in
code generation which that carries through the deterministic unique supply.
See Note [Deterministic Uniques in the CG]
-
7e331c4a
by Rodrigo Mesquita at 2026-07-08T18:21:35+02:00
determinism: DCmmGroup vs CmmGroup
Part of our strategy in producing deterministic objects, namely,
renaming all Cmm uniques in order, depend on the object code produced
having a deterministic order (say, A_closure always comes before
B_closure).
However, the use of LabelMaps in the Cmm representation invalidated this
requirement because the LabelMaps elements would already be in a
non-deterministic order (due to the original uniques), and the renaming
in sequence wouldn't work because of that non-deterministic order.
Therefore, we now start off with lists in CmmGroup (which preserve the
original order), and convert them into LabelMaps (for performance in the
code generator) after the uniques of the list elements have been
renamed.
See Note [DCmmGroup vs CmmGroup or: Deterministic Info Tables] and #12935.
Co-authored-by: Matthew Pickering <matthewtpickering@gmail.com>
-
20fc7733
by Rodrigo Mesquita at 2026-07-08T18:21:35+02:00
determinism: Cmm unique renaming pass
To achieve object determinism, we need to prevent the non-deterministic
uniques from leaking into the object code. We can do this by
deterministically renaming the non-external uniques in the Cmm groups
that are yielded right after StgToCmm.
The key to deterministic renaming is observing that the order of
declarations, instructions, and data in the Cmm groups are already
deterministic (modulo other determinism bugs), regardless of the
uniques. We traverse the Cmm AST in this deterministic order and
rename the uniques, incrementally, in the order they are found, thus
making them deterministic. This renaming is guarded by
-fobject-determinism which is disabled by default for now.
This is one of the key passes for object determinism. Read about the
overview of object determinism and a more detailed explanation of this
pass in:
* Note [Object determinism]
* Note [Renaming uniques deterministically]
Significantly closes the gap to #12935
-
aad980e3
by Ben Gamari at 2026-07-08T18:21:35+02:00
Revert "Division by constants optimization"
This appears to be responsible for the regression described in #25653.
This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb.
-
84a4b44d
by Rodrigo Mesquita at 2026-07-08T18:21:35+02:00
hi: Stable sort avails
Sorting the Avails in DocStructures is required to produce fully
deterministic interface files in presence of re-exported modules.
Fixes #25104
-
d0a4ba37
by Ian-Woo Kim at 2026-07-08T18:21:35+02:00
determinism: Interface re-export list det
In 'DocStructureItem' we want to make sure the 'Avails' are sorted, for
interface file determinism. This commit introduces 'DetOrdAvails', a
newtype that should only be constructed by sorting Avails with
'sortAvails' unless the avails are known to be deterministically
ordered. This newtype is used by 'DocStructureItem' where 'Avails' was
previously used to ensure the list of avails is deterministically sorted
by construction.
Note: Even though we order the constructors and avails in the interface
file, the order of constructors in the haddock output is still
determined from the order of declaration in the source. This was also
true before, when the list of constructors in the interface file <docs>
section was non-deterministic. Some haddock tests such as
"ConstructorArgs" observe this (check the order of constructors in
out/ConstructorArgs.html vs src/ConstructorArgs.hs vs its interface file)
The updated tests are caused by haddock corners where the order in the
source is not preserved (and was non-deterministic before this PR):
* Module header in the latex backend
* Re-export of pattern synonyms associated to a datatype (#25342)
Fixes #25304
authored by Rodrigo Mesquita
-
f3a0e2f2
by Ian-Woo Kim at 2026-07-08T18:21:35+02:00
WIP: determinism: sort dependent file
- sort on dependent_files
- sort on fingerprint for usage
-
d4300dd3
by Matthew Pickering at 2026-07-08T18:21:35+02:00
determinism: Use deterministic map for Strings in TyLitMap
When generating typeable evidence the types we need evidence for all
cached in a TypeMap, the order terms are retrieved from a type map
determines the order the bindings appear in the program.
A TypeMap is quite diligent to use deterministic maps, apart from in the
TyLitMap, which uses a UniqFM for storing strings, whose ordering
depends on the Unique of the FastString.
This can cause non-deterministic .hi and .o files.
Fixes #26846
-
e8bf7fae
by Matthew Pickering at 2026-07-08T18:21:35+02:00
determinism: Use a stable sort in WithHsDocIdentifiers binary instance
`WithHsDocIdentifiers` is defined as
```
71 data WithHsDocIdentifiers a pass = WithHsDocIdentifiers
72 { hsDocString :: !a
73 , hsDocIdentifiers :: ![Located (IdP pass)]
74 }
```
This list of names is populated from `rnHsDocIdentifiers`, which calls
`lookupGRE`, which calls `lookupOccEnv_AllNameSpaces`, which calls
`nonDetEltsUFM` and returns the results in an order depending on
uniques.
Sorting the list with a stable sort before returning the interface makes
the output deterministic and follows the approach taken by other fields
in `Docs`.
Fixes #26858