let app invariant failure, HALP Re: how to write a ghc primop that acts on an unevaluated argument?

Carter Schonwald carter.schonwald at gmail.com
Tue Nov 25 06:47:13 UTC 2014


ok attached is the log of
./inplace/bin/ghc-stage2 codetester.hs  -O2 -dcore-lint  -fforce-recomp
-ddump-simpl -ddump-to-file -dverbose-core2core -ddump-occur-anal
-ddump-inlinings  > output ^&1


the relevant snippet is bellow.

It looks like the Float-Out transformation is what tripping it.


That said, reading through what the semantics are implied by
has_side_effects = True, the prefetch* family of operations ARE side
effectful with respect the fact that they DO modify the CPU cache in a way
that changes what memory locations are in various levels of CPU cache, so
despite seeming read-like, they are modifying the state of the system, just
in a way that is ONLY visible wrt the performance characteristics/runtime
 of the resulting program.

specifically, Duplication, Floating out, and Specultive evaluation all
change *when* the prefetch runs and changes the CPU state, and Discard
means this "mutation" of the CPU cache state would not happen.

if prefetch was pure semantically (ie equiv to a -> ()  ) , they'd just be
no op, they're exclusively a tool for performance engineering, and
accordingly when and where they appear in code matters!

i'm more than happy to write out a more detailed version of this
explanation somewhere if you like.

-Carter

""""

*** Core Linted result of Simplifier:
*** Float out(FOS {Lam = Just 0, Consts = True, OverSatApps = True}):
*** Core Linted result of Float out(FOS {Lam = Just 0, Consts = True,
OverSatApps = True}):
*** Core Lint errors : in result of Float out(FOS {Lam = Just 0,
                                                   Consts = True,
                                                   OverSatApps = True}) ***
<no location info>: Warning:
    In the expression: prefetchValue2#
                         @ [Char]
                         @ RealWorld
                         lvl_s3Oi
                         (prefetchValue1#
                            @ Int
                            @ RealWorld
                            lvl_s3Oj
                            (prefetchAddr3# @ RealWorld ds1_a3zg 0 ds_a3zf))
    This argument does not satisfy the let/app invariant:
      prefetchValue1#
        @ Int
        @ RealWorld
        lvl_s3Oj


"""



On Mon, Nov 24, 2014 at 10:43 PM, Carter Schonwald <
carter.schonwald at gmail.com> wrote:

> huh, apparently i was mixing up '-' and some other similar dash character,
> time to let my rebuild of ghc go through then try gain :)
>
> On Mon, Nov 24, 2014 at 10:37 PM, Carter Schonwald <
> carter.schonwald at gmail.com> wrote:
>
>> when i run
>> ./inplace/bin/ghc-stage2 codetester.hs  -O2 -dcore-lint -S
>>  -fforce-recomp -ddump-simpl -ddump-to-file –dverbose-core2core
>> –ddump-occur-anal –ddump-inlinings
>> i get
>> target ‘–dverbose-core2core’ is not a module name or a source file
>>
>> what am I doing wrong in this CLI invocation?
>>
>> On Mon, Nov 24, 2014 at 10:23 AM, Simon Peyton Jones <
>> simonpj at microsoft.com> wrote:
>>
>>>  Carter
>>>
>>>
>>>
>>> That smells wrong to me.  These flags have a very carefully defined
>>> meaning; see
>>>
>>>             Note [PrimOp can_fail and has_side_effects]
>>>
>>> in PrimOp.lhs
>>>
>>>
>>>
>>> If you say it has side effects when it doesn’t, you’ll confuse your
>>> successor reading the code in five years time.
>>>
>>>
>>>
>>> Better to find out what is going on and why.  Might you do that? What
>>> transformation invalidates the let/app invariant?  Make a small test case,
>>> use –dverbose-core2core –ddump-occur-anal –ddump-inlinings.  I would far
>>> rather that than install a land-mine in the code.
>>>
>>>
>>>
>>> Simon
>>>
>>>
>>>
>>> *From:* Carter Schonwald [mailto:carter.schonwald at gmail.com]
>>> *Sent:* 24 November 2014 00:54
>>> *To:* Edward Kmett
>>> *Cc:* ghc-devs at haskell.org; Simon Peyton Jones; Joachim Breitner
>>> *Subject:* Re: let app invariant failure, HALP Re: how to write a ghc
>>> primop that acts on an unevaluated argument?
>>>
>>>
>>>
>>> woot, solved it, at least in a way thats OK for now.
>>>
>>>
>>>
>>> if I mark the prefetchValue operations as has_side_effects=True, the
>>> core lint failure goes away! I'm not sure if thats the right semantics in
>>> the long term, but it does give me a simple way to make sure it works
>>> safely for 7.10
>>>
>>>
>>>
>>> pardon all the noise
>>>
>>> -Carter
>>>
>>>
>>>
>>> On Sun, Nov 23, 2014 at 4:26 PM, Carter Schonwald <
>>> carter.schonwald at gmail.com> wrote:
>>>
>>>  ok, i'm getting a let/app invariant failure when i build my test case
>>> with O1 or O2 but not without
>>>
>>>
>>>
>>> http://lpaste.net/114881
>>>
>>>
>>>
>>> any help would be appreciated on how to address that
>>>
>>>
>>>
>>> On Sun, Nov 23, 2014 at 4:13 PM, Carter Schonwald <
>>> carter.schonwald at gmail.com> wrote:
>>>
>>>  yup, i have that!
>>>
>>>
>>>
>>>     wrapFetch prefetchValue0# (error "this shouldn't get evaluated")
>>>
>>>
>>>
>>> in the test suite!
>>>
>>>
>>>
>>> in contrast
>>>
>>>     wrapFetch prefetchValue0# $! (error "this shouldn't get evaluated")
>>> does explode
>>>
>>>
>>>
>>> shall I add a "should fail" test with the latter? (it doesn't seem
>>> worthwhile)
>>>
>>>
>>>
>>> On Sun, Nov 23, 2014 at 3:53 PM, Edward Kmett <ekmett at gmail.com> wrote:
>>>
>>>  Maybe test for laziness in the argument by just putting something in
>>> that goes boom when forced, e.g. 'undefined'?
>>>
>>>
>>>
>>>
>>>
>>> On Sun, Nov 23, 2014 at 2:04 PM, Carter Schonwald <
>>> carter.schonwald at gmail.com> wrote:
>>>
>>>   Hey All,
>>>
>>> as part of trying to get some fixups for how prefetch works into 7.10,
>>>
>>> i'm adding a "prefetchValue" primop that prefetchs the memory location
>>> of a lifted heap value
>>>
>>>
>>>
>>> namely
>>>
>>>
>>>
>>> several operations of the following form
>>>
>>>
>>>
>>> primop PrefetchValueOp1 "prefetchValue1#" GenPrimOp
>>>
>>>    a -> State# s -> State# s
>>>
>>>    with strictness  = { \ _arity -> mkClosedStrictSig [botDmd, topDmd]
>>> topRes }
>>>
>>>
>>>
>>> I'd like some feedback on the strictness information design by someone
>>> who's familiar with how that piece of GHC. the idea being that
>>> prefetchValue is lazy in its polymorphic argument (it doesn't force it, it
>>> just does a prefetch on the heap location, which may or may not be
>>> evaluated).
>>>
>>>
>>>
>>> https://phabricator.haskell.org/D350
>>>
>>>
>>>
>>> is the code in question. And i *believe* i'm testing for being lazy in
>>> that argument correctly.
>>>
>>>
>>>
>>> thoughts?
>>>
>>>
>>>
>>> many thanks!
>>>
>>> -Carter
>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> ghc-devs mailing list
>>> ghc-devs at haskell.org
>>> http://www.haskell.org/mailman/listinfo/ghc-devs
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20141125/da2b38ba/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: output
Type: application/octet-stream
Size: 115111 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20141125/da2b38ba/attachment-0001.obj>


More information about the ghc-devs mailing list