summaryrefslogtreecommitdiff
path: root/compiler/simplCore/CoreMonad.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/simplCore/CoreMonad.hs')
-rw-r--r--compiler/simplCore/CoreMonad.hs147
1 files changed, 89 insertions, 58 deletions
diff --git a/compiler/simplCore/CoreMonad.hs b/compiler/simplCore/CoreMonad.hs
index c689eea346..0c5d8d9fd2 100644
--- a/compiler/simplCore/CoreMonad.hs
+++ b/compiler/simplCore/CoreMonad.hs
@@ -9,12 +9,12 @@
module CoreMonad (
-- * Configuration of the core-to-core passes
CoreToDo(..), runWhen, runMaybe,
- SimplifierMode(..),
+ SimplMode(..),
FloatOutSwitches(..),
pprPassDetails,
-- * Plugins
- PluginPass, bindsOnlyPass,
+ CorePluginPass, bindsOnlyPass,
-- * Counting
SimplCount, doSimplTick, doFreeSimplTick, simplCountN,
@@ -47,14 +47,11 @@ module CoreMonad (
putMsg, putMsgS, errorMsg, errorMsgS, warnMsg,
fatalErrorMsg, fatalErrorMsgS,
debugTraceMsg, debugTraceMsgS,
- dumpIfSet_dyn,
-
- -- * Getting 'Name's
- thNameToGhcName
+ dumpIfSet_dyn
) where
-import Name( Name )
-import TcRnMonad ( initTcForLookup )
+import GhcPrelude hiding ( read )
+
import CoreSyn
import HscTypes
import Module
@@ -64,13 +61,11 @@ import Annotations
import IOEnv hiding ( liftIO, failM, failWithM )
import qualified IOEnv ( liftIO )
-import TcEnv ( lookupGlobal )
import Var
import Outputable
import FastString
import qualified ErrUtils as Err
import ErrUtils( Severity(..) )
-import Maybes
import UniqSupply
import UniqFM ( UniqFM, mapUFM, filterUFM )
import MonadUtils
@@ -87,11 +82,6 @@ import Data.Word
import Control.Monad
import Control.Applicative ( Alternative(..) )
-import Prelude hiding ( read )
-
-import {-# SOURCE #-} TcSplice ( lookupThName_maybe )
-import qualified Language.Haskell.TH as TH
-
{-
************************************************************************
* *
@@ -107,14 +97,15 @@ data CoreToDo -- These are diff core-to-core passes,
= CoreDoSimplify -- The core-to-core simplifier.
Int -- Max iterations
- SimplifierMode
- | CoreDoPluginPass String PluginPass
+ SimplMode
+ | CoreDoPluginPass String CorePluginPass
| CoreDoFloatInwards
| CoreDoFloatOutwards FloatOutSwitches
| CoreLiberateCase
| CoreDoPrintCore
| CoreDoStaticArgs
| CoreDoCallArity
+ | CoreDoExitify
| CoreDoStrictness
| CoreDoWorkerWrapper
| CoreDoSpecialising
@@ -122,7 +113,6 @@ data CoreToDo -- These are diff core-to-core passes,
| CoreCSE
| CoreDoRuleCheck CompilerPhase String -- Check for non-application of rules
-- matching this string
- | CoreDoVectorisation
| CoreDoNothing -- Useful when building up
| CoreDoPasses [CoreToDo] -- lists of these things
@@ -142,12 +132,12 @@ instance Outputable CoreToDo where
ppr CoreLiberateCase = text "Liberate case"
ppr CoreDoStaticArgs = text "Static argument"
ppr CoreDoCallArity = text "Called arity analysis"
+ ppr CoreDoExitify = text "Exitification transformation"
ppr CoreDoStrictness = text "Demand analysis"
ppr CoreDoWorkerWrapper = text "Worker Wrapper binds"
ppr CoreDoSpecialising = text "Specialise"
ppr CoreDoSpecConstr = text "SpecConstr"
ppr CoreCSE = text "Common sub-expression"
- ppr CoreDoVectorisation = text "Vectorisation"
ppr CoreDesugar = text "Desugar (before optimization)"
ppr CoreDesugarOpt = text "Desugar (after optimization)"
ppr CoreTidy = text "Tidy Core"
@@ -163,17 +153,19 @@ pprPassDetails (CoreDoSimplify n md) = vcat [ text "Max iterations =" <+> int n
, ppr md ]
pprPassDetails _ = Outputable.empty
-data SimplifierMode -- See comments in SimplMonad
+data SimplMode -- See comments in SimplMonad
= SimplMode
{ sm_names :: [String] -- Name(s) of the phase
, sm_phase :: CompilerPhase
+ , sm_dflags :: DynFlags -- Just for convenient non-monadic
+ -- access; we don't override these
, sm_rules :: Bool -- Whether RULES are enabled
, sm_inline :: Bool -- Whether inlining is enabled
, sm_case_case :: Bool -- Whether case-of-case is enabled
, sm_eta_expand :: Bool -- Whether eta-expansion is enabled
}
-instance Outputable SimplifierMode where
+instance Outputable SimplMode where
ppr (SimplMode { sm_phase = p, sm_names = ss
, sm_rules = r, sm_inline = i
, sm_eta_expand = eta, sm_case_case = cc })
@@ -235,7 +227,7 @@ runMaybe Nothing _ = CoreDoNothing
-}
-- | A description of the plugin pass itself
-type PluginPass = ModGuts -> CoreM ModGuts
+type CorePluginPass = ModGuts -> CoreM ModGuts
bindsOnlyPass :: (CoreProgram -> CoreM CoreProgram) -> ModGuts -> CoreM ModGuts
bindsOnlyPass pass guts
@@ -251,7 +243,7 @@ bindsOnlyPass pass guts
-}
getVerboseSimplStats :: (Bool -> SDoc) -> SDoc
-getVerboseSimplStats = sdocWithPprDebug -- For now, anyway
+getVerboseSimplStats = getPprDebug -- For now, anyway
zeroSimplCount :: DynFlags -> SimplCount
isZeroSimplCount :: SimplCount -> Bool
@@ -341,6 +333,79 @@ pprSimplCount (SimplCount { ticks = tks, details = dts, log1 = l1, log2 = l2 })
else Outputable.empty
]
+{- Note [Which transformations are innocuous]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+At one point (Jun 18) I wondered if some transformations (ticks)
+might be "innocuous", in the sense that they do not unlock a later
+transformation that does not occur in the same pass. If so, we could
+refrain from bumping the overall tick-count for such innocuous
+transformations, and perhaps terminate the simplifier one pass
+earlier.
+
+BUt alas I found that virtually nothing was innocuous! This Note
+just records what I learned, in case anyone wants to try again.
+
+These transformations are not innocuous:
+
+*** NB: I think these ones could be made innocuous
+ EtaExpansion
+ LetFloatFromLet
+
+LetFloatFromLet
+ x = K (let z = e2 in Just z)
+ prepareRhs transforms to
+ x2 = let z=e2 in Just z
+ x = K xs
+ And now more let-floating can happen in the
+ next pass, on x2
+
+PreInlineUnconditionally
+ Example in spectral/cichelli/Auxil
+ hinsert = ...let lo = e in
+ let j = ...lo... in
+ case x of
+ False -> ()
+ True -> case lo of I# lo' ->
+ ...j...
+ When we PreInlineUnconditionally j, lo's occ-info changes to once,
+ so it can be PreInlineUnconditionally in the next pass, and a
+ cascade of further things can happen.
+
+PostInlineUnconditionally
+ let x = e in
+ let y = ...x.. in
+ case .. of { A -> ...x...y...
+ B -> ...x...y... }
+ Current postinlineUnconditinaly will inline y, and then x; sigh.
+
+ But PostInlineUnconditionally might also unlock subsequent
+ transformations for the same reason as PreInlineUnconditionally,
+ so it's probably not innocuous anyway.
+
+KnownBranch, BetaReduction:
+ May drop chunks of code, and thereby enable PreInlineUnconditionally
+ for some let-binding which now occurs once
+
+EtaExpansion:
+ Example in imaginary/digits-of-e1
+ fail = \void. e where e :: IO ()
+ --> etaExpandRhs
+ fail = \void. (\s. (e |> g) s) |> sym g where g :: IO () ~ S -> (S,())
+ --> Next iteration of simplify
+ fail1 = \void. \s. (e |> g) s
+ fail = fail1 |> Void#->sym g
+ And now inline 'fail'
+
+CaseMerge:
+ case x of y {
+ DEFAULT -> case y of z { pi -> ei }
+ alts2 }
+ ---> CaseMerge
+ case x of { pi -> let z = y in ei
+ ; alts2 }
+ The "let z=y" case-binder-swap gets dealt with in the next pass
+-}
+
pprTickCounts :: Map Tick Int -> SDoc
pprTickCounts counts
= vcat (map pprTickGroup groups)
@@ -358,7 +423,7 @@ pprTickGroup group@((tick1,_):_)
| (tick,n) <- sortBy (flip (comparing snd)) group])
pprTickGroup [] = panic "pprTickGroup"
-data Tick
+data Tick -- See Note [Which transformations are innocuous]
= PreInlineUnconditionally Id
| PostInlineUnconditionally Id
@@ -379,7 +444,6 @@ data Tick
| CaseIdentity Id -- Case binder
| FillInCaseDefault Id -- Case binder
- | BottomFound
| SimplifierDone -- Ticked at each iteration of the simplifier
instance Outputable Tick where
@@ -408,7 +472,6 @@ tickToTag (CaseMerge _) = 10
tickToTag (CaseElim _) = 11
tickToTag (CaseIdentity _) = 12
tickToTag (FillInCaseDefault _) = 13
-tickToTag BottomFound = 14
tickToTag SimplifierDone = 16
tickToTag (AltMerge _) = 17
@@ -428,7 +491,6 @@ tickString (AltMerge _) = "AltMerge"
tickString (CaseElim _) = "CaseElim"
tickString (CaseIdentity _) = "CaseIdentity"
tickString (FillInCaseDefault _) = "FillInCaseDefault"
-tickString BottomFound = "BottomFound"
tickString SimplifierDone = "SimplifierDone"
pprTickCts :: Tick -> SDoc
@@ -780,34 +842,3 @@ dumpIfSet_dyn flag str doc
; unqual <- getPrintUnqualified
; when (dopt flag dflags) $ liftIO $
Err.dumpSDoc dflags unqual flag str doc }
-
-{-
-************************************************************************
-* *
- Finding TyThings
-* *
-************************************************************************
--}
-
-instance MonadThings CoreM where
- lookupThing name = do { hsc_env <- getHscEnv
- ; liftIO $ lookupGlobal hsc_env name }
-
-{-
-************************************************************************
-* *
- Template Haskell interoperability
-* *
-************************************************************************
--}
-
--- | Attempt to convert a Template Haskell name to one that GHC can
--- understand. Original TH names such as those you get when you use
--- the @'foo@ syntax will be translated to their equivalent GHC name
--- exactly. Qualified or unqualified TH names will be dynamically bound
--- to names in the module being compiled, if possible. Exact TH names
--- will be bound to the name they represent, exactly.
-thNameToGhcName :: TH.Name -> CoreM (Maybe Name)
-thNameToGhcName th_name = do
- hsc_env <- getHscEnv
- liftIO $ initTcForLookup hsc_env (lookupThName_maybe th_name)