diff options
author | Edward Z. Yang <ezyang@cs.stanford.edu> | 2016-05-12 19:38:57 -0700 |
---|---|---|
committer | Edward Z. Yang <ezyang@cs.stanford.edu> | 2016-08-21 00:53:21 -0700 |
commit | 704913cf79c7dbf9bf622fb3cfe476edd478b5a2 (patch) | |
tree | 7f45bfa7646e877309ac32c5822a7db9d1c28b71 /compiler | |
parent | e907e1f12f4dedc0ec13c7a501c8810bcfc03583 (diff) | |
download | haskell-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.hs | 32 | ||||
-rw-r--r-- | compiler/coreSyn/CorePrep.hs | 4 | ||||
-rw-r--r-- | compiler/prelude/PrelNames.hs | 5 |
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 |