Repository : ssh://darcs.haskell.org//srv/darcs/ghc

On branch  : 

http://hackage.haskell.org/trac/ghc/changeset/ec2f7fc095ab0543546d85f47a58e004f4fdd891

>---------------------------------------------------------------

commit ec2f7fc095ab0543546d85f47a58e004f4fdd891
Author: Max Bolingbroke <batterseapo...@hotmail.com>
Date:   Thu Mar 22 12:33:51 2012 +0000

    Collect reasons as to why unfoldings couldn't be used, experimentally allow 
non-loopbreaker inlinings

>---------------------------------------------------------------

 compiler/supercompile/Supercompile.hs           |   54 ++++++++++++++--------
 compiler/supercompile/Supercompile/Utilities.hs |    5 ++
 2 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/compiler/supercompile/Supercompile.hs 
b/compiler/supercompile/Supercompile.hs
index 4acdc36..d88e3e5 100644
--- a/compiler/supercompile/Supercompile.hs
+++ b/compiler/supercompile/Supercompile.hs
@@ -25,7 +25,7 @@ import qualified Supercompile.Drive.Process1 as S ()
 import qualified Supercompile.Drive.Process2 as S ()
 import qualified Supercompile.Drive.Process3 as S
 
-import BasicTypes (InlinePragma(..), InlineSpec(..), isActiveIn, TupleSort(..))
+import BasicTypes (InlinePragma(..), InlineSpec(..), isActiveIn, 
TupleSort(..), isStrongLoopBreaker)
 import CoreSyn
 import CoreFVs    (exprFreeVars)
 import CoreUtils  (exprType)
@@ -144,27 +144,32 @@ mkLiftedTupleSelector xs want_x tup_e
   where n = length xs
 
 termUnfoldings :: S.Term -> [(Var, S.Term)]
-termUnfoldings e = go (S.termFreeVars e) emptyVarSet []
+termUnfoldings e = go (S.termFreeVars e) emptyVarSet [] []
   where
-    go new_fvs all_fvs all_xes
-      | isEmptyVarSet added_fvs = all_xes -- FIXME: varBndrFreeVars?
-      | otherwise               = go (unionVarSets (map (S.termFreeVars . snd) 
added_xes)) (all_fvs `unionVarSet` added_fvs) (added_xes ++ all_xes)
+    -- FIXME: varBndrFreeVars?
+    go new_fvs all_fvs all_xwhy_nots all_xes
+      | isEmptyVarSet added_fvs = pprTrace "termUnfoldings" (vcat [hang (text 
why_not <> text ":") 2 (vcat (map ppr xs)) | (why_not, xs) <- groups snd fst 
all_xwhy_nots]) $
+                                  all_xes
+      | otherwise               = go (unionVarSets (map (S.termFreeVars . snd) 
added_xes)) (all_fvs `unionVarSet` added_fvs)
+                                     (added_xwhy_nots ++ all_xwhy_nots) 
(added_xes ++ all_xes)
       where added_fvs = new_fvs `minusVarSet` all_fvs
-            added_xes = [ (x, e)
-                        | x <- varSetElems added_fvs
-                        , Just e <- [varUnfolding x]]
+            (added_xwhy_nots, added_xes)
+              = foldVarSet (\x (xwhy_nots, xes) -> case varUnfolding x of
+                                                     Left why_not -> ((x, 
why_not):xwhy_nots,        xes)
+                                                     Right e      -> (         
    xwhy_nots, (x, e):xes))
+                           ([], []) added_fvs
 
     varUnfolding x
-      | Just pop <- isPrimOpId_maybe x     = Just $ primOpUnfolding pop
-      | Just dc <- isDataConWorkId_maybe x = Just $ dataUnfolding dc
-      | not (shouldExposeUnfolding x)      = Nothing
-      | otherwise                          = case realIdUnfolding x of
-        NoUnfolding                   -> Nothing
-        OtherCon _                    -> Nothing
-        DFunUnfolding _ dc es         -> Just $ runParseM us2 $ coreExprToTerm 
$ mkLams as $ mkLams xs $ Var (dataConWorkId dc) `mkTyApps` cls_tys `mkApps` 
[(e `mkTyApps` map mkTyVarTy as) `mkVarApps` xs | e <- es]
+      | Just pop <- isPrimOpId_maybe x          = Right $ primOpUnfolding pop
+      | Just dc <- isDataConWorkId_maybe x      = Right $ dataUnfolding dc
+      | Just why_not <- shouldExposeUnfolding x = Left why_not
+      | otherwise                               = case realIdUnfolding x of
+        NoUnfolding                   -> Left "no unfolding"
+        OtherCon _                    -> Left "no positive unfolding"
+        DFunUnfolding _ dc es         -> Right $ runParseM us2 $ 
coreExprToTerm $ mkLams as $ mkLams xs $ Var (dataConWorkId dc) `mkTyApps` 
cls_tys `mkApps` [(e `mkTyApps` map mkTyVarTy as) `mkVarApps` xs | e <- es]
          where (as, theta, _cls, cls_tys) = tcSplitDFunTy (idType x)
                xs = zipWith (mkSysLocal (fsLit "x")) bv_uniques theta
-        CoreUnfolding { uf_tmpl = e } -> Just $ runParseM us2 $ coreExprToTerm 
e
+        CoreUnfolding { uf_tmpl = e } -> Right $ runParseM us2 $ 
coreExprToTerm e
          -- NB: it's OK if the unfolding is a non-value, as the evaluator 
won't inline LetBound non-values
     
     -- We don't want to expose an unfolding if it would not be inlineable in 
the initial phase.
@@ -176,11 +181,20 @@ termUnfoldings e = go (S.termFreeVars e) emptyVarSet []
     --  * Exhaustively specialises *locally defined* functions on their 
dictionary arguments
     --  * Specialises those *imported* functions that are marked Inlineable
     shouldExposeUnfolding x = case inl_inline inl_prag of
-        Inline          -> not sUPERINLINABLE_ONLY
-        Inlinable super -> not sUPERINLINABLE_ONLY || super
-        NoInline        -> not sUPERINLINABLE_ONLY && isActiveIn 2 (inl_act 
inl_prag)
-        EmptyInlineSpec -> not sUPERINLINABLE_ONLY
+        Inlinable super
+          | only_if_superinlinable, not super  -> Just "INLINEABLE but not 
SUPERINLINABLE"
+        NoInline
+          | isActiveIn 2 (inl_act inl_prag)    -> Just "NONLINE"
+          | only_if_superinlinable             -> Just "(inactive) NOINLINE, 
not SUPERINLINABLE"
+        EmptyInlineSpec 
+          | only_if_superinlinable             -> Just "not SUPERINLINABLE"
+        _                                      -> Nothing
       where inl_prag = idInlinePragma x
+            -- EXPERIMENT: only respect the SUPERINLINABLE distinction on 
*loop breakers*
+            -- The motivation is that we don't really want to go around 
annotating (GHC.Base.>>=),
+            -- bindIO, etc etc as SUPERINLINABLE.
+            only_if_superinlinable | sUPERINLINABLE_ONLY = isStrongLoopBreaker 
(idOccInfo x)
+                                   | otherwise           = False
     
     primOpUnfolding pop = S.tyLambdas as $ S.lambdas xs $ S.primOp pop (map 
mkTyVarTy as) (map S.var xs)
       where (as, arg_tys, _res_ty, _arity, _strictness) = primOpSig pop
diff --git a/compiler/supercompile/Supercompile/Utilities.hs 
b/compiler/supercompile/Supercompile/Utilities.hs
index ddd3a7f..b1f0976 100644
--- a/compiler/supercompile/Supercompile/Utilities.hs
+++ b/compiler/supercompile/Supercompile/Utilities.hs
@@ -486,6 +486,11 @@ sumMap f = Foldable.foldr (\x n -> f x + n) 0
 sumMapMonoid :: (Foldable f, Monoid b) => (a -> b) -> f a -> b
 sumMapMonoid f = Foldable.foldr (\x n -> f x `mappend` n) mempty
 
+{-# INLINE groups #-}
+groups :: Ord b => (a -> b) -> (a -> c) -> [a] -> [(b, [c])]
+groups f g xs = runs f g (sortBy (comparing f) xs)
+
+{-# INLINE runs #-}
 runs :: Eq b => (a -> b) -> (a -> c) -> [a] -> [(b, [c])]
 runs _ _ []     = []
 runs f g (x:xs) = go (f x) [g x] xs



_______________________________________________
Cvs-ghc mailing list
Cvs-ghc@haskell.org
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to