From 941a8dda71e154c7a1e5d3aba3b439ea9541c931 Mon Sep 17 00:00:00 2001 From: Jean-Sebastien Gelinas Date: Wed, 21 Oct 2009 17:20:18 -0400 Subject: [PATCH] analysis: add an optimization to remove 'getter' tests when called outside an init Signed-off-by: Jean-Sebastien Gelinas Signed-off-by: Jean Privat --- src/analysis/analysis.nit | 3 ++ src/analysis/remove_out_of_init_get_test.nit | 54 ++++++++++++++++++++++++++ src/nitc.nit | 4 +- 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/analysis/remove_out_of_init_get_test.nit diff --git a/src/analysis/analysis.nit b/src/analysis/analysis.nit index 533175e..91e9a9d 100644 --- a/src/analysis/analysis.nit +++ b/src/analysis/analysis.nit @@ -42,12 +42,14 @@ import reachable_from_init_method_analysis_impl # Global Optimizations import dead_method_removal import inline_get_and_set +import remove_out_of_init_get_test redef class ToolContext readable writable var _global_callgraph: String = "rta" readable writable var _no_dead_method_removal: Bool = false readable writable var _no_inline_get_set: Bool = false readable writable var _no_callgraph_from_init: Bool = false + readable writable var _no_out_of_init_get_test_removal: Bool = false end redef class Program @@ -95,6 +97,7 @@ redef class Program fun do_global_post_analysis_optimizations do assert tc.global if not tc.no_dead_method_removal then optimize_dead_methods + if not tc.no_out_of_init_get_test_removal then optimize_out_of_init_getters end # This method will create log files storing analysis information diff --git a/src/analysis/remove_out_of_init_get_test.nit b/src/analysis/remove_out_of_init_get_test.nit new file mode 100644 index 0000000..0e8b46d --- /dev/null +++ b/src/analysis/remove_out_of_init_get_test.nit @@ -0,0 +1,54 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2009 Jean-Sebastien Gelinas +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This package introduces an optimization that removes 'get' tests when +# not reachable from an initializer +package remove_out_of_init_get_test + +import reachable_from_init_method_analysis + +redef class Program + # Calling this method will remove all 'isset' that were generated automaticaly + # before a attribute read if this attribute read is done in a method that + # cannot be reached by a initializer + fun optimize_out_of_init_getters do + with_each_iroutines !action(i,m) do + if not rfima.is_iroutine_reachable_from_init(i) then + var remover = new GetterTestRemover + remover.visit_iroutine(i) + end + end + end +end + +class GetterTestRemover +special ICodeVisitor + redef fun visit_icode(ic) + do + # Replace 'x = isset(y)' by 'x = true' + if ic isa IAttrIsset then + var result = ic.result + assert result != null + var e = new INative("TAG_Bool(true)", null) + e.is_pure = true + e.result = result + current_icode.insert_before(e) + current_icode.delete + end + + super + end +end diff --git a/src/nitc.nit b/src/nitc.nit index 8a3ca9d..46fbf1a 100644 --- a/src/nitc.nit +++ b/src/nitc.nit @@ -33,6 +33,7 @@ special AbstractCompiler readable var _opt_global_no_STF_opt: OptionBool = new OptionBool("Do not use SFT optimization", "--no-global-SFT-optimization") readable var _opt_global_no_DMR_opt: OptionBool = new OptionBool("Do not use dead method removal optimization", "--no-global-DMR-optimization") readable var _opt_global_no_inline_get_set: OptionBool = new OptionBool("Do not automatically inline getters/setters", "--no-global-get-set-inlining") + readable var _opt_global_no_out_of_init_get_test_opt: OptionBool = new OptionBool("Do not remove get tests outside object initialization", "--no-global-OOIT-optimization") readable var _opt_global_no_RFIMA: OptionBool = new OptionBool("Do not use a specialized algorithm to find reachable methods from initializers", "--no-global-RFIM-analysis") readable var _opt_global_callgraph: OptionEnum = new OptionEnum(["none", "cha", "rta"], "The algorithm to use to build the callgraph", 2, "--global-callgraph") readable var _opt_clibdir: OptionString = new OptionString("NIT C library directory", "--clibdir") @@ -44,7 +45,7 @@ special AbstractCompiler init do super("nitc") - option_context.add_option(opt_output, opt_boost, opt_no_cc, opt_global, opt_clibdir, opt_bindir, opt_compdir, opt_extension_prefix, opt_dump, opt_global_no_STF_opt, opt_global_no_DMR_opt, opt_global_callgraph, opt_global_no_inline_get_set, opt_global_no_RFIMA) + option_context.add_option(opt_output, opt_boost, opt_no_cc, opt_global, opt_clibdir, opt_bindir, opt_compdir, opt_extension_prefix, opt_dump, opt_global_no_STF_opt, opt_global_no_DMR_opt, opt_global_callgraph, opt_global_no_inline_get_set, opt_global_no_RFIMA, opt_global_no_out_of_init_get_test_opt) end redef fun process_options @@ -60,6 +61,7 @@ special AbstractCompiler no_dead_method_removal = opt_global_no_DMR_opt.value no_inline_get_set = opt_global_no_inline_get_set.value no_callgraph_from_init = opt_global_no_RFIMA.value + no_out_of_init_get_test_removal = opt_global_no_out_of_init_get_test_opt.value global_callgraph = opt_global_callgraph.value_name compdir = opt_compdir.value if compdir == null then -- 1.7.9.5