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