https://github.com/hokein created https://github.com/llvm/llvm-project/pull/142585
This patch reduces the size of several AST nodes by moving some fields into the free bitfield space in the base `Stmt` class: * `CXXForRangeStmt`: 96 → 88 bytes * `ChooseExpr`: 56 → 48 bytes * `ArrayTypeTraitExpr`: 56 → 48 bytes * `ExpressionTraitExpr`: 40 → 32 bytes * `CXXFoldExpr`: 64 → 56 bytes * `ShuffleExpr`: 40 → 32 bytes * `PackIndexingExpr`: 48 → 40 bytes There are no noticeable memory savings (`Expr/Stmt` memory usage 125,824,496 vs 125,826,336 bytes for `SemaExpr.cpp`) in my testing, likely because these node types are not among the most common in typical ASTs. >From 4b1cdc30ddb476d7e30519e5fe5ab6c298b59809 Mon Sep 17 00:00:00 2001 From: Haojian Wu <hokein...@gmail.com> Date: Sat, 10 May 2025 07:44:51 +0200 Subject: [PATCH 1/3] [AST] Restructure the CXXForRanageStmt class to reduce the size, 96 -> 88 --- clang/include/clang/AST/Expr.h | 9 +++------ clang/include/clang/AST/Stmt.h | 4 +++- clang/include/clang/AST/StmtCXX.h | 2 +- clang/lib/AST/Expr.cpp | 7 ++++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index a83320a7ddec2..5125d1a8349c1 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -2890,9 +2890,6 @@ class MatrixSubscriptExpr : public Expr { class CallExpr : public Expr { enum { FN = 0, PREARGS_START = 1 }; - /// The number of arguments in the call expression. - unsigned NumArgs; - /// The location of the right parentheses. This has a different meaning for /// the derived classes of CallExpr. SourceLocation RParenLoc; @@ -3056,7 +3053,7 @@ class CallExpr : public Expr { } /// getNumArgs - Return the number of actual arguments to this call. - unsigned getNumArgs() const { return NumArgs; } + unsigned getNumArgs() const { return CallExprBits.NumArgs; } /// Retrieve the call arguments. Expr **getArgs() { @@ -3104,13 +3101,13 @@ class CallExpr : public Expr { void shrinkNumArgs(unsigned NewNumArgs) { assert((NewNumArgs <= getNumArgs()) && "shrinkNumArgs cannot increase the number of arguments!"); - NumArgs = NewNumArgs; + CallExprBits.NumArgs = NewNumArgs; } /// Bluntly set a new number of arguments without doing any checks whatsoever. /// Only used during construction of a CallExpr in a few places in Sema. /// FIXME: Find a way to remove it. - void setNumArgsUnsafe(unsigned NewNumArgs) { NumArgs = NewNumArgs; } + void setNumArgsUnsafe(unsigned NewNumArgs) { CallExprBits.NumArgs = NewNumArgs; } typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 336eb6d3df7e1..bea85271fbe92 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -572,8 +572,10 @@ class alignas(void *) Stmt { /// trailing objects belonging to CallExpr. Intentionally byte sized /// for faster access. unsigned OffsetToTrailingObjects : 8; + + unsigned NumArgs:20; }; - enum { NumCallExprBits = 32 }; + enum { NumCallExprBits = 52 }; class MemberExprBitfields { friend class ASTStmtReader; diff --git a/clang/include/clang/AST/StmtCXX.h b/clang/include/clang/AST/StmtCXX.h index 8b4ef24ed376a..a15a445fbea40 100644 --- a/clang/include/clang/AST/StmtCXX.h +++ b/clang/include/clang/AST/StmtCXX.h @@ -133,11 +133,11 @@ class CXXTryStmt final : public Stmt, /// analysis of the constituent components. The original syntactic components /// can be extracted using getLoopVariable and getRangeInit. class CXXForRangeStmt : public Stmt { - SourceLocation ForLoc; enum { INIT, RANGE, BEGINSTMT, ENDSTMT, COND, INC, LOOPVAR, BODY, END }; // SubExprs[RANGE] is an expression or declstmt. // SubExprs[COND] and SubExprs[INC] are expressions. Stmt *SubExprs[END]; + SourceLocation ForLoc; SourceLocation CoawaitLoc; SourceLocation ColonLoc; SourceLocation RParenLoc; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 59c0e47c7c195..2a659ef67144a 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1460,7 +1460,7 @@ CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs, ADLCallKind UsesADL) : Expr(SC, Ty, VK, OK_Ordinary), RParenLoc(RParenLoc) { - NumArgs = std::max<unsigned>(Args.size(), MinNumArgs); + CallExprBits.NumArgs = std::max<unsigned>(Args.size(), MinNumArgs); unsigned NumPreArgs = PreArgs.size(); CallExprBits.NumPreArgs = NumPreArgs; assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!"); @@ -1477,7 +1477,7 @@ CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs, setPreArg(I, PreArgs[I]); for (unsigned I = 0; I != Args.size(); ++I) setArg(I, Args[I]); - for (unsigned I = Args.size(); I != NumArgs; ++I) + for (unsigned I = Args.size(); I != CallExprBits.NumArgs; ++I) setArg(I, nullptr); this->computeDependence(); @@ -1490,7 +1490,8 @@ CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs, CallExpr::CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty) - : Expr(SC, Empty), NumArgs(NumArgs) { + : Expr(SC, Empty) { + CallExprBits.NumArgs = NumArgs; CallExprBits.NumPreArgs = NumPreArgs; assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!"); >From ba84803e11817d686ed9f2473bd6ea3e2ee6a794 Mon Sep 17 00:00:00 2001 From: Haojian Wu <hokein...@gmail.com> Date: Tue, 3 Jun 2025 10:44:35 +0200 Subject: [PATCH 2/3] More AST nodes: - ChooseExpr 56->48 - ArrayTypeTraitExpr 56->48 - ExpressionTraitExpr 40->32 - CXXFoldExpr 64->56 - ShuffleExpr 40->32 - PackIndexingExpr 48->40 --- clang/include/clang/AST/Expr.h | 32 +++++---- clang/include/clang/AST/ExprCXX.h | 74 ++++++++++----------- clang/include/clang/AST/Stmt.h | 81 ++++++++++++++++++++++- clang/lib/AST/Expr.cpp | 7 +- clang/lib/AST/ExprCXX.cpp | 3 +- clang/lib/Serialization/ASTReaderStmt.cpp | 14 ++-- clang/lib/Serialization/ASTWriterStmt.cpp | 6 +- 7 files changed, 150 insertions(+), 67 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 5125d1a8349c1..71011dabdade4 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -3107,7 +3107,9 @@ class CallExpr : public Expr { /// Bluntly set a new number of arguments without doing any checks whatsoever. /// Only used during construction of a CallExpr in a few places in Sema. /// FIXME: Find a way to remove it. - void setNumArgsUnsafe(unsigned NewNumArgs) { CallExprBits.NumArgs = NewNumArgs; } + void setNumArgsUnsafe(unsigned NewNumArgs) { + CallExprBits.NumArgs = NewNumArgs; + } typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; @@ -4520,7 +4522,6 @@ class ShuffleVectorExpr : public Expr { // indices. The number of values in this list is always // 2+the number of indices in the vector type. Stmt **SubExprs; - unsigned NumExprs; public: ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args, QualType Type, @@ -4546,34 +4547,39 @@ class ShuffleVectorExpr : public Expr { /// getNumSubExprs - Return the size of the SubExprs array. This includes the /// constant expression, the actual arguments passed in, and the function /// pointers. - unsigned getNumSubExprs() const { return NumExprs; } + unsigned getNumSubExprs() const { return ShuffleVectorExprBits.NumExprs; } /// Retrieve the array of expressions. Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); } /// getExpr - Return the Expr at the specified index. Expr *getExpr(unsigned Index) { - assert((Index < NumExprs) && "Arg access out of range!"); + assert((Index < ShuffleVectorExprBits.NumExprs) && + "Arg access out of range!"); return cast<Expr>(SubExprs[Index]); } const Expr *getExpr(unsigned Index) const { - assert((Index < NumExprs) && "Arg access out of range!"); + assert((Index < ShuffleVectorExprBits.NumExprs) && + "Arg access out of range!"); return cast<Expr>(SubExprs[Index]); } void setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs); llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const { - assert((N < NumExprs - 2) && "Shuffle idx out of range!"); + assert((N < ShuffleVectorExprBits.NumExprs - 2) && + "Shuffle idx out of range!"); return getExpr(N+2)->EvaluateKnownConstInt(Ctx); } // Iterators child_range children() { - return child_range(&SubExprs[0], &SubExprs[0]+NumExprs); + return child_range(&SubExprs[0], + &SubExprs[0] + ShuffleVectorExprBits.NumExprs); } const_child_range children() const { - return const_child_range(&SubExprs[0], &SubExprs[0] + NumExprs); + return const_child_range(&SubExprs[0], + &SubExprs[0] + ShuffleVectorExprBits.NumExprs); } }; @@ -4715,13 +4721,13 @@ class ChooseExpr : public Expr { enum { COND, LHS, RHS, END_EXPR }; Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. SourceLocation BuiltinLoc, RParenLoc; - bool CondIsTrue; + public: ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t, ExprValueKind VK, ExprObjectKind OK, SourceLocation RP, bool condIsTrue) - : Expr(ChooseExprClass, t, VK, OK), BuiltinLoc(BLoc), RParenLoc(RP), - CondIsTrue(condIsTrue) { + : Expr(ChooseExprClass, t, VK, OK), BuiltinLoc(BLoc), RParenLoc(RP) { + ChooseExprBits.CondIsTrue = condIsTrue; SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; @@ -4737,9 +4743,9 @@ class ChooseExpr : public Expr { bool isConditionTrue() const { assert(!isConditionDependent() && "Dependent condition isn't true or false"); - return CondIsTrue; + return ChooseExprBits.CondIsTrue; } - void setIsConditionTrue(bool isTrue) { CondIsTrue = isTrue; } + void setIsConditionTrue(bool isTrue) { ChooseExprBits.CondIsTrue = isTrue; } bool isConditionDependent() const { return getCond()->isTypeDependent() || getCond()->isValueDependent(); diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 844f6dd90ae1d..bc70ba08f3073 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -2973,10 +2973,6 @@ class TypeTraitExpr final /// __array_extent(int[10][20], 1) == 20 /// \endcode class ArrayTypeTraitExpr : public Expr { - /// The trait. An ArrayTypeTrait enum in MSVC compat unsigned. - LLVM_PREFERRED_TYPE(ArrayTypeTrait) - unsigned ATT : 2; - /// The value of the type trait. Unspecified if dependent. uint64_t Value = 0; @@ -2998,21 +2994,27 @@ class ArrayTypeTraitExpr : public Expr { ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att, TypeSourceInfo *queried, uint64_t value, Expr *dimension, SourceLocation rparen, QualType ty) - : Expr(ArrayTypeTraitExprClass, ty, VK_PRValue, OK_Ordinary), ATT(att), + : Expr(ArrayTypeTraitExprClass, ty, VK_PRValue, OK_Ordinary), Value(value), Dimension(dimension), Loc(loc), RParen(rparen), QueriedType(queried) { assert(att <= ATT_Last && "invalid enum value!"); - assert(static_cast<unsigned>(att) == ATT && "ATT overflow!"); + ArrayTypeTraitExprBits.ATT = att; + assert(static_cast<unsigned>(att) == ArrayTypeTraitExprBits.ATT && + "ATT overflow!"); setDependence(computeDependence(this)); } explicit ArrayTypeTraitExpr(EmptyShell Empty) - : Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {} + : Expr(ArrayTypeTraitExprClass, Empty) { + ArrayTypeTraitExprBits.ATT = 0; + } SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } SourceLocation getEndLoc() const LLVM_READONLY { return RParen; } - ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); } + ArrayTypeTrait getTrait() const { + return static_cast<ArrayTypeTrait>(ArrayTypeTraitExprBits.ATT); + } QualType getQueriedType() const { return QueriedType->getType(); } @@ -3044,14 +3046,6 @@ class ArrayTypeTraitExpr : public Expr { /// __is_lvalue_expr(1) == false /// \endcode class ExpressionTraitExpr : public Expr { - /// The trait. A ExpressionTrait enum in MSVC compatible unsigned. - LLVM_PREFERRED_TYPE(ExpressionTrait) - unsigned ET : 31; - - /// The value of the type trait. Unspecified if dependent. - LLVM_PREFERRED_TYPE(bool) - unsigned Value : 1; - /// The location of the type trait keyword. SourceLocation Loc; @@ -3067,24 +3061,32 @@ class ExpressionTraitExpr : public Expr { ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, Expr *queried, bool value, SourceLocation rparen, QualType resultType) : Expr(ExpressionTraitExprClass, resultType, VK_PRValue, OK_Ordinary), - ET(et), Value(value), Loc(loc), RParen(rparen), - QueriedExpression(queried) { + Loc(loc), RParen(rparen), QueriedExpression(queried) { + ExpressionTraitExprBits.ET = et; + ExpressionTraitExprBits.Value = value; + assert(et <= ET_Last && "invalid enum value!"); - assert(static_cast<unsigned>(et) == ET && "ET overflow!"); + assert(static_cast<unsigned>(et) == ExpressionTraitExprBits.ET && + "ET overflow!"); setDependence(computeDependence(this)); } explicit ExpressionTraitExpr(EmptyShell Empty) - : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {} + : Expr(ExpressionTraitExprClass, Empty) { + ExpressionTraitExprBits.ET = 0; + ExpressionTraitExprBits.Value = false; + } SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } SourceLocation getEndLoc() const LLVM_READONLY { return RParen; } - ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); } + ExpressionTrait getTrait() const { + return static_cast<ExpressionTrait>(ExpressionTraitExprBits.ET); + } Expr *getQueriedExpression() const { return QueriedExpression; } - bool getValue() const { return Value; } + bool getValue() const { return ExpressionTraitExprBits.Value; } static bool classof(const Stmt *T) { return T->getStmtClass() == ExpressionTraitExprClass; @@ -4505,22 +4507,15 @@ class PackIndexingExpr final // The pack being indexed, followed by the index Stmt *SubExprs[2]; - // The size of the trailing expressions. - unsigned TransformedExpressions : 31; - - LLVM_PREFERRED_TYPE(bool) - unsigned FullySubstituted : 1; - PackIndexingExpr(QualType Type, SourceLocation EllipsisLoc, SourceLocation RSquareLoc, Expr *PackIdExpr, Expr *IndexExpr, ArrayRef<Expr *> SubstitutedExprs = {}, bool FullySubstituted = false) : Expr(PackIndexingExprClass, Type, VK_LValue, OK_Ordinary), EllipsisLoc(EllipsisLoc), RSquareLoc(RSquareLoc), - SubExprs{PackIdExpr, IndexExpr}, - TransformedExpressions(SubstitutedExprs.size()), - FullySubstituted(FullySubstituted) { - + SubExprs{PackIdExpr, IndexExpr} { + PackIndexingExprBits.TransformedExpressions = SubstitutedExprs.size(); + PackIndexingExprBits.FullySubstituted = FullySubstituted; auto *Exprs = getTrailingObjects<Expr *>(); std::uninitialized_copy(SubstitutedExprs.begin(), SubstitutedExprs.end(), Exprs); @@ -4534,7 +4529,7 @@ class PackIndexingExpr final PackIndexingExpr(EmptyShell Empty) : Expr(PackIndexingExprClass, Empty) {} unsigned numTrailingObjects(OverloadToken<Expr *>) const { - return TransformedExpressions; + return PackIndexingExprBits.TransformedExpressions; } public: @@ -4547,11 +4542,14 @@ class PackIndexingExpr final static PackIndexingExpr *CreateDeserialized(ASTContext &Context, unsigned NumTransformedExprs); - bool isFullySubstituted() const { return FullySubstituted; } + bool isFullySubstituted() const { + return PackIndexingExprBits.FullySubstituted; + } /// Determine if the expression was expanded to empty. bool expandsToEmptyPack() const { - return isFullySubstituted() && TransformedExpressions == 0; + return isFullySubstituted() && + PackIndexingExprBits.TransformedExpressions == 0; } /// Determine the location of the 'sizeof' keyword. @@ -4589,7 +4587,8 @@ class PackIndexingExpr final /// Return the trailing expressions, regardless of the expansion. ArrayRef<Expr *> getExpressions() const { - return {getTrailingObjects<Expr *>(), TransformedExpressions}; + return {getTrailingObjects<Expr *>(), + PackIndexingExprBits.TransformedExpressions}; } static bool classof(const Stmt *T) { @@ -4987,7 +4986,6 @@ class CXXFoldExpr : public Expr { // than the number of expansions. UnsignedOrNone NumExpansions = std::nullopt; Stmt *SubExprs[SubExpr::Count]; - BinaryOperatorKind Opcode; public: CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee, @@ -5020,7 +5018,7 @@ class CXXFoldExpr : public Expr { SourceLocation getLParenLoc() const { return LParenLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } SourceLocation getEllipsisLoc() const { return EllipsisLoc; } - BinaryOperatorKind getOperator() const { return Opcode; } + BinaryOperatorKind getOperator() const { return CXXFoldExprBits.Opcode; } UnsignedOrNone getNumExpansions() const { return NumExpansions; } diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index bea85271fbe92..8ed00a275d5a5 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -19,6 +19,7 @@ #include "clang/AST/OperationKinds.h" #include "clang/AST/StmtIterator.h" #include "clang/Basic/CapturedStmt.h" +#include "clang/Basic/ExpressionTraits.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/Lambda.h" @@ -572,8 +573,8 @@ class alignas(void *) Stmt { /// trailing objects belonging to CallExpr. Intentionally byte sized /// for faster access. unsigned OffsetToTrailingObjects : 8; - - unsigned NumArgs:20; + + unsigned NumArgs : 20; }; enum { NumCallExprBits = 52 }; @@ -734,6 +735,15 @@ class alignas(void *) Stmt { unsigned ProducedByFoldExpansion : 1; }; + class ShuffleVectorExprBitfields { + friend class ShuffleVectorExpr; + + LLVM_PREFERRED_TYPE(ExprBitfields) + unsigned : NumExprBits; + + unsigned NumExprs; + }; + class StmtExprBitfields { friend class ASTStmtReader; friend class StmtExpr; @@ -747,6 +757,16 @@ class alignas(void *) Stmt { unsigned TemplateDepth; }; + class ChooseExprBitfields { + friend class ASTStmtReader; + friend class ChooseExpr; + + LLVM_PREFERRED_TYPE(ExprBitfields) + unsigned : NumExprBits; + + bool CondIsTrue : 1; + }; + //===--- C++ Expression bitfields classes ---===// class CXXOperatorCallExprBitfields { @@ -1182,6 +1202,57 @@ class alignas(void *) Stmt { SourceLocation RequiresKWLoc; }; + class ArrayTypeTraitExprBitfields { + friend class ArrayTypeTraitExpr; + friend class ASTStmtReader; + LLVM_PREFERRED_TYPE(ExprBitfields) + unsigned : NumExprBits; + + /// The trait. An ArrayTypeTrait enum in MSVC compat unsigned. + LLVM_PREFERRED_TYPE(ArrayTypeTrait) + unsigned ATT : 2; + }; + + class ExpressionTraitExprBitfields { + friend class ExpressionTraitExpr; + friend class ASTStmtReader; + LLVM_PREFERRED_TYPE(ExprBitfields) + unsigned : NumExprBits; + + /// The trait. A ExpressionTrait enum in MSVC compatible unsigned. + LLVM_PREFERRED_TYPE(ExpressionTrait) + unsigned ET : 31; + + /// The value of the type trait. Unspecified if dependent. + LLVM_PREFERRED_TYPE(bool) + unsigned Value : 1; + }; + + class CXXFoldExprBitfields { + friend class CXXFoldExpr; + friend class ASTStmtReader; + friend class ASTStmtWriter; + + LLVM_PREFERRED_TYPE(ExprBitfields) + unsigned : NumExprBits; + + BinaryOperatorKind Opcode; + }; + + class PackIndexingExprBitfields { + friend class PackIndexingExpr; + friend class ASTStmtWriter; + friend class ASTStmtReader; + + LLVM_PREFERRED_TYPE(ExprBitfields) + unsigned : NumExprBits; + // The size of the trailing expressions. + unsigned TransformedExpressions : 31; + + LLVM_PREFERRED_TYPE(bool) + unsigned FullySubstituted : 1; + }; + //===--- C++ Coroutines bitfields classes ---===// class CoawaitExprBitfields { @@ -1277,9 +1348,11 @@ class alignas(void *) Stmt { PseudoObjectExprBitfields PseudoObjectExprBits; SourceLocExprBitfields SourceLocExprBits; ParenExprBitfields ParenExprBits; + ShuffleVectorExprBitfields ShuffleVectorExprBits; // GNU Extensions. StmtExprBitfields StmtExprBits; + ChooseExprBitfields ChooseExprBits; // C++ Expressions CXXOperatorCallExprBitfields CXXOperatorCallExprBits; @@ -1306,6 +1379,10 @@ class alignas(void *) Stmt { SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits; LambdaExprBitfields LambdaExprBits; RequiresExprBitfields RequiresExprBits; + ArrayTypeTraitExprBitfields ArrayTypeTraitExprBits; + ExpressionTraitExprBitfields ExpressionTraitExprBits; + CXXFoldExprBitfields CXXFoldExprBits; + PackIndexingExprBitfields PackIndexingExprBits; // C++ Coroutines expressions CoawaitExprBitfields CoawaitBits; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 2a659ef67144a..7009afdd13143 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -4406,7 +4406,8 @@ ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr *> args, QualType Type, SourceLocation BLoc, SourceLocation RP) : Expr(ShuffleVectorExprClass, Type, VK_PRValue, OK_Ordinary), - BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(args.size()) { + BuiltinLoc(BLoc), RParenLoc(RP) { + ShuffleVectorExprBits.NumExprs = args.size(); SubExprs = new (C) Stmt*[args.size()]; for (unsigned i = 0; i != args.size(); i++) SubExprs[i] = args[i]; @@ -4417,8 +4418,8 @@ ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr *> args, void ShuffleVectorExpr::setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs) { if (SubExprs) C.Deallocate(SubExprs); - this->NumExprs = Exprs.size(); - SubExprs = new (C) Stmt*[NumExprs]; + this->ShuffleVectorExprBits.NumExprs = Exprs.size(); + SubExprs = new (C) Stmt *[ShuffleVectorExprBits.NumExprs]; memcpy(SubExprs, Exprs.data(), sizeof(Expr *) * Exprs.size()); } diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 169f11b611066..0d56d10d1a58b 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -1989,7 +1989,8 @@ CXXFoldExpr::CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee, UnsignedOrNone NumExpansions) : Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary), LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc), - NumExpansions(NumExpansions), Opcode(Opcode) { + NumExpansions(NumExpansions) { + CXXFoldExprBits.Opcode = Opcode; // We rely on asserted invariant to distinguish left and right folds. assert(((LHS && LHS->containsUnexpandedParameterPack()) != (RHS && RHS->containsUnexpandedParameterPack())) && diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index f41cfcc53a35d..142332b1cf4bc 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2156,7 +2156,7 @@ void ASTStmtReader::VisitTypeTraitExpr(TypeTraitExpr *E) { void ASTStmtReader::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { VisitExpr(E); - E->ATT = (ArrayTypeTrait)Record.readInt(); + E->ArrayTypeTraitExprBits.ATT = (ArrayTypeTrait)Record.readInt(); E->Value = (unsigned int)Record.readInt(); SourceRange Range = readSourceRange(); E->Loc = Range.getBegin(); @@ -2167,8 +2167,8 @@ void ASTStmtReader::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { void ASTStmtReader::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { VisitExpr(E); - E->ET = (ExpressionTrait)Record.readInt(); - E->Value = (bool)Record.readInt(); + E->ExpressionTraitExprBits.ET = (ExpressionTrait)Record.readInt(); + E->ExpressionTraitExprBits.Value = (bool)Record.readInt(); SourceRange Range = readSourceRange(); E->QueriedExpression = Record.readSubExpr(); E->Loc = Range.getBegin(); @@ -2209,14 +2209,14 @@ void ASTStmtReader::VisitSizeOfPackExpr(SizeOfPackExpr *E) { void ASTStmtReader::VisitPackIndexingExpr(PackIndexingExpr *E) { VisitExpr(E); - E->TransformedExpressions = Record.readInt(); - E->FullySubstituted = Record.readInt(); + E->PackIndexingExprBits.TransformedExpressions = Record.readInt(); + E->PackIndexingExprBits.FullySubstituted = Record.readInt(); E->EllipsisLoc = readSourceLocation(); E->RSquareLoc = readSourceLocation(); E->SubExprs[0] = Record.readStmt(); E->SubExprs[1] = Record.readStmt(); auto **Exprs = E->getTrailingObjects<Expr *>(); - for (unsigned I = 0; I < E->TransformedExpressions; ++I) + for (unsigned I = 0; I < E->PackIndexingExprBits.TransformedExpressions; ++I) Exprs[I] = Record.readExpr(); } @@ -2275,7 +2275,7 @@ void ASTStmtReader::VisitCXXFoldExpr(CXXFoldExpr *E) { E->SubExprs[0] = Record.readSubExpr(); E->SubExprs[1] = Record.readSubExpr(); E->SubExprs[2] = Record.readSubExpr(); - E->Opcode = (BinaryOperatorKind)Record.readInt(); + E->CXXFoldExprBits.Opcode = (BinaryOperatorKind)Record.readInt(); } void ASTStmtReader::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) { diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index b9eabd5ddb64c..83fe30e492b1f 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2211,8 +2211,8 @@ void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { void ASTStmtWriter::VisitPackIndexingExpr(PackIndexingExpr *E) { VisitExpr(E); - Record.push_back(E->TransformedExpressions); - Record.push_back(E->FullySubstituted); + Record.push_back(E->PackIndexingExprBits.TransformedExpressions); + Record.push_back(E->PackIndexingExprBits.FullySubstituted); Record.AddSourceLocation(E->getEllipsisLoc()); Record.AddSourceLocation(E->getRSquareLoc()); Record.AddStmt(E->getPackIdExpression()); @@ -2277,7 +2277,7 @@ void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) { Record.AddStmt(E->SubExprs[0]); Record.AddStmt(E->SubExprs[1]); Record.AddStmt(E->SubExprs[2]); - Record.push_back(E->Opcode); + Record.push_back(E->CXXFoldExprBits.Opcode); Code = serialization::EXPR_CXX_FOLD; } >From bc998ea7085f4f012c3f15ec1a720cb07887cb36 Mon Sep 17 00:00:00 2001 From: Haojian Wu <hokein...@gmail.com> Date: Tue, 3 Jun 2025 13:34:53 +0200 Subject: [PATCH 3/3] Revert the change in CallExpr --- clang/include/clang/AST/Expr.h | 9 ++++++--- clang/include/clang/AST/Stmt.h | 4 +--- clang/lib/AST/Expr.cpp | 7 +++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 71011dabdade4..5b033ff8660fb 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -2890,6 +2890,9 @@ class MatrixSubscriptExpr : public Expr { class CallExpr : public Expr { enum { FN = 0, PREARGS_START = 1 }; + /// The number of arguments in the call expression. + unsigned NumArgs; + /// The location of the right parentheses. This has a different meaning for /// the derived classes of CallExpr. SourceLocation RParenLoc; @@ -3053,7 +3056,7 @@ class CallExpr : public Expr { } /// getNumArgs - Return the number of actual arguments to this call. - unsigned getNumArgs() const { return CallExprBits.NumArgs; } + unsigned getNumArgs() const { return NumArgs; } /// Retrieve the call arguments. Expr **getArgs() { @@ -3101,14 +3104,14 @@ class CallExpr : public Expr { void shrinkNumArgs(unsigned NewNumArgs) { assert((NewNumArgs <= getNumArgs()) && "shrinkNumArgs cannot increase the number of arguments!"); - CallExprBits.NumArgs = NewNumArgs; + NumArgs = NewNumArgs; } /// Bluntly set a new number of arguments without doing any checks whatsoever. /// Only used during construction of a CallExpr in a few places in Sema. /// FIXME: Find a way to remove it. void setNumArgsUnsafe(unsigned NewNumArgs) { - CallExprBits.NumArgs = NewNumArgs; + NumArgs = NewNumArgs; } typedef ExprIterator arg_iterator; diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 8ed00a275d5a5..43e9f61c1b461 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -573,10 +573,8 @@ class alignas(void *) Stmt { /// trailing objects belonging to CallExpr. Intentionally byte sized /// for faster access. unsigned OffsetToTrailingObjects : 8; - - unsigned NumArgs : 20; }; - enum { NumCallExprBits = 52 }; + enum { NumCallExprBits = 32 }; class MemberExprBitfields { friend class ASTStmtReader; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 7009afdd13143..dee1258691698 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1460,7 +1460,7 @@ CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs, ADLCallKind UsesADL) : Expr(SC, Ty, VK, OK_Ordinary), RParenLoc(RParenLoc) { - CallExprBits.NumArgs = std::max<unsigned>(Args.size(), MinNumArgs); + NumArgs = std::max<unsigned>(Args.size(), MinNumArgs); unsigned NumPreArgs = PreArgs.size(); CallExprBits.NumPreArgs = NumPreArgs; assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!"); @@ -1477,7 +1477,7 @@ CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs, setPreArg(I, PreArgs[I]); for (unsigned I = 0; I != Args.size(); ++I) setArg(I, Args[I]); - for (unsigned I = Args.size(); I != CallExprBits.NumArgs; ++I) + for (unsigned I = Args.size(); I != NumArgs; ++I) setArg(I, nullptr); this->computeDependence(); @@ -1490,8 +1490,7 @@ CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs, CallExpr::CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty) - : Expr(SC, Empty) { - CallExprBits.NumArgs = NumArgs; + : Expr(SC, Empty), NumArgs(NumArgs) { CallExprBits.NumPreArgs = NumPreArgs; assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!"); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits