clang 24.0.0git
LowerToLLVMOpenCLMetadata.cpp
Go to the documentation of this file.
1//===- LowerToLLVMOpenCLMetadata.cpp - OpenCL metadata lowering -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
12#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
13#include "mlir/IR/Builders.h"
15#include "llvm/ADT/TypeSwitch.h"
16#include "llvm/Support/ErrorHandling.h"
17
18namespace cir {
19namespace direct {
20
21namespace {
22class LLVMMetadataNodeBuilder {
23public:
24 explicit LLVMMetadataNodeBuilder(mlir::MLIRContext *ctx) : ctx(ctx) {}
25
26 mlir::LLVM::MDConstantAttr getI32(unsigned value) const {
27 mlir::IntegerType intTy = mlir::IntegerType::get(ctx, 32);
28 mlir::IntegerAttr intAttr = mlir::IntegerAttr::get(intTy, value);
29 return mlir::LLVM::MDConstantAttr::get(ctx, intAttr);
30 }
31
32 mlir::LLVM::MDStringAttr getString(llvm::StringRef value) const {
33 return mlir::LLVM::MDStringAttr::get(ctx,
34 mlir::StringAttr::get(ctx, value));
35 }
36
37 mlir::LLVM::MDNodeAttr
38 getNode(llvm::ArrayRef<mlir::Attribute> metadata) const {
39 return mlir::LLVM::MDNodeAttr::get(ctx, metadata);
40 }
41
42 mlir::LLVM::MDNodeAttr getI32Node(llvm::ArrayRef<unsigned> values) const {
43 llvm::SmallVector<mlir::Attribute> metadata;
44 for (unsigned value : values)
45 metadata.push_back(getI32(value));
46 return getNode(metadata);
47 }
48
49 mlir::LLVM::MDNodeAttr getStringNode(mlir::ArrayAttr attrs) const {
50 llvm::SmallVector<mlir::Attribute> metadata;
51 for (mlir::StringAttr attr : attrs.getAsRange<mlir::StringAttr>())
52 metadata.push_back(getString(attr.getValue()));
53 return getNode(metadata);
54 }
55
56private:
57 mlir::MLIRContext *ctx;
58};
59
60using KernelArgStringMetadataGetter =
61 mlir::ArrayAttr (cir::OpenCLKernelArgMetadataAttr::*)() const;
62
63struct KernelArgStringMetadataMapping {
64 llvm::StringLiteral metadataName;
65 KernelArgStringMetadataGetter getMetadata;
66 bool optional;
67};
68
69static unsigned getOpenCLArgInfoAddressSpace(cir::LangAddressSpace as) {
70 switch (as) {
71 case cir::LangAddressSpace::Default:
72 case cir::LangAddressSpace::OffloadPrivate:
73 return 0;
74 case cir::LangAddressSpace::OffloadGlobal:
75 return 1;
76 case cir::LangAddressSpace::OffloadConstant:
77 return 2;
78 case cir::LangAddressSpace::OffloadLocal:
79 return 3;
80 case cir::LangAddressSpace::OffloadGeneric:
81 return 4;
82 case cir::LangAddressSpace::OffloadGlobalDevice:
83 return 5;
84 case cir::LangAddressSpace::OffloadGlobalHost:
85 return 6;
86 }
87 llvm_unreachable("unknown CIR language address space");
88}
89
90static mlir::LLVM::MDNodeAttr
91getAddrSpaceMetadataNode(cir::OpenCLKernelArgMetadataAttr clArgMetadata,
92 const LLVMMetadataNodeBuilder &metadataBuilder) {
93 llvm::SmallVector<unsigned> addrSpaces;
94 for (cir::LangAddressSpaceAttr addressSpace :
95 clArgMetadata.getAddrSpace().getAsRange<cir::LangAddressSpaceAttr>())
96 addrSpaces.push_back(getOpenCLArgInfoAddressSpace(addressSpace.getValue()));
97 return metadataBuilder.getI32Node(addrSpaces);
98}
99
100static void addOpenCLKernelArgFunctionMetadata(
101 mlir::MLIRContext *ctx, llvm::SmallVectorImpl<mlir::Attribute> &entries,
102 llvm::StringRef name, mlir::LLVM::MDNodeAttr node) {
103 entries.push_back(mlir::LLVM::FunctionMetadataAttr::get(
104 ctx, mlir::StringAttr::get(ctx, name), node));
105}
106
107} // namespace
108
110 cir::OpenCLKernelArgMetadataAttr clArgMetadata,
112 mlir::MLIRContext *ctx = clArgMetadata.getContext();
113 LLVMMetadataNodeBuilder metadataBuilder(ctx);
114
115 addOpenCLKernelArgFunctionMetadata(
116 ctx, entries, "kernel_arg_addr_space",
117 getAddrSpaceMetadataNode(clArgMetadata, metadataBuilder));
118
119 static constexpr KernelArgStringMetadataMapping stringMetadataMappings[] = {
120 {"kernel_arg_access_qual",
121 &cir::OpenCLKernelArgMetadataAttr::getAccessQual,
122 /*optional=*/false},
123 {"kernel_arg_type", &cir::OpenCLKernelArgMetadataAttr::getType,
124 /*optional=*/false},
125 {"kernel_arg_base_type", &cir::OpenCLKernelArgMetadataAttr::getBaseType,
126 /*optional=*/false},
127 {"kernel_arg_type_qual", &cir::OpenCLKernelArgMetadataAttr::getTypeQual,
128 /*optional=*/false},
129 {"kernel_arg_name", &cir::OpenCLKernelArgMetadataAttr::getName,
130 /*optional=*/true},
131 };
132
133 for (const KernelArgStringMetadataMapping &mapping : stringMetadataMappings) {
134 mlir::ArrayAttr metadata = (clArgMetadata.*mapping.getMetadata)();
135 if (mapping.optional && !metadata)
136 continue;
137 addOpenCLKernelArgFunctionMetadata(ctx, entries, mapping.metadataName,
138 metadataBuilder.getStringNode(metadata));
139 }
140}
141
143 mlir::MLIRContext *ctx)
144 : ctx(ctx) {}
145
146bool OpenCLFunctionMetadataLowering::lower(mlir::NamedAttribute attr,
147 bool includeFunctionOnlyAttrs) {
148 return llvm::TypeSwitch<mlir::Attribute, bool>(attr.getValue())
149 .Case<cir::OpenCLKernelArgMetadataAttr>(
150 [&](cir::OpenCLKernelArgMetadataAttr clArgMetadata) {
151 if (!includeFunctionOnlyAttrs)
152 return true;
153 lower(clArgMetadata);
154 return true;
155 })
156 .Default(false);
157}
158
161 if (!functionMetadata.empty()) {
162 result.push_back(mlir::NamedAttribute(
163 mlir::LLVM::LLVMFuncOp::getFunctionMetadataAttrName(mlir::OperationName(
164 mlir::LLVM::LLVMFuncOp::getOperationName(), ctx)),
165 mlir::ArrayAttr::get(ctx, functionMetadata)));
166 }
167}
168
170 cir::OpenCLKernelArgMetadataAttr clArgMetadata) {
171 convertOpenCLKernelArgMetadata(clArgMetadata, functionMetadata);
172}
173
174} // namespace direct
175} // namespace cir
static Expected< DynTypedNode > getNode(const ast_matchers::BoundNodes &Nodes, StringRef ID)
void appendAttrs(llvm::SmallVectorImpl< mlir::NamedAttribute > &result) const
bool lower(mlir::NamedAttribute attr, bool includeFunctionOnlyAttrs)
static void convertOpenCLKernelArgMetadata(cir::OpenCLKernelArgMetadataAttr clArgMetadata, llvm::SmallVectorImpl< mlir::Attribute > &entries)
const internal::VariadicAllOfMatcher< Attr > attr