summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/Android.mk2
-rw-r--r--compiler/common_compiler_test.cc3
-rw-r--r--compiler/compiler.cc2
-rw-r--r--compiler/dex/mir_graph.cc6
-rw-r--r--compiler/dex/pass_driver.h118
-rw-r--r--compiler/dex/pass_driver_me.h70
-rw-r--r--compiler/dex/pass_driver_me_opts.cc87
-rw-r--r--compiler/dex/pass_driver_me_opts.h13
-rw-r--r--compiler/dex/pass_driver_me_post_opt.cc78
-rw-r--r--compiler/dex/pass_driver_me_post_opt.h10
-rw-r--r--compiler/dex/pass_manager.cc50
-rw-r--r--compiler/dex/pass_manager.h150
-rw-r--r--compiler/dex/pass_me.h19
-rw-r--r--compiler/dex/quick/quick_compiler.cc72
-rw-r--r--compiler/dex/quick/quick_compiler.h60
-rw-r--r--compiler/dex/quick/quick_compiler_factory.h29
-rw-r--r--compiler/driver/compiler_options.cc80
-rw-r--r--compiler/driver/compiler_options.h48
-rw-r--r--compiler/oat_test.cc3
-rw-r--r--compiler/optimizing/optimizing_unit_test.h1
-rw-r--r--dex2oat/dex2oat.cc32
21 files changed, 573 insertions, 360 deletions
diff --git a/compiler/Android.mk b/compiler/Android.mk
index 1d4f5a3b5b..86649189b6 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 96f8e0c355..1cd78f8168 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 baa6688570..5e8ec1e01b 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 db4141c348..0f7d45df79 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 632df38a96..671bcecfba 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 ff7c4a4b19..fed92be5c6 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 c2b6b911b9..8c8bde63ea 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 0a5b5aec99..b930d02d1e 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 5f0c65c51c..4e1322702f 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 574a6ba04d..9e03c4e73e 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 0000000000..6d58f65b68
--- /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 0000000000..68e488d128
--- /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 73e49ec4f0..79d8f5104f 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 3a34fcde94..909077eca2 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 10de5fbca4..5153a9e82e 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 0000000000..31ee1cf93b
--- /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 0000000000..09ec9a2973
--- /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 5466d4596a..122ae4b575 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 d3d20555d8..46aed60479 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 b3eb1e2d51..29d47e13cc 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 fe3a978c4a..e607e15a13 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