[DAGCombiner] Expand combining of FP logical ops to sign-setting FP ops
[llvm-core.git] / unittests / ProfileData / SampleProfTest.cpp
blob73e8088b638642bc8768e2239d43d5ae8db76ad3
1 //===- unittest/ProfileData/SampleProfTest.cpp ------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ProfileData/SampleProf.h"
11 #include "llvm/ADT/StringMap.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/IR/LLVMContext.h"
14 #include "llvm/IR/Metadata.h"
15 #include "llvm/IR/Module.h"
16 #include "llvm/ProfileData/SampleProfReader.h"
17 #include "llvm/ProfileData/SampleProfWriter.h"
18 #include "llvm/Support/Casting.h"
19 #include "llvm/Support/ErrorOr.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include "gtest/gtest.h"
23 #include <string>
24 #include <vector>
26 using namespace llvm;
27 using namespace sampleprof;
29 static ::testing::AssertionResult NoError(std::error_code EC) {
30 if (!EC)
31 return ::testing::AssertionSuccess();
32 return ::testing::AssertionFailure() << "error " << EC.value() << ": "
33 << EC.message();
36 namespace {
38 struct SampleProfTest : ::testing::Test {
39 LLVMContext Context;
40 std::unique_ptr<SampleProfileWriter> Writer;
41 std::unique_ptr<SampleProfileReader> Reader;
43 SampleProfTest() : Writer(), Reader() {}
45 void createWriter(SampleProfileFormat Format, StringRef Profile) {
46 std::error_code EC;
47 std::unique_ptr<raw_ostream> OS(
48 new raw_fd_ostream(Profile, EC, sys::fs::F_None));
49 auto WriterOrErr = SampleProfileWriter::create(OS, Format);
50 ASSERT_TRUE(NoError(WriterOrErr.getError()));
51 Writer = std::move(WriterOrErr.get());
54 void readProfile(const Module &M, StringRef Profile) {
55 auto ReaderOrErr = SampleProfileReader::create(Profile, Context);
56 ASSERT_TRUE(NoError(ReaderOrErr.getError()));
57 Reader = std::move(ReaderOrErr.get());
58 Reader->collectFuncsToUse(M);
61 void testRoundTrip(SampleProfileFormat Format) {
62 SmallVector<char, 128> ProfilePath;
63 ASSERT_TRUE(NoError(llvm::sys::fs::createTemporaryFile("profile", "", ProfilePath)));
64 StringRef Profile(ProfilePath.data(), ProfilePath.size());
65 createWriter(Format, Profile);
67 StringRef FooName("_Z3fooi");
68 FunctionSamples FooSamples;
69 FooSamples.setName(FooName);
70 FooSamples.addTotalSamples(7711);
71 FooSamples.addHeadSamples(610);
72 FooSamples.addBodySamples(1, 0, 610);
73 FooSamples.addBodySamples(2, 0, 600);
74 FooSamples.addBodySamples(4, 0, 60000);
75 FooSamples.addBodySamples(8, 0, 60351);
76 FooSamples.addBodySamples(10, 0, 605);
78 StringRef BarName("_Z3bari");
79 FunctionSamples BarSamples;
80 BarSamples.setName(BarName);
81 BarSamples.addTotalSamples(20301);
82 BarSamples.addHeadSamples(1437);
83 BarSamples.addBodySamples(1, 0, 1437);
84 // Test how reader/writer handles unmangled names.
85 StringRef MconstructName("_M_construct<char *>");
86 StringRef StringviewName("string_view<std::allocator<char> >");
87 BarSamples.addCalledTargetSamples(1, 0, MconstructName, 1000);
88 BarSamples.addCalledTargetSamples(1, 0, StringviewName, 437);
90 Module M("my_module", Context);
91 FunctionType *fn_type =
92 FunctionType::get(Type::getVoidTy(Context), {}, false);
93 M.getOrInsertFunction(FooName, fn_type);
94 M.getOrInsertFunction(BarName, fn_type);
96 StringMap<FunctionSamples> Profiles;
97 Profiles[FooName] = std::move(FooSamples);
98 Profiles[BarName] = std::move(BarSamples);
100 std::error_code EC;
101 EC = Writer->write(Profiles);
102 ASSERT_TRUE(NoError(EC));
104 Writer->getOutputStream().flush();
106 readProfile(M, Profile);
108 EC = Reader->read();
109 ASSERT_TRUE(NoError(EC));
111 StringMap<FunctionSamples> &ReadProfiles = Reader->getProfiles();
112 ASSERT_EQ(2u, ReadProfiles.size());
114 std::string FooGUID;
115 StringRef FooRep = getRepInFormat(FooName, Format, FooGUID);
116 FunctionSamples &ReadFooSamples = ReadProfiles[FooRep];
117 ASSERT_EQ(7711u, ReadFooSamples.getTotalSamples());
118 ASSERT_EQ(610u, ReadFooSamples.getHeadSamples());
120 std::string BarGUID;
121 StringRef BarRep = getRepInFormat(BarName, Format, BarGUID);
122 FunctionSamples &ReadBarSamples = ReadProfiles[BarRep];
123 ASSERT_EQ(20301u, ReadBarSamples.getTotalSamples());
124 ASSERT_EQ(1437u, ReadBarSamples.getHeadSamples());
125 ErrorOr<SampleRecord::CallTargetMap> CTMap =
126 ReadBarSamples.findCallTargetMapAt(1, 0);
127 ASSERT_FALSE(CTMap.getError());
129 std::string MconstructGUID;
130 StringRef MconstructRep =
131 getRepInFormat(MconstructName, Format, MconstructGUID);
132 std::string StringviewGUID;
133 StringRef StringviewRep =
134 getRepInFormat(StringviewName, Format, StringviewGUID);
135 ASSERT_EQ(1000u, CTMap.get()[MconstructRep]);
136 ASSERT_EQ(437u, CTMap.get()[StringviewRep]);
138 auto VerifySummary = [](ProfileSummary &Summary) mutable {
139 ASSERT_EQ(ProfileSummary::PSK_Sample, Summary.getKind());
140 ASSERT_EQ(123603u, Summary.getTotalCount());
141 ASSERT_EQ(6u, Summary.getNumCounts());
142 ASSERT_EQ(2u, Summary.getNumFunctions());
143 ASSERT_EQ(1437u, Summary.getMaxFunctionCount());
144 ASSERT_EQ(60351u, Summary.getMaxCount());
146 uint32_t Cutoff = 800000;
147 auto Predicate = [&Cutoff](const ProfileSummaryEntry &PE) {
148 return PE.Cutoff == Cutoff;
150 std::vector<ProfileSummaryEntry> &Details = Summary.getDetailedSummary();
151 auto EightyPerc = find_if(Details, Predicate);
152 Cutoff = 900000;
153 auto NinetyPerc = find_if(Details, Predicate);
154 Cutoff = 950000;
155 auto NinetyFivePerc = find_if(Details, Predicate);
156 Cutoff = 990000;
157 auto NinetyNinePerc = find_if(Details, Predicate);
158 ASSERT_EQ(60000u, EightyPerc->MinCount);
159 ASSERT_EQ(60000u, NinetyPerc->MinCount);
160 ASSERT_EQ(60000u, NinetyFivePerc->MinCount);
161 ASSERT_EQ(610u, NinetyNinePerc->MinCount);
164 ProfileSummary &Summary = Reader->getSummary();
165 VerifySummary(Summary);
167 // Test that conversion of summary to and from Metadata works.
168 Metadata *MD = Summary.getMD(Context);
169 ASSERT_TRUE(MD);
170 ProfileSummary *PS = ProfileSummary::getFromMD(MD);
171 ASSERT_TRUE(PS);
172 VerifySummary(*PS);
173 delete PS;
175 // Test that summary can be attached to and read back from module.
176 M.setProfileSummary(MD);
177 MD = M.getProfileSummary();
178 ASSERT_TRUE(MD);
179 PS = ProfileSummary::getFromMD(MD);
180 ASSERT_TRUE(PS);
181 VerifySummary(*PS);
182 delete PS;
186 TEST_F(SampleProfTest, roundtrip_text_profile) {
187 testRoundTrip(SampleProfileFormat::SPF_Text);
190 TEST_F(SampleProfTest, roundtrip_raw_binary_profile) {
191 testRoundTrip(SampleProfileFormat::SPF_Binary);
194 TEST_F(SampleProfTest, roundtrip_compact_binary_profile) {
195 testRoundTrip(SampleProfileFormat::SPF_Compact_Binary);
198 TEST_F(SampleProfTest, sample_overflow_saturation) {
199 const uint64_t Max = std::numeric_limits<uint64_t>::max();
200 sampleprof_error Result;
202 StringRef FooName("_Z3fooi");
203 FunctionSamples FooSamples;
204 Result = FooSamples.addTotalSamples(1);
205 ASSERT_EQ(Result, sampleprof_error::success);
207 Result = FooSamples.addHeadSamples(1);
208 ASSERT_EQ(Result, sampleprof_error::success);
210 Result = FooSamples.addBodySamples(10, 0, 1);
211 ASSERT_EQ(Result, sampleprof_error::success);
213 Result = FooSamples.addTotalSamples(Max);
214 ASSERT_EQ(Result, sampleprof_error::counter_overflow);
215 ASSERT_EQ(FooSamples.getTotalSamples(), Max);
217 Result = FooSamples.addHeadSamples(Max);
218 ASSERT_EQ(Result, sampleprof_error::counter_overflow);
219 ASSERT_EQ(FooSamples.getHeadSamples(), Max);
221 Result = FooSamples.addBodySamples(10, 0, Max);
222 ASSERT_EQ(Result, sampleprof_error::counter_overflow);
223 ErrorOr<uint64_t> BodySamples = FooSamples.findSamplesAt(10, 0);
224 ASSERT_FALSE(BodySamples.getError());
225 ASSERT_EQ(BodySamples.get(), Max);
228 } // end anonymous namespace