<div dir="ltr"><div dir="auto"><div>> I highly doubt that this split will have any measurable overhead.</div><div dir="auto">> Reexporting a definition defined in one module from another module via</div><div dir="auto">> an export list does not produce any code at all; importing such a</div><div dir="auto">> declaration is equivalent to importing the definition from the defining</div><div dir="auto">> module.</div><div dir="auto"><br></div>Ah right, I can see how that's true at the Haskell level but..<br><div dir="auto"><br></div><div dir="auto">> If for some reason we can't in some cases directly reexport then we</div><div dir="auto">> would likely rather have a some very trivial bindings that GHC would be</div><div dir="auto">> quite eager to inline. </div><div dir="auto"><br></div><div dir="auto">Sure, I can see how you'd inline based on the haskell contract, I can't see how you avoid the compile time overhead when compiling the library. If you have a haskell library</div><div dir="auto"><br></div><div dir="auto">module Test (Control.Monad.when, Control.Applicative.many) where<br><br>import Control.Monad(when)<br>import Control.Applicative(many)</div><div dir="auto"><br></div><div>compiling it:</div><div><br></div><div> ghc test.hs<br>[1 of 1] Compiling Test ( test.hs, test.o )</div><div><br></div><div>which still contains the closure for the library. On Windows where GHC forces the use of
<span>--<em>export</em>-<em>all</em>-symbols with dynamic-too this will not result in no code.</span></div><div><span>in fact, it will result in exactly the *same* copy of code as in base inside the shared library:</span></div><div><span><br></span></div><div>
<dt><span><code>--export-all-symbols</code></span></dt><dd><p>Treat all global and weak defined symbols found in the input object
files as symbols to be exported. There is a small list of symbols which
are not exported by default; see the <samp>--no-default-excludes</samp>
option. You may add to the list of symbols to not export by using the
<samp>--exclude-symbols</samp> option.
</p>
</dd></div><div><span>At runtime you're right that you can avoid the extra calls (forgot about re-exportation through module definition) because the library becomes unused,</span></div><div><span>but you don't avoid it at compile and link time in all cases.<br></span></div><div><span><br></span></div><div><span>Yes, </span>
<span>--<em>export</em>-<em>all</em>-symbols</span> is horrible but that's how it works today because GHC does not support symbol visibility correctly.</div><div><br></div><div>So unless there's a very good reason, I still think that it's better for *all* platforms to just move the code as opposed to re-export them, less we make it even</div><div>harder still to support dynamic-too on Windows (though maybe that's ok and GHC should be fixed).</div><div><br></div><div>Thanks,</div><div>Tamar<br>
</div><div dir="auto"><br><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Fri, Mar 24, 2023, 21:18 Ben Gamari <<a href="mailto:ben@smart-cactus.org" target="_blank">ben@smart-cactus.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Phyx <<a href="mailto:lonetiger@gmail.com" rel="noreferrer" target="_blank">lonetiger@gmail.com</a>> writes:<br>
<br>
> Hi,<br>
><br>
> Though I'm no longer a very active GHC developer I do have some questions.<br>
><br>
> Overall I'm in support of this but I think I'd rather see an outright split<br>
> from the start rather than first having a forwarder library.<br>
><br>
> The reason for this is that I'm afraid of the performance impact of having<br>
> this intermediate layer.<br>
><br>
> For statically linked programs this means at least an additional load and<br>
> branch on every call to a standard library. This would for instance affect<br>
> Windows quite heavily. I'm not sure the impact is mitigated by branch<br>
> prediction and prefetching. At the least it'll polute your L2 cache much<br>
> more than before.<br>
><br>
> For dynamically linked we could potentially use symbol preemption to remove<br>
> the forwarding or on Windows redirect using import libraries.<br>
><br>
> Now maybe I'm overestimating the impact this would have, but I'd very much<br>
> like to see some numbers on a small-ish experiment to see what impact (if<br>
> any) there are and what mitigation we can do.<br>
><br>
> Typically it's quite hard to optimize after the fact. Maybe I've missed it<br>
> in there. Proposal, but can the compiler remove the forwarding? i.e. Can<br>
> the calls be specialized directly to the definition one? If so it'll break<br>
> having alternative standard libs at runtime?<br>
><br>
I highly doubt that this split will have any measurable overhead.<br>
Reexporting a definition defined in one module from another module via<br>
an export list does not produce any code at all; importing such a<br>
declaration is equivalent to importing the definition from the defining<br>
module.<br>
<br>
If for some reason we can't in some cases directly reexport then we<br>
would likely rather have a some very trivial bindings that GHC would be<br>
quite eager to inline.<br>
<br>
Cheers,<br>
<br>
- Ben<br>
<br>
</blockquote></div></div></div>
</div>