: Do not compile dead methods (semi-global).
Need `--rta`.
+## LINK-BOOST OPTIMIZATIONS
+
+In `--separate` and in `--erasure` modes, some optimization can be gained by hijacking the linker process.
+
+Warning: these optimisations are not portable since they use extra features of the GNU linker `ld`.
+However, there is very few reasons to not use them if GNU `ld` is available.
+
+`--link-boost`
+: Enable all link-boost optimizations.
+
+`--colors-are-symbols`
+: Store colors as symbols instead of static data.
+
+ By default, the various identifiers used to implement OO-mechanisms are stored as genuine constant static variables.
+
+ This option uses linker symbols to encode these identifiers.
+ This makes the compiled program faster since less indirections are required to get the values.
+ It also produces executables that are a little bit smaller since static memory does not have to store the colors.
+
+`--substitute-monomorph`
+: Replace monomorphic trampolines with direct call.
+
+ Late-binding is implemented with *trampolines*, that are small functions that just select and jump the to right implementations.
+ If, at link-time, is it known that the target will always by the same implementation then all calls to the trampoline are replaced by
+ direct calls to this single implementation.
+
+ Note that using trampolines as indirection slows down the executable.
+ However, it is expected that the gain of monomorphic direct-calls overcompensates the additional indirections in polymorphic trampoline-calls.
+
+ Note: automatically enable option `--trampoline-call`.
## DANGEROUS OPTIMIZATIONS
`--colo-dead-methods`
: Force colorization of dead methods.
-`--colors-are-symbols`
-: Store colors as symbols instead of static data.
-
- By default, the various identifiers used to implement OO-mechanisms are stored as genuine constant static variables.
-
- This option uses linker symbols to encode these identifiers.
- This makes the compiled program faster since less indirections are required to get the values.
- It also produces executables that are a little bit smaller since static memory does not have to store the colors.
-
- Warning: the usage of linker symbols is not portable on all toolchains (eg. Mac OS X).
- Also, this option does nothing on some platforms (like android).
-
`--no-gcc-directive`
: Disable advanced gcc directives for optimization.
+`--trampoline-call`
+: Use an indirection when calling.
+
+ Just add the trampolines of `--substitute-monomorph` without doing any aditionnal optimizations.
## INTERNAL OPTIONS
var opt_no_shortcut_equate = new OptionBool("Always call == in a polymorphic way", "--no-shortcut-equal")
# --colors-are-symbols
var opt_colors_are_symbols = new OptionBool("Store colors as symbols (faster)", "--colors-are-symbols")
+ # --trampoline-call
+ var opt_trampoline_call = new OptionBool("Use an indirection when calling", "--trampoline-call")
# --inline-coloring-numbers
var opt_inline_coloring_numbers = new OptionBool("Inline colors and ids (semi-global)", "--inline-coloring-numbers")
self.option_context.add_option(self.opt_separate)
self.option_context.add_option(self.opt_no_inline_intern)
self.option_context.add_option(self.opt_no_union_attribute)
- self.option_context.add_option(self.opt_no_shortcut_equate, opt_colors_are_symbols)
+ self.option_context.add_option(self.opt_no_shortcut_equate, opt_colors_are_symbols, opt_trampoline_call)
self.option_context.add_option(self.opt_inline_coloring_numbers, opt_inline_some_methods, opt_direct_call_monomorph, opt_skip_dead_methods, opt_semi_global)
self.option_context.add_option(self.opt_colo_dead_methods)
self.option_context.add_option(self.opt_tables_metrics)
r.compile_to_c(self)
var r2 = pd.virtual_runtime_function
if r2 != r then r2.compile_to_c(self)
+
+ # Generate trampolines
+ if modelbuilder.toolcontext.opt_trampoline_call.value then
+ r2.compile_trampolines(self)
+ end
end
end
self.mainmodule = old_module
ss.append(", {a}")
end
- self.require_declaration(const_color)
- var call = "(({runtime_function.c_funptrtype})({arguments.first}->class->vft[{const_color}]))({ss}) /* {mmethod} on {arguments.first.inspect}*/"
+ var call
+ if not compiler.modelbuilder.toolcontext.opt_trampoline_call.value then
+ self.require_declaration(const_color)
+ call = "(({runtime_function.c_funptrtype})({arguments.first}->class->vft[{const_color}]))({ss}) /* {mmethod} on {arguments.first.inspect}*/"
+ else
+ var callsym = "CALL_" + const_color
+ self.require_declaration(callsym)
+ call = "{callsym}({ss}) /* {mmethod} on {arguments.first.inspect}*/"
+ end
if res != null then
self.add("{res} = {call};")
v.add("\}")
compiler.names[self.c_name] = "{mmethoddef.full_name} ({mmethoddef.location.file.filename}:{mmethoddef.location.line_start})"
end
+
+ fun compile_trampolines(compiler: SeparateCompiler)
+ do
+ var recv = self.mmethoddef.mclassdef.bound_mtype
+ var selfvar = arguments.first
+ var ret = called_signature.return_mtype
+
+ if mmethoddef.is_intro and recv.ctype == "val*" then
+ var m = mmethoddef.mproperty
+ var n2 = "CALL_" + m.const_color
+ compiler.provide_declaration(n2, "{c_ret} {n2}{c_sig};")
+ var v2 = compiler.new_visitor
+ v2.add "{c_ret} {n2}{c_sig} \{"
+ v2.require_declaration(m.const_color)
+ var call = "(({c_funptrtype})({selfvar}->class->vft[{m.const_color}]))({arguments.join(", ")});"
+ if ret != null then
+ v2.add "return {call}"
+ else
+ v2.add call
+ end
+
+ v2.add "\}"
+
+ end
+ if mmethoddef.has_supercall and recv.ctype == "val*" then
+ var m = mmethoddef
+ var n2 = "CALL_" + m.const_color
+ compiler.provide_declaration(n2, "{c_ret} {n2}{c_sig};")
+ var v2 = compiler.new_visitor
+ v2.add "{c_ret} {n2}{c_sig} \{"
+ v2.require_declaration(m.const_color)
+ var call = "(({c_funptrtype})({selfvar}->class->vft[{m.const_color}]))({arguments.join(", ")});"
+ if ret != null then
+ v2.add "return {call}"
+ else
+ v2.add call
+ end
+
+ v2.add "\}"
+ end
+ end
end
redef class MEntity