[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