diff options
author | Bartosz Nitka <niteria@gmail.com> | 2015-07-17 16:50:52 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2015-07-17 16:51:18 +0100 |
commit | 3448f9827d2364b91bc60134aa38b74849b9d54e (patch) | |
tree | 6d818b58b8547eabbe42777b47f6cf0042c2fb35 /compiler | |
parent | a5e9da8feb5110ab8ee8fe3821e6b6d53946f983 (diff) | |
download | haskell-3448f9827d2364b91bc60134aa38b74849b9d54e.tar.gz |
Reduce non-determinism in ABI hashes with RULES and instance decls
Summary:
Before this change the `RULES` would be attached to one for the names from
the module that appear on the left hand side. The choice depended on the
`uniq` that was generated, which are known to be non-deterministic (a
separate, bigger problem). Now we use `OccName`s which should be stable.
Analogously for instance declarations, but they are attached to one of
the types involved.
Test Plan:
contbuild
it made `Data.Text.Internal.Fusion.Common` interface stable, previously
stream fusion rule would be attached either to `streamList` or
`unstreamList` depending on if the module was compiled after `cabal
clean` or after `find | grep '\.o$' | xargs rm`.
Reviewers: simonpj, austin, bgamari, simonmar
Subscribers: puffnfresh, thomie
Differential Revision: https://phabricator.haskell.org/D1073
GHC Trac Issues: #4012
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/specialise/Rules.hs | 12 | ||||
-rw-r--r-- | compiler/types/InstEnv.hs | 13 |
2 files changed, 19 insertions, 6 deletions
diff --git a/compiler/specialise/Rules.hs b/compiler/specialise/Rules.hs index cb71e3a3f3..7cf6e56bb7 100644 --- a/compiler/specialise/Rules.hs +++ b/compiler/specialise/Rules.hs @@ -180,9 +180,15 @@ mkRule this_mod is_auto is_local name act fn bndrs args rhs lhs_names = nameSetElems (extendNameSet (exprsOrphNames args) fn) -- TODO: copied from ruleLhsOrphNames - orph = case filter (nameIsLocalOrFrom this_mod) lhs_names of - (n : _) -> NotOrphan (nameOccName n) - [] -> IsOrphan + -- Since rules get eventually attached to one of the free names + -- from the definition when compiling the ABI hash, we should make + -- it deterministic. This chooses the one with minimal OccName + -- as opposed to uniq value. + local_lhs_names = filter (nameIsLocalOrFrom this_mod) lhs_names + anchor = minimum $ map nameOccName local_lhs_names + orph = case local_lhs_names of + (_ : _) -> NotOrphan anchor + [] -> IsOrphan -------------- roughTopNames :: [CoreExpr] -> [Maybe Name] diff --git a/compiler/types/InstEnv.hs b/compiler/types/InstEnv.hs index f810850d4b..db8f531a58 100644 --- a/compiler/types/InstEnv.hs +++ b/compiler/types/InstEnv.hs @@ -236,10 +236,17 @@ mkLocalInstance dfun oflag tvs cls tys do_one (_ltvs, rtvs) = choose_one [ns | (tv,ns) <- cls_tvs `zip` arg_names , not (tv `elem` rtvs)] + -- Since instance declarations get eventually attached to one of the types + -- from the definition when compiling the ABI hash, we should make + -- it deterministic. This chooses the one with minimal OccName + -- as opposed to uniq value. choose_one :: [NameSet] -> IsOrphan - choose_one nss = case nameSetElems (unionNameSets nss) of - [] -> IsOrphan - (n : _) -> NotOrphan (nameOccName n) + choose_one nss = case local_names of + [] -> IsOrphan + (_ : _) -> NotOrphan anchor + where + local_names = nameSetElems (unionNameSets nss) + anchor = minimum $ map nameOccName local_names mkImportedInstance :: Name -> [Maybe Name] |