diff options
author | 2014-04-29 13:42:08 -0700 | |
---|---|---|
committer | 2014-05-27 11:41:29 -0700 | |
commit | 8bceccec7eddff8cd872aa20505b4a3a6be60a16 (patch) | |
tree | c0f7fb0dcf4041542ec8de58c881faf03db07b54 | |
parent | 132236a802a82cc7d27f82e34e40082ef5c17375 (diff) |
ART: Print and dump functionalities per pass
LOG is a great logging tool but sometimes a pass has some debugging text it
want to be able to turn on/off easily.
By going via a print_pass flag, we can actually turn it on/off easily per pass
when debugging/instrumenting.
- Added a pass printer to help debug messages for future passes.
- Added a print_pass flag in CompilationUnit to filter out messages.
At the same time, did a similar system for dumping the CFG.
- Also moved some API into public from protected.
Change-Id: Ie0e89a8fc773e8583f3e4ffd6e4bd2eebdbb2bf4
Signed-off-by: Jean Christophe Beyler <jean.christophe.beyler@intel.com>
Signed-off-by: Razvan A Lupusoru <razvan.a.lupusoru@intel.com>
Signed-off-by: Yixin Shou <yixin.shou@intel.com>
Signed-off-by: Chao-ying Fu <chao-ying.fu@intel.com>
Signed-off-by: Udayan Banerji <udayan.banerji@intel.com>
-rw-r--r-- | compiler/dex/compiler_ir.h | 1 | ||||
-rw-r--r-- | compiler/dex/frontend.cc | 3 | ||||
-rw-r--r-- | compiler/dex/pass.h | 15 | ||||
-rw-r--r-- | compiler/dex/pass_driver.h | 27 | ||||
-rw-r--r-- | compiler/dex/pass_driver_me.cc | 64 | ||||
-rw-r--r-- | dex2oat/dex2oat.cc | 14 |
6 files changed, 107 insertions, 17 deletions
diff --git a/compiler/dex/compiler_ir.h b/compiler/dex/compiler_ir.h index 35d777ec7a..66fb608d39 100644 --- a/compiler/dex/compiler_ir.h +++ b/compiler/dex/compiler_ir.h @@ -88,6 +88,7 @@ struct CompilationUnit { 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 9bad736c8d..e2463025d9 100644 --- a/compiler/dex/frontend.cc +++ b/compiler/dex/frontend.cc @@ -105,7 +105,8 @@ CompilationUnit::CompilationUnit(ArenaPool* pool) 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 4ce040e9ab..b4906d67df 100644 --- a/compiler/dex/pass.h +++ b/compiler/dex/pass.h @@ -89,6 +89,21 @@ class Pass { 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 aa0d1ae462..788f24b461 100644 --- a/compiler/dex/pass_driver.h +++ b/compiler/dex/pass_driver.h @@ -141,7 +141,6 @@ class PassDriver { } } - protected: /** * @brief Gets the list of passes currently schedule to execute. * @return pass_list_ @@ -150,14 +149,27 @@ class PassDriver { 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 @@ class PassDriver { /** @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 d0545004f7..099cfee5ba 100644 --- a/compiler/dex/pass_driver_me.cc +++ b/compiler/dex/pass_driver_me.cc @@ -77,6 +77,19 @@ uint16_t const PassDriver<PassDriverME>::g_passes_size = arraysize(PassDriver<Pa 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 @@ bool PassDriverME::RunPass(const Pass* pass, bool time_split) { // 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); - - if (passFolder[0] != 0) { - // Create directory prefix. - std::string prefix = GetDumpCFGFolder(); - prefix += passFolder; - prefix += "/"; - - c_unit->mir_graph->DumpCFG(prefix.c_str(), false); + bool should_dump = ((c_unit->enable_debug & (1 << kDebugDumpCFG)) != 0); + + const char* dump_pass_list = dump_pass_list_.get(); + + 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 f0b575041d..6d05e5e85a 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -922,6 +922,20 @@ static int dex2oat(int argc, char** argv) { } 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()); } |