1 //===-- MissingFrameInferrer.h - Missing frame inferrer ---------- C++/-*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_TOOLS_LLVM_PROFGEN_MISSINGFRAMEINFERRER_H
10 #define LLVM_TOOLS_LLVM_PROFGEN_MISSINGFRAMEINFERRER_H
12 #include "PerfReader.h"
13 #include "llvm/ADT/DenseSet.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/Statistic.h"
16 #include <unordered_map>
17 #include <unordered_set>
20 namespace sampleprof
{
23 struct BinaryFunction
;
25 class MissingFrameInferrer
{
27 MissingFrameInferrer(ProfiledBinary
*Binary
) : Binary(Binary
) {}
29 // Defininig a frame transition from a caller function to the callee function.
30 using CallerCalleePair
= std::pair
<BinaryFunction
*, BinaryFunction
*>;
32 void initialize(const ContextSampleCounterMap
*SampleCounters
);
34 // Given an input `Context`, output `NewContext` with inferred missing tail
36 void inferMissingFrames(const SmallVectorImpl
<uint64_t> &Context
,
37 SmallVectorImpl
<uint64_t> &NewContext
);
40 friend class ProfiledBinary
;
42 // Compute a unique tail call path for a pair of source frame address and
43 // target frame address. Append the unique path prefix (not including `To`) to
44 // `UniquePath` if exists. Return the whether this's a unqiue tail call
45 // path. The source/dest frame will typically be a pair of adjacent frame
46 // entries of call stack samples.
47 bool inferMissingFrames(uint64_t From
, uint64_t To
,
48 SmallVectorImpl
<uint64_t> &UniquePath
);
50 // Compute a unique tail call path from the source frame address to the target
51 // function. Output the unique path prefix (not including `To`) in
52 // `UniquePath` if exists. Return the number of possibly availabe tail call
54 uint64_t computeUniqueTailCallPath(uint64_t From
, BinaryFunction
*To
,
55 SmallVectorImpl
<uint64_t> &UniquePath
);
57 // Compute a unique tail call path from the source function to the target
58 // function. Output the unique path prefix (not including `To`) in
59 // `UniquePath` if exists. Return the number of possibly availabe tail call
61 uint64_t computeUniqueTailCallPath(BinaryFunction
*From
, BinaryFunction
*To
,
62 SmallVectorImpl
<uint64_t> &UniquePath
);
64 ProfiledBinary
*Binary
;
66 // A map of call instructions to their target addresses. This is first
67 // populated with static call edges but then trimmed down to dynamic call
68 // edges based on LBR samples.
69 std::unordered_map
<uint64_t, std::unordered_set
<uint64_t>> CallEdges
;
71 // A map of tail call instructions to their target addresses. This is first
72 // populated with static call edges but then trimmed down to dynamic call
73 // edges based on LBR samples.
74 std::unordered_map
<uint64_t, std::unordered_set
<uint64_t>> TailCallEdges
;
76 // Dynamic call targets in terms of BinaryFunction for any calls.
77 std::unordered_map
<uint64_t, std::unordered_set
<BinaryFunction
*>> CallEdgesF
;
79 // Dynamic call targets in terms of BinaryFunction for tail calls.
80 std::unordered_map
<uint64_t, std::unordered_set
<BinaryFunction
*>>
83 // Dynamic tail call targets of caller functions.
84 std::unordered_map
<BinaryFunction
*, std::vector
<uint64_t>> FuncToTailCallMap
;
86 // Functions that are reachable via tail calls.
87 DenseSet
<const BinaryFunction
*> TailCallTargetFuncs
;
90 std::size_t operator()(
91 const std::pair
<BinaryFunction
*, BinaryFunction
*> &Pair
) const {
92 return std::hash
<BinaryFunction
*>()(Pair
.first
) ^
93 std::hash
<BinaryFunction
*>()(Pair
.second
);
97 // Cached results from a CallerCalleePair to a unique call path between them.
98 std::unordered_map
<CallerCalleePair
, std::vector
<uint64_t>, PairHash
>
100 // Cached results from CallerCalleePair to the number of available call paths.
101 std::unordered_map
<CallerCalleePair
, uint64_t, PairHash
> NonUniquePaths
;
103 DenseSet
<BinaryFunction
*> Visiting
;
105 uint32_t CurSearchingDepth
= 0;
107 #if LLVM_ENABLE_STATS
108 DenseSet
<std::pair
<uint64_t, uint64_t>> ReachableViaUniquePaths
;
109 DenseSet
<std::pair
<uint64_t, uint64_t>> Unreachables
;
110 DenseSet
<std::pair
<uint64_t, uint64_t>> ReachableViaMultiPaths
;
113 } // end namespace sampleprof
114 } // end namespace llvm