nitg-s: cleaned useless ClassColoring uses
[nit.git] / src / separate_compiler.nit
index 34e378f..cd9768b 100644 (file)
@@ -16,7 +16,8 @@
 module separate_compiler
 
 import abstract_compiler
-import coloring
+intrude import coloring
+import rapid_type_analysis
 
 # Add separate compiler specific options
 redef class ToolContext
@@ -105,9 +106,9 @@ class SeparateCompiler
 
        private var undead_types: Set[MType] = new HashSet[MType]
        private var partial_types: Set[MType] = new HashSet[MType]
-       protected var typeids: HashMap[MType, Int] protected writable = new HashMap[MType, Int]
 
-       private var type_colors: Map[MType, Int] = typeids
+       private var type_layout_builder: TypeLayoutBuilder
+       private var type_layout: nullable TypeLayout
        private var type_tables: nullable Map[MType, Array[nullable MType]] = null
 
        private var live_unanchored_types: Map[MClassDef, Set[MType]] = new HashMap[MClassDef, HashSet[MType]]
@@ -116,8 +117,6 @@ class SeparateCompiler
        private var unanchored_types_tables: nullable Map[MClassType, Array[nullable MType]]
        private var unanchored_types_masks: nullable Map[MClassType, Int]
 
-       protected var class_coloring: ClassColoring
-
        protected var method_colors: Map[MMethod, Int]
        protected var method_tables: Map[MClass, Array[nullable MMethodDef]]
 
@@ -135,11 +134,27 @@ class SeparateCompiler
        init(mainmodule: MModule, mmbuilder: ModelBuilder, runtime_type_analysis: RapidTypeAnalysis) do
                super
                self.header = new_visitor
+               self.init_layout_builders
                self.runtime_type_analysis = runtime_type_analysis
                self.do_property_coloring
                self.compile_box_kinds
        end
 
+       protected fun init_layout_builders do
+               # Typing Layout
+               if modelbuilder.toolcontext.opt_bm_typing.value then
+                       self.type_layout_builder = new BMTypeLayoutBuilder(self.mainmodule)
+               else if modelbuilder.toolcontext.opt_phmod_typing.value then
+                       self.type_layout_builder = new PHTypeLayoutBuilder(self.mainmodule, new PHModOperator)
+                       self.header.add_decl("#define HASH(mask, id) ((mask)%(id))")
+               else if modelbuilder.toolcontext.opt_phand_typing.value then
+                       self.type_layout_builder = new PHTypeLayoutBuilder(self.mainmodule, new PHAndOperator)
+                       self.header.add_decl("#define HASH(mask, id) ((mask)&(id))")
+               else
+                       self.type_layout_builder = new CLTypeLayoutBuilder(self.mainmodule)
+               end
+       end
+
        redef fun compile_header_structs do
                self.header.add_decl("typedef void(*nitmethod_t)(void); /* general C type representing a Nit method. */")
                self.compile_header_attribute_structs
@@ -223,43 +238,38 @@ class SeparateCompiler
 
                # classes coloration
                var mclasses = new HashSet[MClass].from(modelbuilder.model.mclasses)
-               self.class_coloring = new ClassColoring(mainmodule)
+               var class_coloring = new ClassColoring(mainmodule)
                class_coloring.colorize(mclasses)
 
                # methods coloration
-               var method_coloring = new MethodColoring(self.class_coloring)
+               var method_coloring = new MethodColoring(class_coloring)
                self.method_colors = method_coloring.colorize
                self.method_tables = method_coloring.build_property_tables
                self.compile_color_consts(self.method_colors)
 
                # attributes coloration
-               var attribute_coloring = new AttributeColoring(self.class_coloring)
+               var attribute_coloring = new AttributeColoring(class_coloring)
                self.attr_colors = attribute_coloring.colorize
                self.attr_tables = attribute_coloring.build_property_tables
                self.compile_color_consts(self.attr_colors)
 
-               if modelbuilder.toolcontext.opt_bm_typing.value then
-                       self.class_coloring = new NaiveClassColoring(mainmodule)
-                       self.class_coloring.colorize(mclasses)
-               end
-
                # vt coloration
                if modelbuilder.toolcontext.opt_bm_typing.value then
-                       var vt_coloring = new NaiveVTColoring(self.class_coloring)
+                       var vt_coloring = new NaiveVTColoring(class_coloring)
                        self.vt_colors = vt_coloring.colorize
                        self.vt_tables = vt_coloring.build_property_tables
                else if modelbuilder.toolcontext.opt_phmod_typing.value then
-                       var vt_coloring = new VTModPerfectHashing(self.class_coloring)
+                       var vt_coloring = new VTModPerfectHashing(class_coloring)
                        self.vt_colors = vt_coloring.colorize
                        self.vt_masks = vt_coloring.compute_masks
                        self.vt_tables = vt_coloring.build_property_tables
                else if modelbuilder.toolcontext.opt_phand_typing.value then
-                       var vt_coloring = new VTAndPerfectHashing(self.class_coloring)
+                       var vt_coloring = new VTAndPerfectHashing(class_coloring)
                        self.vt_colors = vt_coloring.colorize
                        self.vt_masks = vt_coloring.compute_masks
                        self.vt_tables = vt_coloring.build_property_tables
                else
-                       var vt_coloring = new VTColoring(self.class_coloring)
+                       var vt_coloring = new VTColoring(class_coloring)
                        self.vt_colors = vt_coloring.colorize
                        self.vt_tables = vt_coloring.build_property_tables
                end
@@ -281,48 +291,43 @@ class SeparateCompiler
                end
                mtypes.add_all(self.partial_types)
 
-               # set type unique id
-               if modelbuilder.toolcontext.opt_phmod_typing.value or modelbuilder.toolcontext.opt_phand_typing.value then
-                       var sorted_mtypes = new Array[MType].from(mtypes)
-                       var sorter = new ReverseTypeSorter(self.mainmodule)
-                       sorter.sort(sorted_mtypes)
-                       for mtype in sorted_mtypes do
-                               self.typeids[mtype] = self.typeids.length + 1
-                       end
-               else
-                       for mtype in mtypes do
-                               self.typeids[mtype] = self.typeids.length
-                       end
-               end
-
                # VT and FT are stored with other unresolved types in the big unanchored_tables
                self.compile_unanchored_tables(mtypes)
 
                # colorize types
-               if modelbuilder.toolcontext.opt_bm_typing.value then
-                       var type_coloring = new NaiveTypeColoring(self.mainmodule)
-                       self.type_colors = type_coloring.colorize(mtypes)
-                       self.type_tables = type_coloring.build_type_tables(mtypes, type_colors)
-               else if modelbuilder.toolcontext.opt_phmod_typing.value then
-                       var type_coloring = new TypeModPerfectHashing(self.mainmodule)
-                       self.type_colors = type_coloring.compute_masks(mtypes, typeids)
-                       self.type_tables = type_coloring.hash_type_tables(mtypes, typeids, type_colors)
-                       self.header.add_decl("#define HASH(mask, id) ((mask)%(id))")
-               else if modelbuilder.toolcontext.opt_phand_typing.value then
-                       var type_coloring = new TypeAndPerfectHashing(self.mainmodule)
-                       self.type_colors = type_coloring.compute_masks(mtypes, typeids)
-                       self.type_tables = type_coloring.hash_type_tables(mtypes, typeids, type_colors)
-                       self.header.add_decl("#define HASH(mask, id) ((mask)&(id))")
-               else
-                       var type_coloring = new TypeColoring(self.mainmodule)
-                       self.type_colors = type_coloring.colorize(mtypes)
-                       self.type_tables = type_coloring.build_type_tables(mtypes, type_colors)
-               end
-
-
+               self.type_layout = self.type_layout_builder.build_layout(mtypes)
+               self.type_tables = self.build_type_tables(mtypes)
                return mtypes
        end
 
+       # Build type tables
+       fun build_type_tables(mtypes: Set[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]
+                       var supers = new HashSet[MType]
+                       supers.add_all(self.mainmodule.super_mtypes(mtype, mtypes))
+                       supers.add(mtype)
+                       for sup in supers do
+                               var color: Int
+                               if layout isa PHTypeLayout then
+                                       color = layout.hashes[mtype][sup]
+                               else
+                                       color = layout.pos[sup]
+                               end
+                               if table.length <= color then
+                                       for i in [table.length .. color[ do
+                                               table[i] = null
+                                       end
+                               end
+                               table[color] = sup
+                       end
+                       tables[mtype] = table
+               end
+               return tables
+       end
+
        protected fun compile_unanchored_tables(mtypes: Set[MType]) do
                # Unanchored_tables is used to perform a type resolution at runtime in O(1)
 
@@ -455,9 +460,14 @@ class SeparateCompiler
 
                # const struct type_X
                v.add_decl("const struct type_{c_name} type_{c_name} = \{")
-               v.add_decl("{self.typeids[mtype]},")
+               v.add_decl("{self.type_layout.ids[mtype]},")
                v.add_decl("\"{mtype}\", /* class_name_string */")
-               v.add_decl("{self.type_colors[mtype]},")
+               var layout = self.type_layout
+               if layout isa PHTypeLayout then
+                       v.add_decl("{layout.masks[mtype]},")
+               else
+                       v.add_decl("{layout.pos[mtype]},")
+               end
                if mtype isa MNullableType then
                        v.add_decl("1,")
                else
@@ -474,7 +484,7 @@ class SeparateCompiler
                        if stype == null then
                                v.add_decl("-1, /* empty */")
                        else
-                               v.add_decl("{self.typeids[stype]}, /* {stype} */")
+                               v.add_decl("{self.type_layout.ids[stype]}, /* {stype} */")
                        end
                end
                v.add_decl("\},")
@@ -517,7 +527,7 @@ class SeparateCompiler
                                else
                                        ntype = ft.anchor_to(self.mainmodule, mclass_type)
                                end
-                               if self.typeids.has_key(ntype) then
+                               if self.type_layout.ids.has_key(ntype) then
                                        v.add_decl("(struct type*)&type_{ntype.c_name}, /* {ft} ({ntype}) */")
                                else
                                        v.add_decl("NULL, /* empty ({ft} not a live type) */")
@@ -583,7 +593,7 @@ class SeparateCompiler
                                                abort
                                        end
 
-                                       if self.typeids.has_key(bound) then
+                                       if self.type_layout.ids.has_key(bound) then
                                                v.add_decl("(struct type*)&type_{is_nullable}{bound.c_name}, /* {bound} */")
                                        else
                                                v.add_decl("NULL, /* dead type {bound} */")
@@ -632,7 +642,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.typeids.has_key(tv) then
+                               if self.type_layout.ids.has_key(tv) then
                                        v.add_decl("(struct type*)&type_{tv.c_name}, /* {t}: {tv} */")
                                else
                                        v.add_decl("NULL, /* empty ({t}: {tv} not a live type) */")