summaryrefslogtreecommitdiff
path: root/src/GF/Devel/OptimizeGFCC.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/GF/Devel/OptimizeGFCC.hs')
-rw-r--r--src/GF/Devel/OptimizeGFCC.hs105
1 files changed, 50 insertions, 55 deletions
diff --git a/src/GF/Devel/OptimizeGFCC.hs b/src/GF/Devel/OptimizeGFCC.hs
index 27f510828..78d03911f 100644
--- a/src/GF/Devel/OptimizeGFCC.hs
+++ b/src/GF/Devel/OptimizeGFCC.hs
@@ -1,41 +1,36 @@
module GF.Devel.OptimizeGFCC where
-import qualified GF.Canon.GFCC.AbsGFCC as C
-import qualified GF.Canon.GFCC.DataGFCC as D
-import qualified GF.Canon.GFCC.PrintGFCC as Pr
+import GF.GFCC.AbsGFCC
+import GF.GFCC.DataGFCC
-import qualified GF.Infra.Option as O
-
-import GF.Infra.Option
import GF.Data.Operations
import Data.List
-import Data.Char (isDigit)
import qualified Data.Map as Map
-import Debug.Trace ----
-- back-end optimization:
-- suffix analysis followed by common subexpression elimination
-optGFCC :: D.GFCC -> D.GFCC
+optGFCC :: GFCC -> GFCC
optGFCC gfcc = gfcc {
- D.concretes =
- Map.fromAscList
- [(lang, (opt cnc)) | (lang,cnc) <- Map.assocs (D.concretes gfcc)]
+ concretes = Map.map opt (concretes gfcc)
}
where
- opt cnc = Map.fromAscList $ subex [(f,optTerm t) | (f,t) <- Map.assocs cnc]
+ opt cnc = subex $ cnc {
+ lins = Map.map optTerm (lins cnc),
+ lindefs = Map.map optTerm (lindefs cnc),
+ printnames = Map.map optTerm (printnames cnc)
+ }
-- analyse word form lists into prefix + suffixes
-- suffix sets can later be shared by subex elim
-optTerm :: C.Term -> C.Term
+optTerm :: Term -> Term
optTerm tr = case tr of
- C.R ts@(_:_:_) | all isK ts -> mkSuff $ optToks [s | C.K (C.KS s) <- ts]
- C.R ts -> C.R $ map optTerm ts
- C.P t v -> C.P (optTerm t) v
- C.L x t -> C.L x (optTerm t)
+ R ts@(_:_:_) | all isK ts -> mkSuff $ optToks [s | K (KS s) <- ts]
+ R ts -> R $ map optTerm ts
+ P t v -> P (optTerm t) v
_ -> tr
where
optToks ss = prf : suffs where
@@ -45,67 +40,67 @@ optTerm tr = case tr of
s1:ss2 -> if isPrefixOf cand s1 then pref cand ss2 else pref (init cand) ss
_ -> cand
isK t = case t of
- C.K (C.KS _) -> True
+ K (KS _) -> True
_ -> False
- mkSuff ("":ws) = C.R (map (C.K . C.KS) ws)
- mkSuff (p:ws) = C.W p (C.R (map (C.K . C.KS) ws))
+ mkSuff ("":ws) = R (map (K . KS) ws)
+ mkSuff (p:ws) = W p (R (map (K . KS) ws))
--- common subexpression elimination; see ./Subexpression.hs for the idea
+-- common subexpression elimination
-subex :: [(C.CId,C.Term)] -> [(C.CId,C.Term)]
-subex js = errVal js $ do
- (tree,_) <- appSTM (getSubtermsMod js) (Map.empty,0)
- return $ addSubexpConsts tree js
+---subex :: [(CId,Term)] -> [(CId,Term)]
+subex :: Concr -> Concr
+subex cnc = errVal cnc $ do
+ (tree,_) <- appSTM (getSubtermsMod cnc) (Map.empty,0)
+ return $ addSubexpConsts tree cnc
-type TermList = Map.Map C.Term (Int,Int) -- number of occs, id
+type TermList = Map.Map Term (Int,Int) -- number of occs, id
type TermM a = STM (TermList,Int) a
-addSubexpConsts :: TermList -> [(C.CId,C.Term)] -> [(C.CId,C.Term)]
-addSubexpConsts tree lins =
- let opers = sortBy (\ (f,_) (g,_) -> compare f g)
- [(fid id, trm) | (trm,(_,id)) <- list]
- in map mkOne $ opers ++ lins
+addSubexpConsts :: TermList -> Concr -> Concr
+addSubexpConsts tree cnc = cnc {
+ opers = Map.fromList [(f,recomp f trm) | (f,trm) <- ops],
+ lins = rec lins,
+ lindefs = rec lindefs,
+ printnames = rec printnames
+ }
where
+ ops = [(fid id, trm) | (trm,(_,id)) <- Map.assocs tree]
mkOne (f,trm) = (f, recomp f trm)
recomp f t = case Map.lookup t tree of
- Just (_,id) | fid id /= f -> C.F $ fid id -- not to replace oper itself
+ Just (_,id) | fid id /= f -> F $ fid id -- not to replace oper itself
_ -> case t of
- C.R ts -> C.R $ map (recomp f) ts
- C.S ts -> C.S $ map (recomp f) ts
- C.W s t -> C.W s (recomp f t)
- C.P t p -> C.P (recomp f t) (recomp f p)
- C.RP t p -> C.RP (recomp f t) (recomp f p)
- C.L x t -> C.L x (recomp f t)
+ R ts -> R $ map (recomp f) ts
+ S ts -> S $ map (recomp f) ts
+ W s t -> W s (recomp f t)
+ P t p -> P (recomp f t) (recomp f p)
_ -> t
- fid n = C.CId $ "_" ++ show n
- list = Map.toList tree
+ fid n = CId $ "_" ++ show n
+ rec field = Map.fromAscList [(f,recomp f trm) | (f,trm) <- Map.assocs (field cnc)]
-getSubtermsMod :: [(C.CId,C.Term)] -> TermM TermList
-getSubtermsMod js = do
- mapM (getInfo collectSubterms) js
+
+getSubtermsMod :: Concr -> TermM TermList
+getSubtermsMod cnc = do
+ mapM getSubterms (Map.assocs (lins cnc))
+ mapM getSubterms (Map.assocs (lindefs cnc))
+ mapM getSubterms (Map.assocs (printnames cnc))
(tree0,_) <- readSTM
return $ Map.filter (\ (nu,_) -> nu > 1) tree0
where
- getInfo get (f,trm) = do
- get trm
- return ()
+ getSubterms (f,trm) = collectSubterms trm >> return ()
-collectSubterms :: C.Term -> TermM ()
+collectSubterms :: Term -> TermM ()
collectSubterms t = case t of
- C.R ts -> do
+ R ts -> do
mapM collectSubterms ts
add t
- C.RP u v -> do
- collectSubterms v
- add t
- C.S ts -> do
+ S ts -> do
mapM collectSubterms ts
add t
- C.W s u -> do
+ W s u -> do
collectSubterms u
add t
- C.P p u -> do
+ P p u -> do
collectSubterms p
collectSubterms u
add t