//===- bolt/Passes/CacheMetrics.cpp - Metrics for instruction cache -------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements the CacheMetrics class and functions for showing metrics // of cache lines. // //===----------------------------------------------------------------------===// #include "bolt/Passes/CacheMetrics.h" #include "bolt/Core/BinaryBasicBlock.h" #include "bolt/Core/BinaryFunction.h" #include <unordered_map> usingnamespacellvm; usingnamespacebolt; namespace { /// The following constants are used to estimate the number of i-TLB cache /// misses for a given code layout. Empirically the values result in high /// correlations between the estimations and the perf measurements. /// The constants do not affect the code layout algorithms. constexpr unsigned ITLBPageSize = …; constexpr unsigned ITLBEntries = …; /// Initialize and return a position map for binary basic blocks void extractBasicBlockInfo( const std::vector<BinaryFunction *> &BinaryFunctions, std::unordered_map<BinaryBasicBlock *, uint64_t> &BBAddr, std::unordered_map<BinaryBasicBlock *, uint64_t> &BBSize) { … } /// Calculate TSP metric, which quantifies the number of fallthrough jumps in /// the ordering of basic blocks. The method returns a pair /// (the number of fallthrough branches, the total number of branches) std::pair<uint64_t, uint64_t> calcTSPScore(const std::vector<BinaryFunction *> &BinaryFunctions, const std::unordered_map<BinaryBasicBlock *, uint64_t> &BBAddr, const std::unordered_map<BinaryBasicBlock *, uint64_t> &BBSize) { … } Predecessors; /// Build a simplified version of the call graph: For every function, keep /// its callers and the frequencies of the calls std::unordered_map<const BinaryFunction *, Predecessors> extractFunctionCalls(const std::vector<BinaryFunction *> &BinaryFunctions) { … } /// Compute expected hit ratio of the i-TLB cache (optimized by HFSortPlus alg). /// Given an assignment of functions to the i-TLB pages), we divide all /// functions calls into two categories: /// - 'short' ones that have a caller-callee distance less than a page; /// - 'long' ones where the distance exceeds a page. /// The short calls are likely to result in a i-TLB cache hit. For the long /// ones, the hit/miss result depends on the 'hotness' of the page (i.e., how /// often the page is accessed). Assuming that functions are sent to the i-TLB /// cache in a random order, the probability that a page is present in the cache /// is proportional to the number of samples corresponding to the functions on /// the page. The following procedure detects short and long calls, and /// estimates the expected number of cache misses for the long ones. double expectedCacheHitRatio( const std::vector<BinaryFunction *> &BinaryFunctions, const std::unordered_map<BinaryBasicBlock *, uint64_t> &BBAddr, const std::unordered_map<BinaryBasicBlock *, uint64_t> &BBSize) { … } } // namespace void CacheMetrics::printAll(raw_ostream &OS, const std::vector<BinaryFunction *> &BFs) { … }