Can you give an example?

Generally the wrapper does stuff like evaluating arguments for a strict 
constructor, and unboxing UNPACKed fields.  So if you have
            data T = MkT ! {-# UNPACK #-} Int

the wrapper looks something like this

            $WMkT x = case x of I# y -> MkT y

That is, it evaluates and unboxes the argument.   The source-language reference 
to MkT gets replaced with a call to the wrapper.

In a RULE suppose you write
            f (MkT x) = …blah…
and have a call
            …f (MkT e)….

After replacing MkT by its wrapper call we’d have
            RULE  f ($WMkT x) = ...blah...
and      ....f ($WMkT e)....

Now if the wrapper for MkT is inlined, we’ll see (f (case e of …)) which won’t 
match well!

At the moment, the very first run of the simplifier has almost all inlinings 
switched off, so the rule will indeed have a chance to fire.  But (a) I want to 
change the early simplifier run to do more inlining, and (b) in any case it all 
fails if you had, say
            ...f (h x)....
where
            h x = $WMkT e
Here you want h to inline, exposing the opportunity for the rule to fire.  I 
don’t know if this is the source of your problem, but it might be.

The usual solution to the interaction between RULES and inlining is to delay 
inlining until the rule has had a chance to fire. But in this case the inlining 
isn’t under your control: it’s the wrapper for MkT.

Something very similar happens for the wrappers after strictness analysis; if 
an (automatically generated, INLINE) wrapper is inlined too early, a rule might 
not fire.  The crude but effective solution for strictness wappers is to give 
them an INLINE[0] pragma; ie don’t inline till phase 0.  Maybe we should do the 
same for constructor wrappers.


That was probably more than you wanted to know.  Do send a concrete example.  
Thanks


Simon

From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of Conal Elliott
Sent: 29 April 2014 23:03
To: 
glasgow-haskell-users@haskell.org<mailto:glasgow-haskell-users@haskell.org>; 
ghc-d...@haskell.org<mailto:ghc-d...@haskell.org>
Subject: GHC rewrite rules and constructor wrappers?

I'm trying to sort out the relationship of GHC rewrite rules and constructor 
wrappers. I have rules like

> "reify/(:<)" reifyEP (:<) = kPrim VecSP

This rule seems to fire for `reifyEP ($W:<)` rather than `reifyEP (:<)`. If I'm 
tracking (uncertain), `($W:<)` inlines to `(:<)`. Sometimes I'm able to 
preserve the `$W` form, but sometimes I get the bare form when inlining a 
definition from another already-compiled module. In those cases, I don't know 
how to get my rules to fire.

Advice and explanation appreciated, including pointers explanations of the role 
of these wrappers in GHC.
-- Conal

_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to