[clang] c669a1e - [clang][NFC] Pack LambdaExpr
Bruno Ricci via cfe-commits
cfe-commits at lists.llvm.org
Sat Jun 13 07:08:21 PDT 2020
Author: Bruno Ricci
Date: 2020-06-13T14:31:13+01:00
New Revision: c669a1ed6386d57a75a602b53266466dae1e1d84
URL: https://github.com/llvm/llvm-project/commit/c669a1ed6386d57a75a602b53266466dae1e1d84
DIFF: https://github.com/llvm/llvm-project/commit/c669a1ed6386d57a75a602b53266466dae1e1d84.diff
LOG: [clang][NFC] Pack LambdaExpr
This saves sizeof(void *) bytes per LambdaExpr.
Review-after-commit since this is a straightforward change similar
to the work done on other nodes. NFC.
Added:
Modified:
clang/include/clang/AST/ExprCXX.h
clang/include/clang/AST/Stmt.h
clang/lib/AST/ExprCXX.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 82036a295002..822025a7503f 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -1829,26 +1829,14 @@ Stmt **CXXConstructExpr::getTrailingArgs() {
/// and which can never occur implicitly.
class LambdaExpr final : public Expr,
private llvm::TrailingObjects<LambdaExpr, Stmt *> {
+ // LambdaExpr has some data stored in LambdaExprBits.
+
/// The source range that covers the lambda introducer ([...]).
SourceRange IntroducerRange;
/// The source location of this lambda's capture-default ('=' or '&').
SourceLocation CaptureDefaultLoc;
- /// The number of captures.
- unsigned NumCaptures : 16;
-
- /// The default capture kind, which is a value of type
- /// LambdaCaptureDefault.
- unsigned CaptureDefault : 2;
-
- /// Whether this lambda had an explicit parameter list vs. an
- /// implicit (and empty) parameter list.
- unsigned ExplicitParams : 1;
-
- /// Whether this lambda had the result type explicitly specified.
- unsigned ExplicitResultType : 1;
-
/// The location of the closing brace ('}') that completes
/// the lambda.
///
@@ -1867,15 +1855,9 @@ class LambdaExpr final : public Expr,
SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack);
/// Construct an empty lambda expression.
- LambdaExpr(EmptyShell Empty, unsigned NumCaptures)
- : Expr(LambdaExprClass, Empty), NumCaptures(NumCaptures),
- CaptureDefault(LCD_None), ExplicitParams(false),
- ExplicitResultType(false) {
- getStoredStmts()[NumCaptures] = nullptr;
- }
+ LambdaExpr(EmptyShell Empty, unsigned NumCaptures);
Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
-
Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
public:
@@ -1898,13 +1880,11 @@ class LambdaExpr final : public Expr,
/// Determine the default capture kind for this lambda.
LambdaCaptureDefault getCaptureDefault() const {
- return static_cast<LambdaCaptureDefault>(CaptureDefault);
+ return static_cast<LambdaCaptureDefault>(LambdaExprBits.CaptureDefault);
}
/// Retrieve the location of this lambda's capture-default, if any.
- SourceLocation getCaptureDefaultLoc() const {
- return CaptureDefaultLoc;
- }
+ SourceLocation getCaptureDefaultLoc() const { return CaptureDefaultLoc; }
/// Determine whether one of this lambda's captures is an init-capture.
bool isInitCapture(const LambdaCapture *Capture) const;
@@ -1927,7 +1907,7 @@ class LambdaExpr final : public Expr,
capture_iterator capture_end() const;
/// Determine the number of captures in this lambda.
- unsigned capture_size() const { return NumCaptures; }
+ unsigned capture_size() const { return LambdaExprBits.NumCaptures; }
/// Retrieve this lambda's explicit captures.
capture_range explicit_captures() const;
@@ -1984,13 +1964,13 @@ class LambdaExpr final : public Expr,
/// Retrieve the iterator pointing one past the last
/// initialization argument for this lambda expression.
capture_init_iterator capture_init_end() {
- return capture_init_begin() + NumCaptures;
+ return capture_init_begin() + capture_size();
}
/// Retrieve the iterator pointing one past the last
/// initialization argument for this lambda expression.
const_capture_init_iterator capture_init_end() const {
- return capture_init_begin() + NumCaptures;
+ return capture_init_begin() + capture_size();
}
/// Retrieve the source range covering the lambda introducer,
@@ -2033,10 +2013,12 @@ class LambdaExpr final : public Expr,
/// Determine whether this lambda has an explicit parameter
/// list vs. an implicit (empty) parameter list.
- bool hasExplicitParameters() const { return ExplicitParams; }
+ bool hasExplicitParameters() const { return LambdaExprBits.ExplicitParams; }
/// Whether this lambda had its result type explicitly specified.
- bool hasExplicitResultType() const { return ExplicitResultType; }
+ bool hasExplicitResultType() const {
+ return LambdaExprBits.ExplicitResultType;
+ }
static bool classof(const Stmt *T) {
return T->getStmtClass() == LambdaExprClass;
@@ -2050,12 +2032,12 @@ class LambdaExpr final : public Expr,
child_range children() {
// Includes initialization exprs plus body stmt
- return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
+ return child_range(getStoredStmts(), getStoredStmts() + capture_size() + 1);
}
const_child_range children() const {
return const_child_range(getStoredStmts(),
- getStoredStmts() + NumCaptures + 1);
+ getStoredStmts() + capture_size() + 1);
}
};
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index fdcc213a6aed..5c5c20b3676b 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -927,6 +927,28 @@ class alignas(void *) Stmt {
SourceLocation NameLoc;
};
+ class LambdaExprBitfields {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend class LambdaExpr;
+
+ unsigned : NumExprBits;
+
+ /// The default capture kind, which is a value of type
+ /// LambdaCaptureDefault.
+ unsigned CaptureDefault : 2;
+
+ /// Whether this lambda had an explicit parameter list vs. an
+ /// implicit (and empty) parameter list.
+ unsigned ExplicitParams : 1;
+
+ /// Whether this lambda had the result type explicitly specified.
+ unsigned ExplicitResultType : 1;
+
+ /// The number of captures.
+ unsigned NumCaptures : 16;
+ };
+
class RequiresExprBitfields {
friend class ASTStmtReader;
friend class ASTStmtWriter;
@@ -1039,6 +1061,7 @@ class alignas(void *) Stmt {
UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
CXXNoexceptExprBitfields CXXNoexceptExprBits;
SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;
+ LambdaExprBitfields LambdaExprBits;
RequiresExprBitfields RequiresExprBits;
// C++ Coroutines TS expressions
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 9d4df28c7473..8588e9b47d65 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1093,13 +1093,16 @@ LambdaExpr::LambdaExpr(QualType T, SourceRange IntroducerRange,
bool ContainsUnexpandedParameterPack)
: Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary),
IntroducerRange(IntroducerRange), CaptureDefaultLoc(CaptureDefaultLoc),
- NumCaptures(CaptureInits.size()), CaptureDefault(CaptureDefault),
- ExplicitParams(ExplicitParams), ExplicitResultType(ExplicitResultType),
ClosingBrace(ClosingBrace) {
+ LambdaExprBits.NumCaptures = CaptureInits.size();
+ LambdaExprBits.CaptureDefault = CaptureDefault;
+ LambdaExprBits.ExplicitParams = ExplicitParams;
+ LambdaExprBits.ExplicitResultType = ExplicitResultType;
+
CXXRecordDecl *Class = getLambdaClass();
(void)Class;
- assert(NumCaptures == Class->capture_size() && "Wrong number of captures");
- assert(CaptureDefault == Class->getLambdaCaptureDefault());
+ assert(capture_size() == Class->capture_size() && "Wrong number of captures");
+ assert(getCaptureDefault() == Class->getLambdaCaptureDefault());
// Copy initialization expressions for the non-static data members.
Stmt **Stored = getStoredStmts();
@@ -1112,6 +1115,20 @@ LambdaExpr::LambdaExpr(QualType T, SourceRange IntroducerRange,
setDependence(computeDependence(this, ContainsUnexpandedParameterPack));
}
+LambdaExpr::LambdaExpr(EmptyShell Empty, unsigned NumCaptures)
+ : Expr(LambdaExprClass, Empty) {
+ LambdaExprBits.NumCaptures = NumCaptures;
+
+ // FIXME: There is no need to do this since these members should be
+ // initialized during deserialization.
+ LambdaExprBits.CaptureDefault = LCD_None;
+ LambdaExprBits.ExplicitParams = false;
+ LambdaExprBits.ExplicitResultType = false;
+
+ // FIXME: Remove once the bug in LambdaExpr::getBody is fixed.
+ getStoredStmts()[capture_size()] = nullptr;
+}
+
LambdaExpr *LambdaExpr::Create(const ASTContext &Context, CXXRecordDecl *Class,
SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
@@ -1149,7 +1166,7 @@ LambdaExpr::capture_iterator LambdaExpr::capture_begin() const {
}
LambdaExpr::capture_iterator LambdaExpr::capture_end() const {
- return capture_begin() + NumCaptures;
+ return capture_begin() + capture_size();
}
LambdaExpr::capture_range LambdaExpr::captures() const {
@@ -1210,16 +1227,14 @@ CompoundStmt *LambdaExpr::getBody() const {
// FIXME: this mutation in getBody is bogus. It should be
// initialized in ASTStmtReader::VisitLambdaExpr, but for reasons I
// don't understand, that doesn't work.
- if (!getStoredStmts()[NumCaptures])
- *const_cast<Stmt **>(&getStoredStmts()[NumCaptures]) =
+ if (!getStoredStmts()[capture_size()])
+ *const_cast<Stmt **>(&getStoredStmts()[capture_size()]) =
getCallOperator()->getBody();
- return static_cast<CompoundStmt *>(getStoredStmts()[NumCaptures]);
+ return static_cast<CompoundStmt *>(getStoredStmts()[capture_size()]);
}
-bool LambdaExpr::isMutable() const {
- return !getCallOperator()->isConst();
-}
+bool LambdaExpr::isMutable() const { return !getCallOperator()->isConst(); }
ExprWithCleanups::ExprWithCleanups(Expr *subexpr,
bool CleanupsHaveSideEffects,
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 86895c319ee8..e38c309da339 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1687,12 +1687,13 @@ void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) {
VisitExpr(E);
unsigned NumCaptures = Record.readInt();
- assert(NumCaptures == E->NumCaptures);(void)NumCaptures;
+ (void)NumCaptures;
+ assert(NumCaptures == E->LambdaExprBits.NumCaptures);
E->IntroducerRange = readSourceRange();
- E->CaptureDefault = static_cast<LambdaCaptureDefault>(Record.readInt());
+ E->LambdaExprBits.CaptureDefault = Record.readInt();
E->CaptureDefaultLoc = readSourceLocation();
- E->ExplicitParams = Record.readInt();
- E->ExplicitResultType = Record.readInt();
+ E->LambdaExprBits.ExplicitParams = Record.readInt();
+ E->LambdaExprBits.ExplicitResultType = Record.readInt();
E->ClosingBrace = readSourceLocation();
// Read capture initializers.
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 45cd54f8dc9e..11941329ad2a 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1589,12 +1589,12 @@ void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
VisitExpr(E);
- Record.push_back(E->NumCaptures);
+ Record.push_back(E->LambdaExprBits.NumCaptures);
Record.AddSourceRange(E->IntroducerRange);
- Record.push_back(E->CaptureDefault); // FIXME: stable encoding
+ Record.push_back(E->LambdaExprBits.CaptureDefault); // FIXME: stable encoding
Record.AddSourceLocation(E->CaptureDefaultLoc);
- Record.push_back(E->ExplicitParams);
- Record.push_back(E->ExplicitResultType);
+ Record.push_back(E->LambdaExprBits.ExplicitParams);
+ Record.push_back(E->LambdaExprBits.ExplicitResultType);
Record.AddSourceLocation(E->ClosingBrace);
// Add capture initializers.
More information about the cfe-commits
mailing list