================
@@ -3139,6 +3139,97 @@ void CIRGenModule::setCIRFunctionAttributesForDefinition(
   assert(!cir::MissingFeatures::opFuncColdHotAttr());
 }
 
+void CIRGenModule::emitOpenCLKernelArgMetadata(cir::FuncOp func,
+                                               const clang::FunctionDecl *fd) {
+  assert(fd && "expected a kernel function declaration");
+  const PrintingPolicy &policy = getASTContext().getPrintingPolicy();
+
+  SmallVector<mlir::Attribute> addressQuals;
+  SmallVector<mlir::Attribute> accessQuals;
+  SmallVector<mlir::Attribute> argTypeNames;
+  SmallVector<mlir::Attribute> argBaseTypeNames;
+  SmallVector<mlir::Attribute> argTypeQuals;
+  SmallVector<mlir::Attribute> argNames;
+
+  for (const ParmVarDecl *param : fd->parameters()) {
+    argNames.push_back(builder.getStringAttr(param->getName()));
+
+    QualType type = param->getType();
+    std::string typeQuals;
+
+    if (type->isImageType() || type->isPipeType()) {
+      errorNYI(param->getSourceRange(),
+               "OpenCL kernel argument metadata for image and pipe types");
+      return;
+    }
+
+    accessQuals.push_back(builder.getStringAttr("none"));
+
+    auto getTypeSpelling = [&](QualType paramType) {
+      std::string typeName = 
paramType.getUnqualifiedType().getAsString(policy);
+
+      if (paramType.isCanonical()) {
+        StringRef typeNameRef = typeName;
+        if (typeNameRef.consume_front("unsigned "))
+          return std::string("u") + typeNameRef.str();
+        if (typeNameRef.consume_front("signed "))
+          return typeNameRef.str();
+      }
+
+      return typeName;
+    };
+
+    if (type->isPointerType()) {
+      QualType pointeeType = type->getPointeeType();
+      if (clang::isTargetAddressSpace(pointeeType.getAddressSpace())) {
+        errorNYI(param->getSourceRange(),
+                 "OpenCL kernel argument metadata for target-specific "
+                 "address_space(N) kernel parameters; classic CodeGen "
+                 "currently accepts this case");
+        return;
+      }
+
+      addressQuals.push_back(cir::LangAddressSpaceAttr::get(
+          &getMLIRContext(),
+          cir::toCIRLangAddressSpace(pointeeType.getAddressSpace())));
+
+      argTypeNames.push_back(
+          builder.getStringAttr(getTypeSpelling(pointeeType) + "*"));
+      argBaseTypeNames.push_back(builder.getStringAttr(
+          getTypeSpelling(pointeeType.getCanonicalType()) + "*"));
+
+      if (type.isRestrictQualified())
+        typeQuals = "restrict";
+      if (pointeeType.isConstQualified() ||
+          pointeeType.getAddressSpace() == LangAS::opencl_constant)
+        typeQuals += typeQuals.empty() ? "const" : " const";
+      if (pointeeType.isVolatileQualified())
+        typeQuals += typeQuals.empty() ? "volatile" : " volatile";
+    } else {
+      addressQuals.push_back(cir::LangAddressSpaceAttr::get(
----------------
RiverDave wrote:

So OpenCL handles AS in an odd way. The kernel_arg_addr_space values aren't a 
backend thing and shouldn't be lowered per-target. Take a look at: 
https://github.com/llvm/llvm-project/blob/1060a6be0a471106fd65a3f16937ee1c588dabed/clang/lib/CodeGen/CodeGenModule.cpp#L2740
 the comment makes it explicit.  it maps the AST AS straight to the qualifiers 
the SPIR spec expects, regardless of the target.


You should have a helper that handles the mapping like this:

```
  opencl_global         -> offload_global
  opencl_constant       -> offload_constant
  opencl_local          -> offload_local
  opencl_generic        -> offload_generic
  opencl_global_device  -> offload_global_device
  opencl_global_host    -> offload_global_host
  default:              -> offload_default   // target AS lands here, but so 
does everything non-named
```
One thing to watch: a __attribute__((address_space(N))) arg is a target AS, not 
a named OpenCL space, so it falls into default: and collapses to 
offload_default (id 0), same as ArgInfoAddressSpace does. The number stays on 
the pointer, it just doesn't make it into the metadata. I'd keep it a whitelist 
with a default case rather than checking for target AS specifically, so it 
doesn't drift from upstream.


https://github.com/llvm/llvm-project/pull/200581
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to