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