1 | //===- LLVM.cpp - C Interface for LLVM dialect ----------------------------===// |
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 | |
9 | #include "mlir-c/Dialect/LLVM.h" |
10 | #include "mlir-c/IR.h" |
11 | #include "mlir-c/Support.h" |
12 | #include "mlir/CAPI/Registration.h" |
13 | #include "mlir/CAPI/Wrap.h" |
14 | #include "mlir/Dialect/LLVMIR/LLVMAttrs.h" |
15 | #include "mlir/Dialect/LLVMIR/LLVMDialect.h" |
16 | #include "mlir/Dialect/LLVMIR/LLVMTypes.h" |
17 | #include "llvm-c/Core.h" |
18 | #include "llvm/ADT/SmallVector.h" |
19 | #include "llvm/ADT/SmallVectorExtras.h" |
20 | |
21 | using namespace mlir; |
22 | using namespace mlir::LLVM; |
23 | |
24 | MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(LLVM, llvm, LLVMDialect) |
25 | |
26 | MlirType mlirLLVMPointerTypeGet(MlirContext ctx, unsigned addressSpace) { |
27 | return wrap(LLVMPointerType::get(unwrap(ctx), addressSpace)); |
28 | } |
29 | |
30 | bool mlirTypeIsALLVMPointerType(MlirType type) { |
31 | return isa<LLVM::LLVMPointerType>(unwrap(type)); |
32 | } |
33 | |
34 | unsigned mlirLLVMPointerTypeGetAddressSpace(MlirType pointerType) { |
35 | return cast<LLVM::LLVMPointerType>(unwrap(pointerType)).getAddressSpace(); |
36 | } |
37 | |
38 | MlirType mlirLLVMVoidTypeGet(MlirContext ctx) { |
39 | return wrap(cpp: LLVMVoidType::get(ctx: unwrap(c: ctx))); |
40 | } |
41 | |
42 | MlirType mlirLLVMArrayTypeGet(MlirType elementType, unsigned numElements) { |
43 | return wrap(LLVMArrayType::get(unwrap(elementType), numElements)); |
44 | } |
45 | |
46 | MlirType mlirLLVMFunctionTypeGet(MlirType resultType, intptr_t nArgumentTypes, |
47 | MlirType const *argumentTypes, bool isVarArg) { |
48 | SmallVector<Type, 2> argumentStorage; |
49 | return wrap(LLVMFunctionType::get( |
50 | unwrap(resultType), |
51 | unwrapList(nArgumentTypes, argumentTypes, argumentStorage), isVarArg)); |
52 | } |
53 | |
54 | bool mlirTypeIsALLVMStructType(MlirType type) { |
55 | return isa<LLVM::LLVMStructType>(Val: unwrap(c: type)); |
56 | } |
57 | |
58 | bool mlirLLVMStructTypeIsLiteral(MlirType type) { |
59 | return !cast<LLVM::LLVMStructType>(Val: unwrap(c: type)).isIdentified(); |
60 | } |
61 | |
62 | intptr_t mlirLLVMStructTypeGetNumElementTypes(MlirType type) { |
63 | return cast<LLVM::LLVMStructType>(Val: unwrap(c: type)).getBody().size(); |
64 | } |
65 | |
66 | MlirType mlirLLVMStructTypeGetElementType(MlirType type, intptr_t position) { |
67 | return wrap(cpp: cast<LLVM::LLVMStructType>(Val: unwrap(c: type)).getBody()[position]); |
68 | } |
69 | |
70 | bool mlirLLVMStructTypeIsPacked(MlirType type) { |
71 | return cast<LLVM::LLVMStructType>(Val: unwrap(c: type)).isPacked(); |
72 | } |
73 | |
74 | MlirStringRef mlirLLVMStructTypeGetIdentifier(MlirType type) { |
75 | return wrap(ref: cast<LLVM::LLVMStructType>(Val: unwrap(c: type)).getName()); |
76 | } |
77 | |
78 | bool mlirLLVMStructTypeIsOpaque(MlirType type) { |
79 | return cast<LLVM::LLVMStructType>(Val: unwrap(c: type)).isOpaque(); |
80 | } |
81 | |
82 | MlirType mlirLLVMStructTypeLiteralGet(MlirContext ctx, intptr_t nFieldTypes, |
83 | MlirType const *fieldTypes, |
84 | bool isPacked) { |
85 | SmallVector<Type> fieldStorage; |
86 | return wrap(LLVMStructType::getLiteral( |
87 | context: unwrap(c: ctx), types: unwrapList(size: nFieldTypes, first: fieldTypes, storage&: fieldStorage), |
88 | isPacked)); |
89 | } |
90 | |
91 | MlirType mlirLLVMStructTypeLiteralGetChecked(MlirLocation loc, |
92 | intptr_t nFieldTypes, |
93 | MlirType const *fieldTypes, |
94 | bool isPacked) { |
95 | SmallVector<Type> fieldStorage; |
96 | return wrap(LLVMStructType::getLiteralChecked( |
97 | emitError: [loc]() { return emitError(loc: unwrap(c: loc)); }, context: unwrap(c: loc)->getContext(), |
98 | types: unwrapList(size: nFieldTypes, first: fieldTypes, storage&: fieldStorage), isPacked)); |
99 | } |
100 | |
101 | MlirType mlirLLVMStructTypeOpaqueGet(MlirContext ctx, MlirStringRef name) { |
102 | return wrap(LLVMStructType::getOpaque(name: unwrap(ref: name), context: unwrap(c: ctx))); |
103 | } |
104 | |
105 | MlirType mlirLLVMStructTypeIdentifiedGet(MlirContext ctx, MlirStringRef name) { |
106 | return wrap(LLVMStructType::getIdentified(context: unwrap(c: ctx), name: unwrap(ref: name))); |
107 | } |
108 | |
109 | MlirType mlirLLVMStructTypeIdentifiedNewGet(MlirContext ctx, MlirStringRef name, |
110 | intptr_t nFieldTypes, |
111 | MlirType const *fieldTypes, |
112 | bool isPacked) { |
113 | SmallVector<Type> fields; |
114 | return wrap(LLVMStructType::getNewIdentified( |
115 | context: unwrap(c: ctx), name: unwrap(ref: name), elements: unwrapList(size: nFieldTypes, first: fieldTypes, storage&: fields), |
116 | isPacked)); |
117 | } |
118 | |
119 | MlirLogicalResult mlirLLVMStructTypeSetBody(MlirType structType, |
120 | intptr_t nFieldTypes, |
121 | MlirType const *fieldTypes, |
122 | bool isPacked) { |
123 | SmallVector<Type> fields; |
124 | return wrap( |
125 | res: cast<LLVM::LLVMStructType>(Val: unwrap(c: structType)) |
126 | .setBody(types: unwrapList(size: nFieldTypes, first: fieldTypes, storage&: fields), isPacked)); |
127 | } |
128 | |
129 | MlirAttribute mlirLLVMDIExpressionElemAttrGet(MlirContext ctx, |
130 | unsigned int opcode, |
131 | intptr_t nArguments, |
132 | uint64_t const *arguments) { |
133 | auto list = ArrayRef<uint64_t>(arguments, nArguments); |
134 | return wrap(DIExpressionElemAttr::get(unwrap(ctx), opcode, list)); |
135 | } |
136 | |
137 | MlirAttribute mlirLLVMDIExpressionAttrGet(MlirContext ctx, intptr_t nOperations, |
138 | MlirAttribute const *operations) { |
139 | SmallVector<Attribute> attrStorage; |
140 | attrStorage.reserve(N: nOperations); |
141 | |
142 | return wrap(DIExpressionAttr::get( |
143 | unwrap(ctx), |
144 | llvm::map_to_vector( |
145 | unwrapList(nOperations, operations, attrStorage), |
146 | [](Attribute a) { return cast<DIExpressionElemAttr>(a); }))); |
147 | } |
148 | |
149 | MlirAttribute mlirLLVMDINullTypeAttrGet(MlirContext ctx) { |
150 | return wrap(DINullTypeAttr::get(unwrap(ctx))); |
151 | } |
152 | |
153 | MlirAttribute mlirLLVMDIBasicTypeAttrGet(MlirContext ctx, unsigned int tag, |
154 | MlirAttribute name, |
155 | uint64_t sizeInBits, |
156 | MlirLLVMTypeEncoding encoding) { |
157 | |
158 | return wrap(DIBasicTypeAttr::get( |
159 | unwrap(ctx), tag, cast<StringAttr>(unwrap(name)), sizeInBits, encoding)); |
160 | } |
161 | |
162 | MlirAttribute mlirLLVMDICompositeTypeAttrGet( |
163 | MlirContext ctx, unsigned int tag, MlirAttribute recId, MlirAttribute name, |
164 | MlirAttribute file, uint32_t line, MlirAttribute scope, |
165 | MlirAttribute baseType, int64_t flags, uint64_t sizeInBits, |
166 | uint64_t alignInBits, intptr_t nElements, MlirAttribute const *elements) { |
167 | SmallVector<Attribute> elementsStorage; |
168 | elementsStorage.reserve(N: nElements); |
169 | |
170 | return wrap(DICompositeTypeAttr::get( |
171 | unwrap(ctx), tag, cast<DistinctAttr>(unwrap(recId)), |
172 | cast<StringAttr>(unwrap(name)), cast<DIFileAttr>(unwrap(file)), line, |
173 | cast<DIScopeAttr>(unwrap(scope)), cast<DITypeAttr>(unwrap(baseType)), |
174 | DIFlags(flags), sizeInBits, alignInBits, |
175 | llvm::map_to_vector(unwrapList(nElements, elements, elementsStorage), |
176 | [](Attribute a) { return cast<DINodeAttr>(a); }))); |
177 | } |
178 | |
179 | MlirAttribute |
180 | mlirLLVMDIDerivedTypeAttrGet(MlirContext ctx, unsigned int tag, |
181 | MlirAttribute name, MlirAttribute baseType, |
182 | uint64_t sizeInBits, uint32_t alignInBits, |
183 | uint64_t offsetInBits, MlirAttribute ) { |
184 | return wrap(DIDerivedTypeAttr::get( |
185 | unwrap(ctx), tag, cast<StringAttr>(unwrap(name)), |
186 | cast<DITypeAttr>(unwrap(baseType)), sizeInBits, alignInBits, offsetInBits, |
187 | cast<DINodeAttr>(unwrap(extraData)))); |
188 | } |
189 | |
190 | MlirAttribute |
191 | mlirLLVMDIDerivedTypeAttrGetBaseType(MlirAttribute diDerivedType) { |
192 | return wrap(cast<DIDerivedTypeAttr>(unwrap(diDerivedType)).getBaseType()); |
193 | } |
194 | |
195 | MlirAttribute mlirLLVMCConvAttrGet(MlirContext ctx, MlirLLVMCConv cconv) { |
196 | return wrap(CConvAttr::get(unwrap(ctx), CConv(cconv))); |
197 | } |
198 | |
199 | MlirAttribute mlirLLVMComdatAttrGet(MlirContext ctx, MlirLLVMComdat comdat) { |
200 | return wrap(ComdatAttr::get(unwrap(ctx), comdat::Comdat(comdat))); |
201 | } |
202 | |
203 | MlirAttribute mlirLLVMLinkageAttrGet(MlirContext ctx, MlirLLVMLinkage linkage) { |
204 | return wrap(LinkageAttr::get(unwrap(ctx), linkage::Linkage(linkage))); |
205 | } |
206 | |
207 | MlirAttribute mlirLLVMDIFileAttrGet(MlirContext ctx, MlirAttribute name, |
208 | MlirAttribute directory) { |
209 | return wrap(DIFileAttr::get(unwrap(ctx), cast<StringAttr>(unwrap(name)), |
210 | cast<StringAttr>(unwrap(directory)))); |
211 | } |
212 | |
213 | MlirAttribute |
214 | mlirLLVMDICompileUnitAttrGet(MlirContext ctx, MlirAttribute id, |
215 | unsigned int sourceLanguage, MlirAttribute file, |
216 | MlirAttribute producer, bool isOptimized, |
217 | MlirLLVMDIEmissionKind emissionKind, |
218 | MlirLLVMDINameTableKind nameTableKind) { |
219 | return wrap(DICompileUnitAttr::get( |
220 | unwrap(ctx), cast<DistinctAttr>(unwrap(id)), sourceLanguage, |
221 | cast<DIFileAttr>(unwrap(file)), cast<StringAttr>(unwrap(producer)), |
222 | isOptimized, DIEmissionKind(emissionKind), |
223 | DINameTableKind(nameTableKind))); |
224 | } |
225 | |
226 | MlirAttribute mlirLLVMDIFlagsAttrGet(MlirContext ctx, uint64_t value) { |
227 | return wrap(DIFlagsAttr::get(unwrap(ctx), DIFlags(value))); |
228 | } |
229 | |
230 | MlirAttribute mlirLLVMDILexicalBlockAttrGet(MlirContext ctx, |
231 | MlirAttribute scope, |
232 | MlirAttribute file, |
233 | unsigned int line, |
234 | unsigned int column) { |
235 | return wrap( |
236 | DILexicalBlockAttr::get(unwrap(ctx), cast<DIScopeAttr>(unwrap(scope)), |
237 | cast<DIFileAttr>(unwrap(file)), line, column)); |
238 | } |
239 | |
240 | MlirAttribute mlirLLVMDILexicalBlockFileAttrGet(MlirContext ctx, |
241 | MlirAttribute scope, |
242 | MlirAttribute file, |
243 | unsigned int discriminator) { |
244 | return wrap(DILexicalBlockFileAttr::get( |
245 | unwrap(ctx), cast<DIScopeAttr>(unwrap(scope)), |
246 | cast<DIFileAttr>(unwrap(file)), discriminator)); |
247 | } |
248 | |
249 | MlirAttribute |
250 | mlirLLVMDILocalVariableAttrGet(MlirContext ctx, MlirAttribute scope, |
251 | MlirAttribute name, MlirAttribute diFile, |
252 | unsigned int line, unsigned int arg, |
253 | unsigned int alignInBits, MlirAttribute diType) { |
254 | return wrap(DILocalVariableAttr::get( |
255 | unwrap(ctx), cast<DIScopeAttr>(unwrap(scope)), |
256 | cast<StringAttr>(unwrap(name)), cast<DIFileAttr>(unwrap(diFile)), line, |
257 | arg, alignInBits, cast<DITypeAttr>(unwrap(diType)))); |
258 | } |
259 | |
260 | MlirAttribute mlirLLVMDISubroutineTypeAttrGet(MlirContext ctx, |
261 | unsigned int callingConvention, |
262 | intptr_t nTypes, |
263 | MlirAttribute const *types) { |
264 | SmallVector<Attribute> attrStorage; |
265 | attrStorage.reserve(N: nTypes); |
266 | |
267 | return wrap(DISubroutineTypeAttr::get( |
268 | unwrap(ctx), callingConvention, |
269 | llvm::map_to_vector(unwrapList(nTypes, types, attrStorage), |
270 | [](Attribute a) { return cast<DITypeAttr>(a); }))); |
271 | } |
272 | |
273 | MlirAttribute mlirLLVMDISubprogramAttrGet( |
274 | MlirContext ctx, MlirAttribute id, MlirAttribute compileUnit, |
275 | MlirAttribute scope, MlirAttribute name, MlirAttribute linkageName, |
276 | MlirAttribute file, unsigned int line, unsigned int scopeLine, |
277 | uint64_t subprogramFlags, MlirAttribute type) { |
278 | return wrap(DISubprogramAttr::get( |
279 | unwrap(ctx), cast<DistinctAttr>(unwrap(id)), |
280 | cast<DICompileUnitAttr>(unwrap(compileUnit)), |
281 | cast<DIScopeAttr>(unwrap(scope)), cast<StringAttr>(unwrap(name)), |
282 | cast<StringAttr>(unwrap(linkageName)), cast<DIFileAttr>(unwrap(file)), |
283 | line, scopeLine, DISubprogramFlags(subprogramFlags), |
284 | cast<DISubroutineTypeAttr>(unwrap(type)))); |
285 | } |
286 | |
287 | MlirAttribute mlirLLVMDISubprogramAttrGetScope(MlirAttribute diSubprogram) { |
288 | return wrap(cast<DISubprogramAttr>(unwrap(diSubprogram)).getScope()); |
289 | } |
290 | |
291 | unsigned int mlirLLVMDISubprogramAttrGetLine(MlirAttribute diSubprogram) { |
292 | return cast<DISubprogramAttr>(unwrap(diSubprogram)).getLine(); |
293 | } |
294 | |
295 | unsigned int mlirLLVMDISubprogramAttrGetScopeLine(MlirAttribute diSubprogram) { |
296 | return cast<DISubprogramAttr>(unwrap(diSubprogram)).getScopeLine(); |
297 | } |
298 | |
299 | MlirAttribute |
300 | mlirLLVMDISubprogramAttrGetCompileUnit(MlirAttribute diSubprogram) { |
301 | return wrap(cast<DISubprogramAttr>(unwrap(diSubprogram)).getCompileUnit()); |
302 | } |
303 | |
304 | MlirAttribute mlirLLVMDISubprogramAttrGetFile(MlirAttribute diSubprogram) { |
305 | return wrap(cast<DISubprogramAttr>(unwrap(diSubprogram)).getFile()); |
306 | } |
307 | |
308 | MlirAttribute mlirLLVMDISubprogramAttrGetType(MlirAttribute diSubprogram) { |
309 | return wrap(cast<DISubprogramAttr>(unwrap(diSubprogram)).getType()); |
310 | } |
311 | |
312 | MlirAttribute mlirLLVMDIModuleAttrGet(MlirContext ctx, MlirAttribute file, |
313 | MlirAttribute scope, MlirAttribute name, |
314 | MlirAttribute configMacros, |
315 | MlirAttribute includePath, |
316 | MlirAttribute apinotes, unsigned int line, |
317 | bool isDecl) { |
318 | return wrap(DIModuleAttr::get( |
319 | unwrap(ctx), cast<DIFileAttr>(unwrap(file)), |
320 | cast<DIScopeAttr>(unwrap(scope)), cast<StringAttr>(unwrap(name)), |
321 | cast<StringAttr>(unwrap(configMacros)), |
322 | cast<StringAttr>(unwrap(includePath)), cast<StringAttr>(unwrap(apinotes)), |
323 | line, isDecl)); |
324 | } |
325 | |
326 | MlirAttribute mlirLLVMDIModuleAttrGetScope(MlirAttribute diModule) { |
327 | return wrap(cast<DIModuleAttr>(unwrap(diModule)).getScope()); |
328 | } |
329 | |