Skip to content

Commit 0d02150

Browse files
authored
[clang][AST] Reduce some AST node size. (#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.
1 parent 50f9b8a commit 0d02150

File tree

8 files changed

+147
-65
lines changed

8 files changed

+147
-65
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4579,7 +4579,6 @@ class ShuffleVectorExpr : public Expr {
45794579
// indices. The number of values in this list is always
45804580
// 2+the number of indices in the vector type.
45814581
Stmt **SubExprs;
4582-
unsigned NumExprs;
45834582

45844583
public:
45854584
ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args, QualType Type,
@@ -4605,36 +4604,41 @@ class ShuffleVectorExpr : public Expr {
46054604
/// getNumSubExprs - Return the size of the SubExprs array. This includes the
46064605
/// constant expression, the actual arguments passed in, and the function
46074606
/// pointers.
4608-
unsigned getNumSubExprs() const { return NumExprs; }
4607+
unsigned getNumSubExprs() const { return ShuffleVectorExprBits.NumExprs; }
46094608

46104609
/// Retrieve the array of expressions.
46114610
Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
46124611

46134612
/// getExpr - Return the Expr at the specified index.
46144613
Expr *getExpr(unsigned Index) {
4615-
assert((Index < NumExprs) && "Arg access out of range!");
4614+
assert((Index < ShuffleVectorExprBits.NumExprs) &&
4615+
"Arg access out of range!");
46164616
return cast<Expr>(SubExprs[Index]);
46174617
}
46184618
const Expr *getExpr(unsigned Index) const {
4619-
assert((Index < NumExprs) && "Arg access out of range!");
4619+
assert((Index < ShuffleVectorExprBits.NumExprs) &&
4620+
"Arg access out of range!");
46204621
return cast<Expr>(SubExprs[Index]);
46214622
}
46224623

46234624
void setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs);
46244625

46254626
llvm::APSInt getShuffleMaskIdx(unsigned N) const {
4626-
assert((N < NumExprs - 2) && "Shuffle idx out of range!");
4627+
assert((N < ShuffleVectorExprBits.NumExprs - 2) &&
4628+
"Shuffle idx out of range!");
46274629
assert(isa<ConstantExpr>(getExpr(N + 2)) &&
46284630
"Index expression must be a ConstantExpr");
46294631
return cast<ConstantExpr>(getExpr(N + 2))->getAPValueResult().getInt();
46304632
}
46314633

46324634
// Iterators
46334635
child_range children() {
4634-
return child_range(&SubExprs[0], &SubExprs[0]+NumExprs);
4636+
return child_range(&SubExprs[0],
4637+
&SubExprs[0] + ShuffleVectorExprBits.NumExprs);
46354638
}
46364639
const_child_range children() const {
4637-
return const_child_range(&SubExprs[0], &SubExprs[0] + NumExprs);
4640+
return const_child_range(&SubExprs[0],
4641+
&SubExprs[0] + ShuffleVectorExprBits.NumExprs);
46384642
}
46394643
};
46404644

@@ -4776,13 +4780,13 @@ class ChooseExpr : public Expr {
47764780
enum { COND, LHS, RHS, END_EXPR };
47774781
Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
47784782
SourceLocation BuiltinLoc, RParenLoc;
4779-
bool CondIsTrue;
4783+
47804784
public:
47814785
ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t,
47824786
ExprValueKind VK, ExprObjectKind OK, SourceLocation RP,
47834787
bool condIsTrue)
4784-
: Expr(ChooseExprClass, t, VK, OK), BuiltinLoc(BLoc), RParenLoc(RP),
4785-
CondIsTrue(condIsTrue) {
4788+
: Expr(ChooseExprClass, t, VK, OK), BuiltinLoc(BLoc), RParenLoc(RP) {
4789+
ChooseExprBits.CondIsTrue = condIsTrue;
47864790
SubExprs[COND] = cond;
47874791
SubExprs[LHS] = lhs;
47884792
SubExprs[RHS] = rhs;
@@ -4798,9 +4802,9 @@ class ChooseExpr : public Expr {
47984802
bool isConditionTrue() const {
47994803
assert(!isConditionDependent() &&
48004804
"Dependent condition isn't true or false");
4801-
return CondIsTrue;
4805+
return ChooseExprBits.CondIsTrue;
48024806
}
4803-
void setIsConditionTrue(bool isTrue) { CondIsTrue = isTrue; }
4807+
void setIsConditionTrue(bool isTrue) { ChooseExprBits.CondIsTrue = isTrue; }
48044808

48054809
bool isConditionDependent() const {
48064810
return getCond()->isTypeDependent() || getCond()->isValueDependent();

clang/include/clang/AST/ExprCXX.h

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2974,10 +2974,6 @@ class TypeTraitExpr final
29742974
/// __array_extent(int[10][20], 1) == 20
29752975
/// \endcode
29762976
class ArrayTypeTraitExpr : public Expr {
2977-
/// The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
2978-
LLVM_PREFERRED_TYPE(ArrayTypeTrait)
2979-
unsigned ATT : 2;
2980-
29812977
/// The value of the type trait. Unspecified if dependent.
29822978
uint64_t Value = 0;
29832979

@@ -2999,21 +2995,27 @@ class ArrayTypeTraitExpr : public Expr {
29992995
ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
30002996
TypeSourceInfo *queried, uint64_t value, Expr *dimension,
30012997
SourceLocation rparen, QualType ty)
3002-
: Expr(ArrayTypeTraitExprClass, ty, VK_PRValue, OK_Ordinary), ATT(att),
2998+
: Expr(ArrayTypeTraitExprClass, ty, VK_PRValue, OK_Ordinary),
30032999
Value(value), Dimension(dimension), Loc(loc), RParen(rparen),
30043000
QueriedType(queried) {
30053001
assert(att <= ATT_Last && "invalid enum value!");
3006-
assert(static_cast<unsigned>(att) == ATT && "ATT overflow!");
3002+
ArrayTypeTraitExprBits.ATT = att;
3003+
assert(static_cast<unsigned>(att) == ArrayTypeTraitExprBits.ATT &&
3004+
"ATT overflow!");
30073005
setDependence(computeDependence(this));
30083006
}
30093007

30103008
explicit ArrayTypeTraitExpr(EmptyShell Empty)
3011-
: Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {}
3009+
: Expr(ArrayTypeTraitExprClass, Empty) {
3010+
ArrayTypeTraitExprBits.ATT = 0;
3011+
}
30123012

30133013
SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
30143014
SourceLocation getEndLoc() const LLVM_READONLY { return RParen; }
30153015

3016-
ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
3016+
ArrayTypeTrait getTrait() const {
3017+
return static_cast<ArrayTypeTrait>(ArrayTypeTraitExprBits.ATT);
3018+
}
30173019

30183020
QualType getQueriedType() const { return QueriedType->getType(); }
30193021

@@ -3045,14 +3047,6 @@ class ArrayTypeTraitExpr : public Expr {
30453047
/// __is_lvalue_expr(1) == false
30463048
/// \endcode
30473049
class ExpressionTraitExpr : public Expr {
3048-
/// The trait. A ExpressionTrait enum in MSVC compatible unsigned.
3049-
LLVM_PREFERRED_TYPE(ExpressionTrait)
3050-
unsigned ET : 31;
3051-
3052-
/// The value of the type trait. Unspecified if dependent.
3053-
LLVM_PREFERRED_TYPE(bool)
3054-
unsigned Value : 1;
3055-
30563050
/// The location of the type trait keyword.
30573051
SourceLocation Loc;
30583052

@@ -3068,24 +3062,32 @@ class ExpressionTraitExpr : public Expr {
30683062
ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, Expr *queried,
30693063
bool value, SourceLocation rparen, QualType resultType)
30703064
: Expr(ExpressionTraitExprClass, resultType, VK_PRValue, OK_Ordinary),
3071-
ET(et), Value(value), Loc(loc), RParen(rparen),
3072-
QueriedExpression(queried) {
3065+
Loc(loc), RParen(rparen), QueriedExpression(queried) {
3066+
ExpressionTraitExprBits.ET = et;
3067+
ExpressionTraitExprBits.Value = value;
3068+
30733069
assert(et <= ET_Last && "invalid enum value!");
3074-
assert(static_cast<unsigned>(et) == ET && "ET overflow!");
3070+
assert(static_cast<unsigned>(et) == ExpressionTraitExprBits.ET &&
3071+
"ET overflow!");
30753072
setDependence(computeDependence(this));
30763073
}
30773074

30783075
explicit ExpressionTraitExpr(EmptyShell Empty)
3079-
: Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {}
3076+
: Expr(ExpressionTraitExprClass, Empty) {
3077+
ExpressionTraitExprBits.ET = 0;
3078+
ExpressionTraitExprBits.Value = false;
3079+
}
30803080

30813081
SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
30823082
SourceLocation getEndLoc() const LLVM_READONLY { return RParen; }
30833083

3084-
ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); }
3084+
ExpressionTrait getTrait() const {
3085+
return static_cast<ExpressionTrait>(ExpressionTraitExprBits.ET);
3086+
}
30853087

30863088
Expr *getQueriedExpression() const { return QueriedExpression; }
30873089

3088-
bool getValue() const { return Value; }
3090+
bool getValue() const { return ExpressionTraitExprBits.Value; }
30893091

30903092
static bool classof(const Stmt *T) {
30913093
return T->getStmtClass() == ExpressionTraitExprClass;
@@ -4506,22 +4508,15 @@ class PackIndexingExpr final
45064508
// The pack being indexed, followed by the index
45074509
Stmt *SubExprs[2];
45084510

4509-
// The size of the trailing expressions.
4510-
unsigned TransformedExpressions : 31;
4511-
4512-
LLVM_PREFERRED_TYPE(bool)
4513-
unsigned FullySubstituted : 1;
4514-
45154511
PackIndexingExpr(QualType Type, SourceLocation EllipsisLoc,
45164512
SourceLocation RSquareLoc, Expr *PackIdExpr, Expr *IndexExpr,
45174513
ArrayRef<Expr *> SubstitutedExprs = {},
45184514
bool FullySubstituted = false)
45194515
: Expr(PackIndexingExprClass, Type, VK_LValue, OK_Ordinary),
45204516
EllipsisLoc(EllipsisLoc), RSquareLoc(RSquareLoc),
4521-
SubExprs{PackIdExpr, IndexExpr},
4522-
TransformedExpressions(SubstitutedExprs.size()),
4523-
FullySubstituted(FullySubstituted) {
4524-
4517+
SubExprs{PackIdExpr, IndexExpr} {
4518+
PackIndexingExprBits.TransformedExpressions = SubstitutedExprs.size();
4519+
PackIndexingExprBits.FullySubstituted = FullySubstituted;
45254520
auto *Exprs = getTrailingObjects<Expr *>();
45264521
llvm::uninitialized_copy(SubstitutedExprs, Exprs);
45274522

@@ -4534,7 +4529,7 @@ class PackIndexingExpr final
45344529
PackIndexingExpr(EmptyShell Empty) : Expr(PackIndexingExprClass, Empty) {}
45354530

45364531
unsigned numTrailingObjects(OverloadToken<Expr *>) const {
4537-
return TransformedExpressions;
4532+
return PackIndexingExprBits.TransformedExpressions;
45384533
}
45394534

45404535
public:
@@ -4548,11 +4543,14 @@ class PackIndexingExpr final
45484543
unsigned NumTransformedExprs);
45494544

45504545
// The index expression and all elements of the pack have been substituted.
4551-
bool isFullySubstituted() const { return FullySubstituted; }
4546+
bool isFullySubstituted() const {
4547+
return PackIndexingExprBits.FullySubstituted;
4548+
}
45524549

45534550
/// Determine if the expression was expanded to empty.
45544551
bool expandsToEmptyPack() const {
4555-
return isFullySubstituted() && TransformedExpressions == 0;
4552+
return isFullySubstituted() &&
4553+
PackIndexingExprBits.TransformedExpressions == 0;
45564554
}
45574555

45584556
/// Determine the location of the 'sizeof' keyword.
@@ -4590,7 +4588,8 @@ class PackIndexingExpr final
45904588

45914589
/// Return the trailing expressions, regardless of the expansion.
45924590
ArrayRef<Expr *> getExpressions() const {
4593-
return {getTrailingObjects<Expr *>(), TransformedExpressions};
4591+
return {getTrailingObjects<Expr *>(),
4592+
PackIndexingExprBits.TransformedExpressions};
45944593
}
45954594

45964595
static bool classof(const Stmt *T) {
@@ -4988,7 +4987,6 @@ class CXXFoldExpr : public Expr {
49884987
// than the number of expansions.
49894988
UnsignedOrNone NumExpansions = std::nullopt;
49904989
Stmt *SubExprs[SubExpr::Count];
4991-
BinaryOperatorKind Opcode;
49924990

49934991
public:
49944992
CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee,
@@ -5021,7 +5019,7 @@ class CXXFoldExpr : public Expr {
50215019
SourceLocation getLParenLoc() const { return LParenLoc; }
50225020
SourceLocation getRParenLoc() const { return RParenLoc; }
50235021
SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
5024-
BinaryOperatorKind getOperator() const { return Opcode; }
5022+
BinaryOperatorKind getOperator() const { return CXXFoldExprBits.Opcode; }
50255023

50265024
UnsignedOrNone getNumExpansions() const { return NumExpansions; }
50275025

clang/include/clang/AST/Stmt.h

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "clang/AST/OperationKinds.h"
2020
#include "clang/AST/StmtIterator.h"
2121
#include "clang/Basic/CapturedStmt.h"
22+
#include "clang/Basic/ExpressionTraits.h"
2223
#include "clang/Basic/IdentifierTable.h"
2324
#include "clang/Basic/LLVM.h"
2425
#include "clang/Basic/Lambda.h"
@@ -736,6 +737,15 @@ class alignas(void *) Stmt {
736737
unsigned ProducedByFoldExpansion : 1;
737738
};
738739

740+
class ShuffleVectorExprBitfields {
741+
friend class ShuffleVectorExpr;
742+
743+
LLVM_PREFERRED_TYPE(ExprBitfields)
744+
unsigned : NumExprBits;
745+
746+
unsigned NumExprs;
747+
};
748+
739749
class StmtExprBitfields {
740750
friend class ASTStmtReader;
741751
friend class StmtExpr;
@@ -749,6 +759,17 @@ class alignas(void *) Stmt {
749759
unsigned TemplateDepth;
750760
};
751761

762+
class ChooseExprBitfields {
763+
friend class ASTStmtReader;
764+
friend class ChooseExpr;
765+
766+
LLVM_PREFERRED_TYPE(ExprBitfields)
767+
unsigned : NumExprBits;
768+
769+
LLVM_PREFERRED_TYPE(bool)
770+
bool CondIsTrue : 1;
771+
};
772+
752773
//===--- C++ Expression bitfields classes ---===//
753774

754775
class CXXOperatorCallExprBitfields {
@@ -1184,6 +1205,57 @@ class alignas(void *) Stmt {
11841205
SourceLocation RequiresKWLoc;
11851206
};
11861207

1208+
class ArrayTypeTraitExprBitfields {
1209+
friend class ArrayTypeTraitExpr;
1210+
friend class ASTStmtReader;
1211+
LLVM_PREFERRED_TYPE(ExprBitfields)
1212+
unsigned : NumExprBits;
1213+
1214+
/// The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
1215+
LLVM_PREFERRED_TYPE(ArrayTypeTrait)
1216+
unsigned ATT : 2;
1217+
};
1218+
1219+
class ExpressionTraitExprBitfields {
1220+
friend class ExpressionTraitExpr;
1221+
friend class ASTStmtReader;
1222+
LLVM_PREFERRED_TYPE(ExprBitfields)
1223+
unsigned : NumExprBits;
1224+
1225+
/// The trait. A ExpressionTrait enum in MSVC compatible unsigned.
1226+
LLVM_PREFERRED_TYPE(ExpressionTrait)
1227+
unsigned ET : 31;
1228+
1229+
/// The value of the type trait. Unspecified if dependent.
1230+
LLVM_PREFERRED_TYPE(bool)
1231+
unsigned Value : 1;
1232+
};
1233+
1234+
class CXXFoldExprBitfields {
1235+
friend class CXXFoldExpr;
1236+
friend class ASTStmtReader;
1237+
friend class ASTStmtWriter;
1238+
1239+
LLVM_PREFERRED_TYPE(ExprBitfields)
1240+
unsigned : NumExprBits;
1241+
1242+
BinaryOperatorKind Opcode;
1243+
};
1244+
1245+
class PackIndexingExprBitfields {
1246+
friend class PackIndexingExpr;
1247+
friend class ASTStmtWriter;
1248+
friend class ASTStmtReader;
1249+
1250+
LLVM_PREFERRED_TYPE(ExprBitfields)
1251+
unsigned : NumExprBits;
1252+
// The size of the trailing expressions.
1253+
unsigned TransformedExpressions : 31;
1254+
1255+
LLVM_PREFERRED_TYPE(bool)
1256+
unsigned FullySubstituted : 1;
1257+
};
1258+
11871259
//===--- C++ Coroutines bitfields classes ---===//
11881260

11891261
class CoawaitExprBitfields {
@@ -1279,9 +1351,11 @@ class alignas(void *) Stmt {
12791351
PseudoObjectExprBitfields PseudoObjectExprBits;
12801352
SourceLocExprBitfields SourceLocExprBits;
12811353
ParenExprBitfields ParenExprBits;
1354+
ShuffleVectorExprBitfields ShuffleVectorExprBits;
12821355

12831356
// GNU Extensions.
12841357
StmtExprBitfields StmtExprBits;
1358+
ChooseExprBitfields ChooseExprBits;
12851359

12861360
// C++ Expressions
12871361
CXXOperatorCallExprBitfields CXXOperatorCallExprBits;
@@ -1308,6 +1382,10 @@ class alignas(void *) Stmt {
13081382
SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;
13091383
LambdaExprBitfields LambdaExprBits;
13101384
RequiresExprBitfields RequiresExprBits;
1385+
ArrayTypeTraitExprBitfields ArrayTypeTraitExprBits;
1386+
ExpressionTraitExprBitfields ExpressionTraitExprBits;
1387+
CXXFoldExprBitfields CXXFoldExprBits;
1388+
PackIndexingExprBitfields PackIndexingExprBits;
13111389

13121390
// C++ Coroutines expressions
13131391
CoawaitExprBitfields CoawaitBits;

clang/include/clang/AST/StmtCXX.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,11 @@ class CXXTryStmt final : public Stmt,
133133
/// analysis of the constituent components. The original syntactic components
134134
/// can be extracted using getLoopVariable and getRangeInit.
135135
class CXXForRangeStmt : public Stmt {
136-
SourceLocation ForLoc;
137136
enum { INIT, RANGE, BEGINSTMT, ENDSTMT, COND, INC, LOOPVAR, BODY, END };
138137
// SubExprs[RANGE] is an expression or declstmt.
139138
// SubExprs[COND] and SubExprs[INC] are expressions.
140139
Stmt *SubExprs[END];
140+
SourceLocation ForLoc;
141141
SourceLocation CoawaitLoc;
142142
SourceLocation ColonLoc;
143143
SourceLocation RParenLoc;

0 commit comments

Comments
 (0)