diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-12-05 14:05:15 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2022-12-05 14:05:15 -0500 |
commit | 0bd718898f326c8e7d56107d8d3388c5cf1c8058 (patch) | |
tree | 0bc6f969f053f6284da257fdd914d1f9aab1eb33 | |
parent | c2bb5c6f54e0f09a38960142bf6f75acc531d17a (diff) | |
download | haskell-0bd718898f326c8e7d56107d8d3388c5cf1c8058.tar.gz |
compiler: More efficient implementation of typeArity
-rw-r--r-- | compiler/GHC/Core/Opt/Arity.hs | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/compiler/GHC/Core/Opt/Arity.hs b/compiler/GHC/Core/Opt/Arity.hs index df2a5c31c9..7a2fee6d0f 100644 --- a/compiler/GHC/Core/Opt/Arity.hs +++ b/compiler/GHC/Core/Opt/Arity.hs @@ -179,12 +179,29 @@ When we come to an application we check that the arg is trivial. ********************************************************************* -} +typeArity' :: Type -> Arity +typeArity' ty = length $ typeOneShots (StateHackFlag True) ty + typeArity :: Type -> Arity -- ^ (typeArity ty) says how many arrows GHC can expose in 'ty', after -- looking through newtypes. More generally, (typeOneShots ty) returns -- ty's [OneShotInfo], based only on the type itself, using typeOneShot -- on the argument type to access the "state hack". -typeArity = length . typeOneShots +typeArity ty0 = + assert (res == typeArity' ty0) res + where + res = go initRecTc 0 ty0 + go rec_nts !acc ty + | Just (_, ty') <- splitForAllTyCoVar_maybe ty + = go rec_nts acc ty' + | Just (_,_,_,res) <- splitFunTy_maybe ty + = go rec_nts (acc+1) res + | Just (tc,tys) <- splitTyConApp_maybe ty + , Just (ty', _) <- instNewTyCon_maybe tc tys + , Just rec_nts' <- checkRecTc rec_nts tc -- See Note [Expanding newtypes and products] + = go rec_nts' acc ty' + | otherwise + = acc typeOneShots :: Type -> [OneShotInfo] -- How many value arrows are visible in the type? |