[clang] [CIR][NFC] Use arrangeFunctionDeclaration to build function types (PR #139787)
https://github.com/andykaylor closed https://github.com/llvm/llvm-project/pull/139787 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Use arrangeFunctionDeclaration to build function types (PR #139787)
https://github.com/erichkeane approved this pull request. WithExtraSlots is still kinda 'meh' for a name, but at least a bit better. WOuld love a better comment on them to just explain what is going on (like what non-formal arguments means/), but good enough for now. https://github.com/llvm/llvm-project/pull/139787 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Use arrangeFunctionDeclaration to build function types (PR #139787)
https://github.com/andykaylor updated
https://github.com/llvm/llvm-project/pull/139787
>From 4daf77880eb910d2d9b40f7a5782700195eed7c6 Mon Sep 17 00:00:00 2001
From: Andy Kaylor
Date: Thu, 8 May 2025 18:01:12 -0700
Subject: [PATCH 1/2] [CIR][NFC] Use arrangeFunctionDeclaration to build
function types
This change replaces the simplified call that we were previously using to
convert the function type provided by a global declaration to the CIR
function type. We now go through 'arrangeGlobalDeclaration' which builds
the function type in a more complicated manner. This change has no
observable differences for the currently upstreamed CIR support, but
it is necessary to prepare for C++ member function calls, which require
the extra handling.
---
clang/lib/CIR/CodeGen/CIRGenCall.cpp | 76 ++
clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h | 16 -
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 17 +
clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 14
clang/lib/CIR/CodeGen/CIRGenTypes.h| 32 -
5 files changed, 121 insertions(+), 34 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index 5c65a43641844..9ad048bf357cc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -44,14 +44,11 @@ CIRGenFunctionInfo::create(CanQualType resultType,
cir::FuncType CIRGenTypes::getFunctionType(const CIRGenFunctionInfo &fi) {
mlir::Type resultType = convertType(fi.getReturnType());
+ SmallVector argTypes;
+ argTypes.reserve(fi.getNumRequiredArgs());
- SmallVector argTypes(fi.getNumRequiredArgs());
-
- unsigned argNo = 0;
- llvm::ArrayRef argInfos(fi.argInfoBegin(),
- fi.getNumRequiredArgs());
- for (const auto &argInfo : argInfos)
-argTypes[argNo++] = convertType(argInfo.type);
+ for (const CIRGenFunctionInfoArgInfo &argInfo : fi.requiredArguments())
+argTypes.push_back(convertType(argInfo.type));
return cir::FuncType::get(argTypes,
(resultType ? resultType : builder.getVoidTy()),
@@ -63,6 +60,34 @@ CIRGenCallee
CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const {
return *this;
}
+/// Adds the formal parameters in FPT to the given prefix. If any parameter in
+/// FPT has pass_object_size_attrs, then we'll add parameters for those, too.
+/// TODO(cir): this should be shared with LLVM codegen
+static void appendParameterTypes(const CIRGenTypes &cgt,
+ SmallVectorImpl &prefix,
+ CanQual fpt) {
+ assert(!cir::MissingFeatures::opCallExtParameterInfo());
+ // Fast path: don't touch param info if we don't need to.
+ if (!fpt->hasExtParameterInfos()) {
+prefix.append(fpt->param_type_begin(), fpt->param_type_end());
+return;
+ }
+
+ cgt.getCGModule().errorNYI("appendParameterTypes: hasExtParameterInfos");
+}
+
+/// Arrange the CIR function layout for a value of the given function type, on
+/// top of any implicit parameters already stored.
+static const CIRGenFunctionInfo &
+arrangeCIRFunctionInfo(CIRGenTypes &cgt, SmallVectorImpl &prefix,
+ CanQual ftp) {
+ RequiredArgs required = RequiredArgs::forPrototypePlus(ftp, prefix.size());
+ assert(!cir::MissingFeatures::opCallExtParameterInfo());
+ appendParameterTypes(cgt, prefix, ftp);
+ CanQualType resultType = ftp->getReturnType().getUnqualifiedType();
+ return cgt.arrangeCIRFunctionInfo(resultType, prefix, required);
+}
+
static const CIRGenFunctionInfo &
arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm,
const CallArgList &args,
@@ -95,6 +120,34 @@ CIRGenTypes::arrangeFreeFunctionCall(const CallArgList
&args,
return arrangeFreeFunctionLikeCall(*this, cgm, args, fnType);
}
+/// Arrange the argument and result information for the declaration or
+/// definition of the given function.
+const CIRGenFunctionInfo &
+CIRGenTypes::arrangeFunctionDeclaration(const FunctionDecl *fd) {
+ if (const auto *md = dyn_cast(fd)) {
+if (md->isInstance()) {
+ cgm.errorNYI("arrangeFunctionDeclaration: instance method");
+}
+ }
+
+ CanQualType funcTy = fd->getType()->getCanonicalTypeUnqualified();
+
+ assert(isa(funcTy));
+ // TODO: setCUDAKernelCallingConvention
+ assert(!cir::MissingFeatures::cudaSupport());
+
+ // When declaring a function without a prototype, always use a non-variadic
+ // type.
+ if (CanQual noProto =
+ funcTy.getAs()) {
+assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());
+return arrangeCIRFunctionInfo(noProto->getReturnType(), std::nullopt,
+ RequiredArgs::All);
+ }
+
+ return arrangeFreeFunctionType(funcTy.castAs());
+}
+
static cir::CIRCallOpInterface
emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
cir::FuncOp directFuncOp,
@@ -112,13 +165,8 @@ emi
[clang] [CIR][NFC] Use arrangeFunctionDeclaration to build function types (PR #139787)
@@ -58,8 +59,9 @@ class RequiredArgs {
}
static RequiredArgs
- forPrototypePlus(clang::CanQual prototype) {
-return forPrototypePlus(prototype.getTypePtr());
+ forPrototypePlus(clang::CanQual prototype,
andykaylor wrote:
That's still not exactly right because `additional` will often be zero.
https://github.com/llvm/llvm-project/pull/139787
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Use arrangeFunctionDeclaration to build function types (PR #139787)
@@ -58,8 +59,9 @@ class RequiredArgs {
}
static RequiredArgs
- forPrototypePlus(clang::CanQual prototype) {
-return forPrototypePlus(prototype.getTypePtr());
+ forPrototypePlus(clang::CanQual prototype,
andykaylor wrote:
The intention is RequiredArgs_ForPrototype_PlusAdditionalSlots.
How about `getFromProtoWithExtraSlots`?
https://github.com/llvm/llvm-project/pull/139787
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Use arrangeFunctionDeclaration to build function types (PR #139787)
@@ -58,8 +59,9 @@ class RequiredArgs {
}
static RequiredArgs
- forPrototypePlus(clang::CanQual prototype) {
-return forPrototypePlus(prototype.getTypePtr());
+ forPrototypePlus(clang::CanQual prototype,
erichkeane wrote:
Ok, that name still doesn't really make sense? `for-prototype-plus`? A
prototype of a `for`? And `plus` what?
https://github.com/llvm/llvm-project/pull/139787
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Use arrangeFunctionDeclaration to build function types (PR #139787)
@@ -58,8 +59,9 @@ class RequiredArgs {
}
static RequiredArgs
- forPrototypePlus(clang::CanQual prototype) {
-return forPrototypePlus(prototype.getTypePtr());
+ forPrototypePlus(clang::CanQual prototype,
erichkeane wrote:
Can you decode this name for me? it doesn't really make sense to me.
https://github.com/llvm/llvm-project/pull/139787
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Use arrangeFunctionDeclaration to build function types (PR #139787)
@@ -95,6 +120,34 @@ CIRGenTypes::arrangeFreeFunctionCall(const CallArgList
&args,
return arrangeFreeFunctionLikeCall(*this, cgm, args, fnType);
}
+/// Arrange the argument and result information for the declaration or
+/// definition of the given function.
+const CIRGenFunctionInfo &
+CIRGenTypes::arrangeFunctionDeclaration(const FunctionDecl *fd) {
+ if (const auto *md = dyn_cast(fd)) {
+if (md->isInstance()) {
+ cgm.errorNYI("arrangeFunctionDeclaration: instance method");
+}
+ }
+
+ CanQualType funcTy = fd->getType()->getCanonicalTypeUnqualified();
+
+ assert(isa(funcTy));
+ // TODO: setCUDAKernelCallingConvention
erichkeane wrote:
Isn't that what the `cudaSupport` assert means?
https://github.com/llvm/llvm-project/pull/139787
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Use arrangeFunctionDeclaration to build function types (PR #139787)
llvmbot wrote:
@llvm/pr-subscribers-clang
Author: Andy Kaylor (andykaylor)
Changes
This change replaces the simplified call that we were previously using to
convert the function type provided by a global declaration to the CIR function
type. We now go through 'arrangeGlobalDeclaration' which builds the function
type in a more complicated manner. This change has no observable differences
for the currently upstreamed CIR support, but it is necessary to prepare for
C++ member function calls, which require the extra handling.
---
Full diff: https://github.com/llvm/llvm-project/pull/139787.diff
5 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+62-14)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h (+13-3)
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+2-15)
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+14)
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.h (+30-2)
``diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index 5c65a43641844..9ad048bf357cc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -44,14 +44,11 @@ CIRGenFunctionInfo::create(CanQualType resultType,
cir::FuncType CIRGenTypes::getFunctionType(const CIRGenFunctionInfo &fi) {
mlir::Type resultType = convertType(fi.getReturnType());
+ SmallVector argTypes;
+ argTypes.reserve(fi.getNumRequiredArgs());
- SmallVector argTypes(fi.getNumRequiredArgs());
-
- unsigned argNo = 0;
- llvm::ArrayRef argInfos(fi.argInfoBegin(),
- fi.getNumRequiredArgs());
- for (const auto &argInfo : argInfos)
-argTypes[argNo++] = convertType(argInfo.type);
+ for (const CIRGenFunctionInfoArgInfo &argInfo : fi.requiredArguments())
+argTypes.push_back(convertType(argInfo.type));
return cir::FuncType::get(argTypes,
(resultType ? resultType : builder.getVoidTy()),
@@ -63,6 +60,34 @@ CIRGenCallee
CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const {
return *this;
}
+/// Adds the formal parameters in FPT to the given prefix. If any parameter in
+/// FPT has pass_object_size_attrs, then we'll add parameters for those, too.
+/// TODO(cir): this should be shared with LLVM codegen
+static void appendParameterTypes(const CIRGenTypes &cgt,
+ SmallVectorImpl &prefix,
+ CanQual fpt) {
+ assert(!cir::MissingFeatures::opCallExtParameterInfo());
+ // Fast path: don't touch param info if we don't need to.
+ if (!fpt->hasExtParameterInfos()) {
+prefix.append(fpt->param_type_begin(), fpt->param_type_end());
+return;
+ }
+
+ cgt.getCGModule().errorNYI("appendParameterTypes: hasExtParameterInfos");
+}
+
+/// Arrange the CIR function layout for a value of the given function type, on
+/// top of any implicit parameters already stored.
+static const CIRGenFunctionInfo &
+arrangeCIRFunctionInfo(CIRGenTypes &cgt, SmallVectorImpl &prefix,
+ CanQual ftp) {
+ RequiredArgs required = RequiredArgs::forPrototypePlus(ftp, prefix.size());
+ assert(!cir::MissingFeatures::opCallExtParameterInfo());
+ appendParameterTypes(cgt, prefix, ftp);
+ CanQualType resultType = ftp->getReturnType().getUnqualifiedType();
+ return cgt.arrangeCIRFunctionInfo(resultType, prefix, required);
+}
+
static const CIRGenFunctionInfo &
arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm,
const CallArgList &args,
@@ -95,6 +120,34 @@ CIRGenTypes::arrangeFreeFunctionCall(const CallArgList
&args,
return arrangeFreeFunctionLikeCall(*this, cgm, args, fnType);
}
+/// Arrange the argument and result information for the declaration or
+/// definition of the given function.
+const CIRGenFunctionInfo &
+CIRGenTypes::arrangeFunctionDeclaration(const FunctionDecl *fd) {
+ if (const auto *md = dyn_cast(fd)) {
+if (md->isInstance()) {
+ cgm.errorNYI("arrangeFunctionDeclaration: instance method");
+}
+ }
+
+ CanQualType funcTy = fd->getType()->getCanonicalTypeUnqualified();
+
+ assert(isa(funcTy));
+ // TODO: setCUDAKernelCallingConvention
+ assert(!cir::MissingFeatures::cudaSupport());
+
+ // When declaring a function without a prototype, always use a non-variadic
+ // type.
+ if (CanQual noProto =
+ funcTy.getAs()) {
+assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());
+return arrangeCIRFunctionInfo(noProto->getReturnType(), std::nullopt,
+ RequiredArgs::All);
+ }
+
+ return arrangeFreeFunctionType(funcTy.castAs());
+}
+
static cir::CIRCallOpInterface
emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
cir::FuncOp directFuncOp,
@@ -112,13 +165,8 @@ emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
const CIRGenFunctionInfo &
CIRGenTypes::arrangeFreeFunctionType(CanQual fpt) {
- SmallVecto
[clang] [CIR][NFC] Use arrangeFunctionDeclaration to build function types (PR #139787)
https://github.com/andykaylor created
https://github.com/llvm/llvm-project/pull/139787
This change replaces the simplified call that we were previously using to
convert the function type provided by a global declaration to the CIR function
type. We now go through 'arrangeGlobalDeclaration' which builds the function
type in a more complicated manner. This change has no observable differences
for the currently upstreamed CIR support, but it is necessary to prepare for
C++ member function calls, which require the extra handling.
>From 4daf77880eb910d2d9b40f7a5782700195eed7c6 Mon Sep 17 00:00:00 2001
From: Andy Kaylor
Date: Thu, 8 May 2025 18:01:12 -0700
Subject: [PATCH] [CIR][NFC] Use arrangeFunctionDeclaration to build function
types
This change replaces the simplified call that we were previously using to
convert the function type provided by a global declaration to the CIR
function type. We now go through 'arrangeGlobalDeclaration' which builds
the function type in a more complicated manner. This change has no
observable differences for the currently upstreamed CIR support, but
it is necessary to prepare for C++ member function calls, which require
the extra handling.
---
clang/lib/CIR/CodeGen/CIRGenCall.cpp | 76 ++
clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h | 16 -
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 17 +
clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 14
clang/lib/CIR/CodeGen/CIRGenTypes.h| 32 -
5 files changed, 121 insertions(+), 34 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index 5c65a43641844..9ad048bf357cc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -44,14 +44,11 @@ CIRGenFunctionInfo::create(CanQualType resultType,
cir::FuncType CIRGenTypes::getFunctionType(const CIRGenFunctionInfo &fi) {
mlir::Type resultType = convertType(fi.getReturnType());
+ SmallVector argTypes;
+ argTypes.reserve(fi.getNumRequiredArgs());
- SmallVector argTypes(fi.getNumRequiredArgs());
-
- unsigned argNo = 0;
- llvm::ArrayRef argInfos(fi.argInfoBegin(),
- fi.getNumRequiredArgs());
- for (const auto &argInfo : argInfos)
-argTypes[argNo++] = convertType(argInfo.type);
+ for (const CIRGenFunctionInfoArgInfo &argInfo : fi.requiredArguments())
+argTypes.push_back(convertType(argInfo.type));
return cir::FuncType::get(argTypes,
(resultType ? resultType : builder.getVoidTy()),
@@ -63,6 +60,34 @@ CIRGenCallee
CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const {
return *this;
}
+/// Adds the formal parameters in FPT to the given prefix. If any parameter in
+/// FPT has pass_object_size_attrs, then we'll add parameters for those, too.
+/// TODO(cir): this should be shared with LLVM codegen
+static void appendParameterTypes(const CIRGenTypes &cgt,
+ SmallVectorImpl &prefix,
+ CanQual fpt) {
+ assert(!cir::MissingFeatures::opCallExtParameterInfo());
+ // Fast path: don't touch param info if we don't need to.
+ if (!fpt->hasExtParameterInfos()) {
+prefix.append(fpt->param_type_begin(), fpt->param_type_end());
+return;
+ }
+
+ cgt.getCGModule().errorNYI("appendParameterTypes: hasExtParameterInfos");
+}
+
+/// Arrange the CIR function layout for a value of the given function type, on
+/// top of any implicit parameters already stored.
+static const CIRGenFunctionInfo &
+arrangeCIRFunctionInfo(CIRGenTypes &cgt, SmallVectorImpl &prefix,
+ CanQual ftp) {
+ RequiredArgs required = RequiredArgs::forPrototypePlus(ftp, prefix.size());
+ assert(!cir::MissingFeatures::opCallExtParameterInfo());
+ appendParameterTypes(cgt, prefix, ftp);
+ CanQualType resultType = ftp->getReturnType().getUnqualifiedType();
+ return cgt.arrangeCIRFunctionInfo(resultType, prefix, required);
+}
+
static const CIRGenFunctionInfo &
arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm,
const CallArgList &args,
@@ -95,6 +120,34 @@ CIRGenTypes::arrangeFreeFunctionCall(const CallArgList
&args,
return arrangeFreeFunctionLikeCall(*this, cgm, args, fnType);
}
+/// Arrange the argument and result information for the declaration or
+/// definition of the given function.
+const CIRGenFunctionInfo &
+CIRGenTypes::arrangeFunctionDeclaration(const FunctionDecl *fd) {
+ if (const auto *md = dyn_cast(fd)) {
+if (md->isInstance()) {
+ cgm.errorNYI("arrangeFunctionDeclaration: instance method");
+}
+ }
+
+ CanQualType funcTy = fd->getType()->getCanonicalTypeUnqualified();
+
+ assert(isa(funcTy));
+ // TODO: setCUDAKernelCallingConvention
+ assert(!cir::MissingFeatures::cudaSupport());
+
+ // When declaring a function without a prototype, always use a non-variadic
+ // type.
+ if (CanQual noProto =
+
