Jaro Reinders pushed to branch wip/reduce-type-in-stg at Glasgow Haskell Compiler / GHC
Commits:
-
5d9f2aee
by Jaro Reinders at 2026-04-22T11:53:14+02:00
5 changed files:
- compiler/GHC/Core/Type.hs
- compiler/GHC/Stg/Unarise.hs
- compiler/GHC/StgToCmm/Utils.hs
- compiler/GHC/StgToJS/Expr.hs
- compiler/GHC/Types/RepType.hs
Changes:
| ... | ... | @@ -70,7 +70,7 @@ module GHC.Core.Type ( |
| 70 | 70 | isLitTy,
|
| 71 | 71 | |
| 72 | 72 | getRuntimeRep, splitRuntimeRep_maybe, kindRep_maybe, kindRep,
|
| 73 | - getLevity, levityType_maybe,
|
|
| 73 | + getLevity, levityType_maybe, isUnboxedTupleKind,
|
|
| 74 | 74 | |
| 75 | 75 | mkCastTy, mkCoercionTy, splitCastTy_maybe,
|
| 76 | 76 | |
| ... | ... | @@ -2802,6 +2802,12 @@ isFixedRuntimeRepKind k |
| 2802 | 2802 | -- the isLiftedTypeKind check is necessary b/c of Constraint
|
| 2803 | 2803 | isConcreteType k
|
| 2804 | 2804 | |
| 2805 | +isUnboxedTupleKind :: HasDebugCallStack => Kind -> Bool
|
|
| 2806 | +isUnboxedTupleKind kind
|
|
| 2807 | + = tyConAppTyCon (kindRep kind) `hasKey` tupleRepDataConKey
|
|
| 2808 | + -- NB: Do not use typePrimRep, as that can't tell the difference between
|
|
| 2809 | + -- unboxed tuples and unboxed sums
|
|
| 2810 | + |
|
| 2805 | 2811 | -- | Tests whether the given type is concrete, i.e. it
|
| 2806 | 2812 | -- whether it consists only of concrete type constructors,
|
| 2807 | 2813 | -- concrete type variables, and applications.
|
| ... | ... | @@ -882,7 +882,6 @@ mapSumIdBinders alt_bndr args rhs rho0 |
| 882 | 882 | -- Convert the argument to the given type, and wrap the conversion
|
| 883 | 883 | -- around the given expression. Use the given Id as a name for the
|
| 884 | 884 | -- converted value.
|
| 885 | --- TODO: the 'Type' in the argument here should probably be 'StgKind'
|
|
| 886 | 885 | castArgRename :: [(PrimOp,Type,Unique)] -> StgArg -> StgExpr -> StgExpr
|
| 887 | 886 | castArgRename ops in_arg rhs =
|
| 888 | 887 | case ops of
|
| ... | ... | @@ -896,17 +895,11 @@ castArgRename ops in_arg rhs = |
| 896 | 895 | mkCastVar :: Unique -> Type -> Id
|
| 897 | 896 | mkCastVar uq ty = mkSysLocal (fsLit "cst_sum") uq ManyTy ty
|
| 898 | 897 | |
| 899 | --- TODO: move/rename this
|
|
| 900 | -stgKindPrimRep1 :: HasDebugCallStack => StgKind -> PrimRep
|
|
| 901 | -stgKindPrimRep1 (MkStgKind k) = case kindPrimRep_maybe k of
|
|
| 902 | - Just [rep] -> rep
|
|
| 903 | - r -> pprPanic "kindPrimRepU" (ppr k $$ ppr r)
|
|
| 904 | - |
|
| 905 | 898 | mkCast :: StgArg -> PrimOp -> OutId -> StgKind -> StgExpr -> StgExpr
|
| 906 | 899 | mkCast arg_in cast_op out_id out_kind in_rhs =
|
| 907 | 900 | let scrut = StgOpApp (StgPrimOp cast_op) [arg_in]
|
| 908 | 901 | alt = GenStgAlt { alt_con = DEFAULT, alt_bndrs = [], alt_rhs = in_rhs}
|
| 909 | - alt_ty = PrimAlt (stgKindPrimRep1 out_kind)
|
|
| 902 | + alt_ty = PrimAlt (kindPrimRep1 (getStgKind out_kind))
|
|
| 910 | 903 | in (StgCase scrut out_id alt_ty [alt])
|
| 911 | 904 | |
| 912 | 905 | -- | Build a unboxed sum term from arguments of an alternative.
|
| ... | ... | @@ -92,7 +92,6 @@ import Control.Monad |
| 92 | 92 | import qualified Data.Map.Strict as Map
|
| 93 | 93 | import qualified Data.IntMap.Strict as I
|
| 94 | 94 | import qualified Data.Semigroup (Semigroup(..))
|
| 95 | -import GHC.Builtin.Names (tupleRepDataConKey)
|
|
| 96 | 95 | |
| 97 | 96 | --------------------------------------------------------------------------
|
| 98 | 97 | --
|
| ... | ... | @@ -321,24 +320,22 @@ assignTemp e = do { platform <- getPlatform |
| 321 | 320 | ; emitAssign (CmmLocal reg) e
|
| 322 | 321 | ; return reg }
|
| 323 | 322 | |
| 324 | -newUnboxedTupleRegs :: Kind -> FCode ([LocalReg], [ForeignHint])
|
|
| 323 | +newUnboxedTupleRegs :: HasDebugCallStack => Kind -> FCode ([LocalReg], [ForeignHint])
|
|
| 325 | 324 | -- Choose suitable local regs to use for the components
|
| 326 | 325 | -- of an unboxed tuple that we are about to return to
|
| 327 | 326 | -- the Sequel. If the Sequel is a join point, using the
|
| 328 | 327 | -- regs it wants will save later assignments.
|
| 329 | 328 | newUnboxedTupleRegs res_kind
|
| 330 | - -- TODO: clean up this messy assert. It is basically isUnboxedTupleType, but then for kinds.
|
|
| 331 | - = assert (Just True == ((\x -> tyConAppTyCon x `hasKey` tupleRepDataConKey) <$> kindRep_maybe res_kind)) $
|
|
| 332 | - do { platform <- getPlatform
|
|
| 333 | - ; sequel <- getSequel
|
|
| 334 | - ; regs <- choose_regs platform sequel
|
|
| 335 | - ; massert (regs `equalLength` reps)
|
|
| 336 | - ; return (regs, map primRepForeignHint reps) }
|
|
| 337 | - where
|
|
| 338 | - -- TODO: this is partial
|
|
| 339 | - Just reps = kindPrimRep_maybe res_kind
|
|
| 340 | - choose_regs _ (AssignTo regs _) = return regs
|
|
| 341 | - choose_regs platform _ = mapM (newTemp . primRepCmmType platform) reps
|
|
| 329 | + = assert (isUnboxedTupleKind res_kind) $
|
|
| 330 | + case kindPrimRep_maybe res_kind of
|
|
| 331 | + Just reps ->
|
|
| 332 | + do { platform <- getPlatform
|
|
| 333 | + ; sequel <- getSequel
|
|
| 334 | + ; regs <- case sequel of
|
|
| 335 | + AssignTo regs _ -> regs <$ massert (regs `equalLength` reps)
|
|
| 336 | + _ -> mapM (newTemp . primRepCmmType platform) reps
|
|
| 337 | + ; return (regs, map primRepForeignHint reps) }
|
|
| 338 | + Nothing -> pprPanic "newUnboxedTupleRegs applied to non-unboxed-tuple kind" (ppr res_kind)
|
|
| 342 | 339 | |
| 343 | 340 | -------------------------------------------------------------------------
|
| 344 | 341 | -- emitMultiAssign
|
| ... | ... | @@ -372,7 +372,7 @@ resultSize kind = result |
| 372 | 372 | where
|
| 373 | 373 | result = result_reps `zip` result_slots
|
| 374 | 374 | result_slots = fmap (slotCount . primRepSize) result_reps
|
| 375 | - result_reps = stgKindPrimRep kind
|
|
| 375 | + result_reps = kindPrimRep (getStgKind kind)
|
|
| 376 | 376 | |
| 377 | 377 | -- | Ensure that the set of identifiers has valid 'RuntimeRep's. This function
|
| 378 | 378 | -- returns a no-op when 'csRuntimeAssert' in 'StgToJSConfig' is False.
|
| ... | ... | @@ -14,6 +14,7 @@ module GHC.Types.RepType |
| 14 | 14 | countFunRepArgs, countConRepArgs, dataConRuntimeRepStrictness,
|
| 15 | 15 | tyConPrimRep,
|
| 16 | 16 | runtimeRepPrimRep_maybe, kindPrimRep_maybe, typePrimRep_maybe,
|
| 17 | + kindPrimRep, kindPrimRep1,
|
|
| 17 | 18 | |
| 18 | 19 | -- * Unboxed sum representation type
|
| 19 | 20 | ubxSumRepType, layoutUbxSum, repSlotTy, SlotTy (..),
|
| ... | ... | @@ -566,9 +567,12 @@ to process the LiftedRep and WordRep, concatenating the results. |
| 566 | 567 | -- no runtime representation (void) or multiple (unboxed tuple/sum)
|
| 567 | 568 | -- See also Note [Getting from RuntimeRep to PrimRep]
|
| 568 | 569 | typePrimRep :: HasDebugCallStack => Type -> [PrimRep]
|
| 569 | -typePrimRep ty = kindPrimRep (text "typePrimRep" <+>
|
|
| 570 | - parens (ppr ty <+> dcolon <+> ppr (typeKind ty)))
|
|
| 571 | - (typeKind ty)
|
|
| 570 | +typePrimRep ty =
|
|
| 571 | + let ki = typeKind ty in
|
|
| 572 | + case kindPrimRep_maybe ki of
|
|
| 573 | + Just reps -> reps
|
|
| 574 | + Nothing ->
|
|
| 575 | + pprPanic "typePrimRep" (ppr ty <+> dcolon <+> ppr ki)
|
|
| 572 | 576 | |
| 573 | 577 | -- | Discovers the primitive representation of a 'Type'. Returns
|
| 574 | 578 | -- a list of 'PrimRep': it's a list because of the possibility of
|
| ... | ... | @@ -599,20 +603,29 @@ typePrimRepU ty = case typePrimRep ty of |
| 599 | 603 | -- See also Note [Getting from RuntimeRep to PrimRep]
|
| 600 | 604 | tyConPrimRep :: HasDebugCallStack => TyCon -> [PrimRep]
|
| 601 | 605 | tyConPrimRep tc
|
| 602 | - = kindPrimRep (text "kindRep tc" <+> ppr tc $$ ppr res_kind)
|
|
| 603 | - res_kind
|
|
| 606 | + = case kindPrimRep_maybe res_kind of
|
|
| 607 | + Just reps -> reps
|
|
| 608 | + Nothing -> pprPanic "kindRep tc" (ppr tc $$ ppr res_kind)
|
|
| 604 | 609 | where
|
| 605 | 610 | res_kind = tyConResKind tc
|
| 606 | 611 | |
| 607 | 612 | -- | Take a kind (of shape @TYPE rr@) and produce the 'PrimRep's
|
| 608 | 613 | -- of values of types of this kind.
|
| 609 | 614 | -- See also Note [Getting from RuntimeRep to PrimRep]
|
| 610 | -kindPrimRep :: HasDebugCallStack => SDoc -> Kind -> [PrimRep]
|
|
| 611 | -kindPrimRep doc ki
|
|
| 612 | - | Just runtime_rep <- kindRep_maybe ki
|
|
| 613 | - = runtimeRepPrimRep doc runtime_rep
|
|
| 614 | -kindPrimRep doc ki
|
|
| 615 | - = pprPanic "kindPrimRep" (ppr ki $$ doc)
|
|
| 615 | +kindPrimRep :: HasDebugCallStack => Kind -> [PrimRep]
|
|
| 616 | +kindPrimRep ki
|
|
| 617 | + = case kindPrimRep_maybe ki of
|
|
| 618 | + Just reps -> reps
|
|
| 619 | + Nothing -> pprPanic "kindPrimRep" (ppr ki)
|
|
| 620 | + |
|
| 621 | +-- | Like 'kindPrimRep', but assumes that there is exactly one 'PrimRep' output.
|
|
| 622 | +-- This assumption holds after unarise, see Note [Post-unarisation invariants].
|
|
| 623 | +-- Before unarise it may or may not hold.
|
|
| 624 | +-- See also Note [RuntimeRep and PrimRep] and Note [VoidRep]
|
|
| 625 | +kindPrimRep1 :: HasDebugCallStack => Kind -> PrimRep
|
|
| 626 | +kindPrimRep1 k = case kindPrimRep_maybe k of
|
|
| 627 | + Just [rep] -> rep
|
|
| 628 | + r -> pprPanic "kindPrimRep1" (ppr k $$ ppr r)
|
|
| 616 | 629 | |
| 617 | 630 | -- NB: We could implement the partial methods by calling into the maybe
|
| 618 | 631 | -- variants here. But then both would need to pass around the doc argument.
|