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