summaryrefslogtreecommitdiff
path: root/compiler/GHC/Stg/Pipeline.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Stg/Pipeline.hs')
-rw-r--r--compiler/GHC/Stg/Pipeline.hs27
1 files changed, 20 insertions, 7 deletions
diff --git a/compiler/GHC/Stg/Pipeline.hs b/compiler/GHC/Stg/Pipeline.hs
index b0e1848f19..40ac929c42 100644
--- a/compiler/GHC/Stg/Pipeline.hs
+++ b/compiler/GHC/Stg/Pipeline.hs
@@ -33,6 +33,10 @@ import GHC.Utils.Logger
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Trans.Reader
+import GHC.Utils.Trace
+import GHC.Linker.Types
+import Data.IORef
+import GHC.LanguageExtensions
newtype StgM a = StgM { _unStgM :: ReaderT Char IO a }
deriving (Functor, Applicative, Monad, MonadIO)
@@ -52,13 +56,14 @@ stg2stg :: Logger
-> Bool -- prepare for bytecode?
-> Module -- module being compiled
-> [StgTopBinding] -- input program
- -> IO [StgTopBinding] -- output program
+ -> IO ([StgTopBinding], [SptEntry]) -- output program
stg2stg logger dflags ictxt for_bytecode this_mod binds
= do { dump_when Opt_D_dump_stg_from_core "Initial STG:" binds
; showPass logger "Stg2Stg"
+ ; spt_entries_var <- newIORef []
-- Do the main business!
; binds' <- runStgM 'g' $
- foldM do_stg_pass binds (getStgToDo for_bytecode dflags)
+ foldM (do_stg_pass spt_entries_var) binds (getStgToDo for_bytecode dflags)
-- Dependency sort the program as last thing. The program needs to be
-- in dependency order for the SRT algorithm to work (see
@@ -69,7 +74,8 @@ stg2stg logger dflags ictxt for_bytecode this_mod binds
-- preserve the order or only create minimal recursive groups, so a
-- sorting pass is necessary.
; let binds_sorted = depSortStgPgm this_mod binds'
- ; return binds_sorted
+ ; spt_entries <- readIORef spt_entries_var
+ ; return (binds_sorted, spt_entries)
}
where
@@ -80,8 +86,8 @@ stg2stg logger dflags ictxt for_bytecode this_mod binds
= \ _whodunnit _binds -> return ()
-------------------------------------------
- do_stg_pass :: [StgTopBinding] -> StgToDo -> StgM [StgTopBinding]
- do_stg_pass binds to_do
+ do_stg_pass :: IORef [SptEntry] -> [StgTopBinding] -> StgToDo -> StgM [StgTopBinding]
+ do_stg_pass spt_result binds to_do
= case to_do of
StgDoNothing ->
return binds
@@ -94,8 +100,11 @@ stg2stg logger dflags ictxt for_bytecode this_mod binds
end_pass "StgCse" binds'
StgLiftLams -> do
+ pprTraceM "running lift" empty
us <- getUniqueSupplyM
- let binds' = {-# SCC "StgLiftLams" #-} stgLiftLams dflags us binds
+ let (binds', spt_entries) = {-# SCC "StgLiftLams" #-} stgLiftLams this_mod dflags us binds
+ pprTraceM "spt_entries" (ppr spt_entries)
+ liftIO $ writeIORef spt_result spt_entries
end_pass "StgLiftLams" binds'
StgBcPrep -> do
@@ -149,11 +158,15 @@ getStgToDo for_bytecode dflags =
-- Important that unarisation comes first
-- See Note [StgCse after unarisation] in GHC.Stg.CSE
, optional Opt_StgCSE StgCSE
- , optional Opt_StgLiftLams StgLiftLams
+ , runWhen run_lift StgLiftLams
, runWhen for_bytecode StgBcPrep
, optional Opt_StgStats StgStats
] where
optional opt = runWhen (gopt opt dflags)
+ -- The LiftLams pass lifts static forms to the top-level, this is necessary
+ -- for correctness so the pass is always run when StaticPointers is enabled.
+ -- See [Grand plan for static forms]
+ run_lift = gopt Opt_StgLiftLams dflags || xopt StaticPointers dflags
mandatory = id
runWhen :: Bool -> StgToDo -> StgToDo