diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-08-22 19:00:43 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-11-13 20:39:49 +0000 |
commit | fe6060f10f634930ff71b7c50291ddc610da2475 (patch) | |
tree | 1483580c790bd4d27b6500a7542b5ee00534d3cc /contrib/llvm-project/clang/lib/Basic/SourceManager.cpp | |
parent | b61bce17f346d79cecfd8f195a64b10f77be43b1 (diff) | |
parent | 344a3780b2e33f6ca763666c380202b18aab72a3 (diff) |
Diffstat (limited to 'contrib/llvm-project/clang/lib/Basic/SourceManager.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Basic/SourceManager.cpp | 115 |
1 files changed, 82 insertions, 33 deletions
diff --git a/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp b/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp index c0b22837693b..8cba379aa0f8 100644 --- a/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp +++ b/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp @@ -26,6 +26,7 @@ #include "llvm/Support/Allocator.h" #include "llvm/Support/Capacity.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MathExtras.h" @@ -449,9 +450,9 @@ const SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index, return LoadedSLocEntryTable[Index]; } -std::pair<int, unsigned> +std::pair<int, SourceLocation::UIntTy> SourceManager::AllocateLoadedSLocEntries(unsigned NumSLocEntries, - unsigned TotalSize) { + SourceLocation::UIntTy TotalSize) { assert(ExternalSLocEntries && "Don't have an external sloc source"); // Make sure we're not about to run out of source locations. if (CurrentLoadedOffset - TotalSize < NextLocalOffset) @@ -531,7 +532,8 @@ FileID SourceManager::getNextFileID(FileID FID) const { FileID SourceManager::createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, - int LoadedID, unsigned LoadedOffset) { + int LoadedID, + SourceLocation::UIntTy LoadedOffset) { return createFileID(SourceFile->getLastRef(), IncludePos, FileCharacter, LoadedID, LoadedOffset); } @@ -539,7 +541,8 @@ FileID SourceManager::createFileID(const FileEntry *SourceFile, FileID SourceManager::createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, - int LoadedID, unsigned LoadedOffset) { + int LoadedID, + SourceLocation::UIntTy LoadedOffset) { SrcMgr::ContentCache &IR = getOrCreateContentCache(SourceFile, isSystem(FileCharacter)); @@ -558,7 +561,8 @@ FileID SourceManager::createFileID(FileEntryRef SourceFile, /// MemoryBuffer, so only pass a MemoryBuffer to this once. FileID SourceManager::createFileID(std::unique_ptr<llvm::MemoryBuffer> Buffer, SrcMgr::CharacteristicKind FileCharacter, - int LoadedID, unsigned LoadedOffset, + int LoadedID, + SourceLocation::UIntTy LoadedOffset, SourceLocation IncludeLoc) { StringRef Name = Buffer->getBufferIdentifier(); return createFileIDImpl(createMemBufferContentCache(std::move(Buffer)), Name, @@ -571,7 +575,8 @@ FileID SourceManager::createFileID(std::unique_ptr<llvm::MemoryBuffer> Buffer, /// outlive the SourceManager. FileID SourceManager::createFileID(const llvm::MemoryBufferRef &Buffer, SrcMgr::CharacteristicKind FileCharacter, - int LoadedID, unsigned LoadedOffset, + int LoadedID, + SourceLocation::UIntTy LoadedOffset, SourceLocation IncludeLoc) { return createFileID(llvm::MemoryBuffer::getMemBuffer(Buffer), FileCharacter, LoadedID, LoadedOffset, IncludeLoc); @@ -593,7 +598,8 @@ SourceManager::getOrCreateFileID(const FileEntry *SourceFile, FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, - int LoadedID, unsigned LoadedOffset) { + int LoadedID, + SourceLocation::UIntTy LoadedOffset) { if (LoadedID < 0) { assert(LoadedID != -1 && "Loading sentinel FileID"); unsigned Index = unsigned(-LoadedID) - 2; @@ -632,14 +638,11 @@ SourceManager::createMacroArgExpansionLoc(SourceLocation SpellingLoc, return createExpansionLocImpl(Info, TokLength); } -SourceLocation -SourceManager::createExpansionLoc(SourceLocation SpellingLoc, - SourceLocation ExpansionLocStart, - SourceLocation ExpansionLocEnd, - unsigned TokLength, - bool ExpansionIsTokenRange, - int LoadedID, - unsigned LoadedOffset) { +SourceLocation SourceManager::createExpansionLoc( + SourceLocation SpellingLoc, SourceLocation ExpansionLocStart, + SourceLocation ExpansionLocEnd, unsigned TokLength, + bool ExpansionIsTokenRange, int LoadedID, + SourceLocation::UIntTy LoadedOffset) { ExpansionInfo Info = ExpansionInfo::create( SpellingLoc, ExpansionLocStart, ExpansionLocEnd, ExpansionIsTokenRange); return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset); @@ -657,9 +660,8 @@ SourceLocation SourceManager::createTokenSplitLoc(SourceLocation Spelling, SourceLocation SourceManager::createExpansionLocImpl(const ExpansionInfo &Info, - unsigned TokLength, - int LoadedID, - unsigned LoadedOffset) { + unsigned TokLength, int LoadedID, + SourceLocation::UIntTy LoadedOffset) { if (LoadedID < 0) { assert(LoadedID != -1 && "Loading sentinel FileID"); unsigned Index = unsigned(-LoadedID) - 2; @@ -761,7 +763,7 @@ llvm::Optional<StringRef> SourceManager::getBufferDataOrNone(FileID FID) const { /// This is the cache-miss path of getFileID. Not as hot as that function, but /// still very important. It is responsible for finding the entry in the /// SLocEntry tables that contains the specified location. -FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const { +FileID SourceManager::getFileIDSlow(SourceLocation::UIntTy SLocOffset) const { if (!SLocOffset) return FileID::get(0); @@ -776,7 +778,7 @@ FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const { /// /// This function knows that the SourceLocation is in a local buffer, not a /// loaded one. -FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { +FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const { assert(SLocOffset < NextLocalOffset && "Bad function choice"); // After the first and second level caches, I see two common sorts of @@ -827,7 +829,8 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { NumProbes = 0; while (true) { unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex; - unsigned MidOffset = getLocalSLocEntry(MiddleIndex).getOffset(); + SourceLocation::UIntTy MidOffset = + getLocalSLocEntry(MiddleIndex).getOffset(); ++NumProbes; @@ -858,7 +861,7 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { /// /// This function knows that the SourceLocation is in a loaded buffer, not a /// local one. -FileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const { +FileID SourceManager::getFileIDLoaded(SourceLocation::UIntTy SLocOffset) const { // Sanity checking, otherwise a bug may lead to hanging in release build. if (SLocOffset < CurrentLoadedOffset) { assert(0 && "Invalid SLocOffset or bad function choice"); @@ -1252,12 +1255,22 @@ unsigned SourceManager::getPresumedColumnNumber(SourceLocation Loc, return PLoc.getColumn(); } -#ifdef __SSE2__ -#include <emmintrin.h> -#endif +// Check if mutli-byte word x has bytes between m and n, included. This may also +// catch bytes equal to n + 1. +// The returned value holds a 0x80 at each byte position that holds a match. +// see http://graphics.stanford.edu/~seander/bithacks.html#HasBetweenInWord +template <class T> +static constexpr inline T likelyhasbetween(T x, unsigned char m, + unsigned char n) { + return ((x - ~static_cast<T>(0) / 255 * (n + 1)) & ~x & + ((x & ~static_cast<T>(0) / 255 * 127) + + (~static_cast<T>(0) / 255 * (127 - (m - 1))))) & + ~static_cast<T>(0) / 255 * 128; +} LineOffsetMapping LineOffsetMapping::get(llvm::MemoryBufferRef Buffer, llvm::BumpPtrAllocator &Alloc) { + // Find the file offsets of all of the *physical* source lines. This does // not look at trigraphs, escaped newlines, or anything else tricky. SmallVector<unsigned, 256> LineOffsets; @@ -1268,7 +1281,43 @@ LineOffsetMapping LineOffsetMapping::get(llvm::MemoryBufferRef Buffer, const unsigned char *Buf = (const unsigned char *)Buffer.getBufferStart(); const unsigned char *End = (const unsigned char *)Buffer.getBufferEnd(); const std::size_t BufLen = End - Buf; + unsigned I = 0; + uint64_t Word; + + // scan sizeof(Word) bytes at a time for new lines. + // This is much faster than scanning each byte independently. + if (BufLen > sizeof(Word)) { + do { + Word = llvm::support::endian::read64(Buf + I, llvm::support::little); + // no new line => jump over sizeof(Word) bytes. + auto Mask = likelyhasbetween(Word, '\n', '\r'); + if (!Mask) { + I += sizeof(Word); + continue; + } + + // At that point, Mask contains 0x80 set at each byte that holds a value + // in [\n, \r + 1 [ + + // Scan for the next newline - it's very likely there's one. + unsigned N = + llvm::countTrailingZeros(Mask) - 7; // -7 because 0x80 is the marker + Word >>= N; + I += N / 8 + 1; + unsigned char Byte = Word; + if (Byte == '\n') { + LineOffsets.push_back(I); + } else if (Byte == '\r') { + // If this is \r\n, skip both characters. + if (Buf[I] == '\n') + ++I; + LineOffsets.push_back(I); + } + } while (I < BufLen - sizeof(Word) - 1); + } + + // Handle tail using a regular check. while (I < BufLen) { if (Buf[I] == '\n') { LineOffsets.push_back(I + 1); @@ -1572,7 +1621,7 @@ unsigned SourceManager::getFileIDSize(FileID FID) const { return 0; int ID = FID.ID; - unsigned NextOffset; + SourceLocation::UIntTy NextOffset; if ((ID > 0 && unsigned(ID+1) == local_sloc_entry_size())) NextOffset = getNextLocalOffset(); else if (ID+1 == -1) @@ -1780,8 +1829,8 @@ void SourceManager::associateFileChunkWithMacroArgExp( SourceLocation ExpansionLoc, unsigned ExpansionLength) const { if (!SpellLoc.isFileID()) { - unsigned SpellBeginOffs = SpellLoc.getOffset(); - unsigned SpellEndOffs = SpellBeginOffs + ExpansionLength; + SourceLocation::UIntTy SpellBeginOffs = SpellLoc.getOffset(); + SourceLocation::UIntTy SpellEndOffs = SpellBeginOffs + ExpansionLength; // The spelling range for this macro argument expansion can span multiple // consecutive FileID entries. Go through each entry contained in the @@ -1793,9 +1842,9 @@ void SourceManager::associateFileChunkWithMacroArgExp( std::tie(SpellFID, SpellRelativeOffs) = getDecomposedLoc(SpellLoc); while (true) { const SLocEntry &Entry = getSLocEntry(SpellFID); - unsigned SpellFIDBeginOffs = Entry.getOffset(); + SourceLocation::UIntTy SpellFIDBeginOffs = Entry.getOffset(); unsigned SpellFIDSize = getFileIDSize(SpellFID); - unsigned SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize; + SourceLocation::UIntTy SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize; const ExpansionInfo &Info = Entry.getExpansion(); if (Info.isMacroArgExpansion()) { unsigned CurrSpellLength; @@ -1887,7 +1936,7 @@ SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const { --I; - unsigned MacroArgBeginOffs = I->first; + SourceLocation::UIntTy MacroArgBeginOffs = I->first; SourceLocation MacroArgExpandedLoc = I->second; if (MacroArgExpandedLoc.isValid()) return MacroArgExpandedLoc.getLocWithOffset(Offset - MacroArgBeginOffs); @@ -2107,7 +2156,7 @@ LLVM_DUMP_METHOD void SourceManager::dump() const { llvm::raw_ostream &out = llvm::errs(); auto DumpSLocEntry = [&](int ID, const SrcMgr::SLocEntry &Entry, - llvm::Optional<unsigned> NextStart) { + llvm::Optional<SourceLocation::UIntTy> NextStart) { out << "SLocEntry <FileID " << ID << "> " << (Entry.isFile() ? "file" : "expansion") << " <SourceLocation " << Entry.getOffset() << ":"; if (NextStart) @@ -2147,7 +2196,7 @@ LLVM_DUMP_METHOD void SourceManager::dump() const { : LocalSLocEntryTable[ID + 1].getOffset()); } // Dump loaded SLocEntries. - llvm::Optional<unsigned> NextStart; + llvm::Optional<SourceLocation::UIntTy> NextStart; for (unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) { int ID = -(int)Index - 2; if (SLocEntryLoaded[Index]) { |