self.toolcontext.info("*** GENERATING C ***", 1)
var compiler = new SeparateCompiler(mainmodule, self, runtime_type_analysis)
+ compiler.do_compilation
+ compiler.display_stats
+
+ var time1 = get_time
+ self.toolcontext.info("*** END GENERATING C: {time1-time0} ***", 2)
+ write_and_make(compiler)
+ end
+
+ # Count number of invocations by VFT
+ private var nb_invok_by_tables = 0
+ # Count number of invocations by direct call
+ private var nb_invok_by_direct = 0
+ # Count number of invocations by inlining
+ private var nb_invok_by_inline = 0
+end
+
+# Singleton that store the knowledge about the separate compilation process
+class SeparateCompiler
+ super AbstractCompiler
+
+ redef type VISITOR: SeparateCompilerVisitor
+
+ # The result of the RTA (used to know live types and methods)
+ var runtime_type_analysis: nullable RapidTypeAnalysis
+
+ private var undead_types: Set[MType] = new HashSet[MType]
+ private var live_unresolved_types: Map[MClassDef, Set[MType]] = new HashMap[MClassDef, HashSet[MType]]
+
+ private var type_ids: Map[MType, Int] is noinit
+ private var type_colors: Map[MType, Int] is noinit
+ private var opentype_colors: Map[MType, Int] is noinit
+ protected var method_colors: Map[PropertyLayoutElement, Int] is noinit
+ protected var attr_colors: Map[MAttribute, Int] is noinit
+
+ init do
+ var file = new_file("nit.common")
+ self.header = new CodeWriter(file)
+ self.compile_box_kinds
+ end
+
+ redef fun do_compilation
+ do
+ var compiler = self
compiler.compile_header
+ var c_name = mainmodule.c_name
+
# compile class structures
- self.toolcontext.info("Property coloring", 2)
- compiler.new_file("{mainmodule.name}.classes")
+ modelbuilder.toolcontext.info("Property coloring", 2)
+ compiler.new_file("{c_name}.classes")
compiler.do_property_coloring
for m in mainmodule.in_importation.greaters do
for mclass in m.intro_mclasses do
end
# The main function of the C
- compiler.new_file("{mainmodule.name}.main")
+ compiler.new_file("{c_name}.main")
compiler.compile_nitni_global_ref_functions
compiler.compile_main_function
compiler.compile_finalizer_function
# compile methods
for m in mainmodule.in_importation.greaters do
- self.toolcontext.info("Generate C for module {m}", 2)
- compiler.new_file("{m.name}.sep")
+ modelbuilder.toolcontext.info("Generate C for module {m.full_name}", 2)
+ compiler.new_file("{m.c_name}.sep")
compiler.compile_module_to_c(m)
end
# compile live & cast type structures
- self.toolcontext.info("Type coloring", 2)
- compiler.new_file("{mainmodule.name}.types")
+ modelbuilder.toolcontext.info("Type coloring", 2)
+ compiler.new_file("{c_name}.types")
+ compiler.compile_types
+ end
+
+ # Color and compile type structures and cast information
+ fun compile_types
+ do
+ var compiler = self
+
var mtypes = compiler.do_type_coloring
for t in mtypes do
compiler.compile_type_to_c(t)
compiler.compile_type_to_c(t)
end
- compiler.display_stats
-
- var time1 = get_time
- self.toolcontext.info("*** END GENERATING C: {time1-time0} ***", 2)
- write_and_make(compiler)
- end
-
- # Count number of invocations by VFT
- private var nb_invok_by_tables = 0
- # Count number of invocations by direct call
- private var nb_invok_by_direct = 0
- # Count number of invocations by inlining
- private var nb_invok_by_inline = 0
-end
-
-# Singleton that store the knowledge about the separate compilation process
-class SeparateCompiler
- super AbstractCompiler
-
- redef type VISITOR: SeparateCompilerVisitor
-
- # The result of the RTA (used to know live types and methods)
- var runtime_type_analysis: nullable RapidTypeAnalysis
-
- private var undead_types: Set[MType] = new HashSet[MType]
- private var live_unresolved_types: Map[MClassDef, Set[MType]] = new HashMap[MClassDef, HashSet[MType]]
-
- private var type_ids: Map[MType, Int]
- private var type_colors: Map[MType, Int]
- private var opentype_colors: Map[MType, Int]
- protected var method_colors: Map[PropertyLayoutElement, Int]
- protected var attr_colors: Map[MAttribute, Int]
-
- init(mainmodule: MModule, mmbuilder: ModelBuilder, runtime_type_analysis: nullable RapidTypeAnalysis) do
- super(mainmodule, mmbuilder)
- var file = new_file("nit.common")
- self.header = new CodeWriter(file)
- self.runtime_type_analysis = runtime_type_analysis
- self.compile_box_kinds
end
redef fun compile_header_structs do
var live_cast_types = runtime_type_analysis.live_cast_types
var mtypes = new HashSet[MType]
mtypes.add_all(live_types)
- mtypes.add_all(live_cast_types)
for c in self.box_kinds.keys do
mtypes.add(c.mclass_type)
end
# Compute colors
- var poset = poset_from_mtypes(mtypes)
+ var poset = poset_from_mtypes(mtypes, live_cast_types)
var colorer = new POSetColorer[MType]
colorer.colorize(poset)
type_ids = colorer.ids
return poset
end
- private fun poset_from_mtypes(mtypes: Set[MType]): POSet[MType] do
+ private fun poset_from_mtypes(mtypes, cast_types: Set[MType]): POSet[MType] do
var poset = new POSet[MType]
for e in mtypes do
poset.add_node(e)
- for o in mtypes do
+ for o in cast_types do
if e == o then continue
+ poset.add_node(o)
if e.is_subtype(mainmodule, null, o) then
poset.add_edge(e, o)
end
do
var rta = compiler.runtime_type_analysis
var mmethod = callsite.mproperty
- # TODO: Inlining of new-style constructors
- if compiler.modelbuilder.toolcontext.opt_direct_call_monomorph.value and rta != null and not mmethod.is_root_init then
+ # TODO: Inlining of new-style constructors with initializers
+ if compiler.modelbuilder.toolcontext.opt_direct_call_monomorph.value and rta != null and callsite.mpropdef.initializers.is_empty then
var tgs = rta.live_targets(callsite)
if tgs.length == 1 then
# DIRECT CALL
var res: nullable RuntimeVariable = null
var recv = arguments.first
var consider_null = not self.compiler.modelbuilder.toolcontext.opt_no_check_null.value or mmethod.name == "==" or mmethod.name == "!="
- var maybenull = recv.mcasttype isa MNullableType and consider_null
+ var maybenull = (recv.mcasttype isa MNullableType or recv.mcasttype isa MNullType) and consider_null
if maybenull then
self.add("if ({recv} == NULL) \{")
- if mmethod.name == "==" then
+ if mmethod.name == "==" or mmethod.name == "is_same_instance" then
res = self.new_var(bool_type)
var arg = arguments[1]
if arg.mcasttype isa MNullableType then
else
self.add("\{")
end
- if not self.compiler.modelbuilder.toolcontext.opt_no_shortcut_equate.value and (mmethod.name == "==" or mmethod.name == "!=") then
- if res == null then res = self.new_var(bool_type)
- # Recv is not null, thus is arg is, it is easy to conclude (and respect the invariants)
+ if not self.compiler.modelbuilder.toolcontext.opt_no_shortcut_equate.value and (mmethod.name == "==" or mmethod.name == "!=" or mmethod.name == "is_same_instance") then
+ # Recv is not null, thus if arg is, it is easy to conclude (and respect the invariants)
var arg = arguments[1]
if arg.mcasttype isa MNullType then
- if mmethod.name == "==" then
- self.add("{res} = 0; /* arg is null but recv is not */")
- else
+ if res == null then res = self.new_var(bool_type)
+ if mmethod.name == "!=" then
self.add("{res} = 1; /* arg is null and recv is not */")
+ else # `==` and `is_same_instance`
+ self.add("{res} = 0; /* arg is null but recv is not */")
end
self.add("\}") # closes the null case
self.add("if (0) \{") # what follow is useless, CC will drop it
(compiler.modelbuilder.toolcontext.opt_inline_some_methods.value and mmethoddef.can_inline(self)) then
compiler.modelbuilder.nb_invok_by_inline += 1
if compiler.modelbuilder.toolcontext.opt_invocation_metrics.value then add("count_invoke_by_inline++;")
- var frame = new Frame(self, mmethoddef, recvtype, arguments)
+ var frame = new StaticFrame(self, mmethoddef, recvtype, arguments)
frame.returnlabel = self.get_name("RET_LABEL")
frame.returnvar = res
var old_frame = self.frame
# of the method (ie recv) if the static type is unresolved
# This is more complex than usual because the unresolved type must not be resolved
# with the current receiver (ie self).
- # Therefore to isolate the resolution from self, a local Frame is created.
+ # Therefore to isolate the resolution from self, a local StaticFrame is created.
# One can see this implementation as an inlined method of the receiver whose only
# job is to allocate the array
var old_frame = self.frame
- var frame = new Frame(self, mpropdef, mpropdef.mclassdef.bound_mtype, [recv])
+ var frame = new StaticFrame(self, mpropdef, mpropdef.mclassdef.bound_mtype, [recv])
self.frame = frame
#print "required Array[{elttype}] for recv {recv.inspect}. bound=Array[{self.resolve_for(elttype, recv)}]. selfvar={frame.arguments.first.inspect}"
var res = self.array_instance(varargs, elttype)
var v = compiler.new_visitor
var selfvar = new RuntimeVariable("self", recv, recv)
var arguments = new Array[RuntimeVariable]
- var frame = new Frame(v, mmethoddef, recv, arguments)
+ var frame = new StaticFrame(v, mmethoddef, recv, arguments)
v.frame = frame
var msignature = mmethoddef.msignature.resolve_for(mmethoddef.mclassdef.bound_mtype, mmethoddef.mclassdef.bound_mtype, mmethoddef.mclassdef.mmodule, true)
var v = compiler.new_visitor
var selfvar = new RuntimeVariable("self", v.object_type, recv)
var arguments = new Array[RuntimeVariable]
- var frame = new Frame(v, mmethoddef, recv, arguments)
+ var frame = new StaticFrame(v, mmethoddef, recv, arguments)
v.frame = frame
var sig = new FlatBuffer