[commit: ghc] wip/oneShot: Add GHC.Prim.oneShot (d27eb19)
git at git.haskell.org
git at git.haskell.org
Tue Oct 28 22:44:50 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/oneShot
Link : http://ghc.haskell.org/trac/ghc/changeset/d27eb195223dbdd9de3248be903b6b2dc44422b1/ghc
>---------------------------------------------------------------
commit d27eb195223dbdd9de3248be903b6b2dc44422b1
Author: Joachim Breitner <mail at joachim-breitner.de>
Date: Sun Jan 26 11:36:23 2014 +0000
Add GHC.Prim.oneShot
to allow the programer to explictitly set the oneShot flag. This helps
with #7994 and will be used in left folds. Also see
https://ghc.haskell.org/trac/ghc/wiki/OneShot
>---------------------------------------------------------------
d27eb195223dbdd9de3248be903b6b2dc44422b1
compiler/basicTypes/MkId.lhs | 31 +++++++++++++++++++++++++++++--
compiler/prelude/PrelNames.lhs | 3 ++-
libraries/base/GHC/Event/Manager.hs | 6 +++---
3 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/compiler/basicTypes/MkId.lhs b/compiler/basicTypes/MkId.lhs
index bf1c199..34045db 100644
--- a/compiler/basicTypes/MkId.lhs
+++ b/compiler/basicTypes/MkId.lhs
@@ -135,7 +135,8 @@ ghcPrimIds
seqId,
magicDictId,
coerceId,
- proxyHashId
+ proxyHashId,
+ oneShotId
]
\end{code}
@@ -1016,7 +1017,7 @@ another gun with which to shoot yourself in the foot.
\begin{code}
lazyIdName, unsafeCoerceName, nullAddrName, seqName,
realWorldName, voidPrimIdName, coercionTokenName,
- magicDictName, coerceName, proxyName, dollarName :: Name
+ magicDictName, coerceName, proxyName, dollarName, oneShotName :: Name
unsafeCoerceName = mkWiredInIdName gHC_PRIM (fsLit "unsafeCoerce#") unsafeCoerceIdKey unsafeCoerceId
nullAddrName = mkWiredInIdName gHC_PRIM (fsLit "nullAddr#") nullAddrIdKey nullAddrId
seqName = mkWiredInIdName gHC_PRIM (fsLit "seq") seqIdKey seqId
@@ -1028,6 +1029,7 @@ magicDictName = mkWiredInIdName gHC_PRIM (fsLit "magicDict") magicDict
coerceName = mkWiredInIdName gHC_PRIM (fsLit "coerce") coerceKey coerceId
proxyName = mkWiredInIdName gHC_PRIM (fsLit "proxy#") proxyHashKey proxyHashId
dollarName = mkWiredInIdName gHC_BASE (fsLit "$") dollarIdKey dollarId
+oneShotName = mkWiredInIdName gHC_PRIM (fsLit "oneShot") oneShotKey oneShotId
\end{code}
\begin{code}
@@ -1119,6 +1121,17 @@ lazyId = pcMiscPrelId lazyIdName ty info
info = noCafIdInfo
ty = mkForAllTys [alphaTyVar] (mkFunTy alphaTy alphaTy)
+oneShotId :: Id -- See Note [The oneShot function]
+oneShotId = pcMiscPrelId oneShotName ty info
+ where
+ info = noCafIdInfo `setInlinePragInfo` alwaysInlinePragma
+ `setUnfoldingInfo` mkCompulsoryUnfolding rhs
+ ty = mkForAllTys [alphaTyVar, betaTyVar] (mkFunTy fun_ty fun_ty)
+ fun_ty = mkFunTy alphaTy betaTy
+ [body, x] = mkTemplateLocals [fun_ty, alphaTy]
+ x' = setOneShotLambda x
+ rhs = mkLams [alphaTyVar, betaTyVar, body, x'] $ Var body `App` Var x
+
--------------------------------------------------------------------------------
magicDictId :: Id -- See Note [magicDictId magic]
@@ -1253,6 +1266,20 @@ See Trac #3259 for a real world example.
lazyId is defined in GHC.Base, so we don't *have* to inline it. If it
appears un-applied, we'll end up just calling it.
+Note [The oneShot function]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the context of making left-folds fuse somewhat okish (see ticket #7994
+and Note [Left folds via right fold]) it was determined that it would be useful
+if library authors could explicitly tell the compiler that a certain lambda is
+called at most once. The oneShot function allows that.
+
+Like most magic functions it has a compulsary unfolding, so there is no need
+for a real definition somewhere. It uses `setOneShotLambda` on the lambdas
+binder, that is the whole magic. It is only effective if this bits survives as
+long as possible and makes it into the interface in unfoldings (See Note
+[Preserve OneShotInfo]). Also see https://ghc.haskell.org/trac/ghc/wiki/OneShot.
+
Note [magicDictId magic]
~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/compiler/prelude/PrelNames.lhs b/compiler/prelude/PrelNames.lhs
index 4e98739..73d1cf3 100644
--- a/compiler/prelude/PrelNames.lhs
+++ b/compiler/prelude/PrelNames.lhs
@@ -1686,10 +1686,11 @@ rootMainKey, runMainKey :: Unique
rootMainKey = mkPreludeMiscIdUnique 101
runMainKey = mkPreludeMiscIdUnique 102
-thenIOIdKey, lazyIdKey, assertErrorIdKey :: Unique
+thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey :: Unique
thenIOIdKey = mkPreludeMiscIdUnique 103
lazyIdKey = mkPreludeMiscIdUnique 104
assertErrorIdKey = mkPreludeMiscIdUnique 105
+oneShotKey = mkPreludeMiscIdUnique 106
breakpointIdKey, breakpointCondIdKey, breakpointAutoIdKey,
breakpointJumpIdKey, breakpointCondJumpIdKey,
diff --git a/libraries/base/GHC/Event/Manager.hs b/libraries/base/GHC/Event/Manager.hs
index 2041379..29edd97 100644
--- a/libraries/base/GHC/Event/Manager.hs
+++ b/libraries/base/GHC/Event/Manager.hs
@@ -167,10 +167,10 @@ newDefaultBackend = error "no back end for this platform"
-- | Create a new event manager.
new :: Bool -> IO EventManager
-new oneShot = newWith oneShot =<< newDefaultBackend
+new isOneShot = newWith isOneShot =<< newDefaultBackend
newWith :: Bool -> Backend -> IO EventManager
-newWith oneShot be = do
+newWith isOneShot be = do
iofds <- fmap (listArray (0, callbackArraySize-1)) $
replicateM callbackArraySize (newMVar =<< IT.new 8)
ctrl <- newControl False
@@ -187,7 +187,7 @@ newWith oneShot be = do
, emState = state
, emUniqueSource = us
, emControl = ctrl
- , emOneShot = oneShot
+ , emOneShot = isOneShot
, emLock = lockVar
}
registerControlFd mgr (controlReadFd ctrl) evtRead
More information about the ghc-commits
mailing list