[cfe-commits] r38564 - /cfe/cfe/trunk/Lex/Preprocessor.cpp
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:22:42 PDT 2007
Author: sabre
Date: Wed Jul 11 11:22:42 2007
New Revision: 38564
URL: http://llvm.org/viewvc/llvm-project?rev=38564&view=rev
Log:
increase the performance of skipping (#if 0) by optimizing lookup of directive names.
Modified:
cfe/cfe/trunk/Lex/Preprocessor.cpp
Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=38564&r1=38563&r2=38564&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:22:42 2007
@@ -677,25 +677,46 @@
CurLexer->ParsingPreprocessorDirective = false;
continue;
}
-
+
// If the first letter isn't i or e, it isn't intesting to us. We know that
// this is safe in the face of spelling differences, because there is no way
// to spell an i/e in a strange way that is another letter. Skipping this
- // allows us to avoid computing the spelling for #define/#undef and other
- // common directives.
- // FIXME: This should use a bit in the identifier information!
- char FirstChar = SourceMgr.getCharacterData(Tok.getLocation())[0];
+ // allows us to avoid looking up the identifier info for #define/#undef and
+ // other common directives.
+ const char *RawCharData = SourceMgr.getCharacterData(Tok.getLocation());
+ char FirstChar = RawCharData[0];
if (FirstChar >= 'a' && FirstChar <= 'z' &&
FirstChar != 'i' && FirstChar != 'e') {
CurLexer->ParsingPreprocessorDirective = false;
continue;
}
- // Strip out trigraphs and embedded newlines.
- std::string Directive = getSpelling(Tok);
- FirstChar = Directive[0];
+ // Get the identifier name without trigraphs or embedded newlines. Note
+ // that we can't use Tok.getIdentifierInfo() because its lookup is disabled
+ // when skipping.
+ // TODO: could do this with zero copies in the no-clean case by using
+ // strncmp below.
+ char Directive[20];
+ unsigned IdLen;
+ if (!Tok.needsCleaning() && Tok.getLength() < 20) {
+ IdLen = Tok.getLength();
+ memcpy(Directive, RawCharData, IdLen);
+ Directive[IdLen] = 0;
+ } else {
+ std::string DirectiveStr = getSpelling(Tok);
+ IdLen = DirectiveStr.size();
+ if (IdLen >= 20) {
+ CurLexer->ParsingPreprocessorDirective = false;
+ continue;
+ }
+ memcpy(Directive, &DirectiveStr[0], IdLen);
+ Directive[IdLen] = 0;
+ }
+
if (FirstChar == 'i' && Directive[1] == 'f') {
- if (Directive == "if" || Directive == "ifdef" || Directive == "ifndef") {
+ if ((IdLen == 2) || // "if"
+ (IdLen == 5 && !strcmp(Directive+2, "def")) || // "ifdef"
+ (IdLen == 6 && !strcmp(Directive+2, "ndef"))) { // "ifndef"
// We know the entire #if/#ifdef/#ifndef block will be skipped, don't
// bother parsing the condition.
DiscardUntilEndOfDirective();
@@ -704,7 +725,7 @@
/*fnddelse*/false);
}
} else if (FirstChar == 'e') {
- if (Directive == "endif") {
+ if (IdLen == 5 && !strcmp(Directive+1, "ndif")) { // "endif"
CheckEndOfDirective("#endif");
PPConditionalInfo CondInfo;
CondInfo.WasSkipping = true; // Silence bogus warning.
@@ -714,7 +735,7 @@
// If we popped the outermost skipping block, we're done skipping!
if (!CondInfo.WasSkipping)
break;
- } else if (Directive == "else") {
+ } else if (IdLen == 4 && !strcmp(Directive+1, "lse")) { // "else".
// #else directive in a skipping conditional. If not in some other
// skipping conditional, and if #else hasn't already been seen, enter it
// as a non-skipping conditional.
@@ -733,7 +754,7 @@
CondInfo.FoundNonSkip = true;
break;
}
- } else if (Directive == "elif") {
+ } else if (IdLen == 4 && !strcmp(Directive+1, "lif")) { // "elif".
PPConditionalInfo &CondInfo = CurLexer->peekConditionalLevel();
bool ShouldEnter;
More information about the cfe-commits
mailing list