Trying to fix an efficiency issue noted in a TODO in SAT.hs
David Feuer
david.feuer at gmail.com
Sun Sep 7 03:05:44 UTC 2014
compiler/simplCore/SAT.hs has a TODO comment about the fact that it does a
fair bit of appending onto the ends of lists, and that should be done
differently. I made an attempt to fix it. The complexity of the recursion,
however, leaves me uncertain as to whether I really did or not. I've
attached a diff and I hope someone will be able to take a look at it. The
only use of Sequence.fromList is source line 172, and the only significant
use of Foldable.toList (aside from pretty-printing) is on source line 402.
Note that the use of Sequence may be temporary—I want to get the right code
structure down before choosing the best data structure.
Thanks,
David Feuer
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20140906/14956a24/attachment.html>
-------------- next part --------------
diff --git a/compiler/simplCore/SAT.lhs b/compiler/simplCore/SAT.lhs
index a0b3151..aae3e69 100644
--- a/compiler/simplCore/SAT.lhs
+++ b/compiler/simplCore/SAT.lhs
@@ -67,10 +67,16 @@ import VarSet
import Unique
import UniqSet
import Outputable
-
import Data.List
import FastString
+--We're probably not really going to use Data.Sequence
+--this is just a temporary temporary thing to see what we'll
+--actually need.
+import qualified Data.Sequence as S
+import Data.Foldable (toList)
+import Data.Sequence (Seq, (|>), (<|), (><), fromList)
+
#include "HsVersions.h"
\end{code}
@@ -118,7 +124,7 @@ data Staticness a = Static a | NotStatic
type IdAppInfo = (Id, SATInfo)
-type SATInfo = [Staticness App]
+type SATInfo = Seq (Staticness App) -- [Staticness App]
type IdSATInfo = IdEnv SATInfo
emptyIdSATInfo :: IdSATInfo
emptyIdSATInfo = emptyUFM
@@ -129,7 +135,7 @@ pprIdSATInfo id_sat_info = vcat (map pprIdAndSATInfo (Map.toList id_sat_info))
-}
pprSATInfo :: SATInfo -> SDoc
-pprSATInfo staticness = hcat $ map pprStaticness staticness
+pprSATInfo staticness = hcat $ map pprStaticness $ toList staticness
pprStaticness :: Staticness App -> SDoc
pprStaticness (Static (VarApp _)) = ptext (sLit "SV")
@@ -139,15 +145,22 @@ pprStaticness NotStatic = ptext (sLit "NS")
mergeSATInfo :: SATInfo -> SATInfo -> SATInfo
-mergeSATInfo [] _ = []
-mergeSATInfo _ [] = []
-mergeSATInfo (NotStatic:statics) (_:apps) = NotStatic : mergeSATInfo statics apps
-mergeSATInfo (_:statics) (NotStatic:apps) = NotStatic : mergeSATInfo statics apps
-mergeSATInfo ((Static (VarApp v)):statics) ((Static (VarApp v')):apps) = (if v == v' then Static (VarApp v) else NotStatic) : mergeSATInfo statics apps
-mergeSATInfo ((Static (TypeApp t)):statics) ((Static (TypeApp t')):apps) = (if t `eqType` t' then Static (TypeApp t) else NotStatic) : mergeSATInfo statics apps
-mergeSATInfo ((Static (CoApp c)):statics) ((Static (CoApp c')):apps) = (if c `coreEqCoercion` c' then Static (CoApp c) else NotStatic) : mergeSATInfo statics apps
-mergeSATInfo l r = pprPanic "mergeSATInfo" $ ptext (sLit "Left:") <> pprSATInfo l <> ptext (sLit ", ")
- <> ptext (sLit "Right:") <> pprSATInfo r
+mergeSATInfo l r = S.zipWith mergeSA l r
+ where
+ mergeSA NotStatic _ = NotStatic
+ mergeSA _ NotStatic = NotStatic
+ mergeSA (Static (VarApp v)) (Static (VarApp v'))
+ | v == v' = Static (VarApp v)
+ | otherwise = NotStatic
+ mergeSA (Static (TypeApp t)) (Static (TypeApp t'))
+ | t `eqType` t' = Static (TypeApp t)
+ | otherwise = NotStatic
+ mergeSA (Static (CoApp c)) (Static (CoApp c'))
+ | c `coreEqCoercion` c' = Static (CoApp c)
+ | otherwise = NotStatic
+ mergeSA _ _ = pprPanic "mergeSATInfo" $ ptext (sLit "Left:")
+ <> pprSATInfo l <> ptext (sLit ", ")
+ <> ptext (sLit "Right:") <> pprSATInfo r
mergeIdSATInfo :: IdSATInfo -> IdSATInfo -> IdSATInfo
mergeIdSATInfo = plusUFM_C mergeSATInfo
@@ -156,7 +169,7 @@ mergeIdSATInfos :: [IdSATInfo] -> IdSATInfo
mergeIdSATInfos = foldl' mergeIdSATInfo emptyIdSATInfo
bindersToSATInfo :: [Id] -> SATInfo
-bindersToSATInfo vs = map (Static . binderToApp) vs
+bindersToSATInfo vs = fromList $ map (Static . binderToApp) vs
where binderToApp v | isId v = VarApp v
| isTyVar v = TypeApp $ mkTyVarTy v
| otherwise = CoApp $ mkCoVarCo v
@@ -178,7 +191,7 @@ satTopLevelExpr expr interesting_ids = do
satExpr :: CoreExpr -> IdSet -> SatM (CoreExpr, IdSATInfo, Maybe IdAppInfo)
satExpr var@(Var v) interesting_ids = do
let app_info = if v `elementOfUniqSet` interesting_ids
- then Just (v, [])
+ then Just (v, S.empty)
else Nothing
return (var, emptyIdSATInfo, app_info)
@@ -195,8 +208,7 @@ satExpr (App fn arg) interesting_ids = do
case fn_app of
Nothing -> satRemainder Nothing
Just (fn_id, fn_app_info) ->
- -- TODO: remove this use of append somehow (use a data structure with O(1) append but a left-to-right kind of interface)
- let satRemainderWithStaticness arg_staticness = satRemainder $ Just (fn_id, fn_app_info ++ [arg_staticness])
+ let satRemainderWithStaticness arg_staticness = satRemainder $ Just (fn_id, fn_app_info |> arg_staticness)
in case arg of
Type t -> satRemainderWithStaticness $ Static (TypeApp t)
Coercion c -> satRemainderWithStaticness $ Static (CoApp c)
@@ -371,7 +383,7 @@ saTransformMaybe binder maybe_arg_staticness rhs_binders rhs_body
where
should_transform staticness = n_static_args > 1 -- THIS IS THE DECISION POINT
where
- n_static_args = length (filter isStaticValue staticness)
+ n_static_args = S.length (S.filter isStaticValue staticness)
saTransform :: Id -> SATInfo -> [Id] -> CoreExpr -> SatM CoreBind
saTransform binder arg_staticness rhs_binders rhs_body
@@ -385,13 +397,17 @@ saTransform binder arg_staticness rhs_binders rhs_body
-- rhs_binders = [\alpha, \beta, c, n, xs]
-- rhs_body = e
- binders_w_staticness = rhs_binders `zip` (arg_staticness ++ repeat NotStatic)
+ (rhs_binders_known_staticness, rhs_binders_unknown_staticness) = splitAt (S.length arg_staticness) rhs_binders
+
+ binders_w_known_staticness = rhs_binders_known_staticness `zip` toList arg_staticness
+ binders_w_staticness = binders_w_known_staticness ++
+ map (\x->(x,NotStatic)) rhs_binders_unknown_staticness
-- Any extra args are assumed NotStatic
non_static_args :: [Var]
-- non_static_args = [xs]
-- rhs_binders_without_type_capture = [\alpha', \beta', c, n, xs]
- non_static_args = [v | (v, NotStatic) <- binders_w_staticness]
+ non_static_args = [v | (v, NotStatic) <- binders_w_known_staticness] ++ rhs_binders_unknown_staticness
clone (bndr, NotStatic) = return bndr
clone (bndr, _ ) = do { uniq <- newUnique
More information about the ghc-devs
mailing list