summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/cmm/CmmUtils.hs40
-rw-r--r--compiler/cmm/Hoopl.hs106
-rw-r--r--compiler/cmm/Hoopl/Dataflow.hs530
3 files changed, 11 insertions, 665 deletions
diff --git a/compiler/cmm/CmmUtils.hs b/compiler/cmm/CmmUtils.hs
index b82f780c08..bce02fa948 100644
--- a/compiler/cmm/CmmUtils.hs
+++ b/compiler/cmm/CmmUtils.hs
@@ -58,8 +58,8 @@ module CmmUtils(
toBlockListEntryFirst, toBlockListEntryFirstFalseFallthrough,
foldGraphBlocks, mapGraphNodes, postorderDfs, mapGraphNodes1,
- analFwd, analBwd, analRewFwd, analRewBwd,
- dataflowPassFwd, dataflowPassBwd, dataflowAnalFwd, dataflowAnalBwd,
+ analFwd, analBwd,
+ dataflowAnalFwd, dataflowAnalBwd,
dataflowAnalFwdBlocks,
-- * Ticks
@@ -565,30 +565,10 @@ postorderDfs g = {-# SCC "postorderDfs" #-} postorder_dfs_from (toBlockMap g) (g
analFwd :: DataflowLattice f -> FwdTransfer n f -> FwdPass UniqSM n f
analBwd :: DataflowLattice f -> BwdTransfer n f -> BwdPass UniqSM n f
-analFwd lat xfer = analRewFwd lat xfer noFwdRewrite
-analBwd lat xfer = analRewBwd lat xfer noBwdRewrite
-
--- Constructing forward and backward analysis + rewrite pass
-analRewFwd :: DataflowLattice f -> FwdTransfer n f
- -> FwdRewrite UniqSM n f
- -> FwdPass UniqSM n f
-
-analRewBwd :: DataflowLattice f
- -> BwdTransfer n f
- -> BwdRewrite UniqSM n f
- -> BwdPass UniqSM n f
-
-analRewFwd lat xfer rew = FwdPass {fp_lattice = lat, fp_transfer = xfer, fp_rewrite = rew}
-analRewBwd lat xfer rew = BwdPass {bp_lattice = lat, bp_transfer = xfer, bp_rewrite = rew}
-
--- Running forward and backward dataflow analysis + optional rewrite
-dataflowPassFwd :: NonLocal n =>
- GenCmmGraph n -> [(BlockId, f)]
- -> FwdPass UniqSM n f
- -> UniqSM (GenCmmGraph n, BlockEnv f)
-dataflowPassFwd (CmmGraph {g_entry=entry, g_graph=graph}) facts fwd = do
- (graph, facts, NothingO) <- analyzeAndRewriteFwd fwd (JustC [entry]) graph (mkFactBase (fp_lattice fwd) facts)
- return (CmmGraph {g_entry=entry, g_graph=graph}, facts)
+analFwd lat xfer =
+ FwdPass {fp_lattice = lat, fp_transfer = xfer, fp_rewrite = noFwdRewrite}
+analBwd lat xfer =
+ BwdPass {bp_lattice = lat, bp_transfer = xfer, bp_rewrite = noBwdRewrite}
dataflowAnalFwd :: NonLocal n =>
GenCmmGraph n -> [(BlockId, f)]
@@ -613,14 +593,6 @@ dataflowAnalBwd :: NonLocal n =>
dataflowAnalBwd (CmmGraph {g_entry=entry, g_graph=graph}) facts bwd =
analyzeBwd bwd (JustC [entry]) graph (mkFactBase (bp_lattice bwd) facts)
-dataflowPassBwd :: NonLocal n =>
- GenCmmGraph n -> [(BlockId, f)]
- -> BwdPass UniqSM n f
- -> UniqSM (GenCmmGraph n, BlockEnv f)
-dataflowPassBwd (CmmGraph {g_entry=entry, g_graph=graph}) facts bwd = do
- (graph, facts, NothingO) <- analyzeAndRewriteBwd bwd (JustC [entry]) graph (mkFactBase (bp_lattice bwd) facts)
- return (CmmGraph {g_entry=entry, g_graph=graph}, facts)
-
-------------------------------------------------
-- Tick utilities
diff --git a/compiler/cmm/Hoopl.hs b/compiler/cmm/Hoopl.hs
index 4b3717288f..b8acc5a3e6 100644
--- a/compiler/cmm/Hoopl.hs
+++ b/compiler/cmm/Hoopl.hs
@@ -3,9 +3,6 @@
module Hoopl (
module Compiler.Hoopl,
module Hoopl.Dataflow,
- deepFwdRw, deepFwdRw3,
- deepBwdRw, deepBwdRw3,
- thenFwdRw
) where
import Compiler.Hoopl hiding
@@ -23,109 +20,6 @@ import Compiler.Hoopl hiding
)
import Hoopl.Dataflow
-import Control.Monad
-import UniqSupply
-
-deepFwdRw3 :: (n C O -> f -> UniqSM (Maybe (Graph n C O)))
- -> (n O O -> f -> UniqSM (Maybe (Graph n O O)))
- -> (n O C -> f -> UniqSM (Maybe (Graph n O C)))
- -> (FwdRewrite UniqSM n f)
-deepFwdRw :: (forall e x . n e x -> f -> UniqSM (Maybe (Graph n e x))) -> FwdRewrite UniqSM n f
-deepFwdRw3 f m l = iterFwdRw $ mkFRewrite3 f m l
-deepFwdRw f = deepFwdRw3 f f f
-
--- N.B. rw3, rw3', and rw3a are triples of functions.
--- But rw and rw' are single functions.
-thenFwdRw :: forall n f.
- FwdRewrite UniqSM n f
- -> FwdRewrite UniqSM n f
- -> FwdRewrite UniqSM n f
-thenFwdRw rw3 rw3' = wrapFR2 thenrw rw3 rw3'
- where
- thenrw :: forall e x t t1.
- (t -> t1 -> UniqSM (Maybe (Graph n e x, FwdRewrite UniqSM n f)))
- -> (t -> t1 -> UniqSM (Maybe (Graph n e x, FwdRewrite UniqSM n f)))
- -> t
- -> t1
- -> UniqSM (Maybe (Graph n e x, FwdRewrite UniqSM n f))
- thenrw rw rw' n f = rw n f >>= fwdRes
- where fwdRes Nothing = rw' n f
- fwdRes (Just gr) = return $ Just $ fadd_rw rw3' gr
-
-iterFwdRw :: forall n f.
- FwdRewrite UniqSM n f
- -> FwdRewrite UniqSM n f
-iterFwdRw rw3 = wrapFR iter rw3
- where iter :: forall a e x t.
- (t -> a -> UniqSM (Maybe (Graph n e x, FwdRewrite UniqSM n f)))
- -> t
- -> a
- -> UniqSM (Maybe (Graph n e x, FwdRewrite UniqSM n f))
- iter rw n = (liftM $ liftM $ fadd_rw (iterFwdRw rw3)) . rw n
-
--- | Function inspired by 'rew' in the paper
-_frewrite_cps :: ((Graph n e x, FwdRewrite UniqSM n f) -> UniqSM a)
- -> UniqSM a
- -> (forall e x . n e x -> f -> UniqSM (Maybe (Graph n e x, FwdRewrite UniqSM n f)))
- -> n e x
- -> f
- -> UniqSM a
-_frewrite_cps j n rw node f =
- do mg <- rw node f
- case mg of Nothing -> n
- Just gr -> j gr
-
-
-
--- | Function inspired by 'add' in the paper
-fadd_rw :: FwdRewrite UniqSM n f
- -> (Graph n e x, FwdRewrite UniqSM n f)
- -> (Graph n e x, FwdRewrite UniqSM n f)
-fadd_rw rw2 (g, rw1) = (g, rw1 `thenFwdRw` rw2)
-
-
-
-deepBwdRw3 ::
- (n C O -> f -> UniqSM (Maybe (Graph n C O)))
- -> (n O O -> f -> UniqSM (Maybe (Graph n O O)))
- -> (n O C -> FactBase f -> UniqSM (Maybe (Graph n O C)))
- -> (BwdRewrite UniqSM n f)
-deepBwdRw :: (forall e x . n e x -> Fact x f -> UniqSM (Maybe (Graph n e x)))
- -> BwdRewrite UniqSM n f
-deepBwdRw3 f m l = iterBwdRw $ mkBRewrite3 f m l
-deepBwdRw f = deepBwdRw3 f f f
-
-
-thenBwdRw :: forall n f. BwdRewrite UniqSM n f -> BwdRewrite UniqSM n f -> BwdRewrite UniqSM n f
-thenBwdRw rw1 rw2 = wrapBR2 f rw1 rw2
- where f :: forall t t1 t2 e x.
- t
- -> (t1 -> t2 -> UniqSM (Maybe (Graph n e x, BwdRewrite UniqSM n f)))
- -> (t1 -> t2 -> UniqSM (Maybe (Graph n e x, BwdRewrite UniqSM n f)))
- -> t1
- -> t2
- -> UniqSM (Maybe (Graph n e x, BwdRewrite UniqSM n f))
- f _ rw1 rw2' n f = do
- res1 <- rw1 n f
- case res1 of
- Nothing -> rw2' n f
- Just gr -> return $ Just $ badd_rw rw2 gr
-
-iterBwdRw :: forall n f. BwdRewrite UniqSM n f -> BwdRewrite UniqSM n f
-iterBwdRw rw = wrapBR f rw
- where f :: forall t e x t1 t2.
- t
- -> (t1 -> t2 -> UniqSM (Maybe (Graph n e x, BwdRewrite UniqSM n f)))
- -> t1
- -> t2
- -> UniqSM (Maybe (Graph n e x, BwdRewrite UniqSM n f))
- f _ rw' n f = liftM (liftM (badd_rw (iterBwdRw rw))) (rw' n f)
-
--- | Function inspired by 'add' in the paper
-badd_rw :: BwdRewrite UniqSM n f
- -> (Graph n e x, BwdRewrite UniqSM n f)
- -> (Graph n e x, BwdRewrite UniqSM n f)
-badd_rw rw2 (g, rw1) = (g, rw1 `thenBwdRw` rw2)
-- Note [Deprecations in Hoopl]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/compiler/cmm/Hoopl/Dataflow.hs b/compiler/cmm/Hoopl/Dataflow.hs
index 1e3adf4726..a7475d2626 100644
--- a/compiler/cmm/Hoopl/Dataflow.hs
+++ b/compiler/cmm/Hoopl/Dataflow.hs
@@ -21,36 +21,20 @@ module Hoopl.Dataflow
( DataflowLattice(..), OldFact(..), NewFact(..), Fact, mkFactBase
, ChangeFlag(..)
, FwdPass(..), FwdTransfer, mkFTransfer, mkFTransfer3, getFTransfer3
- -- * Respecting Fuel
- -- $fuel
- , FwdRewrite, mkFRewrite, mkFRewrite3, getFRewrite3, noFwdRewrite
- , wrapFR, wrapFR2
, BwdPass(..), BwdTransfer, mkBTransfer, mkBTransfer3, getBTransfer3
- , wrapBR, wrapBR2
- , BwdRewrite, mkBRewrite, mkBRewrite3, getBRewrite3, noBwdRewrite
- , analyzeAndRewriteFwd, analyzeAndRewriteBwd
+
+ , noBwdRewrite, noFwdRewrite
+
, analyzeFwd, analyzeFwdBlocks, analyzeBwd
)
where
import UniqSupply
-import Data.Maybe
import Data.Array
-import Compiler.Hoopl hiding
- ( mkBRewrite3, mkFRewrite3, noFwdRewrite, noBwdRewrite
- , analyzeAndRewriteBwd, analyzeAndRewriteFwd
- )
-import Compiler.Hoopl.Internals
- ( wrapFR, wrapFR2
- , wrapBR, wrapBR2
- , splice
- )
-
-
--- -----------------------------------------------------------------------------
+import Compiler.Hoopl hiding (noFwdRewrite, noBwdRewrite)
noRewrite :: a -> b -> UniqSM (Maybe c)
noRewrite _ _ = return Nothing
@@ -58,173 +42,9 @@ noRewrite _ _ = return Nothing
noFwdRewrite :: FwdRewrite UniqSM n f
noFwdRewrite = FwdRewrite3 (noRewrite, noRewrite, noRewrite)
--- | Functions passed to 'mkFRewrite3' should not be aware of the fuel supply.
--- The result returned by 'mkFRewrite3' respects fuel.
-mkFRewrite3 :: forall n f.
- (n C O -> f -> UniqSM (Maybe (Graph n C O)))
- -> (n O O -> f -> UniqSM (Maybe (Graph n O O)))
- -> (n O C -> f -> UniqSM (Maybe (Graph n O C)))
- -> FwdRewrite UniqSM n f
-mkFRewrite3 f m l = FwdRewrite3 (lift f, lift m, lift l)
- where lift :: forall t t1 a. (t -> t1 -> UniqSM (Maybe a))
- -> t -> t1 -> UniqSM (Maybe (a, FwdRewrite UniqSM n f))
- {-# INLINE lift #-}
- lift rw node fact = do
- a <- rw node fact
- case a of
- Nothing -> return Nothing
- Just a -> return (Just (a,noFwdRewrite))
-
noBwdRewrite :: BwdRewrite UniqSM n f
noBwdRewrite = BwdRewrite3 (noRewrite, noRewrite, noRewrite)
-mkBRewrite3 :: forall n f.
- (n C O -> f -> UniqSM (Maybe (Graph n C O)))
- -> (n O O -> f -> UniqSM (Maybe (Graph n O O)))
- -> (n O C -> FactBase f -> UniqSM (Maybe (Graph n O C)))
- -> BwdRewrite UniqSM n f
-mkBRewrite3 f m l = BwdRewrite3 (lift f, lift m, lift l)
- where lift :: forall t t1 a. (t -> t1 -> UniqSM (Maybe a))
- -> t -> t1 -> UniqSM (Maybe (a, BwdRewrite UniqSM n f))
- {-# INLINE lift #-}
- lift rw node fact = do
- a <- rw node fact
- case a of
- Nothing -> return Nothing
- Just a -> return (Just (a,noBwdRewrite))
-
------------------------------------------------------------------------------
--- Analyze and rewrite forward: the interface
------------------------------------------------------------------------------
-
--- | if the graph being analyzed is open at the entry, there must
--- be no other entry point, or all goes horribly wrong...
-analyzeAndRewriteFwd
- :: forall n f e x . NonLocal n =>
- FwdPass UniqSM n f
- -> MaybeC e [Label]
- -> Graph n e x -> Fact e f
- -> UniqSM (Graph n e x, FactBase f, MaybeO x f)
-analyzeAndRewriteFwd pass entries g f =
- do (rg, fout) <- arfGraph pass (fmap targetLabels entries) g f
- let (g', fb) = normalizeGraph rg
- return (g', fb, distinguishedExitFact g' fout)
-
-distinguishedExitFact :: forall n e x f . Graph n e x -> Fact x f -> MaybeO x f
-distinguishedExitFact g f = maybe g
- where maybe :: Graph n e x -> MaybeO x f
- maybe GNil = JustO f
- maybe (GUnit {}) = JustO f
- maybe (GMany _ _ x) = case x of NothingO -> NothingO
- JustO _ -> JustO f
-
-----------------------------------------------------------------
--- Forward Implementation
-----------------------------------------------------------------
-
-type Entries e = MaybeC e [Label]
-
-arfGraph :: forall n f e x . NonLocal n =>
- FwdPass UniqSM n f ->
- Entries e -> Graph n e x -> Fact e f -> UniqSM (DG f n e x, Fact x f)
-arfGraph pass@FwdPass { fp_lattice = lattice,
- fp_transfer = transfer,
- fp_rewrite = rewrite } entries g in_fact = graph g in_fact
- where
- {- nested type synonyms would be so lovely here
- type ARF thing = forall e x . thing e x -> f -> m (DG f n e x, Fact x f)
- type ARFX thing = forall e x . thing e x -> Fact e f -> m (DG f n e x, Fact x f)
- -}
- graph :: Graph n e x -> Fact e f -> UniqSM (DG f n e x, Fact x f)
- block :: forall e x .
- Block n e x -> f -> UniqSM (DG f n e x, Fact x f)
-
- body :: [Label] -> LabelMap (Block n C C)
- -> Fact C f -> UniqSM (DG f n C C, Fact C f)
- -- Outgoing factbase is restricted to Labels *not* in
- -- in the Body; the facts for Labels *in*
- -- the Body are in the 'DG f n C C'
-
- cat :: forall e a x f1 f2 f3.
- (f1 -> UniqSM (DG f n e a, f2))
- -> (f2 -> UniqSM (DG f n a x, f3))
- -> (f1 -> UniqSM (DG f n e x, f3))
-
- graph GNil f = return (dgnil, f)
- graph (GUnit blk) f = block blk f
- graph (GMany e bdy x) f = ((e `ebcat` bdy) `cat` exit x) f
- where
- ebcat :: MaybeO e (Block n O C) -> Body n -> Fact e f -> UniqSM (DG f n e C, Fact C f)
- exit :: MaybeO x (Block n C O) -> Fact C f -> UniqSM (DG f n C x, Fact x f)
- exit (JustO blk) f = arfx block blk f
- exit NothingO f = return (dgnilC, f)
- ebcat entry bdy f = c entries entry f
- where c :: MaybeC e [Label] -> MaybeO e (Block n O C)
- -> Fact e f -> UniqSM (DG f n e C, Fact C f)
- c NothingC (JustO entry) f = (block entry `cat` body (successors entry) bdy) f
- c (JustC entries) NothingO f = body entries bdy f
-
- -- Lift from nodes to blocks
- block BNil f = return (dgnil, f)
- block (BlockCO n b) f = (node n `cat` block b) f
- block (BlockCC l b n) f = (node l `cat` block b `cat` node n) f
- block (BlockOC b n) f = (block b `cat` node n) f
-
- block (BMiddle n) f = node n f
- block (BCat b1 b2) f = (block b1 `cat` block b2) f
- block (BSnoc h n) f = (block h `cat` node n) f
- block (BCons n t) f = (node n `cat` block t) f
-
- {-# INLINE node #-}
- node :: forall e x . (ShapeLifter e x)
- => n e x -> f -> UniqSM (DG f n e x, Fact x f)
- node n f
- = do { grw <- frewrite rewrite n f
- ; case grw of
- Nothing -> return ( singletonDG f n
- , ftransfer transfer n f )
- Just (g, rw) ->
- let pass' = pass { fp_rewrite = rw }
- f' = fwdEntryFact n f
- in arfGraph pass' (fwdEntryLabel n) g f' }
-
- -- | Compose fact transformers and concatenate the resulting
- -- rewritten graphs.
- {-# INLINE cat #-}
- cat ft1 ft2 f = do { (g1,f1) <- ft1 f
- ; (g2,f2) <- ft2 f1
- ; let !g = g1 `dgSplice` g2
- ; return (g, f2) }
-
- arfx :: forall x .
- (Block n C x -> f -> UniqSM (DG f n C x, Fact x f))
- -> (Block n C x -> Fact C f -> UniqSM (DG f n C x, Fact x f))
- arfx arf thing fb =
- arf thing $ fromJust $ lookupFact (entryLabel thing) $ joinInFacts lattice fb
- -- joinInFacts adds debugging information
-
-
- -- Outgoing factbase is restricted to Labels *not* in
- -- in the Body; the facts for Labels *in*
- -- the Body are in the 'DG f n C C'
- body entries blockmap init_fbase
- = fixpoint Fwd lattice do_block entries blockmap init_fbase
- where
- lattice = fp_lattice pass
- do_block :: forall x . Block n C x -> FactBase f
- -> UniqSM (DG f n C x, Fact x f)
- do_block b fb = block b entryFact
- where entryFact = getFact lattice (entryLabel b) fb
-
-
--- Join all the incoming facts with bottom.
--- We know the results _shouldn't change_, but the transfer
--- functions might, for example, generate some debugging traces.
-joinInFacts :: DataflowLattice f -> FactBase f -> FactBase f
-joinInFacts (lattice @ DataflowLattice {fact_bot = bot, fact_join = fj}) fb =
- mkFactBase lattice $ map botJoin $ mapToList fb
- where botJoin (l, f) = (l, snd $ fj l (OldFact bot) (NewFact f))
-
forwardBlockList :: (NonLocal n)
=> [Label] -> Body n -> [Block n C C]
-- This produces a list of blocks in order suitable for forward analysis,
@@ -360,123 +180,6 @@ analyzeBwd BwdPass { bp_lattice = lattice,
cat :: forall f1 f2 f3 . (f2 -> f3) -> (f1 -> f2) -> (f1 -> f3)
cat ft1 ft2 = \f -> ft1 $! ft2 f
------------------------------------------------------------------------------
--- Backward analysis and rewriting: the interface
------------------------------------------------------------------------------
-
-
--- | if the graph being analyzed is open at the exit, I don't
--- quite understand the implications of possible other exits
-analyzeAndRewriteBwd
- :: NonLocal n
- => BwdPass UniqSM n f
- -> MaybeC e [Label] -> Graph n e x -> Fact x f
- -> UniqSM (Graph n e x, FactBase f, MaybeO e f)
-analyzeAndRewriteBwd pass entries g f =
- do (rg, fout) <- arbGraph pass (fmap targetLabels entries) g f
- let (g', fb) = normalizeGraph rg
- return (g', fb, distinguishedEntryFact g' fout)
-
-distinguishedEntryFact :: forall n e x f . Graph n e x -> Fact e f -> MaybeO e f
-distinguishedEntryFact g f = maybe g
- where maybe :: Graph n e x -> MaybeO e f
- maybe GNil = JustO f
- maybe (GUnit {}) = JustO f
- maybe (GMany e _ _) = case e of NothingO -> NothingO
- JustO _ -> JustO f
-
-
------------------------------------------------------------------------------
--- Backward implementation
------------------------------------------------------------------------------
-
-arbGraph :: forall n f e x .
- NonLocal n =>
- BwdPass UniqSM n f ->
- Entries e -> Graph n e x -> Fact x f -> UniqSM (DG f n e x, Fact e f)
-arbGraph pass@BwdPass { bp_lattice = lattice,
- bp_transfer = transfer,
- bp_rewrite = rewrite } entries g in_fact = graph g in_fact
- where
- {- nested type synonyms would be so lovely here
- type ARB thing = forall e x . thing e x -> Fact x f -> m (DG f n e x, f)
- type ARBX thing = forall e x . thing e x -> Fact x f -> m (DG f n e x, Fact e f)
- -}
- graph :: Graph n e x -> Fact x f -> UniqSM (DG f n e x, Fact e f)
- block :: forall e x . Block n e x -> Fact x f -> UniqSM (DG f n e x, f)
- body :: [Label] -> Body n -> Fact C f -> UniqSM (DG f n C C, Fact C f)
- node :: forall e x . (ShapeLifter e x)
- => n e x -> Fact x f -> UniqSM (DG f n e x, f)
- cat :: forall e a x info info' info''.
- (info' -> UniqSM (DG f n e a, info''))
- -> (info -> UniqSM (DG f n a x, info'))
- -> (info -> UniqSM (DG f n e x, info''))
-
- graph GNil f = return (dgnil, f)
- graph (GUnit blk) f = block blk f
- graph (GMany e bdy x) f = ((e `ebcat` bdy) `cat` exit x) f
- where
- ebcat :: MaybeO e (Block n O C) -> Body n -> Fact C f -> UniqSM (DG f n e C, Fact e f)
- exit :: MaybeO x (Block n C O) -> Fact x f -> UniqSM (DG f n C x, Fact C f)
- exit (JustO blk) f = arbx block blk f
- exit NothingO f = return (dgnilC, f)
- ebcat entry bdy f = c entries entry f
- where c :: MaybeC e [Label] -> MaybeO e (Block n O C)
- -> Fact C f -> UniqSM (DG f n e C, Fact e f)
- c NothingC (JustO entry) f = (block entry `cat` body (successors entry) bdy) f
- c (JustC entries) NothingO f = body entries bdy f
-
- -- Lift from nodes to blocks
- block BNil f = return (dgnil, f)
- block (BlockCO n b) f = (node n `cat` block b) f
- block (BlockCC l b n) f = (node l `cat` block b `cat` node n) f
- block (BlockOC b n) f = (block b `cat` node n) f
-
- block (BMiddle n) f = node n f
- block (BCat b1 b2) f = (block b1 `cat` block b2) f
- block (BSnoc h n) f = (block h `cat` node n) f
- block (BCons n t) f = (node n `cat` block t) f
-
- {-# INLINE node #-}
- node n f
- = do { bwdres <- brewrite rewrite n f
- ; case bwdres of
- Nothing -> return (singletonDG entry_f n, entry_f)
- where entry_f = btransfer transfer n f
- Just (g, rw) ->
- do { let pass' = pass { bp_rewrite = rw }
- ; (g, f) <- arbGraph pass' (fwdEntryLabel n) g f
- ; return (g, bwdEntryFact lattice n f)} }
-
- -- | Compose fact transformers and concatenate the resulting
- -- rewritten graphs.
- {-# INLINE cat #-}
- cat ft1 ft2 f = do { (g2,f2) <- ft2 f
- ; (g1,f1) <- ft1 f2
- ; let !g = g1 `dgSplice` g2
- ; return (g, f1) }
-
- arbx :: forall x .
- (Block n C x -> Fact x f -> UniqSM (DG f n C x, f))
- -> (Block n C x -> Fact x f -> UniqSM (DG f n C x, Fact C f))
-
- arbx arb thing f = do { (rg, f) <- arb thing f
- ; let fb = joinInFacts (bp_lattice pass) $
- mapSingleton (entryLabel thing) f
- ; return (rg, fb) }
- -- joinInFacts adds debugging information
-
- -- Outgoing factbase is restricted to Labels *not* in
- -- in the Body; the facts for Labels *in*
- -- the Body are in the 'DG f n C C'
- body entries blockmap init_fbase
- = fixpoint Bwd (bp_lattice pass) do_block entries blockmap init_fbase
- where
- do_block :: forall x. Block n C x -> Fact x f -> UniqSM (DG f n C x, LabelMap f)
- do_block b f = do (g, f) <- block b f
- return (g, mapSingleton (entryLabel b) f)
-
-
{-
The forward and backward cases are not dual. In the forward case, the
@@ -541,95 +244,7 @@ fixpointAnal direction DataflowLattice{ fact_bot = _, fact_join = join }
loop todo' fbase'
--- | fixpointing for combined analysis/rewriting
---
-fixpoint :: forall n f. NonLocal n
- => Direction
- -> DataflowLattice f
- -> (Block n C C -> Fact C f -> UniqSM (DG f n C C, Fact C f))
- -> [Label]
- -> LabelMap (Block n C C)
- -> (Fact C f -> UniqSM (DG f n C C, Fact C f))
-
-fixpoint direction DataflowLattice{ fact_bot = _, fact_join = join }
- do_block entries blockmap init_fbase
- = do
- -- trace ("fixpoint: " ++ show (case direction of Fwd -> True; Bwd -> False) ++ " " ++ show (mapKeys blockmap) ++ show entries ++ " " ++ show (mapKeys init_fbase)) $ return()
- (fbase, newblocks) <- loop start init_fbase mapEmpty
- -- trace ("fixpoint DONE: " ++ show (mapKeys fbase) ++ show (mapKeys newblocks)) $ return()
- return (GMany NothingO newblocks NothingO,
- mapDeleteList (mapKeys blockmap) fbase)
- -- The successors of the Graph are the the Labels
- -- for which we have facts and which are *not* in
- -- the blocks of the graph
- where
- blocks = sortBlocks direction entries blockmap
- n = length blocks
- block_arr = {-# SCC "block_arr" #-} listArray (0,n-1) blocks
- start = {-# SCC "start" #-} [0..n-1]
- dep_blocks = {-# SCC "dep_blocks" #-} mkDepBlocks direction blocks
-
- loop
- :: IntHeap
- -> FactBase f -- current factbase (increases monotonically)
- -> LabelMap (DBlock f n C C) -- transformed graph
- -> UniqSM (FactBase f, LabelMap (DBlock f n C C))
-
- loop [] fbase newblocks = return (fbase, newblocks)
- loop (ix:todo) fbase !newblocks = do
- let blk = block_arr ! ix
-
- -- trace ("analysing: " ++ show (entryLabel blk)) $ return ()
- (rg, out_facts) <- do_block blk fbase
- let !(todo', fbase') =
- mapFoldWithKey (updateFact join dep_blocks)
- (todo,fbase) out_facts
-
- -- trace ("fbase': " ++ show (mapKeys fbase')) $ return ()
- -- trace ("changed: " ++ show changed) $ return ()
- -- trace ("to analyse: " ++ show to_analyse) $ return ()
-
- let newblocks' = case rg of
- GMany _ blks _ -> mapUnion blks newblocks
-
- loop todo' fbase' newblocks'
-
-
-{- Note [TxFactBase invariants]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The TxFactBase is used only during a fixpoint iteration (or "sweep"),
-and accumulates facts (and the transformed code) during the fixpoint
-iteration.
-
-* tfb_fbase increases monotonically, across all sweeps
-
-* At the beginning of each sweep
- tfb_cha = NoChange
- tfb_lbls = {}
-
-* During each sweep we process each block in turn. Processing a block
- is done thus:
- 1. Read from tfb_fbase the facts for its entry label (forward)
- or successors labels (backward)
- 2. Transform those facts into new facts for its successors (forward)
- or entry label (backward)
- 3. Augment tfb_fbase with that info
- We call the labels read in step (1) the "in-labels" of the sweep
-
-* The field tfb_lbls is the set of in-labels of all blocks that have
- been processed so far this sweep, including the block that is
- currently being processed. tfb_lbls is initialised to {}. It is a
- subset of the Labels of the *original* (not transformed) blocks.
-
-* The tfb_cha field is set to SomeChange iff we decide we need to
- perform another iteration of the fixpoint loop. It is initialsed to NoChange.
-
- Specifically, we set tfb_cha to SomeChange in step (3) iff
- (a) The fact in tfb_fbase for a block L changes
- (b) L is in tfb_lbls
- Reason: until a label enters the in-labels its accumuated fact in tfb_fbase
- has not been read, hence cannot affect the outcome
-
+{-
Note [Unreachable blocks]
~~~~~~~~~~~~~~~~~~~~~~~~~
A block that is not in the domain of tfb_fbase is "currently unreachable".
@@ -720,150 +335,15 @@ we don't need to record a change. So there's a tradeoff here. It turns
out that always recording a change is faster.
-}
------------------------------------------------------------------------------
--- DG: an internal data type for 'decorated graphs'
--- TOTALLY internal to Hoopl; each block is decorated with a fact
------------------------------------------------------------------------------
-
-type DG f = Graph' (DBlock f)
-data DBlock f n e x = DBlock f (Block n e x) -- ^ block decorated with fact
-
-instance NonLocal n => NonLocal (DBlock f n) where
- entryLabel (DBlock _ b) = entryLabel b
- successors (DBlock _ b) = successors b
-
---- constructors
-
-dgnil :: DG f n O O
-dgnilC :: DG f n C C
-dgSplice :: NonLocal n => DG f n e a -> DG f n a x -> DG f n e x
-
----- observers
-
-normalizeGraph :: forall n f e x .
- NonLocal n => DG f n e x
- -> (Graph n e x, FactBase f)
- -- A Graph together with the facts for that graph
- -- The domains of the two maps should be identical
-
-normalizeGraph g = (mapGraphBlocks dropFact g, facts g)
- where dropFact :: DBlock t t1 t2 t3 -> Block t1 t2 t3
- dropFact (DBlock _ b) = b
- facts :: DG f n e x -> FactBase f
- facts GNil = noFacts
- facts (GUnit _) = noFacts
- facts (GMany _ body exit) = bodyFacts body `mapUnion` exitFacts exit
- exitFacts :: MaybeO x (DBlock f n C O) -> FactBase f
- exitFacts NothingO = noFacts
- exitFacts (JustO (DBlock f b)) = mapSingleton (entryLabel b) f
- bodyFacts :: LabelMap (DBlock f n C C) -> FactBase f
- bodyFacts body = mapFoldWithKey f noFacts body
- where f :: forall t a x. Label -> DBlock a t C x -> LabelMap a -> LabelMap a
- f lbl (DBlock f _) fb = mapInsert lbl f fb
-
---- implementation of the constructors (boring)
-
-dgnil = GNil
-dgnilC = GMany NothingO emptyBody NothingO
-
-dgSplice = splice fzCat
- where fzCat :: DBlock f n e O -> DBlock t n O x -> DBlock f n e x
- fzCat (DBlock f b1) (DBlock _ b2) = DBlock f $! b1 `blockAppend` b2
- -- NB. strictness, this function is hammered.
-
----------------------------------------------------------------
-- Utilities
----------------------------------------------------------------
--- Lifting based on shape:
--- - from nodes to blocks
--- - from facts to fact-like things
--- Lowering back:
--- - from fact-like things to facts
--- Note that the latter two functions depend only on the entry shape.
-class ShapeLifter e x where
- singletonDG :: f -> n e x -> DG f n e x
- fwdEntryFact :: NonLocal n => n e x -> f -> Fact e f
- fwdEntryLabel :: NonLocal n => n e x -> MaybeC e [Label]
- ftransfer :: FwdTransfer n f -> n e x -> f -> Fact x f
- frewrite :: FwdRewrite m n f -> n e x
- -> f -> m (Maybe (Graph n e x, FwdRewrite m n f))
--- @ end node.tex
- bwdEntryFact :: NonLocal n => DataflowLattice f -> n e x -> Fact e f -> f
- btransfer :: BwdTransfer n f -> n e x -> Fact x f -> f
- brewrite :: BwdRewrite m n f -> n e x
- -> Fact x f -> m (Maybe (Graph n e x, BwdRewrite m n f))
-
-instance ShapeLifter C O where
- singletonDG f n = gUnitCO (DBlock f (BlockCO n BNil))
- fwdEntryFact n f = mapSingleton (entryLabel n) f
- bwdEntryFact lat n fb = getFact lat (entryLabel n) fb
- ftransfer (FwdTransfer3 (ft, _, _)) n f = ft n f
- btransfer (BwdTransfer3 (bt, _, _)) n f = bt n f
- frewrite (FwdRewrite3 (fr, _, _)) n f = fr n f
- brewrite (BwdRewrite3 (br, _, _)) n f = br n f
- fwdEntryLabel n = JustC [entryLabel n]
-
-instance ShapeLifter O O where
- singletonDG f = gUnitOO . DBlock f . BMiddle
- fwdEntryFact _ f = f
- bwdEntryFact _ _ f = f
- ftransfer (FwdTransfer3 (_, ft, _)) n f = ft n f
- btransfer (BwdTransfer3 (_, bt, _)) n f = bt n f
- frewrite (FwdRewrite3 (_, fr, _)) n f = fr n f
- brewrite (BwdRewrite3 (_, br, _)) n f = br n f
- fwdEntryLabel _ = NothingC
-
-instance ShapeLifter O C where
- singletonDG f n = gUnitOC (DBlock f (BlockOC BNil n))
- fwdEntryFact _ f = f
- bwdEntryFact _ _ f = f
- ftransfer (FwdTransfer3 (_, _, ft)) n f = ft n f
- btransfer (BwdTransfer3 (_, _, bt)) n f = bt n f
- frewrite (FwdRewrite3 (_, _, fr)) n f = fr n f
- brewrite (BwdRewrite3 (_, _, br)) n f = br n f
- fwdEntryLabel _ = NothingC
-
-{-
-class ShapeLifter e x where
- singletonDG :: f -> n e x -> DG f n e x
-
-instance ShapeLifter C O where
- singletonDG f n = gUnitCO (DBlock f (BlockCO n BNil))
-
-instance ShapeLifter O O where
- singletonDG f = gUnitOO . DBlock f . BMiddle
-
-instance ShapeLifter O C where
- singletonDG f n = gUnitOC (DBlock f (BlockOC BNil n))
--}
-
-- Fact lookup: the fact `orelse` bottom
getFact :: DataflowLattice f -> Label -> FactBase f -> f
getFact lat l fb = case lookupFact l fb of Just f -> f
Nothing -> fact_bot lat
-
-
-{- Note [Respects fuel]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--}
--- $fuel
--- A value of type 'FwdRewrite' or 'BwdRewrite' /respects fuel/ if
--- any function contained within the value satisfies the following properties:
---
--- * When fuel is exhausted, it always returns 'Nothing'.
---
--- * When it returns @Just g rw@, it consumes /exactly/ one unit
--- of fuel, and new rewrite 'rw' also respects fuel.
---
--- Provided that functions passed to 'mkFRewrite', 'mkFRewrite3',
--- 'mkBRewrite', and 'mkBRewrite3' are not aware of the fuel supply,
--- the results respect fuel.
---
--- It is an /unchecked/ run-time error for the argument passed to 'wrapFR',
--- 'wrapFR2', 'wrapBR', or 'warpBR2' to return a function that does not respect fuel.
-
-- -----------------------------------------------------------------------------
-- a Heap of Int