diff options
author | Ben Gamari <bgamari.foss@gmail.com> | 2016-10-13 21:53:13 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2016-10-13 22:57:13 -0400 |
commit | 34d933d6a821edf5abfcbee76d9325362fc28a13 (patch) | |
tree | c371fe1f7d1b6ea6d8b3fb9185d10bf4115fb2e6 /compiler/prelude/KnownUniques.hs | |
parent | 1cccb646e2e4bcf3bbb1f2ad01737f7e745b5f1b (diff) | |
download | haskell-34d933d6a821edf5abfcbee76d9325362fc28a13.tar.gz |
Clean up handling of known-key Names in interface files
Previously BinIface had some dedicated logic for handling tuple names in
the symbol table. As it turns out, this logic was essentially dead code
as it was superceded by the special handling of known-key things. Here
we cull the tuple code-path and use the known-key codepath for all
tuple-ish things.
This had a surprising number of knock-on effects,
* constraint tuple datacons had to be made known-key (previously they
were not)
* IfaceTopBndr was changed from being a synonym of OccName to a
synonym of Name (since we now need to be able to deserialize Names
directly from interface files)
* the change to IfaceTopBndr complicated fingerprinting, since we need
to ensure that we don't go looking for the fingerprint of the thing
we are currently fingerprinting in the fingerprint environment (see
notes in MkIface). Handling this required distinguishing between
binding and non-binding Name occurrences in the Binary serializers.
* the original name cache logic which previously lived in IfaceEnv has
been moved to a new NameCache module
* I ripped tuples and sums out of knownKeyNames since they introduce a
very large number of entries. During interface file deserialization
we use static functions (defined in the new KnownUniques module) to
map from a Unique to a known-key Name (the Unique better correspond
to a known-key name!) When we need to do an original name cache
lookup we rely on the parser implemented in isBuiltInOcc_maybe.
* HscMain.allKnownKeyNames was folded into PrelInfo.knownKeyNames.
* Lots of comments were sprinkled about describing the new scheme.
Updates haddock submodule.
Test Plan: Validate
Reviewers: niteria, simonpj, austin, hvr
Reviewed By: simonpj
Subscribers: simonmar, niteria, thomie
Differential Revision: https://phabricator.haskell.org/D2467
GHC Trac Issues: #12532, #12415
Diffstat (limited to 'compiler/prelude/KnownUniques.hs')
-rw-r--r-- | compiler/prelude/KnownUniques.hs | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/compiler/prelude/KnownUniques.hs b/compiler/prelude/KnownUniques.hs new file mode 100644 index 0000000000..2dc6f8388d --- /dev/null +++ b/compiler/prelude/KnownUniques.hs @@ -0,0 +1,150 @@ +{-# LANGUAGE CPP #-} + +-- | This is where we define a mapping from Uniques to their associated +-- known-key Names for things associated with tuples and sums. We use this +-- mapping while deserializing known-key Names in interface file symbol tables, +-- which are encoded as their Unique. See Note [Symbol table representation of +-- names] for details. +-- + +module KnownUniques + ( -- * Looking up known-key names + knownUniqueName + + -- * Getting the 'Unique's of 'Name's + -- ** Anonymous sums + , mkSumTyConUnique + , mkSumDataConUnique + -- ** Tuples + -- *** Vanilla + , mkTupleTyConUnique + , mkTupleDataConUnique + -- *** Constraint + , mkCTupleTyConUnique + , mkCTupleDataConUnique + ) where + +#include "HsVersions.h" + +import TysWiredIn +import TyCon +import DataCon +import Id +import BasicTypes +import Outputable +import Unique +import Name +import Util + +import Data.Bits +import Data.Maybe + +-- | Get the 'Name' associated with a known-key 'Unique'. +knownUniqueName :: Unique -> Maybe Name +knownUniqueName u = + case tag of + 'z' -> Just $ getUnboxedSumName n + '4' -> Just $ getTupleTyConName Boxed n + '5' -> Just $ getTupleTyConName Unboxed n + '7' -> Just $ getTupleDataConName Boxed n + '8' -> Just $ getTupleDataConName Unboxed n + 'k' -> Just $ getCTupleTyConName n + 'm' -> Just $ getCTupleDataConUnique n + _ -> Nothing + where + (tag, n) = unpkUnique u + +-------------------------------------------------- +-- Anonymous sums +-- +-- Sum arities start from 2. The encoding is a bit funny: we break up the +-- integral part into bitfields for the arity and alternative index (which is +-- taken to be 0xff in the case of the TyCon) +-- +-- TyCon for sum of arity k: +-- 00000000 kkkkkkkk 11111111 +-- DataCon for sum of arity k and alternative n (zero-based): +-- 00000000 kkkkkkkk nnnnnnnn + +mkSumTyConUnique :: Arity -> Unique +mkSumTyConUnique arity = + ASSERT(arity < 0xff) + mkUnique 'z' (arity `shiftL` 8 .|. 0xff) + +mkSumDataConUnique :: ConTagZ -> Arity -> Unique +mkSumDataConUnique alt arity + | alt >= arity + = panic ("mkSumDataConUnique: " ++ show alt ++ " >= " ++ show arity) + | otherwise + = mkUnique 'z' (arity `shiftL` 8 + alt) {- skip the tycon -} + +getUnboxedSumName :: Int -> Name +getUnboxedSumName n = + case n .&. 0xff of + 0xff -> tyConName $ sumTyCon arity + alt -> dataConName $ sumDataCon (alt + 1) arity + where arity = n `shiftR` 8 + +-- Note [Uniques for tuple type and data constructors] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- +-- Wired-in type constructor keys occupy *two* slots: +-- * u: the TyCon itself +-- * u+1: the TyConRepName of the TyCon +-- +-- Wired-in tuple data constructor keys occupy *three* slots: +-- * u: the DataCon itself +-- * u+1: its worker Id +-- * u+2: the TyConRepName of the promoted TyCon + +-------------------------------------------------- +-- Constraint tuples + +mkCTupleTyConUnique :: Arity -> Unique +mkCTupleTyConUnique a = mkUnique 'k' (2*a) + +mkCTupleDataConUnique :: Arity -> Unique +mkCTupleDataConUnique a = mkUnique 'm' (3*a) + +getCTupleTyConName :: Int -> Name +getCTupleTyConName n = + case n `divMod` 2 of + (arity, 0) -> cTupleTyConName arity + (arity, 1) -> mkPrelTyConRepName $ cTupleTyConName arity + _ -> panic "getCTupleTyConName: impossible" + +getCTupleDataConUnique :: Int -> Name +getCTupleDataConUnique n = + case n `divMod` 3 of + (arity, 0) -> cTupleDataConName arity + (_arity, 1) -> panic "getCTupleDataConName: no worker" + (arity, 2) -> mkPrelTyConRepName $ cTupleDataConName arity + _ -> panic "getCTupleDataConName: impossible" + +-------------------------------------------------- +-- Normal tuples + +mkTupleDataConUnique :: Boxity -> Arity -> Unique +mkTupleDataConUnique Boxed a = mkUnique '7' (3*a) -- may be used in C labels +mkTupleDataConUnique Unboxed a = mkUnique '8' (3*a) + +mkTupleTyConUnique :: Boxity -> Arity -> Unique +mkTupleTyConUnique Boxed a = mkUnique '4' (2*a) +mkTupleTyConUnique Unboxed a = mkUnique '5' (2*a) + +getTupleTyConName :: Boxity -> Int -> Name +getTupleTyConName boxity n = + case n `divMod` 2 of + (arity, 0) -> tyConName $ tupleTyCon boxity arity + (arity, 1) -> fromMaybe (panic "getTupleTyConName") + $ tyConRepName_maybe $ tupleTyCon boxity arity + _ -> panic "getTupleTyConName: impossible" + +getTupleDataConName :: Boxity -> Int -> Name +getTupleDataConName boxity n = + case n `divMod` 3 of + (arity, 0) -> dataConName $ tupleDataCon boxity arity + (arity, 1) -> idName $ dataConWorkId $ tupleDataCon boxity arity + (arity, 2) -> fromMaybe (panic "getTupleDataCon") + $ tyConRepName_maybe $ promotedTupleDataCon boxity arity + _ -> panic "getTupleDataConName: impossible" |