Introduce SourceManager::getDecomposedIncludedLoc, that returns the "included/expanded in" decomposed location of the given FileID.

The main benefit is to speed-up SourceManager::isBeforeInTranslationUnit which is common to query
the included/expanded location of the same FileID multiple times.

llvm-svn: 179435
This commit is contained in:
Argyrios Kyrtzidis 2013-04-13 01:03:57 +00:00
parent 2f08822f9d
commit 37613a9c6f
2 changed files with 41 additions and 11 deletions

View File

@ -646,6 +646,13 @@ class SourceManager : public RefCountedBase<SourceManager> {
// Statistics for -print-stats.
mutable unsigned NumLinearScans, NumBinaryProbes;
/// \brief Associates a FileID with its "included/expanded in" decomposed
/// location.
///
/// Used to cache results from and speed-up \c getDecomposedIncludedLoc
/// function.
mutable llvm::DenseMap<FileID, std::pair<FileID, unsigned> > IncludedLocMap;
/// The key value into the IsBeforeInTUCache table.
typedef std::pair<FileID, FileID> IsBeforeInTUCacheKey;
@ -1127,6 +1134,10 @@ public:
return getDecomposedSpellingLocSlowCase(E, Offset);
}
/// \brief Returns the "included/expanded in" decomposed location of the given
/// FileID.
std::pair<FileID, unsigned> getDecomposedIncludedLoc(FileID FID) const;
/// \brief Returns the offset from the start of the file that the
/// specified SourceLocation represents.
///

View File

@ -1848,23 +1848,42 @@ SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const {
return Loc;
}
std::pair<FileID, unsigned>
SourceManager::getDecomposedIncludedLoc(FileID FID) const {
// Uses IncludedLocMap to retrieve/cache the decomposed loc.
typedef std::pair<FileID, unsigned> DecompTy;
typedef llvm::DenseMap<FileID, DecompTy> MapTy;
std::pair<MapTy::iterator, bool>
InsertOp = IncludedLocMap.insert(std::make_pair(FID, DecompTy()));
DecompTy &DecompLoc = InsertOp.first->second;
if (!InsertOp.second)
return DecompLoc; // already in map.
SourceLocation UpperLoc;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
if (Entry.isExpansion())
UpperLoc = Entry.getExpansion().getExpansionLocStart();
else
UpperLoc = Entry.getFile().getIncludeLoc();
if (UpperLoc.isValid())
DecompLoc = getDecomposedLoc(UpperLoc);
return DecompLoc;
}
/// Given a decomposed source location, move it up the include/expansion stack
/// to the parent source location. If this is possible, return the decomposed
/// version of the parent in Loc and return false. If Loc is the top-level
/// entry, return true and don't modify it.
static bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc,
const SourceManager &SM) {
SourceLocation UpperLoc;
const SrcMgr::SLocEntry &Entry = SM.getSLocEntry(Loc.first);
if (Entry.isExpansion())
UpperLoc = Entry.getExpansion().getExpansionLocStart();
else
UpperLoc = Entry.getFile().getIncludeLoc();
if (UpperLoc.isInvalid())
std::pair<FileID, unsigned> UpperLoc = SM.getDecomposedIncludedLoc(Loc.first);
if (UpperLoc.first.isInvalid())
return true; // We reached the top.
Loc = SM.getDecomposedLoc(UpperLoc);
Loc = UpperLoc;
return false;
}
@ -1929,7 +1948,7 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
// of the other looking for a match.
// We use a map from FileID to Offset to store the chain. Easier than writing
// a custom set hash info that only depends on the first part of a pair.
typedef llvm::DenseMap<FileID, unsigned> LocSet;
typedef llvm::SmallDenseMap<FileID, unsigned, 16> LocSet;
LocSet LChain;
do {
LChain.insert(LOffs);