From fb2cf74ebc2b776c004cc6a0d3e9fc90b4fb4dd4 Mon Sep 17 00:00:00 2001 From: Dario Rexin Date: Thu, 6 Jun 2024 13:53:15 -0700 Subject: [PATCH] [CodeGen] Add typed error logic to SwiftAggLowering rdar://129359321 Adds SwiftAggLowerign::shouldReturnTypedErrorIndirectly, which checks if a typed error can be returned directly, similar to how shouldPassIndirectly works, but with the additional restriction of the type having to consist of only integers. --- .../include/clang/CodeGen/SwiftCallingConv.h | 2 ++ clang/lib/CodeGen/ABIInfo.cpp | 9 ++++++++ clang/lib/CodeGen/ABIInfo.h | 3 +++ clang/lib/CodeGen/SwiftCallingConv.cpp | 21 +++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/clang/include/clang/CodeGen/SwiftCallingConv.h b/clang/include/clang/CodeGen/SwiftCallingConv.h index d7a0c84699ab0..806c3f13ffe62 100644 --- a/clang/include/clang/CodeGen/SwiftCallingConv.h +++ b/clang/include/clang/CodeGen/SwiftCallingConv.h @@ -88,6 +88,8 @@ class SwiftAggLowering { /// passed indirectly as an argument bool shouldPassIndirectly(bool asReturnValue) const; + bool shouldReturnTypedErrorIndirectly() const; + using EnumerationCallback = llvm::function_ref; diff --git a/clang/lib/CodeGen/ABIInfo.cpp b/clang/lib/CodeGen/ABIInfo.cpp index edd7146dc1ac7..d2f82644ddeb2 100644 --- a/clang/lib/CodeGen/ABIInfo.cpp +++ b/clang/lib/CodeGen/ABIInfo.cpp @@ -275,6 +275,15 @@ bool SwiftABIInfo::shouldPassIndirectly(ArrayRef ComponentTys, return occupiesMoreThan(ComponentTys, /*total=*/4); } +bool SwiftABIInfo::shouldReturnTypedErrorIndirectly( + ArrayRef ComponentTys) const { + for (llvm::Type *type : ComponentTys) { + if (!type->isIntegerTy() && !type->isPointerTy()) + return true; + } + return shouldPassIndirectly(ComponentTys, /*AsReturnValue=*/true); +} + bool SwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy, unsigned NumElts) const { // The default implementation of this assumes that the target guarantees diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h index b8a8de57e5b97..25655e1bf14d3 100644 --- a/clang/lib/CodeGen/ABIInfo.h +++ b/clang/lib/CodeGen/ABIInfo.h @@ -153,6 +153,9 @@ class SwiftABIInfo { /// Returns true if swifterror is lowered to a register by the target ABI. bool isSwiftErrorInRegister() const { return SwiftErrorInRegister; }; + + virtual bool + shouldReturnTypedErrorIndirectly(ArrayRef ComponentTys) const; }; } // end namespace CodeGen } // end namespace clang diff --git a/clang/lib/CodeGen/SwiftCallingConv.cpp b/clang/lib/CodeGen/SwiftCallingConv.cpp index ab2e2bd0b3064..21578d3eeb401 100644 --- a/clang/lib/CodeGen/SwiftCallingConv.cpp +++ b/clang/lib/CodeGen/SwiftCallingConv.cpp @@ -644,6 +644,27 @@ bool SwiftAggLowering::shouldPassIndirectly(bool asReturnValue) const { return getSwiftABIInfo(CGM).shouldPassIndirectly(componentTys, asReturnValue); } +bool SwiftAggLowering::shouldReturnTypedErrorIndirectly() const { + assert(Finished && "haven't yet finished lowering"); + + // Empty types don't need to be passed indirectly. + if (Entries.empty()) + return false; + + // Avoid copying the array of types when there's just a single element. + if (Entries.size() == 1) { + return getSwiftABIInfo(CGM).shouldReturnTypedErrorIndirectly( + Entries.back().Type); + } + + SmallVector componentTys; + componentTys.reserve(Entries.size()); + for (auto &entry : Entries) { + componentTys.push_back(entry.Type); + } + return getSwiftABIInfo(CGM).shouldReturnTypedErrorIndirectly(componentTys); +} + bool swiftcall::shouldPassIndirectly(CodeGenModule &CGM, ArrayRef componentTys, bool asReturnValue) {