summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ProfileData
diff options
context:
space:
mode:
authorRong Xu <xur@google.com>2016-02-10 17:18:30 +0000
committerRong Xu <xur@google.com>2016-02-10 17:18:30 +0000
commit33c76c0cc2aac6d78ea0c3b1ed71a0fadbd307d7 (patch)
tree72f293874b989caf7e13fb6dafe4994ae75a883e /llvm/lib/ProfileData
parent96449907a538b78c402696d94fe47bb3f96d543c (diff)
downloadbcm5719-llvm-33c76c0cc2aac6d78ea0c3b1ed71a0fadbd307d7.tar.gz
bcm5719-llvm-33c76c0cc2aac6d78ea0c3b1ed71a0fadbd307d7.zip
[PGO] Differentiate Clang instrumentation and IR level instrumentation profiles
This patch uses one bit in profile version to differentiate Clang instrumentation and IR level instrumentation profiles. PGOInstrumenation generates a COMDAT variable __llvm_profile_raw_version so that the compiler runtime can set the right profile kind. For Maco-O platform, we generate the variable as linkonce_odr linkage as COMDAT is not supported. PGOInstrumenation now checks this bit to make sure it's an IR level instrumentation profile. The patch was submitted as r260164 but reverted due to a Darwin test breakage. Original Differential Revision: http://reviews.llvm.org/D15540 Differential Revision: http://reviews.llvm.org/D17020 llvm-svn: 260385
Diffstat (limited to 'llvm/lib/ProfileData')
-rw-r--r--llvm/lib/ProfileData/InstrProfReader.cpp30
-rw-r--r--llvm/lib/ProfileData/InstrProfWriter.cpp6
2 files changed, 30 insertions, 6 deletions
diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp
index f189713c77a..7968cf1f60d 100644
--- a/llvm/lib/ProfileData/InstrProfReader.cpp
+++ b/llvm/lib/ProfileData/InstrProfReader.cpp
@@ -109,8 +109,26 @@ bool TextInstrProfReader::hasFormat(const MemoryBuffer &Buffer) {
[](char c) { return ::isprint(c) || ::isspace(c); });
}
+// Read the profile variant flag from the header: ":FE" means this is a FE
+// generated profile. ":IR" means this is an IR level profile. Other strings
+// with a leading ':' will be reported an error format.
std::error_code TextInstrProfReader::readHeader() {
Symtab.reset(new InstrProfSymtab());
+ bool IsIRInstr = false;
+ if (!Line->startswith(":")) {
+ IsIRLevelProfile = false;
+ return success();
+ }
+ StringRef Str = (Line)->substr(1);
+ if (Str.equals_lower("ir"))
+ IsIRInstr = true;
+ else if (Str.equals_lower("fe"))
+ IsIRInstr = false;
+ else
+ return instrprof_error::bad_header;
+
+ ++Line;
+ IsIRLevelProfile = IsIRInstr;
return success();
}
@@ -293,7 +311,8 @@ void RawInstrProfReader<IntPtrT>::createSymtab(InstrProfSymtab &Symtab) {
template <class IntPtrT>
std::error_code
RawInstrProfReader<IntPtrT>::readHeader(const RawInstrProf::Header &Header) {
- if (swap(Header.Version) != RawInstrProf::Version)
+ Version = swap(Header.Version);
+ if (GET_VERSION(Version) != RawInstrProf::Version)
return error(instrprof_error::unsupported_version);
CountersDelta = swap(Header.CountersDelta);
@@ -470,10 +489,10 @@ data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D,
return data_type();
uint64_t Hash = endian::readNext<uint64_t, little, unaligned>(D);
- // Initialize number of counters for FormatVersion == 1.
+ // Initialize number of counters for GET_VERSION(FormatVersion) == 1.
uint64_t CountsSize = N / sizeof(uint64_t) - 1;
// If format version is different then read the number of counters.
- if (FormatVersion != IndexedInstrProf::ProfVersion::Version1) {
+ if (GET_VERSION(FormatVersion) != IndexedInstrProf::ProfVersion::Version1) {
if (D + sizeof(uint64_t) > End)
return data_type();
CountsSize = endian::readNext<uint64_t, little, unaligned>(D);
@@ -490,7 +509,7 @@ data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D,
DataBuffer.emplace_back(K, Hash, std::move(CounterBuffer));
// Read value profiling data.
- if (FormatVersion > IndexedInstrProf::ProfVersion::Version2 &&
+ if (GET_VERSION(FormatVersion) > IndexedInstrProf::ProfVersion::Version2 &&
!readValueProfilingData(D, End)) {
DataBuffer.clear();
return data_type();
@@ -603,7 +622,8 @@ std::error_code IndexedInstrProfReader::readHeader() {
// Read the version.
uint64_t FormatVersion = endian::byte_swap<uint64_t, little>(Header->Version);
- if (FormatVersion > IndexedInstrProf::ProfVersion::CurrentVersion)
+ if (GET_VERSION(FormatVersion) >
+ IndexedInstrProf::ProfVersion::CurrentVersion)
return error(instrprof_error::unsupported_version);
Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur);
diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp
index a486d4eecb7..3e325718769 100644
--- a/llvm/lib/ProfileData/InstrProfWriter.cpp
+++ b/llvm/lib/ProfileData/InstrProfWriter.cpp
@@ -142,7 +142,7 @@ public:
}
InstrProfWriter::InstrProfWriter(bool Sparse)
- : Sparse(Sparse), FunctionData(),
+ : Sparse(Sparse), FunctionData(), ProfileKind(PF_Unknown),
InfoObj(new InstrProfRecordWriterTrait()) {}
InstrProfWriter::~InstrProfWriter() { delete InfoObj; }
@@ -230,6 +230,8 @@ void InstrProfWriter::writeImpl(ProfOStream &OS) {
IndexedInstrProf::Header Header;
Header.Magic = IndexedInstrProf::Magic;
Header.Version = IndexedInstrProf::ProfVersion::CurrentVersion;
+ if (ProfileKind == PF_IRLevel)
+ Header.Version |= VARIANT_MASK_IR_PROF;
Header.Unused = 0;
Header.HashType = static_cast<uint64_t>(IndexedInstrProf::HashType);
Header.HashOffset = 0;
@@ -336,6 +338,8 @@ void InstrProfWriter::writeRecordInText(const InstrProfRecord &Func,
}
void InstrProfWriter::writeText(raw_fd_ostream &OS) {
+ if (ProfileKind == PF_IRLevel)
+ OS << "# IR level Instrumentation Flag\n:ir\n";
InstrProfSymtab Symtab;
for (const auto &I : FunctionData)
if (shouldEncodeData(I.getValue()))
OpenPOWER on IntegriCloud