riccibruno created this revision.
riccibruno added a reviewer: rsmith.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

Use the newly available space in the bit-fields of `Stmt`
to store some data from `ArraySubscriptExpr` and `CallExpr`.
This saves a pointer for each of them (which is a lot given
how frequently `CallExpr` is used).

Additionally for `ArraySubscriptExpr` store a bit indicating
whether the LHS is the base of the array subscript expression,
instead of checking if the type of the RHS is an integer type during
each access. This removes an indirection during each access.


Repository:
  rC Clang

https://reviews.llvm.org/D54172

Files:
  include/clang/AST/Expr.h
  include/clang/AST/Stmt.h
  lib/AST/Expr.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp

Index: lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -638,6 +638,7 @@
   VisitExpr(E);
   Record.AddStmt(E->getLHS());
   Record.AddStmt(E->getRHS());
+  Record.push_back(E->lhsIsBase());
   Record.AddSourceLocation(E->getRBracketLoc());
   Code = serialization::EXPR_ARRAY_SUBSCRIPT;
 }
Index: lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -725,6 +725,7 @@
   VisitExpr(E);
   E->setLHS(Record.readSubExpr());
   E->setRHS(Record.readSubExpr());
+  E->setLhsIsBase(Record.readInt());
   E->setRBracketLoc(ReadSourceLocation());
 }
 
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -1225,23 +1225,26 @@
                    ExprValueKind VK, SourceLocation rparenloc)
     : Expr(SC, t, VK, OK_Ordinary, fn->isTypeDependent(),
            fn->isValueDependent(), fn->isInstantiationDependent(),
-           fn->containsUnexpandedParameterPack()),
-      NumArgs(args.size()) {
+           fn->containsUnexpandedParameterPack()) {
+  unsigned NumArgs = args.size();
+  CallExprBits.NumArgs = NumArgs;
+  assert((getNumArgs() == NumArgs) && "NumArgs overflow!");
 
   unsigned NumPreArgs = preargs.size();
-  SubExprs = new (C) Stmt *[args.size()+PREARGS_START+NumPreArgs];
+  CallExprBits.NumPreArgs = NumPreArgs;
+
+  SubExprs = new (C) Stmt *[NumArgs+PREARGS_START+NumPreArgs];
   SubExprs[FN] = fn;
   for (unsigned i = 0; i != NumPreArgs; ++i) {
     updateDependenciesFromArg(preargs[i]);
     SubExprs[i+PREARGS_START] = preargs[i];
   }
-  for (unsigned i = 0; i != args.size(); ++i) {
+  for (unsigned i = 0; i != NumArgs; ++i) {
     updateDependenciesFromArg(args[i]);
     SubExprs[i+PREARGS_START+NumPreArgs] = args[i];
   }
 
-  CallExprBits.NumPreArgs = NumPreArgs;
-  RParenLoc = rparenloc;
+  setRParenLoc(rparenloc);
 }
 
 CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
@@ -1259,7 +1262,8 @@
 
 CallExpr::CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
                    EmptyShell Empty)
-  : Expr(SC, Empty), SubExprs(nullptr), NumArgs(0) {
+  : Expr(SC, Empty), SubExprs(nullptr) {
+  CallExprBits.NumArgs = 0;
   // FIXME: Why do we allocate this?
   SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs]();
   CallExprBits.NumPreArgs = NumPreArgs;
@@ -1317,7 +1321,7 @@
 
   // If shrinking # arguments, just delete the extras and forgot them.
   if (NumArgs < getNumArgs()) {
-    this->NumArgs = NumArgs;
+    CallExprBits.NumArgs = NumArgs;
     return;
   }
 
@@ -1334,7 +1338,7 @@
 
   if (SubExprs) C.Deallocate(SubExprs);
   SubExprs = NewSubExprs;
-  this->NumArgs = NumArgs;
+  CallExprBits.NumArgs = NumArgs;
 }
 
 /// getBuiltinCallee - If this is a call to a builtin, return the builtin ID. If
Index: include/clang/AST/Stmt.h
===================================================================
--- include/clang/AST/Stmt.h
+++ include/clang/AST/Stmt.h
@@ -395,6 +395,22 @@
     unsigned IsType : 1; // true if operand is a type, false if an expression.
   };
 
+  class ArraySubscriptExprBitfields {
+    friend class ArraySubscriptExpr;
+    friend class ASTStmtReader;
+
+    unsigned : NumExprBits;
+
+    /// True if the expression is of the form A[4], that is
+    /// getLHS() == getBase(). False if the the expression is of the
+    /// form 4[A], that is getRHS() == getBase(). See the comment
+    /// above ArraySubscriptExpr::lhsIsBase.
+    unsigned LhsIsBase : 1;
+
+    /// The location of the right bracket.
+    SourceLocation RBracketLoc;
+  };
+
   class DeclRefExprBitfields {
     friend class ASTStmtReader; // deserialization
     friend class DeclRefExpr;
@@ -431,6 +447,9 @@
     unsigned : NumExprBits;
 
     unsigned NumPreArgs : 1;
+    unsigned NumArgs : 14;
+
+    SourceLocation RParenLoc;
   };
 
   class MemberExprBitfields {
@@ -590,6 +609,7 @@
     CharacterLiteralBitfields CharacterLiteralBits;
     FloatingLiteralBitfields FloatingLiteralBits;
     UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits;
+    ArraySubscriptExprBitfields ArraySubscriptExprBits;
     DeclRefExprBitfields DeclRefExprBits;
     UnaryOperatorBitfields UnaryOperatorBits;
     CallExprBitfields CallExprBits;
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h
+++ include/clang/AST/Expr.h
@@ -2311,28 +2311,32 @@
 
 /// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
 class ArraySubscriptExpr : public Expr {
-  enum { LHS, RHS, END_EXPR=2 };
-  Stmt* SubExprs[END_EXPR];
-  SourceLocation RBracketLoc;
+  friend class ASTStmtReader;
+
+  enum { LHS, RHS, END_EXPR };
+  Stmt *SubExprs[END_EXPR];
+
+  void setLhsIsBase(bool B) { ArraySubscriptExprBits.LhsIsBase = B; }
+
 public:
-  ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t,
-                     ExprValueKind VK, ExprObjectKind OK,
-                     SourceLocation rbracketloc)
-  : Expr(ArraySubscriptExprClass, t, VK, OK,
-         lhs->isTypeDependent() || rhs->isTypeDependent(),
-         lhs->isValueDependent() || rhs->isValueDependent(),
-         (lhs->isInstantiationDependent() ||
-          rhs->isInstantiationDependent()),
-         (lhs->containsUnexpandedParameterPack() ||
-          rhs->containsUnexpandedParameterPack())),
-    RBracketLoc(rbracketloc) {
-    SubExprs[LHS] = lhs;
-    SubExprs[RHS] = rhs;
+  ArraySubscriptExpr(Expr *Lhs, Expr *Rhs, QualType Ty, ExprValueKind VK,
+                     ExprObjectKind OK, SourceLocation RBracketLoc)
+      : Expr(ArraySubscriptExprClass, Ty, VK, OK,
+             Lhs->isTypeDependent() || Rhs->isTypeDependent(),
+             Lhs->isValueDependent() || Rhs->isValueDependent(),
+             (Lhs->isInstantiationDependent() ||
+              Rhs->isInstantiationDependent()),
+             (Lhs->containsUnexpandedParameterPack() ||
+              Rhs->containsUnexpandedParameterPack())) {
+    setLHS(Lhs);
+    setRHS(Rhs);
+    setLhsIsBase(Rhs->getType()->isIntegerType());
+    setRBracketLoc(RBracketLoc);
   }
 
   /// Create an empty array subscript expression.
   explicit ArraySubscriptExpr(EmptyShell Shell)
-    : Expr(ArraySubscriptExprClass, Shell) { }
+      : Expr(ArraySubscriptExprClass, Shell) {}
 
   /// An array access can be written A[4] or 4[A] (both are equivalent).
   /// - getBase() and getIdx() always present the normalized view: A[4].
@@ -2343,37 +2347,33 @@
   /// predicate the format conversion in getBase and getIdx only on the
   /// the type of the RHS, as it is possible for the LHS to be a vector of
   /// integer type
+  bool lhsIsBase() const { return ArraySubscriptExprBits.LhsIsBase; }
+
   Expr *getLHS() { return cast<Expr>(SubExprs[LHS]); }
   const Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
   void setLHS(Expr *E) { SubExprs[LHS] = E; }
 
   Expr *getRHS() { return cast<Expr>(SubExprs[RHS]); }
   const Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
   void setRHS(Expr *E) { SubExprs[RHS] = E; }
 
-  Expr *getBase() {
-    return getRHS()->getType()->isIntegerType() ? getLHS() : getRHS();
-  }
-
-  const Expr *getBase() const {
-    return getRHS()->getType()->isIntegerType() ? getLHS() : getRHS();
-  }
-
-  Expr *getIdx() {
-    return getRHS()->getType()->isIntegerType() ? getRHS() : getLHS();
-  }
+  Expr *getBase() { return lhsIsBase() ? getLHS() : getRHS(); }
+  const Expr *getBase() const { return lhsIsBase() ? getLHS() : getRHS(); }
 
-  const Expr *getIdx() const {
-    return getRHS()->getType()->isIntegerType() ? getRHS() : getLHS();
-  }
+  Expr *getIdx() { return lhsIsBase() ? getRHS() : getLHS(); }
+  const Expr *getIdx() const { return lhsIsBase() ? getRHS() : getLHS(); }
 
   SourceLocation getBeginLoc() const LLVM_READONLY {
     return getLHS()->getBeginLoc();
   }
-  SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
+  SourceLocation getEndLoc() const { return getRBracketLoc(); }
 
-  SourceLocation getRBracketLoc() const { return RBracketLoc; }
-  void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
+  SourceLocation getRBracketLoc() const {
+    return ArraySubscriptExprBits.RBracketLoc;
+  }
+  void setRBracketLoc(SourceLocation L) {
+    ArraySubscriptExprBits.RBracketLoc = L;
+  }
 
   SourceLocation getExprLoc() const LLVM_READONLY {
     return getBase()->getExprLoc();
@@ -2385,7 +2385,7 @@
 
   // Iterators
   child_range children() {
-    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+    return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
   }
   const_child_range children() const {
     return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
@@ -2401,8 +2401,6 @@
 class CallExpr : public Expr {
   enum { FN=0, PREARGS_START=1 };
   Stmt **SubExprs;
-  unsigned NumArgs;
-  SourceLocation RParenLoc;
 
   void updateDependenciesFromArg(Expr *Arg);
 
@@ -2454,8 +2452,7 @@
   }
 
   /// getNumArgs - Return the number of actual arguments to this call.
-  ///
-  unsigned getNumArgs() const { return NumArgs; }
+  unsigned getNumArgs() const { return CallExprBits.NumArgs; }
 
   /// Retrieve the call arguments.
   Expr **getArgs() {
@@ -2468,17 +2465,17 @@
 
   /// getArg - Return the specified argument.
   Expr *getArg(unsigned Arg) {
-    assert(Arg < NumArgs && "Arg access out of range!");
+    assert(Arg < getNumArgs() && "Arg access out of range!");
     return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
   }
   const Expr *getArg(unsigned Arg) const {
-    assert(Arg < NumArgs && "Arg access out of range!");
+    assert(Arg < getNumArgs() && "Arg access out of range!");
     return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
   }
 
   /// setArg - Set the specified argument.
   void setArg(unsigned Arg, Expr *ArgExpr) {
-    assert(Arg < NumArgs && "Arg access out of range!");
+    assert(Arg < getNumArgs() && "Arg access out of range!");
     SubExprs[Arg+getNumPreArgs()+PREARGS_START] = ArgExpr;
   }
 
@@ -2519,7 +2516,7 @@
 
   /// getNumCommas - Return the number of commas that must have been present in
   /// this function call.
-  unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
+  unsigned getNumCommas() const { return getNumArgs() ? getNumArgs() - 1 : 0; }
 
   /// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
   /// of the callee. If not, return 0.
@@ -2534,8 +2531,8 @@
   /// type.
   QualType getCallReturnType(const ASTContext &Ctx) const;
 
-  SourceLocation getRParenLoc() const { return RParenLoc; }
-  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+  SourceLocation getRParenLoc() const { return CallExprBits.RParenLoc; }
+  void setRParenLoc(SourceLocation L) { CallExprBits.RParenLoc = L; }
 
   SourceLocation getBeginLoc() const LLVM_READONLY;
   SourceLocation getEndLoc() const LLVM_READONLY;
@@ -2557,12 +2554,12 @@
 
   // Iterators
   child_range children() {
-    return child_range(&SubExprs[0],
-                       &SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START);
+    return child_range(&SubExprs[0], &SubExprs[0] + getNumArgs() +
+                                         getNumPreArgs() + PREARGS_START);
   }
 
   const_child_range children() const {
-    return const_child_range(&SubExprs[0], &SubExprs[0] + NumArgs +
+    return const_child_range(&SubExprs[0], &SubExprs[0] + getNumArgs() +
                                                getNumPreArgs() + PREARGS_START);
   }
 };
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D54172: [AST] Pack Arr... Bruno Ricci via Phabricator via cfe-commits

Reply via email to