https://github.com/andykaylor created 
https://github.com/llvm/llvm-project/pull/140612

A previous refactoring had reduced the ArgInfo structure to contain a single 
member, the argument type. This change eliminates the ArgInfo structure 
entirely, instead just storing the argument type directly in places where 
ArgInfo had previously been used.

This also updates the place where the arg types were previously being copied 
for a call to CIRGenFunctionInfo::Profile to instead use the stored argument 
types buffer directly and adds assertions where the calculated folding set ID 
is used to verify that any match was correct.

>From 2310c8af56330682ab15ca318971d530cd45e73b Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akay...@nvidia.com>
Date: Mon, 19 May 2025 13:18:55 -0700
Subject: [PATCH] [CIR][NFC] Eliminate ArgInfo structure

A previous refactoring had reduced the ArgInfo structure to contain a
single member, the argument type. This change eliminates the ArgInfo
structure entirely, instead just storing the argument type directly in
places where ArgInfo had previously been used.

This also updates the place where the arg types were previously being
copied for a call to CIRGenFunctionInfo::Profile to instead use the
stored argument types buffer directly and adds assertions where the
calculated folding set ID is used to verify that any match was
correct.
---
 clang/lib/CIR/CodeGen/CIRGenCall.cpp       | 21 ++++---
 clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h | 65 +++++++++-------------
 clang/lib/CIR/CodeGen/CIRGenTypes.cpp      |  9 ++-
 3 files changed, 44 insertions(+), 51 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp 
b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index 17bfa19f9fd63..f63b971ac26b4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -23,8 +23,9 @@ CIRGenFunctionInfo *
 CIRGenFunctionInfo::create(CanQualType resultType,
                            llvm::ArrayRef<CanQualType> argTypes,
                            RequiredArgs required) {
-  // The first slot allocated for ArgInfo is for the return value.
-  void *buffer = operator new(totalSizeToAlloc<ArgInfo>(argTypes.size() + 1));
+  // The first slot allocated for arg type slot is for the return value.
+  void *buffer = operator new(
+      totalSizeToAlloc<CanQualType>(argTypes.size() + 1));
 
   assert(!cir::MissingFeatures::opCallCIRGenFuncInfoParamInfo());
 
@@ -33,10 +34,8 @@ CIRGenFunctionInfo::create(CanQualType resultType,
   fi->required = required;
   fi->numArgs = argTypes.size();
 
-  ArgInfo *argsBuffer = fi->getArgsBuffer();
-  (argsBuffer++)->type = resultType;
-  for (CanQualType ty : argTypes)
-    (argsBuffer++)->type = ty;
+  fi->getArgTypes()[0] = resultType;
+  std::copy(argTypes.begin(), argTypes.end(), fi->argTypesBegin());
   assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());
 
   return fi;
@@ -47,8 +46,8 @@ cir::FuncType CIRGenTypes::getFunctionType(const 
CIRGenFunctionInfo &fi) {
   SmallVector<mlir::Type, 8> argTypes;
   argTypes.reserve(fi.getNumRequiredArgs());
 
-  for (const CIRGenFunctionInfoArgInfo &argInfo : fi.requiredArguments())
-    argTypes.push_back(convertType(argInfo.type));
+  for (const CanQualType &argType : fi.requiredArguments())
+    argTypes.push_back(convertType(argType));
 
   return cir::FuncType::get(argTypes,
                             (resultType ? resultType : builder.getVoidTy()),
@@ -189,13 +188,13 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo 
&funcInfo,
   assert(!cir::MissingFeatures::emitLifetimeMarkers());
 
   // Translate all of the arguments as necessary to match the CIR lowering.
-  for (auto [argNo, arg, argInfo] :
-       llvm::enumerate(args, funcInfo.argInfos())) {
+  for (auto [argNo, arg, canQualArgType] :
+       llvm::enumerate(args, funcInfo.argTypes())) {
 
     // Insert a padding argument to ensure proper alignment.
     assert(!cir::MissingFeatures::opCallPaddingArgs());
 
-    mlir::Type argType = convertType(argInfo.type);
+    mlir::Type argType = convertType(canQualArgType);
     if (!mlir::isa<cir::RecordType>(argType)) {
       mlir::Value v;
       if (arg.isAggregate())
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h 
b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
index b74460b09a44e..334b2864a2fb2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
@@ -21,10 +21,6 @@
 
 namespace clang::CIRGen {
 
-struct CIRGenFunctionInfoArgInfo {
-  CanQualType type;
-};
-
 /// A class for recording the number of arguments that a function signature
 /// requires.
 class RequiredArgs {
@@ -72,16 +68,15 @@ class RequiredArgs {
 
 class CIRGenFunctionInfo final
     : public llvm::FoldingSetNode,
-      private llvm::TrailingObjects<CIRGenFunctionInfo,
-                                    CIRGenFunctionInfoArgInfo> {
-  using ArgInfo = CIRGenFunctionInfoArgInfo;
-
+      private llvm::TrailingObjects<CIRGenFunctionInfo, CanQualType> {
   RequiredArgs required;
 
   unsigned numArgs;
 
-  ArgInfo *getArgsBuffer() { return getTrailingObjects<ArgInfo>(); }
-  const ArgInfo *getArgsBuffer() const { return getTrailingObjects<ArgInfo>(); 
}
+  CanQualType *getArgTypes() { return getTrailingObjects<CanQualType>(); }
+  const CanQualType *getArgTypes() const {
+    return getTrailingObjects<CanQualType>();
+  }
 
   CIRGenFunctionInfo() : required(RequiredArgs::All) {}
 
@@ -96,8 +91,8 @@ class CIRGenFunctionInfo final
   // these have to be public.
   friend class TrailingObjects;
 
-  using const_arg_iterator = const ArgInfo *;
-  using arg_iterator = ArgInfo *;
+  using const_arg_iterator = const CanQualType *;
+  using arg_iterator = CanQualType *;
 
   // This function has to be CamelCase because llvm::FoldingSet requires so.
   // NOLINTNEXTLINE(readability-identifier-naming)
@@ -112,49 +107,41 @@ class CIRGenFunctionInfo final
 
   // NOLINTNEXTLINE(readability-identifier-naming)
   void Profile(llvm::FoldingSetNodeID &id) {
-    // It's unfortunate that we are looping over the arguments twice (here and
-    // in the static Profile function we call from here), but if the Profile
-    // functions get out of sync, we can end up with incorrect function
-    // signatures, and we don't have the argument types in the format that the
-    // static Profile function requires.
-    llvm::SmallVector<CanQualType, 16> argTypes;
-    for (const ArgInfo &argInfo : arguments())
-      argTypes.push_back(argInfo.type);
-
-    Profile(id, required, getReturnType(), argTypes);
+    // If the Profile functions get out of sync, we can end up with incorrect
+    // function signatures, so we call the static Profile function here rather
+    // than duplicating the logic.
+    Profile(id, required, getReturnType(), arguments());
   }
 
-  llvm::ArrayRef<ArgInfo> arguments() const {
-    return llvm::ArrayRef<ArgInfo>(argInfoBegin(), numArgs);
+  llvm::ArrayRef<CanQualType> arguments() const {
+    return llvm::ArrayRef<CanQualType>(argTypesBegin(), numArgs);
   }
 
-  llvm::ArrayRef<ArgInfo> requiredArguments() const {
-    return llvm::ArrayRef<ArgInfo>(argInfoBegin(), getNumRequiredArgs());
+  llvm::ArrayRef<CanQualType> requiredArguments() const {
+    return llvm::ArrayRef<CanQualType>(argTypesBegin(), getNumRequiredArgs());
   }
 
-  CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
+  CanQualType getReturnType() const { return getArgTypes()[0]; }
 
-  const_arg_iterator argInfoBegin() const { return getArgsBuffer() + 1; }
-  const_arg_iterator argInfoEnd() const {
-    return getArgsBuffer() + 1 + numArgs;
-  }
-  arg_iterator argInfoBegin() { return getArgsBuffer() + 1; }
-  arg_iterator argInfoEnd() { return getArgsBuffer() + 1 + numArgs; }
+  const_arg_iterator argTypesBegin() const { return getArgTypes() + 1; }
+  const_arg_iterator argTypesEnd() const { return getArgTypes() + 1 + numArgs; 
}
+  arg_iterator argTypesBegin() { return getArgTypes() + 1; }
+  arg_iterator argTypesEnd() { return getArgTypes() + 1 + numArgs; }
 
-  unsigned argInfoSize() const { return numArgs; }
+  unsigned argTypeSize() const { return numArgs; }
 
-  llvm::MutableArrayRef<ArgInfo> argInfos() {
-    return llvm::MutableArrayRef<ArgInfo>(argInfoBegin(), numArgs);
+  llvm::MutableArrayRef<CanQualType> argTypes() {
+    return llvm::MutableArrayRef<CanQualType>(argTypesBegin(), numArgs);
   }
-  llvm::ArrayRef<ArgInfo> argInfos() const {
-    return llvm::ArrayRef<ArgInfo>(argInfoBegin(), numArgs);
+  llvm::ArrayRef<CanQualType> argTypes() const {
+    return llvm::ArrayRef<CanQualType>(argTypesBegin(), numArgs);
   }
 
   bool isVariadic() const { return required.allowsOptionalArgs(); }
   RequiredArgs getRequiredArgs() const { return required; }
   unsigned getNumRequiredArgs() const {
     return isVariadic() ? getRequiredArgs().getNumRequiredArgs()
-                        : argInfoSize();
+                        : argTypeSize();
   }
 };
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp 
b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index dc8872122995c..45990f198d227 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -542,8 +542,15 @@ CIRGenTypes::arrangeCIRFunctionInfo(CanQualType returnType,
 
   void *insertPos = nullptr;
   CIRGenFunctionInfo *fi = functionInfos.FindNodeOrInsertPos(id, insertPos);
-  if (fi)
+  if (fi) {
+    // We found a matching function info based on id. These asserts verify that
+    // it really is a match.
+    assert(
+        fi->getReturnType() == returnType &&
+        std::equal(fi->argTypesBegin(), fi->argTypesEnd(), argTypes.begin()) &&
+        "Bad match based on CIRGenFunctionInfo folding set id");
     return *fi;
+  }
 
   assert(!cir::MissingFeatures::opCallCallConv());
 

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to