<div dir="ltr">On Fri, Jul 25, 2008 at 7:54 PM, Adam Goode <span dir="ltr">&lt;<a href="mailto:adam@spicenitz.org" target="_blank">adam@spicenitz.org</a>&gt;</span> wrote:<br><div class="gmail_quote"><div dir="ltr"><div class="gmail_quote">
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="Ih2E3d">
<div>Wesley W. Terpstra wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
What options can I use to convince MLton to output small executables? Ideally I&#39;d like to get hello-world to below 100k. With static linking of all but libc/m it is currently 260k.<br>
<br>
I already tried removing all unused symbols from libgmp.a and libmlton.a. The benefit was not spectacular, only 40k. libgmp.a already includes each function in a separate file so static linking drops all the unneeded methods. Similarly, most of the basis wrapper functions are dropped.<br>

</blockquote></div><br></div><div class="Ih2E3d">
1. Compile mlton with -ffunction-sections and -fdata-sections, then link with --gc-sections (gcc option is -Wl,--gc-sections). This may save space or may even bloat space, but it is worth investigating. Also, try compiling everything with -Os. It is also worth seeing if mlton&#39;s invocation of gcc can be safely augmented with these options. Finally, look into the -combine and -fwhole-program gcc options.</div>
</blockquote>
<div><br>I already messed around with -fdata-sections and -ffunction-sections. However, separate C source files are already compiled into different text segments. When you link statically to an archive, an object file is only linked in if it satisfies an unresolved symbol. Thus, if each source file contains a separate function, the options you list do not improve the space use of the program. Most of the MLton runtime already has one function per file, with the notable exception of the garbage collector. However, the garbage collector has almost no dead-code anyway. Anyway, I did something very similar to what you propose (though a bit more aggressive) and only won 40k as I mentioned.<br>

<br>You can change -O1 to -Os by modifying the mlton execution shell script. At least for my hello-world test program, the executable had exactly the same size as with -O1.<br><br>I was hoping to learn what options I can give to the MLton compiler itself to have it generate more space-efficient executable code.<br>

<br></div><div class="Ih2E3d"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">2. Make libmlton a dynamic library. You&#39;ll get no benefit if you are installing only 1 program, but it will start to pay off after installing a few. You can try this without too much hassle for testing, and if it becomes useful, only later look into the ABI issues of having a persistent libmlton installed on a system. (For your embedded device, this probably won&#39;t matter.) I&#39;d be interested in having a shared libmlton on Fedora, since it makes executables smaller and makes various gdb and debugging things easier (separate debuginfo packages don&#39;t work with static libraries).</blockquote>

</div><div><br>While I agree with you that this can be a good idea for an embedded device, there are a couple caveats. First, a dynamic library always includes all objects. Thus it will be larger than the piece linked into a static binary. However, with enough MLton programs you would still save. Doing this on Fedora though is, I think, a bad idea. There is a very tight coupling between the compiler and the runtime. Executables compiled with version A, but using runtime library version B may experience bad behaviour. Your Fedora box is big, just pay the cost. :-)<br>

<br></div><div class="Ih2E3d"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Both of these techniques can work with each other, and may both give benefits. One more thing, if you try the dynamic library route, making a proper set of function exports and using hidden visibility will probably lead to even more benefit. <a href="http://gcc.gnu.org/wiki/Visibility" target="_blank">http://gcc.gnu.org/wiki/Visibility</a></blockquote>

</div><div><br>I already implemented this in the patch to output C libraries from MLton. <br><br>However, that page makes the interesting claim that if a symbol has visibility hidden it doesn&#39;t need to accessed via PIC. If true and I tell gas that all the MLton_* methods are hidden, perhaps this would avoid needing the amd64 codegen to output PIC compatible code! (the runtime is compiled with -fPIC so the relocation to libgmp/c/m should work there)<br>

<br></div></div></div>
</div></div>