Why doesn’t the simple optimizer fuse casts?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Why doesn’t the simple optimizer fuse casts?

Alexis King
This question is spurred by curiosity more than anything else, but
I’ve noticed that the simple optimizer doesn’t fuse nested casts, and
I’m wondering if there’s any reason it couldn’t. To make what I’m
talking about more concrete, suppose we have an expression like this:

    (x |> co) |> sym co

It seems like it would be trivial for simpleOptExpr to fuse the nested
casts to get

    x |> co; sym co

and then the coercion optimizer could get rid of it entirely.
Moreover, this seems within the spirit of the simple optimizer, since
it’s really just “cleaning up” an expression. Is there any reason the
simple optimizer doesn’t do this, or is it just something nobody
implemented?

(For context, I’ve recently been staring at a lot of -ddump-ds output,
and there happen to be a bunch of nested casts in the result that are
really just noise. It would be nice if the simple optimizer got rid of
them for me.)

Alexis
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: Why doesn’t the simple optimizer fuse casts?

Richard Eisenberg-5
Hi Alexis,

Nested casts shouldn't happen. The mkCast function gets rid of them. Someone somewhere is forgetting to call it. If you have a concrete program that leads to nested casts, post a bug report. :)

Thanks!
Richard

> On Apr 27, 2020, at 8:29 PM, Alexis King <[hidden email]> wrote:
>
> This question is spurred by curiosity more than anything else, but
> I’ve noticed that the simple optimizer doesn’t fuse nested casts, and
> I’m wondering if there’s any reason it couldn’t. To make what I’m
> talking about more concrete, suppose we have an expression like this:
>
>    (x |> co) |> sym co
>
> It seems like it would be trivial for simpleOptExpr to fuse the nested
> casts to get
>
>    x |> co; sym co
>
> and then the coercion optimizer could get rid of it entirely.
> Moreover, this seems within the spirit of the simple optimizer, since
> it’s really just “cleaning up” an expression. Is there any reason the
> simple optimizer doesn’t do this, or is it just something nobody
> implemented?
>
> (For context, I’ve recently been staring at a lot of -ddump-ds output,
> and there happen to be a bunch of nested casts in the result that are
> really just noise. It would be nice if the simple optimizer got rid of
> them for me.)
>
> Alexis
> _______________________________________________
> ghc-devs mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: Why doesn’t the simple optimizer fuse casts?

Alexis King
Hi Richard,

Nested casts can absolutely happen after the simple optimizer runs.
Suppose we produce a desugared expression like:

    let { y = x `cast` co1 } in y `cast` co2

The simple optimizer will inline y, since it only appears once, so now
we have a nested cast. Perhaps you mean you expect the casts to be
merged when the simple optimizer gets to the Cast expression itself,
but they aren’t, as it doesn’t use mkCast to reconstruct the result:

    -- from GHC.Core.SimpleOpt.simple_opt_expr
    go (Cast e co)      | isReflCo co' = go e
                        | otherwise    = Cast (go e) co'

I suppose a really simple fix would be to just use mkCast here instead
of Cast, but that wouldn’t be completely satisfying, since the merged
coercion wouldn’t be optimized. So you’d have to do something slightly
more complicated to detect if the result of `go e` was a cast
expression and combine the coercions before calling optCoercion.

Whether or not doing that would be a good idea is precisely what I’m
asking about. :)

Alexis

> On Apr 27, 2020, at 16:22, Richard Eisenberg <[hidden email]> wrote:
>
> Hi Alexis,
>
> Nested casts shouldn't happen. The mkCast function gets rid of them.
> Someone somewhere is forgetting to call it. If you have a concrete
> program that leads to nested casts, post a bug report. :)
>
> Thanks!
> Richard
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: Why doesn’t the simple optimizer fuse casts?

Ben Gamari-2
Alexis King <[hidden email]> writes:

...

> Whether or not doing that would be a good idea is precisely what I’m
> asking about. :)
>
Sounds like it would be worth a quick try. Given that this will get hit
by the simplifier eventually anyways I suspect it won't make much of a
difference one way or the other. That being said, I've been wrong before...

Cheers,

- Ben


_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

signature.asc (497 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Why doesn’t the simple optimizer fuse casts?

Richard Eisenberg-5


On Apr 28, 2020, at 1:07 AM, Ben Gamari <[hidden email]> wrote:

Sounds like it would be worth a quick try.

I agree with Ben. I generally expect not to see nested casts -- the Cast constructor should rarely (never?) appear as an expression outside of mkCast. But you're right about the missing optimization opportunity if we do the naive thing.

Let us know if you run into trouble with the "quick try"!

Richard

_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

RE: Why doesn’t the simple optimizer fuse casts?

GHC - devs mailing list
In reply to this post by Alexis King
Good spot.  The very simple optimiser is, well, very simple.   So let's not do anything complicated.

But could you submit a ticket, and patch, to replace that Cast with mkCast?  Thanks!

Simon

|  -----Original Message-----
|  From: ghc-devs <[hidden email]> On Behalf Of Alexis King
|  Sent: 27 April 2020 22:58
|  To: Richard Eisenberg <[hidden email]>
|  Cc: ghc-devs <[hidden email]>
|  Subject: Re: Why doesn’t the simple optimizer fuse casts?
|  
|  Hi Richard,
|  
|  Nested casts can absolutely happen after the simple optimizer runs.
|  Suppose we produce a desugared expression like:
|  
|      let { y = x `cast` co1 } in y `cast` co2
|  
|  The simple optimizer will inline y, since it only appears once, so now
|  we have a nested cast. Perhaps you mean you expect the casts to be
|  merged when the simple optimizer gets to the Cast expression itself,
|  but they aren’t, as it doesn’t use mkCast to reconstruct the result:
|  
|      -- from GHC.Core.SimpleOpt.simple_opt_expr
|      go (Cast e co)      | isReflCo co' = go e
|                          | otherwise    = Cast (go e) co'
|  
|  I suppose a really simple fix would be to just use mkCast here instead
|  of Cast, but that wouldn’t be completely satisfying, since the merged
|  coercion wouldn’t be optimized. So you’d have to do something slightly
|  more complicated to detect if the result of `go e` was a cast
|  expression and combine the coercions before calling optCoercion.
|  
|  Whether or not doing that would be a good idea is precisely what I’m
|  asking about. :)
|  
|  Alexis
|  
|  > On Apr 27, 2020, at 16:22, Richard Eisenberg <[hidden email]> wrote:
|  >
|  > Hi Alexis,
|  >
|  > Nested casts shouldn't happen. The mkCast function gets rid of them.
|  > Someone somewhere is forgetting to call it. If you have a concrete
|  > program that leads to nested casts, post a bug report. :)
|  >
|  > Thanks!
|  > Richard
|  _______________________________________________
|  ghc-devs mailing list
|  [hidden email]
|  https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmail.has
|  kell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fghc-
|  devs&amp;data=02%7C01%7Csimonpj%40microsoft.com%7C825fe41065dd450030e908d
|  7eaf61d19%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637236215077850647
|  &amp;sdata=w%2Fk4JG%2FOmpwPoUAAGqdC62ssQSYcLQioY8T9%2BZ3XS8E%3D&amp;reser
|  ved=0
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs