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. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits