summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorEdward Z. Yang <ezyang@cs.stanford.edu>2016-05-12 19:38:57 -0700
committerEdward Z. Yang <ezyang@cs.stanford.edu>2016-08-21 00:53:21 -0700
commit704913cf79c7dbf9bf622fb3cfe476edd478b5a2 (patch)
tree7f45bfa7646e877309ac32c5822a7db9d1c28b71 /compiler
parente907e1f12f4dedc0ec13c7a501c8810bcfc03583 (diff)
downloadhaskell-704913cf79c7dbf9bf622fb3cfe476edd478b5a2.tar.gz
Support for noinline magic function.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu> Test Plan: validate Reviewers: simonpj, austin, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2209
Diffstat (limited to 'compiler')
-rw-r--r--compiler/basicTypes/MkId.hs32
-rw-r--r--compiler/coreSyn/CorePrep.hs4
-rw-r--r--compiler/prelude/PrelNames.hs5
3 files changed, 36 insertions, 5 deletions
diff --git a/compiler/basicTypes/MkId.hs b/compiler/basicTypes/MkId.hs
index 151e1cf983..649100a7c0 100644
--- a/compiler/basicTypes/MkId.hs
+++ b/compiler/basicTypes/MkId.hs
@@ -31,7 +31,7 @@ module MkId (
voidPrimId, voidArgId,
nullAddrId, seqId, lazyId, lazyIdKey, runRWId,
coercionTokenId, magicDictId, coerceId,
- proxyHashId,
+ proxyHashId, noinlineIdName,
-- Re-export error Ids
module PrelRules
@@ -112,6 +112,9 @@ There are several reasons why an Id might appear in the wiredInIds:
(4) lazyId is wired in because the wired-in version overrides the
strictness of the version defined in GHC.Base
+(5) noinlineId is wired in because when we serialize to interfaces
+ we may insert noinline statements.
+
In cases (2-4), the function has a definition in a library module, and
can be called; but the wired-in version means that the details are
never read from that module's interface file; instead, the full definition
@@ -120,7 +123,7 @@ is right here.
wiredInIds :: [Id]
wiredInIds
- = [lazyId, dollarId, oneShotId, runRWId]
+ = [lazyId, dollarId, oneShotId, runRWId, noinlineId]
++ errorIds -- Defined in MkCore
++ ghcPrimIds
@@ -1039,7 +1042,7 @@ another gun with which to shoot yourself in the foot.
lazyIdName, unsafeCoerceName, nullAddrName, seqName,
realWorldName, voidPrimIdName, coercionTokenName,
magicDictName, coerceName, proxyName, dollarName, oneShotName,
- runRWName :: Name
+ runRWName, noinlineIdName :: 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
@@ -1053,6 +1056,7 @@ proxyName = mkWiredInIdName gHC_PRIM (fsLit "proxy#") proxyHash
dollarName = mkWiredInIdName gHC_BASE (fsLit "$") dollarIdKey dollarId
oneShotName = mkWiredInIdName gHC_MAGIC (fsLit "oneShot") oneShotKey oneShotId
runRWName = mkWiredInIdName gHC_MAGIC (fsLit "runRW#") runRWKey runRWId
+noinlineIdName = mkWiredInIdName gHC_MAGIC (fsLit "noinline") noinlineIdKey noinlineId
dollarId :: Id -- Note [dollarId magic]
dollarId = pcMiscPrelId dollarName ty
@@ -1159,6 +1163,12 @@ lazyId = pcMiscPrelId lazyIdName ty info
info = noCafIdInfo
ty = mkSpecForAllTys [alphaTyVar] (mkFunTy alphaTy alphaTy)
+noinlineId :: Id -- See Note [noinlineId magic]
+noinlineId = pcMiscPrelId noinlineIdName ty info
+ where
+ info = noCafIdInfo
+ ty = mkSpecForAllTys [alphaTyVar] (mkFunTy alphaTy alphaTy)
+
oneShotId :: Id -- See Note [The oneShot function]
oneShotId = pcMiscPrelId oneShotName ty info
where
@@ -1362,6 +1372,22 @@ Implementing 'lazy' is a bit tricky:
* 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 [noinlineId magic]
+~~~~~~~~~~~~~~~~~~~~~~~
+noinline :: forall a. a -> a
+
+'noinline' is used to make sure that a function f is never inlined,
+e.g., as in 'noinline f x'. Ordinarily, the identity function with NOINLINE
+could be used to achieve this effect; however, this has the unfortunate
+result of leaving a (useless) call to noinline at runtime. So we have
+a little bit of magic to optimize away 'noinline' after we are done
+running the simplifier.
+
+'noinline' needs to be wired-in because it gets inserted automatically
+when we serialize an expression to the interface format, and we DON'T
+want use its fingerprints.
+
+
Note [runRW magic]
~~~~~~~~~~~~~~~~~~
Some definitions, for instance @runST@, must have careful control over float out
diff --git a/compiler/coreSyn/CorePrep.hs b/compiler/coreSyn/CorePrep.hs
index 320a98992c..8e9c01a0a9 100644
--- a/compiler/coreSyn/CorePrep.hs
+++ b/compiler/coreSyn/CorePrep.hs
@@ -110,6 +110,7 @@ The goal of this pass is to prepare for code generation.
aren't inlined by some caller.
9. Replace (lazy e) by e. See Note [lazyId magic] in MkId.hs
+ Also replace (noinline e) by e.
10. Convert (LitInteger i t) into the core representation
for the Integer i. Normally this uses mkInteger, but if
@@ -517,7 +518,8 @@ cpeRhsE _env expr@(Lit {}) = return (emptyFloats, expr)
cpeRhsE env expr@(Var {}) = cpeApp env expr
cpeRhsE env (Var f `App` _{-type-} `App` arg)
- | f `hasKey` lazyIdKey -- Replace (lazy a) by a
+ | f `hasKey` lazyIdKey -- Replace (lazy a) with a, and
+ || f `hasKey` noinlineIdKey -- Replace (noinline a) with a
= cpeRhsE env arg -- See Note [lazyId magic] in MkId
cpeRhsE env (Var f `App` _runtimeRep `App` _type `App` arg)
diff --git a/compiler/prelude/PrelNames.hs b/compiler/prelude/PrelNames.hs
index e5e458d626..00e9ffed96 100644
--- a/compiler/prelude/PrelNames.hs
+++ b/compiler/prelude/PrelNames.hs
@@ -2034,8 +2034,9 @@ breakpointJumpIdKey = mkPreludeMiscIdUnique 113
breakpointCondJumpIdKey = mkPreludeMiscIdUnique 114
breakpointAutoJumpIdKey = mkPreludeMiscIdUnique 115
-inlineIdKey :: Unique
+inlineIdKey, noinlineIdKey :: Unique
inlineIdKey = mkPreludeMiscIdUnique 120
+-- see below
mapIdKey, groupWithIdKey, dollarIdKey :: Unique
mapIdKey = mkPreludeMiscIdUnique 121
@@ -2045,6 +2046,8 @@ dollarIdKey = mkPreludeMiscIdUnique 123
coercionTokenIdKey :: Unique
coercionTokenIdKey = mkPreludeMiscIdUnique 124
+noinlineIdKey = mkPreludeMiscIdUnique 125
+
rationalToFloatIdKey, rationalToDoubleIdKey :: Unique
rationalToFloatIdKey = mkPreludeMiscIdUnique 130
rationalToDoubleIdKey = mkPreludeMiscIdUnique 131