riccibruno created this revision.
riccibruno added a reviewer: rjmccall.
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 `CallExpr`. This saves 8 bytes per `CallExpr`. This is a
straightforward
patch, except that it limits the maximum number of arguments to `2^14 - 1`.
The maximum number of arguments to a function call is already
limited to 16 bits because of `FunctionTypeBitfields::NumParams`,
which used to be 15 bits until a few month ago.
This also do not leave any space for additional bits, but after looking at
the history of `CallExpr` it seems that people are not adding data
here very frequently.
It would be possible to reuse some bits of the `SubExprs` pointer, but ideally
this pointer would be removed by storing the arguments in a trailing array.
Alternatively it would be possible to store the number of arguments in a
trailing object when it is too large.
Repository:
rC Clang
https://reviews.llvm.org/D54676
Files:
include/clang/AST/Expr.h
include/clang/AST/Stmt.h
lib/AST/Expr.cpp
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
@@ -422,6 +422,9 @@
unsigned : NumExprBits;
unsigned NumPreArgs : 1;
+ unsigned NumArgs : 14;
+
+ SourceLocation RParenLoc;
};
class MemberExprBitfields {
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h
+++ include/clang/AST/Expr.h
@@ -2405,8 +2405,6 @@
class CallExpr : public Expr {
enum { FN=0, PREARGS_START=1 };
Stmt **SubExprs;
- unsigned NumArgs;
- SourceLocation RParenLoc;
void updateDependenciesFromArg(Expr *Arg);
@@ -2458,8 +2456,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() {
@@ -2472,17 +2469,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;
}
@@ -2523,7 +2520,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.
@@ -2538,8 +2535,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;
@@ -2561,12 +2558,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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits