diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2020-06-26 23:22:05 +0100 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-07-10 10:33:44 -0400 |
commit | d9f095060b0f00d7140f8b0858b7a5dcbffea9ef (patch) | |
tree | adbe11dfcc159e2360eb75f24adfecfbd1a730d4 /compiler/GHC/Core | |
parent | 3656dff8259199d0dab2d1a1f1b887c252a9c1a3 (diff) | |
download | haskell-d9f095060b0f00d7140f8b0858b7a5dcbffea9ef.tar.gz |
Define multiShotIO and use it in mkSplitUniqueSupply
This patch is part of the ongoing eta-expansion saga;
see #18238.
It implements a neat trick (suggested by Sebastian Graf)
that allows the programmer to disable the default one-shot behaviour
of IO (the "state hack"). The trick is to use a new multiShotIO
function; see Note [multiShotIO]. For now, multiShotIO is defined
here in Unique.Supply; but it should ultimately be moved to the IO
library.
The change is necessary to get good code for GHC's unique supply;
see Note [Optimising the unique supply].
However it makes no difference to GHC as-is. Rather, it makes
a difference when a subsequent commit
Improve eta-expansion using ArityType
lands.
Diffstat (limited to 'compiler/GHC/Core')
-rw-r--r-- | compiler/GHC/Core/Opt/ConstantFold.hs | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/compiler/GHC/Core/Opt/ConstantFold.hs b/compiler/GHC/Core/Opt/ConstantFold.hs index de98dd0842..e6d23f3d0a 100644 --- a/compiler/GHC/Core/Opt/ConstantFold.hs +++ b/compiler/GHC/Core/Opt/ConstantFold.hs @@ -1519,18 +1519,40 @@ match_cstring_length env id_unf _ [lit1] match_cstring_length _ _ _ _ = Nothing --------------------------------------------------- --- The rule is this: --- inline f_ty (f a b c) = <f's unfolding> a b c --- (if f has an unfolding, EVEN if it's a loop breaker) --- --- It's important to allow the argument to 'inline' to have args itself --- (a) because its more forgiving to allow the programmer to write --- inline f a b c --- or inline (f a b c) --- (b) because a polymorphic f wll get a type argument that the --- programmer can't avoid --- --- Also, don't forget about 'inline's type argument! +{- Note [inlineId magic] +~~~~~~~~~~~~~~~~~~~~~~~~ +The call 'inline f' arranges that 'f' is inlined, regardless of +its size. More precisely, the call 'inline f' rewrites to the +right-hand side of 'f's definition. This allows the programmer to +control inlining from a particular call site rather than the +definition site of the function. + +The moving parts are simple: + +* A very simple definition in the library base:GHC.Magic + {-# NOINLINE[0] inline #-} + inline :: a -> a + inline x = x + So in phase 0, 'inline' will be inlined, so its use imposes + no overhead. + +* A rewrite rule, in GHC.Core.Opt.ConstantFold, which makes + (inline f) inline, implemented by match_inline. + The rule for the 'inline' function is this: + inline f_ty (f a b c) = <f's unfolding> a b c + (if f has an unfolding, EVEN if it's a loop breaker) + + It's important to allow the argument to 'inline' to have args itself + (a) because its more forgiving to allow the programmer to write + either inline f a b c + or inline (f a b c) + (b) because a polymorphic f wll get a type argument that the + programmer can't avoid, so the call may look like + inline (map @Int @Bool) g xs + + Also, don't forget about 'inline's type argument! +-} + match_inline :: [Expr CoreBndr] -> Maybe (Expr CoreBndr) match_inline (Type _ : e : _) | (Var f, args1) <- collectArgs e, @@ -1540,7 +1562,7 @@ match_inline (Type _ : e : _) match_inline _ = Nothing - +--------------------------------------------------- -- See Note [magicDictId magic] in "GHC.Types.Id.Make" -- for a description of what is going on here. match_magicDict :: [Expr CoreBndr] -> Maybe (Expr CoreBndr) |