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