1 //===-- ProfileGenerator.h - Profile Generator -----------------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_TOOLS_LLVM_PROGEN_PROFILEGENERATOR_H
10 #define LLVM_TOOLS_LLVM_PROGEN_PROFILEGENERATOR_H
11 #include "ErrorHandling.h"
12 #include "PerfReader.h"
13 #include "ProfiledBinary.h"
14 #include "llvm/ProfileData/SampleProfWriter.h"
15 
16 using namespace llvm;
17 using namespace sampleprof;
18 
19 namespace llvm {
20 namespace sampleprof {
21 
22 class ProfileGenerator {
23 
24 public:
ProfileGenerator()25   ProfileGenerator(){};
26   virtual ~ProfileGenerator() = default;
27   static std::unique_ptr<ProfileGenerator>
28   create(const BinarySampleCounterMap &SampleCounters,
29          enum PerfScriptType SampleType);
30   virtual void generateProfile() = 0;
31 
32   // Use SampleProfileWriter to serialize profile map
33   void write();
34 
35 protected:
36   /*
37   For each region boundary point, mark if it is begin or end (or both) of
38   the region. Boundary points are inclusive. Log the sample count as well
39   so we can use it when we compute the sample count of each disjoint region
40   later. Note that there might be multiple ranges with different sample
41   count that share same begin/end point. We need to accumulate the sample
42   count for the boundary point for such case, because for the example
43   below,
44 
45   |<--100-->|
46   |<------200------>|
47   A         B       C
48 
49   sample count for disjoint region [A,B] would be 300.
50   */
51   void findDisjointRanges(RangeSample &DisjointRanges,
52                           const RangeSample &Ranges);
53 
54   // Used by SampleProfileWriter
55   StringMap<FunctionSamples> ProfileMap;
56 };
57 
58 class CSProfileGenerator : public ProfileGenerator {
59   const BinarySampleCounterMap &BinarySampleCounters;
60 
61 public:
CSProfileGenerator(const BinarySampleCounterMap & Counters)62   CSProfileGenerator(const BinarySampleCounterMap &Counters)
63       : BinarySampleCounters(Counters){};
64 
65 public:
generateProfile()66   void generateProfile() override {
67     // Fill in function body samples
68     populateFunctionBodySamples();
69 
70     // Fill in boundary sample counts as well as call site samples for calls
71     populateFunctionBoundarySamples();
72 
73     // Fill in call site value sample for inlined calls and also use context to
74     // infer missing samples. Since we don't have call count for inlined
75     // functions, we estimate it from inlinee's profile using the entry of the
76     // body sample.
77     populateInferredFunctionSamples();
78   }
79 
80 private:
81   // Helper function for updating body sample for a leaf location in
82   // FunctionProfile
83   void updateBodySamplesforFunctionProfile(FunctionSamples &FunctionProfile,
84                                            const FrameLocation &LeafLoc,
85                                            uint64_t Count);
86   // Lookup or create FunctionSamples for the context
87   FunctionSamples &getFunctionProfileForContext(StringRef ContextId);
88   void populateFunctionBodySamples();
89   void populateFunctionBoundarySamples();
90   void populateInferredFunctionSamples();
91 };
92 
93 } // end namespace sampleprof
94 } // end namespace llvm
95 
96 #endif
97