[Haskell] unsafePerformIO and optimizations
Wolfgang Jeltsch
wolfgang at jeltsch.net
Sat Aug 6 10:23:58 EDT 2005
Hello,
http://haskell.org/ghc/docs/latest/html/libraries/base/
System.IO.Unsafe.html#v%3AunsafePerformIO
talks about what optimizations you should disable if you apply unsafePerformIO
to an action which contains side effects. These are:
* inlining of functions which call unsafePerformIO
* common subexpression elimination (on the module which contains the
unsafePerformIO application, if I understand correctly)
* let-floating
Alas, the documentation is very terse, in my opinion, and I don't understand
these things fully.
First, what is the problem with inlining a function call? Say, I have a
function f defined as follows:
f :: Char -> ()
f c = unsafePerformIO (putChar c)
If inlining is allowed, the expression f '*' becomes
unsafePerformIO (putChar '*').
Is this a problem? Or is inlining dangerous in other situations?
On the other hand, I can see that inlining non-functions could cause harm.
Say I have something like this:
u :: ()
u = unsafePerformIO (putChar '*')
Now, inlining u would transform (u,u) to
(unsafePerformIO (putChar '*),unsafePerformIO (putChar '*'))
which could result in putChar '*' being executed multiple times. So why does
the library documentation only talk about disabling inlining of functions?
I understand that common subexpression elimination could cause harm. It could
transform the expression
(unsafePerformIO (putChar '*),unsafePerformIO (putChar '*'))
to
let
u = unsafePerformIO (putChar '*')
in
(u,u),
couldn't it? This would result in the I/O action be performed at most once
which is not what was intended. But couldn't the same thing also happen if I
use the expression (f '*',f '*'), probably in a different module? Does this
mean that I have to use -fno-cse not only in the module which contains the
unsafePerformIO application but also in every other module which uses
unsafePerformIO indirectly via f or functions using f?
Does let-floating only have to be disabled in the module which uses
unsafePerformIO? Say, I have f defined as above and have the following
definition in a module different from the one f is defined in:
g :: Int -> ()
g n = f '*'
Couldn't it be that the asterisk is output only once instead of every time, g
is called?
I would be thankful for any help.
Best regards,
Wolfgang
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users at haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
More information about the Haskell
mailing list