diff options
author | Amy Huang <akhuang@google.com> | 2022-11-07 15:29:27 -0800 |
---|---|---|
committer | Amy Huang <akhuang@google.com> | 2023-06-20 17:30:20 -0700 |
commit | 015049338d7e8e0e81f2ad2f94e5a43e2e3f5220 (patch) | |
tree | 962b29a46a879a9a95abe06bf15a7887ed2c8fa1 /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | 72df12cce226e1ed47e9dbd6e2fc461229947b85 (diff) | |
download | llvm-015049338d7e8e0e81f2ad2f94e5a43e2e3f5220.zip llvm-015049338d7e8e0e81f2ad2f94e5a43e2e3f5220.tar.gz llvm-015049338d7e8e0e81f2ad2f94e5a43e2e3f5220.tar.bz2 |
Try to implement lambdas with inalloca parameters by forwarding without use of inallocas.
Differential Revision: https://reviews.llvm.org/D137872
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index b8d3937..6899388 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -683,6 +683,19 @@ static bool matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx) { return true; } +bool CodeGenFunction::isInAllocaArgument(CGCXXABI &ABI, QualType Ty) { + const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); + return RD && ABI.getRecordArgABI(RD) == CGCXXABI::RAA_DirectInMemory; +} + +bool CodeGenFunction::hasInAllocaArg(const CXXMethodDecl *MD) { + return getTarget().getTriple().getArch() == llvm::Triple::x86 && + getTarget().getCXXABI().isMicrosoft() && + llvm::any_of(MD->parameters(), [&](ParmVarDecl *P) { + return isInAllocaArgument(CGM.getCXXABI(), P->getType()); + }); +} + /// Return the UBSan prologue signature for \p FD if one is available. static llvm::Constant *getPrologueSignature(CodeGenModule &CGM, const FunctionDecl *FD) { @@ -1447,6 +1460,17 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, // The lambda static invoker function is special, because it forwards or // clones the body of the function call operator (but is actually static). EmitLambdaStaticInvokeBody(cast<CXXMethodDecl>(FD)); + + } else if (isa<CXXMethodDecl>(FD) && + isLambdaCallOperator(cast<CXXMethodDecl>(FD)) && + cast<CXXMethodDecl>(FD)->getParent()->getLambdaStaticInvoker() && + hasInAllocaArg(cast<CXXMethodDecl>(FD) + ->getParent() + ->getLambdaStaticInvoker()) && + !FnInfo.isDelegateCall()) { + // If emitting a lambda with static invoker on X86 Windows, change + // the call operator body. + EmitLambdaInAllocaCallOpBody(cast<CXXMethodDecl>(FD)); } else if (FD->isDefaulted() && isa<CXXMethodDecl>(FD) && (cast<CXXMethodDecl>(FD)->isCopyAssignmentOperator() || cast<CXXMethodDecl>(FD)->isMoveAssignmentOperator())) { |