Thanks SimonM for answering my question!
To give more details:
* ticks should be done on *entry* to a expression, not exit.
so what is the strictness of
tick<n> e
?
If you mark tick as strict in e, then e might be explicitly pre-
evaluated (and perhaps throw an exception, before being ticked).
If you mark tick as lazy in e, then we build many, many thunks, and
disable almost every optimization. (slowdown of ~30).
But
case tick<n> of
DEFAULT -> e
does exactly the Right Thing!
* I've seen the double tick-merge happen. Its not a big deal, as it
reflect sharing anyway. I compared
the output of a large program, before and after the change, and this
merging and one other trivial
difference was the only change in tix info. All within the scope of
our Haskell semantics under
optimizations.
* We need have binary tick boxes so that we can have accurate branch
counts, because I want to use this
information for optimization purposes later. Can imagine the inliner
using Hpc information to drive inlining :-)
The problem that
tick<n> True
Is CAF-able. So
case expr of
True -> tick<n> True
False -> tick<n> False
Only gives 1 or 0 answers.
* I've started a wikipage, as requested.
http://hackage.haskell.org/trac/ghc/wiki/Commentary/Hpc
It is not under .../compiler, because it is crosscutting, and
includes RTS changes.
Feel free to add questions; just mark them QTA: (question to Author/
Authority).
("QTA:" might be a good annotation for the wiki. If you fill
something, and are not 100% sure,
you can QTA: a question, and we can search for unanswered QTAs. The
Author/Authority would
change the page, answering the question or putting in a link.)
Andy
On Dec 4, 2006, at 1:52 AM, Simon Marlow wrote:
Simon Peyton-Jones wrote:
I had a look at what you did. Generally looks good. Much better
than the Note version, as I hope you agree! (You seem to have
deleted quite a bit of code!)
Here's a qn. I thought you were going to do ticks like this:
dsExpr (HsTick a e) = tick{a} e
but instead you have
dsExpr (HsTick a e) = case tick{a} of DEFAULT -> e
I think that both are probably fine, but the implications are not
clear to me.
It's perhaps because I suggested we use the case form. If we had
tick{a} e
then we really don't want e compiled to a thunk. So somehow this
must turn into the case form in the back end:
case tick{a} of DEFAULT -> e
but just declaring tick{a} to be strict won't do this: it'll give you
case e of DEFAULT -> tick{a} e
Perhaps this still works, I don't know. To me it seems like a
longer way around; the case form more directly says what you want
to happen. But maybe I'm missing something?
The former seems more robust somehow. For example if we have
case tick{a} of DEFAULT -> ....(case tick{a} of DEFAULT -
> ...)
GHC might eliminate the inner tick. Would that be OK (after all,
you're only checking coverage, and it's covered)?
One of the suggestions was to use a PrimOp (like the foreign call
op) for tick, which would prevent the simplifier from eliminating
the inner tick because the PrimOp would be declared as having side
effects.
Cheers,
Simon
_______________________________________________
Cvs-ghc mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/cvs-ghc