[Haskell-cafe] evaluating CAFs at compile time

Carter Schonwald carter.schonwald at gmail.com
Sun Jan 19 00:25:25 UTC 2014


evan, could you share a minimal example of the code that illustrates your
problem? It may be that theres
a) an alternative way to write it that that gives the
perf characteristics you want
b) it could be a good example for future ghc optimization efforts
c) other

-Carter


On Sat, Jan 18, 2014 at 7:14 PM, Evan Laforge <qdunkan at gmail.com> wrote:

> So I have a large CAF which is expensive to generate.  Theoretically
> it should be possible to totally evaluate at compile time, resulting
> in a bunch of constructor calls, ideally totally de-thunked and in the
> read-only segment of the binary.
>
> In the absence of a "eval at compile time" pragma, it seemed like TH
> should be able to do this, and searching haskell-cafe I turned up an
> old post by Wren where he is doing basically that, and eventually
> discovered the Lift class in
>
> http://hackage.haskell.org/package/template-haskell-2.8.0.0/docs/Language-Haskell-TH-Syntax.html
>
> However, if I understand Lift correctly (and not really understanding
> much of TH), you need to create instances for every type you wish to
> generate, which seems like it would be a pain.  Even if they can be
> automatically derived, it would spread TH dependency gunk throughout
> the whole program.  Is this true?  Is there a library that does the
> equivalent of a "eval at compile time" pragma? (Wren's proposed QAF
> library seems to have never made it to hackage, but maybe given Lift
> and the proper instances it turns out to be trivial.)  Would it be
> possible or desirable for an actual pragma that wouldn't introduce a
> TH dependency?
>
> Also, I assume it would produce a giant set of constructor
> applications which ghc would then optimize as well as it can...  but
> it seems like that might not include full strictness, since even 'x =
> (4, undefined)' is obliged to not diverge as long as you don't look at
> the snd field, so even a large literal expression is actually
> unevaluated code if there are some non-strict data types in there.
>
> And... is it actually possible for ghc to do clever optimization with
> constant values, i.e. lay them out fully evaluated in read-only
> memory?  I know that something like 'x = "abc" ++ "def"' will wind up
> as 'unpackCString# "abcdef"', but I'm curious what happens to more
> complicated data structures.  Strictness seems to make a difference,
> e.g. with nonstrict fields the core has separate bindings for the
> contained values, while with strict ones the values get inlined
> directly into the consumer of the data type and the constructor is
> nowhere to be seen.  But if the type is recursive (data X = X Int
> (Maybe X)), then we wind up with CAFs applying it, though they have
> lots of provocative flags that indicate ghc knows it's dealing with
> constructors:
>
>  Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
>          ConLike=True, WorkFree=False, Expandable=True,
>          Guidance=IF_ARGS [] 10 30}]
>
> I assume it still can't hoist the undefined to the entire expression
> though, because of non-strictness.  I would think that if all data
> types are strict, then it could transform 'caf = X 42 (StrictJust (X
> 24 undefined))' to 'caf = undefined', but that doesn't seem to happen
> either.
>
> Tangentially, I've noticed that the 'unpackCString# "abcdef"'
> optimization is limited to String, replacing it with Text produces
> "abc" + giant wodge of code that is presumably appending "def" at
> runtime.  I'm sure I've seen some discussions around here about
> wanting to optimize string literals to 'Text 0 len (giant chunk of
> binary data)', but I don't think they talked about possible compile
> time evaluation... presumably it could also solve that problem?
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20140118/1e29790b/attachment.html>


More information about the Haskell-Cafe mailing list