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)
+ modelbuilder.toolcontext.info("Property coloring", 2)
compiler.new_file("{c_name}.classes")
compiler.do_property_coloring
for m in mainmodule.in_importation.greaters do
# compile methods
for m in mainmodule.in_importation.greaters do
- self.toolcontext.info("Generate C for module {m.full_name}", 2)
+ 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)
+ 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] 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 compile_header_structs do
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
else
self.add("\{")
end
- if not self.compiler.modelbuilder.toolcontext.opt_no_shortcut_equate.value and (mmethod.name == "==" or mmethod.name == "!=") then
+ 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 res == null then res = self.new_var(bool_type)
- if mmethod.name == "==" then
- self.add("{res} = 0; /* arg is null but recv is not */")
- else
+ 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