Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
GHC
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
Alex D
GHC
Commits
abfbdd1c
Commit
abfbdd1c
authored
Oct 31, 2014
by
Simon Peyton Jones
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add comments explaining ProbOneShot
parent
dbbffb7b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
79 additions
and
44 deletions
+79
-44
compiler/basicTypes/BasicTypes.lhs
compiler/basicTypes/BasicTypes.lhs
+5
-3
compiler/basicTypes/Demand.lhs
compiler/basicTypes/Demand.lhs
+71
-39
compiler/simplCore/OccurAnal.lhs
compiler/simplCore/OccurAnal.lhs
+2
-2
compiler/simplCore/SetLevels.lhs
compiler/simplCore/SetLevels.lhs
+1
-0
No files found.
compiler/basicTypes/BasicTypes.lhs
View file @
abfbdd1c
...
...
@@ -155,9 +155,11 @@ type Alignment = Int -- align to next N-byte boundary (N must be a power of 2).
-- This information may be useful in optimisation, as computations may
-- safely be floated inside such a lambda without risk of duplicating
-- work.
data OneShotInfo = NoOneShotInfo -- ^ No information
| ProbOneShot -- ^ The lambda is probably applied at most once
| OneShotLam -- ^ The lambda is applied at most once.
data OneShotInfo
= NoOneShotInfo -- ^ No information
| ProbOneShot -- ^ The lambda is probably applied at most once
-- See Note [Computing one-shot info, and ProbOneShot] in OccurAnl
| OneShotLam -- ^ The lambda is applied at most once.
-- | It is always safe to assume that an 'Id' has no lambda-bound variable information
noOneShotInfo :: OneShotInfo
...
...
compiler/basicTypes/Demand.lhs
View file @
abfbdd1c
...
...
@@ -1493,6 +1493,11 @@ newtype StrictSig = StrictSig DmdType
instance Outputable StrictSig where
ppr (StrictSig ty) = ppr ty
-- Used for printing top-level strictness pragmas in interface files
pprIfaceStrictSig :: StrictSig -> SDoc
pprIfaceStrictSig (StrictSig (DmdType _ dmds res))
= hcat (map ppr dmds) <> ppr res
mkStrictSig :: DmdType -> StrictSig
mkStrictSig dmd_ty = StrictSig dmd_ty
...
...
@@ -1520,29 +1525,8 @@ botSig = StrictSig botDmdType
cprProdSig :: Arity -> StrictSig
cprProdSig arity = StrictSig (cprProdDmdType arity)
argsOneShots :: StrictSig -> Arity -> [[OneShotInfo]]
argsOneShots (StrictSig (DmdType _ arg_ds _)) n_val_args
= go arg_ds
where
good_one_shot
| arg_ds `lengthExceeds` n_val_args = ProbOneShot
| otherwise = OneShotLam
go [] = []
go (arg_d : arg_ds) = argOneShots good_one_shot arg_d `cons` go arg_ds
cons [] [] = []
cons a as = a:as
argOneShots :: OneShotInfo -> JointDmd -> [OneShotInfo]
argOneShots one_shot_info (JD { absd = usg })
= case usg of
Use _ arg_usg -> go arg_usg
_ -> []
where
go (UCall One u) = one_shot_info : go u
go (UCall Many u) = NoOneShotInfo : go u
go _ = []
seqStrictSig :: StrictSig -> ()
seqStrictSig (StrictSig ty) = seqDmdType ty
dmdTransformSig :: StrictSig -> CleanDemand -> DmdType
-- (dmdTransformSig fun_sig dmd) considers a call to a function whose
...
...
@@ -1617,31 +1601,79 @@ you might do strictness analysis, but there is no inlining for the class op.
This is weird, so I'm not worried about whether this optimises brilliantly; but
it should not fall over.
Note [Non-full application]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
If a function having bottom as its demand result is applied to a less
number of arguments than its syntactic arity, we cannot say for sure
that it is going to diverge. This is the reason why we use the
function appIsBottom, which, given a strictness signature and a number
of arguments, says conservatively if the function is going to diverge
or not.
\begin{code}
argsOneShots :: StrictSig -> Arity -> [[OneShotInfo]]
-- See Note [Computing one-shot info, and ProbOneShot]
argsOneShots (StrictSig (DmdType _ arg_ds _)) n_val_args
= go arg_ds
where
unsaturated_call = arg_ds `lengthExceeds` n_val_args
good_one_shot
| unsaturated_call = ProbOneShot
| otherwise = OneShotLam
go [] = []
go (arg_d : arg_ds) = argOneShots good_one_shot arg_d `cons` go arg_ds
-- Avoid list tail like [ [], [], [] ]
cons [] [] = []
cons a as = a:as
argOneShots :: OneShotInfo -> JointDmd -> [OneShotInfo]
argOneShots one_shot_info (JD { absd = usg })
= case usg of
Use _ arg_usg -> go arg_usg
_ -> []
where
go (UCall One u) = one_shot_info : go u
go (UCall Many u) = NoOneShotInfo : go u
go _ = []
\end{code}
Note [Computing one-shot info, and ProbOneShot]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider a call
f (\pqr. e1) (\xyz. e2) e3
where f has usage signature
C1(C(C1(U))) C1(U) U
Then argsOneShots returns a [[OneShotInfo]] of
[[OneShot,NoOneShotInfo,OneShot], [OneShot]]
The occurrence analyser propagates this one-shot infor to the
binders \pqr and \xyz; see Note [Use one-shot information] in OccurAnal.
But suppose f was not saturated, so the call looks like
f (\pqr. e1) (\xyz. e2)
The in principle this partial application might be shared, and
the (\prq.e1) abstraction might be called more than once. So
we can't mark them OneShot. But instead we return
[[ProbOneShot,NoOneShotInfo,ProbOneShot], [ProbOneShot]]
The occurrence analyser propagates this to the \pqr and \xyz
binders.
How is it used? Well, it's quite likely that the partial application
of f is not shared, so the float-out pass (in SetLevels.lvlLamBndrs)
does not float MFEs out of a ProbOneShot lambda. That currently is
the only way that ProbOneShot is used.
\begin{code}
-- appIsBottom returns true if an application to n args would diverge
-- See Note [Unsaturated applications]
appIsBottom :: StrictSig -> Int -> Bool
appIsBottom (StrictSig (DmdType _ ds res)) n
| isBotRes res = not $ lengthExceeds ds n
appIsBottom _ _ = False
seqStrictSig :: StrictSig -> ()
seqStrictSig (StrictSig ty) = seqDmdType ty
-- Used for printing top-level strictness pragmas in interface files
pprIfaceStrictSig :: StrictSig -> SDoc
pprIfaceStrictSig (StrictSig (DmdType _ dmds res))
= hcat (map ppr dmds) <> ppr res
\end{code}
Note [Unsaturated applications]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If a function having bottom as its demand result is applied to a less
number of arguments than its syntactic arity, we cannot say for sure
that it is going to diverge. This is the reason why we use the
function appIsBottom, which, given a strictness signature and a number
of arguments, says conservatively if the function is going to diverge
or not.
Zap absence or one-shot information, under control of flags
\begin{code}
...
...
compiler/simplCore/OccurAnal.lhs
View file @
abfbdd1c
...
...
@@ -1380,13 +1380,13 @@ The occurrrence analyser propagates one-shot-lambda information in two situation
Propagate one-shot info from the strictness signature of 'build' to
the \cn
* Let-bindings: eg let f = \c. let ... in \n -> blah
* Let-bindings: eg let f = \c. let ... in \n -> blah
in (build f, build f)
Propagate one-shot info from the demanand-info on 'f' to the
lambdas in its RHS (which may not be syntactically at the top)
Some of this is done by the demand analyser, but this way it happens
much earlier, taking advantage of the strictness signature of
much earlier, taking advantage of the strictness signature of
imported functions.
Note [Binders in case alternatives]
...
...
compiler/simplCore/SetLevels.lhs
View file @
abfbdd1c
...
...
@@ -827,6 +827,7 @@ lvlLamBndrs env lvl bndrs
is_major bndr = isId bndr && not (isProbablyOneShotLambda bndr)
-- The "probably" part says "don't float things out of a
-- probable one-shot lambda"
-- See Note [Computing one-shot info] in Demand.lhs
lvlBndrs :: LevelEnv -> Level -> [CoreBndr] -> (LevelEnv, [LevelledBndr])
...
...
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