diff --git a/opt/remove-unused-args/RemoveUnusedArgs.cpp b/opt/remove-unused-args/RemoveUnusedArgs.cpp index 537b53dce90..7bcb56974a3 100644 --- a/opt/remove-unused-args/RemoveUnusedArgs.cpp +++ b/opt/remove-unused-args/RemoveUnusedArgs.cpp @@ -23,6 +23,7 @@ #include "OptData.h" #include "OptDataDefs.h" #include "PassManager.h" +#include "Purity.h" #include "Resolver.h" #include "Show.h" #include "Walkers.h" @@ -533,9 +534,9 @@ void run_cleanup(DexMethod* method, cfg::ControlFlowGraph& cfg, const init_classes::InitClassesWithSideEffects* init_classes_with_side_effects, + const std::unordered_set& pure_methods, std::mutex& mutex, LocalDce::Stats& stats) { - std::unordered_set pure_methods; auto local_dce = LocalDce(init_classes_with_side_effects, pure_methods); local_dce.dce(cfg, /* normalize_new_instances */ true, method->get_class()); const auto& local_stats = local_dce.get_stats(); @@ -667,6 +668,7 @@ RemoveArgs::MethodStats RemoveArgs::update_method_protos( run_cleanup(method, cfg, &m_init_classes_with_side_effects, + m_pure_methods, local_dce_stats_mutex, local_dce_stats); } @@ -745,6 +747,7 @@ std::pair RemoveArgs::update_callsites() { run_cleanup(method, cfg, &m_init_classes_with_side_effects, + m_pure_methods, local_dce_stats_mutex, local_dce_stats); } @@ -768,10 +771,11 @@ void RemoveUnusedArgsPass::run_pass(DexStoresVector& stores, size_t num_method_protos_reordered_count = 0; size_t num_iterations = 0; LocalDce::Stats local_dce_stats; + auto pure_methods = get_pure_methods(); while (true) { num_iterations++; RemoveArgs rm_args(scope, init_classes_with_side_effects, m_blocklist, - m_total_iterations++); + pure_methods, m_total_iterations++); auto pass_stats = rm_args.run(conf); if (pass_stats.methods_updated_count == 0) { break; diff --git a/opt/remove-unused-args/RemoveUnusedArgs.h b/opt/remove-unused-args/RemoveUnusedArgs.h index c796f4af1f2..bb2bf8dd8b2 100644 --- a/opt/remove-unused-args/RemoveUnusedArgs.h +++ b/opt/remove-unused-args/RemoveUnusedArgs.h @@ -47,11 +47,13 @@ class RemoveArgs { const init_classes::InitClassesWithSideEffects& init_classes_with_side_effects, const std::vector& blocklist, + const std::unordered_set& pure_methods, size_t iteration = 0) : m_scope(scope), m_init_classes_with_side_effects(init_classes_with_side_effects), m_blocklist(blocklist), - m_iteration(iteration) {} + m_iteration(iteration), + m_pure_methods(pure_methods) {} RemoveArgs::PassStats run(ConfigFiles& conf); private: @@ -72,6 +74,7 @@ class RemoveArgs { std::unordered_map m_reordered_protos; const std::vector& m_blocklist; size_t m_iteration; + const std::unordered_set& m_pure_methods; DexTypeList::ContainerType get_live_arg_type_list( DexMethod* method, const std::deque& live_arg_idxs); diff --git a/test/unit/RemoveUnusedArgsTest.cpp b/test/unit/RemoveUnusedArgsTest.cpp index 666512534a0..99c315c1d6f 100644 --- a/test/unit/RemoveUnusedArgsTest.cpp +++ b/test/unit/RemoveUnusedArgsTest.cpp @@ -23,6 +23,7 @@ struct RemoveUnusedArgsTest : public RedexTest { remove_unused_args::RemoveArgs* m_remove_args; std::vector m_blocklist; + std::unordered_set m_pure_methods; RemoveUnusedArgsTest() { Scope dummy_scope; @@ -34,7 +35,8 @@ struct RemoveUnusedArgsTest : public RedexTest { auto dummy_cls = create_internal_class(dummy_t, obj_t, {}); dummy_scope.push_back(dummy_cls); m_remove_args = new remove_unused_args::RemoveArgs( - dummy_scope, dummy_init_classes_with_side_effects, m_blocklist); + dummy_scope, dummy_init_classes_with_side_effects, m_blocklist, + m_pure_methods); } ~RemoveUnusedArgsTest() {}