summaryrefslogtreecommitdiff
path: root/compiler/cmm
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/cmm')
-rw-r--r--compiler/cmm/CmmBuildInfoTables.hs18
-rw-r--r--compiler/cmm/CmmCPSZ.hs25
-rw-r--r--compiler/cmm/CmmSpillReload.hs2
-rw-r--r--compiler/cmm/CmmTx.hs1
-rw-r--r--compiler/cmm/DFMonad.hs14
-rw-r--r--compiler/cmm/ZipCfgCmmRep.hs3
-rw-r--r--compiler/cmm/ZipDataflow.hs103
7 files changed, 84 insertions, 82 deletions
diff --git a/compiler/cmm/CmmBuildInfoTables.hs b/compiler/cmm/CmmBuildInfoTables.hs
index fa2c009740..bf5ef8eb1a 100644
--- a/compiler/cmm/CmmBuildInfoTables.hs
+++ b/compiler/cmm/CmmBuildInfoTables.hs
@@ -165,15 +165,15 @@ cafLattice = DataflowLattice "live cafs" emptyFM add False
cafTransfers :: BackwardTransfers Middle Last CAFSet
cafTransfers = BackwardTransfers first middle last
- where first _ live = live
- middle m live = foldExpDeepMiddle addCaf m live
- last l env = foldExpDeepLast addCaf l (joinOuts cafLattice env l)
- addCaf e set = case e of
- CmmLit (CmmLabel c) -> add c set
- CmmLit (CmmLabelOff c _) -> add c set
- CmmLit (CmmLabelDiffOff c1 c2 _) -> add c1 $ add c2 set
- _ -> set
- add l s = if hasCAF l then addToFM s (cvtToClosureLbl l) () else s
+ where first _ live = live
+ middle m live = foldExpDeepMiddle addCaf m live
+ last l env = foldExpDeepLast addCaf l (joinOuts cafLattice env l)
+ addCaf e set = case e of
+ CmmLit (CmmLabel c) -> add c set
+ CmmLit (CmmLabelOff c _) -> add c set
+ CmmLit (CmmLabelDiffOff c1 c2 _) -> add c1 $ add c2 set
+ _ -> set
+ add l s = if hasCAF l then addToFM s (cvtToClosureLbl l) () else s
type CafFix a = FuelMonad (BackwardFixedPoint Middle Last CAFSet a)
cafAnal :: LGraph Middle Last -> FuelMonad CAFEnv
diff --git a/compiler/cmm/CmmCPSZ.hs b/compiler/cmm/CmmCPSZ.hs
index db72c64216..5f3775b26f 100644
--- a/compiler/cmm/CmmCPSZ.hs
+++ b/compiler/cmm/CmmCPSZ.hs
@@ -85,23 +85,34 @@ cpsTop hsc_env (CmmProc h l args (stackInfo@(entry_off, _), g)) =
g <- return $ elimCommonBlocks g
dump Opt_D_dump_cmmz "Post common block elimination" g
procPoints <- run $ minimalProcPointSet callPPs g
- -- print $ "call procPoints: " ++ (showSDoc $ ppr procPoints)
g <- run $ addProcPointProtocols callPPs procPoints g
dump Opt_D_dump_cmmz "Post Proc Points Added" g
- g <- dual_rewrite Opt_D_dump_cmmz "spills and reloads"
+ g <-
+ -- pprTrace "pre Spills" (ppr g) $
+ dual_rewrite Opt_D_dump_cmmz "spills and reloads"
(dualLivenessWithInsertion procPoints) g
-- Insert spills at defns; reloads at return points
- g <- run $ insertLateReloads g -- Duplicate reloads just before uses
+ g <-
+ -- pprTrace "pre insertLateReloads" (ppr g) $
+ run $ insertLateReloads g -- Duplicate reloads just before uses
dump Opt_D_dump_cmmz "Post late reloads" g
- g <- dual_rewrite Opt_D_dump_cmmz "Dead Assignment Elimination"
+ g <-
+ -- pprTrace "post insertLateReloads" (ppr g) $
+ dual_rewrite Opt_D_dump_cmmz "Dead Assignment Elimination"
(removeDeadAssignmentsAndReloads procPoints) g
-- Remove redundant reloads (and any other redundant asst)
-- Debugging: stubbing slots on death can cause crashes early
- g <- if opt_StubDeadValues then run $ stubSlotsOnDeath g else return g
+ g <-
+ -- trace "post dead-assign elim" $
+ if opt_StubDeadValues then run $ stubSlotsOnDeath g else return g
slotEnv <- run $ liveSlotAnal g
mbpprTrace "live slot analysis results: " (ppr slotEnv) $ return ()
- cafEnv <- run $ cafAnal g
- (cafEnv, slotEnv) <- return $ extendEnvsForSafeForeignCalls cafEnv slotEnv g
+ cafEnv <-
+ -- trace "post liveSlotAnal" $
+ run $ cafAnal g
+ (cafEnv, slotEnv) <-
+ -- trace "post print cafAnal" $
+ return $ extendEnvsForSafeForeignCalls cafEnv slotEnv g
mbpprTrace "slotEnv extended for safe foreign calls: " (ppr slotEnv) $ return ()
let areaMap = layout procPoints slotEnv entry_off g
mbpprTrace "areaMap" (ppr areaMap) $ return ()
diff --git a/compiler/cmm/CmmSpillReload.hs b/compiler/cmm/CmmSpillReload.hs
index 085dc377db..fb6931e006 100644
--- a/compiler/cmm/CmmSpillReload.hs
+++ b/compiler/cmm/CmmSpillReload.hs
@@ -66,7 +66,7 @@ changeRegs f live = live { in_regs = f (in_regs live) }
dualLiveLattice :: DataflowLattice DualLive
dualLiveLattice =
- DataflowLattice "variables live in registers and on stack" empty add False
+ DataflowLattice "variables live in registers and on stack" empty add True
where empty = DualLive emptyRegSet emptyRegSet
-- | compute in the Tx monad to track whether anything has changed
add new old = do stack <- add1 (on_stack new) (on_stack old)
diff --git a/compiler/cmm/CmmTx.hs b/compiler/cmm/CmmTx.hs
index d9733b8593..af9b7f1adf 100644
--- a/compiler/cmm/CmmTx.hs
+++ b/compiler/cmm/CmmTx.hs
@@ -1,4 +1,3 @@
-
module CmmTx where
data ChangeFlag = NoChange | SomeChange
diff --git a/compiler/cmm/DFMonad.hs b/compiler/cmm/DFMonad.hs
index 4db3b966af..0cf1ead0fc 100644
--- a/compiler/cmm/DFMonad.hs
+++ b/compiler/cmm/DFMonad.hs
@@ -59,14 +59,14 @@ data DataflowLattice a = DataflowLattice {
-- case of DFM, parameterized over any monad.
-- In practice, we apply DFM' to the FuelMonad, which provides optimization fuel and
-- the unique supply.
-data DFState f = DFState { df_rewritten :: ChangeFlag
- , df_facts :: BlockEnv f
- , df_exit_fact :: f
- , df_last_outs :: [(BlockId, f)]
- , df_facts_change :: ChangeFlag
+data DFState f = DFState { df_rewritten :: !ChangeFlag
+ , df_facts :: !(BlockEnv f)
+ , df_exit_fact :: !f
+ , df_last_outs :: ![(BlockId, f)]
+ , df_facts_change :: !ChangeFlag
}
-newtype DFM' m fact a = DFM' (DataflowLattice fact -> DFState fact
+newtype DFM' m fact a = DFM' (DataflowLattice fact -> DFState fact
-> m (a, DFState fact))
type DFM fact a = DFM' FuelMonad fact a
@@ -190,7 +190,7 @@ graphWasRewritten = DFM' f
instance Monad m => Monad (DFM' m f) where
DFM' f >>= k = DFM' (\l s -> do (a, s') <- f l s
- let DFM' f' = k a in f' l s')
+ s' `seq` case k a of DFM' f' -> f' l s')
return a = DFM' (\_ s -> return (a, s))
instance FuelUsingMonad (DFM' FuelMonad f) where
diff --git a/compiler/cmm/ZipCfgCmmRep.hs b/compiler/cmm/ZipCfgCmmRep.hs
index 348ab5bf2b..a64a81d548 100644
--- a/compiler/cmm/ZipCfgCmmRep.hs
+++ b/compiler/cmm/ZipCfgCmmRep.hs
@@ -456,7 +456,8 @@ pprMiddle stmt = pp_stmt <+> pp_debug
MidForeignCall {} -> text "MidForeignCall"
ppr_fc :: ForeignConvention -> SDoc
-ppr_fc (ForeignConvention c _ _) = doubleQuotes (ppr c)
+ppr_fc (ForeignConvention c args res) =
+ doubleQuotes (ppr c) <+> text "args: " <+> ppr args <+> text " results: " <+> ppr res
ppr_safety :: ForeignSafety -> SDoc
ppr_safety (Safe bid upd) = text "safe<" <> ppr bid <> text ", " <> ppr upd <> text ">"
diff --git a/compiler/cmm/ZipDataflow.hs b/compiler/cmm/ZipDataflow.hs
index e8fefbfd0d..39a4798ee4 100644
--- a/compiler/cmm/ZipDataflow.hs
+++ b/compiler/cmm/ZipDataflow.hs
@@ -513,55 +513,46 @@ forward_sol check_maybe = forw
set_or_save = mk_set_or_save (isJust . lookupBlockEnv blockenv)
set_successor_facts (Block id tail) fuel =
do { idfact <- getFact id
- ; (last_outs, fuel) <-
- case check_maybe fuel $ fr_first rewrites id idfact of
- Nothing -> solve_tail (ft_first_out transfers id idfact) tail fuel
- Just g ->
- do g <- areturn g
- (a, fuel) <- subAnalysis' $
- case rewrite of
- RewriteDeep -> solve getExitFact idfact g (oneLessFuel fuel)
- RewriteShallow ->
- do { a <- anal_f getExitFact idfact g
- ; return (a, oneLessFuel fuel) }
- solve_tail a tail fuel
+ ; (last_outs, fuel) <- rec_rewrite (fr_first rewrites id idfact)
+ (ft_first_out transfers id idfact)
+ getExitFact (solve_tail tail)
+ (solve_tail tail) idfact fuel
; set_or_save last_outs
; return fuel }
-
- in do { (last_outs, fuel) <- solve_tail in_fact entry fuel
- ; set_or_save last_outs
+ in do { (last_outs, fuel) <- solve_tail entry in_fact fuel
+ -- last_outs contains a mix of internal facts, which
+ -- are inputs to 'run', and external facts, which
+ -- are going to be forgotten by 'run'
+ ; set_or_save last_outs
; fuel <- run "forward" name set_successor_facts blocks fuel
- ; b <- finish
+ ; set_or_save last_outs
+ -- Re-set facts that may have been forgotten by run
+ ; b <- finish
; return (b, fuel)
}
-
- solve_tail in' (G.ZTail m t) fuel =
- case check_maybe fuel $ fr_middle rewrites m in' of
- Nothing -> solve_tail (ft_middle_out transfers m in') t fuel
- Just g ->
- do { g <- areturn g
- ; (a, fuel) <- subAnalysis' $
- case rewrite of
- RewriteDeep -> solve getExitFact in' g (oneLessFuel fuel)
- RewriteShallow -> do { a <- anal_f getExitFact in' g
- ; return (a, oneLessFuel fuel) }
- ; solve_tail a t fuel
- }
- solve_tail in' (G.ZLast l) fuel =
- case check_maybe fuel $ either_last rewrites in' l of
- Nothing ->
- case l of LastOther l -> return (ft_last_outs transfers l in', fuel)
- LastExit -> do { setExitFact (ft_exit_out transfers in')
- ; return (LastOutFacts [], fuel) }
- Just g ->
- do { g <- areturn g
- ; (last_outs :: LastOutFacts a, fuel) <- subAnalysis' $
- case rewrite of
- RewriteDeep -> solve lastOutFacts in' g (oneLessFuel fuel)
- RewriteShallow -> do { los <- anal_f lastOutFacts in' g
- ; return (los, fuel) }
- ; return (last_outs, fuel)
- }
+ -- The need for both k1 and k2 suggests that maybe there's an opportunity
+ -- for improvement here -- in most cases, they're the same...
+ rec_rewrite rewritten analyzed finish k1 k2 in' fuel =
+ case check_maybe fuel rewritten of -- fr_first rewrites id idfact of
+ Nothing -> k1 analyzed fuel
+ Just g -> do g <- areturn g
+ (a, fuel) <- subAnalysis' $
+ case rewrite of
+ RewriteDeep -> solve finish in' g (oneLessFuel fuel)
+ RewriteShallow -> do { a <- anal_f finish in' g
+ ; return (a, oneLessFuel fuel) }
+ k2 a fuel
+ solve_tail (G.ZTail m t) in' fuel =
+ rec_rewrite (fr_middle rewrites m in') (ft_middle_out transfers m in')
+ getExitFact (solve_tail t) (solve_tail t) in' fuel
+ solve_tail (G.ZLast (LastOther l)) in' fuel =
+ rec_rewrite (fr_last rewrites l in') (ft_last_outs transfers l in')
+ lastOutFacts k k in' fuel
+ where k a b = return (a, b)
+ solve_tail (G.ZLast LastExit) in' fuel =
+ rec_rewrite (fr_exit rewrites in') (ft_exit_out transfers in')
+ lastOutFacts k (\a b -> return (a, b)) in' fuel
+ where k a fuel = do { setExitFact a ; return (LastOutFacts [], fuel) }
fixed_point in_fact g fuel =
do { setAllFacts start_facts
@@ -572,10 +563,6 @@ forward_sol check_maybe = forw
; let fp = FFP cfp last_outs
; return (fp, fuel)
}
-
- either_last rewrites in' (LastExit) = fr_exit rewrites in'
- either_last rewrites in' (LastOther l) = fr_last rewrites l in'
-
in fixed_point
@@ -585,7 +572,7 @@ mk_set_or_save :: (DataflowAnalysis df, Monad (df a), Outputable a) =>
(BlockId -> Bool) -> LastOutFacts a -> df a ()
mk_set_or_save is_local (LastOutFacts l) = mapM_ set_or_save_one l
where set_or_save_one (id, a) =
- if is_local id then setFact id a else addLastOutFact (id, a)
+ if is_local id then setFact id a else pprTrace "addLastOutFact" (ppr $ length l) $ addLastOutFact (id, a)
@@ -619,6 +606,7 @@ forward_rew check_maybe = forw
-> a -> Graph m l -> Fuel
-> DFM a (b, Graph m l, Fuel)
rewrite start finish in_fact g fuel =
+ in_fact `seq` g `seq`
let Graph entry blockenv = g
blocks = G.postorder_dfs_from blockenv entry
in do { solve depth name start transfers rewrites in_fact g fuel
@@ -647,6 +635,7 @@ forward_rew check_maybe = forw
; let fp = FFP cfp last_outs
; return (fp, fuel)
}
+-- JD: WHY AREN'T WE TAKING ANY FUEL HERE?
rewrite_blocks :: [Block m l] -> (BlockEnv (Block m l))
-> Fuel -> DFM a (BlockEnv (Block m l), Fuel)
rewrite_blocks [] rewritten fuel = return (rewritten, fuel)
@@ -667,10 +656,11 @@ forward_rew check_maybe = forw
; rewrite_blocks bs rewritten fuel }
rew_tail head in' (G.ZTail m t) rewritten fuel =
+ in' `seq` rewritten `seq`
my_trace "Rewriting middle node" (ppr m) $
case check_maybe fuel $ fr_middle rewrites m in' of
Nothing -> rew_tail (G.ZHead head m) (ft_middle_out transfers m in') t
- rewritten fuel
+ rewritten fuel
Just g -> do { markGraphRewritten
; g <- areturn g
; (a, g, fuel) <- inner_rew getExitFact in' g fuel
@@ -678,13 +668,15 @@ forward_rew check_maybe = forw
; rew_tail h a t (blocks `plusBlockEnv` rewritten) fuel
}
rew_tail h in' (G.ZLast l) rewritten fuel =
+ in' `seq` rewritten `seq`
my_trace "Rewriting last node" (ppr l) $
case check_maybe fuel $ either_last rewrites in' l of
Nothing -> do check_facts in' l
return (insertBlock (zipht h (G.ZLast l)) rewritten, fuel)
- Just g -> do { markGraphRewritten
+ Just g -> do { markGraphRewritten
; g <- areturn g
- ; ((), g, fuel) <- inner_rew (return ()) in' g fuel
+ ; ((), g, fuel) <-
+ my_trace "Just" (ppr g) $ inner_rew (return ()) in' g fuel
; let g' = G.splice_head_only' h g
; return (G.lg_blocks g' `plusBlockEnv` rewritten, fuel)
}
@@ -1010,10 +1002,9 @@ run dir name do_block blocks b =
do_block block b
return (b', cnt + 1)
iterate n =
- do { markFactsUnchanged
- ; (b, _) <-
- my_trace "block count:" (ppr (length blocks)) $
- foldM trace_block (b, 0 :: Int) blocks
+ do { forgetLastOutFacts
+ ; markFactsUnchanged
+ ; (b, _) <- foldM trace_block (b, 0 :: Int) blocks
; changed <- factsStatus
; facts <- getAllFacts
; let depth = 0 -- was nesting depth