diff options
author | John McCall <rjmccall@apple.com> | 2010-10-26 08:39:16 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-10-26 08:39:16 +0000 |
commit | 8e6285af719adc6f86d6faa235d22a08eb68ee3a (patch) | |
tree | 96033c3c348ba398637cfa7d2a09ec34cfcae41e | |
parent | 3fa5cae9b3812cab9fab6c042c3329bb70a3d046 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117359 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Expr.h | 68 | ||||
-rw-r--r-- | include/clang/AST/Stmt.h | 116 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 32 | ||||
-rw-r--r-- | lib/AST/Stmt.cpp | 10 |
4 files changed, 139 insertions, 87 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index ecfa1307dd..ba4a38029e 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -53,29 +53,26 @@ class Expr : public Stmt { 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 @@ public: /// @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 @@ public: /// 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 @@ public: typedef clang::CastKind CastKind; private: - unsigned Kind : 5; - unsigned BasePathSize : BitsRemaining - 5; Stmt *Op; void CheckBasePath() const { @@ -2019,17 +2014,21 @@ protected: // 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 @@ public: 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 @@ private: 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 @@ public: 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 @@ public: 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; diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 3ea0e9c5be..3862cf3fba 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -104,10 +104,7 @@ public: 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 @@ protected: 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 @@ public: 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 @@ public: /// 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 @@ class LabelStmt : public Stmt { 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 @@ public: /// \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()); diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 92e7119445..011887b9a7 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -124,8 +124,8 @@ std::size_t ExplicitTemplateArgumentList::sizeFor( } void DeclRefExpr::computeDependence() { - TypeDependent = false; - ValueDependent = false; + ExprBits.TypeDependent = false; + ExprBits.ValueDependent = false; NamedDecl *D = getDecl(); @@ -140,27 +140,27 @@ void DeclRefExpr::computeDependence() { // (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 @@ void DeclRefExpr::computeDependence() { 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 @@ InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc, { 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 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, 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 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, // 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(); diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index cc4b6c9ddb..4f46b35040 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -46,7 +46,7 @@ static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) { } const char *Stmt::getStmtClassName() const { - return getStmtInfoTableEntry((StmtClass)sClass).Name; + return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name; } void Stmt::PrintStats() { @@ -87,7 +87,7 @@ bool Stmt::CollectingStats(bool Enable) { 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 @@ SourceRange ReturnStmt::getSourceRange() const { } bool Stmt::hasImplicitControlFlow() const { - switch (sClass) { + switch (StmtBits.sClass) { default: return false; @@ -604,7 +604,9 @@ Stmt::child_iterator NullStmt::child_end() { return child_iterator(); } // 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]; } |