service/method-outliner/OutliningProfileGuidanceImpl.h (44 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "BigBlocks.h" #include "Dominators.h" #include "Lazy.h" #include "OutliningProfileGuidance.h" struct ConfigFiles; class PassManager; namespace outliner_impl { //////////////////////////////////////////////////////////////////////////////// // gather_sufficiently_warm_and_hot_methods //////////////////////////////////////////////////////////////////////////////// // We'll look around the provided configuration information to identify hot and // warm methods. The preferred way is now to use "method profiles". We look at // each interaction. If a method appears in at least 1% of the samples, then... // - If the method is invoked at least 10 times on average, we won't outline // from it at all (truly "hot") // - If the method is invoked less often ("at least once", otherwise it wouldn't // appear in the method profiles), then we won't outline from any of its loops // ("warm" code) // // The actual thresholds are configurable. // // The intention here is to avoid outlining any code snippet that runs many // times, in which case the call overhead might become significant. Otherwise, // if it is called only rarely (0 to 9 times), then any added CPU overhead might // be made up by the I/O savings due to reduced code size. // // When method profiles are completely unavailable, we can use cold-start // classes to identify warm code. void gather_sufficiently_warm_and_hot_methods( const Scope& scope, ConfigFiles& config_files, PassManager& mgr, const outliner::ProfileGuidanceConfig& config, std::unordered_set<DexMethod*>* sufficiently_warm_methods, std::unordered_set<DexMethod*>* sufficiently_hot_methods); outliner::PerfSensitivity parse_perf_sensitivity(const std::string& str); class CanOutlineBlockDecider { private: const outliner::ProfileGuidanceConfig& m_config; bool m_sufficiently_warm; bool m_sufficiently_hot; mutable std::unique_ptr<LazyUnorderedMap<cfg::Block*, bool>> m_is_in_loop; mutable std::unique_ptr<LazyUnorderedMap<cfg::Block*, boost::optional<float>>> m_max_vals; mutable std::unique_ptr<dominators::SimpleFastDominators<cfg::GraphInterface>> m_dominators; public: CanOutlineBlockDecider(const outliner::ProfileGuidanceConfig& config, bool sufficiently_warm, bool sufficiently_hot); enum class Result { CanOutline, BlockExceedsThresholds, WarmLoop, WarmLoopExceedsThresholds, WarmLoopNoSourceBlocks, Hot, HotExceedsThresholds, HotNoSourceBlocks, }; Result can_outline_from_big_block( const big_blocks::BigBlock& big_block) const; }; } // namespace outliner_impl