X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FProfileData%2FInstrProfReader.cpp;h=5c1993766aacedf4ebb48821057c98e737d9443f;hb=9f92467a5348cecdc5513ba9805add6c67e504c2;hp=c7809b8b8c6bd3f45ff2ceb99e034d0815ba771f;hpb=4e2b922131ae617cb8738d1871e9d918c44bdb69;p=oota-llvm.git diff --git a/lib/ProfileData/InstrProfReader.cpp b/lib/ProfileData/InstrProfReader.cpp index c7809b8b8c6..5c1993766aa 100644 --- a/lib/ProfileData/InstrProfReader.cpp +++ b/lib/ProfileData/InstrProfReader.cpp @@ -23,8 +23,11 @@ using namespace llvm; static std::error_code setupMemoryBuffer(std::string Path, std::unique_ptr &Buffer) { - if (std::error_code EC = MemoryBuffer::getFileOrSTDIN(Path, Buffer)) + ErrorOr> BufferOrErr = + MemoryBuffer::getFileOrSTDIN(Path); + if (std::error_code EC = BufferOrErr.getError()) return EC; + Buffer = std::move(BufferOrErr.get()); // Sanity check the file. if (Buffer->getBufferSize() > std::numeric_limits::max()) @@ -80,8 +83,8 @@ void InstrProfIterator::Increment() { } std::error_code TextInstrProfReader::readNextRecord(InstrProfRecord &Record) { - // Skip empty lines. - while (!Line.is_at_end() && Line->empty()) + // Skip empty lines and comments. + while (!Line.is_at_end() && (Line->empty() || Line->startswith("#"))) ++Line; // If we hit EOF while looking for a name, we're done. if (Line.is_at_end()) @@ -158,7 +161,7 @@ bool RawInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) { uint64_t Magic = *reinterpret_cast(DataBuffer.getBufferStart()); return getRawMagic() == Magic || - sys::SwapByteOrder(getRawMagic()) == Magic; + sys::getSwappedBytes(getRawMagic()) == Magic; } template @@ -304,8 +307,8 @@ std::error_code IndexedInstrProfReader::readHeader() { return error(instrprof_error::bad_magic); // Read the version. - uint64_t Version = endian::readNext(Cur); - if (Version != IndexedInstrProf::Version) + FormatVersion = endian::readNext(Cur); + if (FormatVersion > IndexedInstrProf::Version) return error(instrprof_error::unsupported_version); // Read the maximal function count. @@ -328,18 +331,31 @@ std::error_code IndexedInstrProfReader::readHeader() { } std::error_code IndexedInstrProfReader::getFunctionCounts( - StringRef FuncName, uint64_t &FuncHash, std::vector &Counts) { - const auto &Iter = Index->find(FuncName); + StringRef FuncName, uint64_t FuncHash, std::vector &Counts) { + auto Iter = Index->find(FuncName); if (Iter == Index->end()) return error(instrprof_error::unknown_function); - // Found it. Make sure it's valid before giving back a result. - const InstrProfRecord &Record = *Iter; - if (Record.Name.empty()) - return error(instrprof_error::malformed); - FuncHash = Record.Hash; - Counts = Record.Counts; - return success(); + // Found it. Look for counters with the right hash. + ArrayRef Data = (*Iter).Data; + uint64_t NumCounts; + for (uint64_t I = 0, E = Data.size(); I != E; I += NumCounts) { + // The function hash comes first. + uint64_t FoundHash = Data[I++]; + // In v1, we have at least one count. Later, we have the number of counts. + if (I == E) + return error(instrprof_error::malformed); + NumCounts = FormatVersion == 1 ? E - I : Data[I++]; + // If we have more counts than data, this is bogus. + if (I + NumCounts > E) + return error(instrprof_error::malformed); + // Check for a match and fill the vector if there is one. + if (FoundHash == FuncHash) { + Counts = Data.slice(I, NumCounts); + return success(); + } + } + return error(instrprof_error::hash_mismatch); } std::error_code @@ -348,10 +364,30 @@ IndexedInstrProfReader::readNextRecord(InstrProfRecord &Record) { if (RecordIterator == Index->data_end()) return error(instrprof_error::eof); - // Read the next one. - Record = *RecordIterator; - ++RecordIterator; - if (Record.Name.empty()) + // Record the current function name. + Record.Name = (*RecordIterator).Name; + + ArrayRef Data = (*RecordIterator).Data; + // Valid data starts with a hash and either a count or the number of counts. + if (CurrentOffset + 1 > Data.size()) + return error(instrprof_error::malformed); + // First we have a function hash. + Record.Hash = Data[CurrentOffset++]; + // In version 1 we knew the number of counters implicitly, but in newer + // versions we store the number of counters next. + uint64_t NumCounts = + FormatVersion == 1 ? Data.size() - CurrentOffset : Data[CurrentOffset++]; + if (CurrentOffset + NumCounts > Data.size()) return error(instrprof_error::malformed); + // And finally the counts themselves. + Record.Counts = Data.slice(CurrentOffset, NumCounts); + + // If we've exhausted this function's data, increment the record. + CurrentOffset += NumCounts; + if (CurrentOffset == Data.size()) { + ++RecordIterator; + CurrentOffset = 0; + } + return success(); }