Skip to content

Commit 1179116

Browse files
ThePhDh-vetinari
authored andcommitted
⚡ [Lex] Better reservations for improved performance/memory usage.
1 parent 07795f2 commit 1179116

File tree

2 files changed

+93
-21
lines changed

2 files changed

+93
-21
lines changed

clang/include/clang/Lex/Preprocessor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2741,14 +2741,14 @@ class Preprocessor {
27412741
const FileEntry *LookupFromFile = nullptr);
27422742
void HandleEmbedDirectiveNaive(SourceLocation HashLoc,
27432743
SourceLocation FilenameTok,
2744-
LexEmbedParametersResult &Params,
2744+
const LexEmbedParametersResult &Params,
27452745
StringRef BinaryContents,
27462746
const size_t TargetCharWidth);
27472747
void HandleEmbedDirectiveBuiltin(SourceLocation HashLoc,
27482748
const Token &FilenameTok,
27492749
StringRef ResolvedFilename,
27502750
StringRef SearchPath, StringRef RelativePath,
2751-
LexEmbedParametersResult &Params,
2751+
const LexEmbedParametersResult &Params,
27522752
StringRef BinaryContents,
27532753
const size_t TargetCharWidth);
27542754

clang/lib/Lex/PPDirectives.cpp

Lines changed: 91 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3826,11 +3826,59 @@ inline constexpr const char *IntegerLiterals[] = {
38263826
"242", "243", "244", "245", "246", "247", "248", "249", "250", "251", "252",
38273827
"253", "254", "255"};
38283828

3829-
void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
3830-
SourceLocation FilenameLoc,
3831-
LexEmbedParametersResult &Params,
3832-
StringRef BinaryContents,
3833-
const size_t TargetCharWidth) {
3829+
static size_t
3830+
ComputeNaiveReserveSize(const Preprocessor::LexEmbedParametersResult &Params,
3831+
StringRef TypeName, StringRef BinaryContents,
3832+
SmallVectorImpl<char> &TokSpellingBuffer) {
3833+
size_t ReserveSize = 0;
3834+
if (BinaryContents.empty()) {
3835+
if (Params.MaybeIfEmptyParam) {
3836+
for (const auto &Tok : Params.MaybeIfEmptyParam->Tokens) {
3837+
const size_t TokLen = Tok.getLength();
3838+
if (TokLen > TokSpellingBuffer.size()) {
3839+
TokSpellingBuffer.resize(TokLen);
3840+
}
3841+
ReserveSize += TokLen;
3842+
}
3843+
}
3844+
} else {
3845+
if (Params.MaybePrefixParam) {
3846+
for (const auto &Tok : Params.MaybePrefixParam->Tokens) {
3847+
const size_t TokLen = Tok.getLength();
3848+
if (TokLen > TokSpellingBuffer.size()) {
3849+
TokSpellingBuffer.resize(TokLen);
3850+
}
3851+
ReserveSize += TokLen;
3852+
}
3853+
}
3854+
for (const auto &Byte : BinaryContents) {
3855+
ReserveSize += 3 + TypeName.size(); // ((type-name)
3856+
if (Byte > 99) {
3857+
ReserveSize += 3; // ###
3858+
} else if (Byte > 9) {
3859+
ReserveSize += 2; // ##
3860+
} else {
3861+
ReserveSize += 1; // #
3862+
}
3863+
ReserveSize += 2; // ),
3864+
}
3865+
if (Params.MaybePrefixParam) {
3866+
for (const auto &Tok : Params.MaybePrefixParam->Tokens) {
3867+
const size_t TokLen = Tok.getLength();
3868+
if (TokLen > TokSpellingBuffer.size()) {
3869+
TokSpellingBuffer.resize(TokLen);
3870+
}
3871+
ReserveSize += TokLen;
3872+
}
3873+
}
3874+
}
3875+
return ReserveSize;
3876+
}
3877+
3878+
void Preprocessor::HandleEmbedDirectiveNaive(
3879+
SourceLocation HashLoc, SourceLocation FilenameLoc,
3880+
const LexEmbedParametersResult &Params, StringRef BinaryContents,
3881+
const size_t TargetCharWidth) {
38343882
// Load up a new embed buffer for this file and set of parameters in
38353883
// particular.
38363884
EmbedBuffers.push_back("");
@@ -3841,30 +3889,37 @@ void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
38413889
return PrefixNumber.concat(">");
38423890
}(EmbedBufferNumberVal);
38433891
std::string &TargetEmbedBuffer = EmbedBuffers.back();
3892+
const size_t TotalSize = BinaryContents.size();
3893+
// In the future, this might change/improve.
3894+
const StringRef TypeName = "unsigned char";
38443895

3845-
// In the future, this might improve.
3846-
const StringRef SmallestType = "unsigned char";
3896+
SmallVector<char, 32> TokSpellingBuffer(32, 0);
3897+
const size_t ReserveSize = ComputeNaiveReserveSize(
3898+
Params, TypeName, BinaryContents, TokSpellingBuffer);
3899+
TargetEmbedBuffer.reserve(ReserveSize);
38473900

38483901
// Generate the look-alike source file
38493902
if (BinaryContents.empty()) {
38503903
if (Params.MaybeIfEmptyParam) {
3851-
PPEmbedParameterIfEmpty &EmptyParam = *Params.MaybeIfEmptyParam;
3904+
const PPEmbedParameterIfEmpty &EmptyParam = *Params.MaybeIfEmptyParam;
38523905
for (const auto &Tok : EmptyParam.Tokens) {
3853-
TargetEmbedBuffer.append(this->getSpelling(Tok));
3906+
StringRef Spelling = this->getSpelling(Tok, TokSpellingBuffer);
3907+
TargetEmbedBuffer.append(Spelling.data(), Spelling.size());
38543908
}
38553909
}
38563910
} else {
38573911
if (Params.MaybePrefixParam) {
3858-
PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam;
3912+
const PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam;
38593913
for (const auto &Tok : PrefixParam.Tokens) {
3860-
TargetEmbedBuffer.append(this->getSpelling(Tok));
3914+
StringRef Spelling = this->getSpelling(Tok, TokSpellingBuffer);
3915+
TargetEmbedBuffer.append(Spelling.data(), Spelling.size());
38613916
}
38623917
}
38633918
for (size_t I = 0; I < BinaryContents.size(); ++I) {
38643919
unsigned char ByteValue = BinaryContents[I];
38653920
StringRef ByteRepresentation = IntegerLiterals[ByteValue];
38663921
TargetEmbedBuffer.append(2, '(');
3867-
TargetEmbedBuffer.append(SmallestType.data(), SmallestType.size());
3922+
TargetEmbedBuffer.append(TypeName.data(), TypeName.size());
38683923
TargetEmbedBuffer.append(1, ')');
38693924
TargetEmbedBuffer.append(ByteRepresentation.data(),
38703925
ByteRepresentation.size());
@@ -3875,9 +3930,10 @@ void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
38753930
}
38763931
}
38773932
if (Params.MaybeSuffixParam) {
3878-
PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam;
3933+
const PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam;
38793934
for (const auto &Tok : SuffixParam.Tokens) {
3880-
TargetEmbedBuffer.append(this->getSpelling(Tok));
3935+
StringRef Spelling = this->getSpelling(Tok, TokSpellingBuffer);
3936+
TargetEmbedBuffer.append(Spelling.data(), Spelling.size());
38813937
}
38823938
}
38833939
}
@@ -3898,7 +3954,7 @@ void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
38983954
static bool TokenListIsCharacterArray(Preprocessor &PP,
38993955
const size_t TargetCharWidth,
39003956
bool IsPrefix,
3901-
SmallVectorImpl<Token> &Tokens,
3957+
const SmallVectorImpl<Token> &Tokens,
39023958
llvm::SmallVectorImpl<char> &Output) {
39033959
const bool IsSuffix = !IsPrefix;
39043960
size_t MaxValue =
@@ -4004,7 +4060,7 @@ static void TripleEncodeBase64(StringRef Bytes0, StringRef Bytes1,
40044060
void Preprocessor::HandleEmbedDirectiveBuiltin(
40054061
SourceLocation HashLoc, const Token &FilenameTok,
40064062
StringRef ResolvedFilename, StringRef SearchPath, StringRef RelativePath,
4007-
LexEmbedParametersResult &Params, StringRef BinaryContents,
4063+
const LexEmbedParametersResult &Params, StringRef BinaryContents,
40084064
const size_t TargetCharWidth) {
40094065
// if it's empty, just process it like a normal expanded token stream
40104066
if (BinaryContents.empty()) {
@@ -4017,7 +4073,7 @@ void Preprocessor::HandleEmbedDirectiveBuiltin(
40174073
if (Params.MaybePrefixParam) {
40184074
// If we ahve a prefix, validate that it's a good fit for direct data
40194075
// embedded (and prepare to prepend it)
4020-
PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam;
4076+
const PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam;
40214077
if (!TokenListIsCharacterArray(*this, TargetCharWidth, true,
40224078
PrefixParam.Tokens, BinaryPrefix)) {
40234079
HandleEmbedDirectiveNaive(HashLoc, FilenameTok.getLocation(), Params,
@@ -4028,7 +4084,7 @@ void Preprocessor::HandleEmbedDirectiveBuiltin(
40284084
if (Params.MaybeSuffixParam) {
40294085
// If we ahve a prefix, validate that it's a good fit for direct data
40304086
// embedding (and prepare to append it)
4031-
PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam;
4087+
const PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam;
40324088
if (!TokenListIsCharacterArray(*this, TargetCharWidth, false,
40334089
SuffixParam.Tokens, BinarySuffix)) {
40344090
HandleEmbedDirectiveNaive(HashLoc, FilenameTok.getLocation(), Params,
@@ -4047,9 +4103,25 @@ void Preprocessor::HandleEmbedDirectiveBuiltin(
40474103
return PrefixNumber.concat(">");
40484104
}(EmbedBufferNumberVal);
40494105
std::string &TargetEmbedBuffer = EmbedBuffers.back();
4106+
StringRef TypeName = "unsigned char";
4107+
const size_t TotalSize =
4108+
BinaryPrefix.size() + BinaryContents.size() + BinarySuffix.size();
4109+
const size_t ReserveSize = // add up for necessary size:
4110+
19 // __builtin_pp_embed(
4111+
+ TypeName.size() // type-name
4112+
+ 2 // ,"
4113+
+ ResolvedFilename.size() // file-name
4114+
+ 3 // ","
4115+
+ (((TotalSize + 2) / 3) * 4) // base64-string
4116+
+ 2 // ");
4117+
;
4118+
// Reserve appropriate size
4119+
TargetEmbedBuffer.reserve(ReserveSize);
40504120

40514121
// Generate the look-alike source file
4052-
TargetEmbedBuffer.append("__builtin_pp_embed(unsigned char,\"");
4122+
TargetEmbedBuffer.append("__builtin_pp_embed(");
4123+
TargetEmbedBuffer.append(TypeName.data(), TypeName.size());
4124+
TargetEmbedBuffer.append(",\"");
40534125
TargetEmbedBuffer.append(ResolvedFilename.data(), ResolvedFilename.size());
40544126
TargetEmbedBuffer.append("\",\"");
40554127
// include the prefix(...) and suffix(...) binary data in the total contents

0 commit comments

Comments
 (0)