src: remove remaining references of subclasses on AMethPropdef
[nit.git] / src / separate_compiler.nit
index b701cb7..071b706 100644 (file)
@@ -35,6 +35,12 @@ redef class ToolContext
        var opt_inline_some_methods: OptionBool = new OptionBool("Allow the separate compiler to inline some methods (semi-global)", "--inline-some-methods")
        # --direct-call-monomorph
        var opt_direct_call_monomorph: OptionBool = new OptionBool("Allow the separate compiler to direct call monomorph sites (semi-global)", "--direct-call-monomorph")
+       # --skip-dead-methods
+       var opt_skip_dead_methods = new OptionBool("Do not compile dead methods (semi-global)", "--skip-dead-methods")
+       # --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")
        # --use-naive-coloring
        var opt_bm_typing: OptionBool = new OptionBool("Colorize items incrementaly, used to simulate binary matrix typing", "--bm-typing")
        # --use-mod-perfect-hashing
@@ -51,12 +57,26 @@ redef class ToolContext
                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)
-               self.option_context.add_option(self.opt_inline_coloring_numbers, opt_inline_some_methods, opt_direct_call_monomorph)
+               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_bm_typing)
                self.option_context.add_option(self.opt_phmod_typing)
                self.option_context.add_option(self.opt_phand_typing)
                self.option_context.add_option(self.opt_tables_metrics)
        end
+
+       redef fun process_options(args)
+       do
+               super
+
+               var tc = self
+               if tc.opt_semi_global.value then
+                       tc.opt_inline_coloring_numbers.value = true
+                       tc.opt_inline_some_methods.value = true
+                       tc.opt_direct_call_monomorph.value = true
+                       tc.opt_skip_dead_methods.value = true
+               end
+       end
 end
 
 redef class ModelBuilder
@@ -248,6 +268,8 @@ class SeparateCompiler
        fun do_property_coloring do
                var mclasses = new HashSet[MClass].from(modelbuilder.model.mclasses)
 
+               var rta = runtime_type_analysis
+
                # Layouts
                var method_layout_builder: PropertyLayoutBuilder[PropertyLayoutElement]
                var attribute_layout_builder: PropertyLayoutBuilder[MAttribute]
@@ -269,6 +291,9 @@ class SeparateCompiler
                attribute_layout_builder = new MPropertyColorer[MAttribute](self.mainmodule, class_layout_builder)
                #end
 
+               # The dead methods, still need to provide a dead color symbol
+               var dead_methods = new Array[MMethod]
+
                # lookup properties to build layout with
                var mmethods = new HashMap[MClass, Set[PropertyLayoutElement]]
                var mattributes = new HashMap[MClass, Set[MAttribute]]
@@ -277,6 +302,10 @@ 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
+                                               dead_methods.add(mprop)
+                                               continue
+                                       end
                                        mmethods[mclass].add(mprop)
                                else if mprop isa MAttribute then
                                        mattributes[mclass].add(mprop)
@@ -299,8 +328,8 @@ class SeparateCompiler
 
                # lookup super calls and add it to the list of mmethods to build layout with
                var super_calls
-               if runtime_type_analysis != null then
-                       super_calls = runtime_type_analysis.live_super_sends
+               if rta != null then
+                       super_calls = rta.live_super_sends
                else
                        super_calls = all_super_calls
                end
@@ -318,7 +347,10 @@ class SeparateCompiler
                self.method_tables = build_method_tables(mclasses, super_calls)
                self.compile_color_consts(method_layout.pos)
 
-               # attribute null color to dead supercalls
+               # attribute null color to dead methods and supercalls
+               for mproperty in dead_methods do
+                       compile_color_const(new_visitor, mproperty, -1)
+               end
                for mpropdef in all_super_calls do
                        if super_calls.has(mpropdef) then continue
                        compile_color_const(new_visitor, mpropdef, -1)
@@ -348,6 +380,7 @@ 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 table.length <= color then
                                                for i in [table.length .. color[ do
@@ -374,6 +407,7 @@ 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 table.length <= color then
                                        for i in [table.length .. color[ do
@@ -605,6 +639,8 @@ class SeparateCompiler
                for cd in mmodule.mclassdefs do
                        for pd in cd.mpropdefs do
                                if not pd isa MMethodDef then continue
+                               var rta = runtime_type_analysis
+                               if modelbuilder.toolcontext.opt_skip_dead_methods.value and rta != null and not rta.live_methoddefs.has(pd) then continue
                                #print "compile {pd} @ {cd} @ {mmodule}"
                                var r = pd.separate_runtime_function
                                r.compile_to_c(self)
@@ -882,7 +918,9 @@ class SeparateCompiler
                if self.modelbuilder.toolcontext.opt_tables_metrics.value then
                        display_sizes
                end
-
+               if self.modelbuilder.toolcontext.opt_isset_checks_metrics.value then
+                       display_isset_checks
+               end
                var tc = self.modelbuilder.toolcontext
                tc.info("# implementation of method invocation",2)
                var nb_invok_total = modelbuilder.nb_invok_by_tables + modelbuilder.nb_invok_by_direct + modelbuilder.nb_invok_by_inline
@@ -935,6 +973,16 @@ class SeparateCompiler
                print "\t{total}\t{holes}"
        end
 
+       protected var isset_checks_count = 0
+       protected var attr_read_count = 0
+
+       fun display_isset_checks do
+               print "# total number of compiled attribute reads"
+               print "\t{attr_read_count}"
+               print "# total number of compiled isset-checks"
+               print "\t{isset_checks_count}"
+       end
+
        redef fun compile_nitni_structs
        do
                self.header.add_decl("struct nitni_instance \{struct instance *value;\};")
@@ -1298,6 +1346,11 @@ class SeparateCompilerVisitor
                var intromclassdef = a.intro.mclassdef
                ret = ret.resolve_for(intromclassdef.bound_mtype, intromclassdef.bound_mtype, intromclassdef.mmodule, true)
 
+               if self.compiler.modelbuilder.toolcontext.opt_isset_checks_metrics.value then
+                       self.compiler.attr_read_count += 1
+                       self.add("count_attr_reads++;")
+               end
+
                self.require_declaration(a.const_color)
                if self.compiler.modelbuilder.toolcontext.opt_no_union_attribute.value then
                        # Get the attribute or a box (ie. always a val*)
@@ -1308,10 +1361,15 @@ class SeparateCompilerVisitor
                        self.add("{res} = {recv}->attrs[{a.const_color}]; /* {a} on {recv.inspect} */")
 
                        # Check for Uninitialized attribute
-                       if not ret isa MNullableType and not self.compiler.modelbuilder.toolcontext.opt_no_check_initialization.value then
+                       if not ret isa MNullableType and not self.compiler.modelbuilder.toolcontext.opt_no_check_attr_isset.value then
                                self.add("if (unlikely({res} == NULL)) \{")
                                self.add_abort("Uninitialized attribute {a.name}")
                                self.add("\}")
+
+                               if self.compiler.modelbuilder.toolcontext.opt_isset_checks_metrics.value then
+                                       self.compiler.isset_checks_count += 1
+                                       self.add("count_isset_checks++;")
+                               end
                        end
 
                        # Return the attribute or its unboxed version
@@ -1322,10 +1380,14 @@ class SeparateCompilerVisitor
                        self.add("{res} = {recv}->attrs[{a.const_color}].{ret.ctypename}; /* {a} on {recv.inspect} */")
 
                        # Check for Uninitialized attribute
-                       if ret.ctype == "val*" and not ret isa MNullableType and not self.compiler.modelbuilder.toolcontext.opt_no_check_initialization.value then
+                       if ret.ctype == "val*" and not ret isa MNullableType and not self.compiler.modelbuilder.toolcontext.opt_no_check_attr_isset.value then
                                self.add("if (unlikely({res} == NULL)) \{")
                                self.add_abort("Uninitialized attribute {a.name}")
                                self.add("\}")
+                               if self.compiler.modelbuilder.toolcontext.opt_isset_checks_metrics.value then
+                                       self.compiler.isset_checks_count += 1
+                                       self.add("count_isset_checks++;")
+                               end
                        end
 
                        return res