When does GHC produce unlifted `let` bindings?

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

When does GHC produce unlifted `let` bindings?

Sebastian Graf
Hi folks,

I was debugging a Core-to-Core transform for TEST=spec-inline and was wondering (yet again) why GHC produces unlifted `let` bindings in Core like it seems supposed to be doing.
  • Why doesn't this use `case` instead? 
  • Is there a semantic difference? 
  • Can `case` be used with unlifted types? 
  • And if not, why can `let`?
Unlifted `let` seems much close to `case` than to `let`. Some GHC passes seem to agree.

Cheers,
Sebastian

_______________________________________________
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: When does GHC produce unlifted `let` bindings?

Ben Gamari-2


Sebastian Graf <[hidden email]> writes:

> Hi folks,
>
> I was debugging a Core-to-Core transform for TEST=spec-inline
> <https://github.com/ghc/ghc/blob/fe04f3783b662c52c4a0ff36b2d62a7a575998a5/testsuite/tests/simplCore/should_compile/spec-inline.hs>
> and
> was wondering (yet again) why GHC produces unlifted `let` bindings in Core
> like it seems supposed to be doing
> <https://github.com/ghc/ghc/blob/fe04f3783b662c52c4a0ff36b2d62a7a575998a5/testsuite/tests/simplCore/should_compile/spec-inline.stderr#L68-L76>
> .
>
>    - Why doesn't this use `case` instead?
>    - Is there a semantic difference?
My understanding is that we use `case` in this case since there is no
thunk evaluation necessary. Recall that operationally (under STG) `case`
is what drives evaluation whereas `let` is simply allocation. In a
sense, bringing an unlifted binding into scope is closer to the latter
than the former, being a simple register assignment.

>    - Can `case` be used with unlifted types?

I'm honestly not sure what would happen in this case. It may work fine
or something may explode. I suspect CoreToStg will lower a case with an
unlifted scrutinee to a let, but perhaps not. If not then things likely
will blow up since, according to Note [Types in StgConApp], unlifted
values can't be let-bound in STG.

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: When does GHC produce unlifted `let` bindings?

GHC - devs mailing list
In reply to this post by Sebastian Graf

See Note [CoreSyn let/app invariant] in CoreSyn.

 

Briefly, you can write

            let x::Int# = e in …

if e is “ok-for-speculation”.  See extensive comments in CoreUtils on what that means.

 

You could also use case, but let-bindings “float” more easily than cases, because they are not worried about preserving exception behaviour.

 

Simon

 

From: ghc-devs [mailto:[hidden email]] On Behalf Of Sebastian Graf
Sent: 29 October 2017 21:07
To: ghc-devs <[hidden email]>
Subject: When does GHC produce unlifted `let` bindings?

 

Hi folks,

 

I was debugging a Core-to-Core transform for TEST=spec-inline and was wondering (yet again) why GHC produces unlifted `let` bindings in Core like it seems supposed to be doing.

  • Why doesn't this use `case` instead? 
  • Is there a semantic difference? 
  • Can `case` be used with unlifted types? 
  • And if not, why can `let`?

Unlifted `let` seems much close to `case` than to `let`. Some GHC passes seem to agree.

 

Cheers,

Sebastian


_______________________________________________
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: When does GHC produce unlifted `let` bindings?

Sebastian Graf
Thanks both of you, that makes sense.

Re: let-bindings floating more easily, would a check for `exprIsOkForSpeculation scrut` in theory suffice to float out cases?

On Mon, Oct 30, 2017 at 10:56 AM, Simon Peyton Jones <[hidden email]> wrote:

See Note [CoreSyn let/app invariant] in CoreSyn.

 

Briefly, you can write

            let x::Int# = e in …

if e is “ok-for-speculation”.  See extensive comments in CoreUtils on what that means.

 

You could also use case, but let-bindings “float” more easily than cases, because they are not worried about preserving exception behaviour.

 

Simon

 

From: ghc-devs [mailto:[hidden email]] On Behalf Of Sebastian Graf
Sent: 29 October 2017 21:07
To: ghc-devs <[hidden email]>
Subject: When does GHC produce unlifted `let` bindings?

 

Hi folks,

 

I was debugging a Core-to-Core transform for TEST=spec-inline and was wondering (yet again) why GHC produces unlifted `let` bindings in Core like it seems supposed to be doing.

  • Why doesn't this use `case` instead? 
  • Is there a semantic difference? 
  • Can `case` be used with unlifted types? 
  • And if not, why can `let`?

Unlifted `let` seems much close to `case` than to `let`. Some GHC passes seem to agree.

 

Cheers,

Sebastian



_______________________________________________
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: When does GHC produce unlifted `let` bindings?

GHC - devs mailing list

Re: let-bindings floating more easily, would a check for `exprIsOkForSpeculation scrut` in theory suffice to float out cases?

 

Yes; but instead we simply turn such cases into lets.

 

Simon

 

From: Sebastian Graf [mailto:[hidden email]]
Sent: 02 November 2017 08:33
To: Simon Peyton Jones <[hidden email]>
Cc: ghc-devs <[hidden email]>
Subject: Re: When does GHC produce unlifted `let` bindings?

 

Thanks both of you, that makes sense.

 

Re: let-bindings floating more easily, would a check for `exprIsOkForSpeculation scrut` in theory suffice to float out cases?

 

On Mon, Oct 30, 2017 at 10:56 AM, Simon Peyton Jones <[hidden email]> wrote:

See Note [CoreSyn let/app invariant] in CoreSyn.

 

Briefly, you can write

            let x::Int# = e in …

if e is “ok-for-speculation”.  See extensive comments in CoreUtils on what that means.

 

You could also use case, but let-bindings “float” more easily than cases, because they are not worried about preserving exception behaviour.

 

Simon

 

From: ghc-devs [mailto:[hidden email]] On Behalf Of Sebastian Graf
Sent: 29 October 2017 21:07
To: ghc-devs <[hidden email]>
Subject: When does GHC produce unlifted `let` bindings?

 

Hi folks,

 

I was debugging a Core-to-Core transform for TEST=spec-inline and was wondering (yet again) why GHC produces unlifted `let` bindings in Core like it seems supposed to be doing.

  • Why doesn't this use `case` instead? 
  • Is there a semantic difference? 
  • Can `case` be used with unlifted types? 
  • And if not, why can `let`?

Unlifted `let` seems much close to `case` than to `let`. Some GHC passes seem to agree.

 

Cheers,

Sebastian

 


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