On 06/07/2011 13:47, Max Bolingbroke wrote:
On 6 July 2011 12:22, Simon Marlow<[email protected]>  wrote:
So I'm not sure it's worth the hassle of dealing with platform-specific
low-level stuff for this case, since we don't save many symbols - there
aren't many nullary constructors compared to, say, thunks or function
closures.

The idea behind using a statically allocated indirection was to avoid
the use of symbol aliases at the assembly-language level: it should be
a portable solution.

This would save many more symbols than you might think: GHC would
export 1538 less symbols! This originate from e.g. enumerations of the
primops, lexer lexemes, LLVM base types, types of conditional flag in
the X86 backend, the dynflags.. etc etc. So I really think it is worth
pursuing this change. Is there anything obviously wrong with the patch
as you see it?

Ah, sorry I didn't read your message carefully enough.

Now I'm not sure whether this will work as is. As seen from another module, this Id will look like a constructor, so we might pointer-tag it when referring to it. I'm not sure whether we actually do this or not, and it's hard to tell from looking at the code. Pointer-tagging it would be wrong if it were an indirection rather than an actual constructor.

The other thing to be careful of is that your IND_STATIC should have a static link field with a non-zero value, so it will be ignored by the GC (I think you're doing this, but I'd check the assembly output just to be sure).

== New Idea ==

I've also come up with another way we could reduce the number of
exports: data constructors needn't export their _info pointers. The
reason is that GHC invariably eta-expands data constructor
applications to their maximum arity, so the use site code is always
generated directly as allocated a dyn closure using the _con_info
symbol.

You can see this behaviour like so:

"""
$ cat DC.hs
module DC where

static_not_app = Just

static_pap = (,) 1

static_full_ap = Left 1

foo x = (dynamic_pap, dynamic_full_ap)
   where
     -- dynamic_not_app would just be floated
     dynamic_pap = (,) x
     dynamic_full_ap = Left x

$ ghc -c -ddump-stg -ddump-cmm DC.hs

==================== STG syntax: ====================
DC.foo =
     \r [x_srR]
         let { sat_srU = NO_CCS Data.Either.Left! [x_srR]; } in
         let { sat_srV = \r [eta_B1] (,) [x_srR eta_B1];
         } in  (,) [sat_srV sat_srU];
SRT(DC.foo): []
a_rrN = \u srt:(0,*bitmap*) [] GHC.Integer.smallInteger 1;
SRT(a_rrN): [GHC.Integer.smallInteger]
DC.static_full_ap = NO_CCS Data.Either.Left! [a_rrN];
SRT(DC.static_full_ap): []
a1_rrP = \u srt:(0,*bitmap*) [] GHC.Integer.smallInteger 1;
SRT(a1_rrP): [GHC.Integer.smallInteger]
DC.static_pap = \r srt:(0,*bitmap*) [eta_B1] (,) [a1_rrP eta_B1];
SRT(DC.static_pap): [a1_rrP]
DC.static_not_app = \r [eta_B1] Data.Maybe.Just [eta_B1];
SRT(DC.static_not_app): []
"""

Constructors aren't always saturated. For good reasons: the constructor might have to do complex evaluation and unpacking, and unfolding this code everywhere would be wasteful. Try this:

  justs = map Just

I get this STG:

  Test.justs = \u srt:(0,*bitmap*) [] GHC.Base.map Data.Maybe.Just;

Now, although GHC hasn't saturated the constructor, it still doesn't refer to the _info symbol, it refers to the _closure. I don't know whether it's possible to refer to the _info symbol - it probably shouldn't be, because that would be mean we're making a fast call to the constructor, in which case it would be about the same amount of code to just allocate the constructor inline.

Cheers,
        Simon

_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to