forked from OSchip/llvm-project
Amend r138129 (reduction of SLocEntries) which introduced performance regression due
to increased calls to SourceManager::getFileID. (rdar://9992664) Use a slightly different approach that is more efficient both in terms of speed (no extra getFileID calls) and in SLocEntries reduction. Comparing pre-r138129 and this patch we get: For compiling SemaExpr.cpp reduction of SLocEntries by 26%. For the boost enum library: -SLocEntries -34% (note that this was -5% for r138129) -Memory consumption -50% -PCH size -31% Reduced SLocEntries also benefit the hot function SourceManager::getFileID, evident by the reduced "FileID scans". llvm-svn: 138380
This commit is contained in:
parent
e7f7516148
commit
2797df6a24
|
@ -906,6 +906,25 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Return true if both \arg LHS and \arg RHS are in the local source
|
||||||
|
/// location address space or the loaded one. If it's true and
|
||||||
|
/// \arg RelativeOffset is non-null, it will be set to the offset of \arg RHS
|
||||||
|
/// relative to \arg LHS.
|
||||||
|
bool isInSameSLocAddrSpace(SourceLocation LHS, SourceLocation RHS,
|
||||||
|
int *RelativeOffset) const {
|
||||||
|
unsigned LHSOffs = LHS.getOffset(), RHSOffs = RHS.getOffset();
|
||||||
|
bool LHSLoaded = LHSOffs >= CurrentLoadedOffset;
|
||||||
|
bool RHSLoaded = RHSOffs >= CurrentLoadedOffset;
|
||||||
|
|
||||||
|
if (LHSLoaded == RHSLoaded) {
|
||||||
|
if (RelativeOffset)
|
||||||
|
*RelativeOffset = RHSOffs - LHSOffs;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Queries about the code at a SourceLocation.
|
// Queries about the code at a SourceLocation.
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
|
@ -834,10 +834,11 @@ SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
|
||||||
SourceLocation Loc;
|
SourceLocation Loc;
|
||||||
do {
|
do {
|
||||||
Loc = E->getExpansion().getSpellingLoc();
|
Loc = E->getExpansion().getSpellingLoc();
|
||||||
|
Loc = Loc.getFileLocWithOffset(Offset);
|
||||||
|
|
||||||
FID = getFileID(Loc);
|
FID = getFileID(Loc);
|
||||||
E = &getSLocEntry(FID);
|
E = &getSLocEntry(FID);
|
||||||
Offset += Loc.getOffset()-E->getOffset();
|
Offset = Loc.getOffset()-E->getOffset();
|
||||||
} while (!Loc.isFileID());
|
} while (!Loc.isFileID());
|
||||||
|
|
||||||
return std::make_pair(FID, Offset);
|
return std::make_pair(FID, Offset);
|
||||||
|
|
|
@ -669,33 +669,51 @@ static void updateConsecutiveMacroArgTokens(SourceManager &SM,
|
||||||
Token *&begin_tokens,
|
Token *&begin_tokens,
|
||||||
Token * end_tokens) {
|
Token * end_tokens) {
|
||||||
assert(begin_tokens < end_tokens);
|
assert(begin_tokens < end_tokens);
|
||||||
Token &FirstTok = *begin_tokens;
|
|
||||||
FileID SpellFID = SM.getFileID(FirstTok.getLocation());
|
|
||||||
|
|
||||||
// Look for the first token that is not from the same FileID.
|
SourceLocation FirstLoc = begin_tokens->getLocation();
|
||||||
Token *NextFIDTok = begin_tokens + 1;
|
SourceLocation CurLoc = FirstLoc;
|
||||||
for (; NextFIDTok < end_tokens; ++NextFIDTok)
|
|
||||||
if (!SM.isInFileID(NextFIDTok->getLocation(), SpellFID))
|
// Compare the source location offset of tokens and group together tokens that
|
||||||
|
// are close, even if their locations point to different FileIDs. e.g.
|
||||||
|
//
|
||||||
|
// |bar | foo | cake | (3 tokens from 3 consecutive FileIDs)
|
||||||
|
// ^ ^
|
||||||
|
// |bar foo cake| (one SLocEntry chunk for all tokens)
|
||||||
|
//
|
||||||
|
// we can perform this "merge" since the token's spelling location depends
|
||||||
|
// on the relative offset.
|
||||||
|
|
||||||
|
Token *NextTok = begin_tokens + 1;
|
||||||
|
for (; NextTok < end_tokens; ++NextTok) {
|
||||||
|
int RelOffs;
|
||||||
|
if (!SM.isInSameSLocAddrSpace(CurLoc, NextTok->getLocation(), &RelOffs))
|
||||||
|
break; // Token from different local/loaded location.
|
||||||
|
// Check that token is not before the previous token or more than 50
|
||||||
|
// "characters" away.
|
||||||
|
if (RelOffs < 0 || RelOffs > 50)
|
||||||
break;
|
break;
|
||||||
|
CurLoc = NextTok->getLocation();
|
||||||
|
}
|
||||||
|
|
||||||
// For the consecutive tokens, find the length of the SLocEntry to contain
|
// For the consecutive tokens, find the length of the SLocEntry to contain
|
||||||
// all of them.
|
// all of them.
|
||||||
unsigned FirstOffs, LastOffs;
|
Token &LastConsecutiveTok = *(NextTok-1);
|
||||||
SM.isInFileID(FirstTok.getLocation(), SpellFID, &FirstOffs);
|
int LastRelOffs;
|
||||||
SM.isInFileID((NextFIDTok-1)->getLocation(), SpellFID, &LastOffs);
|
SM.isInSameSLocAddrSpace(FirstLoc, LastConsecutiveTok.getLocation(),
|
||||||
unsigned FullLength = (LastOffs - FirstOffs) + (NextFIDTok-1)->getLength();
|
&LastRelOffs);
|
||||||
|
unsigned FullLength = LastRelOffs + LastConsecutiveTok.getLength();
|
||||||
|
|
||||||
// Create a macro expansion SLocEntry that will "contain" all of the tokens.
|
// Create a macro expansion SLocEntry that will "contain" all of the tokens.
|
||||||
SourceLocation Expansion =
|
SourceLocation Expansion =
|
||||||
SM.createMacroArgExpansionLoc(FirstTok.getLocation(), InstLoc,FullLength);
|
SM.createMacroArgExpansionLoc(FirstLoc, InstLoc,FullLength);
|
||||||
|
|
||||||
// Change the location of the tokens from the spelling location to the new
|
// Change the location of the tokens from the spelling location to the new
|
||||||
// expanded location.
|
// expanded location.
|
||||||
for (; begin_tokens < NextFIDTok; ++begin_tokens) {
|
for (; begin_tokens < NextTok; ++begin_tokens) {
|
||||||
Token &Tok = *begin_tokens;
|
Token &Tok = *begin_tokens;
|
||||||
unsigned Offs;
|
int RelOffs;
|
||||||
SM.isInFileID(Tok.getLocation(), SpellFID, &Offs);
|
SM.isInSameSLocAddrSpace(FirstLoc, Tok.getLocation(), &RelOffs);
|
||||||
Tok.setLocation(Expansion.getFileLocWithOffset(Offs - FirstOffs));
|
Tok.setLocation(Expansion.getFileLocWithOffset(RelOffs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,9 +728,19 @@ void TokenLexer::updateLocForMacroArgTokens(SourceLocation ArgIdSpellLoc,
|
||||||
Token *end_tokens) {
|
Token *end_tokens) {
|
||||||
SourceManager &SM = PP.getSourceManager();
|
SourceManager &SM = PP.getSourceManager();
|
||||||
|
|
||||||
SourceLocation curInst =
|
SourceLocation InstLoc =
|
||||||
getExpansionLocForMacroDefLoc(ArgIdSpellLoc);
|
getExpansionLocForMacroDefLoc(ArgIdSpellLoc);
|
||||||
|
|
||||||
while (begin_tokens < end_tokens)
|
while (begin_tokens < end_tokens) {
|
||||||
updateConsecutiveMacroArgTokens(SM, curInst, begin_tokens, end_tokens);
|
// If there's only one token just create a SLocEntry for it.
|
||||||
|
if (end_tokens - begin_tokens == 1) {
|
||||||
|
Token &Tok = *begin_tokens;
|
||||||
|
Tok.setLocation(SM.createMacroArgExpansionLoc(Tok.getLocation(),
|
||||||
|
InstLoc,
|
||||||
|
Tok.getLength()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateConsecutiveMacroArgTokens(SM, InstLoc, begin_tokens, end_tokens);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue