[<<][meta][>>][..]
Mon Aug 1 18:38:14 CEST 2011
Sharing
f3 x = let xx = x * x in xx * xx
*Main> f3 1 :: SSA Tfloat
R0 = fmul 1.0 1.0
R1 = fmul 1.0 1.0
R2 = fmul R0 R1
R2
Why isn't "fmul 1.0 1.0" shared? Or, a bit more obvious:
f4 x = let x1 = x * x in
let x2 = x1 * x1 in
let x3 = x2 * x2 in
x3 * x3
*Main> f4 1 :: SSA Tfloat
R0 = fmul 1.0 1.0
R1 = fmul 1.0 1.0
R2 = fmul R0 R1
R3 = fmul 1.0 1.0
R4 = fmul 1.0 1.0
R5 = fmul R3 R4
R6 = fmul R2 R5
R7 = fmul 1.0 1.0
R8 = fmul 1.0 1.0
R9 = fmul R7 R8
R10 = fmul 1.0 1.0
R11 = fmul 1.0 1.0
R12 = fmul R10 R11
R13 = fmul R9 R12
R14 = fmul R6 R13
R14
Why doesn't this share anything, while there is threading going on?
f5 x = let_ (x * x) $ \x1 ->
let_ (x1 * x1) $ \x2 ->
let_ (x2 * x2) $ \x3 ->
x3 * x3
*Main> f5 1 :: SSA Tfloat
R0 = fmul 1.0 1.0
R1 = let R0
R2 = let R0
R3 = fmul R1 R2
R4 = let R3
R5 = let R3
R6 = fmul R4 R5
R7 = let R6
R8 = let R6
R9 = fmul R7 R8
This is correct apart from the copying of variables.
The right implementation of let_ seems to be:
let' (SSA x) body = SSA $ do
vx <- x
lowerSSA body $ return vx
Or with wrapping expanded:
let' (SSA x) body = SSA $ do
vx <- x
unSSA $ body $ SSA $ return vx
Is all that wrapping/unwrapping necessary? It might be simpler to
define SSA as a monad.
I came to the following explanation, which could be worded better but
I believe does hint at what's going on:
The idea is that in let' the monadic variable x is only
"dereferenced" once, which would not be the case for an ordinary
let expression which would run a computation multiple times.
[Reply][About]
[<<][meta][>>][..]