diff options
author | Chris Lattner <sabre@nondot.org> | 2009-08-11 17:49:14 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-08-11 17:49:14 +0000 |
commit | 1d96ccc69a265435cc1fb0eafe208857290e7dd2 (patch) | |
tree | 1d45ab0258b12cf1fd64844f9041a1c9368f0e09 | |
parent | b27a41b44092c0a6e439203586cc944187de3388 (diff) | |
download | external_llvm-1d96ccc69a265435cc1fb0eafe208857290e7dd2.zip external_llvm-1d96ccc69a265435cc1fb0eafe208857290e7dd2.tar.gz external_llvm-1d96ccc69a265435cc1fb0eafe208857290e7dd2.tar.bz2 |
add a trivial line # cache to SourceMgr to make repeated queries to
FindLineNumber much faster when in sequence.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78693 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Support/SourceMgr.h | 6 | ||||
-rw-r--r-- | lib/Support/SourceMgr.cpp | 40 |
2 files changed, 45 insertions, 1 deletions
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index 37cdc0a..5b6f56b 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -65,10 +65,14 @@ class SourceMgr { // include files in. std::vector<std::string> IncludeDirectories; + /// LineNoCache - This is a cache for line number queries, its implementation + /// is really private to SourceMgr.cpp. + mutable void *LineNoCache; + SourceMgr(const SourceMgr&); // DO NOT IMPLEMENT void operator=(const SourceMgr&); // DO NOT IMPLEMENT public: - SourceMgr() {} + SourceMgr() : LineNoCache(0) {} ~SourceMgr(); void setIncludeDirs(const std::vector<std::string> &Dirs) { diff --git a/lib/Support/SourceMgr.cpp b/lib/Support/SourceMgr.cpp index 6b0d55c..4b93f7f 100644 --- a/lib/Support/SourceMgr.cpp +++ b/lib/Support/SourceMgr.cpp @@ -18,7 +18,24 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; +namespace { + struct LineNoCacheTy { + int LastQueryBufferID; + const char *LastQuery; + unsigned LineNoOfQuery; + }; +} + +static LineNoCacheTy *getCache(void *Ptr) { + return (LineNoCacheTy*)Ptr; +} + + SourceMgr::~SourceMgr() { + // Delete the line # cache if allocated. + if (LineNoCacheTy *Cache = getCache(LineNoCache)) + delete Cache; + while (!Buffers.empty()) { delete Buffers.back().Buffer; Buffers.pop_back(); @@ -71,8 +88,31 @@ unsigned SourceMgr::FindLineNumber(SMLoc Loc, int BufferID) const { const char *Ptr = Buff->getBufferStart(); + // If we have a line number cache, and if the query is to a later point in the + // same file, start searching from the last query location. This optimizes + // for the case when multiple diagnostics come out of one file in order. + if (LineNoCacheTy *Cache = getCache(LineNoCache)) + if (Cache->LastQueryBufferID == BufferID && + Cache->LastQuery <= Loc.getPointer()) { + Ptr = Cache->LastQuery; + LineNo = Cache->LineNoOfQuery; + } + + // Scan for the location being queried, keeping track of the number of lines + // we see. for (; SMLoc::getFromPointer(Ptr) != Loc; ++Ptr) if (*Ptr == '\n') ++LineNo; + + + // Allocate the line number cache if it doesn't exist. + if (LineNoCache == 0) + LineNoCache = new LineNoCacheTy(); + + // Update the line # cache. + LineNoCacheTy &Cache = *getCache(LineNoCache); + Cache.LastQueryBufferID = BufferID; + Cache.LastQuery = Ptr; + Cache.LineNoOfQuery = LineNo; return LineNo; } |