Merge "ART: Print and dump functionalities per pass"
diff --git a/compiler/dex/compiler_ir.h b/compiler/dex/compiler_ir.h
index 35d777e..66fb608 100644
--- a/compiler/dex/compiler_ir.h
+++ b/compiler/dex/compiler_ir.h
@@ -88,6 +88,7 @@
std::unique_ptr<MIRGraph> mir_graph; // MIR container.
std::unique_ptr<Backend> cg; // Target-specific codegen.
TimingLogger timings;
+ bool print_pass; // Do we want to print a pass or not?
};
} // namespace art
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index c3f694d..1d4a9bb 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -105,7 +105,8 @@
arena_stack(pool),
mir_graph(nullptr),
cg(nullptr),
- timings("QuickCompiler", true, false) {
+ timings("QuickCompiler", true, false),
+ print_pass(false) {
}
CompilationUnit::~CompilationUnit() {
diff --git a/compiler/dex/pass.h b/compiler/dex/pass.h
index 4ce040e..b4906d6 100644
--- a/compiler/dex/pass.h
+++ b/compiler/dex/pass.h
@@ -89,6 +89,21 @@
return false;
}
+ static void BasePrintMessage(CompilationUnit* c_unit, const char* pass_name, const char* message, ...) {
+ // Check if we want to log something or not.
+ if (c_unit->print_pass) {
+ // Stringify the message.
+ va_list args;
+ va_start(args, message);
+ std::string stringified_message;
+ StringAppendV(&stringified_message, message, args);
+ va_end(args);
+
+ // Log the message and ensure to include pass name.
+ LOG(INFO) << pass_name << ": " << stringified_message;
+ }
+ }
+
protected:
/** @brief The pass name: used for searching for a pass when running a particular pass or debugging. */
const char* const pass_name_;
diff --git a/compiler/dex/pass_driver.h b/compiler/dex/pass_driver.h
index aa0d1ae..788f24b 100644
--- a/compiler/dex/pass_driver.h
+++ b/compiler/dex/pass_driver.h
@@ -141,7 +141,6 @@
}
}
- protected:
/**
* @brief Gets the list of passes currently schedule to execute.
* @return pass_list_
@@ -150,14 +149,27 @@
return pass_list_;
}
- virtual void InitializePasses() {
- SetDefaultPasses();
+ static void SetPrintAllPasses() {
+ default_print_passes_ = true;
+ }
+
+ static void SetDumpPassList(const char* list) {
+ dump_pass_list_.reset(list);
+ }
+
+ static void SetPrintPassList(const char* list) {
+ print_pass_list_.reset(list);
}
void SetDefaultPasses() {
pass_list_ = PassDriver<PassDriverType>::g_default_pass_list;
}
+ protected:
+ virtual void InitializePasses() {
+ SetDefaultPasses();
+ }
+
/**
* @brief Apply a patch: perform start/work/end functions.
*/
@@ -185,6 +197,15 @@
/** @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::unique_ptr<const char> print_pass_list_;
+
+ /** @brief What are the passes we want to be dumping the CFG? */
+ static std::unique_ptr<const char> dump_pass_list_;
};
} // namespace art
diff --git a/compiler/dex/pass_driver_me.cc b/compiler/dex/pass_driver_me.cc
index d054500..099cfee 100644
--- a/compiler/dex/pass_driver_me.cc
+++ b/compiler/dex/pass_driver_me.cc
@@ -77,6 +77,19 @@
template<>
std::vector<const Pass*> PassDriver<PassDriverME>::g_default_pass_list(PassDriver<PassDriverME>::g_passes, PassDriver<PassDriverME>::g_passes + PassDriver<PassDriverME>::g_passes_size);
+// By default, do not have a dump pass list.
+template<>
+std::unique_ptr<const char> PassDriver<PassDriverME>::dump_pass_list_(nullptr);
+
+// By default, do not have a print pass list.
+template<>
+std::unique_ptr<const char> PassDriver<PassDriverME>::print_pass_list_(nullptr);
+
+// By default, we do not print the pass' information.
+template<>
+bool PassDriver<PassDriverME>::default_print_passes_ = false;
+
+
PassDriverME::PassDriverME(CompilationUnit* cu)
: PassDriver(), pass_me_data_holder_(), dump_cfg_folder_("/sdcard/") {
pass_me_data_holder_.bb = nullptr;
@@ -136,26 +149,51 @@
// Check the pass gate first.
bool should_apply_pass = pass->Gate(&pass_me_data_holder_);
+
if (should_apply_pass) {
+ bool old_print_pass = c_unit->print_pass;
+
+ c_unit->print_pass = default_print_passes_;
+
+ const char* print_pass_list = print_pass_list_.get();
+
+ if (print_pass_list != nullptr && strstr(print_pass_list, pass->GetName()) != nullptr) {
+ c_unit->print_pass = true;
+ }
+
// Applying the pass: first start, doWork, and end calls.
ApplyPass(&pass_me_data_holder_, pass);
// Do we want to log it?
- if ((c_unit->enable_debug& (1 << kDebugDumpCFG)) != 0) {
- // Do we have a pass folder?
- const PassME* me_pass = (down_cast<const PassME*>(pass));
- const char* passFolder = me_pass->GetDumpCFGFolder();
- DCHECK(passFolder != nullptr);
+ bool should_dump = ((c_unit->enable_debug & (1 << kDebugDumpCFG)) != 0);
- if (passFolder[0] != 0) {
- // Create directory prefix.
- std::string prefix = GetDumpCFGFolder();
- prefix += passFolder;
- prefix += "/";
+ const char* dump_pass_list = dump_pass_list_.get();
- c_unit->mir_graph->DumpCFG(prefix.c_str(), false);
+ if (dump_pass_list != nullptr) {
+ bool found = strstr(dump_pass_list, pass->GetName());
+ should_dump = (should_dump || found);
+ }
+
+ if (should_dump) {
+ // Do we want to log it?
+ if ((c_unit->enable_debug& (1 << kDebugDumpCFG)) != 0) {
+ // Do we have a pass folder?
+ const PassME* me_pass = (down_cast<const PassME*>(pass));
+ const char* passFolder = me_pass->GetDumpCFGFolder();
+ DCHECK(passFolder != nullptr);
+
+ if (passFolder[0] != 0) {
+ // Create directory prefix.
+ std::string prefix = GetDumpCFGFolder();
+ prefix += passFolder;
+ prefix += "/";
+
+ c_unit->mir_graph->DumpCFG(prefix.c_str(), false);
+ }
}
}
+
+ c_unit->print_pass = old_print_pass;
}
// If the pass gate passed, we can declare success.
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 2126625..91a1418 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -923,6 +923,20 @@
} else if (option.starts_with("--disable-passes=")) {
std::string disable_passes = option.substr(strlen("--disable-passes=")).data();
PassDriverME::CreateDefaultPassList(disable_passes);
+ } else if (option.starts_with("--print-passes=")) {
+ std::string print_passes = option.substr(strlen("--print-passes=")).data();
+ size_t len = print_passes.length() + 1;
+ char* duplicate = new char[len];
+ strncpy(duplicate, print_passes.c_str(), len);
+ PassDriverME::SetPrintPassList(duplicate);
+ } else if (option == "--print-all-passes") {
+ PassDriverME::SetPrintAllPasses();
+ } else if (option.starts_with("--dump-cfg-passes=")) {
+ std::string dump_passes = option.substr(strlen("--dump-cfg-passes=")).data();
+ size_t len = dump_passes.length() + 1;
+ char* duplicate = new char[len];
+ strncpy(duplicate, dump_passes.c_str(), len);
+ PassDriverME::SetDumpPassList(duplicate);
} else {
Usage("Unknown argument %s", option.data());
}