xref: /llvm-project/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td (revision 1c067a513c757b731434fd793351c52b49628489)
1//===-- LLVMAttrDefs.td - LLVM Attributes definition file --*- tablegen -*-===//
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#ifndef LLVMIR_ATTRDEFS
10#define LLVMIR_ATTRDEFS
11
12include "mlir/Dialect/LLVMIR/LLVMDialect.td"
13include "mlir/Dialect/LLVMIR/LLVMInterfaces.td"
14include "mlir/IR/AttrTypeBase.td"
15include "mlir/IR/CommonAttrConstraints.td"
16
17// All of the attributes will extend this class.
18class LLVM_Attr<string name, string attrMnemonic,
19                list<Trait> traits = [],
20                string baseCppClass = "::mlir::Attribute">
21    : AttrDef<LLVM_Dialect, name, traits, baseCppClass> {
22  let mnemonic = attrMnemonic;
23}
24
25//===----------------------------------------------------------------------===//
26// CConvAttr
27//===----------------------------------------------------------------------===//
28
29def CConvAttr : LLVM_Attr<"CConv", "cconv"> {
30  let parameters = (ins "CConv":$CallingConv);
31  let assemblyFormat = "`<` $CallingConv `>`";
32}
33
34//===----------------------------------------------------------------------===//
35// ComdatAttr
36//===----------------------------------------------------------------------===//
37
38def ComdatAttr : LLVM_Attr<"Comdat", "comdat"> {
39  let parameters = (ins "comdat::Comdat":$comdat);
40  let assemblyFormat = "$comdat";
41}
42
43//===----------------------------------------------------------------------===//
44// LinkageAttr
45//===----------------------------------------------------------------------===//
46
47def LinkageAttr : LLVM_Attr<"Linkage", "linkage"> {
48  let parameters = (ins "linkage::Linkage":$linkage);
49  let assemblyFormat = "`<` $linkage `>`";
50}
51
52//===----------------------------------------------------------------------===//
53// FramePointerKindAttr
54//===----------------------------------------------------------------------===//
55
56def FramePointerKindAttr : LLVM_Attr<"FramePointerKind", "framePointerKind"> {
57  let parameters = (ins "framePointerKind::FramePointerKind":$framePointerKind);
58  let assemblyFormat = "`<` $framePointerKind `>`";
59}
60
61//===----------------------------------------------------------------------===//
62// Loop Attributes
63//===----------------------------------------------------------------------===//
64
65def LoopVectorizeAttr : LLVM_Attr<"LoopVectorize", "loop_vectorize"> {
66  let description = [{
67    This attribute defines vectorization specific loop annotations that map to
68    the "!llvm.loop.vectorize" metadata.
69  }];
70
71  let parameters = (ins
72    OptionalParameter<"BoolAttr">:$disable,
73    OptionalParameter<"BoolAttr">:$predicateEnable,
74    OptionalParameter<"BoolAttr">:$scalableEnable,
75    OptionalParameter<"IntegerAttr">:$width,
76    OptionalParameter<"LoopAnnotationAttr">:$followupVectorized,
77    OptionalParameter<"LoopAnnotationAttr">:$followupEpilogue,
78    OptionalParameter<"LoopAnnotationAttr">:$followupAll
79  );
80
81  let assemblyFormat = "`<` struct(params) `>`";
82}
83
84def LoopInterleaveAttr : LLVM_Attr<"LoopInterleave", "loop_interleave"> {
85  let description = [{
86    This attribute defines interleaving specific loop annotations that map to
87    the "!llvm.loop.interleave" metadata.
88  }];
89
90  let parameters = (ins
91    "IntegerAttr":$count
92  );
93
94  let assemblyFormat = "`<` struct(params) `>`";
95}
96
97def LoopUnrollAttr : LLVM_Attr<"LoopUnroll", "loop_unroll"> {
98  let description = [{
99    This attribute defines unrolling specific loop annotations that map to
100    the "!llvm.loop.unroll" metadata.
101  }];
102
103  let parameters = (ins
104    OptionalParameter<"BoolAttr">:$disable,
105    OptionalParameter<"IntegerAttr">:$count,
106    OptionalParameter<"BoolAttr">:$runtimeDisable,
107    OptionalParameter<"BoolAttr">:$full,
108    OptionalParameter<"LoopAnnotationAttr">:$followupUnrolled,
109    OptionalParameter<"LoopAnnotationAttr">:$followupRemainder,
110    OptionalParameter<"LoopAnnotationAttr">:$followupAll
111  );
112
113  let assemblyFormat = "`<` struct(params) `>`";
114}
115
116def LoopUnrollAndJamAttr : LLVM_Attr<"LoopUnrollAndJam", "loop_unroll_and_jam"> {
117  let description = [{
118    This attribute defines "unroll and jam" specific loop annotations that map to
119    the "!llvm.loop.unroll_and_jam" metadata.
120  }];
121
122  let parameters = (ins
123    OptionalParameter<"BoolAttr">:$disable,
124    OptionalParameter<"IntegerAttr">:$count,
125    OptionalParameter<"LoopAnnotationAttr">:$followupOuter,
126    OptionalParameter<"LoopAnnotationAttr">:$followupInner,
127    OptionalParameter<"LoopAnnotationAttr">:$followupRemainderOuter,
128    OptionalParameter<"LoopAnnotationAttr">:$followupRemainderInner,
129    OptionalParameter<"LoopAnnotationAttr">:$followupAll
130  );
131
132  let assemblyFormat = "`<` struct(params) `>`";
133}
134
135def LoopLICMAttr : LLVM_Attr<"LoopLICM", "loop_licm"> {
136  let description = [{
137    This attribute encapsulates loop invariant code motion (licm) specific loop
138    annotations. The fields correspond to the "!llvm.licm.disable" and the
139    "!llvm.loop.licm_versioning.disable" metadata.
140  }];
141
142  let parameters = (ins
143    OptionalParameter<"BoolAttr">:$disable,
144    OptionalParameter<"BoolAttr">:$versioningDisable
145  );
146
147  let assemblyFormat = "`<` struct(params) `>`";
148}
149
150def LoopDistributeAttr : LLVM_Attr<"LoopDistribute", "loop_distribute"> {
151  let description = [{
152    This attribute defines distribution specific loop annotations that map to
153    the "!llvm.loop.distribute" metadata.
154  }];
155
156  let parameters = (ins
157    OptionalParameter<"BoolAttr">:$disable,
158    OptionalParameter<"LoopAnnotationAttr">:$followupCoincident,
159    OptionalParameter<"LoopAnnotationAttr">:$followupSequential,
160    OptionalParameter<"LoopAnnotationAttr">:$followupFallback,
161    OptionalParameter<"LoopAnnotationAttr">:$followupAll
162  );
163
164  let assemblyFormat = "`<` struct(params) `>`";
165}
166
167def LoopPipelineAttr : LLVM_Attr<"LoopPipeline", "loop_pipeline"> {
168  let description = [{
169    This attribute defines pipelining specific loop annotations that map to
170    the "!llvm.loop.pipeline" metadata.
171  }];
172
173  let parameters = (ins
174    OptionalParameter<"BoolAttr">:$disable,
175    OptionalParameter<"IntegerAttr">:$initiationinterval
176  );
177
178  let assemblyFormat = "`<` struct(params) `>`";
179}
180
181def LoopPeeledAttr : LLVM_Attr<"LoopPeeled", "loop_peeled"> {
182  let description = [{
183    This attribute defines pipelining specific loop annotations that map to
184    the "!llvm.loop.peeled" metadata.
185  }];
186
187  let parameters = (ins
188    OptionalParameter<"IntegerAttr">:$count
189  );
190
191  let assemblyFormat = "`<` struct(params) `>`";
192}
193
194def LoopUnswitchAttr : LLVM_Attr<"LoopUnswitch", "loop_unswitch"> {
195  let description = [{
196    This attribute defines pipelining specific loop annotations that map to
197    the "!llvm.loop.unswitch" metadata.
198  }];
199
200  let parameters = (ins
201    OptionalParameter<"BoolAttr">:$partialDisable
202  );
203
204  let assemblyFormat = "`<` struct(params) `>`";
205}
206
207def LoopAnnotationAttr : LLVM_Attr<"LoopAnnotation", "loop_annotation"> {
208  let description = [{
209    This attributes encapsulates "loop metadata". It is meant to decorate
210    branches that are "latches" (loop backedges) and maps to the `!llvm.loop`
211    metadatas: https://llvm.org/docs/LangRef.html#llvm-loop
212    It stores annotations in attribute parameters and groups related options in
213    nested attributes to provide structured access.
214  }];
215
216  let parameters = (ins
217    OptionalParameter<"BoolAttr">:$disableNonforced,
218    OptionalParameter<"LoopVectorizeAttr">:$vectorize,
219    OptionalParameter<"LoopInterleaveAttr">:$interleave,
220    OptionalParameter<"LoopUnrollAttr">:$unroll,
221    OptionalParameter<"LoopUnrollAndJamAttr">:$unrollAndJam,
222    OptionalParameter<"LoopLICMAttr">:$licm,
223    OptionalParameter<"LoopDistributeAttr">:$distribute,
224    OptionalParameter<"LoopPipelineAttr">:$pipeline,
225    OptionalParameter<"LoopPeeledAttr">:$peeled,
226    OptionalParameter<"LoopUnswitchAttr">:$unswitch,
227    OptionalParameter<"BoolAttr">:$mustProgress,
228    OptionalParameter<"BoolAttr">:$isVectorized,
229    OptionalParameter<"FusedLoc">:$startLoc,
230    OptionalParameter<"FusedLoc">:$endLoc,
231    OptionalArrayRefParameter<"AccessGroupAttr">:$parallelAccesses
232  );
233
234  let assemblyFormat = "`<` struct(params) `>`";
235}
236
237//===----------------------------------------------------------------------===//
238// DebugInfo Attributes
239//===----------------------------------------------------------------------===//
240
241class LLVM_DIParameter<string summary, string default, string parseName,
242                       string errorCase, string printName = parseName>
243    : AttrOrTypeParameter<"unsigned", "debug info " # summary> {
244  let parser = [{ [&]() -> FailureOr<unsigned> {
245    SMLoc tagLoc = $_parser.getCurrentLocation();
246    StringRef name;
247    if ($_parser.parseKeyword(&name))
248      return failure();
249
250    unsigned tag = llvm::dwarf::get}] # parseName # [{(name);
251    if (tag == }] # errorCase # [{)
252      return $_parser.emitError(tagLoc)
253        << "invalid debug info }] # summary # [{ name: " << name;
254    return tag;
255  }() }];
256  let printer = "$_printer << llvm::dwarf::" # printName # "String($_self)";
257  let defaultValue = default;
258}
259
260def LLVM_DICallingConventionParameter : LLVM_DIParameter<
261  "calling convention", /*default=*/"0", "CallingConvention", /*errorCase=*/"0",
262  "Convention"
263>;
264
265def LLVM_DIEncodingParameter : LLVM_DIParameter<
266  "encoding", /*default=*/"0", "AttributeEncoding", /*errorCase=*/"0"
267>;
268
269def LLVM_DILanguageParameter : LLVM_DIParameter<
270  "language", /*default=*/"", "Language", /*errorCase=*/"0"
271>;
272
273def LLVM_DITagParameter : LLVM_DIParameter<
274  "tag", /*default=*/"0", "Tag", /*errorCase=*/"llvm::dwarf::DW_TAG_invalid"
275>;
276
277def LLVM_DIOperationEncodingParameter : LLVM_DIParameter<
278  "operation encoding", /*default=*/"", "OperationEncoding", /*errorCase=*/"0"
279>;
280
281//===----------------------------------------------------------------------===//
282// DIExpressionAttr
283//===----------------------------------------------------------------------===//
284
285def LLVM_DIExpressionElemAttr : LLVM_Attr<"DIExpressionElem",
286                                          "di_expression_elem"> {
287  let parameters = (ins
288    LLVM_DIOperationEncodingParameter:$opcode,
289    OptionalArrayRefParameter<"uint64_t">:$arguments);
290  let assemblyFormat = [{
291    `` $opcode ( `(` custom<ExpressionArg>(ref($opcode), $arguments)^ `)` ) : (``)?
292  }];
293}
294
295def LLVM_DIExpressionAttr : LLVM_Attr<"DIExpression", "di_expression"> {
296  let parameters = (ins
297    OptionalArrayRefParameter<"DIExpressionElemAttr">:$operations
298  );
299  let builders = [
300    AttrBuilder<(ins)>
301  ];
302  let constBuilderCall =
303            "::mlir::LLVM::DIExpressionAttr::get($_builder.getContext(), $0)";
304  let assemblyFormat = "`<` ( `[` $operations^ `]` ) : (``)? `>`";
305}
306
307//===----------------------------------------------------------------------===//
308// DINullTypeAttr
309//===----------------------------------------------------------------------===//
310
311def LLVM_DINullTypeAttr : LLVM_Attr<"DINullType", "di_null_type",
312                                    /*traits=*/[], "DITypeAttr"> {
313  let parameters = (ins);
314}
315
316//===----------------------------------------------------------------------===//
317// DIBasicTypeAttr
318//===----------------------------------------------------------------------===//
319
320def LLVM_DIBasicTypeAttr : LLVM_Attr<"DIBasicType", "di_basic_type",
321                                     /*traits=*/[], "DITypeAttr"> {
322  let parameters = (ins
323    LLVM_DITagParameter:$tag,
324    "StringAttr":$name,
325    OptionalParameter<"uint64_t">:$sizeInBits,
326    LLVM_DIEncodingParameter:$encoding
327  );
328
329  let builders = [
330    TypeBuilder<(ins
331      "unsigned":$tag, "const Twine &":$name, "uint64_t":$sizeInBits,
332      "unsigned":$encoding
333    ), [{
334      return $_get($_ctxt, tag, StringAttr::get($_ctxt, name), sizeInBits,
335                   encoding);
336    }]>
337  ];
338  let assemblyFormat = "`<` struct(params) `>`";
339}
340
341//===----------------------------------------------------------------------===//
342// DICompileUnitAttr
343//===----------------------------------------------------------------------===//
344
345def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
346                                       /*traits=*/[], "DIScopeAttr"> {
347  let parameters = (ins
348    "DistinctAttr":$id,
349    LLVM_DILanguageParameter:$sourceLanguage,
350    "DIFileAttr":$file,
351    OptionalParameter<"StringAttr">:$producer,
352    "bool":$isOptimized,
353    "DIEmissionKind":$emissionKind,
354    OptionalParameter<"DINameTableKind">:$nameTableKind
355  );
356  let builders = [
357    AttrBuilderWithInferredContext<(ins
358      "DistinctAttr":$id, "unsigned":$sourceLanguage, "DIFileAttr":$file,
359      "StringAttr":$producer, "bool":$isOptimized,
360      "DIEmissionKind":$emissionKind,
361      CArg<"DINameTableKind", "DINameTableKind::Default">:$nameTableKind
362    ), [{
363      return $_get(id.getContext(), id, sourceLanguage, file, producer,
364                   isOptimized, emissionKind, nameTableKind);
365    }]>
366  ];
367  let assemblyFormat = "`<` struct(params) `>`";
368}
369
370//===----------------------------------------------------------------------===//
371// DICompositeTypeAttr
372//===----------------------------------------------------------------------===//
373
374def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type",
375                                         [LLVM_DIRecursiveTypeAttrInterface],
376                                         "DITypeAttr"> {
377  let parameters = (ins
378    // DIRecursiveTypeAttrInterface specific parameters.
379    OptionalParameter<"DistinctAttr">:$recId,
380    OptionalParameter<"bool">:$isRecSelf,
381    // DICompositeType specific parameters.
382    LLVM_DITagParameter:$tag,
383    OptionalParameter<"StringAttr">:$name,
384    OptionalParameter<"DIFileAttr">:$file,
385    OptionalParameter<"uint32_t">:$line,
386    OptionalParameter<"DIScopeAttr">:$scope,
387    OptionalParameter<"DITypeAttr">:$baseType,
388    OptionalParameter<"DIFlags">:$flags,
389    OptionalParameter<"uint64_t">:$sizeInBits,
390    OptionalParameter<"uint64_t">:$alignInBits,
391    OptionalArrayRefParameter<"DINodeAttr">:$elements,
392    OptionalParameter<"DIExpressionAttr">:$dataLocation,
393    OptionalParameter<"DIExpressionAttr">:$rank,
394    OptionalParameter<"DIExpressionAttr">:$allocated,
395    OptionalParameter<"DIExpressionAttr">:$associated
396  );
397  let builders = [
398    AttrBuilder<(ins
399      "unsigned":$tag, "StringAttr":$name, "DIFileAttr":$file,
400      "uint32_t":$line, "DIScopeAttr":$scope, "DITypeAttr":$baseType,
401      "DIFlags":$flags, "uint64_t":$sizeInBits, "uint64_t":$alignInBits,
402      "ArrayRef<DINodeAttr>":$elements, "DIExpressionAttr":$dataLocation,
403      "DIExpressionAttr":$rank, "DIExpressionAttr":$allocated,
404      "DIExpressionAttr":$associated
405    ), [{
406      return $_get($_ctxt, /*recId=*/nullptr, /*isRecSelf=*/nullptr,
407                   tag, name, file, line, scope, baseType, flags, sizeInBits,
408                   alignInBits, elements, dataLocation, rank, allocated,
409                   associated);
410    }]>
411  ];
412  let assemblyFormat = "`<` struct(params) `>`";
413  let extraClassDeclaration = [{
414    /// Requirements of DIRecursiveTypeAttrInterface.
415    /// @{
416
417    /// Get a copy of this type attr but with the recursive ID set to `recId`.
418    DIRecursiveTypeAttrInterface withRecId(DistinctAttr recId);
419
420    /// Build a rec-self instance using the provided `recId`.
421    static DIRecursiveTypeAttrInterface getRecSelf(DistinctAttr recId);
422
423    /// @}
424  }];
425}
426
427//===----------------------------------------------------------------------===//
428// DIDerivedTypeAttr
429//===----------------------------------------------------------------------===//
430
431def LLVM_DIDerivedTypeAttr : LLVM_Attr<"DIDerivedType", "di_derived_type",
432                                       /*traits=*/[], "DITypeAttr"> {
433  let parameters = (ins
434    LLVM_DITagParameter:$tag,
435    OptionalParameter<"StringAttr">:$name,
436    OptionalParameter<"DITypeAttr">:$baseType,
437    OptionalParameter<"uint64_t">:$sizeInBits,
438    OptionalParameter<"uint32_t">:$alignInBits,
439    OptionalParameter<"uint64_t">:$offsetInBits,
440    OptionalParameter<"std::optional<unsigned>">:$dwarfAddressSpace,
441    OptionalParameter<"DINodeAttr">:$extraData
442  );
443  let assemblyFormat = "`<` struct(params) `>`";
444}
445
446//===----------------------------------------------------------------------===//
447// DIFileAttr
448//===----------------------------------------------------------------------===//
449
450def LLVM_DIFileAttr : LLVM_Attr<"DIFile", "di_file", /*traits=*/[], "DIScopeAttr"> {
451  let parameters = (ins "StringAttr":$name, "StringAttr":$directory);
452  let builders = [AttrBuilder<(ins "StringRef":$name, "StringRef":$directory), [{
453      return $_get($_ctxt, StringAttr::get($_ctxt, name),
454                   StringAttr::get($_ctxt, directory));
455    }]>
456  ];
457  let assemblyFormat = "`<` $name `in` $directory `>`";
458}
459
460//===----------------------------------------------------------------------===//
461// DIGlobalVariableExpressionAttr
462//===----------------------------------------------------------------------===//
463
464def LLVM_DIGlobalVariableExpressionAttr
465    : LLVM_Attr<"DIGlobalVariableExpression", "di_global_variable_expression"> {
466  let parameters = (ins
467    "DIGlobalVariableAttr":$var,
468    OptionalParameter<"DIExpressionAttr">:$expr
469  );
470  let assemblyFormat = "`<` struct(params) `>`";
471  let constBuilderCall = "$0";
472}
473
474def DIGlobalVariableExpressionArrayAttr :
475  TypedArrayAttrBase<LLVM_DIGlobalVariableExpressionAttr,
476  "an array of variable expressions">;
477
478//===----------------------------------------------------------------------===//
479// DIGlobalVariableAttr
480//===----------------------------------------------------------------------===//
481
482def LLVM_DIGlobalVariable : LLVM_Attr<"DIGlobalVariable", "di_global_variable",
483                                      /*traits=*/[], "DINodeAttr"> {
484  let parameters = (ins
485    OptionalParameter<"DIScopeAttr">:$scope,
486    OptionalParameter<"StringAttr">:$name,
487    OptionalParameter<"StringAttr">:$linkageName,
488    "DIFileAttr":$file,
489    "unsigned":$line,
490    "DITypeAttr":$type,
491    OptionalParameter<"bool">:$isLocalToUnit,
492    OptionalParameter<"bool">:$isDefined,
493    OptionalParameter<"unsigned">:$alignInBits);
494  let assemblyFormat = "`<` struct(params) `>`";
495}
496
497//===----------------------------------------------------------------------===//
498// DILexicalBlockAttr
499//===----------------------------------------------------------------------===//
500
501def LLVM_DILexicalBlockAttr : LLVM_Attr<"DILexicalBlock", "di_lexical_block",
502                                        /*traits=*/[], "DIScopeAttr"> {
503  let parameters = (ins
504    "DIScopeAttr":$scope,
505    OptionalParameter<"DIFileAttr">:$file,
506    OptionalParameter<"unsigned">:$line,
507    OptionalParameter<"unsigned">:$column
508  );
509  let builders = [
510    AttrBuilderWithInferredContext<(ins
511      "DIScopeAttr":$scope, "DIFileAttr":$file, "unsigned":$line,
512      "unsigned":$column
513    ), [{
514      return $_get(scope.getContext(), scope, file, line, column);
515    }]>
516  ];
517  let assemblyFormat = "`<` struct(params) `>`";
518}
519
520//===----------------------------------------------------------------------===//
521// DILexicalBlockFileAttr
522//===----------------------------------------------------------------------===//
523
524def LLVM_DILexicalBlockFile : LLVM_Attr<"DILexicalBlockFile", "di_lexical_block_file",
525                                        /*traits=*/[], "DIScopeAttr"> {
526  let parameters = (ins
527    "DIScopeAttr":$scope,
528    OptionalParameter<"DIFileAttr">:$file,
529    "unsigned":$discriminator
530  );
531  let builders = [
532    AttrBuilderWithInferredContext<(ins
533      "DIScopeAttr":$scope, "DIFileAttr":$file, "unsigned":$discriminator
534    ), [{
535      return $_get(scope.getContext(), scope, file, discriminator);
536    }]>
537  ];
538  let assemblyFormat = "`<` struct(params) `>`";
539}
540
541//===----------------------------------------------------------------------===//
542// DILocalVariableAttr
543//===----------------------------------------------------------------------===//
544
545def LLVM_DILocalVariableAttr : LLVM_Attr<"DILocalVariable", "di_local_variable",
546                                         /*traits=*/[], "DINodeAttr"> {
547  let parameters = (ins
548    "DIScopeAttr":$scope,
549    OptionalParameter<"StringAttr">:$name,
550    OptionalParameter<"DIFileAttr">:$file,
551    OptionalParameter<"unsigned">:$line,
552    OptionalParameter<"unsigned">:$arg,
553    OptionalParameter<"unsigned">:$alignInBits,
554    OptionalParameter<"DITypeAttr">:$type,
555    OptionalParameter<"DIFlags", "DIFlags::Zero">:$flags
556  );
557  let builders = [
558    AttrBuilderWithInferredContext<(ins
559      "DIScopeAttr":$scope, "StringRef":$name, "DIFileAttr":$file,
560      "unsigned":$line, "unsigned":$arg, "unsigned":$alignInBits,
561      "DITypeAttr":$type, "DIFlags":$flags
562    ), [{
563      MLIRContext *ctx = scope.getContext();
564      return $_get(ctx, scope, StringAttr::get(ctx, name), file, line,
565                   arg, alignInBits, type, flags);
566    }]>
567  ];
568  let assemblyFormat = "`<` struct(params) `>`";
569}
570
571//===----------------------------------------------------------------------===//
572// DISubprogramAttr
573//===----------------------------------------------------------------------===//
574
575def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram",
576                                      [LLVM_DIRecursiveTypeAttrInterface],
577                                      "DIScopeAttr"> {
578  let parameters = (ins
579    // DIRecursiveTypeAttrInterface specific parameters.
580    OptionalParameter<"DistinctAttr">:$recId,
581    OptionalParameter<"bool">:$isRecSelf,
582    // DISubprogramAttr specific parameters.
583    OptionalParameter<"DistinctAttr">:$id,
584    OptionalParameter<"DICompileUnitAttr">:$compileUnit,
585    OptionalParameter<"DIScopeAttr">:$scope,
586    OptionalParameter<"StringAttr">:$name,
587    OptionalParameter<"StringAttr">:$linkageName,
588    OptionalParameter<"DIFileAttr">:$file,
589    OptionalParameter<"unsigned">:$line,
590    OptionalParameter<"unsigned">:$scopeLine,
591    OptionalParameter<"DISubprogramFlags">:$subprogramFlags,
592    OptionalParameter<"DISubroutineTypeAttr">:$type,
593    OptionalArrayRefParameter<"DINodeAttr">:$retainedNodes,
594    OptionalArrayRefParameter<"DINodeAttr">:$annotations
595  );
596  let builders = [
597    AttrBuilder<(ins
598      "DistinctAttr":$id, "DICompileUnitAttr":$compileUnit,
599      "DIScopeAttr":$scope, "StringAttr":$name, "StringAttr":$linkageName,
600      "DIFileAttr":$file, "unsigned":$line, "unsigned":$scopeLine,
601      "DISubprogramFlags":$subprogramFlags, "DISubroutineTypeAttr":$type,
602      "ArrayRef<DINodeAttr>":$retainedNodes, "ArrayRef<DINodeAttr>":$annotations
603    ), [{
604      return $_get($_ctxt, /*recId=*/nullptr, /*isRecSelf=*/false, id, compileUnit,
605                   scope, name, linkageName, file, line, scopeLine,
606                   subprogramFlags, type, retainedNodes, annotations);
607    }]>
608  ];
609  let assemblyFormat = "`<` struct(params) `>`";
610  let extraClassDeclaration = [{
611    /// Requirements of DIRecursiveTypeAttrInterface.
612    /// @{
613
614    /// Get a copy of this type attr but with the recursive ID set to `recId`.
615    DIRecursiveTypeAttrInterface withRecId(DistinctAttr recId);
616
617    /// Build a rec-self instance using the provided `recId`.
618    static DIRecursiveTypeAttrInterface getRecSelf(DistinctAttr recId);
619
620    /// @}
621  }];
622}
623
624//===----------------------------------------------------------------------===//
625// DIModuleAttr
626//===----------------------------------------------------------------------===//
627
628def LLVM_DIModuleAttr : LLVM_Attr<"DIModule", "di_module",
629                                      /*traits=*/[], "DIScopeAttr"> {
630  let parameters = (ins
631    OptionalParameter<"DIFileAttr">:$file,
632    OptionalParameter<"DIScopeAttr">:$scope,
633    OptionalParameter<"StringAttr">:$name,
634    OptionalParameter<"StringAttr">:$configMacros,
635    OptionalParameter<"StringAttr">:$includePath,
636    OptionalParameter<"StringAttr">:$apinotes,
637    OptionalParameter<"unsigned">:$line,
638    OptionalParameter<"bool">:$isDecl
639  );
640
641  let assemblyFormat = "`<` struct(params) `>`";
642}
643
644//===----------------------------------------------------------------------===//
645// DINamespaceAttr
646//===----------------------------------------------------------------------===//
647
648def LLVM_DINamespaceAttr : LLVM_Attr<"DINamespace", "di_namespace",
649                                      /*traits=*/[], "DIScopeAttr"> {
650  let parameters = (ins
651    OptionalParameter<"StringAttr">:$name,
652    OptionalParameter<"DIScopeAttr">:$scope,
653    "bool":$exportSymbols
654  );
655
656  let assemblyFormat = "`<` struct(params) `>`";
657}
658
659//===----------------------------------------------------------------------===//
660// DIImportedEntityAttr
661//===----------------------------------------------------------------------===//
662
663def LLVM_DIImportedEntityAttr : LLVM_Attr<"DIImportedEntity", "di_imported_entity",
664                                           /*traits=*/[], "DINodeAttr"> {
665  let parameters = (ins
666    LLVM_DITagParameter:$tag,
667    "DIScopeAttr":$scope,
668    "DINodeAttr":$entity,
669    OptionalParameter<"DIFileAttr">:$file,
670    OptionalParameter<"unsigned">:$line,
671    OptionalParameter<"StringAttr">:$name,
672    OptionalArrayRefParameter<"DINodeAttr">:$elements
673  );
674
675  let assemblyFormat = "`<` struct(params) `>`";
676}
677
678//===----------------------------------------------------------------------===//
679// DIAnnotationAttr
680//===----------------------------------------------------------------------===//
681
682def LLVM_DIAnnotationAttr : LLVM_Attr<"DIAnnotation",
683                                      "di_annotation",
684                                      /*traits=*/[], "DINodeAttr"> {
685  let parameters = (ins
686    "StringAttr":$name,
687    "StringAttr":$value
688  );
689
690  let assemblyFormat = "`<` struct(params) `>`";
691}
692
693//===----------------------------------------------------------------------===//
694// DISubrangeAttr
695//===----------------------------------------------------------------------===//
696
697def LLVM_DISubrangeAttr : LLVM_Attr<"DISubrange", "di_subrange", /*traits=*/[],
698                                    "DINodeAttr"> {
699  let parameters = (ins
700    OptionalParameter<"::mlir::Attribute">:$count,
701    OptionalParameter<"::mlir::Attribute">:$lowerBound,
702    OptionalParameter<"::mlir::Attribute">:$upperBound,
703    OptionalParameter<"::mlir::Attribute">:$stride
704  );
705  let assemblyFormat = "`<` struct(params) `>`";
706}
707
708//===----------------------------------------------------------------------===//
709// DICommonBlockAttr
710//===----------------------------------------------------------------------===//
711
712def LLVM_DICommonBlockAttr : LLVM_Attr<"DICommonBlock", "di_common_block",
713                                       /*traits=*/[], "DIScopeAttr"> {
714  let parameters = (ins
715    "DIScopeAttr":$scope,
716    OptionalParameter<"DIGlobalVariableAttr">:$decl,
717    "StringAttr":$name,
718    OptionalParameter<"DIFileAttr">:$file,
719    OptionalParameter<"unsigned">:$line
720  );
721  let assemblyFormat = "`<` struct(params) `>`";
722}
723
724//===----------------------------------------------------------------------===//
725// DIGenericSubrangeAttr
726//===----------------------------------------------------------------------===//
727
728def LLVM_DIGenericSubrangeAttr : LLVM_Attr<"DIGenericSubrange",
729                                           "di_generic_subrange", /*traits=*/[],
730                                           "DINodeAttr"> {
731  let parameters = (ins
732    OptionalParameter<"::mlir::Attribute">:$count,
733    "::mlir::Attribute":$lowerBound,
734    OptionalParameter<"::mlir::Attribute">:$upperBound,
735    "::mlir::Attribute":$stride
736  );
737  let assemblyFormat = "`<` struct(params) `>`";
738}
739
740//===----------------------------------------------------------------------===//
741// DISubroutineTypeAttr
742//===----------------------------------------------------------------------===//
743
744def LLVM_DISubroutineTypeAttr : LLVM_Attr<"DISubroutineType", "di_subroutine_type",
745                                          /*traits=*/[], "DITypeAttr"> {
746  let parameters = (ins
747    LLVM_DICallingConventionParameter:$callingConvention,
748    OptionalArrayRefParameter<"DITypeAttr">:$types
749  );
750  let builders = [
751    TypeBuilder<(ins "ArrayRef<DITypeAttr>":$types), [{
752      return $_get($_ctxt, /*callingConvention=*/0, types);
753    }]>
754  ];
755  let assemblyFormat = "`<` struct(params) `>`";
756}
757
758//===----------------------------------------------------------------------===//
759// DILabelAttr
760//===----------------------------------------------------------------------===//
761
762def LLVM_DILabelAttr : LLVM_Attr<"DILabel", "di_label",
763                                 /*traits=*/[], "DINodeAttr"> {
764  let parameters = (ins
765    "DIScopeAttr":$scope,
766    OptionalParameter<"StringAttr">:$name,
767    OptionalParameter<"DIFileAttr">:$file,
768    OptionalParameter<"unsigned">:$line
769  );
770  let builders = [
771    AttrBuilderWithInferredContext<(ins
772      "DIScopeAttr":$scope, "StringRef":$name, "DIFileAttr":$file,
773      "unsigned":$line
774    ), [{
775      MLIRContext *ctx = scope.getContext();
776      return $_get(ctx, scope, StringAttr::get(ctx, name), file, line);
777    }]>
778  ];
779
780  let assemblyFormat = "`<` struct(params) `>`";
781}
782
783//===----------------------------------------------------------------------===//
784// DIStringTypeAttr
785//===----------------------------------------------------------------------===//
786
787def LLVM_DIStringTypeAttr : LLVM_Attr<"DIStringType", "di_string_type",
788                                     /*traits=*/[], "DITypeAttr"> {
789  let parameters = (ins
790    LLVM_DITagParameter:$tag,
791    "StringAttr":$name,
792    OptionalParameter<"uint64_t">:$sizeInBits,
793    OptionalParameter<"uint32_t">:$alignInBits,
794    OptionalParameter<"DIVariableAttr">:$stringLength,
795    OptionalParameter<"DIExpressionAttr">:$stringLengthExp,
796    OptionalParameter<"DIExpressionAttr">:$stringLocationExp,
797    LLVM_DIEncodingParameter:$encoding
798  );
799  let assemblyFormat = "`<` struct(params) `>`";
800}
801
802//===----------------------------------------------------------------------===//
803// MemoryEffectsAttr
804//===----------------------------------------------------------------------===//
805
806def LLVM_MemoryEffectsAttr : LLVM_Attr<"MemoryEffects", "memory_effects"> {
807  let parameters = (ins
808    "ModRefInfo":$other,
809    "ModRefInfo":$argMem,
810    "ModRefInfo":$inaccessibleMem
811  );
812  let extraClassDeclaration = [{
813    bool isReadWrite();
814  }];
815  let builders = [
816    TypeBuilder<(ins "ArrayRef<ModRefInfo>":$memInfoArgs)>
817  ];
818  let assemblyFormat = "`<` struct(params) `>`";
819}
820
821//===----------------------------------------------------------------------===//
822// AliasScopeDomainAttr
823//===----------------------------------------------------------------------===//
824
825def LLVM_AliasScopeDomainAttr : LLVM_Attr<"AliasScopeDomain",
826                                          "alias_scope_domain"> {
827  let parameters = (ins
828    "Attribute":$id,
829    OptionalParameter<"StringAttr">:$description
830  );
831
832  let builders = [
833    AttrBuilder<(ins CArg<"StringAttr", "{}">:$description), [{
834      return $_get($_ctxt, DistinctAttr::create(UnitAttr::get($_ctxt)), description);
835    }]>
836  ];
837
838  let summary = "LLVM dialect alias scope domain metadata";
839
840  let description = [{
841    Defines a domain that may be associated with an alias scope.
842
843    See the following link for more details:
844    https://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata
845  }];
846
847  let assemblyFormat = "`<` struct(params) `>`";
848}
849
850//===----------------------------------------------------------------------===//
851// AliasScopeAttr
852//===----------------------------------------------------------------------===//
853
854def LLVM_AliasScopeAttr : LLVM_Attr<"AliasScope", "alias_scope"> {
855  let parameters = (ins
856    "Attribute":$id,
857    "AliasScopeDomainAttr":$domain,
858    OptionalParameter<"StringAttr">:$description
859  );
860
861  let builders = [
862    AttrBuilderWithInferredContext<(ins
863      "AliasScopeDomainAttr":$domain,
864      CArg<"StringAttr", "{}">:$description
865    ), [{
866      MLIRContext *ctx = domain.getContext();
867      return $_get(ctx, DistinctAttr::create(UnitAttr::get(ctx)), domain, description);
868    }]>
869  ];
870
871  let description = [{
872    Defines an alias scope that can be attached to a memory-accessing operation.
873    Such scopes can be used in combination with `noalias` metadata to indicate
874    that sets of memory-affecting operations in one scope do not alias with
875    memory-affecting operations in another scope.
876
877    Example:
878    ```mlir
879    #domain = #llvm.alias_scope_domain<id = distinct[1]<>, description = "Optional domain description">
880    #scope1 = #llvm.alias_scope<id = distinct[2]<>, domain = #domain>
881    #scope2 = #llvm.alias_scope<id = distinct[3]<>, domain = #domain, description = "Optional scope description">
882    llvm.func @foo(%ptr1 : !llvm.ptr) {
883        %c0 = llvm.mlir.constant(0 : i32) : i32
884        %c4 = llvm.mlir.constant(4 : i32) : i32
885        %1 = llvm.ptrtoint %ptr1 : !llvm.ptr to i32
886        %2 = llvm.add %1, %c1 : i32
887        %ptr2 = llvm.inttoptr %2 : i32 to !llvm.ptr
888        llvm.store %c0, %ptr1 { alias_scopes = [#scope1], llvm.noalias = [#scope2] } : i32, !llvm.ptr
889        llvm.store %c4, %ptr2 { alias_scopes = [#scope2], llvm.noalias = [#scope1] } : i32, !llvm.ptr
890        llvm.return
891    }
892    ```
893
894    The first attribute can either be a DistinctAttr or a StringAttr.
895
896    See the following link for more details:
897    https://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata
898  }];
899
900  let summary = "LLVM dialect alias scope";
901
902  let assemblyFormat = "`<` struct(params) `>`";
903
904  let genVerifyDecl = 1;
905}
906
907def LLVM_AliasScopeArrayAttr
908    : TypedArrayAttrBase<LLVM_AliasScopeAttr,
909                         LLVM_AliasScopeAttr.summary # " array"> {
910  let constBuilderCall = ?;
911}
912
913//===----------------------------------------------------------------------===//
914// AccessGroupAttr
915//===----------------------------------------------------------------------===//
916
917def LLVM_AccessGroupAttr : LLVM_Attr<"AccessGroup", "access_group"> {
918
919  let parameters = (ins "DistinctAttr":$id);
920
921  let builders = [
922    AttrBuilder<(ins), [{
923      return $_get($_ctxt, DistinctAttr::create(UnitAttr::get($_ctxt)));
924    }]>
925  ];
926
927  let summary = "LLVM dialect access group metadata";
928
929  let description = [{
930    Defines an access group metadata that can be set on any instruction
931    that potentially accesses memory via the `AccessGroupOpInterface` or on
932    branch instructions in the loop latch block via the `parallelAccesses`
933    parameter of `LoopAnnotationAttr`.
934
935    See the following link for more details:
936    https://llvm.org/docs/LangRef.html#llvm-access-group-metadata
937  }];
938
939  let assemblyFormat = "`<` struct(params) `>`";
940}
941
942def LLVM_AccessGroupArrayAttr
943    : TypedArrayAttrBase<LLVM_AccessGroupAttr,
944                         LLVM_AccessGroupAttr.summary # " array"> {
945  let constBuilderCall = ?;
946}
947
948//===----------------------------------------------------------------------===//
949// TBAARootAttr
950//===----------------------------------------------------------------------===//
951
952def LLVM_TBAARootAttr : LLVM_Attr<"TBAARoot", "tbaa_root", [], "TBAANodeAttr"> {
953  let parameters = (ins OptionalParameter<"StringAttr">:$id);
954
955  let summary = "LLVM dialect TBAA root metadata";
956  let description = [{
957    Defines a TBAA root node.
958
959    Example:
960    ```mlir
961    #cpp_root = #llvm.tbaa_root<identity = "Simple C/C++ TBAA">
962    #other_root = #llvm.tbaa_root
963    ```
964
965    See the following link for more details:
966    https://llvm.org/docs/LangRef.html#tbaa-metadata
967  }];
968
969  let assemblyFormat = "(`<` struct(params)^ `>`)?";
970}
971
972//===----------------------------------------------------------------------===//
973// TBAATypeDescriptorAttr
974//===----------------------------------------------------------------------===//
975
976def LLVM_TBAAMemberAttr : LLVM_Attr<"TBAAMember", "tbaa_member"> {
977  let parameters = (ins
978    "TBAANodeAttr":$typeDesc,
979    "int64_t":$offset
980  );
981
982  let builders = [
983    AttrBuilderWithInferredContext<(ins "TBAANodeAttr":$typeDesc,
984                                        "int64_t":$offset), [{
985      return $_get(typeDesc.getContext(), typeDesc, offset);
986    }]>
987  ];
988
989  let assemblyFormat = "`<` params `>`";
990}
991
992def LLVM_TBAAMemberAttrArray : ArrayRefParameter<"TBAAMemberAttr"> {
993  let printer = [{
994    $_printer << '{';
995    llvm::interleaveComma($_self, $_printer, [&](TBAAMemberAttr attr) {
996        $_printer.printStrippedAttrOrType(attr);
997    });
998    $_printer << '}';
999  }];
1000
1001  let parser = [{
1002    [&]() -> FailureOr<SmallVector<TBAAMemberAttr>> {
1003        using Result = SmallVector<TBAAMemberAttr>;
1004        if ($_parser.parseLBrace())
1005            return failure();
1006        FailureOr<Result> result = FieldParser<Result>::parse($_parser);
1007        if (failed(result))
1008            return failure();
1009        if ($_parser.parseRBrace())
1010            return failure();
1011        return result;
1012    }()
1013  }];
1014}
1015
1016def LLVM_TBAATypeDescriptorAttr : LLVM_Attr<"TBAATypeDescriptor",
1017    "tbaa_type_desc", [], "TBAANodeAttr"> {
1018  let parameters = (ins
1019    StringRefParameter<>:$id,
1020    LLVM_TBAAMemberAttrArray:$members
1021  );
1022
1023  let summary = "LLVM dialect TBAA type metadata";
1024
1025  let description = [{
1026    Defines a TBAA node describing a type.
1027
1028    Example:
1029    ```mlir
1030    #tbaa_root = #llvm.tbaa_root<identity = "Simple C/C++ TBAA">
1031    #tbaa_type_desc1 = #llvm.tbaa_type_desc<id = "omnipotent char", members = {<#tbaa_root, 0>}>
1032    #tbaa_type_desc2 = #llvm.tbaa_type_desc<id = "long long", members = {<#tbaa_root, 0>}>
1033    #tbaa_type_desc3 = #llvm.tbaa_type_desc<id = "agg2_t", members = {<#tbaa_type_desc2, 0>, <#tbaa_type_desc2, 8>}>
1034    #tbaa_type_desc4 = #llvm.tbaa_type_desc<id = "int", members = {<#tbaa_type_desc1, 0>}>
1035    #tbaa_type_desc5 = #llvm.tbaa_type_desc<id = "agg1_t", members = {<#tbaa_type_desc4, 0>, <#tbaa_type_desc4, 4>}>
1036    ```
1037
1038    See the following link for more details:
1039    https://llvm.org/docs/LangRef.html#tbaa-metadata
1040  }];
1041
1042  let assemblyFormat = "`<` struct(params) `>`";
1043}
1044
1045//===----------------------------------------------------------------------===//
1046// TBAATagAttr
1047//===----------------------------------------------------------------------===//
1048
1049def LLVM_TBAATagAttr : LLVM_Attr<"TBAATag", "tbaa_tag"> {
1050  let parameters = (ins
1051    "TBAATypeDescriptorAttr":$base_type,
1052    "TBAATypeDescriptorAttr":$access_type,
1053    "int64_t":$offset,
1054    DefaultValuedParameter<"bool", "false">:$constant
1055  );
1056
1057  let builders = [
1058    AttrBuilderWithInferredContext<(ins "TBAATypeDescriptorAttr":$baseType,
1059                                        "TBAATypeDescriptorAttr":$accessType,
1060                                        "int64_t":$offset), [{
1061      return $_get(baseType.getContext(), baseType, accessType, offset,
1062                    /*constant=*/false);
1063    }]>
1064  ];
1065
1066  let summary = "LLVM dialect TBAA tag metadata";
1067
1068  let description = [{
1069    Defines a TBAA node describing a memory access.
1070
1071    Example:
1072    ```mlir
1073    #tbaa_root = #llvm.tbaa_root<identity = "Simple C/C++ TBAA">
1074    #tbaa_type_desc1 = #llvm.tbaa_type_desc<id = "omnipotent char", members = {<#tbaa_root, 0>}>
1075    #tbaa_type_desc2 = #llvm.tbaa_type_desc<id = "int", members = {<#tbaa_type_desc1, 0>}>
1076    #tbaa_type_desc3 = #llvm.tbaa_type_desc<id = "agg1_t", members = {<#tbaa_type_desc4, 0>, <#tbaa_type_desc4, 4>}>
1077    #tbaa_tag = #llvm.tbaa_tag<base_type = #tbaa_type_desc3, access_type = #tbaa_type_desc2, offset = 0, constant = true>
1078    ```
1079
1080    See the following link for more details:
1081    https://llvm.org/docs/LangRef.html#tbaa-metadata
1082  }];
1083
1084  let assemblyFormat = "`<` struct(params) `>`";
1085}
1086
1087def LLVM_TBAATagArrayAttr
1088    : TypedArrayAttrBase<LLVM_TBAATagAttr,
1089                         LLVM_TBAATagAttr.summary # " array"> {
1090  let constBuilderCall = ?;
1091}
1092
1093//===----------------------------------------------------------------------===//
1094// ConstantRangeAttr
1095//===----------------------------------------------------------------------===//
1096def LLVM_ConstantRangeAttr : LLVM_Attr<"ConstantRange", "constant_range"> {
1097  let parameters = (ins
1098    "::llvm::APInt":$lower,
1099    "::llvm::APInt":$upper
1100  );
1101  let summary = "A range of two integers, corresponding to LLVM's ConstantRange";
1102  let description = [{
1103    A pair of two integers, mapping to the ConstantRange structure in LLVM IR,
1104    which is allowed to wrap or be empty.
1105
1106    The range represented is [Lower, Upper), and is either signed or unsigned
1107    depending on context.
1108
1109    `lower` and `upper` must have the same width.
1110
1111    Syntax:
1112    ```
1113    `<` `i`(width($lower)) $lower `,` $upper `>`
1114    ```
1115  }];
1116
1117  let builders = [
1118    AttrBuilder<(ins "uint32_t":$bitWidth, "int64_t":$lower, "int64_t":$upper), [{
1119      return $_get($_ctxt, ::llvm::APInt(bitWidth, lower), ::llvm::APInt(bitWidth, upper));
1120    }]>
1121  ];
1122
1123  let hasCustomAssemblyFormat = 1;
1124  let genVerifyDecl = 1;
1125}
1126
1127
1128//===----------------------------------------------------------------------===//
1129// VScaleRangeAttr
1130//===----------------------------------------------------------------------===//
1131
1132def LLVM_VScaleRangeAttr : LLVM_Attr<"VScaleRange", "vscale_range"> {
1133  let parameters =  (ins
1134    "IntegerAttr":$minRange,
1135    "IntegerAttr":$maxRange);
1136  let assemblyFormat = "`<` struct(params) `>`";
1137}
1138
1139//===----------------------------------------------------------------------===//
1140// TargetFeaturesAttr
1141//===----------------------------------------------------------------------===//
1142
1143def LLVM_TargetFeaturesAttr : LLVM_Attr<"TargetFeatures", "target_features">
1144{
1145  let summary = "LLVM target features attribute";
1146
1147  let description = [{
1148    Represents the LLVM target features as a list that can be checked within
1149    passes/rewrites.
1150
1151    Example:
1152    ```mlir
1153    #llvm.target_features<["+sme", "+sve", "+sme-f64f64"]>
1154    ```
1155
1156    Then within a pass or rewrite the features active at an op can be queried:
1157
1158    ```c++
1159    auto targetFeatures = LLVM::TargetFeaturesAttr::featuresAt(op);
1160
1161    if (!targetFeatures.contains("+sme-f64f64"))
1162      return failure();
1163    ```
1164  }];
1165
1166  let parameters = (ins OptionalArrayRefParameter<"StringAttr">:$features);
1167
1168  let builders = [
1169    TypeBuilder<(ins "::llvm::StringRef":$features)>,
1170    TypeBuilder<(ins "::llvm::ArrayRef<::llvm::StringRef>":$features)>
1171  ];
1172
1173  let extraClassDeclaration = [{
1174    /// Checks if a feature is contained within the features list.
1175    /// Note: Using a StringAttr allows doing pointer-comparisons.
1176    bool contains(::mlir::StringAttr feature) const;
1177    bool contains(::llvm::StringRef feature) const;
1178
1179    bool nullOrEmpty() const {
1180      // Checks if this attribute is null, or the features are empty.
1181      return !bool(*this) || getFeatures().empty();
1182    }
1183
1184    /// Returns the list of features as an LLVM-compatible string.
1185    std::string getFeaturesString() const;
1186
1187    /// Finds the target features on the parent FunctionOpInterface.
1188    /// Note: This assumes the attribute name matches the return value of
1189    /// `getAttributeName()`.
1190    static TargetFeaturesAttr featuresAt(Operation* op);
1191
1192    /// Canonical name for this attribute within MLIR.
1193    static constexpr StringLiteral getAttributeName() {
1194      return StringLiteral("target_features");
1195    }
1196  }];
1197
1198  let assemblyFormat = "`<` `[` (`]`) : ($features^ `]`)? `>`";
1199  let genVerifyDecl = 1;
1200}
1201
1202//===----------------------------------------------------------------------===//
1203// UndefAttr
1204//===----------------------------------------------------------------------===//
1205
1206/// Folded into from LLVM::UndefOp.
1207def LLVM_UndefAttr : LLVM_Attr<"Undef", "undef">;
1208
1209//===----------------------------------------------------------------------===//
1210// PoisonAttr
1211//===----------------------------------------------------------------------===//
1212
1213/// Folded into from LLVM::PoisonOp.
1214def LLVM_PoisonAttr : LLVM_Attr<"Poison", "poison">;
1215
1216//===----------------------------------------------------------------------===//
1217// VecTypeHintAttr
1218//===----------------------------------------------------------------------===//
1219
1220def LLVM_VecTypeHintAttr : LLVM_Attr<"VecTypeHint", "vec_type_hint"> {
1221  let summary = "Explicit vectorization compiler hint";
1222  let description = [{
1223    A hint to the compiler that indicates most operations used in the function
1224    are explictly vectorized using a particular vector type. `$hint` is the
1225    vector or scalar type in particular. `$is_signed` can be used with integer
1226    types to state whether the type is signed.
1227  }];
1228  let parameters = (ins "TypeAttr":$hint,
1229                        DefaultValuedParameter<"bool", "false">:$is_signed);
1230  let assemblyFormat = "`<` struct(params) `>`";
1231}
1232
1233//===----------------------------------------------------------------------===//
1234// ZeroAttr
1235//===----------------------------------------------------------------------===//
1236
1237/// Folded into from LLVM::ZeroOp.
1238def LLVM_ZeroAttr : LLVM_Attr<"Zero", "zero">;
1239
1240//===----------------------------------------------------------------------===//
1241// TailCallKindAttr
1242//===----------------------------------------------------------------------===//
1243
1244def TailCallKindAttr : LLVM_Attr<"TailCallKind", "tailcallkind"> {
1245  let parameters = (ins "TailCallKind":$tailCallKind);
1246  let assemblyFormat = "`<` $tailCallKind `>`";
1247}
1248
1249//===----------------------------------------------------------------------===//
1250// WorkgroupAttributionAttr
1251//===----------------------------------------------------------------------===//
1252
1253def WorkgroupAttributionAttr
1254    : LLVM_Attr<"WorkgroupAttribution", "mlir.workgroup_attribution"> {
1255  let summary = "GPU workgroup attribution information";
1256  let description = [{
1257    GPU workgroup attributions are `gpu.func` attributes encoding memory
1258    allocations in the workgroup address space. These might be encoded as
1259    `llvm.ptr` function arguments in our dialect, but then type and size
1260    information would be dropped. This attribute can be attached to `llvm.ptr`
1261    function arguments encoding GPU workgroup attributions to mark them as
1262    arguments encoding workgroup attributions and keeping type and size
1263    information in our dialect.
1264  }];
1265  let parameters = (ins "IntegerAttr":$num_elements,
1266                        "TypeAttr":$element_type);
1267  let assemblyFormat = "`<` $num_elements `,` $element_type `>`";
1268}
1269
1270#endif // LLVMIR_ATTRDEFS
1271