llvm.org GIT mirror llvm / aab8d7f
[PGO] Revert r260146 as it breaks Darwin platforms. r260146 | xur | 2016-02-08 13:07:46 -0800 (Mon, 08 Feb 2016) | 13 lines [PGO] Differentiate Clang instrumentation and IR level instrumentation profiles git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260170 91177308-0d34-0410-b5e6-96231b3b80d8 Rong Xu 3 years ago
25 changed file(s) with 13 addition(s) and 147 deletion(s). Raw diff Collapse all Expand all
704704 * version for other variants of profile. We set the lowest bit of the upper 8
705705 * bits (i.e. bit 56) to 1 to indicate if this is an IR-level instrumentaiton
706706 * generated profile, and 0 if this is a Clang FE generated profile.
707 */
707 */
708708 #define VARIANT_MASKS_ALL 0xff00000000000000ULL
709709 #define GET_VERSION(V) ((V) & ~VARIANT_MASKS_ALL)
710 #define VARIANT_MASK_IR_PROF (0x1ULL << 56)
711 #define IR_LEVEL_PROF_VERSION_VAR __llvm_profile_raw_version
712710
713711 /* Runtime section names and name strings. */
714712 #define INSTR_PROF_DATA_SECT_NAME __llvm_prf_data
6363 /// Iterator over profile data.
6464 InstrProfIterator begin() { return InstrProfIterator(this); }
6565 InstrProfIterator end() { return InstrProfIterator(); }
66 virtual bool isIRLevelProfile() const = 0;
6766
6867 /// Return the PGO symtab. There are three different readers:
6968 /// Raw, Text, and Indexed profile readers. The first two types
118117 std::unique_ptr DataBuffer;
119118 /// Iterator over the profile data.
120119 line_iterator Line;
121 bool IsIRLevelProfile;
122120
123121 TextInstrProfReader(const TextInstrProfReader &) = delete;
124122 TextInstrProfReader &operator=(const TextInstrProfReader &) = delete;
126124
127125 public:
128126 TextInstrProfReader(std::unique_ptr DataBuffer_)
129 : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#'),
130 IsIRLevelProfile(false) {}
127 : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#') {}
131128
132129 /// Return true if the given buffer is in text instrprof format.
133130 static bool hasFormat(const MemoryBuffer &Buffer);
134
135 bool isIRLevelProfile() const override { return IsIRLevelProfile; }
136131
137132 /// Read the header.
138133 std::error_code readHeader() override;
158153 /// The profile data file contents.
159154 std::unique_ptr DataBuffer;
160155 bool ShouldSwapBytes;
161 // The value of the version field of the raw profile data header. The lower 56
162 // bits specifies the format version and the most significant 8 bits specify
163 // the variant types of the profile.
164 uint64_t Version;
165156 uint64_t CountersDelta;
166157 uint64_t NamesDelta;
167158 const RawInstrProf::ProfileData *Data;
185176 static bool hasFormat(const MemoryBuffer &DataBuffer);
186177 std::error_code readHeader() override;
187178 std::error_code readNextRecord(InstrProfRecord &Record) override;
188 bool isIRLevelProfile() const override {
189 return (Version & VARIANT_MASK_IR_PROF) != 0;
190 }
191179
192180 InstrProfSymtab &getSymtab() override {
193181 assert(Symtab.get());
303291 virtual void setValueProfDataEndianness(support::endianness Endianness) = 0;
304292 virtual ~InstrProfReaderIndexBase() {}
305293 virtual uint64_t getVersion() const = 0;
306 virtual bool isIRLevelProfile() const = 0;
307294 virtual void populateSymtab(InstrProfSymtab &) = 0;
308295 };
309296
335322 HashTable->getInfoObj().setValueProfDataEndianness(Endianness);
336323 }
337324 ~InstrProfReaderIndex() override {}
338 uint64_t getVersion() const override { return GET_VERSION(FormatVersion); }
339 bool isIRLevelProfile() const override {
340 return (FormatVersion & VARIANT_MASK_IR_PROF) != 0;
341 }
325 uint64_t getVersion() const override { return FormatVersion; }
342326 void populateSymtab(InstrProfSymtab &Symtab) override {
343327 Symtab.create(HashTable->keys());
344328 }
363347 const unsigned char *Cur);
364348
365349 public:
366 /// Return the profile version.
367350 uint64_t getVersion() const { return Index->getVersion(); }
368 bool isIRLevelProfile() const override { return Index->isIRLevelProfile(); }
369351 IndexedInstrProfReader(std::unique_ptr DataBuffer)
370352 : DataBuffer(std::move(DataBuffer)), Index(nullptr) {}
371353
2929 class InstrProfWriter {
3030 public:
3131 typedef SmallDenseMap ProfilingData;
32 enum ProfKind { PF_Unknown = 0, PF_FE, PF_IRLevel };
3332
3433 private:
3534 bool Sparse;
3635 StringMap FunctionData;
37 ProfKind ProfileKind;
3836 // Use raw pointer here for the incomplete type object.
3937 InstrProfRecordWriterTrait *InfoObj;
4038
5654 /// Write the profile, returning the raw data. For testing.
5755 std::unique_ptr writeBuffer();
5856
59 /// Set the ProfileKind. Report error if mixing FE and IR level profiles.
60 std::error_code setIsIRLevelProfile(bool IsIRLevel) {
61 if (ProfileKind == PF_Unknown) {
62 ProfileKind = IsIRLevel ? PF_IRLevel: PF_FE;
63 return instrprof_error::success;
64 }
65 return (IsIRLevel == (ProfileKind == PF_IRLevel)) ?
66 instrprof_error::success : instrprof_error::unsupported_version;
67 }
68
6957 // Internal interface for testing purpose only.
7058 void setValueProfDataEndianness(support::endianness Endianness);
7159 void setOutputSparse(bool Sparse);
108108 [](char c) { return ::isprint(c) || ::isspace(c); });
109109 }
110110
111 // Read the profile variant flag from the header: ":FE" means this is a FE
112 // generated profile. ":IR" means this is an IR level profile. Other strings
113 // with a leading ':' will be reported an error format.
114111 std::error_code TextInstrProfReader::readHeader() {
115112 Symtab.reset(new InstrProfSymtab());
116 bool IsIRInstr = false;
117 if (!Line->startswith(":")) {
118 IsIRLevelProfile = false;
119 return success();
120 }
121 StringRef Str = (Line)->substr(1);
122 if (Str.equals_lower("ir"))
123 IsIRInstr = true;
124 else if (Str.equals_lower("fe"))
125 IsIRInstr = false;
126 else
127 return instrprof_error::bad_header;
128
129 ++Line;
130 IsIRLevelProfile = IsIRInstr;
131113 return success();
132114 }
133115
310292 template
311293 std::error_code
312294 RawInstrProfReader::readHeader(const RawInstrProf::Header &Header) {
313 Version = swap(Header.Version);
314 if (GET_VERSION(Version) != RawInstrProf::Version)
295 if (swap(Header.Version) != RawInstrProf::Version)
315296 return error(instrprof_error::unsupported_version);
316297
317298 CountersDelta = swap(Header.CountersDelta);
488469 return data_type();
489470 uint64_t Hash = endian::readNext(D);
490471
491 // Initialize number of counters for GET_VERSION(FormatVersion) == 1.
472 // Initialize number of counters for FormatVersion == 1.
492473 uint64_t CountsSize = N / sizeof(uint64_t) - 1;
493474 // If format version is different then read the number of counters.
494 if (GET_VERSION(FormatVersion) != IndexedInstrProf::ProfVersion::Version1) {
475 if (FormatVersion != IndexedInstrProf::ProfVersion::Version1) {
495476 if (D + sizeof(uint64_t) > End)
496477 return data_type();
497478 CountsSize = endian::readNext(D);
508489 DataBuffer.emplace_back(K, Hash, std::move(CounterBuffer));
509490
510491 // Read value profiling data.
511 if (GET_VERSION(FormatVersion) > IndexedInstrProf::ProfVersion::Version2 &&
492 if (FormatVersion > IndexedInstrProf::ProfVersion::Version2 &&
512493 !readValueProfilingData(D, End)) {
513494 DataBuffer.clear();
514495 return data_type();
621602
622603 // Read the version.
623604 uint64_t FormatVersion = endian::byte_swap(Header->Version);
624 if (GET_VERSION(FormatVersion) >
625 IndexedInstrProf::ProfVersion::CurrentVersion)
605 if (FormatVersion > IndexedInstrProf::ProfVersion::CurrentVersion)
626606 return error(instrprof_error::unsupported_version);
627607
628608 Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur);
141141 }
142142
143143 InstrProfWriter::InstrProfWriter(bool Sparse)
144 : Sparse(Sparse), FunctionData(), ProfileKind(PF_Unknown),
144 : Sparse(Sparse), FunctionData(),
145145 InfoObj(new InstrProfRecordWriterTrait()) {}
146146
147147 InstrProfWriter::~InstrProfWriter() { delete InfoObj; }
229229 IndexedInstrProf::Header Header;
230230 Header.Magic = IndexedInstrProf::Magic;
231231 Header.Version = IndexedInstrProf::ProfVersion::CurrentVersion;
232 if (ProfileKind == PF_IRLevel)
233 Header.Version |= VARIANT_MASK_IR_PROF;
234232 Header.Unused = 0;
235233 Header.HashType = static_cast(IndexedInstrProf::HashType);
236234 Header.HashOffset = 0;
337335 }
338336
339337 void InstrProfWriter::writeText(raw_fd_ostream &OS) {
340 if (ProfileKind == PF_IRLevel)
341 OS << "# IR level Instrumentation Flag\n:ir\n";
342338 InstrProfSymtab Symtab;
343339 for (const auto &I : FunctionData)
344340 if (shouldEncodeData(I.getValue()))
712712 }
713713 } // end anonymous namespace
714714
715 // Create a COMDAT variable IR_LEVEL_PROF_VARNAME to make the runtime
716 // aware this is an ir_level profile so it can set the version flag.
717 static void createIRLevelProfileFlagVariable(Module &M) {
718 Type *IntTy64 = Type::getInt64Ty(M.getContext());
719 uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
720 auto IRLevelVersionVariable =
721 new GlobalVariable(M, IntTy64, true, GlobalVariable::ExternalLinkage,
722 Constant::getIntegerValue(IntTy64, APInt(64, ProfileVersion)),
723 INSTR_PROF_QUOTE(IR_LEVEL_PROF_VERSION_VAR));
724 IRLevelVersionVariable->setVisibility(GlobalValue::DefaultVisibility);
725 IRLevelVersionVariable->setComdat(
726 M.getOrInsertComdat(StringRef(INSTR_PROF_QUOTE(IR_LEVEL_PROF_VERSION_VAR))));
727 }
728
729715 bool PGOInstrumentationGen::runOnModule(Module &M) {
730 createIRLevelProfileFlagVariable(M);
731716 for (auto &F : M) {
732717 if (F.isDeclaration())
733718 continue;
765750 "Cannot get PGOReader"));
766751 return false;
767752 }
768 // TODO: might need to change the warning once the clang option is finalized.
769 if (!PGOReader->isIRLevelProfile()) {
770 Ctx.diagnose(DiagnosticInfoPGOProfile(
771 ProfileFileName.data(), "Not an IR level instrumentation profile"));
772 return false;
773 }
774
775753
776754 for (auto &F : M) {
777755 if (F.isDeclaration())
None # :ir is the flag to indicate this is IR level profile.
1 :ir
2 test_br_1
31 25571299074
42 2
None # :ir is the flag to indicate this is IR level profile.
1 :ir
2 test_br_2
31 29667547796
42 2
None # :ir is the flag to indicate this is IR level profile.
1 :ir
2 test_criticalEdge
31 82323253069
42 8
None # :ir is the flag to indicate this is IR level profile.
1 :ir
2 foo
31 12884999999
42 1
+0
-5
test/Transforms/PGOProfile/Inputs/diag_FE.proftext less more
None foo
1 12884999999
2 1
3 1
4
None # :ir is the flag to indicate this is IR level profile.
1 :ir
2 foo
31 59130013419
42 4
None # :ir is the flag to indicate this is IR level profile.
1 :ir
2 test_simple_for
31 34137660316
42 2
None # :ir is the flag to indicate this is IR level profile.
1 :ir
2 test_nested_for
31 53929068288
42 3
None # :ir is the flag to indicate this is IR level profile.
1 :ir
2 test_switch
31 46200943743
42 4
33 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
44 target triple = "x86_64-unknown-linux-gnu"
55
6 ; GEN: $__llvm_profile_raw_version = comdat any
7 ; GEN: @__llvm_profile_raw_version = constant i64 72057594037927939, comdat
86 ; GEN: @__profn_test_br_1 = private constant [9 x i8] c"test_br_1"
97
108 define i32 @test_br_1(i32 %i) {
33 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
44 target triple = "x86_64-unknown-linux-gnu"
55
6 ; GEN: $__llvm_profile_raw_version = comdat any
7 ; GEN: @__llvm_profile_raw_version = constant i64 72057594037927939, comdat
86 ; GEN: @__profn_test_br_2 = private constant [9 x i8] c"test_br_2"
97
108 define i32 @test_br_2(i32 %i) {
33 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
44 target triple = "x86_64-unknown-linux-gnu"
55
6 ; GEN: $__llvm_profile_raw_version = comdat any
7 ; GEN: @__llvm_profile_raw_version = constant i64 72057594037927939, comdat
86 ; GEN: @__profn_test_criticalEdge = private constant [17 x i8] c"test_criticalEdge"
97 ; GEN: @__profn__stdin__bar = private constant [11 x i8] c":bar"
108
+0
-12
test/Transforms/PGOProfile/diag_FE_profile.ll less more
None ; RUN: llvm-profdata merge %S/Inputs/diag_FE.proftext -o %t.profdata
1 ; RUN: not opt < %s -pgo-instr-use -pgo-test-profile-file=%t.profdata -S 2>&1 | FileCheck %s
2
3 ; CHECK: Not an IR level instrumentation profile
4
5 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6 target triple = "x86_64-unknown-linux-gnu"
7
8 define i32 @foo() {
9 entry:
10 ret i32 0
11 }
55
66 @val = global i32 0, align 4
77 @_ZTIi = external constant i8*
8 ; GEN: $__llvm_profile_raw_version = comdat any
9 ; GEN: @__llvm_profile_raw_version = constant i64 72057594037927939, comdat
108 ; GEN: @__profn_bar = private constant [3 x i8] c"bar"
119 ; GEN: @__profn_foo = private constant [3 x i8] c"foo"
1210
33 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
44 target triple = "x86_64-unknown-linux-gnu"
55
6 ; GEN: $__llvm_profile_raw_version = comdat any
7 ; GEN: @__llvm_profile_raw_version = constant i64 72057594037927939, comdat
86 ; GEN: @__profn_test_simple_for = private constant [15 x i8] c"test_simple_for"
97
108 define i32 @test_simple_for(i32 %n) {
33 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
44 target triple = "x86_64-unknown-linux-gnu"
55
6 ; GEN: $__llvm_profile_raw_version = comdat any
7 ; GEN: @__llvm_profile_raw_version = constant i64 72057594037927939, comdat
86 ; GEN: @__profn_test_nested_for = private constant [15 x i8] c"test_nested_for"
97
108 define i32 @test_nested_for(i32 %r, i32 %s) {
11 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
22 target triple = "x86_64-unknown-linux-gnu"
33
4 ; GEN: $__llvm_profile_raw_version = comdat any
5 ; GEN: @__llvm_profile_raw_version = constant i64 72057594037927939, comdat
64 ; GEN: @__profn_single_bb = private constant [9 x i8] c"single_bb"
75
86 define i32 @single_bb() {
33 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
44 target triple = "x86_64-unknown-linux-gnu"
55
6 ; GEN: $__llvm_profile_raw_version = comdat any
7 ; GEN: @__llvm_profile_raw_version = constant i64 72057594037927939, comdat
86 ; GEN: @__profn_test_switch = private constant [11 x i8] c"test_switch"
97
108 define void @test_switch(i32 %i) {
127127 exitWithErrorCode(ec, Input.Filename);
128128
129129 auto Reader = std::move(ReaderOrErr.get());
130 bool IsIRProfile = Reader->isIRLevelProfile();
131 if (Writer.setIsIRLevelProfile(IsIRProfile))
132 exitWithError("Merge IR generated profile with Clang generated profile.");
133
134130 for (auto &I : *Reader) {
135131 if (std::error_code EC = Writer.addRecord(std::move(I), Input.Weight)) {
136132 // Only show hint the first time an error occurs.
272268 exitWithErrorCode(EC, Filename);
273269
274270 auto Reader = std::move(ReaderOrErr.get());
275 bool IsIRInstr = Reader->isIRLevelProfile();
276271 size_t ShownFunctions = 0;
277272 for (const auto &Func : *Reader) {
278273 bool Show =
299294
300295 OS << " " << Func.Name << ":\n"
301296 << " Hash: " << format("0x%016" PRIx64, Func.Hash) << "\n"
302 << " Counters: " << Func.Counts.size() << "\n";
303 if (!IsIRInstr)
304 OS << " Function count: " << Func.Counts[0] << "\n";
297 << " Counters: " << Func.Counts.size() << "\n"
298 << " Function count: " << Func.Counts[0] << "\n";
305299
306300 if (ShowIndirectCallTargets)
307301 OS << " Indirect Call Site Count: "
309303
310304 if (ShowCounts) {
311305 OS << " Block counts: [";
312 size_t Start = (IsIRInstr ? 0 : 1);
313 for (size_t I = Start, E = Func.Counts.size(); I < E; ++I) {
314 OS << (I == Start ? "" : ", ") << Func.Counts[I];
306 for (size_t I = 1, E = Func.Counts.size(); I < E; ++I) {
307 OS << (I == 1 ? "" : ", ") << Func.Counts[I];
315308 }
316309 OS << "]\n";
317310 }