llvm.org GIT mirror llvm / dcefe31
Revert "Replace the use of MaxFunctionCount module flag" This reverts commit r266477. This commit introduces cyclic dependency. This commit has "Analysis" depend on "ProfileData", while "ProfileData" depends on "Object", which depends on "BitCode", which depends on "Analysis". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@266619 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Liu 4 years ago
7 changed file(s) with 18 addition(s) and 186 deletion(s). Raw diff Collapse all Expand all
2020 #include
2121
2222 #include "llvm/Support/Casting.h"
23 #include "llvm/Support/ManagedStatic.h"
24 #include "llvm/Support/Mutex.h"
2523
2624 namespace llvm {
2725 class Function;
3634 class Metadata;
3735 class MDTuple;
3836 class MDNode;
39 class Module;
4037
4138 inline const char *getHotSectionPrefix() { return ".hot"; }
4239 inline const char *getUnlikelySectionPrefix() { return ".unlikely"; }
6966 // appears in the profile. The map is kept sorted in the descending order of
7067 // counts.
7168 std::map> CountFrequencies;
72 // Compute profile summary for a module.
73 static ProfileSummary *computeProfileSummary(Module *M);
74 // Cache of last seen module and its profile summary.
75 static ManagedStatic>>
76 CachedSummary;
77 // Mutex to access summary cache
78 static ManagedStatic> CacheMutex;
79
8069 protected:
8170 SummaryEntryVector DetailedSummary;
8271 std::vector DetailedSummaryCutoffs;
9584 : PSK(K), DetailedSummary(DetailedSummary), TotalCount(TotalCount),
9685 MaxCount(MaxCount), MaxFunctionCount(MaxFunctionCount),
9786 NumCounts(NumCounts), NumFunctions(NumFunctions) {}
87 ~ProfileSummary() = default;
9888 inline void addCount(uint64_t Count);
9989 /// \brief Return metadata specific to the profile format.
10090 /// Derived classes implement this method to return a vector of Metadata.
10191 virtual std::vector getFormatSpecificMD(LLVMContext &Context) = 0;
10292 /// \brief Return detailed summary as metadata.
10393 Metadata *getDetailedSummaryMD(LLVMContext &Context);
94
10495 public:
10596 static const int Scale = 1000000;
10697 Kind getKind() const { return PSK; }
119110 static ProfileSummary *getFromMD(Metadata *MD);
120111 uint32_t getNumFunctions() { return NumFunctions; }
121112 uint64_t getMaxFunctionCount() { return MaxFunctionCount; }
122 /// \brief Get profile summary associated with module \p M
123 static inline ProfileSummary *getProfileSummary(Module *M);
124 virtual ~ProfileSummary() = default;
125 virtual bool operator==(ProfileSummary &Other);
126113 };
127114
128115 class InstrProfSummary final : public ProfileSummary {
152139 uint64_t getTotalCount() { return TotalCount; }
153140 uint64_t getMaxBlockCount() { return MaxCount; }
154141 uint64_t getMaxInternalBlockCount() { return MaxInternalBlockCount; }
155 bool operator==(ProfileSummary &Other) override;
156142 };
157143
158144 class SampleProfileSummary final : public ProfileSummary {
193179 return DetailedSummary;
194180 }
195181
196 ProfileSummary *ProfileSummary::getProfileSummary(Module *M) {
197 if (!M)
198 return nullptr;
199 sys::SmartScopedLock Lock(*CacheMutex);
200 // Computing profile summary for a module involves parsing a fairly large
201 // metadata and could be expensive. We use a simple cache of the last seen
202 // module and its profile summary.
203 if (CachedSummary->first != M) {
204 auto *Summary = computeProfileSummary(M);
205 // Do not cache if the summary is empty. This is because a later pass
206 // (sample profile loader, for example) could attach the summary metadata on
207 // the module.
208 if (!Summary)
209 return nullptr;
210 CachedSummary->first = M;
211 CachedSummary->second.reset(Summary);
212 }
213 return CachedSummary->second.get();
214 }
215182 } // end namespace llvm
216183 #endif
2929 #include "llvm/IR/InstVisitor.h"
3030 #include "llvm/IR/IntrinsicInst.h"
3131 #include "llvm/IR/Operator.h"
32 #include "llvm/ProfileData/ProfileCommon.h"
3332 #include "llvm/Support/Debug.h"
3433 #include "llvm/Support/raw_ostream.h"
3534
626625 // a well-tuned heuristic based on *callsite* hotness and not callee hotness.
627626 uint64_t FunctionCount = 0, MaxFunctionCount = 0;
628627 bool HasPGOCounts = false;
629 ProfileSummary *PS = ProfileSummary::getProfileSummary(Callee.getParent());
630 if (Callee.getEntryCount() && PS) {
628 if (Callee.getEntryCount() && Callee.getParent()->getMaximumFunctionCount()) {
631629 HasPGOCounts = true;
632630 FunctionCount = Callee.getEntryCount().getValue();
633 MaxFunctionCount = PS->getMaxFunctionCount();
631 MaxFunctionCount = Callee.getParent()->getMaximumFunctionCount().getValue();
634632 }
635633
636634 // Listen to the inlinehint attribute or profile based hotness information
1414 #include "llvm/IR/Constants.h"
1515 #include "llvm/IR/Function.h"
1616 #include "llvm/IR/Metadata.h"
17 #include "llvm/IR/Module.h"
1817 #include "llvm/IR/Type.h"
1918 #include "llvm/ProfileData/InstrProf.h"
2019 #include "llvm/ProfileData/ProfileCommon.h"
3130 200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000, 800000,
3231 900000, 950000, 990000, 999000, 999900, 999990, 999999});
3332 const char *ProfileSummary::KindStr[2] = {"InstrProf", "SampleProfile"};
34
35 ManagedStatic>>
36 ProfileSummary::CachedSummary;
37 ManagedStatic> ProfileSummary::CacheMutex;
3833
3934 void InstrProfSummary::addRecord(const InstrProfRecord &R) {
4035 addEntryCount(R.Counts[0]);
8681 }
8782 }
8883
89 bool ProfileSummary::operator==(ProfileSummary &Other) {
90 if (getKind() != Other.getKind())
91 return false;
92 if (TotalCount != Other.TotalCount)
93 return false;
94 if (MaxCount != Other.MaxCount)
95 return false;
96 if (MaxFunctionCount != Other.MaxFunctionCount)
97 return false;
98 if (NumFunctions != Other.NumFunctions)
99 return false;
100 if (NumCounts != Other.NumCounts)
101 return false;
102 std::vector DS1 = getDetailedSummary();
103 std::vector DS2 = Other.getDetailedSummary();
104 auto CompareSummaryEntry = [](ProfileSummaryEntry &E1,
105 ProfileSummaryEntry &E2) {
106 return E1.Cutoff == E2.Cutoff && E1.MinCount == E2.MinCount &&
107 E1.NumCounts == E2.NumCounts;
108 };
109 if (!std::equal(DS1.begin(), DS1.end(), DS2.begin(), CompareSummaryEntry))
110 return false;
111 return true;
112 }
113
114 bool InstrProfSummary::operator==(ProfileSummary &Other) {
115 InstrProfSummary *OtherIPS = dyn_cast(&Other);
116 if (!OtherIPS)
117 return false;
118 return MaxInternalBlockCount == OtherIPS->MaxInternalBlockCount &&
119 ProfileSummary::operator==(Other);
120 }
121
12284 // Returns true if the function is a hot function.
12385 bool ProfileSummary::isFunctionHot(const Function *F) {
12486 // FIXME: update when summary data is stored in module's metadata.
399361 else
400362 return nullptr;
401363 }
402
403 ProfileSummary *ProfileSummary::computeProfileSummary(Module *M) {
404 if (Metadata *MD = M->getProfileSummary())
405 return getFromMD(MD);
406 return nullptr;
407 }
44 ; A callee with identical body does gets inlined because cost fits within the
55 ; inline-threshold
66
7 define i32 @callee1(i32 %x) !prof !21 {
7 define i32 @callee1(i32 %x) !prof !1 {
88 %x1 = add i32 %x, 1
99 %x2 = add i32 %x1, 1
1010 %x3 = add i32 %x2, 1
1212 ret i32 %x3
1313 }
1414
15 define i32 @callee2(i32 %x) !prof !22 {
15 define i32 @callee2(i32 %x) !prof !2 {
1616 ; CHECK-LABEL: @callee2(
1717 %x1 = add i32 %x, 1
1818 %x2 = add i32 %x1, 1
2121 ret i32 %x3
2222 }
2323
24 define i32 @caller2(i32 %y1) !prof !22 {
24 define i32 @caller2(i32 %y1) !prof !2 {
2525 ; CHECK-LABEL: @caller2(
2626 ; CHECK: call i32 @callee2
2727 ; CHECK-NOT: call i32 @callee1
3131 ret i32 %y3
3232 }
3333
34 !llvm.module.flags = !{!1}
35 !21 = !{!"function_entry_count", i64 100}
36 !22 = !{!"function_entry_count", i64 1}
34 !llvm.module.flags = !{!0}
35 !0 = !{i32 1, !"MaxFunctionCount", i32 1000}
36 !1 = !{!"function_entry_count", i64 100}
37 !2 = !{!"function_entry_count", i64 1}
3738
38 !1 = !{i32 1, !"ProfileSummary", !2}
39 !2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
40 !3 = !{!"ProfileFormat", !"InstrProf"}
41 !4 = !{!"TotalCount", i64 10000}
42 !5 = !{!"MaxBlockCount", i64 1000}
43 !6 = !{!"MaxInternalBlockCount", i64 1}
44 !7 = !{!"MaxFunctionCount", i64 1000}
45 !8 = !{!"NumBlocks", i64 3}
46 !9 = !{!"NumFunctions", i64 3}
47 !10 = !{!"DetailedSummary", !11}
48 !11 = !{!12}
49 !12 = !{i32 10000, i64 0, i32 0}
44 ; A cold callee with identical body does not get inlined because cost exceeds the
55 ; inline-threshold
66
7 define i32 @callee1(i32 %x) !prof !20 {
7 define i32 @callee1(i32 %x) !prof !1 {
88 %x1 = add i32 %x, 1
99 %x2 = add i32 %x1, 1
1010 %x3 = add i32 %x2, 1
1212 ret i32 %x3
1313 }
1414
15 define i32 @callee2(i32 %x) !prof !21 {
15 define i32 @callee2(i32 %x) !prof !2 {
1616 ; CHECK-LABEL: @callee2(
1717 %x1 = add i32 %x, 1
1818 %x2 = add i32 %x1, 1
2121 ret i32 %x3
2222 }
2323
24 define i32 @caller2(i32 %y1) !prof !21 {
24 define i32 @caller2(i32 %y1) !prof !2 {
2525 ; CHECK-LABEL: @caller2(
2626 ; CHECK: call i32 @callee2
2727 ; CHECK-NOT: call i32 @callee1
3131 ret i32 %y3
3232 }
3333
34 !llvm.module.flags = !{!1}
35 !20 = !{!"function_entry_count", i64 10}
36 !21 = !{!"function_entry_count", i64 1}
34 !llvm.module.flags = !{!0}
35 !0 = !{i32 1, !"MaxFunctionCount", i32 10}
36 !1 = !{!"function_entry_count", i64 10}
37 !2 = !{!"function_entry_count", i64 1}
3738
38 !1 = !{i32 1, !"ProfileSummary", !2}
39 !2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
40 !3 = !{!"ProfileFormat", !"InstrProf"}
41 !4 = !{!"TotalCount", i64 10000}
42 !5 = !{!"MaxBlockCount", i64 10}
43 !6 = !{!"MaxInternalBlockCount", i64 1}
44 !7 = !{!"MaxFunctionCount", i64 10}
45 !8 = !{!"NumBlocks", i64 3}
46 !9 = !{!"NumFunctions", i64 3}
47 !10 = !{!"DetailedSummary", !11}
48 !11 = !{!12}
49 !12 = !{i32 10000, i64 0, i32 0}
66 add_llvm_unittest(ProfileDataTests
77 CoverageMappingTest.cpp
88 InstrProfTest.cpp
9 ProfileSummaryTest.cpp
109 SampleProfTest.cpp
1110 )
+0
-66
unittests/ProfileData/ProfileSummaryTest.cpp less more
None //===- unittest/ProfileData/ProfileSummaryTest.cpp --------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/IR/Module.h"
10 #include "llvm/ProfileData/InstrProf.h"
11 #include "llvm/ProfileData/ProfileCommon.h"
12 #include "llvm/ProfileData/SampleProf.h"
13 #include "gtest/gtest.h"
14
15 using namespace llvm;
16 using namespace sampleprof;
17
18 struct ProfileSummaryTest : ::testing::Test {
19 InstrProfSummary IPS;
20 SampleProfileSummary SPS;
21
22 ProfileSummaryTest()
23 : IPS({100000, 900000, 999999}), SPS({100000, 900000, 999999}) {}
24 void SetUp() {
25 InstrProfRecord Record1("func1", 0x1234, {97531, 5, 99999});
26 InstrProfRecord Record2("func2", 0x1234, {57341, 10000, 10, 1});
27 IPS.addRecord(Record1);
28 IPS.addRecord(Record2);
29
30 IPS.computeDetailedSummary();
31
32 FunctionSamples FooSamples;
33 FooSamples.addTotalSamples(7711);
34 FooSamples.addHeadSamples(610);
35 FooSamples.addBodySamples(1, 0, 610);
36 FooSamples.addBodySamples(2, 0, 600);
37 FooSamples.addBodySamples(4, 0, 60000);
38 FooSamples.addBodySamples(8, 0, 60351);
39 FooSamples.addBodySamples(10, 0, 605);
40
41 FunctionSamples BarSamples;
42 BarSamples.addTotalSamples(20301);
43 BarSamples.addHeadSamples(1437);
44 BarSamples.addBodySamples(1, 0, 1437);
45
46 SPS.addRecord(FooSamples);
47 SPS.addRecord(BarSamples);
48
49 SPS.computeDetailedSummary();
50 }
51
52 };
53
54 TEST_F(ProfileSummaryTest, summary_from_module) {
55 LLVMContext Context;
56 Module M1("M1", Context);
57 EXPECT_FALSE(ProfileSummary::getProfileSummary(&M1));
58 M1.setProfileSummary(IPS.getMD(Context));
59 EXPECT_TRUE(IPS == *ProfileSummary::getProfileSummary(&M1));
60
61 Module M2("M2", Context);
62 EXPECT_FALSE(ProfileSummary::getProfileSummary(&M2));
63 M2.setProfileSummary(SPS.getMD(Context));
64 EXPECT_TRUE(SPS == *ProfileSummary::getProfileSummary(&M2));
65 }