r233921 - [ast] Put the Stmt hierarchy on a diet for 64 bit targets.

Benjamin Kramer benny.kra at googlemail.com
Thu Apr 2 08:29:07 PDT 2015


Author: d0k
Date: Thu Apr  2 10:29:07 2015
New Revision: 233921

URL: http://llvm.org/viewvc/llvm-project?rev=233921&view=rev
Log:
[ast] Put the Stmt hierarchy on a diet for 64 bit targets.

Previously we would waste 32 bits on alignment, use LLVM_ALIGNAS to
free that space for derived classes an place. Sadly still have to #ifdef
out MSVC 2013 because it can't align based on a sizeof expr.

No intended functionality change. New byte counts:
sizeof(before)			|	sizeof(after)

LabelStmt: 32			|	LabelStmt: 24
SwitchStmt: 48			|	SwitchStmt: 40
WhileStmt: 40			|	WhileStmt: 32
DoStmt: 40			|	DoStmt: 32
ForStmt: 64			|	ForStmt: 56
ContinueStmt: 16		|	ContinueStmt: 8
BreakStmt: 16			|	BreakStmt: 8
ReturnStmt: 32			|	ReturnStmt: 24
AsmStmt: 40			|	AsmStmt: 32
GCCAsmStmt: 80			|	GCCAsmStmt: 72
MSAsmStmt: 96			|	MSAsmStmt: 88
SEHExceptStmt: 32		|	SEHExceptStmt: 24
SEHFinallyStmt: 24		|	SEHFinallyStmt: 16
SEHLeaveStmt: 16		|	SEHLeaveStmt: 8
CapturedStmt: 32		|	CapturedStmt: 24
CXXCatchStmt: 32		|	CXXCatchStmt: 24
CXXForRangeStmt: 72		|	CXXForRangeStmt: 64
ObjCAtFinallyStmt: 24		|	ObjCAtFinallyStmt: 16
ObjCAtSynchronizedStmt: 32	|	ObjCAtSynchronizedStmt: 24
ObjCAtThrowStmt: 24		|	ObjCAtThrowStmt: 16
ObjCAutoreleasePoolStmt: 24	|	ObjCAutoreleasePoolStmt: 16

Modified:
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/include/clang/AST/StmtCXX.h
    cfe/trunk/include/clang/AST/StmtObjC.h
    cfe/trunk/lib/AST/Stmt.cpp

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=233921&r1=233920&r2=233921&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Thu Apr  2 10:29:07 2015
@@ -101,7 +101,13 @@ namespace clang {
 
 /// Stmt - This represents one statement.
 ///
+#if !defined(_MSC_VER) || LLVM_MSC_PREREQ(1900)
+class LLVM_ALIGNAS(sizeof(void *)) Stmt {
+#else
+// Old MSVC has issues to align this. Drop when we retire MSVC 2013. When GCC
+// 4.7 is also gone this can be just alignof(void *).
 class Stmt {
+#endif
 public:
   enum StmtClass {
     NoStmtClass = 0,
@@ -287,8 +293,10 @@ protected:
   };
 
   union {
+#if !(!defined(_MSC_VER) || LLVM_MSC_PREREQ(1900))
     // FIXME: this is wasteful on 64-bit platforms.
     void *Aligner;
+#endif
 
     StmtBitfields StmtBits;
     CompoundStmtBitfields CompoundStmtBits;
@@ -688,10 +696,10 @@ public:
 };
 
 class CaseStmt : public SwitchCase {
+  SourceLocation EllipsisLoc;
   enum { LHS, RHS, SUBSTMT, END_EXPR };
   Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
                              // GNU "case 1 ... 4" extension
-  SourceLocation EllipsisLoc;
 public:
   CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
            SourceLocation ellipsisLoc, SourceLocation colonLoc)
@@ -788,13 +796,13 @@ inline SourceLocation SwitchCase::getLoc
 ///    foo: return;
 ///
 class LabelStmt : public Stmt {
+  SourceLocation IdentLoc;
   LabelDecl *TheDecl;
   Stmt *SubStmt;
-  SourceLocation IdentLoc;
+
 public:
   LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
-    : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt), IdentLoc(IL) {
-  }
+      : Stmt(LabelStmtClass), IdentLoc(IL), TheDecl(D), SubStmt(substmt) {}
 
   // \brief Build an empty label statement.
   explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
@@ -943,16 +951,14 @@ public:
 /// SwitchStmt - This represents a 'switch' stmt.
 ///
 class SwitchStmt : public Stmt {
+  SourceLocation SwitchLoc;
   enum { VAR, COND, BODY, END_EXPR };
   Stmt* SubExprs[END_EXPR];
-  // This points to a linked list of case and default statements.
-  SwitchCase *FirstCase;
-  SourceLocation SwitchLoc;
-
-  /// If the SwitchStmt is a switch on an enum value, this records whether
-  /// all the enum values were covered by CaseStmts.  This value is meant to
-  /// be a hint for possible clients.
-  unsigned AllEnumCasesCovered : 1;
+  // This points to a linked list of case and default statements and, if the
+  // SwitchStmt is a switch on an enum value, records whether all the enum
+  // values were covered by CaseStmts.  The coverage information value is meant
+  // to be a hint for possible clients.
+  llvm::PointerIntPair<SwitchCase *, 1, bool> FirstCase;
 
 public:
   SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond);
@@ -980,16 +986,16 @@ public:
 
   const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
   const Stmt *getBody() const { return SubExprs[BODY]; }
-  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
+  const SwitchCase *getSwitchCaseList() const { return FirstCase.getPointer(); }
 
   Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
   void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
   Stmt *getBody() { return SubExprs[BODY]; }
   void setBody(Stmt *S) { SubExprs[BODY] = S; }
-  SwitchCase *getSwitchCaseList() { return FirstCase; }
+  SwitchCase *getSwitchCaseList() { return FirstCase.getPointer(); }
 
   /// \brief Set the case list for this switch statement.
-  void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
+  void setSwitchCaseList(SwitchCase *SC) { FirstCase.setPointer(SC); }
 
   SourceLocation getSwitchLoc() const { return SwitchLoc; }
   void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
@@ -1001,21 +1007,17 @@ public:
   void addSwitchCase(SwitchCase *SC) {
     assert(!SC->getNextSwitchCase()
            && "case/default already added to a switch");
-    SC->setNextSwitchCase(FirstCase);
-    FirstCase = SC;
+    SC->setNextSwitchCase(FirstCase.getPointer());
+    FirstCase.setPointer(SC);
   }
 
   /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a
   /// switch over an enum value then all cases have been explicitly covered.
-  void setAllEnumCasesCovered() {
-    AllEnumCasesCovered = 1;
-  }
+  void setAllEnumCasesCovered() { FirstCase.setInt(true); }
 
   /// Returns true if the SwitchStmt is a switch of an enum value and all cases
   /// have been explicitly covered.
-  bool isAllEnumCasesCovered() const {
-    return (bool) AllEnumCasesCovered;
-  }
+  bool isAllEnumCasesCovered() const { return FirstCase.getInt(); }
 
   SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; }
   SourceLocation getLocEnd() const LLVM_READONLY {
@@ -1036,9 +1038,9 @@ public:
 /// WhileStmt - This represents a 'while' stmt.
 ///
 class WhileStmt : public Stmt {
+  SourceLocation WhileLoc;
   enum { VAR, COND, BODY, END_EXPR };
   Stmt* SubExprs[END_EXPR];
-  SourceLocation WhileLoc;
 public:
   WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
             SourceLocation WL);
@@ -1091,9 +1093,9 @@ public:
 /// DoStmt - This represents a 'do/while' stmt.
 ///
 class DoStmt : public Stmt {
+  SourceLocation DoLoc;
   enum { BODY, COND, END_EXPR };
   Stmt* SubExprs[END_EXPR];
-  SourceLocation DoLoc;
   SourceLocation WhileLoc;
   SourceLocation RParenLoc;  // Location of final ')' in do stmt condition.
 
@@ -1142,9 +1144,9 @@ public:
 /// specified in the source.
 ///
 class ForStmt : public Stmt {
+  SourceLocation ForLoc;
   enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
   Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
-  SourceLocation ForLoc;
   SourceLocation LParenLoc, RParenLoc;
 
 public:
@@ -1345,18 +1347,16 @@ public:
 /// depend on the return type of the function and the presence of an argument.
 ///
 class ReturnStmt : public Stmt {
-  Stmt *RetExpr;
   SourceLocation RetLoc;
+  Stmt *RetExpr;
   const VarDecl *NRVOCandidate;
 
 public:
-  ReturnStmt(SourceLocation RL)
-    : Stmt(ReturnStmtClass), RetExpr(nullptr), RetLoc(RL),
-      NRVOCandidate(nullptr) {}
+  explicit ReturnStmt(SourceLocation RL) : ReturnStmt(RL, nullptr, nullptr) {}
 
   ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
-    : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL),
-      NRVOCandidate(NRVOCandidate) {}
+      : Stmt(ReturnStmtClass), RetLoc(RL), RetExpr((Stmt *)E),
+        NRVOCandidate(NRVOCandidate) {}
 
   /// \brief Build an empty return expression.
   explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }

Modified: cfe/trunk/include/clang/AST/StmtCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtCXX.h?rev=233921&r1=233920&r2=233921&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtCXX.h (original)
+++ cfe/trunk/include/clang/AST/StmtCXX.h Thu Apr  2 10:29:07 2015
@@ -126,11 +126,11 @@ public:
 /// analysis of the constituent components. The original syntactic components
 /// can be extracted using getLoopVariable and getRangeInit.
 class CXXForRangeStmt : public Stmt {
+  SourceLocation ForLoc;
   enum { RANGE, BEGINEND, 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 ColonLoc;
   SourceLocation RParenLoc;
 public:

Modified: cfe/trunk/include/clang/AST/StmtObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtObjC.h?rev=233921&r1=233920&r2=233921&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtObjC.h (original)
+++ cfe/trunk/include/clang/AST/StmtObjC.h Thu Apr  2 10:29:07 2015
@@ -118,12 +118,13 @@ public:
 
 /// \brief Represents Objective-C's \@finally statement
 class ObjCAtFinallyStmt : public Stmt {
-  Stmt *AtFinallyStmt;
   SourceLocation AtFinallyLoc;
+  Stmt *AtFinallyStmt;
+
 public:
   ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
-  : Stmt(ObjCAtFinallyStmtClass),
-    AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
+      : Stmt(ObjCAtFinallyStmtClass), AtFinallyLoc(atFinallyLoc),
+        AtFinallyStmt(atFinallyStmt) {}
 
   explicit ObjCAtFinallyStmt(EmptyShell Empty) :
     Stmt(ObjCAtFinallyStmtClass, Empty) { }
@@ -260,9 +261,9 @@ public:
 /// \endcode
 class ObjCAtSynchronizedStmt : public Stmt {
 private:
+  SourceLocation AtSynchronizedLoc;
   enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
   Stmt* SubStmts[END_EXPR];
-  SourceLocation AtSynchronizedLoc;
 
 public:
   ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
@@ -310,8 +311,9 @@ public:
 
 /// \brief Represents Objective-C's \@throw statement.
 class ObjCAtThrowStmt : public Stmt {
-  Stmt *Throw;
   SourceLocation AtThrowLoc;
+  Stmt *Throw;
+
 public:
   ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
   : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
@@ -341,13 +343,12 @@ public:
 
 /// \brief Represents Objective-C's \@autoreleasepool Statement
 class ObjCAutoreleasePoolStmt : public Stmt {
-  Stmt *SubStmt;
   SourceLocation AtLoc;
+  Stmt *SubStmt;
+
 public:
-  ObjCAutoreleasePoolStmt(SourceLocation atLoc, 
-                            Stmt *subStmt)
-  : Stmt(ObjCAutoreleasePoolStmtClass),
-    SubStmt(subStmt), AtLoc(atLoc) {}
+  ObjCAutoreleasePoolStmt(SourceLocation atLoc, Stmt *subStmt)
+      : Stmt(ObjCAutoreleasePoolStmtClass), AtLoc(atLoc), SubStmt(subStmt) {}
 
   explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) :
     Stmt(ObjCAutoreleasePoolStmtClass, Empty) { }

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=233921&r1=233920&r2=233921&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Thu Apr  2 10:29:07 2015
@@ -940,8 +940,7 @@ void ForStmt::setConditionVariable(const
 }
 
 SwitchStmt::SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond)
-  : Stmt(SwitchStmtClass), FirstCase(nullptr), AllEnumCasesCovered(0)
-{
+    : Stmt(SwitchStmtClass), FirstCase(nullptr, false) {
   setConditionVariable(C, Var);
   SubExprs[COND] = cond;
   SubExprs[BODY] = nullptr;





More information about the cfe-commits mailing list