diff options
author | Mathieu Chartier <mathieuc@google.com> | 2015-01-29 01:17:10 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-01-29 01:17:11 +0000 |
commit | 4a50662eeaa0b1a26be66e7584fb765151dabc59 (patch) | |
tree | 0f298a17285fd845303472e2c27ccd69f586feac | |
parent | f08c6506858ff06d61c8f7ca2741409cd62142f5 (diff) | |
parent | 5bdab12d8b48ca4c395d9d2c506ebff0df01b734 (diff) | |
download | art-4a50662eeaa0b1a26be66e7584fb765151dabc59.zip art-4a50662eeaa0b1a26be66e7584fb765151dabc59.tar.gz art-4a50662eeaa0b1a26be66e7584fb765151dabc59.tar.bz2 |
Merge "Clean up pass driver"
-rw-r--r-- | compiler/Android.mk | 2 | ||||
-rw-r--r-- | compiler/common_compiler_test.cc | 3 | ||||
-rw-r--r-- | compiler/compiler.cc | 2 | ||||
-rw-r--r-- | compiler/dex/mir_graph.cc | 6 | ||||
-rw-r--r-- | compiler/dex/pass_driver.h | 118 | ||||
-rw-r--r-- | compiler/dex/pass_driver_me.h | 70 | ||||
-rw-r--r-- | compiler/dex/pass_driver_me_opts.cc | 87 | ||||
-rw-r--r-- | compiler/dex/pass_driver_me_opts.h | 13 | ||||
-rw-r--r-- | compiler/dex/pass_driver_me_post_opt.cc | 78 | ||||
-rw-r--r-- | compiler/dex/pass_driver_me_post_opt.h | 10 | ||||
-rw-r--r-- | compiler/dex/pass_manager.cc | 50 | ||||
-rw-r--r-- | compiler/dex/pass_manager.h | 150 | ||||
-rw-r--r-- | compiler/dex/pass_me.h | 19 | ||||
-rw-r--r-- | compiler/dex/quick/quick_compiler.cc | 72 | ||||
-rw-r--r-- | compiler/dex/quick/quick_compiler.h | 60 | ||||
-rw-r--r-- | compiler/dex/quick/quick_compiler_factory.h | 29 | ||||
-rw-r--r-- | compiler/driver/compiler_options.cc | 80 | ||||
-rw-r--r-- | compiler/driver/compiler_options.h | 48 | ||||
-rw-r--r-- | compiler/oat_test.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_unit_test.h | 1 | ||||
-rw-r--r-- | dex2oat/dex2oat.cc | 32 |
21 files changed, 573 insertions, 360 deletions
diff --git a/compiler/Android.mk b/compiler/Android.mk index 27c6daf..4f4d075 100644 --- a/compiler/Android.mk +++ b/compiler/Android.mk @@ -69,12 +69,14 @@ LIBART_COMPILER_SRC_FILES := \ dex/post_opt_passes.cc \ dex/pass_driver_me_opts.cc \ dex/pass_driver_me_post_opt.cc \ + dex/pass_manager.cc \ dex/ssa_transformation.cc \ dex/verified_method.cc \ dex/verification_results.cc \ dex/vreg_analysis.cc \ dex/quick_compiler_callbacks.cc \ driver/compiler_driver.cc \ + driver/compiler_options.cc \ driver/dex_compilation_unit.cc \ jni/quick/arm/calling_convention_arm.cc \ jni/quick/arm64/calling_convention_arm64.cc \ diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc index 96f8e0c..1cd78f8 100644 --- a/compiler/common_compiler_test.cc +++ b/compiler/common_compiler_test.cc @@ -19,9 +19,10 @@ #include "arch/instruction_set_features.h" #include "class_linker.h" #include "compiled_method.h" +#include "dex/pass_manager.h" #include "dex/quick_compiler_callbacks.h" -#include "dex/verification_results.h" #include "dex/quick/dex_file_to_method_inliner_map.h" +#include "dex/verification_results.h" #include "driver/compiler_driver.h" #include "interpreter/interpreter.h" #include "mirror/art_method.h" diff --git a/compiler/compiler.cc b/compiler/compiler.cc index baa6688..5e8ec1e 100644 --- a/compiler/compiler.cc +++ b/compiler/compiler.cc @@ -17,7 +17,7 @@ #include "compiler.h" #include "base/logging.h" -#include "dex/quick/quick_compiler.h" +#include "dex/quick/quick_compiler_factory.h" #include "driver/compiler_driver.h" #include "optimizing/optimizing_compiler.h" diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc index db4141c..0f7d45d 100644 --- a/compiler/dex/mir_graph.cc +++ b/compiler/dex/mir_graph.cc @@ -30,6 +30,7 @@ #include "dex_instruction-inl.h" #include "driver/compiler_driver.h" #include "driver/dex_compilation_unit.h" +#include "dex/quick/quick_compiler.h" #include "leb128.h" #include "pass_driver_me_post_opt.h" #include "stack.h" @@ -2432,7 +2433,10 @@ BasicBlock* MIRGraph::CreateNewBB(BBType block_type) { } void MIRGraph::CalculateBasicBlockInformation() { - PassDriverMEPostOpt driver(cu_); + auto* quick_compiler = down_cast<QuickCompiler*>(cu_->compiler_driver->GetCompiler()); + DCHECK(quick_compiler != nullptr); + /* Create the pass driver and launch it */ + PassDriverMEPostOpt driver(quick_compiler->GetPostOptPassManager(), cu_); driver.Launch(); } diff --git a/compiler/dex/pass_driver.h b/compiler/dex/pass_driver.h index 632df38..671bcec 100644 --- a/compiler/dex/pass_driver.h +++ b/compiler/dex/pass_driver.h @@ -21,19 +21,14 @@ #include "base/logging.h" #include "pass.h" -#include "safe_map.h" +#include "pass_manager.h" namespace art { -/** - * @brief Helper function to create a single instance of a given Pass and can be shared across - * the threads. - */ -template <typename PassType> -const Pass* GetPassInstance() { - static const PassType pass; - return &pass; -} +class Pass; +class PassDataHolder; +class PassDriver; +class PassManager; // Empty holder for the constructor. class PassDriverDataHolder { @@ -43,11 +38,11 @@ class PassDriverDataHolder { * @class PassDriver * @brief PassDriver is the wrapper around all Pass instances in order to execute them */ -template <typename PassDriverType> class PassDriver { public: - explicit PassDriver() { - InitializePasses(); + explicit PassDriver(const PassManager* const pass_manager) : pass_manager_(pass_manager) { + pass_list_ = *pass_manager_->GetDefaultPassList(); + DCHECK(!pass_list_.empty()); } virtual ~PassDriver() { @@ -58,12 +53,12 @@ class PassDriver { */ void InsertPass(const Pass* new_pass) { DCHECK(new_pass != nullptr); - DCHECK(new_pass->GetName() != nullptr && new_pass->GetName()[0] != 0); + DCHECK(new_pass->GetName() != nullptr); + DCHECK_NE(new_pass->GetName()[0], 0); // It is an error to override an existing pass. DCHECK(GetPass(new_pass->GetName()) == nullptr) << "Pass name " << new_pass->GetName() << " already used."; - // Now add to the list. pass_list_.push_back(new_pass); } @@ -74,7 +69,8 @@ class PassDriver { */ virtual bool RunPass(const char* pass_name) { // Paranoid: c_unit cannot be nullptr and we need a pass name. - DCHECK(pass_name != nullptr && pass_name[0] != 0); + DCHECK(pass_name != nullptr); + DCHECK_NE(pass_name[0], 0); const Pass* cur_pass = GetPass(pass_name); @@ -108,21 +104,6 @@ class PassDriver { return nullptr; } - static void CreateDefaultPassList(const std::string& disable_passes) { - // Insert each pass from g_passes into g_default_pass_list. - PassDriverType::g_default_pass_list.clear(); - PassDriverType::g_default_pass_list.reserve(PassDriver<PassDriverType>::g_passes_size); - for (uint16_t i = 0; i < PassDriver<PassDriverType>::g_passes_size; ++i) { - const Pass* pass = PassDriver<PassDriverType>::g_passes[i]; - // Check if we should disable this pass. - if (disable_passes.find(pass->GetName()) != std::string::npos) { - LOG(INFO) << "Skipping " << pass->GetName(); - } else { - PassDriver<PassDriverType>::g_default_pass_list.push_back(pass); - } - } - } - /** * @brief Run a pass using the Pass itself. * @param time_split do we want a time split request(default: false)? @@ -130,57 +111,7 @@ class PassDriver { */ virtual bool RunPass(const Pass* pass, bool time_split = false) = 0; - /** - * @brief Print the pass names of all the passes available. - */ - static void PrintPassNames() { - LOG(INFO) << "Loop Passes are:"; - - for (const Pass* cur_pass : PassDriver<PassDriverType>::g_default_pass_list) { - LOG(INFO) << "\t-" << cur_pass->GetName(); - } - } - - /** - * @brief Gets the list of passes currently schedule to execute. - * @return pass_list_ - */ - std::vector<const Pass*>& GetPasses() { - return pass_list_; - } - - static void SetPrintAllPasses() { - default_print_passes_ = true; - } - - static void SetDumpPassList(const std::string& list) { - dump_pass_list_ = list; - } - - static void SetPrintPassList(const std::string& list) { - print_pass_list_ = list; - } - - /** - * @brief Used to set a string that contains the overridden pass options. - * @details An overridden pass option means that the pass uses this option - * instead of using its default option. - * @param s The string passed by user with overridden options. The string is in format - * Pass1Name:Pass1Option:Pass1Setting,Pass2Name:Pass2Option::Pass2Setting - */ - static void SetOverriddenPassOptions(const std::string& s) { - overridden_pass_options_list_ = s; - } - - void SetDefaultPasses() { - pass_list_ = PassDriver<PassDriverType>::g_default_pass_list; - } - protected: - virtual void InitializePasses() { - SetDefaultPasses(); - } - /** * @brief Apply a patch: perform start/work/end functions. */ @@ -189,6 +120,7 @@ class PassDriver { DispatchPass(pass); pass->End(data); } + /** * @brief Dispatch a patch. * Gives the ability to add logic when running the patch. @@ -197,29 +129,11 @@ class PassDriver { UNUSED(pass); } - /** @brief List of passes: provides the order to execute the passes. */ + /** @brief List of passes: provides the order to execute the passes. + * Passes are owned by pass_manager_. */ std::vector<const Pass*> pass_list_; - /** @brief The number of passes within g_passes. */ - static const uint16_t g_passes_size; - - /** @brief The number of passes within g_passes. */ - static const Pass* const g_passes[]; - - /** @brief The default pass list is used to initialize pass_list_. */ - static std::vector<const Pass*> g_default_pass_list; - - /** @brief Do we, by default, want to be printing the log messages? */ - static bool default_print_passes_; - - /** @brief What are the passes we want to be printing the log messages? */ - static std::string print_pass_list_; - - /** @brief What are the passes we want to be dumping the CFG? */ - static std::string dump_pass_list_; - - /** @brief String of all options that should be overridden for selected passes */ - static std::string overridden_pass_options_list_; + const PassManager* const pass_manager_; }; } // namespace art diff --git a/compiler/dex/pass_driver_me.h b/compiler/dex/pass_driver_me.h index ff7c4a4..fed92be 100644 --- a/compiler/dex/pass_driver_me.h +++ b/compiler/dex/pass_driver_me.h @@ -19,20 +19,25 @@ #include <cstdlib> #include <cstring> + #include "bb_optimizations.h" #include "dataflow_iterator.h" #include "dataflow_iterator-inl.h" #include "dex_flags.h" #include "pass_driver.h" +#include "pass_manager.h" #include "pass_me.h" +#include "safe_map.h" namespace art { -template <typename PassDriverType> -class PassDriverME: public PassDriver<PassDriverType> { +class PassManager; +class PassManagerOptions; + +class PassDriverME: public PassDriver { public: - explicit PassDriverME(CompilationUnit* cu) - : pass_me_data_holder_(), dump_cfg_folder_("/sdcard/") { + explicit PassDriverME(const PassManager* const pass_manager, CompilationUnit* cu) + : PassDriver(pass_manager), pass_me_data_holder_(), dump_cfg_folder_("/sdcard/") { pass_me_data_holder_.bb = nullptr; pass_me_data_holder_.c_unit = cu; } @@ -82,7 +87,7 @@ class PassDriverME: public PassDriver<PassDriverType> { } } - bool RunPass(const Pass* pass, bool time_split) { + bool RunPass(const Pass* pass, bool time_split) OVERRIDE { // Paranoid: c_unit and pass cannot be nullptr, and the pass should have a name DCHECK(pass != nullptr); DCHECK(pass->GetName() != nullptr && pass->GetName()[0] != 0); @@ -96,15 +101,17 @@ class PassDriverME: public PassDriver<PassDriverType> { // First, work on determining pass verbosity. bool old_print_pass = c_unit->print_pass; - c_unit->print_pass = PassDriver<PassDriverType>::default_print_passes_; - const char* print_pass_list = PassDriver<PassDriverType>::print_pass_list_.c_str(); - if (print_pass_list != nullptr && strstr(print_pass_list, pass->GetName()) != nullptr) { + c_unit->print_pass = pass_manager_->GetOptions().GetPrintAllPasses(); + auto* const options = &pass_manager_->GetOptions(); + const std::string& print_pass_list = options->GetPrintPassList(); + if (!print_pass_list.empty() && strstr(print_pass_list.c_str(), pass->GetName()) != nullptr) { c_unit->print_pass = true; } - // Next, check if there are any overridden settings for the pass that change default configuration. + // Next, check if there are any overridden settings for the pass that change default + // configuration. c_unit->overridden_pass_options.clear(); - FillOverriddenPassSettings(pass->GetName(), c_unit->overridden_pass_options); + FillOverriddenPassSettings(options, pass->GetName(), c_unit->overridden_pass_options); if (c_unit->print_pass) { for (auto setting_it : c_unit->overridden_pass_options) { LOG(INFO) << "Overridden option \"" << setting_it.first << ":" @@ -118,13 +125,12 @@ class PassDriverME: public PassDriver<PassDriverType> { // Applying the pass: first start, doWork, and end calls. this->ApplyPass(&pass_me_data_holder_, pass); - bool should_dump = ((c_unit->enable_debug & (1 << kDebugDumpCFG)) != 0); - - const char* dump_pass_list = PassDriver<PassDriverType>::dump_pass_list_.c_str(); + bool should_dump = (c_unit->enable_debug & (1 << kDebugDumpCFG)) != 0; - if (dump_pass_list != nullptr) { - bool found = strstr(dump_pass_list, pass->GetName()); - should_dump = (should_dump || found); + const std::string& dump_pass_list = pass_manager_->GetOptions().GetDumpPassList(); + if (!dump_pass_list.empty()) { + const bool found = strstr(dump_pass_list.c_str(), pass->GetName()); + should_dump = should_dump || found; } if (should_dump) { @@ -154,22 +160,23 @@ class PassDriverME: public PassDriver<PassDriverType> { return should_apply_pass; } - const char* GetDumpCFGFolder() const { - return dump_cfg_folder_; - } - - static void PrintPassOptions() { - for (auto pass : PassDriver<PassDriverType>::g_default_pass_list) { + static void PrintPassOptions(PassManager* manager) { + for (const auto* pass : *manager->GetDefaultPassList()) { const PassME* me_pass = down_cast<const PassME*>(pass); if (me_pass->HasOptions()) { LOG(INFO) << "Pass options for \"" << me_pass->GetName() << "\" are:"; SafeMap<const std::string, int> overridden_settings; - FillOverriddenPassSettings(me_pass->GetName(), overridden_settings); + FillOverriddenPassSettings(&manager->GetOptions(), me_pass->GetName(), + overridden_settings); me_pass->PrintPassOptions(overridden_settings); } } } + const char* GetDumpCFGFolder() const { + return dump_cfg_folder_; + } + protected: /** @brief The data holder that contains data needed for the PassDriverME. */ PassMEDataHolder pass_me_data_holder_; @@ -198,12 +205,15 @@ class PassDriverME: public PassDriver<PassDriverType> { } /** - * @brief Fills the settings_to_fill by finding all of the applicable options in the overridden_pass_options_list_. + * @brief Fills the settings_to_fill by finding all of the applicable options in the + * overridden_pass_options_list_. * @param pass_name The pass name for which to fill settings. - * @param settings_to_fill Fills the options to contain the mapping of name of option to the new configuration. + * @param settings_to_fill Fills the options to contain the mapping of name of option to the new + * configuration. */ - static void FillOverriddenPassSettings(const char* pass_name, SafeMap<const std::string, int>& settings_to_fill) { - const std::string& settings = PassDriver<PassDriverType>::overridden_pass_options_list_; + static void FillOverriddenPassSettings(const PassManagerOptions* options, const char* pass_name, + SafeMap<const std::string, int>& settings_to_fill) { + const std::string& settings = options->GetOverriddenPassOptions(); const size_t settings_len = settings.size(); // Before anything, check if we care about anything right now. @@ -277,10 +287,12 @@ class PassDriverME: public PassDriver<PassDriverType> { // Get the actual setting itself. Strtol is being used to convert because it is // exception safe. If the input is not sane, it will set a setting of 0. - std::string setting_string = settings.substr(setting_pos, next_configuration_separator - setting_pos); + std::string setting_string = + settings.substr(setting_pos, next_configuration_separator - setting_pos); int setting = std::strtol(setting_string.c_str(), 0, 0); - std::string setting_name = settings.substr(setting_name_pos, setting_pos - setting_name_pos - 1); + std::string setting_name = + settings.substr(setting_name_pos, setting_pos - setting_name_pos - 1); settings_to_fill.Put(setting_name, setting); diff --git a/compiler/dex/pass_driver_me_opts.cc b/compiler/dex/pass_driver_me_opts.cc index c2b6b91..8c8bde6 100644 --- a/compiler/dex/pass_driver_me_opts.cc +++ b/compiler/dex/pass_driver_me_opts.cc @@ -21,77 +21,44 @@ #include "bb_optimizations.h" #include "dataflow_iterator.h" #include "dataflow_iterator-inl.h" +#include "pass_driver_me_opts.h" +#include "pass_manager.h" #include "post_opt_passes.h" namespace art { -/* - * Create the pass list. These passes are immutable and are shared across the threads. - * - * Advantage is that there will be no race conditions here. - * Disadvantage is the passes can't change their internal states depending on CompilationUnit: - * - This is not yet an issue: no current pass would require it. - */ -// The initial list of passes to be used by the PassDriveMEOpts. -template<> -const Pass* const PassDriver<PassDriverMEOpts>::g_passes[] = { - GetPassInstance<CacheFieldLoweringInfo>(), - GetPassInstance<CacheMethodLoweringInfo>(), - GetPassInstance<CalculatePredecessors>(), - GetPassInstance<DFSOrders>(), - GetPassInstance<ClassInitCheckElimination>(), - GetPassInstance<SpecialMethodInliner>(), - GetPassInstance<NullCheckElimination>(), - GetPassInstance<BBCombine>(), - GetPassInstance<CodeLayout>(), - GetPassInstance<GlobalValueNumberingPass>(), - GetPassInstance<ConstantPropagation>(), - GetPassInstance<MethodUseCount>(), - GetPassInstance<BBOptimizations>(), - GetPassInstance<SuspendCheckElimination>(), -}; - -// The number of the passes in the initial list of Passes (g_passes). -template<> -uint16_t const PassDriver<PassDriverMEOpts>::g_passes_size = - arraysize(PassDriver<PassDriverMEOpts>::g_passes); - -// The default pass list is used by the PassDriverME instance of PassDriver -// to initialize pass_list_. -template<> -std::vector<const Pass*> PassDriver<PassDriverMEOpts>::g_default_pass_list( - PassDriver<PassDriverMEOpts>::g_passes, - PassDriver<PassDriverMEOpts>::g_passes + - PassDriver<PassDriverMEOpts>::g_passes_size); - -// By default, do not have a dump pass list. -template<> -std::string PassDriver<PassDriverMEOpts>::dump_pass_list_ = std::string(); - -// By default, do not have a print pass list. -template<> -std::string PassDriver<PassDriverMEOpts>::print_pass_list_ = std::string(); - -// By default, we do not print the pass' information. -template<> -bool PassDriver<PassDriverMEOpts>::default_print_passes_ = false; - -// By default, there are no overridden pass settings. -template<> -std::string PassDriver<PassDriverMEOpts>::overridden_pass_options_list_ = std::string(); +void PassDriverMEOpts::SetupPasses(PassManager* pass_manager) { + /* + * Create the pass list. These passes are immutable and are shared across the threads. + * + * Advantage is that there will be no race conditions here. + * Disadvantage is the passes can't change their internal states depending on CompilationUnit: + * - This is not yet an issue: no current pass would require it. + */ + pass_manager->AddPass(new CacheFieldLoweringInfo); + pass_manager->AddPass(new CacheMethodLoweringInfo); + pass_manager->AddPass(new CalculatePredecessors); + pass_manager->AddPass(new DFSOrders); + pass_manager->AddPass(new ClassInitCheckElimination); + pass_manager->AddPass(new SpecialMethodInliner); + pass_manager->AddPass(new NullCheckElimination); + pass_manager->AddPass(new BBCombine); + pass_manager->AddPass(new CodeLayout); + pass_manager->AddPass(new GlobalValueNumberingPass); + pass_manager->AddPass(new ConstantPropagation); + pass_manager->AddPass(new MethodUseCount); + pass_manager->AddPass(new BBOptimizations); + pass_manager->AddPass(new SuspendCheckElimination); +} void PassDriverMEOpts::ApplyPass(PassDataHolder* data, const Pass* pass) { - const PassME* pass_me = down_cast<const PassME*> (pass); + const PassME* const pass_me = down_cast<const PassME*>(pass); DCHECK(pass_me != nullptr); - - PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data); - + PassMEDataHolder* const pass_me_data_holder = down_cast<PassMEDataHolder*>(data); // Set to dirty. pass_me_data_holder->dirty = true; - // First call the base class' version. PassDriver::ApplyPass(data, pass); - // Now we care about flags. if ((pass_me->GetFlag(kOptimizationBasicBlockChange) == true) || (pass_me->GetFlag(kOptimizationDefUsesChange) == true)) { diff --git a/compiler/dex/pass_driver_me_opts.h b/compiler/dex/pass_driver_me_opts.h index 0a5b5ae..b930d02 100644 --- a/compiler/dex/pass_driver_me_opts.h +++ b/compiler/dex/pass_driver_me_opts.h @@ -25,19 +25,26 @@ namespace art { struct CompilationUnit; class Pass; class PassDataHolder; +class PassManager; -class PassDriverMEOpts : public PassDriverME<PassDriverMEOpts> { +class PassDriverMEOpts : public PassDriverME { public: - explicit PassDriverMEOpts(CompilationUnit* cu):PassDriverME<PassDriverMEOpts>(cu) { + explicit PassDriverMEOpts(const PassManager* const manager, CompilationUnit* cu) + : PassDriverME(manager, cu) { } ~PassDriverMEOpts() { } /** + * @brief Write and allocate corresponding passes into the pass manager. + */ + static void SetupPasses(PassManager* pass_manasger); + + /** * @brief Apply a patch: perform start/work/end functions. */ - virtual void ApplyPass(PassDataHolder* data, const Pass* pass); + virtual void ApplyPass(PassDataHolder* data, const Pass* pass) OVERRIDE; }; } // namespace art diff --git a/compiler/dex/pass_driver_me_post_opt.cc b/compiler/dex/pass_driver_me_post_opt.cc index 5f0c65c..4e13227 100644 --- a/compiler/dex/pass_driver_me_post_opt.cc +++ b/compiler/dex/pass_driver_me_post_opt.cc @@ -14,63 +14,35 @@ * limitations under the License. */ +#include "pass_driver_me_post_opt.h" + #include "base/macros.h" #include "post_opt_passes.h" -#include "pass_driver_me_post_opt.h" +#include "pass_manager.h" namespace art { -/* - * Create the pass list. These passes are immutable and are shared across the threads. - * - * Advantage is that there will be no race conditions here. - * Disadvantage is the passes can't change their internal states depending on CompilationUnit: - * - This is not yet an issue: no current pass would require it. - */ -// The initial list of passes to be used by the PassDriveMEPostOpt. -template<> -const Pass* const PassDriver<PassDriverMEPostOpt>::g_passes[] = { - GetPassInstance<DFSOrders>(), - GetPassInstance<BuildDomination>(), - GetPassInstance<TopologicalSortOrders>(), - GetPassInstance<InitializeSSATransformation>(), - GetPassInstance<ClearPhiInstructions>(), - GetPassInstance<DefBlockMatrix>(), - GetPassInstance<CreatePhiNodes>(), - GetPassInstance<SSAConversion>(), - GetPassInstance<PhiNodeOperands>(), - GetPassInstance<PerformInitRegLocations>(), - GetPassInstance<TypeInference>(), - GetPassInstance<FinishSSATransformation>(), -}; - -// The number of the passes in the initial list of Passes (g_passes). -template<> -uint16_t const PassDriver<PassDriverMEPostOpt>::g_passes_size = - arraysize(PassDriver<PassDriverMEPostOpt>::g_passes); - -// The default pass list is used by the PassDriverME instance of PassDriver -// to initialize pass_list_. -template<> -std::vector<const Pass*> PassDriver<PassDriverMEPostOpt>::g_default_pass_list( - PassDriver<PassDriverMEPostOpt>::g_passes, - PassDriver<PassDriverMEPostOpt>::g_passes + - PassDriver<PassDriverMEPostOpt>::g_passes_size); - -// By default, do not have a dump pass list. -template<> -std::string PassDriver<PassDriverMEPostOpt>::dump_pass_list_ = std::string(); - -// By default, do not have a print pass list. -template<> -std::string PassDriver<PassDriverMEPostOpt>::print_pass_list_ = std::string(); - -// By default, we do not print the pass' information. -template<> -bool PassDriver<PassDriverMEPostOpt>::default_print_passes_ = false; - -// By default, there are no overridden pass settings. -template<> -std::string PassDriver<PassDriverMEPostOpt>::overridden_pass_options_list_ = std::string(); +void PassDriverMEPostOpt::SetupPasses(PassManager* pass_manager) { + /* + * Create the pass list. These passes are immutable and are shared across the threads. + * + * Advantage is that there will be no race conditions here. + * Disadvantage is the passes can't change their internal states depending on CompilationUnit: + * - This is not yet an issue: no current pass would require it. + */ + // The initial list of passes to be used by the PassDriveMEPostOpt. + pass_manager->AddPass(new DFSOrders); + pass_manager->AddPass(new BuildDomination); + pass_manager->AddPass(new TopologicalSortOrders); + pass_manager->AddPass(new InitializeSSATransformation); + pass_manager->AddPass(new ClearPhiInstructions); + pass_manager->AddPass(new DefBlockMatrix); + pass_manager->AddPass(new CreatePhiNodes); + pass_manager->AddPass(new SSAConversion); + pass_manager->AddPass(new PhiNodeOperands); + pass_manager->AddPass(new PerformInitRegLocations); + pass_manager->AddPass(new TypeInference); + pass_manager->AddPass(new FinishSSATransformation); +} } // namespace art diff --git a/compiler/dex/pass_driver_me_post_opt.h b/compiler/dex/pass_driver_me_post_opt.h index 574a6ba..9e03c4e 100644 --- a/compiler/dex/pass_driver_me_post_opt.h +++ b/compiler/dex/pass_driver_me_post_opt.h @@ -26,13 +26,19 @@ struct CompilationUnit; class Pass; class PassDataHolder; -class PassDriverMEPostOpt : public PassDriverME<PassDriverMEPostOpt> { +class PassDriverMEPostOpt : public PassDriverME { public: - explicit PassDriverMEPostOpt(CompilationUnit* cu) : PassDriverME<PassDriverMEPostOpt>(cu) { + explicit PassDriverMEPostOpt(const PassManager* const manager, CompilationUnit* cu) + : PassDriverME(manager, cu) { } ~PassDriverMEPostOpt() { } + + /** + * @brief Write and allocate corresponding passes into the pass manager. + */ + static void SetupPasses(PassManager* pass_manager); }; } // namespace art diff --git a/compiler/dex/pass_manager.cc b/compiler/dex/pass_manager.cc new file mode 100644 index 0000000..6d58f65 --- /dev/null +++ b/compiler/dex/pass_manager.cc @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * 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. + */ + +#include "pass_manager.h" + +#include "base/stl_util.h" +#include "pass_me.h" + +namespace art { + +PassManager::PassManager(const PassManagerOptions& options) : options_(options) { +} + +PassManager::~PassManager() { + STLDeleteElements(&passes_); +} + +void PassManager::CreateDefaultPassList() { + default_pass_list_.clear(); + // Add each pass which isn't disabled into default_pass_list_. + for (const auto* pass : passes_) { + if (options_.GetDisablePassList().find(pass->GetName()) != std::string::npos) { + LOG(INFO) << "Skipping disabled pass " << pass->GetName(); + } else { + default_pass_list_.push_back(pass); + } + } +} + +void PassManager::PrintPassNames() const { + LOG(INFO) << "Loop Passes are:"; + for (const Pass* cur_pass : default_pass_list_) { + LOG(INFO) << "\t-" << cur_pass->GetName(); + } +} + +} // namespace art diff --git a/compiler/dex/pass_manager.h b/compiler/dex/pass_manager.h new file mode 100644 index 0000000..68e488d --- /dev/null +++ b/compiler/dex/pass_manager.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * 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. + */ + +#ifndef ART_COMPILER_DEX_PASS_MANAGER_H_ +#define ART_COMPILER_DEX_PASS_MANAGER_H_ + +#include <string> +#include <vector> + +#include "base/logging.h" + +namespace art { + +class Pass; + +class PassManagerOptions { + public: + PassManagerOptions() + : default_print_passes_(false), + print_pass_names_(false), + print_pass_options_(false) { + } + explicit PassManagerOptions(const PassManagerOptions&) = default; + + void SetPrintPassNames(bool b) { + print_pass_names_ = b; + } + + void SetPrintAllPasses() { + default_print_passes_ = true; + } + bool GetPrintAllPasses() const { + return default_print_passes_; + } + + void SetDisablePassList(const std::string& list) { + disable_pass_list_ = list; + } + const std::string& GetDisablePassList() const { + return disable_pass_list_; + } + + void SetPrintPassList(const std::string& list) { + print_pass_list_ = list; + } + const std::string& GetPrintPassList() const { + return print_pass_list_; + } + + void SetDumpPassList(const std::string& list) { + dump_pass_list_ = list; + } + const std::string& GetDumpPassList() const { + return dump_pass_list_; + } + + /** + * @brief Used to set a string that contains the overridden pass options. + * @details An overridden pass option means that the pass uses this option + * instead of using its default option. + * @param s The string passed by user with overridden options. The string is in format + * Pass1Name:Pass1Option:Pass1Setting,Pass2Name:Pass2Option::Pass2Setting + */ + void SetOverriddenPassOptions(const std::string& list) { + overridden_pass_options_list_ = list; + } + const std::string& GetOverriddenPassOptions() const { + return overridden_pass_options_list_; + } + + void SetPrintPassOptions(bool b) { + print_pass_options_ = b; + } + bool GetPrintPassOptions() const { + return print_pass_options_; + } + + private: + /** @brief Do we, by default, want to be printing the log messages? */ + bool default_print_passes_; + + /** @brief What are the passes we want to be printing the log messages? */ + std::string print_pass_list_; + + /** @brief What are the passes we want to be dumping the CFG? */ + std::string dump_pass_list_; + + /** @brief String of all options that should be overridden for selected passes */ + std::string overridden_pass_options_list_; + + /** @brief String of all options that should be overridden for selected passes */ + std::string disable_pass_list_; + + /** @brief Whether or not we print all the passes when we create the pass manager */ + bool print_pass_names_; + + /** @brief Whether or not we print all the pass options when we create the pass manager */ + bool print_pass_options_; +}; + +/** + * @class PassManager + * @brief Owns passes + */ +class PassManager { + public: + explicit PassManager(const PassManagerOptions& options); + virtual ~PassManager(); + void CreateDefaultPassList(); + void AddPass(const Pass* pass) { + passes_.push_back(pass); + } + /** + * @brief Print the pass names of all the passes available. + */ + void PrintPassNames() const; + const std::vector<const Pass*>* GetDefaultPassList() const { + return &default_pass_list_; + } + const PassManagerOptions& GetOptions() const { + return options_; + } + + private: + /** @brief The set of possible passes. */ + std::vector<const Pass*> passes_; + + /** @brief The default pass list is used to initialize pass_list_. */ + std::vector<const Pass*> default_pass_list_; + + /** @brief Pass manager options. */ + PassManagerOptions options_; + + DISALLOW_COPY_AND_ASSIGN(PassManager); +}; +} // namespace art +#endif // ART_COMPILER_DEX_PASS_MANAGER_H_ diff --git a/compiler/dex/pass_me.h b/compiler/dex/pass_me.h index 73e49ec..79d8f51 100644 --- a/compiler/dex/pass_me.h +++ b/compiler/dex/pass_me.h @@ -42,11 +42,11 @@ std::ostream& operator<<(std::ostream& os, const OptimizationFlag& rhs); // Data holder class. class PassMEDataHolder: public PassDataHolder { - public: - CompilationUnit* c_unit; - BasicBlock* bb; - void* data; /**< @brief Any data the pass wants to use */ - bool dirty; /**< @brief Has the pass rendered the CFG dirty, requiring post-opt? */ + public: + CompilationUnit* c_unit; + BasicBlock* bb; + void* data; /**< @brief Any data the pass wants to use */ + bool dirty; /**< @brief Has the pass rendered the CFG dirty, requiring post-opt? */ }; enum DataFlowAnalysisMode { @@ -103,8 +103,8 @@ class PassME : public Pass { * @details The printing is done using LOG(INFO). */ void PrintPassDefaultOptions() const { - for (auto option_it = default_options_.begin(); option_it != default_options_.end(); option_it++) { - LOG(INFO) << "\t" << option_it->first << ":" << std::dec << option_it->second; + for (const auto& option : default_options_) { + LOG(INFO) << "\t" << option.first << ":" << std::dec << option.second; } } @@ -115,8 +115,9 @@ class PassME : public Pass { void PrintPassOptions(SafeMap<const std::string, int>& overridden_options) const { // We walk through the default options only to get the pass names. We use GetPassOption to // also consider the overridden ones. - for (auto option_it = default_options_.begin(); option_it != default_options_.end(); option_it++) { - LOG(INFO) << "\t" << option_it->first << ":" << std::dec << GetPassOption(option_it->first, overridden_options); + for (const auto& option : default_options_) { + LOG(INFO) << "\t" << option.first << ":" << std::dec + << GetPassOption(option.first, overridden_options); } } diff --git a/compiler/dex/quick/quick_compiler.cc b/compiler/dex/quick/quick_compiler.cc index 3a34fcd..909077e 100644 --- a/compiler/dex/quick/quick_compiler.cc +++ b/compiler/dex/quick/quick_compiler.cc @@ -29,6 +29,8 @@ #include "dex/dex_flags.h" #include "dex/mir_graph.h" #include "dex/pass_driver_me_opts.h" +#include "dex/pass_driver_me_post_opt.h" +#include "dex/pass_manager.h" #include "dex/quick/mir_to_lir.h" #include "driver/compiler_driver.h" #include "driver/compiler_options.h" @@ -47,48 +49,6 @@ namespace art { -class QuickCompiler FINAL : public Compiler { - public: - explicit QuickCompiler(CompilerDriver* driver) : Compiler(driver, 100) {} - - void Init() OVERRIDE; - - void UnInit() const OVERRIDE; - - bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, CompilationUnit* cu) const - OVERRIDE; - - CompiledMethod* Compile(const DexFile::CodeItem* code_item, - uint32_t access_flags, - InvokeType invoke_type, - uint16_t class_def_idx, - uint32_t method_idx, - jobject class_loader, - const DexFile& dex_file) const OVERRIDE; - - CompiledMethod* JniCompile(uint32_t access_flags, - uint32_t method_idx, - const DexFile& dex_file) const OVERRIDE; - - uintptr_t GetEntryPointOf(mirror::ArtMethod* method) const OVERRIDE - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - - bool WriteElf(art::File* file, - OatWriter* oat_writer, - const std::vector<const art::DexFile*>& dex_files, - const std::string& android_root, - bool is_host) const - OVERRIDE - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - - Mir2Lir* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const; - - void InitCompilationUnit(CompilationUnit& cu) const OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(QuickCompiler); -}; - static_assert(0U == static_cast<size_t>(kNone), "kNone not 0"); static_assert(1U == static_cast<size_t>(kArm), "kArm not 1"); static_assert(2U == static_cast<size_t>(kArm64), "kArm64 not 2"); @@ -730,7 +690,7 @@ CompiledMethod* QuickCompiler::Compile(const DexFile::CodeItem* code_item, } /* Create the pass driver and launch it */ - PassDriverMEOpts pass_driver(&cu); + PassDriverMEOpts pass_driver(GetPreOptPassManager(), &cu); pass_driver.Launch(); /* For non-leaf methods check if we should skip compilation when the profiler is enabled. */ @@ -850,8 +810,34 @@ Mir2Lir* QuickCompiler::GetCodeGenerator(CompilationUnit* cu, void* compilation_ return mir_to_lir; } +QuickCompiler::QuickCompiler(CompilerDriver* driver) : Compiler(driver, 100) { + const auto& compiler_options = driver->GetCompilerOptions(); + auto* pass_manager_options = compiler_options.GetPassManagerOptions(); + pre_opt_pass_manager_.reset(new PassManager(*pass_manager_options)); + CHECK(pre_opt_pass_manager_.get() != nullptr); + PassDriverMEOpts::SetupPasses(pre_opt_pass_manager_.get()); + pre_opt_pass_manager_->CreateDefaultPassList(); + if (pass_manager_options->GetPrintPassOptions()) { + PassDriverMEOpts::PrintPassOptions(pre_opt_pass_manager_.get()); + } + // TODO: Different options for pre vs post opts? + post_opt_pass_manager_.reset(new PassManager(PassManagerOptions())); + CHECK(post_opt_pass_manager_.get() != nullptr); + PassDriverMEPostOpt::SetupPasses(post_opt_pass_manager_.get()); + post_opt_pass_manager_->CreateDefaultPassList(); + if (pass_manager_options->GetPrintPassOptions()) { + PassDriverMEPostOpt::PrintPassOptions(post_opt_pass_manager_.get()); + } +} + +QuickCompiler::~QuickCompiler() { +} Compiler* CreateQuickCompiler(CompilerDriver* driver) { + return QuickCompiler::Create(driver); +} + +Compiler* QuickCompiler::Create(CompilerDriver* driver) { return new QuickCompiler(driver); } diff --git a/compiler/dex/quick/quick_compiler.h b/compiler/dex/quick/quick_compiler.h index 10de5fb..5153a9e 100644 --- a/compiler/dex/quick/quick_compiler.h +++ b/compiler/dex/quick/quick_compiler.h @@ -17,12 +17,70 @@ #ifndef ART_COMPILER_DEX_QUICK_QUICK_COMPILER_H_ #define ART_COMPILER_DEX_QUICK_QUICK_COMPILER_H_ +#include "compiler.h" + namespace art { class Compiler; class CompilerDriver; +class Mir2Lir; +class PassManager; + +class QuickCompiler : public Compiler { + public: + virtual ~QuickCompiler(); + + void Init() OVERRIDE; + + void UnInit() const OVERRIDE; + + bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, CompilationUnit* cu) const + OVERRIDE; + + CompiledMethod* Compile(const DexFile::CodeItem* code_item, + uint32_t access_flags, + InvokeType invoke_type, + uint16_t class_def_idx, + uint32_t method_idx, + jobject class_loader, + const DexFile& dex_file) const OVERRIDE; + + CompiledMethod* JniCompile(uint32_t access_flags, + uint32_t method_idx, + const DexFile& dex_file) const OVERRIDE; + + uintptr_t GetEntryPointOf(mirror::ArtMethod* method) const OVERRIDE + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + + bool WriteElf(art::File* file, + OatWriter* oat_writer, + const std::vector<const art::DexFile*>& dex_files, + const std::string& android_root, + bool is_host) const + OVERRIDE + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + + Mir2Lir* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const; + + void InitCompilationUnit(CompilationUnit& cu) const OVERRIDE; + + static Compiler* Create(CompilerDriver* driver); + + const PassManager* GetPreOptPassManager() const { + return pre_opt_pass_manager_.get(); + } + const PassManager* GetPostOptPassManager() const { + return post_opt_pass_manager_.get(); + } + + protected: + explicit QuickCompiler(CompilerDriver* driver); -Compiler* CreateQuickCompiler(CompilerDriver* driver); + private: + std::unique_ptr<PassManager> pre_opt_pass_manager_; + std::unique_ptr<PassManager> post_opt_pass_manager_; + DISALLOW_COPY_AND_ASSIGN(QuickCompiler); +}; } // namespace art diff --git a/compiler/dex/quick/quick_compiler_factory.h b/compiler/dex/quick/quick_compiler_factory.h new file mode 100644 index 0000000..31ee1cf --- /dev/null +++ b/compiler/dex/quick/quick_compiler_factory.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * 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. + */ + +#ifndef ART_COMPILER_DEX_QUICK_QUICK_COMPILER_FACTORY_H_ +#define ART_COMPILER_DEX_QUICK_QUICK_COMPILER_FACTORY_H_ + +namespace art { + +class Compiler; +class CompilerDriver; + +Compiler* CreateQuickCompiler(CompilerDriver* driver); + +} // namespace art + +#endif // ART_COMPILER_DEX_QUICK_QUICK_COMPILER_FACTORY_H_ diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc new file mode 100644 index 0000000..09ec9a2 --- /dev/null +++ b/compiler/driver/compiler_options.cc @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * 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. + */ + +#include "compiler_options.h" + +#include "dex/pass_manager.h" + +namespace art { + +CompilerOptions::CompilerOptions() + : compiler_filter_(kDefaultCompilerFilter), + huge_method_threshold_(kDefaultHugeMethodThreshold), + large_method_threshold_(kDefaultLargeMethodThreshold), + small_method_threshold_(kDefaultSmallMethodThreshold), + tiny_method_threshold_(kDefaultTinyMethodThreshold), + num_dex_methods_threshold_(kDefaultNumDexMethodsThreshold), + generate_gdb_information_(false), + include_patch_information_(kDefaultIncludePatchInformation), + top_k_profile_threshold_(kDefaultTopKProfileThreshold), + include_debug_symbols_(kDefaultIncludeDebugSymbols), + implicit_null_checks_(true), + implicit_so_checks_(true), + implicit_suspend_checks_(false), + compile_pic_(false), + verbose_methods_(nullptr), + pass_manager_options_(new PassManagerOptions), + init_failure_output_(nullptr) { +} + +CompilerOptions::CompilerOptions(CompilerFilter compiler_filter, + size_t huge_method_threshold, + size_t large_method_threshold, + size_t small_method_threshold, + size_t tiny_method_threshold, + size_t num_dex_methods_threshold, + bool generate_gdb_information, + bool include_patch_information, + double top_k_profile_threshold, + bool include_debug_symbols, + bool implicit_null_checks, + bool implicit_so_checks, + bool implicit_suspend_checks, + bool compile_pic, + const std::vector<std::string>* verbose_methods, + PassManagerOptions* pass_manager_options, + std::ostream* init_failure_output + ) : // NOLINT(whitespace/parens) + compiler_filter_(compiler_filter), + huge_method_threshold_(huge_method_threshold), + large_method_threshold_(large_method_threshold), + small_method_threshold_(small_method_threshold), + tiny_method_threshold_(tiny_method_threshold), + num_dex_methods_threshold_(num_dex_methods_threshold), + generate_gdb_information_(generate_gdb_information), + include_patch_information_(include_patch_information), + top_k_profile_threshold_(top_k_profile_threshold), + include_debug_symbols_(include_debug_symbols), + implicit_null_checks_(implicit_null_checks), + implicit_so_checks_(implicit_so_checks), + implicit_suspend_checks_(implicit_suspend_checks), + compile_pic_(compile_pic), + verbose_methods_(verbose_methods), + pass_manager_options_(pass_manager_options), + init_failure_output_(init_failure_output) { +} + +} // namespace art diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index 5466d45..122ae4b 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -26,6 +26,8 @@ namespace art { +class PassManagerOptions; + class CompilerOptions FINAL { public: enum CompilerFilter { @@ -53,24 +55,7 @@ class CompilerOptions FINAL { static const bool kDefaultIncludeDebugSymbols = kIsDebugBuild; static const bool kDefaultIncludePatchInformation = false; - CompilerOptions() : - compiler_filter_(kDefaultCompilerFilter), - huge_method_threshold_(kDefaultHugeMethodThreshold), - large_method_threshold_(kDefaultLargeMethodThreshold), - small_method_threshold_(kDefaultSmallMethodThreshold), - tiny_method_threshold_(kDefaultTinyMethodThreshold), - num_dex_methods_threshold_(kDefaultNumDexMethodsThreshold), - generate_gdb_information_(false), - include_patch_information_(kDefaultIncludePatchInformation), - top_k_profile_threshold_(kDefaultTopKProfileThreshold), - include_debug_symbols_(kDefaultIncludeDebugSymbols), - implicit_null_checks_(true), - implicit_so_checks_(true), - implicit_suspend_checks_(false), - compile_pic_(false), - verbose_methods_(nullptr), - init_failure_output_(nullptr) { - } + CompilerOptions(); CompilerOptions(CompilerFilter compiler_filter, size_t huge_method_threshold, @@ -87,25 +72,8 @@ class CompilerOptions FINAL { bool implicit_suspend_checks, bool compile_pic, const std::vector<std::string>* verbose_methods, - std::ostream* init_failure_output - ) : // NOLINT(whitespace/parens) - compiler_filter_(compiler_filter), - huge_method_threshold_(huge_method_threshold), - large_method_threshold_(large_method_threshold), - small_method_threshold_(small_method_threshold), - tiny_method_threshold_(tiny_method_threshold), - num_dex_methods_threshold_(num_dex_methods_threshold), - generate_gdb_information_(generate_gdb_information), - include_patch_information_(include_patch_information), - top_k_profile_threshold_(top_k_profile_threshold), - include_debug_symbols_(include_debug_symbols), - implicit_null_checks_(implicit_null_checks), - implicit_so_checks_(implicit_so_checks), - implicit_suspend_checks_(implicit_suspend_checks), - compile_pic_(compile_pic), - verbose_methods_(verbose_methods), - init_failure_output_(init_failure_output) { - } + PassManagerOptions* pass_manager_options, + std::ostream* init_failure_output); CompilerFilter GetCompilerFilter() const { return compiler_filter_; @@ -210,6 +178,10 @@ class CompilerOptions FINAL { return init_failure_output_; } + const PassManagerOptions* GetPassManagerOptions() const { + return pass_manager_options_.get(); + } + private: CompilerFilter compiler_filter_; const size_t huge_method_threshold_; @@ -230,6 +202,8 @@ class CompilerOptions FINAL { // Vector of methods to have verbose output enabled for. const std::vector<std::string>* const verbose_methods_; + std::unique_ptr<PassManagerOptions> pass_manager_options_; + // Log initialization of initialization failures to this stream if not null. std::ostream* const init_failure_output_; diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index d3d2055..46aed60 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -18,9 +18,10 @@ #include "class_linker.h" #include "common_compiler_test.h" #include "compiler.h" -#include "dex/verification_results.h" +#include "dex/pass_manager.h" #include "dex/quick/dex_file_to_method_inliner_map.h" #include "dex/quick_compiler_callbacks.h" +#include "dex/verification_results.h" #include "entrypoints/quick/quick_entrypoints.h" #include "mirror/art_method-inl.h" #include "mirror/class-inl.h" diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h index b3eb1e2..29d47e1 100644 --- a/compiler/optimizing/optimizing_unit_test.h +++ b/compiler/optimizing/optimizing_unit_test.h @@ -19,6 +19,7 @@ #include "nodes.h" #include "builder.h" +#include "compiler/dex/pass_manager.h" #include "dex_file.h" #include "dex_instruction.h" #include "ssa_liveness_analysis.h" diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index fe3a978..e607e15 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -44,7 +44,7 @@ #include "compiler.h" #include "compiler_callbacks.h" #include "dex_file-inl.h" -#include "dex/pass_driver_me_opts.h" +#include "dex/pass_manager.h" #include "dex/verification_results.h" #include "dex/quick_compiler_callbacks.h" #include "dex/quick/dex_file_to_method_inliner_map.h" @@ -490,12 +490,13 @@ class Dex2Oat FINAL { // Profile file to use double top_k_profile_threshold = CompilerOptions::kDefaultTopKProfileThreshold; - bool print_pass_options = false; bool include_patch_information = CompilerOptions::kDefaultIncludePatchInformation; bool include_debug_symbols = kIsDebugBuild; bool watch_dog_enabled = true; bool generate_gdb_information = kIsDebugBuild; + PassManagerOptions pass_manager_options; + std::string error_msg; for (int i = 0; i < argc; i++) { @@ -685,23 +686,23 @@ class Dex2Oat FINAL { } else if (option.starts_with("--top-k-profile-threshold=")) { ParseDouble(option.data(), '=', 0.0, 100.0, &top_k_profile_threshold); } else if (option == "--print-pass-names") { - PassDriverMEOpts::PrintPassNames(); + pass_manager_options.SetPrintPassNames(true); } else if (option.starts_with("--disable-passes=")) { - std::string disable_passes = option.substr(strlen("--disable-passes=")).data(); - PassDriverMEOpts::CreateDefaultPassList(disable_passes); + const std::string disable_passes = option.substr(strlen("--disable-passes=")).data(); + pass_manager_options.SetDisablePassList(disable_passes); } else if (option.starts_with("--print-passes=")) { - std::string print_passes = option.substr(strlen("--print-passes=")).data(); - PassDriverMEOpts::SetPrintPassList(print_passes); + const std::string print_passes = option.substr(strlen("--print-passes=")).data(); + pass_manager_options.SetPrintPassList(print_passes); } else if (option == "--print-all-passes") { - PassDriverMEOpts::SetPrintAllPasses(); + pass_manager_options.SetPrintAllPasses(); } else if (option.starts_with("--dump-cfg-passes=")) { - std::string dump_passes_string = option.substr(strlen("--dump-cfg-passes=")).data(); - PassDriverMEOpts::SetDumpPassList(dump_passes_string); + const std::string dump_passes_string = option.substr(strlen("--dump-cfg-passes=")).data(); + pass_manager_options.SetDumpPassList(dump_passes_string); } else if (option == "--print-pass-options") { - print_pass_options = true; + pass_manager_options.SetPrintPassOptions(true); } else if (option.starts_with("--pass-options=")) { - std::string options = option.substr(strlen("--pass-options=")).data(); - PassDriverMEOpts::SetOverriddenPassOptions(options); + const std::string options = option.substr(strlen("--pass-options=")).data(); + pass_manager_options.SetOverriddenPassOptions(options); } else if (option == "--include-patch-information") { include_patch_information = true; } else if (option == "--no-include-patch-information") { @@ -924,10 +925,6 @@ class Dex2Oat FINAL { break; } - if (print_pass_options) { - PassDriverMEOpts::PrintPassOptions(); - } - compiler_options_.reset(new CompilerOptions(compiler_filter, huge_method_threshold, large_method_threshold, @@ -945,6 +942,7 @@ class Dex2Oat FINAL { verbose_methods_.empty() ? nullptr : &verbose_methods_, + new PassManagerOptions(pass_manager_options), init_failure_output_.get())); // Done with usage checks, enable watchdog if requested |