[cfe-commits] r117359 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/AST/Stmt.h lib/AST/Expr.cpp lib/AST/Stmt.cpp
John McCall
rjmccall at apple.com
Tue Oct 26 01:39:16 PDT 2010
Author: rjmccall
Date: Tue Oct 26 03:39:16 2010
New Revision: 117359
URL: http://llvm.org/viewvc/llvm-project?rev=117359&view=rev
Log:
Optimize field space usage in CompoundStmt, LabelStmt, Expr, and CastExpr.
There's probably still significant padding waste on x86-64 UNIXen, but
the difference in 32-bit compiles should be significant.
There are a lot of Expr nodes left that could lose a word this way.
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/AST/Stmt.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/Stmt.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=117359&r1=117358&r2=117359&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Tue Oct 26 03:39:16 2010
@@ -53,29 +53,26 @@
QualType TR;
virtual void ANCHOR(); // key function.
-protected:
- /// TypeDependent - Whether this expression is type-dependent
- /// (C++ [temp.dep.expr]).
- bool TypeDependent : 1;
-
- /// ValueDependent - Whether this expression is value-dependent
- /// (C++ [temp.dep.constexpr]).
- bool ValueDependent : 1;
-
- /// ValueKind - The value classification of this expression.
- /// Only actually used by certain subclasses.
- unsigned ValueKind : 2;
-
- enum { BitsRemaining = 28 };
- Expr(StmtClass SC, QualType T, bool TD, bool VD)
- : Stmt(SC), TypeDependent(TD), ValueDependent(VD), ValueKind(0) {
+protected:
+ Expr(StmtClass SC, QualType T, bool TD, bool VD) : Stmt(SC) {
+ ExprBits.TypeDependent = TD;
+ ExprBits.ValueDependent = VD;
+ ExprBits.ValueKind = 0;
setType(T);
}
/// \brief Construct an empty expression.
explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { }
+ /// getValueKind - The value kind that this cast produces.
+ ExprValueKind getValueKind() const {
+ return static_cast<ExprValueKind>(ExprBits.ValueKind);
+ }
+
+ /// setValueKind - Set the value kind this cast produces.
+ void setValueKind(ExprValueKind Cat) { ExprBits.ValueKind = Cat; }
+
public:
QualType getType() const { return TR; }
void setType(QualType t) {
@@ -99,10 +96,10 @@
/// @code
/// template<int Size, char (&Chars)[Size]> struct meta_string;
/// @endcode
- bool isValueDependent() const { return ValueDependent; }
+ bool isValueDependent() const { return ExprBits.ValueDependent; }
/// \brief Set whether this expression is value-dependent or not.
- void setValueDependent(bool VD) { ValueDependent = VD; }
+ void setValueDependent(bool VD) { ExprBits.ValueDependent = VD; }
/// isTypeDependent - Determines whether this expression is
/// type-dependent (C++ [temp.dep.expr]), which means that its type
@@ -115,10 +112,10 @@
/// x + y;
/// }
/// @endcode
- bool isTypeDependent() const { return TypeDependent; }
+ bool isTypeDependent() const { return ExprBits.TypeDependent; }
/// \brief Set whether this expression is type-dependent or not.
- void setTypeDependent(bool TD) { TypeDependent = TD; }
+ void setTypeDependent(bool TD) { ExprBits.TypeDependent = TD; }
/// SourceLocation tokens are not useful in isolation - they are low level
/// value objects created/interpreted by SourceManager. We assume AST
@@ -1959,8 +1956,6 @@
typedef clang::CastKind CastKind;
private:
- unsigned Kind : 5;
- unsigned BasePathSize : BitsRemaining - 5;
Stmt *Op;
void CheckBasePath() const {
@@ -2019,17 +2014,21 @@
// Cast expressions are value-dependent if the type is
// dependent or if the subexpression is value-dependent.
ty->isDependentType() || (op && op->isValueDependent())),
- Kind(kind), BasePathSize(BasePathSize), Op(op) {
+ Op(op) {
+ CastExprBits.Kind = kind;
+ CastExprBits.BasePathSize = BasePathSize;
CheckBasePath();
}
/// \brief Construct an empty cast.
CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
- : Expr(SC, Empty), BasePathSize(BasePathSize) { }
+ : Expr(SC, Empty) {
+ CastExprBits.BasePathSize = BasePathSize;
+ }
public:
- CastKind getCastKind() const { return static_cast<CastKind>(Kind); }
- void setCastKind(CastKind K) { Kind = K; }
+ CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; }
+ void setCastKind(CastKind K) { CastExprBits.Kind = K; }
const char *getCastKindName() const;
Expr *getSubExpr() { return cast<Expr>(Op); }
@@ -2046,8 +2045,8 @@
typedef CXXBaseSpecifier **path_iterator;
typedef const CXXBaseSpecifier * const *path_const_iterator;
- bool path_empty() const { return BasePathSize == 0; }
- unsigned path_size() const { return BasePathSize; }
+ bool path_empty() const { return CastExprBits.BasePathSize == 0; }
+ unsigned path_size() const { return CastExprBits.BasePathSize; }
path_iterator path_begin() { return path_buffer(); }
path_iterator path_end() { return path_buffer() + path_size(); }
path_const_iterator path_begin() const { return path_buffer(); }
@@ -2091,7 +2090,7 @@
ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
unsigned BasePathLength, ExprValueKind VK)
: CastExpr(ImplicitCastExprClass, ty, kind, op, BasePathLength) {
- ValueKind = VK;
+ setValueKind(VK);
}
/// \brief Construct an empty implicit cast.
@@ -2103,7 +2102,7 @@
ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op,
ExprValueKind VK)
: CastExpr(ImplicitCastExprClass, ty, kind, op, 0) {
- ValueKind = VK;
+ setValueKind(VK);
}
static ImplicitCastExpr *Create(ASTContext &Context, QualType T,
@@ -2117,13 +2116,8 @@
return getSubExpr()->getSourceRange();
}
- /// getValueKind - The value kind that this cast produces.
- ExprValueKind getValueKind() const {
- return static_cast<ExprValueKind>(ValueKind);
- }
-
- /// setValueKind - Set the value kind this cast produces.
- void setValueKind(ExprValueKind Cat) { ValueKind = Cat; }
+ using Expr::getValueKind;
+ using Expr::setValueKind;
static bool classof(const Stmt *T) {
return T->getStmtClass() == ImplicitCastExprClass;
Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=117359&r1=117358&r2=117359&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Tue Oct 26 03:39:16 2010
@@ -104,10 +104,7 @@
first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class
#define ABSTRACT_STMT(STMT)
#include "clang/AST/StmtNodes.inc"
-};
-private:
- /// \brief The statement class.
- const unsigned sClass : 8;
+ };
// Make vanilla 'new' and 'delete' illegal for Stmts.
protected:
@@ -119,6 +116,58 @@
assert(0 && "Stmts cannot be released with regular 'delete'.");
}
+ class StmtBitfields {
+ friend class Stmt;
+
+ /// \brief The statement class.
+ unsigned sClass : 8;
+ };
+ enum { NumStmtBits = 8 };
+
+ class CompoundStmtBitfields {
+ friend class CompoundStmt;
+ unsigned : NumStmtBits;
+
+ unsigned NumStmts : 32 - NumStmtBits;
+ };
+
+ class LabelStmtBitfields {
+ friend class LabelStmt;
+ unsigned : NumStmtBits;
+
+ unsigned Used : 1;
+ unsigned HasUnusedAttr : 1;
+ };
+
+ class ExprBitfields {
+ friend class Expr;
+ friend class DeclRefExpr; // computeDependence
+ friend class InitListExpr; // ctor
+ friend class DesignatedInitExpr; // ctor
+ unsigned : NumStmtBits;
+
+ unsigned ValueKind : 2;
+ unsigned TypeDependent : 1;
+ unsigned ValueDependent : 1;
+ };
+ enum { NumExprBits = 12 };
+
+ class CastExprBitfields {
+ friend class CastExpr;
+ unsigned : NumExprBits;
+
+ unsigned Kind : 5;
+ unsigned BasePathSize : 32 - NumExprBits - 5;
+ };
+
+ union {
+ StmtBitfields StmtBits;
+ CompoundStmtBitfields CompoundStmtBits;
+ LabelStmtBitfields LabelStmtBits;
+ ExprBitfields ExprBits;
+ CastExprBitfields CastExprBits;
+ };
+
public:
// Only allow allocation of Stmts using the allocator in ASTContext
// or by doing a placement new.
@@ -149,18 +198,20 @@
protected:
/// \brief Construct an empty statement.
- explicit Stmt(StmtClass SC, EmptyShell) : sClass(SC) {
+ explicit Stmt(StmtClass SC, EmptyShell) {
+ StmtBits.sClass = SC;
if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
}
public:
- Stmt(StmtClass SC) : sClass(SC) {
+ Stmt(StmtClass SC) {
+ StmtBits.sClass = SC;
if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
}
virtual ~Stmt() {}
StmtClass getStmtClass() const {
- return (StmtClass)sClass;
+ return static_cast<StmtClass>(StmtBits.sClass);
}
const char *getStmtClassName() const;
@@ -333,42 +384,47 @@
///
class CompoundStmt : public Stmt {
Stmt** Body;
- unsigned NumStmts;
SourceLocation LBracLoc, RBracLoc;
public:
- CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned numStmts,
- SourceLocation LB, SourceLocation RB)
- : Stmt(CompoundStmtClass), NumStmts(numStmts), LBracLoc(LB), RBracLoc(RB) {
+ CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned NumStmts,
+ SourceLocation LB, SourceLocation RB)
+ : Stmt(CompoundStmtClass), LBracLoc(LB), RBracLoc(RB) {
+ CompoundStmtBits.NumStmts = NumStmts;
+
if (NumStmts == 0) {
Body = 0;
return;
}
Body = new (C) Stmt*[NumStmts];
- memcpy(Body, StmtStart, numStmts * sizeof(*Body));
+ memcpy(Body, StmtStart, NumStmts * sizeof(*Body));
}
// \brief Build an empty compound statement.
explicit CompoundStmt(EmptyShell Empty)
- : Stmt(CompoundStmtClass, Empty), Body(0), NumStmts(0) { }
+ : Stmt(CompoundStmtClass, Empty), Body(0) {
+ CompoundStmtBits.NumStmts = 0;
+ }
void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts);
- bool body_empty() const { return NumStmts == 0; }
- unsigned size() const { return NumStmts; }
+ bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
+ unsigned size() const { return CompoundStmtBits.NumStmts; }
typedef Stmt** body_iterator;
body_iterator body_begin() { return Body; }
- body_iterator body_end() { return Body + NumStmts; }
- Stmt *body_back() { return NumStmts ? Body[NumStmts-1] : 0; }
+ body_iterator body_end() { return Body + size(); }
+ Stmt *body_back() { return !body_empty() ? Body[size()-1] : 0; }
- void setLastStmt(Stmt *S)
- { assert(NumStmts && "setLastStmt"); Body[NumStmts-1] = S; }
+ void setLastStmt(Stmt *S) {
+ assert(!body_empty() && "setLastStmt");
+ Body[size()-1] = S;
+ }
typedef Stmt* const * const_body_iterator;
const_body_iterator body_begin() const { return Body; }
- const_body_iterator body_end() const { return Body + NumStmts; }
- const Stmt *body_back() const { return NumStmts ? Body[NumStmts-1] : 0; }
+ const_body_iterator body_end() const { return Body + size(); }
+ const Stmt *body_back() const { return !body_empty() ? Body[size()-1] : 0; }
typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
reverse_body_iterator body_rbegin() {
@@ -542,14 +598,13 @@
IdentifierInfo *Label;
Stmt *SubStmt;
SourceLocation IdentLoc;
- bool Used : 1;
- bool HasUnusedAttr : 1;
public:
LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt,
bool hasUnusedAttr = false)
- : Stmt(LabelStmtClass), Label(label),
- SubStmt(substmt), IdentLoc(IL), Used(false),
- HasUnusedAttr(hasUnusedAttr) {}
+ : Stmt(LabelStmtClass), Label(label), SubStmt(substmt), IdentLoc(IL) {
+ LabelStmtBits.Used = false;
+ LabelStmtBits.HasUnusedAttr = hasUnusedAttr;
+ }
// \brief Build an empty label statement.
explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
@@ -565,12 +620,13 @@
/// \brief Whether this label was used.
bool isUsed(bool CheckUnusedAttr = true) const {
- return Used || (CheckUnusedAttr && HasUnusedAttr);
+ return LabelStmtBits.Used ||
+ (CheckUnusedAttr && LabelStmtBits.HasUnusedAttr);
}
- void setUsed(bool U = true) { Used = U; }
+ void setUsed(bool U = true) { LabelStmtBits.Used = U; }
- bool HasUnusedAttribute() const { return HasUnusedAttr; }
- void setUnusedAttribute(bool U) { HasUnusedAttr = U; }
+ bool HasUnusedAttribute() const { return LabelStmtBits.HasUnusedAttr; }
+ void setUnusedAttribute(bool U) { LabelStmtBits.HasUnusedAttr = U; }
virtual SourceRange getSourceRange() const {
return SourceRange(IdentLoc, SubStmt->getLocEnd());
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=117359&r1=117358&r2=117359&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Oct 26 03:39:16 2010
@@ -124,8 +124,8 @@
}
void DeclRefExpr::computeDependence() {
- TypeDependent = false;
- ValueDependent = false;
+ ExprBits.TypeDependent = false;
+ ExprBits.ValueDependent = false;
NamedDecl *D = getDecl();
@@ -140,27 +140,27 @@
// (TD) - an identifier that was declared with dependent type
// (VD) - a name declared with a dependent type,
if (getType()->isDependentType()) {
- TypeDependent = true;
- ValueDependent = true;
+ ExprBits.TypeDependent = true;
+ ExprBits.ValueDependent = true;
}
// (TD) - a conversion-function-id that specifies a dependent type
else if (D->getDeclName().getNameKind()
== DeclarationName::CXXConversionFunctionName &&
D->getDeclName().getCXXNameType()->isDependentType()) {
- TypeDependent = true;
- ValueDependent = true;
+ ExprBits.TypeDependent = true;
+ ExprBits.ValueDependent = true;
}
// (TD) - a template-id that is dependent,
else if (hasExplicitTemplateArgs() &&
TemplateSpecializationType::anyDependentTemplateArguments(
getTemplateArgs(),
getNumTemplateArgs())) {
- TypeDependent = true;
- ValueDependent = true;
+ ExprBits.TypeDependent = true;
+ ExprBits.ValueDependent = true;
}
// (VD) - the name of a non-type template parameter,
else if (isa<NonTypeTemplateParmDecl>(D))
- ValueDependent = true;
+ ExprBits.ValueDependent = true;
// (VD) - a constant with integral or enumeration type and is
// initialized with an expression that is value-dependent.
else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
@@ -168,20 +168,20 @@
Var->getType().getCVRQualifiers() == Qualifiers::Const) {
if (const Expr *Init = Var->getAnyInitializer())
if (Init->isValueDependent())
- ValueDependent = true;
+ ExprBits.ValueDependent = true;
}
// (VD) - FIXME: Missing from the standard:
// - a member function or a static data member of the current
// instantiation
else if (Var->isStaticDataMember() &&
Var->getDeclContext()->isDependentContext())
- ValueDependent = true;
+ ExprBits.ValueDependent = true;
}
// (VD) - FIXME: Missing from the standard:
// - a member function or a static data member of the current
// instantiation
else if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext())
- ValueDependent = true;
+ ExprBits.ValueDependent = true;
// (TD) - a nested-name-specifier or a qualified-id that names a
// member of an unknown specialization.
// (handled by DependentScopeDeclRefExpr)
@@ -999,9 +999,9 @@
{
for (unsigned I = 0; I != numInits; ++I) {
if (initExprs[I]->isTypeDependent())
- TypeDependent = true;
+ ExprBits.TypeDependent = true;
if (initExprs[I]->isValueDependent())
- ValueDependent = true;
+ ExprBits.ValueDependent = true;
}
InitExprs.insert(C, InitExprs.end(), initExprs, initExprs+numInits);
@@ -2224,7 +2224,7 @@
if (this->Designators[I].isArrayDesignator()) {
// Compute type- and value-dependence.
Expr *Index = IndexExprs[IndexIdx];
- ValueDependent = ValueDependent ||
+ ExprBits.ValueDependent = ExprBits.ValueDependent ||
Index->isTypeDependent() || Index->isValueDependent();
// Copy the index expressions into permanent storage.
@@ -2233,7 +2233,7 @@
// Compute type- and value-dependence.
Expr *Start = IndexExprs[IndexIdx];
Expr *End = IndexExprs[IndexIdx + 1];
- ValueDependent = ValueDependent ||
+ ExprBits.ValueDependent = ExprBits.ValueDependent ||
Start->isTypeDependent() || Start->isValueDependent() ||
End->isTypeDependent() || End->isValueDependent();
Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=117359&r1=117358&r2=117359&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Tue Oct 26 03:39:16 2010
@@ -46,7 +46,7 @@
}
const char *Stmt::getStmtClassName() const {
- return getStmtInfoTableEntry((StmtClass)sClass).Name;
+ return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name;
}
void Stmt::PrintStats() {
@@ -87,7 +87,7 @@
void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
if (this->Body)
C.Deallocate(Body);
- this->NumStmts = NumStmts;
+ this->CompoundStmtBits.NumStmts = NumStmts;
Body = new (C) Stmt*[NumStmts];
memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts);
@@ -106,7 +106,7 @@
}
bool Stmt::hasImplicitControlFlow() const {
- switch (sClass) {
+ switch (StmtBits.sClass) {
default:
return false;
@@ -604,7 +604,9 @@
// CompoundStmt
Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; }
-Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+NumStmts; }
+Stmt::child_iterator CompoundStmt::child_end() {
+ return &Body[0]+CompoundStmtBits.NumStmts;
+}
// CaseStmt
Stmt::child_iterator CaseStmt::child_begin() { return &SubExprs[0]; }
More information about the cfe-commits
mailing list