Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Glasgow Haskell Compiler
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
0
Merge Requests
0
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Package Registry
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Shayne Fletcher
Glasgow Haskell Compiler
Commits
c73d372b
Commit
c73d372b
authored
Jul 17, 2013
by
nfrisby
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
resurrected -fdicts-strict, off by default
also added -fdmd-tx-dict-sel, on by default
parent
27572589
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
147 additions
and
83 deletions
+147
-83
compiler/basicTypes/DataCon.lhs
compiler/basicTypes/DataCon.lhs
+41
-1
compiler/basicTypes/Demand.lhs
compiler/basicTypes/Demand.lhs
+55
-3
compiler/basicTypes/Id.lhs
compiler/basicTypes/Id.lhs
+2
-2
compiler/deSugar/DsCCall.lhs
compiler/deSugar/DsCCall.lhs
+0
-41
compiler/main/DynFlags.hs
compiler/main/DynFlags.hs
+7
-1
compiler/main/StaticFlags.hs
compiler/main/StaticFlags.hs
+0
-8
compiler/stranal/DmdAnal.lhs
compiler/stranal/DmdAnal.lhs
+40
-9
compiler/types/Type.lhs
compiler/types/Type.lhs
+2
-18
No files found.
compiler/basicTypes/DataCon.lhs
View file @
c73d372b
...
@@ -36,7 +36,9 @@ module DataCon (
...
@@ -36,7 +36,9 @@ module DataCon (
dataConIsInfix,
dataConIsInfix,
dataConWorkId, dataConWrapId, dataConWrapId_maybe, dataConImplicitIds,
dataConWorkId, dataConWrapId, dataConWrapId_maybe, dataConImplicitIds,
dataConRepStrictness, dataConRepBangs, dataConBoxer,
dataConRepStrictness, dataConRepBangs, dataConBoxer,
splitDataProductType_maybe,
-- ** Predicates on DataCons
-- ** Predicates on DataCons
isNullarySrcDataCon, isNullaryRepDataCon, isTupleDataCon, isUnboxedTupleCon,
isNullarySrcDataCon, isNullaryRepDataCon, isTupleDataCon, isUnboxedTupleCon,
isVanillaDataCon, classDataCon, dataConCannotMatch,
isVanillaDataCon, classDataCon, dataConCannotMatch,
...
@@ -1086,3 +1088,41 @@ promoteKind (TyConApp tc [])
...
@@ -1086,3 +1088,41 @@ promoteKind (TyConApp tc [])
promoteKind (FunTy arg res) = FunTy (promoteKind arg) (promoteKind res)
promoteKind (FunTy arg res) = FunTy (promoteKind arg) (promoteKind res)
promoteKind k = pprPanic "promoteKind" (ppr k)
promoteKind k = pprPanic "promoteKind" (ppr k)
\end{code}
\end{code}
%************************************************************************
%* *
\subsection{Splitting products}
%* *
%************************************************************************
\begin{code}
-- | Extract the type constructor, type argument, data constructor and it's
-- /representation/ argument types from a type if it is a product type.
--
-- Precisely, we return @Just@ for any type that is all of:
--
-- * Concrete (i.e. constructors visible)
--
-- * Single-constructor
--
-- * Not existentially quantified
--
-- Whether the type is a @data@ type or a @newtype@
splitDataProductType_maybe
:: Type -- ^ A product type, perhaps
-> Maybe (TyCon, -- The type constructor
[Type], -- Type args of the tycon
DataCon, -- The data constructor
[Type]) -- Its /representation/ arg types
-- Rejecing existentials is conservative. Maybe some things
-- could be made to work with them, but I'm not going to sweat
-- it through till someone finds it's important.
splitDataProductType_maybe ty
| Just (tycon, ty_args) <- splitTyConApp_maybe ty
, Just con <- isDataProductTyCon_maybe tycon
= Just (tycon, ty_args, con, dataConInstArgTys con ty_args)
| otherwise
= Nothing
\end{code}
compiler/basicTypes/Demand.lhs
View file @
c73d372b
...
@@ -38,11 +38,14 @@ module Demand (
...
@@ -38,11 +38,14 @@ module Demand (
deferDmd, deferType, deferAndUse, deferEnv, modifyEnv,
deferDmd, deferType, deferAndUse, deferEnv, modifyEnv,
splitProdDmd, splitProdDmd_maybe, peelCallDmd, mkCallDmd,
splitProdDmd, splitProdDmd_maybe, peelCallDmd, mkCallDmd,
dmdTransformSig, dmdTransformDataConSig, argOneShots, argsOneShots,
dmdTransformSig, dmdTransformDataConSig, dmdTransformDictSelSig,
argOneShots, argsOneShots,
isSingleUsed, useType, useEnv, zapDemand, zapStrictSig,
isSingleUsed, useType, useEnv, zapDemand, zapStrictSig,
worthSplittingFun, worthSplittingThunk
worthSplittingFun, worthSplittingThunk,
strictifyDictDmd
) where
) where
...
@@ -57,6 +60,10 @@ import Util
...
@@ -57,6 +60,10 @@ import Util
import BasicTypes
import BasicTypes
import Binary
import Binary
import Maybes ( isJust, expectJust )
import Maybes ( isJust, expectJust )
import Type ( Type )
import TyCon ( isNewTyCon, isClassTyCon )
import DataCon ( splitDataProductType_maybe )
\end{code}
\end{code}
%************************************************************************
%************************************************************************
...
@@ -1303,6 +1310,21 @@ dmdTransformDataConSig arity (StrictSig (DmdType _ _ con_res))
...
@@ -1303,6 +1310,21 @@ dmdTransformDataConSig arity (StrictSig (DmdType _ _ con_res))
go_abs 0 dmd = Just (splitUseProdDmd arity dmd)
go_abs 0 dmd = Just (splitUseProdDmd arity dmd)
go_abs n (UCall One u') = go_abs (n-1) u'
go_abs n (UCall One u') = go_abs (n-1) u'
go_abs _ _ = Nothing
go_abs _ _ = Nothing
dmdTransformDictSelSig :: StrictSig -> CleanDemand -> DmdType
-- Like dmdTransformDataConSig, we have a special demand transformer
-- for dictionary selectors. If the selector is saturated (ie has one
-- argument: the dictionary), we feed the demand on the result into
-- the indicated dictionary component.
dmdTransformDictSelSig (StrictSig (DmdType _ [dictJd] _)) cd
= case peelCallDmd cd of
(cd',False,_) -> case splitProdDmd_maybe dictJd of
Just jds -> DmdType emptyDmdEnv [mkManyUsedDmd $ mkProdDmd $ map enhance jds] topRes
where enhance old | isAbsDmd old = old
| otherwise = mkManyUsedDmd cd'
Nothing -> panic "dmdTransformDictSelSig: split failed"
_ -> topDmdType
dmdTransformDictSelSig _ _ = panic "dmdTransformDictSelSig: no args"
\end{code}
\end{code}
Note [Non-full application]
Note [Non-full application]
...
@@ -1373,6 +1395,37 @@ zap_usg kfs (UProd us) = UProd (map (zap_musg kfs) us)
...
@@ -1373,6 +1395,37 @@ zap_usg kfs (UProd us) = UProd (map (zap_musg kfs) us)
zap_usg _ u = u
zap_usg _ u = u
\end{code}
\end{code}
\begin{code}
-- If the argument is a used non-newtype dictionary, give it strict
-- demand. Also split the product type & demand and recur in order to
-- similarly strictify the argument's contained used non-newtype
-- superclass dictionaries. We use the demand as our recursive measure
-- to guarantee termination.
strictifyDictDmd :: Type -> Demand -> Demand
strictifyDictDmd ty dmd = case absd dmd of
Use n _ |
Just (tycon, _arg_tys, _data_con, inst_con_arg_tys)
<- splitDataProductType_maybe ty,
not (isNewTyCon tycon), isClassTyCon tycon -- is a non-newtype dictionary
-> seqDmd `bothDmd` -- main idea: ensure it's strict
case splitProdDmd_maybe dmd of
-- superclass cycles should not be a problem, since the demand we are
-- consuming would also have to be infinite in order for us to diverge
Nothing -> dmd -- no components have interesting demand, so stop
-- looking for superclass dicts
Just dmds
| all (not . isAbsDmd) dmds -> evalDmd
-- abstract to strict w/ arbitrary component use, since this
-- smells like reboxing; results in CBV boxed
--
-- TODO revisit this if we ever do boxity analysis
| otherwise -> case mkProdDmd $ zipWith strictifyDictDmd inst_con_arg_tys dmds of
CD {sd = s,ud = a} -> JD (Str s) (Use n a)
-- TODO could optimize with an aborting variant of zipWith since
-- the superclass dicts are always a prefix
_ -> dmd -- unused or not a dictionary
\end{code}
%************************************************************************
%************************************************************************
%* *
%* *
...
@@ -1500,4 +1553,3 @@ instance Binary CPRResult where
...
@@ -1500,4 +1553,3 @@ instance Binary CPRResult where
2 -> return NoCPR
2 -> return NoCPR
_ -> return BotCPR
_ -> return BotCPR
\end{code}
\end{code}
compiler/basicTypes/Id.lhs
View file @
c73d372b
...
@@ -479,8 +479,8 @@ zapIdStrictness :: Id -> Id
...
@@ -479,8 +479,8 @@ zapIdStrictness :: Id -> Id
zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` topSig) id
zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` topSig) id
-- | This predicate says whether the 'Id' has a strict demand placed on it or
-- | This predicate says whether the 'Id' has a strict demand placed on it or
-- has a type such that it can always be evaluated strictly (
e.g.,
an
-- has a type such that it can always be evaluated strictly (
i.e
an
-- unlifted type,
but see the comment for 'isStrictType'
). We need to
-- unlifted type,
as of GHC 7.6
). We need to
-- check separately whether the 'Id' has a so-called \"strict type\" because if
-- check separately whether the 'Id' has a so-called \"strict type\" because if
-- the demand for the given @id@ hasn't been computed yet but @id@ has a strict
-- the demand for the given @id@ hasn't been computed yet but @id@ has a strict
-- type, we still want @isStrictId id@ to be @True@.
-- type, we still want @isStrictId id@ to be @True@.
...
...
compiler/deSugar/DsCCall.lhs
View file @
c73d372b
...
@@ -19,7 +19,6 @@ module DsCCall
...
@@ -19,7 +19,6 @@ module DsCCall
, unboxArg
, unboxArg
, boxResult
, boxResult
, resultWrapper
, resultWrapper
, splitDataProductType_maybe
) where
) where
#include "HsVersions.h"
#include "HsVersions.h"
...
@@ -392,43 +391,3 @@ maybeNarrow dflags tycon
...
@@ -392,43 +391,3 @@ maybeNarrow dflags tycon
&& wORD_SIZE dflags > 4 = \e -> App (Var (mkPrimOpId Narrow32WordOp)) e
&& wORD_SIZE dflags > 4 = \e -> App (Var (mkPrimOpId Narrow32WordOp)) e
| otherwise = id
| otherwise = id
\end{code}
\end{code}
%************************************************************************
%* *
\subsection{Splitting products}
%* *
%************************************************************************
\begin{code}
-- | Extract the type constructor, type argument, data constructor and it's
-- /representation/ argument types from a type if it is a product type.
--
-- Precisely, we return @Just@ for any type that is all of:
--
-- * Concrete (i.e. constructors visible)
--
-- * Single-constructor
--
-- * Not existentially quantified
--
-- Whether the type is a @data@ type or a @newtype@
splitDataProductType_maybe
:: Type -- ^ A product type, perhaps
-> Maybe (TyCon, -- The type constructor
[Type], -- Type args of the tycon
DataCon, -- The data constructor
[Type]) -- Its /representation/ arg types
-- Rejecing existentials is conservative. Maybe some things
-- could be made to work with them, but I'm not going to sweat
-- it through till someone finds it's important.
splitDataProductType_maybe ty
| Just (tycon, ty_args) <- splitTyConApp_maybe ty
, Just con <- isDataProductTyCon_maybe tycon
= Just (tycon, ty_args, con, dataConInstArgTys con ty_args)
| otherwise
= Nothing
\end{code}
compiler/main/DynFlags.hs
View file @
c73d372b
...
@@ -308,6 +308,8 @@ data GeneralFlag
...
@@ -308,6 +308,8 @@ data GeneralFlag
|
Opt_OmitYields
|
Opt_OmitYields
|
Opt_SimpleListLiterals
|
Opt_SimpleListLiterals
|
Opt_FunToThunk
-- allow WwLib.mkWorkerArgs to remove all value lambdas
|
Opt_FunToThunk
-- allow WwLib.mkWorkerArgs to remove all value lambdas
|
Opt_DictsStrict
-- be strict in argument dictionaries
|
Opt_DmdTxDictSel
-- use a special demand transformer for dictionary selectors
-- Interface files
-- Interface files
|
Opt_IgnoreInterfacePragmas
|
Opt_IgnoreInterfacePragmas
...
@@ -2590,7 +2592,9 @@ fFlags = [
...
@@ -2590,7 +2592,9 @@ fFlags = [
(
"flat-cache"
,
Opt_FlatCache
,
nop
),
(
"flat-cache"
,
Opt_FlatCache
,
nop
),
(
"use-rpaths"
,
Opt_RPath
,
nop
),
(
"use-rpaths"
,
Opt_RPath
,
nop
),
(
"kill-absence"
,
Opt_KillAbsence
,
nop
),
(
"kill-absence"
,
Opt_KillAbsence
,
nop
),
(
"kill-one-shot"
,
Opt_KillOneShot
,
nop
)
(
"kill-one-shot"
,
Opt_KillOneShot
,
nop
),
(
"dicts-strict"
,
Opt_DictsStrict
,
nop
),
(
"dmd-tx-dict-sel"
,
Opt_DmdTxDictSel
,
nop
)
]
]
-- | These @-f\<blah\>@ flags can all be reversed with @-fno-\<blah\>@
-- | These @-f\<blah\>@ flags can all be reversed with @-fno-\<blah\>@
...
@@ -2874,6 +2878,8 @@ optLevelFlags
...
@@ -2874,6 +2878,8 @@ optLevelFlags
,
([
1
,
2
],
Opt_CmmSink
)
,
([
1
,
2
],
Opt_CmmSink
)
,
([
1
,
2
],
Opt_CmmElimCommonBlocks
)
,
([
1
,
2
],
Opt_CmmElimCommonBlocks
)
,
([
0
,
1
,
2
],
Opt_DmdTxDictSel
)
-- , ([2], Opt_StaticArgumentTransformation)
-- , ([2], Opt_StaticArgumentTransformation)
-- Max writes: I think it's probably best not to enable SAT with -O2 for the
-- Max writes: I think it's probably best not to enable SAT with -O2 for the
-- 6.10 release. The version of SAT in HEAD at the moment doesn't incorporate
-- 6.10 release. The version of SAT in HEAD at the moment doesn't incorporate
...
...
compiler/main/StaticFlags.hs
View file @
c73d372b
...
@@ -23,9 +23,6 @@ module StaticFlags (
...
@@ -23,9 +23,6 @@ module StaticFlags (
opt_PprStyle_Debug
,
opt_PprStyle_Debug
,
opt_NoDebugOutput
,
opt_NoDebugOutput
,
-- language opts
opt_DictsStrict
,
-- optimisation opts
-- optimisation opts
opt_NoStateHack
,
opt_NoStateHack
,
opt_CprOff
,
opt_CprOff
,
...
@@ -149,7 +146,6 @@ isStaticFlag f = f `elem` flagsStaticNames
...
@@ -149,7 +146,6 @@ isStaticFlag f = f `elem` flagsStaticNames
flagsStaticNames
::
[
String
]
flagsStaticNames
::
[
String
]
flagsStaticNames
=
[
flagsStaticNames
=
[
"fdicts-strict"
,
"fno-state-hack"
,
"fno-state-hack"
,
"fno-opt-coercion"
,
"fno-opt-coercion"
,
"fcpr-off"
"fcpr-off"
...
@@ -189,10 +185,6 @@ opt_PprStyle_Debug = lookUp (fsLit "-dppr-debug")
...
@@ -189,10 +185,6 @@ opt_PprStyle_Debug = lookUp (fsLit "-dppr-debug")
opt_NoDebugOutput
::
Bool
opt_NoDebugOutput
::
Bool
opt_NoDebugOutput
=
lookUp
(
fsLit
"-dno-debug-output"
)
opt_NoDebugOutput
=
lookUp
(
fsLit
"-dno-debug-output"
)
-- language opts
opt_DictsStrict
::
Bool
opt_DictsStrict
=
lookUp
(
fsLit
"-fdicts-strict"
)
opt_NoStateHack
::
Bool
opt_NoStateHack
::
Bool
opt_NoStateHack
=
lookUp
(
fsLit
"-fno-state-hack"
)
opt_NoStateHack
=
lookUp
(
fsLit
"-fno-state-hack"
)
...
...
compiler/stranal/DmdAnal.lhs
View file @
c73d372b
...
@@ -180,6 +180,7 @@ dmdAnal env dmd (App fun arg) -- Non-type arguments
...
@@ -180,6 +180,7 @@ dmdAnal env dmd (App fun arg) -- Non-type arguments
-- , text "overall res dmd_ty =" <+> ppr (res_ty `bothDmdType` arg_ty) ])
-- , text "overall res dmd_ty =" <+> ppr (res_ty `bothDmdType` arg_ty) ])
(res_ty `bothDmdType` arg_ty, App fun' arg')
(res_ty `bothDmdType` arg_ty, App fun' arg')
-- this is an anonymous lambda, since @dmdAnalRhs@ uses @collectBinders@
dmdAnal env dmd (Lam var body)
dmdAnal env dmd (Lam var body)
| isTyVar var
| isTyVar var
= let
= let
...
@@ -195,7 +196,7 @@ dmdAnal env dmd (Lam var body)
...
@@ -195,7 +196,7 @@ dmdAnal env dmd (Lam var body)
env' = extendSigsWithLam env var
env' = extendSigsWithLam env var
(body_ty, body') = dmdAnal env' body_dmd body
(body_ty, body') = dmdAnal env' body_dmd body
(lam_ty, var') = annotateLamIdBndr env body_ty one_shot var
(lam_ty, var') = annotateLamIdBndr env
notArgOfDfun
body_ty one_shot var
in
in
(deferAndUse defer_me one_shot lam_ty, Lam var' body')
(deferAndUse defer_me one_shot lam_ty, Lam var' body')
...
@@ -480,6 +481,10 @@ dmdTransform env var dmd
...
@@ -480,6 +481,10 @@ dmdTransform env var dmd
= dmdTransformDataConSig
= dmdTransformDataConSig
(idArity var) (idStrictness var) dmd
(idArity var) (idStrictness var) dmd
| gopt Opt_DmdTxDictSel (ae_dflags env),
Just _ <- isClassOpId_maybe var -- Dictionary component selector
= dmdTransformDictSelSig (idStrictness var) dmd
| isGlobalId var -- Imported function
| isGlobalId var -- Imported function
= let res = dmdTransformSig (idStrictness var) dmd in
= let res = dmdTransformSig (idStrictness var) dmd in
-- pprTrace "dmdTransform" (vcat [ppr var, ppr (idStrictness var), ppr dmd, ppr res])
-- pprTrace "dmdTransform" (vcat [ppr var, ppr (idStrictness var), ppr dmd, ppr res])
...
@@ -589,7 +594,7 @@ dmdAnalRhs top_lvl rec_flag env id rhs
...
@@ -589,7 +594,7 @@ dmdAnalRhs top_lvl rec_flag env id rhs
(bndrs, body) = collectBinders rhs
(bndrs, body) = collectBinders rhs
env_body = foldl extendSigsWithLam env bndrs
env_body = foldl extendSigsWithLam env bndrs
(body_dmd_ty, body') = dmdAnal env_body body_dmd body
(body_dmd_ty, body') = dmdAnal env_body body_dmd body
(rhs_dmd_ty, bndrs') = annotateLamBndrs env body_dmd_ty bndrs
(rhs_dmd_ty, bndrs') = annotateLamBndrs env
(isDFunId id)
body_dmd_ty bndrs
id' = set_idStrictness env id sig_ty
id' = set_idStrictness env id sig_ty
sig_ty = mkStrictSig (mkDmdType sig_fv rhs_dmds rhs_res')
sig_ty = mkStrictSig (mkDmdType sig_fv rhs_dmds rhs_res')
-- See Note [NOINLINE and strictness]
-- See Note [NOINLINE and strictness]
...
@@ -733,6 +738,13 @@ the safe result we also have absent demand set to Abs, which makes it
...
@@ -733,6 +738,13 @@ the safe result we also have absent demand set to Abs, which makes it
possible to safely ignore non-mentioned variables (their joint demand
possible to safely ignore non-mentioned variables (their joint demand
is <L,A>).
is <L,A>).
Note [do not strictify the argument dictionaries of a dfun]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The typechecker can tie recursive knots involving dfuns, so we do the
conservative thing and refrain from strictifying a dfun's argument
dictionaries.
\begin{code}
\begin{code}
annotateBndr :: AnalEnv -> DmdType -> Var -> (DmdType, Var)
annotateBndr :: AnalEnv -> DmdType -> Var -> (DmdType, Var)
-- The returned env has the var deleted
-- The returned env has the var deleted
...
@@ -741,33 +753,41 @@ annotateBndr :: AnalEnv -> DmdType -> Var -> (DmdType, Var)
...
@@ -741,33 +753,41 @@ annotateBndr :: AnalEnv -> DmdType -> Var -> (DmdType, Var)
-- No effect on the argument demands
-- No effect on the argument demands
annotateBndr env dmd_ty@(DmdType fv ds res) var
annotateBndr env dmd_ty@(DmdType fv ds res) var
| isTyVar var = (dmd_ty, var)
| isTyVar var = (dmd_ty, var)
| otherwise = (DmdType fv' ds res, set_idDemandInfo env var dmd)
| otherwise = (DmdType fv' ds res, set_idDemandInfo env var dmd
'
)
where
where
(fv', dmd) = peelFV fv var res
(fv', dmd) = peelFV fv var res
dmd' | gopt Opt_DictsStrict (ae_dflags env)
-- We never want to strictify a recursive let. At the moment
-- annotateBndr is only call for non-recursive lets; if that
-- changes, we need a RecFlag parameter and another guard here.
= strictifyDictDmd (idType var) dmd
| otherwise = dmd
annotateBndrs :: AnalEnv -> DmdType -> [Var] -> (DmdType, [Var])
annotateBndrs :: AnalEnv -> DmdType -> [Var] -> (DmdType, [Var])
annotateBndrs env = mapAccumR (annotateBndr env)
annotateBndrs env = mapAccumR (annotateBndr env)
annotateLamBndrs :: AnalEnv -> DmdType -> [Var] -> (DmdType, [Var])
annotateLamBndrs :: AnalEnv -> D
FunFlag -> D
mdType -> [Var] -> (DmdType, [Var])
annotateLamBndrs env ty bndrs = mapAccumR annotate ty bndrs
annotateLamBndrs env
args_of_dfun
ty bndrs = mapAccumR annotate ty bndrs
where
where
annotate dmd_ty bndr
annotate dmd_ty bndr
| isId bndr = annotateLamIdBndr env dmd_ty Many bndr
| isId bndr = annotateLamIdBndr env
args_of_dfun
dmd_ty Many bndr
| otherwise = (dmd_ty, bndr)
| otherwise = (dmd_ty, bndr)
annotateLamIdBndr :: AnalEnv
annotateLamIdBndr :: AnalEnv
-> DFunFlag -- is this lambda at the top of the RHS of a dfun?
-> DmdType -- Demand type of body
-> DmdType -- Demand type of body
-> Count -- One-shot-ness of the lambda
-> Count -- One-shot-ness of the lambda
-> Id -- Lambda binder
-> Id -- Lambda binder
-> (DmdType, -- Demand type of lambda
-> (DmdType, -- Demand type of lambda
Id) -- and binder annotated with demand
Id) -- and binder annotated with demand
annotateLamIdBndr env _dmd_ty@(DmdType fv ds res) one_shot id
annotateLamIdBndr env
arg_of_dfun
_dmd_ty@(DmdType fv ds res) one_shot id
-- For lambdas we add the demand to the argument demands
-- For lambdas we add the demand to the argument demands
-- Only called for Ids
-- Only called for Ids
= ASSERT( isId id )
= ASSERT( isId id )
-- pprTrace "annLamBndr" (vcat [ppr id, ppr _dmd_ty]) $
-- pprTrace "annLamBndr" (vcat [ppr id, ppr _dmd_ty]) $
(final_ty, setOneShotness one_shot (set_idDemandInfo env id dmd))
(final_ty, setOneShotness one_shot (set_idDemandInfo env id dmd
'
))
where
where
-- Watch out! See note [Lambda-bound unfoldings]
-- Watch out! See note [Lambda-bound unfoldings]
final_ty = case maybeUnfoldingTemplate (idUnfolding id) of
final_ty = case maybeUnfoldingTemplate (idUnfolding id) of
...
@@ -780,6 +800,12 @@ annotateLamIdBndr env _dmd_ty@(DmdType fv ds res) one_shot id
...
@@ -780,6 +800,12 @@ annotateLamIdBndr env _dmd_ty@(DmdType fv ds res) one_shot id
(fv', dmd) = peelFV fv id res
(fv', dmd) = peelFV fv id res
dmd' | gopt Opt_DictsStrict (ae_dflags env),
-- see Note [do not strictify the argument dictionaries of a dfun]
not arg_of_dfun
= strictifyDictDmd (idType id) dmd
| otherwise = dmd
deleteFVs :: DmdType -> [Var] -> DmdType
deleteFVs :: DmdType -> [Var] -> DmdType
deleteFVs (DmdType fvs dmds res) bndrs
deleteFVs (DmdType fvs dmds res) bndrs
= DmdType (delVarEnvList fvs bndrs) dmds res
= DmdType (delVarEnvList fvs bndrs) dmds res
...
@@ -985,13 +1011,18 @@ forget that fact, otherwise we might make 'x' absent when it isn't.
...
@@ -985,13 +1011,18 @@ forget that fact, otherwise we might make 'x' absent when it isn't.
%************************************************************************
%************************************************************************
\begin{code}
\begin{code}
type DFunFlag = Bool -- indicates if the lambda being considered is in the
-- sequence of lambdas at the top of the RHS of a dfun
notArgOfDfun :: DFunFlag
notArgOfDfun = False
data AnalEnv
data AnalEnv
= AE { ae_dflags :: DynFlags
= AE { ae_dflags :: DynFlags
, ae_sigs :: SigEnv
, ae_sigs :: SigEnv
, ae_virgin :: Bool -- True on first iteration only
, ae_virgin :: Bool -- True on first iteration only
-- See Note [Initialising strictness]
-- See Note [Initialising strictness]
, ae_rec_tc :: RecTcChecker
, ae_rec_tc :: RecTcChecker
}
}
-- We use the se_env to tell us whether to
-- We use the se_env to tell us whether to
-- record info about a variable in the DmdEnv
-- record info about a variable in the DmdEnv
...
...
compiler/types/Type.lhs
View file @
c73d372b
...
@@ -166,7 +166,6 @@ import CoAxiom
...
@@ -166,7 +166,6 @@ import CoAxiom
-- others
-- others
import Unique ( Unique, hasKey )
import Unique ( Unique, hasKey )
import BasicTypes ( Arity, RepArity )
import BasicTypes ( Arity, RepArity )
import StaticFlags
import Util
import Util
import Outputable
import Outputable
import FastString
import FastString
...
@@ -1093,25 +1092,10 @@ isClosedAlgType ty
...
@@ -1093,25 +1092,10 @@ isClosedAlgType ty
\begin{code}
\begin{code}
-- | Computes whether an argument (or let right hand side) should
-- | Computes whether an argument (or let right hand side) should
-- be computed strictly or lazily, based only on its type.
-- be computed strictly or lazily, based only on its type.
-- Works just like 'isUnLiftedType', except that it has a special case
-- Currently, it's just 'isUnLiftedType'.
-- for dictionaries (i.e. does not work purely on representation types)
-- Since it takes account of class 'PredType's, you might think
-- this function should be in 'TcType', but 'isStrictType' is used by 'DataCon',
-- which is below 'TcType' in the hierarchy, so it's convenient to put it here.
--
-- We may be strict in dictionary types, but only if it
-- has more than one component.
--
-- (Being strict in a single-component dictionary risks
-- poking the dictionary component, which is wrong.)
isStrictType :: Type -> Bool
isStrictType :: Type -> Bool
isStrictType ty | Just ty' <- coreView ty = isStrictType ty'
isStrictType = isUnLiftedType
isStrictType (ForAllTy _ ty) = isStrictType ty
isStrictType (TyConApp tc _)
| isUnLiftedTyCon tc = True
| isClassTyCon tc, opt_DictsStrict = True
isStrictType _ = False
\end{code}
\end{code}
\begin{code}
\begin{code}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment