Clean up pass driver
Added pass manager to hold the state which used to be in global
variables.
Static variables caused issues with Runtime.exit since they are
destroyed by the global destructors while threads are still
executing.
Bug: 17950037
Change-Id: Ie0e4546dc9e48909c8df996a5c135be682d50044
diff --git a/compiler/Android.mk b/compiler/Android.mk
index 1d4f5a3..8664918 100644
--- a/compiler/Android.mk
+++ b/compiler/Android.mk
@@ -69,12 +69,14 @@
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 @@
}
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 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 @@
*/
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 @@
*/
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 @@
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 @@
*/
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 @@
DispatchPass(pass);
pass->End(data);
}
+
/**
* @brief Dispatch a patch.
* Gives the ability to add logic when running the patch.
@@ -197,29 +129,11 @@
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 @@
}
}
- 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 @@
// 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 @@
// 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);
+ bool should_dump = (c_unit->enable_debug & (1 << kDebugDumpCFG)) != 0;
- const char* dump_pass_list = PassDriver<PassDriverType>::dump_pass_list_.c_str();
-
- 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 @@
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 @@
}
/**
- * @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 @@
// 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 @@
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 @@
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 @@
// 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 @@
* @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 @@
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 @@
}
/* 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 @@
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;
-Compiler* CreateQuickCompiler(CompilerDriver* driver);
+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);
+
+ 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 @@
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 @@
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 @@
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 @@
// 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 @@
// 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 @@
} 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 @@
break;
}
- if (print_pass_options) {
- PassDriverMEOpts::PrintPassOptions();
- }
-
compiler_options_.reset(new CompilerOptions(compiler_filter,
huge_method_threshold,
large_method_threshold,
@@ -945,6 +942,7 @@
verbose_methods_.empty() ?
nullptr :
&verbose_methods_,
+ new PassManagerOptions(pass_manager_options),
init_failure_output_.get()));
// Done with usage checks, enable watchdog if requested