Skip to content

Commit 82ada73

Browse files
authored
[clang] Optimize EmbedExpr child iterator callback (#155803)
Instead of querying the bitwidth and signeness of the integer literal for every iteration, get the bitwidth directly from the `APIntStorage` and assume the signeness to be `true` since we set the type of the `EmbedExpr` to `Ctx.IntTy` and the type of the integer literal to that of the `EmbedExpr`, so it should always be signed, as long as `ASTContext::IntTy` is signed. Before: ``` $ hyperfine -r 50 -w 3 'bin/clang -c ../../benchmarks/embed.cpp -std=c++20 -fconstexpr-steps=1000000000' Benchmark 1: bin/clang -c ../../benchmarks/embed.cpp -std=c++20 -fconstexpr-steps=1000000000 Time (mean ± σ): 1.796 s ± 0.090 s [User: 0.961 s, System: 0.834 s] Range (min … max): 1.640 s … 2.150 s 50 runs ``` After: ``` $ hyperfine -r 50 -w 3 'bin/clang -c ../../benchmarks/embed.cpp -std=c++20 -fconstexpr-steps=1000000000' Benchmark 1: bin/clang -c ../../benchmarks/embed.cpp -std=c++20 -fconstexpr-steps=1000000000 Time (mean ± σ): 1.700 s ± 0.050 s [User: 0.909 s, System: 0.789 s] Range (min … max): 1.637 s … 1.880 s 50 runs ``` That is roughly .1s less, or whatever, 5% or something. The benchmark is simply: ```c++ constexpr char str[] = { #embed "sqlite3.c" suffix(,0) }; constexpr char str2[] = { #embed "sqlite3.c" suffix(,0) }; constexpr char str3[] = { #embed "sqlite3.c" suffix(,0) }; ``` where `sqlite3.c` contains the sqlite3 amalgamation (roughly 9 million characters).
1 parent 3fb490c commit 82ada73

File tree

4 files changed

+6
-4
lines changed

4 files changed

+6
-4
lines changed

clang/include/clang/AST/APNumericStorage.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ class APNumericStorage {
2828
uint64_t VAL; ///< Used to store the <= 64 bits integer value.
2929
uint64_t *pVal; ///< Used to store the >64 bits integer value.
3030
};
31-
unsigned BitWidth;
3231

3332
bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
3433

3534
APNumericStorage(const APNumericStorage &) = delete;
3635
void operator=(const APNumericStorage &) = delete;
3736

3837
protected:
38+
unsigned BitWidth;
3939
APNumericStorage() : VAL(0), BitWidth(0) {}
4040

4141
llvm::APInt getIntValue() const {
@@ -51,6 +51,7 @@ class APNumericStorage {
5151
class APIntStorage : private APNumericStorage {
5252
public:
5353
llvm::APInt getValue() const { return getIntValue(); }
54+
unsigned getBitWidth() const { return BitWidth; }
5455
void setValue(const ASTContext &C, const llvm::APInt &Val) {
5556
setIntValue(C, Val);
5657
}

clang/include/clang/AST/Expr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5113,9 +5113,9 @@ class EmbedExpr final : public Expr {
51135113
"trying to dereference an invalid iterator");
51145114
IntegerLiteral *N = EExpr->FakeChildNode;
51155115
N->setValue(*EExpr->Ctx,
5116-
llvm::APInt(N->getValue().getBitWidth(),
5116+
llvm::APInt(N->getBitWidth(),
51175117
EExpr->Data->BinaryData->getCodeUnit(CurOffset),
5118-
N->getType()->isSignedIntegerType()));
5118+
/*Signed=*/true));
51195119
// We want to return a reference to the fake child node in the
51205120
// EmbedExpr, not the local variable N.
51215121
return const_cast<typename BaseTy::reference>(EExpr->FakeChildNode);

clang/lib/AST/Expr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2395,6 +2395,7 @@ EmbedExpr::EmbedExpr(const ASTContext &Ctx, SourceLocation Loc,
23952395
setDependence(ExprDependence::None);
23962396
FakeChildNode = IntegerLiteral::Create(
23972397
Ctx, llvm::APInt::getZero(Ctx.getTypeSize(getType())), getType(), Loc);
2398+
assert(getType()->isSignedIntegerType() && "IntTy should be signed");
23982399
}
23992400

24002401
InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc,

clang/lib/Serialization/ASTWriterStmt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
730730
Record.AddSourceLocation(E->getLocation());
731731
Record.AddAPInt(E->getValue());
732732

733-
if (E->getValue().getBitWidth() == 32) {
733+
if (E->getBitWidth() == 32) {
734734
AbbrevToUse = Writer.getIntegerLiteralAbbrev();
735735
}
736736

0 commit comments

Comments
 (0)