git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: optimize mutually recursive let funcs
eddf446Andy Arvanitis
src/Language/PureScript/CodeGen/Cpp.hs+26−12
@@ -29,7 +29,7 @@ module Language.PureScript.CodeGen.Cpp
29import Data.Char (isLetter)
29import Data.Char (isLetter)
30import Data.List
30import Data.List
31import Data.Function (on)
31import Data.Function (on)
32−import Data.Maybe (catMaybes)
32+import Data.Maybe (catMaybes, fromJust)
33import qualified Data.Map as M
33import qualified Data.Map as M
34
34
35import Control.Monad (forM, replicateM)
35import Control.Monad (forM, replicateM)
@@ -314,14 +314,20 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
314 go cpp = cpp
314 go cpp = cpp
315
315
316 -------------------------------------------------------------------------------------------------
316 -------------------------------------------------------------------------------------------------
317− convertRecursiveFns :: [Cpp] -> [Cpp]
317+ convertRecursiveFns :: [Cpp] -> Cpp -> [Cpp]
318 -------------------------------------------------------------------------------------------------
318 -------------------------------------------------------------------------------------------------
319− convertRecursiveFns cpps
319+ convertRecursiveFns cpps otherCpp
320− | not $ null fns = dict : (accessor topdict <$> fns) ++ (everywhereOnCpp removeRec <$> cpps)
320+ | not $ null fns = dict : (accessor topdict <$> filteredFns allCpps) ++ cpps'
321 where
321 where
322+ cpps' = everywhereOnCpp removeRec <$> cpps
323+ allCpps = CppBlock $ otherCpp : cpps'
324+
322 fns :: [(String, Cpp)]
325 fns :: [(String, Cpp)]
323 fns = toelem <$> concatMap (everythingOnCpp (++) recursive) cpps
326 fns = toelem <$> concatMap (everythingOnCpp (++) recursive) cpps
324
327
328+ filteredFns :: Cpp -> [(String, Cpp)]
329+ filteredFns cpp = filter (\(f,_) -> everythingOnCpp (||) (== CppVar f) cpp) fns
330+
325 recursive :: Cpp -> [Cpp]
331 recursive :: Cpp -> [Cpp]
326 recursive cpp'@(CppFunction _ _ _ qs _) | CppRecursive `elem` qs = [cpp']
332 recursive cpp'@(CppFunction _ _ _ qs _) | CppRecursive `elem` qs = [cpp']
327 recursive _ = []
333 recursive _ = []
@@ -334,7 +340,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
334 dict = CppVariableIntroduction
340 dict = CppVariableIntroduction
335 (topdict, Just $ CppAny [CppConst])
341 (topdict, Just $ CppAny [CppConst])
336 []
342 []
337− (Just $ CppObjectLiteral fns)
343+ (Just $ CppDataLiteral ((\(f,cpp) -> CppComment [LineComment f] cpp) <$> fns))
338
344
339 accessor :: String -> (String, Cpp) -> Cpp
345 accessor :: String -> (String, Cpp) -> Cpp
340 accessor dictname (name, _) =
346 accessor dictname (name, _) =
@@ -344,15 +350,23 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
344 (Just accessed)
350 (Just accessed)
345 where
351 where
346 dict' = CppVar dictname
352 dict' = CppVar dictname
353+ dict'' = CppCast dataType dict'
347− accessed = CppApp (CppIndexer (CppStringLiteral name) dict') [dict']
354+ accessed = CppApp
355+ (CppIndexer
356+ (CppNumericLiteral .
357+ Left .
358+ fromIntegral .
359+ fromJust $ findIndex ((== name) . fst) fns)
360+ dict'')
361+ [dict']
348
362
349 toelem :: Cpp -> (String, Cpp)
363 toelem :: Cpp -> (String, Cpp)
350− toelem (CppFunction name args rtyp _ (CppBlock body)) =
364+ toelem (CppFunction name args rtyp _ body'@(CppBlock body)) =
351 (name, withdict . maybeRemCaps $ CppLambda
365 (name, withdict . maybeRemCaps $ CppLambda
352 [CppCaptureAll]
366 [CppCaptureAll]
353 args
367 args
354 rtyp
368 rtyp
355− (CppBlock $ (accessor localdict <$> fns) ++ body))
369+ (CppBlock $ (accessor localdict <$> filteredFns body') ++ body))
356 toelem _ = error "not a function"
370 toelem _ = error "not a function"
357
371
358 withdict :: Cpp -> Cpp
372 withdict :: Cpp -> Cpp
@@ -362,11 +376,11 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
362 (Just $ CppAny [])
376 (Just $ CppAny [])
363 (asReturnBlock cpp')
377 (asReturnBlock cpp')
364 topdict :: String
378 topdict :: String
365− topdict = "__dict__"
379+ topdict = "_$dict$_"
366 localdict :: String
380 localdict :: String
367− localdict = "_dict_"
381+ localdict = "$dict$"
368
382
369− convertRecursiveFns cpps = cpps
383+ convertRecursiveFns cpps _ = cpps
370
384
371 -- |
385 -- |
372 -- Generate code in the simplified C++1x intermediate representation for a value or expression.
386 -- Generate code in the simplified C++1x intermediate representation for a value or expression.
@@ -486,7 +500,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
486 opts <- ask
500 opts <- ask
487 let ds'' = tco opts <$> ds'
501 let ds'' = tco opts <$> ds'
488 let rs = if hasRecursion ds''
502 let rs = if hasRecursion ds''
489− then convertRecursiveFns ds''
503+ then convertRecursiveFns ds'' ret
490 else ds''
504 else ds''
491 let cpps = convertNestedLambdas <$> rs
505 let cpps = convertNestedLambdas <$> rs
492 return $ CppApp
506 return $ CppApp