Hi all, I'm a little bit worried about the sheer size of the resulting binaries of a project using LLVM. The medium large project for which I'm planning to use it (which currently uses a custom dynamic code generator), produces a compact 1.6 MB binary. When I compile LLVM's simple 'Fibonacci' example project the executable is 2.6 MB. I realize LLVM is a complex and feature rich project but could anyone give me a rough idea of where most of the executable size is coming from, and maybe give some ideas on how to reduce it if possible? It's not like 2.6 MB is huge but it just seems disproportionate and I'd like to keep my project lightweight (it could be used for embedded systems one day). Note that I'm basically only using the IRBuilder, JIT, and a few common optimization passes. Removing the optimizations doesn't seem to affect the executable size at all, so I'm starting to wonder whether there are a lot of other unused features ending up in the binary (I'm using Visual C++ 2005 by the way, which is supposed to be quite good at reducing code size). Maybe there is some way to explicitly disable unused features (not compile them or use stubs)? I'm also under the impression that LLVM uses a lot of static (pre-generated) tables, and maybe they could be somewhat smaller when making some extra assumptions? Thanks a lot, Nicolas Capens -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080526/de40abed/attachment.html>
Hi Nicholas, On May 26, 2008, at 02:29, Nicolas Capens wrote:> I realize LLVM is a complex and feature rich project but could > anyone give me a rough idea of where most of the executable size is > coming from, and maybe give some ideas on how to reduce it if > possible?'nm' can give you this information on Unix. I don't know what the equivalent in the VS toolchain is.> It’s not like 2.6 MB is huge but it just seems disproportionate and > I’d like to keep my project lightweight (it could be used for > embedded systems one day). Note that I’m basically only using the > IRBuilder, JIT, and a few common optimization passes. Removing the > optimizations doesn’t seem to affect the executable size at all, so > I’m starting to wonder whether there are a lot of other unused > features ending up in the binary (I’m using Visual C++ 2005 by the > way, which is supposed to be quite good at reducing code size). > Maybe there is some way to explicitly disable unused features (not > compile them or use stubs)? I’m also under the impression that LLVM > uses a lot of static (pre-generated) tables, and maybe they could be > somewhat smaller when making some extra assumptions?Make sure that you're passing /opt:ref to link.exe. Otherwise, unreferenced code within the static libraries will be retained. The same goes on Unix, though the requisite flags to ld are platform- dependent. LLVM is fairly accommodating to unreferenced code omission, but a stripped-down JIT is still close to the size you show. — Gordon
> 'nm' can give you this information on Unix. I don't know what the > equivalent in the VS toolchain is.Or simply have the linker spit out the map (/MAP:filename)...in the Linker/Debugging Options in the IDE.
On May 25, 2008, at 11:29 PM, Nicolas Capens wrote:> I’m a little bit worried about the sheer size of the resulting > binaries of a project using LLVM.I'd identify all the optimization passes you don't want to use, and then see who is pulling them in. Then, you can add controls as necessary so that projects that don't want them can use those controls to make them disappear. For example, take the hypothetical: if (doing_opt_pass_35) opt_pass_35(); where that variable can wind up being set in some way the optimizer cannot see. If you add: if (gate_35 && doing_opt_pass_35) opt_pass_35(); and then have: const int gate_35 = 0; in your project, then this reduces to turning on the link time optimizations and ensuring the optimizer is at least smart enough to remove that reference. This kinda assumes you're using llvm's link time optimizer (or someone elses).
On May 25, 2008, at 11:29 PM, Nicolas Capens wrote:> Hi all, > > I’m a little bit worried about the sheer size of the resulting > binaries of a project using LLVM. The medium large project for which > I’m planning to use it (which currently uses a custom dynamic code > generator), produces a compact 1.6 MB binary. When I compile LLVM’s > simple ‘Fibonacci’ example project the executable is 2.6 MB… > > I realize LLVM is a complex and feature rich project but could > anyone give me a rough idea of where most of the executable size is > coming from, and maybe give some ideas on how to reduce it if > possible? > > It’s not like 2.6 MB is huge but it just seems disproportionate and > I’d like to keep my project lightweight (it could be used for > embedded systems one day). Note that I’m basically only using the > IRBuilder, JIT, and a few common optimization passes. Removing the > optimizations doesn’t seem to affect the executable size at all, so > I’m starting to wonder whether there are a lot of other unused > features ending up in the binary (I’m using Visual C++ 2005 by the > way, which is supposed to be quite good at reducing code size). > Maybe there is some way to explicitly disable unused features (not > compile them or use stubs)? I’m also under the impression that LLVM > uses a lot of static (pre-generated) tables, and maybe they could be > somewhat smaller when making some extra assumptions? >Hi Nicholas, As others have mentioned, the first step is to find out what is consuming the size. We have done some work to reduce code size, but there is still a lot that we can do. For example, we know that killing off the last few uses or RTTI info will shrink generated code size by 5-10% or so. There are other refactorings that can be done to reduce executable size. Specifically, if you're using a JIT, there is no reason to link in the code to do .s file printing (and X86 has two versions of this code). This code is non-trivial and pulls in some big string tables. Getting this out of the JIT code footprint would require refactoring the asmprinter stuff so that it isn't accessible via the X86 target's vtable. This is very doable, but noone has stepped up to do it yet. I'm sure that there are a ton of other similar things that can be done to squeeze it down. -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080527/02651190/attachment.html>
Hi Chris, Thanks for the info. I'll probably try disabling the Intel and AT&T asm printers then, once I have everything else going for my project. I'll get back on this topic in due time to see what the other potential size reducing measures are. I was just hoping maybe there are some simple options already available, but I don't mind stepping up and doing it myself if I can get some guidelines. Cheers, Nicolas P.S: It's Nicolas, not Nicholas ;-) From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] On Behalf Of Chris Lattner Sent: Wednesday, 28 May, 2008 08:02 To: LLVM Developers Mailing List Subject: Re: [LLVMdev] LLVM project binary size On May 25, 2008, at 11:29 PM, Nicolas Capens wrote: Hi all, I'm a little bit worried about the sheer size of the resulting binaries of a project using LLVM. The medium large project for which I'm planning to use it (which currently uses a custom dynamic code generator), produces a compact 1.6 MB binary. When I compile LLVM's simple 'Fibonacci' example project the executable is 2.6 MB. I realize LLVM is a complex and feature rich project but could anyone give me a rough idea of where most of the executable size is coming from, and maybe give some ideas on how to reduce it if possible? It's not like 2.6 MB is huge but it just seems disproportionate and I'd like to keep my project lightweight (it could be used for embedded systems one day). Note that I'm basically only using the IRBuilder, JIT, and a few common optimization passes. Removing the optimizations doesn't seem to affect the executable size at all, so I'm starting to wonder whether there are a lot of other unused features ending up in the binary (I'm using Visual C++ 2005 by the way, which is supposed to be quite good at reducing code size). Maybe there is some way to explicitly disable unused features (not compile them or use stubs)? I'm also under the impression that LLVM uses a lot of static (pre-generated) tables, and maybe they could be somewhat smaller when making some extra assumptions? Hi Nicholas, As others have mentioned, the first step is to find out what is consuming the size. We have done some work to reduce code size, but there is still a lot that we can do. For example, we know that killing off the last few uses or RTTI info will shrink generated code size by 5-10% or so. There are other refactorings that can be done to reduce executable size. Specifically, if you're using a JIT, there is no reason to link in the code to do .s file printing (and X86 has two versions of this code). This code is non-trivial and pulls in some big string tables. Getting this out of the JIT code footprint would require refactoring the asmprinter stuff so that it isn't accessible via the X86 target's vtable. This is very doable, but noone has stepped up to do it yet. I'm sure that there are a ton of other similar things that can be done to squeeze it down. -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080528/262a03db/attachment.html>