Merge: No duplicated mclassdefs
[nit.git] / src / separate_compiler.nit
index 6243caa..36b8082 100644 (file)
@@ -16,7 +16,7 @@
 module separate_compiler
 
 import abstract_compiler
-import layout_builders
+import coloring
 import rapid_type_analysis
 
 # Add separate compiler specific options
@@ -40,7 +40,7 @@ redef class ToolContext
        # --semi-global
        var opt_semi_global = new OptionBool("Enable all semi-global optimizations", "--semi-global")
        # --no-colo-dead-methods
-       var opt_no_colo_dead_methods = new OptionBool("Do not colorize dead methods", "--no-colo-dead-methods")
+       var opt_colo_dead_methods = new OptionBool("Force colorization of dead methods", "--colo-dead-methods")
        # --tables-metrics
        var opt_tables_metrics: OptionBool = new OptionBool("Enable static size measuring of tables used for vft, typing and resolution", "--tables-metrics")
 
@@ -52,7 +52,7 @@ redef class ToolContext
                self.option_context.add_option(self.opt_no_union_attribute)
                self.option_context.add_option(self.opt_no_shortcut_equate)
                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_no_colo_dead_methods)
+               self.option_context.add_option(self.opt_colo_dead_methods)
                self.option_context.add_option(self.opt_tables_metrics)
        end
 
@@ -154,10 +154,11 @@ class SeparateCompiler
        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_layout: nullable Layout[MType]
-       private var resolution_layout: nullable Layout[MType]
-       protected var method_layout: nullable Layout[PropertyLayoutElement]
-       protected var attr_layout: nullable Layout[MAttribute]
+       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)
@@ -278,7 +279,7 @@ class SeparateCompiler
                        mattributes[mclass] = new HashSet[MAttribute]
                        for mprop in self.mainmodule.properties(mclass) do
                                if mprop isa MMethod then
-                                       if modelbuilder.toolcontext.opt_no_colo_dead_methods.value and rta != null and not rta.live_methods.has(mprop) then
+                                       if not modelbuilder.toolcontext.opt_colo_dead_methods.value and rta != null and not rta.live_methods.has(mprop) then
                                                dead_methods.add(mprop)
                                                continue
                                        end
@@ -320,10 +321,9 @@ class SeparateCompiler
 
                # methods coloration
                var meth_colorer = new POSetBucketsColorer[MClass, PropertyLayoutElement](poset, colorer.conflicts)
-               self.method_layout = new Layout[PropertyLayoutElement]
-               self.method_layout.pos = meth_colorer.colorize(mmethods)
-               self.method_tables = build_method_tables(mclasses, super_calls)
-               self.compile_color_consts(method_layout.pos)
+               method_colors = meth_colorer.colorize(mmethods)
+               method_tables = build_method_tables(mclasses, super_calls)
+               compile_color_consts(method_colors)
 
                # attribute null color to dead methods and supercalls
                for mproperty in dead_methods do
@@ -336,14 +336,12 @@ class SeparateCompiler
 
                # attributes coloration
                var attr_colorer = new POSetBucketsColorer[MClass, MAttribute](poset, colorer.conflicts)
-               self.attr_layout = new Layout[MAttribute]
-               self.attr_layout.pos = attr_colorer.colorize(mattributes)
-               self.attr_tables = build_attr_tables(mclasses)
-               self.compile_color_consts(attr_layout.pos)
+               attr_colors = attr_colorer.colorize(mattributes)
+               attr_tables = build_attr_tables(mclasses)
+               compile_color_consts(attr_colors)
        end
 
        fun build_method_tables(mclasses: Set[MClass], super_calls: Set[MMethodDef]): Map[MClass, Array[nullable MPropDef]] do
-               var layout = self.method_layout
                var tables = new HashMap[MClass, Array[nullable MPropDef]]
                for mclass in mclasses do
                        var table = new Array[nullable MPropDef]
@@ -360,8 +358,8 @@ class SeparateCompiler
                                if parent == mclass then continue
                                for mproperty in self.mainmodule.properties(parent) do
                                        if not mproperty isa MMethod then continue
-                                       if not layout.pos.has_key(mproperty) then continue
-                                       var color = layout.pos[mproperty]
+                                       if not method_colors.has_key(mproperty) then continue
+                                       var color = method_colors[mproperty]
                                        if table.length <= color then
                                                for i in [table.length .. color[ do
                                                        table[i] = null
@@ -387,8 +385,8 @@ class SeparateCompiler
                        # then override with local properties
                        for mproperty in self.mainmodule.properties(mclass) do
                                if not mproperty isa MMethod then continue
-                               if not layout.pos.has_key(mproperty) then continue
-                               var color = layout.pos[mproperty]
+                               if not method_colors.has_key(mproperty) then continue
+                               var color = method_colors[mproperty]
                                if table.length <= color then
                                        for i in [table.length .. color[ do
                                                table[i] = null
@@ -411,7 +409,7 @@ class SeparateCompiler
                        end
                        # insert super calls in table according to receiver
                        for supercall in supercalls do
-                               var color = layout.pos[supercall]
+                               var color = method_colors[supercall]
                                if table.length <= color then
                                        for i in [table.length .. color[ do
                                                table[i] = null
@@ -426,7 +424,6 @@ class SeparateCompiler
        end
 
        fun build_attr_tables(mclasses: Set[MClass]): Map[MClass, Array[nullable MPropDef]] do
-               var layout = self.attr_layout
                var tables = new HashMap[MClass, Array[nullable MPropDef]]
                for mclass in mclasses do
                        var table = new Array[nullable MPropDef]
@@ -440,7 +437,7 @@ class SeparateCompiler
                                if parent == mclass then continue
                                for mproperty in self.mainmodule.properties(parent) do
                                        if not mproperty isa MAttribute then continue
-                                       var color = layout.pos[mproperty]
+                                       var color = attr_colors[mproperty]
                                        if table.length <= color then
                                                for i in [table.length .. color[ do
                                                        table[i] = null
@@ -457,7 +454,7 @@ class SeparateCompiler
                        # then override with local properties
                        for mproperty in self.mainmodule.properties(mclass) do
                                if not mproperty isa MAttribute then continue
-                               var color = layout.pos[mproperty]
+                               var color = attr_colors[mproperty]
                                if table.length <= color then
                                        for i in [table.length .. color[ do
                                                table[i] = null
@@ -490,8 +487,9 @@ class SeparateCompiler
                var poset = poset_from_mtypes(mtypes)
                var colorer = new POSetColorer[MType]
                colorer.colorize(poset)
-               self.type_layout = colorer.to_layout
-               self.type_tables = self.build_type_tables(poset)
+               type_ids = colorer.ids
+               type_colors = colorer.colors
+               type_tables = build_type_tables(poset)
 
                # VT and FT are stored with other unresolved types in the big resolution_tables
                self.compile_resolution_tables(mtypes)
@@ -516,16 +514,10 @@ class SeparateCompiler
        # Build type tables
        fun build_type_tables(mtypes: POSet[MType]): Map[MType, Array[nullable MType]] do
                var tables = new HashMap[MType, Array[nullable MType]]
-               var layout = self.type_layout
                for mtype in mtypes do
                        var table = new Array[nullable MType]
                        for sup in mtypes[mtype].greaters do
-                               var color: Int
-                               if layout isa PHLayout[MType, MType] then
-                                       color = layout.hashes[mtype][sup]
-                               else
-                                       color = layout.pos[sup]
-                               end
+                               var color = type_colors[sup]
                                if table.length <= color then
                                        for i in [table.length .. color[ do
                                                table[i] = null
@@ -559,9 +551,8 @@ class SeparateCompiler
 
                # Compute the table layout with the prefered method
                var colorer = new BucketsColorer[MType, MType]
-               resolution_layout = new Layout[MType]
-               resolution_layout.pos = colorer.colorize(mtype2unresolved)
-               self.resolution_tables = self.build_resolution_tables(mtype2unresolved)
+               opentype_colors = colorer.colorize(mtype2unresolved)
+               resolution_tables = self.build_resolution_tables(mtype2unresolved)
 
                # Compile a C constant for each collected unresolved type.
                # Either to a color, or to -1 if the unresolved type is dead (no live receiver can require it)
@@ -571,8 +562,8 @@ class SeparateCompiler
                end
                var all_unresolved_types_colors = new HashMap[MType, Int]
                for t in all_unresolved do
-                       if self.resolution_layout.pos.has_key(t) then
-                               all_unresolved_types_colors[t] = self.resolution_layout.pos[t]
+                       if opentype_colors.has_key(t) then
+                               all_unresolved_types_colors[t] = opentype_colors[t]
                        else
                                all_unresolved_types_colors[t] = -1
                        end
@@ -588,16 +579,10 @@ class SeparateCompiler
 
        fun build_resolution_tables(elements: Map[MClassType, Set[MType]]): Map[MClassType, Array[nullable MType]] do
                var tables = new HashMap[MClassType, Array[nullable MType]]
-               var layout = self.resolution_layout
                for mclasstype, mtypes in elements do
                        var table = new Array[nullable MType]
                        for mtype in mtypes do
-                               var color: Int
-                               if layout isa PHLayout[MClassType, MType] then
-                                       color = layout.hashes[mclasstype][mtype]
-                               else
-                                       color = layout.pos[mtype]
-                               end
+                               var color = opentype_colors[mtype]
                                if table.length <= color then
                                        for i in [table.length .. color[ do
                                                table[i] = null
@@ -634,7 +619,6 @@ class SeparateCompiler
        fun compile_type_to_c(mtype: MType)
        do
                assert not mtype.need_anchor
-               var layout = self.type_layout
                var is_live = mtype isa MClassType and runtime_type_analysis.live_types.has(mtype)
                var is_cast_live = runtime_type_analysis.live_cast_types.has(mtype)
                var c_name = mtype.c_name
@@ -649,7 +633,7 @@ class SeparateCompiler
 
                # type id (for cast target)
                if is_cast_live then
-                       v.add_decl("{layout.ids[mtype]},")
+                       v.add_decl("{type_ids[mtype]},")
                else
                        v.add_decl("-1, /*CAST DEAD*/")
                end
@@ -659,11 +643,7 @@ class SeparateCompiler
 
                # type color (for cast target)
                if is_cast_live then
-                       if layout isa PHLayout[MType, MType] then
-                               v.add_decl("{layout.masks[mtype]},")
-                       else
-                               v.add_decl("{layout.pos[mtype]},")
-                       end
+                       v.add_decl("{type_colors[mtype]},")
                else
                        v.add_decl("-1, /*CAST DEAD*/")
                end
@@ -699,7 +679,7 @@ class SeparateCompiler
                                if stype == null then
                                        v.add_decl("-1, /* empty */")
                                else
-                                       v.add_decl("{layout.ids[stype]}, /* {stype} */")
+                                       v.add_decl("{type_ids[stype]}, /* {stype} */")
                                end
                        end
                        v.add_decl("\},")
@@ -718,19 +698,13 @@ class SeparateCompiler
                        mclass_type = mtype.as(MClassType)
                end
 
-               var layout = self.resolution_layout
-
                # extern const struct resolution_table_X resolution_table_X
                self.provide_declaration("resolution_table_{mtype.c_name}", "extern const struct types resolution_table_{mtype.c_name};")
 
                # const struct fts_table_X fts_table_X
                var v = new_visitor
                v.add_decl("const struct types resolution_table_{mtype.c_name} = \{")
-               if layout isa PHLayout[MClassType, MType] then
-                       v.add_decl("{layout.masks[mclass_type]},")
-               else
-                       v.add_decl("0, /* dummy */")
-               end
+               v.add_decl("0, /* dummy */")
                v.add_decl("\{")
                for t in self.resolution_tables[mclass_type] do
                        if t == null then
@@ -741,7 +715,7 @@ class SeparateCompiler
                                # the value stored is tv.
                                var tv = t.resolve_for(mclass_type, mclass_type, self.mainmodule, true)
                                # FIXME: What typeids means here? How can a tv not be live?
-                               if self.type_layout.ids.has_key(tv) then
+                               if type_ids.has_key(tv) then
                                        v.require_declaration("type_{tv.c_name}")
                                        v.add_decl("&type_{tv.c_name}, /* {t}: {tv} */")
                                else
@@ -877,7 +851,7 @@ class SeparateCompiler
                v.add_abort("type null")
                v.add("\}")
                v.add("if({t}->table_size == 0) \{")
-               v.add("fprintf(stderr, \"Insantiation of a dead type: %s\\n\", {t}->name);")
+               v.add("PRINT_ERROR(\"Insantiation of a dead type: %s\\n\", {t}->name);")
                v.add_abort("type dead")
                v.add("\}")
        end
@@ -1011,7 +985,7 @@ class SeparateCompilerVisitor
                        var res = self.new_var(mtype)
                        if compiler.runtime_type_analysis != null and not compiler.runtime_type_analysis.live_types.has(valtype) then
                                self.add("/*no autobox from {value.mtype} to {mtype}: {value.mtype} is not live! */")
-                               self.add("printf(\"Dead code executed!\\n\"); show_backtrace(1);")
+                               self.add("PRINT_ERROR(\"Dead code executed!\\n\"); show_backtrace(1);")
                                return res
                        end
                        self.require_declaration("BOX_{valtype.c_name}")
@@ -1023,7 +997,7 @@ class SeparateCompilerVisitor
                        # Bad things will appen!
                        var res = self.new_var(mtype)
                        self.add("/* {res} left unintialized (cannot convert {value.mtype} to {mtype}) */")
-                       self.add("printf(\"Cast error: Cannot cast %s to %s.\\n\", \"{value.mtype}\", \"{mtype}\"); show_backtrace(1);")
+                       self.add("PRINT_ERROR(\"Cast error: Cannot cast %s to %s.\\n\", \"{value.mtype}\", \"{mtype}\"); show_backtrace(1);")
                        return res
                end
        end
@@ -1414,7 +1388,7 @@ class SeparateCompilerVisitor
                self.require_declaration(mtype.const_color)
                var col = mtype.const_color
                self.add("if({col} == -1) \{")
-               self.add("fprintf(stderr, \"Resolution of a dead open type: %s\\n\", \"{mtype.to_s.escape_to_c}\");")
+               self.add("PRINT_ERROR(\"Resolution of a dead open type: %s\\n\", \"{mtype.to_s.escape_to_c}\");")
                self.add_abort("open type dead")
                self.add("\}")
        end
@@ -1427,7 +1401,7 @@ class SeparateCompilerVisitor
                add_abort("cast type null")
                add("\}")
                add("if({t}->id == -1 || {t}->color == -1) \{")
-               add("fprintf(stderr, \"Try to cast on a dead cast type: %s\\n\", {t}->name);")
+               add("PRINT_ERROR(\"Try to cast on a dead cast type: %s\\n\", {t}->name);")
                add_abort("cast type dead")
                add("\}")
        end
@@ -1514,7 +1488,7 @@ class SeparateCompilerVisitor
                                self.add("count_type_test_resolved_{tag}++;")
                        end
                else
-                       self.add("printf(\"NOT YET IMPLEMENTED: type_test(%s, {mtype}).\\n\", \"{value.inspect}\"); show_backtrace(1);")
+                       self.add("PRINT_ERROR(\"NOT YET IMPLEMENTED: type_test(%s, {mtype}).\\n\", \"{value.inspect}\"); show_backtrace(1);")
                end
 
                # check color is in table
@@ -1957,10 +1931,14 @@ redef class MClass
        end
 end
 
+interface PropertyLayoutElement end
+
 redef class MProperty
+       super PropertyLayoutElement
        fun const_color: String do return "COLOR_{c_name}"
 end
 
 redef class MPropDef
+       super PropertyLayoutElement
        fun const_color: String do return "COLOR_{c_name}"
 end