diff options
author | Richard Eisenberg <rae@cs.brynmawr.edu> | 2016-12-14 21:37:43 -0500 |
---|---|---|
committer | Richard Eisenberg <rae@cs.brynmawr.edu> | 2017-01-19 10:31:52 -0500 |
commit | e7985ed23ddc68b6a2e4af753578dc1d9e8ab4c9 (patch) | |
tree | ba8c4016e218710f8165db92d4b4c10e5559245a /compiler/simplStg | |
parent | 38374caa9d6e1373d1b9d335d0f99f3664931fd9 (diff) | |
download | haskell-e7985ed23ddc68b6a2e4af753578dc1d9e8ab4c9.tar.gz |
Update levity polymorphism
This commit implements the proposal in
https://github.com/ghc-proposals/ghc-proposals/pull/29 and
https://github.com/ghc-proposals/ghc-proposals/pull/35.
Here are some of the pieces of that proposal:
* Some of RuntimeRep's constructors have been shortened.
* TupleRep and SumRep are now parameterized over a list of RuntimeReps.
* This
means that two types with the same kind surely have the same
representation.
Previously, all unboxed tuples had the same kind, and thus the fact
above was
false.
* RepType.typePrimRep and friends now return a *list* of PrimReps. These
functions can now work successfully on unboxed tuples. This change is
necessary because we allow abstraction over unboxed tuple types and so
cannot
always handle unboxed tuples specially as we did before.
* We sometimes have to create an Id from a PrimRep. I thus split PtrRep
* into
LiftedRep and UnliftedRep, so that the created Ids have the right
strictness.
* The RepType.RepType type was removed, as it didn't seem to help with
* much.
* The RepType.repType function is also removed, in favor of typePrimRep.
* I have waffled a good deal on whether or not to keep VoidRep in
TyCon.PrimRep. In the end, I decided to keep it there. PrimRep is *not*
represented in RuntimeRep, and typePrimRep will never return a list
including
VoidRep. But it's handy to have in, e.g., ByteCodeGen and friends. I can
imagine another design choice where we have a PrimRepV type that is
PrimRep
with an extra constructor. That seemed to be a heavier design, though,
and I'm
not sure what the benefit would be.
* The last, unused vestiges of # (unliftedTypeKind) have been removed.
* There were several pretty-printing bugs that this change exposed;
* these are fixed.
* We previously checked for levity polymorphism in the types of binders.
* But we
also must exclude levity polymorphism in function arguments. This is
hard to check
for, requiring a good deal of care in the desugarer. See Note [Levity
polymorphism
checking] in DsMonad.
* In order to efficiently check for levity polymorphism in functions, it
* was necessary
to add a new bit of IdInfo. See Note [Levity info] in IdInfo.
* It is now safe for unlifted types to be unsaturated in Core. Core Lint
* is updated
accordingly.
* We can only know strictness after zonking, so several checks around
* strictness
in the type-checker (checkStrictBinds, the check for unlifted variables
under a ~
pattern) have been moved to the desugarer.
* Along the way, I improved the treatment of unlifted vs. banged
* bindings. See
Note [Strict binds checks] in DsBinds and #13075.
* Now that we print type-checked source, we must be careful to print
* ConLikes correctly.
This is facilitated by a new HsConLikeOut constructor to HsExpr.
Particularly troublesome
are unlifted pattern synonyms that get an extra void# argument.
* Includes a submodule update for haddock, getting rid of #.
* New testcases:
typecheck/should_fail/StrictBinds
typecheck/should_fail/T12973
typecheck/should_run/StrictPats
typecheck/should_run/T12809
typecheck/should_fail/T13105
patsyn/should_fail/UnliftedPSBind
typecheck/should_fail/LevPolyBounded
typecheck/should_compile/T12987
typecheck/should_compile/T11736
* Fixed tickets:
#12809
#12973
#11736
#13075
#12987
* This also adds a test case for #13105. This test case is
* "compile_fail" and
succeeds, because I want the testsuite to monitor the error message.
When #13105 is fixed, the test case will compile cleanly.
Diffstat (limited to 'compiler/simplStg')
-rw-r--r-- | compiler/simplStg/RepType.hs | 341 | ||||
-rw-r--r-- | compiler/simplStg/UnariseStg.hs | 58 |
2 files changed, 198 insertions, 201 deletions
diff --git a/compiler/simplStg/RepType.hs b/compiler/simplStg/RepType.hs index 6309aecb3a..f59a8548f1 100644 --- a/compiler/simplStg/RepType.hs +++ b/compiler/simplStg/RepType.hs @@ -2,37 +2,40 @@ {-# LANGUAGE FlexibleContexts #-} module RepType - ( -- * Code generator views onto Types + ( + -- * Code generator views onto Types UnaryType, NvUnaryType, isNvUnaryType, - RepType(..), repType, repTypeArgs, isUnaryRep, isMultiRep, + unwrapType, -- * Predicates on types - isVoidTy, typePrimRep, + isVoidTy, -- * Type representation for the code generator - countConRepArgs, idFunRepArity, tyConPrimRep, + typePrimRep, typePrimRep1, + runtimeRepPrimRep, typePrimRepArgs, + PrimRep(..), primRepToType, + countFunRepArgs, countConRepArgs, tyConPrimRep, tyConPrimRep1, -- * Unboxed sum representation type - ubxSumRepType, layout, typeSlotTy, SlotTy (..), slotTyToType, - slotPrimRep, repTypeSlots + ubxSumRepType, layoutUbxSum, typeSlotTy, SlotTy (..), + slotPrimRep, primRepSlot ) where #include "HsVersions.h" import BasicTypes (Arity, RepArity) import DataCon -import Id import Outputable import PrelNames +import Coercion import TyCon import TyCoRep import Type -import TysPrim -import TysWiredIn import Util +import TysPrim +import {-# SOURCE #-} TysWiredIn ( anyTypeOfKind ) import Data.List (foldl', sort) -import Data.Maybe (maybeToList) import qualified Data.IntSet as IS {- ********************************************************************** @@ -49,101 +52,64 @@ type UnaryType = Type -- NvUnaryType : never an unboxed tuple or sum, or void -- -- UnaryType : never an unboxed tuple or sum; - -- can be Void# (but not (# #)) + -- can be Void# or (# #) isNvUnaryType :: Type -> Bool isNvUnaryType ty - = case repType ty of - UnaryRep _ -> True - MultiRep ss -> not (null ss) - -data RepType - = MultiRep [SlotTy] -- Represented by multiple values (e.g. unboxed tuple or sum) - | UnaryRep NvUnaryType -- Represented by a single value; but never Void#, or any - -- other zero-width type (isVoidTy) - -instance Outputable RepType where - ppr (MultiRep slots) = text "MultiRep" <+> ppr slots - ppr (UnaryRep ty) = text "UnaryRep" <+> ppr ty - -isMultiRep :: RepType -> Bool -isMultiRep (MultiRep _) = True -isMultiRep _ = False - -isUnaryRep :: RepType -> Bool -isUnaryRep (UnaryRep _) = True -isUnaryRep _ = False + | [_] <- typePrimRep ty + = True + | otherwise + = False -- INVARIANT: the result list is never empty. -repTypeArgs :: Type -> [UnaryType] -repTypeArgs ty = case repType ty of - MultiRep [] -> [voidPrimTy] - MultiRep slots -> map slotTyToType slots - UnaryRep ty -> [ty] - -repTypeSlots :: RepType -> [SlotTy] -repTypeSlots (MultiRep slots) = slots -repTypeSlots (UnaryRep ty) = maybeToList (typeSlotTy ty) - --- | 'repType' figure out how a type will be represented at runtime. It looks --- through --- --- 1. For-alls --- 2. Synonyms --- 3. Predicates --- 4. All newtypes, including recursive ones, but not newtype families --- 5. Casts --- -repType :: Type -> RepType -repType ty - = go initRecTc ty +typePrimRepArgs :: Type -> [PrimRep] +typePrimRepArgs ty + | [] <- reps + = [VoidRep] + | otherwise + = reps where - go :: RecTcChecker -> Type -> RepType - go rec_nts ty -- Expand predicates and synonyms - | Just ty' <- coreView ty - = go rec_nts ty' - - go rec_nts (ForAllTy _ ty2) -- Drop type foralls - = go rec_nts ty2 - - go rec_nts ty@(TyConApp tc tys) -- Expand newtypes - | isNewTyCon tc - , tys `lengthAtLeast` tyConArity tc - , Just rec_nts' <- checkRecTc rec_nts tc -- See Note [Expanding newtypes] in TyCon - = go rec_nts' (newTyConInstRhs tc tys) - - | isUnboxedTupleTyCon tc - = MultiRep (concatMap (repTypeSlots . go rec_nts) non_rr_tys) - - | isUnboxedSumTyCon tc - = MultiRep (ubxSumRepType non_rr_tys) - - | isVoidTy ty - = MultiRep [] - where - -- See Note [Unboxed tuple RuntimeRep vars] in TyCon - non_rr_tys = dropRuntimeRepArgs tys - - go rec_nts (CastTy ty _) - = go rec_nts ty - - go _ ty@(CoercionTy _) - = pprPanic "repType" (ppr ty) - - go _ ty = UnaryRep ty - - -idFunRepArity :: Id -> RepArity -idFunRepArity x = countFunRepArgs (idArity x) (idType x) + reps = typePrimRep ty + +-- | Gets rid of the stuff that prevents us from understanding the +-- runtime representation of a type. Including: +-- 1. Casts +-- 2. Newtypes +-- 3. Foralls +-- 4. Synonyms +-- But not type/data families, because we don't have the envs to hand. +unwrapType :: Type -> Type +unwrapType ty + | Just (_, unwrapped) + <- topNormaliseTypeX stepper mappend inner_ty + = unwrapped + | otherwise + = inner_ty + where + inner_ty = go ty + + go t | Just t' <- coreView t = go t' + go (ForAllTy _ t) = go t + go (CastTy t _) = go t + go t = t + + -- cf. Coercion.unwrapNewTypeStepper + stepper rec_nts tc tys + | Just (ty', _) <- instNewTyCon_maybe tc tys + = case checkRecTc rec_nts tc of + Just rec_nts' -> NS_Step rec_nts' (go ty') () + Nothing -> NS_Abort -- infinite newtypes + | otherwise + = NS_Done countFunRepArgs :: Arity -> Type -> RepArity countFunRepArgs 0 _ = 0 countFunRepArgs n ty - | UnaryRep (FunTy arg res) <- repType ty - = length (repTypeArgs arg) + countFunRepArgs (n - 1) res + | FunTy arg res <- unwrapType ty + = length (typePrimRepArgs arg) + countFunRepArgs (n - 1) res | otherwise - = pprPanic "countFunRepArgs: arity greater than type can handle" (ppr (n, ty, repType ty)) + = pprPanic "countFunRepArgs: arity greater than type can handle" (ppr (n, ty, typePrimRep ty)) countConRepArgs :: DataCon -> RepArity countConRepArgs dc = go (dataConRepArity dc) (dataConRepType dc) @@ -152,14 +118,14 @@ countConRepArgs dc = go (dataConRepArity dc) (dataConRepType dc) go 0 _ = 0 go n ty - | UnaryRep (FunTy arg res) <- repType ty - = length (repTypeSlots (repType arg)) + go (n - 1) res + | FunTy arg res <- unwrapType ty + = length (typePrimRep arg) + go (n - 1) res | otherwise - = pprPanic "countConRepArgs: arity greater than type can handle" (ppr (n, ty, repType ty)) + = pprPanic "countConRepArgs: arity greater than type can handle" (ppr (n, ty, typePrimRep ty)) -- | True if the type has zero width. isVoidTy :: Type -> Bool -isVoidTy ty = typePrimRep ty == VoidRep +isVoidTy = null . typePrimRep {- ********************************************************************** @@ -176,52 +142,59 @@ type SortedSlotTys = [SlotTy] -- -- E.g. -- --- (# Int | Maybe Int | (# Int, Bool #) #) +-- (# Int# | Maybe Int | (# Int#, Float# #) #) -- --- We call `ubxSumRepType [ Int, Maybe Int, (# Int,Bool #) ]`, --- which returns [Tag#, PtrSlot, PtrSlot] +-- We call `ubxSumRepType [ [IntRep], [LiftedRep], [IntRep, FloatRep] ]`, +-- which returns [WordSlot, PtrSlot, WordSlot, FloatSlot] -- -- INVARIANT: Result slots are sorted (via Ord SlotTy), except that at the head -- of the list we have the slot for the tag. -ubxSumRepType :: [Type] -> [SlotTy] -ubxSumRepType constrs0 = - ASSERT2( length constrs0 > 1, ppr constrs0 ) -- otherwise it isn't a sum type - let - combine_alts :: [SortedSlotTys] -- slots of constructors - -> SortedSlotTys -- final slots - combine_alts constrs = foldl' merge [] constrs - - merge :: SortedSlotTys -> SortedSlotTys -> SortedSlotTys - merge existing_slots [] - = existing_slots - merge [] needed_slots - = needed_slots - merge (es : ess) (s : ss) - | Just s' <- s `fitsIn` es - = -- found a slot, use it - s' : merge ess ss - | s < es - = -- we need a new slot and this is the right place for it - s : merge (es : ess) ss - | otherwise - = -- keep searching for a slot - es : merge ess (s : ss) - - -- Nesting unboxed tuples and sums is OK, so we need to flatten first. - rep :: Type -> SortedSlotTys - rep ty = sort (repTypeSlots (repType ty)) - - sumRep = WordSlot : combine_alts (map rep constrs0) - -- WordSlot: for the tag of the sum - in - sumRep - -layout :: SortedSlotTys -- Layout of sum. Does not include tag. - -- We assume that they are in increasing order - -> [SlotTy] -- Slot types of things we want to map to locations in the - -- sum layout - -> [Int] -- Where to map 'things' in the sum layout -layout sum_slots0 arg_slots0 = +ubxSumRepType :: [[PrimRep]] -> [SlotTy] +ubxSumRepType constrs0 + -- These first two cases never classify an actual unboxed sum, which always + -- has at least two disjuncts. But it could happen if a user writes, e.g., + -- forall (a :: TYPE (SumRep [IntRep])). ... + -- which could never be instantiated. We still don't want to panic. + | length constrs0 < 2 + = [WordSlot] + + | otherwise + = let + combine_alts :: [SortedSlotTys] -- slots of constructors + -> SortedSlotTys -- final slots + combine_alts constrs = foldl' merge [] constrs + + merge :: SortedSlotTys -> SortedSlotTys -> SortedSlotTys + merge existing_slots [] + = existing_slots + merge [] needed_slots + = needed_slots + merge (es : ess) (s : ss) + | Just s' <- s `fitsIn` es + = -- found a slot, use it + s' : merge ess ss + | s < es + = -- we need a new slot and this is the right place for it + s : merge (es : ess) ss + | otherwise + = -- keep searching for a slot + es : merge ess (s : ss) + + -- Nesting unboxed tuples and sums is OK, so we need to flatten first. + rep :: [PrimRep] -> SortedSlotTys + rep ty = sort (map primRepSlot ty) + + sumRep = WordSlot : combine_alts (map rep constrs0) + -- WordSlot: for the tag of the sum + in + sumRep + +layoutUbxSum :: SortedSlotTys -- Layout of sum. Does not include tag. + -- We assume that they are in increasing order + -> [SlotTy] -- Slot types of things we want to map to locations in the + -- sum layout + -> [Int] -- Where to map 'things' in the sum layout +layoutUbxSum sum_slots0 arg_slots0 = go arg_slots0 IS.empty where go :: [SlotTy] -> IS.IntSet -> [Int] @@ -273,11 +246,12 @@ typeSlotTy ty | isVoidTy ty = Nothing | otherwise - = Just (primRepSlot (typePrimRep ty)) + = Just (primRepSlot (typePrimRep1 ty)) primRepSlot :: PrimRep -> SlotTy primRepSlot VoidRep = pprPanic "primRepSlot" (text "No slot for VoidRep") -primRepSlot PtrRep = PtrSlot +primRepSlot LiftedRep = PtrSlot +primRepSlot UnliftedRep = PtrSlot primRepSlot IntRep = WordSlot primRepSlot WordRep = WordSlot primRepSlot Int64Rep = Word64Slot @@ -287,16 +261,8 @@ primRepSlot FloatRep = FloatSlot primRepSlot DoubleRep = DoubleSlot primRepSlot VecRep{} = pprPanic "primRepSlot" (text "No slot for VecRep") --- Used when unarising sum binders (need to give unarised Ids types) -slotTyToType :: SlotTy -> Type -slotTyToType PtrSlot = anyTypeOfKind liftedTypeKind -slotTyToType Word64Slot = int64PrimTy -slotTyToType WordSlot = intPrimTy -slotTyToType DoubleSlot = doublePrimTy -slotTyToType FloatSlot = floatPrimTy - slotPrimRep :: SlotTy -> PrimRep -slotPrimRep PtrSlot = PtrRep +slotPrimRep PtrSlot = LiftedRep -- choice between lifted & unlifted seems arbitrary slotPrimRep Word64Slot = Word64Rep slotPrimRep WordSlot = WordRep slotPrimRep DoubleSlot = DoubleRep @@ -332,41 +298,68 @@ fitsIn ty1 ty2 * * ********************************************************************** -} --- | Discovers the primitive representation of a more abstract 'UnaryType' -typePrimRep :: HasDebugCallStack => UnaryType -> PrimRep -typePrimRep ty = kindPrimRep (text "kindRep ty" <+> ppr ty $$ ppr (typeKind ty)) +-- | Discovers the primitive representation of a 'Type'. Returns +-- a list of 'PrimRep': it's a list because of the possibility of +-- no runtime representation (void) or multiple (unboxed tuple/sum) +typePrimRep :: HasDebugCallStack => Type -> [PrimRep] +typePrimRep ty = kindPrimRep (text "typePrimRep" <+> + parens (ppr ty <+> dcolon <+> ppr (typeKind ty))) (typeKind ty) +-- | Like 'typePrimRep', but assumes that there is precisely one 'PrimRep' output; +-- an empty list of PrimReps becomes a VoidRep +typePrimRep1 :: HasDebugCallStack => UnaryType -> PrimRep +typePrimRep1 ty = case typePrimRep ty of + [] -> VoidRep + [rep] -> rep + _ -> pprPanic "typePrimRep1" (ppr ty $$ ppr (typePrimRep ty)) + -- | Find the runtime representation of a 'TyCon'. Defined here to --- avoid module loops. Do not call this on unboxed tuples or sums, --- because they don't /have/ a runtime representation -tyConPrimRep :: HasDebugCallStack => TyCon -> PrimRep +-- avoid module loops. Returns a list of the register shapes necessary. +tyConPrimRep :: HasDebugCallStack => TyCon -> [PrimRep] tyConPrimRep tc - = ASSERT2( not (isUnboxedTupleTyCon tc), ppr tc ) - ASSERT2( not (isUnboxedSumTyCon tc), ppr tc ) - kindPrimRep (text "kindRep tc" <+> ppr tc $$ ppr res_kind) + = kindPrimRep (text "kindRep tc" <+> ppr tc $$ ppr res_kind) res_kind where res_kind = tyConResKind tc --- | Take a kind (of shape @TYPE rr@) and produce the 'PrimRep' +-- | Like 'tyConPrimRep', but assumed that there is precisely zero or +-- one 'PrimRep' output +tyConPrimRep1 :: HasDebugCallStack => TyCon -> PrimRep +tyConPrimRep1 tc = case tyConPrimRep tc of + [] -> VoidRep + [rep] -> rep + _ -> pprPanic "tyConPrimRep1" (ppr tc $$ ppr (tyConPrimRep tc)) + +-- | Take a kind (of shape @TYPE rr@) and produce the 'PrimRep's -- of values of types of this kind. -kindPrimRep :: HasDebugCallStack => SDoc -> Kind -> PrimRep +kindPrimRep :: HasDebugCallStack => SDoc -> Kind -> [PrimRep] kindPrimRep doc ki | Just ki' <- coreViewOneStarKind ki = kindPrimRep doc ki' -kindPrimRep _ (TyConApp typ [runtime_rep]) +kindPrimRep doc (TyConApp typ [runtime_rep]) = ASSERT( typ `hasKey` tYPETyConKey ) - go runtime_rep - where - go rr - | Just rr' <- coreView rr - = go rr' - go (TyConApp rr_dc args) - | RuntimeRep fun <- tyConRuntimeRepInfo rr_dc - = fun args - go rr - = pprPanic "kindPrimRep.go" (ppr rr) + runtimeRepPrimRep doc runtime_rep kindPrimRep doc ki - = WARN( True, text "kindPrimRep defaulting to PtrRep on" <+> ppr ki $$ doc ) - PtrRep -- this can happen legitimately for, e.g., Any + = pprPanic "kindPrimRep" (ppr ki $$ doc) + + -- TODO (RAE): Remove: + -- WARN( True, text "kindPrimRep defaulting to LiftedRep on" <+> ppr ki $$ doc ) + -- [LiftedRep] -- this can happen legitimately for, e.g., Any + +-- | Take a type of kind RuntimeRep and extract the list of 'PrimRep' that +-- it encodes. +runtimeRepPrimRep :: HasDebugCallStack => SDoc -> Type -> [PrimRep] +runtimeRepPrimRep doc rr_ty + | Just rr_ty' <- coreView rr_ty + = runtimeRepPrimRep doc rr_ty' + | TyConApp rr_dc args <- rr_ty + , RuntimeRep fun <- tyConRuntimeRepInfo rr_dc + = fun args + | otherwise + = pprPanic "runtimeRepPrimRep" (doc $$ ppr rr_ty) + +-- | Convert a PrimRep back to a Type. Used only in the unariser to give types +-- to fresh Ids. Really, only the type's representation matters. +primRepToType :: PrimRep -> Type +primRepToType = anyTypeOfKind . tYPE . primRepToRuntimeRep diff --git a/compiler/simplStg/UnariseStg.hs b/compiler/simplStg/UnariseStg.hs index e8ba200d0a..aa42586cd1 100644 --- a/compiler/simplStg/UnariseStg.hs +++ b/compiler/simplStg/UnariseStg.hs @@ -209,7 +209,7 @@ import Outputable import RepType import StgSyn import Type -import TysPrim (intPrimTyCon, intPrimTy) +import TysPrim (intPrimTy) import TysWiredIn import UniqSupply import Util @@ -225,7 +225,7 @@ import qualified Data.IntMap as IM -- -- x :-> MultiVal [a,b,c] in rho -- --- iff x's repType is a MultiRep, or equivalently +-- iff x's typePrimRep is not a singleton, or equivalently -- x's type is an unboxed tuple, sum or void. -- -- x :-> UnaryVal x' @@ -487,24 +487,24 @@ mapTupleIdBinders mapTupleIdBinders ids args0 rho0 = ASSERT(not (any (isVoidTy . stgArgType) args0)) let - ids_unarised :: [(Id, RepType)] - ids_unarised = map (\id -> (id, repType (idType id))) ids + ids_unarised :: [(Id, [PrimRep])] + ids_unarised = map (\id -> (id, typePrimRep (idType id))) ids - map_ids :: UnariseEnv -> [(Id, RepType)] -> [StgArg] -> UnariseEnv + map_ids :: UnariseEnv -> [(Id, [PrimRep])] -> [StgArg] -> UnariseEnv map_ids rho [] _ = rho - map_ids rho ((x, x_rep) : xs) args = + map_ids rho ((x, x_reps) : xs) args = let - x_arity = length (repTypeSlots x_rep) + x_arity = length x_reps (x_args, args') = ASSERT(args `lengthAtLeast` x_arity) splitAt x_arity args rho' - | isMultiRep x_rep - = extendRho rho x (MultiVal x_args) - | otherwise + | x_arity == 1 = ASSERT(x_args `lengthIs` 1) extendRho rho x (UnaryVal (head x_args)) + | otherwise + = extendRho rho x (MultiVal x_args) in map_ids rho' xs args' in @@ -521,9 +521,9 @@ mapSumIdBinders mapSumIdBinders [id] args rho0 = ASSERT(not (any (isVoidTy . stgArgType) args)) let - arg_slots = concatMap (repTypeSlots . repType . stgArgType) args - id_slots = repTypeSlots (repType (idType id)) - layout1 = layout arg_slots id_slots + arg_slots = map primRepSlot $ concatMap (typePrimRep . stgArgType) args + id_slots = map primRepSlot $ typePrimRep (idType id) + layout1 = layoutUbxSum arg_slots id_slots in if isMultiValBndr id then extendRho rho0 id (MultiVal [ args !! i | i <- layout1 ]) @@ -550,12 +550,12 @@ mkUbxSum -> [OutStgArg] -- Final tuple arguments mkUbxSum dc ty_args args0 = let - (_ : sum_slots) = ubxSumRepType ty_args + (_ : sum_slots) = ubxSumRepType (map typePrimRep ty_args) -- drop tag slot tag = dataConTag dc - layout' = layout sum_slots (mapMaybe (typeSlotTy . stgArgType) args0) + layout' = layoutUbxSum sum_slots (mapMaybe (typeSlotTy . stgArgType) args0) tag_arg = StgLitArg (MachInt (fromIntegral tag)) arg_idxs = IM.fromList (zipEqual "mkUbxSum" layout' args0) @@ -656,12 +656,12 @@ unariseFunArgBinders rho xs = second concat <$> mapAccumLM unariseFunArgBinder r unariseFunArgBinder :: UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id]) -- Result list of binders is never empty unariseFunArgBinder rho x = - case repType (idType x) of - UnaryRep _ -> return (rho, [x]) - MultiRep [] -> return (extendRho rho x (MultiVal []), [voidArgId]) - -- NB: do not remove void binders - MultiRep slots -> do - xs <- mkIds (mkFastString "us") (map slotTyToType slots) + case typePrimRep (idType x) of + [] -> return (extendRho rho x (MultiVal []), [voidArgId]) + -- NB: do not remove void binders + [_] -> return (rho, [x]) + reps -> do + xs <- mkIds (mkFastString "us") (map primRepToType reps) return (extendRho rho x (MultiVal (map StgVarArg xs)), xs) -------------------------------------------------------------------------------- @@ -687,10 +687,10 @@ unariseConArgBinders rho xs = second concat <$> mapAccumLM unariseConArgBinder r unariseConArgBinder :: UnariseEnv -> Id -> UniqSM (UnariseEnv, [Id]) unariseConArgBinder rho x = - case repType (idType x) of - UnaryRep _ -> return (rho, [x]) - MultiRep slots -> do - xs <- mkIds (mkFastString "us") (map slotTyToType slots) + case typePrimRep (idType x) of + [_] -> return (rho, [x]) + reps -> do + xs <- mkIds (mkFastString "us") (map primRepToType reps) return (extendRho rho x (MultiVal (map StgVarArg xs)), xs) unariseFreeVars :: UnariseEnv -> [InId] -> [OutId] @@ -720,7 +720,11 @@ mkId :: FastString -> UnaryType -> UniqSM Id mkId = mkSysLocalOrCoVarM isMultiValBndr :: Id -> Bool -isMultiValBndr = isMultiRep . repType . idType +isMultiValBndr id + | [_] <- typePrimRep (idType id) + = False + | otherwise + = True isUnboxedSumBndr :: Id -> Bool isUnboxedSumBndr = isUnboxedSumType . idType @@ -732,7 +736,7 @@ mkTuple :: [StgArg] -> StgExpr mkTuple args = StgConApp (tupleDataCon Unboxed (length args)) args (map stgArgType args) tagAltTy :: AltType -tagAltTy = PrimAlt intPrimTyCon +tagAltTy = PrimAlt IntRep tagTy :: Type tagTy = intPrimTy |