From 9f569d45e0e42bcf60fe8f43b847a133a1a38c12 Mon Sep 17 00:00:00 2001 From: Bruno Ricci Date: Fri, 21 Dec 2018 15:20:32 +0000 Subject: [AST] Store the callee and argument expressions of CallExpr in a trailing array. Since CallExpr::setNumArgs has been removed, it is now possible to store the callee expression and the argument expressions of CallExpr in a trailing array. This saves one pointer per CallExpr, CXXOperatorCallExpr, CXXMemberCallExpr, CUDAKernelCallExpr and UserDefinedLiteral. Given that CallExpr is used as a base of the above classes we cannot use llvm::TrailingObjects. Instead we store the offset in bytes from the this pointer to the start of the trailing objects and manually do the casts + arithmetic. Some notes: 1.) I did not try to fit the number of arguments in the bit-fields of Stmt. This leaves some space for future additions and avoid the discussion about whether x bits are sufficient to hold the number of arguments. 2.) It would be perfectly possible to recompute the offset to the trailing objects before accessing the trailing objects. However the trailing objects are frequently accessed and benchmarks show that it is slightly faster to just load the offset from the bit-fields. Additionally, because of 1), we have plenty of space in the bit-fields of Stmt. Differential Revision: https://reviews.llvm.org/D55771 Reviewed By: rjmccall git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349910 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaOverload.cpp | 114 ++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 60 deletions(-) (limited to 'lib/Sema/SemaOverload.cpp') diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index d829194364..94f7979f66 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -7003,13 +7003,17 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, // there are 0 arguments (i.e., nothing is allocated using ASTContext's // allocator). QualType CallResultType = ConversionType.getNonLValueExprType(Context); - CallExpr Call(Context, &ConversionFn, None, CallResultType, VK, - From->getBeginLoc()); + + llvm::AlignedCharArray + Buffer; + CallExpr *TheTemporaryCall = CallExpr::CreateTemporary( + Buffer.buffer, &ConversionFn, CallResultType, VK, From->getBeginLoc()); + ImplicitConversionSequence ICS = - TryCopyInitialization(*this, &Call, ToType, - /*SuppressUserConversions=*/true, - /*InOverloadResolution=*/false, - /*AllowObjCWritebackConversion=*/false); + TryCopyInitialization(*this, TheTemporaryCall, ToType, + /*SuppressUserConversions=*/true, + /*InOverloadResolution=*/false, + /*AllowObjCWritebackConversion=*/false); switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: @@ -11988,12 +11992,12 @@ bool Sema::buildOverloadedCallSet(Scope *S, Expr *Fn, if (CandidateSet->empty() || CandidateSet->BestViableFunction(*this, Fn->getBeginLoc(), Best) == OR_No_Viable_Function) { - // In Microsoft mode, if we are inside a template class member function then - // create a type dependent CallExpr. The goal is to postpone name lookup - // to instantiation time to be able to search into type dependent base - // classes. - CallExpr *CE = new (Context) CallExpr( - Context, Fn, Args, Context.DependentTy, VK_RValue, RParenLoc); + // In Microsoft mode, if we are inside a template class member function + // then create a type dependent CallExpr. The goal is to postpone name + // lookup to instantiation time to be able to search into type dependent + // base classes. + CallExpr *CE = CallExpr::Create(Context, Fn, Args, Context.DependentTy, + VK_RValue, RParenLoc); CE->setTypeDependent(true); CE->setValueDependent(true); CE->setInstantiationDependent(true); @@ -12199,14 +12203,12 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, VK_RValue, OK_Ordinary, OpLoc, false); CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators - UnresolvedLookupExpr *Fn - = UnresolvedLookupExpr::Create(Context, NamingClass, - NestedNameSpecifierLoc(), OpNameInfo, - /*ADL*/ true, IsOverloaded(Fns), - Fns.begin(), Fns.end()); - return new (Context) - CXXOperatorCallExpr(Context, Op, Fn, ArgsArray, Context.DependentTy, - VK_RValue, OpLoc, FPOptions()); + UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create( + Context, NamingClass, NestedNameSpecifierLoc(), OpNameInfo, + /*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end()); + return CXXOperatorCallExpr::Create(Context, Op, Fn, ArgsArray, + Context.DependentTy, VK_RValue, OpLoc, + FPOptions()); } // Build an empty overload set. @@ -12278,9 +12280,9 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, ResultTy = ResultTy.getNonLValueExprType(Context); Args[0] = Input; - CallExpr *TheCall = new (Context) - CXXOperatorCallExpr(Context, Op, FnExpr.get(), ArgsArray, ResultTy, - VK, OpLoc, FPOptions(), Best->IsADLCandidate); + CallExpr *TheCall = CXXOperatorCallExpr::Create( + Context, Op, FnExpr.get(), ArgsArray, ResultTy, VK, OpLoc, + FPOptions(), Best->IsADLCandidate); if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) return ExprError(); @@ -12390,14 +12392,12 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators // TODO: provide better source location info in DNLoc component. DeclarationNameInfo OpNameInfo(OpName, OpLoc); - UnresolvedLookupExpr *Fn - = UnresolvedLookupExpr::Create(Context, NamingClass, - NestedNameSpecifierLoc(), OpNameInfo, - /*ADL*/PerformADL, IsOverloaded(Fns), - Fns.begin(), Fns.end()); - return new (Context) - CXXOperatorCallExpr(Context, Op, Fn, Args, Context.DependentTy, - VK_RValue, OpLoc, FPFeatures); + UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create( + Context, NamingClass, NestedNameSpecifierLoc(), OpNameInfo, + /*ADL*/ PerformADL, IsOverloaded(Fns), Fns.begin(), Fns.end()); + return CXXOperatorCallExpr::Create(Context, Op, Fn, Args, + Context.DependentTy, VK_RValue, OpLoc, + FPFeatures); } // Always do placeholder-like conversions on the RHS. @@ -12510,9 +12510,9 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); - CXXOperatorCallExpr *TheCall = new (Context) - CXXOperatorCallExpr(Context, Op, FnExpr.get(), Args, ResultTy, VK, - OpLoc, FPFeatures, Best->IsADLCandidate); + CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( + Context, Op, FnExpr.get(), Args, ResultTy, VK, OpLoc, FPFeatures, + Best->IsADLCandidate); if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) @@ -12658,9 +12658,9 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, UnresolvedSetIterator()); // Can't add any actual overloads yet - return new (Context) - CXXOperatorCallExpr(Context, OO_Subscript, Fn, Args, - Context.DependentTy, VK_RValue, RLoc, FPOptions()); + return CXXOperatorCallExpr::Create(Context, OO_Subscript, Fn, Args, + Context.DependentTy, VK_RValue, RLoc, + FPOptions()); } // Handle placeholders on both operands. @@ -12734,10 +12734,8 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = - new (Context) CXXOperatorCallExpr(Context, OO_Subscript, - FnExpr.get(), Args, - ResultTy, VK, RLoc, - FPOptions()); + CXXOperatorCallExpr::Create(Context, OO_Subscript, FnExpr.get(), + Args, ResultTy, VK, RLoc, FPOptions()); if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl)) return ExprError(); @@ -12857,10 +12855,9 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, << (qualsString.find(' ') == std::string::npos ? 1 : 2); } - CXXMemberCallExpr *call - = new (Context) CXXMemberCallExpr(Context, MemExprE, Args, - resultType, valueKind, RParenLoc, - proto->getNumParams()); + CXXMemberCallExpr *call = + CXXMemberCallExpr::Create(Context, MemExprE, Args, resultType, + valueKind, RParenLoc, proto->getNumParams()); if (CheckCallReturnType(proto->getReturnType(), op->getRHS()->getBeginLoc(), call, nullptr)) @@ -12876,8 +12873,8 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, } if (isa(NakedMemExpr)) - return new (Context) - CallExpr(Context, MemExprE, Args, Context.VoidTy, VK_RValue, RParenLoc); + return CallExpr::Create(Context, MemExprE, Args, Context.VoidTy, VK_RValue, + RParenLoc); UnbridgedCastsSet UnbridgedCasts; if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts)) @@ -13012,9 +13009,8 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, assert(Method && "Member call to something that isn't a method?"); const auto *Proto = Method->getType()->getAs(); CXXMemberCallExpr *TheCall = - new (Context) CXXMemberCallExpr(Context, MemExprE, Args, - ResultType, VK, RParenLoc, - Proto->getNumParams()); + CXXMemberCallExpr::Create(Context, MemExprE, Args, ResultType, VK, + RParenLoc, Proto->getNumParams()); // Check for a valid return type. if (CheckCallReturnType(Method->getReturnType(), MemExpr->getMemberLoc(), @@ -13353,9 +13349,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); - CXXOperatorCallExpr *TheCall = new (Context) - CXXOperatorCallExpr(Context, OO_Call, NewFn.get(), MethodArgs, ResultTy, - VK, RParenLoc, FPOptions()); + CXXOperatorCallExpr *TheCall = + CXXOperatorCallExpr::Create(Context, OO_Call, NewFn.get(), MethodArgs, + ResultTy, VK, RParenLoc, FPOptions()); if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method)) return true; @@ -13471,9 +13467,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, QualType ResultTy = Method->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); - CXXOperatorCallExpr *TheCall = - new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.get(), - Base, ResultTy, VK, OpLoc, FPOptions()); + CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( + Context, OO_Arrow, FnExpr.get(), Base, ResultTy, VK, OpLoc, FPOptions()); if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method)) return ExprError(); @@ -13545,10 +13540,9 @@ ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R, ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); - UserDefinedLiteral *UDL = - new (Context) UserDefinedLiteral(Context, Fn.get(), - llvm::makeArrayRef(ConvArgs, Args.size()), - ResultTy, VK, LitEndLoc, UDSuffixLoc); + UserDefinedLiteral *UDL = UserDefinedLiteral::Create( + Context, Fn.get(), llvm::makeArrayRef(ConvArgs, Args.size()), ResultTy, + VK, LitEndLoc, UDSuffixLoc); if (CheckCallReturnType(FD->getReturnType(), UDSuffixLoc, UDL, FD)) return ExprError(); -- cgit v1.2.1