Jaro Reinders pushed to branch wip/reduce-type-in-stg at Glasgow Haskell Compiler / GHC
Commits:
-
87077c02
by Jaro Reinders at 2026-03-02T11:57:48+01:00
3 changed files:
Changes:
| ... | ... | @@ -548,8 +548,11 @@ mkStgApp f how_bound core_args stg_args res_ty |
| 548 | 548 | else
|
| 549 | 549 | StgConApp dc NoNumber stg_args []
|
| 550 | 550 | |
| 551 | - -- We rewrite the TagToEnum primop to a special StgTagToEnumOp which contains information about the type constructor
|
|
| 552 | - PrimOpId TagToEnumOp _ -> StgOpApp (StgTagToEnumOp (tcTyConAppTyCon res_ty)) stg_args res_kind
|
|
| 551 | + -- We rewrite the 'tagToEnum#' primop to a special 'StgTagToEnumOp' which
|
|
| 552 | + -- stores the type constructor information. See Note [tagToEnum# in STG]
|
|
| 553 | + -- in GHC.Stg.Syntax.
|
|
| 554 | + PrimOpId TagToEnumOp _ ->
|
|
| 555 | + StgOpApp (StgTagToEnumOp (tcTyConAppTyCon res_ty)) stg_args res_kind
|
|
| 553 | 556 | |
| 554 | 557 | -- Some primitive operator that might be implemented as a library call.
|
| 555 | 558 | -- As noted by Note [Eta expanding primops] in GHC.Builtin.PrimOps
|
| ... | ... | @@ -766,6 +766,30 @@ StgOp |
| 766 | 766 | |
| 767 | 767 | An StgOp allows us to group together PrimOps and ForeignCalls. It's quite useful
|
| 768 | 768 | to move these around together, notably in StgOpApp and COpStmt.
|
| 769 | + |
|
| 770 | +Note [tagToEnum# in STG]
|
|
| 771 | +~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 772 | + |
|
| 773 | +STG is untyped, but 'tagToEnum#' needs type information, so we make it a special
|
|
| 774 | +STG operation which stores the type constructor information alongside it.
|
|
| 775 | + |
|
| 776 | +This happens in three main steps throughout the compiler:
|
|
| 777 | + |
|
| 778 | +1. The type checker ensures 'tagToEnum#' is applied to a concrete type.
|
|
| 779 | +2. When converting Core to STG, we rewrite the 'tagToEnum#' primop to a special
|
|
| 780 | + 'StgTagToEnumOp' along with the type constructor info (the 'TyCon').
|
|
| 781 | +3. This information is used for code generation in the back end.
|
|
| 782 | + |
|
| 783 | +At run-time, the 'tagToEnum#' operation converts an integer to a constructor of
|
|
| 784 | +an enumeration data type. Given an integer, it produces a pointer to a data
|
|
| 785 | +constructor. Hence, we need information about where the constructors are stored
|
|
| 786 | +in memory.
|
|
| 787 | + |
|
| 788 | +To preserve this information we desugar the 'tagToEnum#' primop into a special
|
|
| 789 | +'StgTagToEnumOp' which has an extra field to store the type constructor
|
|
| 790 | +information. This desugaring happens when converting Core to STG, which is the
|
|
| 791 | +last moment that we still have access to the type information.
|
|
| 792 | + |
|
| 769 | 793 | -}
|
| 770 | 794 | |
| 771 | 795 | data StgOp
|
| ... | ... | @@ -780,7 +804,7 @@ data StgOp |
| 780 | 804 | -- GHC.StgToCmm.Foreign.
|
| 781 | 805 | -- See Note [Unlifted boxed arguments to foreign calls]
|
| 782 | 806 | |
| 783 | - | StgTagToEnumOp TyCon
|
|
| 807 | + | StgTagToEnumOp TyCon -- See Note [tagToEnum# in STG]
|
|
| 784 | 808 | |
| 785 | 809 | {-
|
| 786 | 810 | ************************************************************************
|
| ... | ... | @@ -1685,8 +1685,9 @@ emitPrimOp cfg primop = |
| 1685 | 1685 | then Left (MO_S_Mul2 (wordWidth platform))
|
| 1686 | 1686 | else Right genericIntMul2Op
|
| 1687 | 1687 | |
| 1688 | - -- tagToEnum# is removed in CoreToStg and rewritten to a special StgTagToEnumOp
|
|
| 1689 | - -- See Note [?]
|
|
| 1688 | + -- 'tagToEnum#' is removed in CoreToStg and rewritten to a special
|
|
| 1689 | + -- 'StgTagToEnumOp' from GHC.Stg.Syntax instead.
|
|
| 1690 | + -- See Note [tagToEnum# in STG] in GHC.Stg.Syntax
|
|
| 1690 | 1691 | TagToEnumOp -> panic "emitPrimOp: TagToEnumOp should have been gone by now"
|
| 1691 | 1692 | |
| 1692 | 1693 | -- Out of line primops.
|