summaryrefslogtreecommitdiff
path: root/compiler/codeGen
diff options
context:
space:
mode:
authorÖmer Sinan Ağacan <omeragacan@gmail.com>2016-09-20 00:19:15 -0400
committerÖmer Sinan Ağacan <omeragacan@gmail.com>2016-09-20 00:19:27 -0400
commit14c2e8e0c11bb2b95f81303284d1460bb80a9a98 (patch)
treeb9c67117f0e2f7f79037e9a07c20a0256800f5cc /compiler/codeGen
parentea310f9956179f91ca973bc747b0bc7b061bc174 (diff)
downloadhaskell-14c2e8e0c11bb2b95f81303284d1460bb80a9a98.tar.gz
Codegen for case: Remove redundant void id checks
New unarise (714bebf) eliminates void binders in patterns already, so no need to eliminate them here. I leave assertions to make sure this is the case. Assertion failure -> bug in unarise Reviewers: bgamari, simonpj, austin, simonmar, hvr Reviewed By: simonpj Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2416
Diffstat (limited to 'compiler/codeGen')
-rw-r--r--compiler/codeGen/StgCmm.hs19
-rw-r--r--compiler/codeGen/StgCmmBind.hs20
-rw-r--r--compiler/codeGen/StgCmmClosure.hs51
-rw-r--r--compiler/codeGen/StgCmmCon.hs15
-rw-r--r--compiler/codeGen/StgCmmEnv.hs22
-rw-r--r--compiler/codeGen/StgCmmExpr.hs26
-rw-r--r--compiler/codeGen/StgCmmLayout.hs30
-rw-r--r--compiler/codeGen/StgCmmTicky.hs3
8 files changed, 114 insertions, 72 deletions
diff --git a/compiler/codeGen/StgCmm.hs b/compiler/codeGen/StgCmm.hs
index 85f8845c8a..28ca97d9a2 100644
--- a/compiler/codeGen/StgCmm.hs
+++ b/compiler/codeGen/StgCmm.hs
@@ -138,7 +138,9 @@ cgTopRhs :: DynFlags -> RecFlag -> Id -> StgRhs -> (CgIdInfo, FCode ())
-- It's already been externalised if necessary
cgTopRhs dflags _rec bndr (StgRhsCon _cc con args)
- = cgTopRhsCon dflags bndr con args
+ = cgTopRhsCon dflags bndr con (assertNonVoidStgArgs args)
+ -- con args are always non-void,
+ -- see Note [Post-unarisation invariants] in UnariseStg
cgTopRhs dflags rec bndr (StgRhsClosure cc bi fvs upd_flag args body)
= ASSERT(null fvs) -- There should be no free variables
@@ -219,8 +221,8 @@ cgDataCon data_con
= do { dflags <- getDynFlags
; let
(tot_wds, -- #ptr_wds + #nonptr_wds
- ptr_wds, -- #ptr_wds
- arg_things) = mkVirtConstrOffsets dflags arg_reps
+ ptr_wds) -- #ptr_wds
+ = mkVirtConstrSizes dflags arg_reps
nonptr_wds = tot_wds - ptr_wds
@@ -240,14 +242,17 @@ cgDataCon data_con
-- NB 2: We don't set CC when entering data (WDP 94/06)
do { _ <- ticky_code
; ldvEnter (CmmReg nodeReg)
- ; tickyReturnOldCon (length arg_things)
+ ; tickyReturnOldCon (length arg_reps)
; void $ emitReturn [cmmOffsetB dflags (CmmReg nodeReg) (tagForCon dflags data_con)]
}
-- The case continuation code expects a tagged pointer
- arg_reps :: [(PrimRep, UnaryType)]
- arg_reps = [(typePrimRep rep_ty, rep_ty) | ty <- dataConRepArgTys data_con
- , rep_ty <- repTypeArgs ty]
+ -- We're generating info tables, so we don't know and care about
+ -- what the actual arguments are. Using () here as the place holder.
+ arg_reps :: [NonVoid PrimRep]
+ arg_reps = [NonVoid (typePrimRep rep_ty) | ty <- dataConRepArgTys data_con
+ , rep_ty <- repTypeArgs ty
+ , not (isVoidTy rep_ty)]
-- Dynamic closure code for non-nullary constructors only
; when (not (isNullaryRepDataCon data_con))
diff --git a/compiler/codeGen/StgCmmBind.hs b/compiler/codeGen/StgCmmBind.hs
index 93756ec406..e173f354b7 100644
--- a/compiler/codeGen/StgCmmBind.hs
+++ b/compiler/codeGen/StgCmmBind.hs
@@ -206,7 +206,9 @@ cgRhs :: Id
cgRhs id (StgRhsCon cc con args)
= withNewTickyCounterCon (idName id) $
- buildDynCon id True cc con args
+ buildDynCon id True cc con (assertNonVoidStgArgs args)
+ -- con args are always non-void,
+ -- see Note [Post-unarisation invariants] in UnariseStg
{- See Note [GC recovery] in compiler/codeGen/StgCmmClosure.hs -}
cgRhs id (StgRhsClosure cc bi fvs upd_flag args body)
@@ -273,8 +275,9 @@ mkRhsClosure dflags bndr _cc _bi
, StgApp selectee [{-no args-}] <- strip sel_expr
, the_fv == scrutinee -- Scrutinee is the only free variable
- , let (_, _, params_w_offsets) = mkVirtConstrOffsets dflags (addIdReps params)
- -- Just want the layout
+ , let (_, _, params_w_offsets) = mkVirtConstrOffsets dflags (addIdReps (assertNonVoidIds params))
+ -- pattern binders are always non-void,
+ -- see Note [Post-unarisation invariants] in UnariseStg
, Just the_offset <- assocMaybe params_w_offsets (NonVoid selectee)
, let offset_into_int = bytesToWordsRoundUp dflags the_offset
@@ -305,7 +308,7 @@ mkRhsClosure dflags bndr _cc _bi
-- args are all distinct local variables
-- The "-1" is for fun_id
-- Missed opportunity: (f x x) is not detected
- , all (isGcPtrRep . idPrimRep . unsafe_stripNV) fvs
+ , all (isGcPtrRep . idPrimRep . fromNonVoid) fvs
, isUpdatable upd_flag
, n_fvs <= mAX_SPEC_AP_SIZE dflags
, not (gopt Opt_SccProfilingOn dflags)
@@ -348,7 +351,7 @@ mkRhsClosure dflags bndr cc _ fvs upd_flag args body
fv_details :: [(NonVoid Id, ByteOff)]
(tot_wds, ptr_wds, fv_details)
= mkVirtHeapOffsets dflags (isLFThunk lf_info)
- (addIdReps (map unsafe_stripNV reduced_fvs))
+ (addIdReps reduced_fvs)
closure_info = mkClosureInfo dflags False -- Not static
bndr lf_info tot_wds ptr_wds
descr
@@ -392,7 +395,8 @@ cgRhsStdThunk bndr lf_info payload
mod_name <- getModuleName
; dflags <- getDynFlags
; let (tot_wds, ptr_wds, payload_w_offsets)
- = mkVirtHeapOffsets dflags (isLFThunk lf_info) (addArgReps payload)
+ = mkVirtHeapOffsets dflags (isLFThunk lf_info)
+ (addArgReps (nonVoidStgArgs payload))
descr = closureDescription dflags mod_name (idName bndr)
closure_info = mkClosureInfo dflags False -- Not static
@@ -421,9 +425,9 @@ mkClosureLFInfo :: DynFlags
-> LambdaFormInfo
mkClosureLFInfo dflags bndr top fvs upd_flag args
| null args =
- mkLFThunk (idType bndr) top (map unsafe_stripNV fvs) upd_flag
+ mkLFThunk (idType bndr) top (map fromNonVoid fvs) upd_flag
| otherwise =
- mkLFReEntrant top (map unsafe_stripNV fvs) args (mkArgDescr dflags args)
+ mkLFReEntrant top (map fromNonVoid fvs) args (mkArgDescr dflags args)
------------------------------------------------------------------------
diff --git a/compiler/codeGen/StgCmmClosure.hs b/compiler/codeGen/StgCmmClosure.hs
index f831789454..23b803cc56 100644
--- a/compiler/codeGen/StgCmmClosure.hs
+++ b/compiler/codeGen/StgCmmClosure.hs
@@ -18,6 +18,9 @@ module StgCmmClosure (
idPrimRep, isVoidRep, isGcPtrRep, addIdReps, addArgReps,
argPrimRep,
+ NonVoid(..), fromNonVoid, nonVoidIds, nonVoidStgArgs,
+ assertNonVoidIds, assertNonVoidStgArgs,
+
-- * LambdaFormInfo
LambdaFormInfo, -- Abstract
StandardFormInfo, -- ...ditto...
@@ -84,6 +87,8 @@ import Outputable
import DynFlags
import Util
+import Data.Coerce (coerce)
+
-----------------------------------------------------------------------------
-- Data types and synonyms
-----------------------------------------------------------------------------
@@ -115,6 +120,42 @@ isKnownFun LFLetNoEscape = True
isKnownFun _ = False
+-------------------------------------
+-- Non-void types
+-------------------------------------
+-- We frequently need the invariant that an Id or a an argument
+-- is of a non-void type. This type is a witness to the invariant.
+
+newtype NonVoid a = NonVoid a
+ deriving (Eq, Show)
+
+fromNonVoid :: NonVoid a -> a
+fromNonVoid (NonVoid a) = a
+
+instance (Outputable a) => Outputable (NonVoid a) where
+ ppr (NonVoid a) = ppr a
+
+nonVoidIds :: [Id] -> [NonVoid Id]
+nonVoidIds ids = [NonVoid id | id <- ids, not (isVoidTy (idType id))]
+
+-- | Used in places where some invariant ensures that all these Ids are
+-- non-void; e.g. constructor field binders in case expressions.
+-- See Note [Post-unarisation invariants] in UnariseStg.
+assertNonVoidIds :: [Id] -> [NonVoid Id]
+assertNonVoidIds ids = ASSERT(not (any (isVoidTy . idType) ids))
+ coerce ids
+
+nonVoidStgArgs :: [StgArg] -> [NonVoid StgArg]
+nonVoidStgArgs args = [NonVoid arg | arg <- args, not (isVoidTy (stgArgType arg))]
+
+-- | Used in places where some invariant ensures that all these arguments are
+-- non-void; e.g. constructor arguments.
+-- See Note [Post-unarisation invariants] in UnariseStg.
+assertNonVoidStgArgs :: [StgArg] -> [NonVoid StgArg]
+assertNonVoidStgArgs args = ASSERT(not (any (isVoidTy . stgArgType) args))
+ coerce args
+
+
-----------------------------------------------------------------------------
-- Representations
-----------------------------------------------------------------------------
@@ -126,11 +167,13 @@ idPrimRep id = typePrimRep (idType id)
-- NB: typePrimRep fails on unboxed tuples,
-- but by StgCmm no Ids have unboxed tuple type
-addIdReps :: [Id] -> [(PrimRep, Id)]
-addIdReps ids = [(idPrimRep id, id) | id <- ids]
+addIdReps :: [NonVoid Id] -> [NonVoid (PrimRep, Id)]
+addIdReps = map (\id -> let id' = fromNonVoid id
+ in NonVoid (idPrimRep id', id'))
-addArgReps :: [StgArg] -> [(PrimRep, StgArg)]
-addArgReps args = [(argPrimRep arg, arg) | arg <- args]
+addArgReps :: [NonVoid StgArg] -> [NonVoid (PrimRep, StgArg)]
+addArgReps = map (\arg -> let arg' = fromNonVoid arg
+ in NonVoid (argPrimRep arg', arg'))
argPrimRep :: StgArg -> PrimRep
argPrimRep arg = typePrimRep (stgArgType arg)
diff --git a/compiler/codeGen/StgCmmCon.hs b/compiler/codeGen/StgCmmCon.hs
index 4255f10201..3a615f750f 100644
--- a/compiler/codeGen/StgCmmCon.hs
+++ b/compiler/codeGen/StgCmmCon.hs
@@ -58,7 +58,7 @@ import Data.Char
cgTopRhsCon :: DynFlags
-> Id -- Name of thing bound to this RHS
-> DataCon -- Id
- -> [StgArg] -- Args
+ -> [NonVoid StgArg] -- Args
-> (CgIdInfo, FCode ())
cgTopRhsCon dflags id con args =
let id_info = litIdInfo dflags id (mkConLFInfo con) (CmmLabel closure_label)
@@ -72,7 +72,7 @@ cgTopRhsCon dflags id con args =
do { this_mod <- getModuleName
; when (platformOS (targetPlatform dflags) == OSMinGW32) $
-- Windows DLLs have a problem with static cross-DLL refs.
- ASSERT( not (isDllConApp dflags this_mod con args) ) return ()
+ MASSERT( not (isDllConApp dflags this_mod con (map fromNonVoid args)) )
; ASSERT( args `lengthIs` countConRepArgs con ) return ()
-- LAY IT OUT
@@ -120,7 +120,7 @@ buildDynCon :: Id -- Name of the thing to which this constr will
-> CostCentreStack -- Where to grab cost centre from;
-- current CCS if currentOrSubsumedCCS
-> DataCon -- The data constructor
- -> [StgArg] -- Its args
+ -> [NonVoid StgArg] -- Its args
-> FCode (CgIdInfo, FCode CmmAGraph)
-- Return details about how to find it and initialization code
buildDynCon binder actually_bound cc con args
@@ -133,7 +133,7 @@ buildDynCon' :: DynFlags
-> Id -> Bool
-> CostCentreStack
-> DataCon
- -> [StgArg]
+ -> [NonVoid StgArg]
-> FCode (CgIdInfo, FCode CmmAGraph)
{- We used to pass a boolean indicating whether all the
@@ -192,7 +192,7 @@ because they don't support cross package data references well.
buildDynCon' dflags platform binder _ _cc con [arg]
| maybeIntLikeCon con
, platformOS platform /= OSMinGW32 || not (gopt Opt_PIC dflags)
- , StgLitArg (MachInt val) <- arg
+ , NonVoid (StgLitArg (MachInt val)) <- arg
, val <= fromIntegral (mAX_INTLIKE dflags) -- Comparisons at type Integer!
, val >= fromIntegral (mIN_INTLIKE dflags) -- ...ditto...
= do { let intlike_lbl = mkCmmClosureLabel rtsUnitId (fsLit "stg_INTLIKE")
@@ -206,7 +206,7 @@ buildDynCon' dflags platform binder _ _cc con [arg]
buildDynCon' dflags platform binder _ _cc con [arg]
| maybeCharLikeCon con
, platformOS platform /= OSMinGW32 || not (gopt Opt_PIC dflags)
- , StgLitArg (MachChar val) <- arg
+ , NonVoid (StgLitArg (MachChar val)) <- arg
, let val_int = ord val :: Int
, val_int <= mAX_CHARLIKE dflags
, val_int >= mIN_CHARLIKE dflags
@@ -228,7 +228,6 @@ buildDynCon' dflags _ binder actually_bound ccs con args
gen_code reg
= do { let (tot_wds, ptr_wds, args_w_offsets)
= mkVirtConstrOffsets dflags (addArgReps args)
- -- No void args in args_w_offsets
nonptr_wds = tot_wds - ptr_wds
info_tbl = mkDataConInfoTable dflags con False
ptr_wds nonptr_wds
@@ -250,7 +249,7 @@ buildDynCon' dflags _ binder actually_bound ccs con args
-- Binding constructor arguments
---------------------------------------------------------------
-bindConArgs :: AltCon -> LocalReg -> [Id] -> FCode [LocalReg]
+bindConArgs :: AltCon -> LocalReg -> [NonVoid Id] -> FCode [LocalReg]
-- bindConArgs is called from cgAlt of a case
-- (bindConArgs con args) augments the environment with bindings for the
-- binders args, assuming that we have just returned from a 'case' which
diff --git a/compiler/codeGen/StgCmmEnv.hs b/compiler/codeGen/StgCmmEnv.hs
index 44d3df84ee..30307a2a3a 100644
--- a/compiler/codeGen/StgCmmEnv.hs
+++ b/compiler/codeGen/StgCmmEnv.hs
@@ -13,8 +13,6 @@ module StgCmmEnv (
litIdInfo, lneIdInfo, rhsIdInfo, mkRhsInit,
idInfoToAmode,
- NonVoid(..), unsafe_stripNV, nonVoidIds,
-
addBindC, addBindsC,
bindArgsToRegs, bindToReg, rebindToReg,
@@ -30,6 +28,7 @@ import TyCon
import StgCmmMonad
import StgCmmUtils
import StgCmmClosure
+import StgSyn (StgArg)
import CLabel
@@ -46,25 +45,6 @@ import UniqFM
import VarEnv
-------------------------------------
--- Non-void types
--------------------------------------
--- We frequently need the invariant that an Id or a an argument
--- is of a non-void type. This type is a witness to the invariant.
-
-newtype NonVoid a = NonVoid a
- deriving (Eq, Show)
-
--- Use with care; if used inappropriately, it could break invariants.
-unsafe_stripNV :: NonVoid a -> a
-unsafe_stripNV (NonVoid a) = a
-
-instance (Outputable a) => Outputable (NonVoid a) where
- ppr (NonVoid a) = ppr a
-
-nonVoidIds :: [Id] -> [NonVoid Id]
-nonVoidIds ids = [NonVoid id | id <- ids, not (isVoidRep (idPrimRep id))]
-
--------------------------------------
-- Manipulating CgIdInfo
-------------------------------------
diff --git a/compiler/codeGen/StgCmmExpr.hs b/compiler/codeGen/StgCmmExpr.hs
index 91cfba6bd0..fdd902d8c7 100644
--- a/compiler/codeGen/StgCmmExpr.hs
+++ b/compiler/codeGen/StgCmmExpr.hs
@@ -525,24 +525,24 @@ isSimpleOp (StgPrimCallOp _) _ = return False
-----------------
chooseReturnBndrs :: Id -> AltType -> [StgAlt] -> [NonVoid Id]
--- These are the binders of a case that are assigned
--- by the evaluation of the scrutinee
--- Only non-void ones come back
+-- These are the binders of a case that are assigned by the evaluation of the
+-- scrutinee.
+-- They're non-void, see Note [Post-unarisation invariants] in UnariseStg.
chooseReturnBndrs bndr (PrimAlt _) _alts
- = nonVoidIds [bndr]
+ = assertNonVoidIds [bndr]
chooseReturnBndrs _bndr (MultiValAlt n) [(_, ids, _)]
- = ASSERT2(n == length (nonVoidIds ids), ppr n $$ ppr ids $$ ppr _bndr)
- nonVoidIds ids -- 'bndr' is not assigned!
+ = ASSERT2(n == length ids, ppr n $$ ppr ids $$ ppr _bndr)
+ assertNonVoidIds ids -- 'bndr' is not assigned!
chooseReturnBndrs bndr (AlgAlt _) _alts
- = nonVoidIds [bndr] -- Only 'bndr' is assigned
+ = assertNonVoidIds [bndr] -- Only 'bndr' is assigned
chooseReturnBndrs bndr PolyAlt _alts
- = nonVoidIds [bndr] -- Only 'bndr' is assigned
+ = assertNonVoidIds [bndr] -- Only 'bndr' is assigned
chooseReturnBndrs _ _ _ = panic "chooseReturnBndrs"
- -- UbxTupALt has only one alternative
+ -- MultiValAlt has only one alternative
-------------------------------------
cgAlts :: (GcPlan,ReturnKind) -> NonVoid Id -> AltType -> [StgAlt]
@@ -651,7 +651,9 @@ cgAltRhss gc_plan bndr alts = do
cg_alt (con, bndrs, rhs)
= getCodeScoped $
maybeAltHeapCheck gc_plan $
- do { _ <- bindConArgs con base_reg bndrs
+ do { _ <- bindConArgs con base_reg (assertNonVoidIds bndrs)
+ -- alt binders are always non-void,
+ -- see Note [Post-unarisation invariants] in UnariseStg
; _ <- cgExpr rhs
; return con }
forkAlts (map cg_alt alts)
@@ -677,7 +679,9 @@ cgConApp con stg_args
| otherwise -- Boxed constructors; allocate and return
= ASSERT2( stg_args `lengthIs` countConRepArgs con, ppr con <> parens (ppr (countConRepArgs con)) <+> ppr stg_args )
do { (idinfo, fcode_init) <- buildDynCon (dataConWorkId con) False
- currentCCS con stg_args
+ currentCCS con (assertNonVoidStgArgs stg_args)
+ -- con args are always non-void,
+ -- see Note [Post-unarisation invariants] in UnariseStg
-- The first "con" says that the name bound to this
-- closure is is "con", which is a bit of a fudge, but
-- it only affects profiling (hence the False)
diff --git a/compiler/codeGen/StgCmmLayout.hs b/compiler/codeGen/StgCmmLayout.hs
index 59bbc8d5ea..21698c7bbf 100644
--- a/compiler/codeGen/StgCmmLayout.hs
+++ b/compiler/codeGen/StgCmmLayout.hs
@@ -17,7 +17,7 @@ module StgCmmLayout (
slowCall, directCall,
- mkVirtHeapOffsets, mkVirtConstrOffsets, getHpRelOffset,
+ mkVirtHeapOffsets, mkVirtConstrOffsets, mkVirtConstrSizes, getHpRelOffset,
ArgRep(..), toArgRep, argRepSizeW -- re-exported from StgCmmArgRep
) where
@@ -388,8 +388,8 @@ getHpRelOffset virtual_offset
mkVirtHeapOffsets
:: DynFlags
- -> Bool -- True <=> is a thunk
- -> [(PrimRep,a)] -- Things to make offsets for
+ -> Bool -- True <=> is a thunk
+ -> [NonVoid (PrimRep,a)] -- Things to make offsets for
-> (WordOff, -- _Total_ number of words allocated
WordOff, -- Number of words allocated for *pointers*
[(NonVoid a, ByteOff)])
@@ -398,14 +398,12 @@ mkVirtHeapOffsets
-- increasing offset; BUT THIS MAY BE DIFFERENT TO INPUT ORDER
-- First in list gets lowest offset, which is initial offset + 1.
--
--- Void arguments are removed, so output list may be shorter than
--- input list
---
-- mkVirtHeapOffsets always returns boxed things with smaller offsets
-- than the unboxed things
mkVirtHeapOffsets dflags is_thunk things
- = ( bytesToWordsRoundUp dflags tot_bytes
+ = ASSERT(not (any (isVoidRep . fst . fromNonVoid) things))
+ ( bytesToWordsRoundUp dflags tot_bytes
, bytesToWordsRoundUp dflags bytes_of_ptrs
, ptrs_w_offsets ++ non_ptrs_w_offsets
)
@@ -414,24 +412,34 @@ mkVirtHeapOffsets dflags is_thunk things
| otherwise = fixedHdrSizeW dflags
hdr_bytes = wordsToBytes dflags hdr_words
- non_void_things = filterOut (isVoidRep . fst) things
- (ptrs, non_ptrs) = partition (isGcPtrRep . fst) non_void_things
+ (ptrs, non_ptrs) = partition (isGcPtrRep . fst . fromNonVoid) things
(bytes_of_ptrs, ptrs_w_offsets) =
mapAccumL computeOffset 0 ptrs
(tot_bytes, non_ptrs_w_offsets) =
mapAccumL computeOffset bytes_of_ptrs non_ptrs
- computeOffset bytes_so_far (rep, thing)
+ computeOffset bytes_so_far nv_thing
= (bytes_so_far + wordsToBytes dflags (argRepSizeW dflags (toArgRep rep)),
(NonVoid thing, hdr_bytes + bytes_so_far))
+ where (rep,thing) = fromNonVoid nv_thing
-- | Just like mkVirtHeapOffsets, but for constructors
mkVirtConstrOffsets
- :: DynFlags -> [(PrimRep,a)]
+ :: DynFlags -> [NonVoid (PrimRep, a)]
-> (WordOff, WordOff, [(NonVoid a, ByteOff)])
mkVirtConstrOffsets dflags = mkVirtHeapOffsets dflags False
+-- | Just like mkVirtConstrOffsets, but used when we don't have the actual
+-- arguments. Useful when e.g. generating info tables; we just need to know
+-- sizes of pointer and non-pointer fields.
+mkVirtConstrSizes :: DynFlags -> [NonVoid PrimRep] -> (WordOff, WordOff)
+mkVirtConstrSizes dflags field_reps
+ = (tot_wds, ptr_wds)
+ where
+ (tot_wds, ptr_wds, _) =
+ mkVirtConstrOffsets dflags
+ (map (\nv_rep -> NonVoid (fromNonVoid nv_rep, ())) field_reps)
-------------------------------------------------------------------------
--
diff --git a/compiler/codeGen/StgCmmTicky.hs b/compiler/codeGen/StgCmmTicky.hs
index 8df2dcac28..8e4e5ece5a 100644
--- a/compiler/codeGen/StgCmmTicky.hs
+++ b/compiler/codeGen/StgCmmTicky.hs
@@ -107,7 +107,6 @@ module StgCmmTicky (
#include "HsVersions.h"
import StgCmmArgRep ( slowCallPattern , toArgRep , argRepString )
-import StgCmmEnv ( NonVoid, unsafe_stripNV )
import StgCmmClosure
import StgCmmUtils
import StgCmmMonad
@@ -234,7 +233,7 @@ emitTickyCounter cloType name args
else n <+> ext <+> p
; fun_descr_lit <- newStringCLit $ showSDocDebug dflags ppr_for_ticky_name
- ; arg_descr_lit <- newStringCLit $ map (showTypeCategory . idType . unsafe_stripNV) args
+ ; arg_descr_lit <- newStringCLit $ map (showTypeCategory . idType . fromNonVoid) args
; emitDataLits ctr_lbl
-- Must match layout of includes/rts/Ticky.h's StgEntCounter
--