On Sun, Mar 4, 2018 at 4:14 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
Currently in Gambit there are two ways to achieve whole program optimization.
The first is to conceptually concatenate all modules by using a file that contains “include”s of all the modules. This has the advantage of exposing all definitions to the inliner, and to allow the tree-shaker to eliminate the useless code. This obviously gives a relatively slow compilation, but the best code specialization because the compiler “sees the whole code base”.
There are a few of problems with the include approach: - the main problem is C compilation performance or lack thereof. gcc just takes forever and usually runs out of memory if you have more than a handful of (non trivial) modules linked in. Compiling an 11M/230kloc single-host function is not a simple matter. - the second problem is leakage of module declarations; if for example a module declares (fixnum), that declaration will leak to the rest of the program after the include. I guess this could be avoided by carefully resetting the declarations after each include, so it's not insurmountable. - the third problem is leakage of ffi symbols -- you suddenly have all the ffi code linked in the same C module, which means that you lose the ability to locally name things. More of an annoyance, but I didn't like having to rename all the `ffi_free` functions in the various ffi modules.
The first problem is truly insurmountable. Linking more than a handful of modules results in gcc blowing up... I haven't managed to compile any non-trivial program that uses a decent part of the gerbil stdlib, they all end with the compiler getting OOM killed.
The second method is to use the “core” declaration (which is undocumented). When a toplevel definition is in the scope of a (not core) declaration, it will not generate any code per-se, but the definition is remembered so that the definition can be inlined in the rest of the program. For example:
thanks, I didn't know about it; this sounds useful to force inlining of a module in conjunction with the include method. How does it behave with complex recursive functions or functions that are used more than once? Will it emit code for the function then?
-- vyzo