[clang] [CIR][NFC] Use arrangeFunctionDeclaration to build function types (PR #139787)

2025-05-16 Thread Andy Kaylor via cfe-commits

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)

2025-05-15 Thread Erich Keane via cfe-commits

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)

2025-05-15 Thread Andy Kaylor via cfe-commits

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)

2025-05-14 Thread Andy Kaylor via cfe-commits


@@ -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)

2025-05-14 Thread Andy Kaylor via cfe-commits


@@ -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)

2025-05-14 Thread Erich Keane via cfe-commits


@@ -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)

2025-05-13 Thread Erich Keane via cfe-commits


@@ -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)

2025-05-13 Thread Erich Keane via cfe-commits


@@ -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)

2025-05-13 Thread via cfe-commits

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)

2025-05-13 Thread Andy Kaylor via cfe-commits

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 =
+