Is there a way to optimize out some foreign calls?
Brian Hulley
brianh at metamilk.com
Tue Apr 4 11:20:05 EDT 2006
H -
I'm wondering if there is any way to specify that certain sequences of
foreign calls can be merged into a single foreign call. For example, in a
common situation where a state of a foreign API is pushed and popped so that
the previous state is restored, I'd like successive pops to avoid wasting
time restoring intermediate states as in:
-- push a state onto the API's state stack (without changing the state)
foreign import ccall api_push :: State -> IO ()
-- discards the state at the top of the stack
foreign import ccall api_pop :: IO ()
-- synchronises the API's state with the state at the top of the stack
foreign import ccall api_sync :: IO ()
use :: State -> IO () -> IO ()
use s action = do
api_push s
api_sync
action
api_pop
api_sync -- put the API back into the previous state
main = do
use State1 $ do
actionIn1a
use State2 $ do
actionIn2
use State3 $ do
actionIn3
actionIn1b
If 'use' is inlined, the compiler would (presumably) produce code like:
main = do
api_push State1
api_sync
actionIn1a
api_push State2
api_sync
actionIn2
api_push State3
api_sync
actionIn3
api_pop
api_sync -- This is a waste of time
api_pop
api_sync
actionIn1b
api_pop
api_sync
I'm wondering if there is any way to cause the compiler to avoid the
wasteful call to api_sync above.
I'm thinking in terms of some way of marking foreign functions to specify
how they can be optimized out or specifying rewrite sequences eg
x >> api_sync >> api_pop >> api_sync >> y = x >> api_pop >>
api_sync >> y
I've read the manual (7.10) on rewrite rules, but I'm having difficulty
understanding how to express the lhs of the above equation as a rewrite rule
so that it matches a sequence anywhere in a do block (to deal with nested
parentheses and the use of >>= instead of >>)
Any ideas?
Thanks, Brian.
More information about the Glasgow-haskell-users
mailing list