MLIR 23.0.0git
LLVMAttrs.cpp
Go to the documentation of this file.
1//===- LLVMAttrs.cpp - LLVM Attributes registration -----------------------===//
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// This file defines the attribute details for the LLVM IR dialect in MLIR.
10//
11//===----------------------------------------------------------------------===//
12
17#include "mlir/IR/Builders.h"
20#include "llvm/ADT/StringExtras.h"
21#include "llvm/ADT/TypeSwitch.h"
22#include "llvm/BinaryFormat/Dwarf.h"
23
24using namespace mlir;
25using namespace mlir::LLVM;
26
27/// Parses DWARF expression arguments with respect to the DWARF operation
28/// opcode. Some DWARF expression operations have a specific number of operands
29/// and may appear in a textual form.
30static ParseResult parseExpressionArg(AsmParser &parser, uint64_t opcode,
32
33/// Prints DWARF expression arguments with respect to the specific DWARF
34/// operation. Some operands are printed in their textual form.
35static void printExpressionArg(AsmPrinter &printer, uint64_t opcode,
37
38#include "mlir/Dialect/LLVMIR/LLVMAttrInterfaces.cpp.inc"
39#include "mlir/Dialect/LLVMIR/LLVMOpsEnums.cpp.inc"
40#define GET_ATTRDEF_CLASSES
41#include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.cpp.inc"
42
43//===----------------------------------------------------------------------===//
44// LLVMDialect registration
45//===----------------------------------------------------------------------===//
46
47void LLVMDialect::registerAttributes() {
48 addAttributes<
49#define GET_ATTRDEF_LIST
50#include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.cpp.inc"
51
52 >();
53}
54
55//===----------------------------------------------------------------------===//
56// AddressSpaceAttr
57//===----------------------------------------------------------------------===//
58
59/// Checks whether the given type is an LLVM type that can be loaded or stored.
61 Type type, ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
62 const ::mlir::DataLayout *dataLayout,
64 if (!isLoadableType(type)) {
65 if (emitError)
66 emitError() << "type must be LLVM type with size, but got " << type;
67 return false;
68 }
69 if (ordering == ptr::AtomicOrdering::not_atomic)
70 return true;
71
72 // To check atomic validity we need a datalayout.
73 if (!dataLayout) {
74 if (emitError)
75 emitError() << "expected a valid data layout";
76 return false;
77 }
78 if (!isTypeCompatibleWithAtomicOp(type, *dataLayout)) {
79 if (emitError)
80 emitError() << "unsupported type " << type << " for atomic access";
81 return false;
82 }
83 return true;
84}
85
86bool AddressSpaceAttr::isValidLoad(
87 Type type, ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
88 const ::mlir::DataLayout *dataLayout,
90 return detail::isValidLoadStoreImpl(type, ordering, alignment, dataLayout,
91 emitError);
92}
93
94bool AddressSpaceAttr::isValidStore(
95 Type type, ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
96 const ::mlir::DataLayout *dataLayout,
98 return detail::isValidLoadStoreImpl(type, ordering, alignment, dataLayout,
99 emitError);
100}
101
102bool AddressSpaceAttr::isValidAtomicOp(
103 ptr::AtomicBinOp op, Type type, ptr::AtomicOrdering ordering,
104 std::optional<int64_t> alignment, const ::mlir::DataLayout *dataLayout,
106 // TODO: update this method once `ptr.atomic_rmw` is implemented.
107 assert(false && "unimplemented, see TODO in the source.");
108 return false;
109}
110
111bool AddressSpaceAttr::isValidAtomicXchg(
112 Type type, ptr::AtomicOrdering successOrdering,
113 ptr::AtomicOrdering failureOrdering, std::optional<int64_t> alignment,
114 const ::mlir::DataLayout *dataLayout,
116 // TODO: update this method once `ptr.atomic_cmpxchg` is implemented.
117 assert(false && "unimplemented, see TODO in the source.");
118 return false;
119}
120
121bool AddressSpaceAttr::isValidAddrSpaceCast(
123 // TODO: update this method once the `ptr.addrspace_cast` op is added to the
124 // dialect.
125 assert(false && "unimplemented, see TODO in the source.");
126 return false;
127}
128
129bool AddressSpaceAttr::isValidPtrIntCast(
130 Type intLikeTy, Type ptrLikeTy,
132 // TODO: update this method once the int-cast ops are added to the `ptr`
133 // dialect.
134 assert(false && "unimplemented, see TODO in the source.");
135 return false;
136}
137
138//===----------------------------------------------------------------------===//
139// AliasScopeAttr
140//===----------------------------------------------------------------------===//
141
142LogicalResult
143AliasScopeAttr::verify(function_ref<InFlightDiagnostic()> emitError,
144 Attribute id, AliasScopeDomainAttr domain,
145 StringAttr description) {
146 (void)domain;
147 (void)description;
148 if (!llvm::isa<StringAttr, DistinctAttr>(id))
149 return emitError()
150 << "id of an alias scope must be a StringAttr or a DistrinctAttr";
151
152 return success();
153}
154
155//===----------------------------------------------------------------------===//
156// DINodeAttr
157//===----------------------------------------------------------------------===//
158
160 return llvm::isa<
161 DIBasicTypeAttr, DICommonBlockAttr, DICompileUnitAttr,
162 DICompositeTypeAttr, DIDerivedTypeAttr, DIFileAttr, DIGenericSubrangeAttr,
163 DIGlobalVariableAttr, DIImportedEntityAttr, DILabelAttr,
164 DILexicalBlockAttr, DILexicalBlockFileAttr, DILocalVariableAttr,
165 DIModuleAttr, DINamespaceAttr, DINullTypeAttr, DIAnnotationAttr,
166 DIStringTypeAttr, DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
167 attr);
168}
169
170//===----------------------------------------------------------------------===//
171// DIScopeAttr
172//===----------------------------------------------------------------------===//
173
175 return llvm::isa<DICommonBlockAttr, DICompileUnitAttr, DICompositeTypeAttr,
176 DIDerivedTypeAttr, DIFileAttr, DILocalScopeAttr,
177 DIModuleAttr, DINamespaceAttr>(attr);
178}
179
180//===----------------------------------------------------------------------===//
181// DILocalScopeAttr
182//===----------------------------------------------------------------------===//
183
185 return llvm::isa<DILexicalBlockAttr, DILexicalBlockFileAttr,
186 DISubprogramAttr>(attr);
187}
188
189//===----------------------------------------------------------------------===//
190// DIVariableAttr
191//===----------------------------------------------------------------------===//
192
194 return llvm::isa<DILocalVariableAttr, DIGlobalVariableAttr>(attr);
195}
196
197//===----------------------------------------------------------------------===//
198// DITypeAttr
199//===----------------------------------------------------------------------===//
200
202 return llvm::isa<DINullTypeAttr, DIBasicTypeAttr, DICompositeTypeAttr,
203 DIDerivedTypeAttr, DIStringTypeAttr, DISubroutineTypeAttr>(
204 attr);
205}
206
207//===----------------------------------------------------------------------===//
208// DIDerivedTypeAttr
209//===----------------------------------------------------------------------===//
210
211LogicalResult DIDerivedTypeAttr::verify(
212 function_ref<InFlightDiagnostic()> emitError, unsigned tag, StringAttr name,
213 DIFileAttr file, uint32_t line, DIScopeAttr scope, DITypeAttr baseType,
214 uint64_t sizeInBits, uint32_t alignInBits, uint64_t offsetInBits,
215 std::optional<unsigned> dwarfAddressSpace, DIFlags flags,
216 Attribute extraData) {
217 if (extraData && !llvm::isa<DINodeAttr, IntegerAttr>(extraData))
218 return emitError() << "extraData must be a DINodeAttr or an IntegerAttr";
219 return success();
220}
221
222//===----------------------------------------------------------------------===//
223// TBAANodeAttr
224//===----------------------------------------------------------------------===//
225
227 return llvm::isa<TBAATypeDescriptorAttr, TBAARootAttr>(attr);
228}
229
230//===----------------------------------------------------------------------===//
231// MemoryEffectsAttr
232//===----------------------------------------------------------------------===//
233
234MemoryEffectsAttr MemoryEffectsAttr::get(MLIRContext *context,
235 ArrayRef<ModRefInfo> memInfoArgs) {
236 if (memInfoArgs.empty())
237 return MemoryEffectsAttr::get(context, /*other=*/ModRefInfo::ModRef,
238 /*argMem=*/ModRefInfo::ModRef,
239 /*inaccessibleMem=*/ModRefInfo::ModRef,
240 /*errnoMem=*/ModRefInfo::ModRef,
241 /*targetMem0=*/ModRefInfo::ModRef,
242 /*targetMem1=*/ModRefInfo::ModRef);
243 if (memInfoArgs.size() == 6)
244 return MemoryEffectsAttr::get(context, memInfoArgs[0], memInfoArgs[1],
245 memInfoArgs[2], memInfoArgs[3],
246 memInfoArgs[4], memInfoArgs[5]);
247 return {};
248}
249
250bool MemoryEffectsAttr::isReadWrite() {
251 if (this->getArgMem() != ModRefInfo::ModRef)
252 return false;
253 if (this->getInaccessibleMem() != ModRefInfo::ModRef)
254 return false;
255 if (this->getOther() != ModRefInfo::ModRef)
256 return false;
257 if (this->getErrnoMem() != ModRefInfo::ModRef)
258 return false;
259 if (this->getTargetMem0() != ModRefInfo::ModRef)
260 return false;
261 if (this->getTargetMem1() != ModRefInfo::ModRef)
262 return false;
263 return true;
264}
265
266//===----------------------------------------------------------------------===//
267// DIExpression
268//===----------------------------------------------------------------------===//
269
270DIExpressionAttr DIExpressionAttr::get(MLIRContext *context) {
271 return get(context, ArrayRef<DIExpressionElemAttr>({}));
272}
273
274ParseResult parseExpressionArg(AsmParser &parser, uint64_t opcode,
275 SmallVector<uint64_t> &args) {
276 auto operandParser = [&]() -> LogicalResult {
277 uint64_t operand = 0;
278 if (!args.empty() && opcode == llvm::dwarf::DW_OP_LLVM_convert) {
279 // Attempt to parse a keyword.
280 StringRef keyword;
281 if (succeeded(parser.parseOptionalKeyword(&keyword))) {
282 operand = llvm::dwarf::getAttributeEncoding(keyword);
283 if (operand == 0) {
284 // The keyword is invalid.
285 return parser.emitError(parser.getCurrentLocation())
286 << "encountered unknown attribute encoding \"" << keyword
287 << "\"";
288 }
289 }
290 }
291
292 // operand should be non-zero if a keyword was parsed. Otherwise, the
293 // operand MUST be an integer.
294 if (operand == 0) {
295 // Parse the next operand as an integer.
296 if (parser.parseInteger(operand)) {
297 return parser.emitError(parser.getCurrentLocation())
298 << "expected integer operand";
299 }
300 }
301
302 args.push_back(operand);
303 return success();
304 };
305
306 // Parse operands as a comma-separated list.
307 return parser.parseCommaSeparatedList(operandParser);
308}
309
310void printExpressionArg(AsmPrinter &printer, uint64_t opcode,
311 ArrayRef<uint64_t> args) {
312 size_t i = 0;
313 llvm::interleaveComma(args, printer, [&](uint64_t operand) {
314 if (i > 0 && opcode == llvm::dwarf::DW_OP_LLVM_convert) {
315 if (const StringRef keyword =
316 llvm::dwarf::AttributeEncodingString(operand);
317 !keyword.empty()) {
318 printer << keyword;
319 return;
320 }
321 }
322 // All operands are expected to be printed as integers.
323 printer << operand;
324 i++;
325 });
326}
327
328//===----------------------------------------------------------------------===//
329// DICompositeTypeAttr
330//===----------------------------------------------------------------------===//
331
332DIRecursiveTypeAttrInterface
333DICompositeTypeAttr::withRecId(DistinctAttr recId) {
334 return DICompositeTypeAttr::get(
335 getContext(), recId, getIsRecSelf(), getTag(), getName(), getFile(),
336 getLine(), getScope(), getBaseType(), getFlags(), getSizeInBits(),
337 getAlignInBits(), getDataLocation(), getRank(), getAllocated(),
338 getAssociated(), getIdentifier(), getDiscriminator(), getElements());
339}
340
341DIRecursiveTypeAttrInterface
342DICompositeTypeAttr::getRecSelf(DistinctAttr recId) {
343 return DICompositeTypeAttr::get(recId.getContext(), recId, /*isRecSelf=*/true,
344 0, {}, {}, 0, {}, {}, DIFlags(), 0, 0, {}, {},
345 {}, {}, {}, {}, {});
346}
347
348//===----------------------------------------------------------------------===//
349// DICompileUnitAttr
350//===----------------------------------------------------------------------===//
351
352DIRecursiveTypeAttrInterface DICompileUnitAttr::withRecId(DistinctAttr recId) {
353 return DICompileUnitAttr::get(
354 getContext(), recId, getIsRecSelf(), getId(), getSourceLanguage(),
355 getFile(), getProducer(), getIsOptimized(), getEmissionKind(),
356 getIsDebugInfoForProfiling(), getNameTableKind(), getSplitDebugFilename(),
357 getImportedEntities());
358}
359
360DIRecursiveTypeAttrInterface DICompileUnitAttr::getRecSelf(DistinctAttr recId) {
361
362 return DICompileUnitAttr::get(
363 recId.getContext(), recId, /*isRecSelf=*/true, /*id=*/{},
364 /*sourceLanguage=*/0u, /*file=*/{}, /*producer=*/{},
365 /*isOptimized=*/false, DIEmissionKind::None,
366 /*isDebugInfoForProfiling=*/false, DINameTableKind::Default,
367 /*splitDebugFilename=*/{}, /*importedEntities=*/{});
368}
369
370//===----------------------------------------------------------------------===//
371// DISubprogramAttr
372//===----------------------------------------------------------------------===//
373
374DIRecursiveTypeAttrInterface DISubprogramAttr::withRecId(DistinctAttr recId) {
375 return DISubprogramAttr::get(getContext(), recId, getIsRecSelf(), getId(),
376 getCompileUnit(), getScope(), getName(),
377 getLinkageName(), getFile(), getLine(),
378 getScopeLine(), getSubprogramFlags(), getType(),
379 getRetainedNodes(), getAnnotations());
380}
381
382DIRecursiveTypeAttrInterface DISubprogramAttr::getRecSelf(DistinctAttr recId) {
383 return DISubprogramAttr::get(recId.getContext(), recId, /*isRecSelf=*/true,
384 {}, {}, {}, {}, {}, {}, 0, 0, {}, {}, {}, {});
385}
386
387//===----------------------------------------------------------------------===//
388// ConstantRangeAttr
389//===----------------------------------------------------------------------===//
390
391Attribute ConstantRangeAttr::parse(AsmParser &parser, Type odsType) {
392 llvm::SMLoc loc = parser.getCurrentLocation();
393 IntegerType widthType;
394 if (parser.parseLess() || parser.parseType(widthType) ||
395 parser.parseComma()) {
396 return Attribute{};
397 }
398 unsigned bitWidth = widthType.getWidth();
399 APInt lower(bitWidth, 0);
400 APInt upper(bitWidth, 0);
401 if (parser.parseInteger(lower) || parser.parseComma() ||
402 parser.parseInteger(upper) || parser.parseGreater())
403 return Attribute{};
404 // Non-positive numbers may use more bits than `bitWidth`
405 lower = lower.sextOrTrunc(bitWidth);
406 upper = upper.sextOrTrunc(bitWidth);
407 return parser.getChecked<ConstantRangeAttr>(loc, parser.getContext(), lower,
408 upper);
409}
410
411void ConstantRangeAttr::print(AsmPrinter &printer) const {
412 printer << "<i" << getLower().getBitWidth() << ", " << getLower() << ", "
413 << getUpper() << ">";
414}
415
416LogicalResult
417ConstantRangeAttr::verify(llvm::function_ref<InFlightDiagnostic()> emitError,
418 APInt lower, APInt upper) {
419 if (lower.getBitWidth() != upper.getBitWidth())
420 return emitError()
421 << "expected lower and upper to have matching bitwidths but got "
422 << lower.getBitWidth() << " vs. " << upper.getBitWidth();
423 return success();
424}
425
426//===----------------------------------------------------------------------===//
427// TargetFeaturesAttr
428//===----------------------------------------------------------------------===//
429
430TargetFeaturesAttr TargetFeaturesAttr::get(MLIRContext *context,
431 llvm::ArrayRef<StringRef> features) {
432 return Base::get(context,
433 llvm::map_to_vector(features, [&](StringRef feature) {
434 return StringAttr::get(context, feature);
435 }));
436}
437
438TargetFeaturesAttr
439TargetFeaturesAttr::getChecked(function_ref<InFlightDiagnostic()> emitError,
440 MLIRContext *context,
441 llvm::ArrayRef<StringRef> features) {
442 return Base::getChecked(emitError, context,
443 llvm::map_to_vector(features, [&](StringRef feature) {
444 return StringAttr::get(context, feature);
445 }));
446}
447
448TargetFeaturesAttr TargetFeaturesAttr::get(MLIRContext *context,
449 StringRef targetFeatures) {
450 SmallVector<StringRef> features;
451 targetFeatures.split(features, ',', /*MaxSplit=*/-1,
452 /*KeepEmpty=*/false);
453 return get(context, features);
454}
455
456TargetFeaturesAttr
457TargetFeaturesAttr::getChecked(function_ref<InFlightDiagnostic()> emitError,
458 MLIRContext *context, StringRef targetFeatures) {
459 SmallVector<StringRef> features;
460 targetFeatures.split(features, ',', /*MaxSplit=*/-1,
461 /*KeepEmpty=*/false);
462 ArrayRef featuresRef(features);
463 return getChecked(emitError, context, featuresRef);
464}
465
466LogicalResult
467TargetFeaturesAttr::verify(function_ref<InFlightDiagnostic()> emitError,
468 llvm::ArrayRef<StringAttr> features) {
469 for (StringAttr featureAttr : features) {
470 if (!featureAttr || featureAttr.empty())
471 return emitError() << "target features can not be null or empty";
472 auto feature = featureAttr.strref();
473 if (feature[0] != '+' && feature[0] != '-')
474 return emitError() << "target features must start with '+' or '-'";
475 if (feature.contains(','))
476 return emitError() << "target features can not contain ','";
477 }
478 return success();
479}
480
481bool TargetFeaturesAttr::contains(StringAttr feature) const {
482 if (nullOrEmpty())
483 return false;
484 // Note: Using StringAttr does pointer comparisons.
485 return llvm::is_contained(getFeatures(), feature);
486}
487
488bool TargetFeaturesAttr::contains(StringRef feature) const {
489 if (nullOrEmpty())
490 return false;
491 return llvm::is_contained(getFeatures(), feature);
492}
493
494std::string TargetFeaturesAttr::getFeaturesString() const {
495 std::string featuresString;
496 llvm::raw_string_ostream ss(featuresString);
497 llvm::interleave(
498 getFeatures(), ss, [&](auto &feature) { ss << feature.strref(); }, ",");
499 return featuresString;
500}
501
502TargetFeaturesAttr TargetFeaturesAttr::featuresAt(Operation *op) {
503 auto parentFunction = op->getParentOfType<FunctionOpInterface>();
504 if (!parentFunction)
505 return {};
506 return parentFunction.getOperation()->getAttrOfType<TargetFeaturesAttr>(
507 getAttributeName());
508}
509
510FailureOr<Attribute> TargetFeaturesAttr::query(DataLayoutEntryKey key) {
511 auto stringKey = dyn_cast<StringAttr>(key);
512 if (!stringKey)
513 return failure();
514
515 if (contains(stringKey))
516 return UnitAttr::get(getContext());
517
518 if (contains((std::string("+") + stringKey.strref()).str()))
519 return BoolAttr::get(getContext(), true);
520
521 if (contains((std::string("-") + stringKey.strref()).str()))
522 return BoolAttr::get(getContext(), false);
523
524 return failure();
525}
526
527//===----------------------------------------------------------------------===//
528// TargetAttr
529//===----------------------------------------------------------------------===//
530
531FailureOr<::mlir::Attribute> TargetAttr::query(DataLayoutEntryKey key) {
532 if (auto stringAttrKey = dyn_cast<StringAttr>(key)) {
533 if (stringAttrKey.getValue() == "triple")
534 return getTriple();
535 if (stringAttrKey.getValue() == "chip")
536 return getChip();
537 if (stringAttrKey.getValue() == "features" && getFeatures())
538 return getFeatures();
539 }
540 return failure();
541}
542
543//===----------------------------------------------------------------------===//
544// ModuleFlagAttr
545//===----------------------------------------------------------------------===//
546
547LogicalResult
548ModuleFlagAttr::verify(function_ref<InFlightDiagnostic()> emitError,
549 LLVM::ModFlagBehavior flagBehavior, StringAttr key,
550 Attribute value) {
551 if (key == LLVMDialect::getModuleFlagKeyCGProfileName()) {
552 auto arrayAttr = dyn_cast<ArrayAttr>(value);
553 if ((!arrayAttr) || (!llvm::all_of(arrayAttr, [](Attribute attr) {
554 return isa<ModuleFlagCGProfileEntryAttr>(attr);
555 })))
556 return emitError()
557 << "'CG Profile' key expects an array of '#llvm.cgprofile_entry'";
558 return success();
559 }
560
561 if (key == LLVMDialect::getModuleFlagKeyProfileSummaryName()) {
562 if (!isa<ModuleFlagProfileSummaryAttr>(value))
563 return emitError() << "'ProfileSummary' key expects a "
564 "'#llvm.profile_summary' attribute";
565 return success();
566 }
567
568 if (isa<IntegerAttr, StringAttr>(value))
569 return success();
570
571 // Allow non-empty ArrayAttr of StringAttrs to represent MDTuples of
572 // MDStrings (e.g. the "riscv-isa" module flag). Integer values within
573 // MDTuples are not handled here because integer module flags are encoded as
574 // ConstantAsMetadata at the top level (not as MDTuples), so no known use
575 // case requires an array-of-integers representation.
576 if (auto arrayAttr = dyn_cast<ArrayAttr>(value))
577 if (!arrayAttr.empty() &&
578 llvm::all_of(arrayAttr, [](Attribute a) { return isa<StringAttr>(a); }))
579 return success();
580
581 return emitError() << "only integer, string, and string-array values are "
582 "currently supported for unknown key '"
583 << key << "'";
584}
return success()
static void printExpressionArg(AsmPrinter &printer, uint64_t opcode, ArrayRef< uint64_t > args)
Prints DWARF expression arguments with respect to the specific DWARF operation.
static ParseResult parseExpressionArg(AsmParser &parser, uint64_t opcode, SmallVector< uint64_t > &args)
Parses DWARF expression arguments with respect to the DWARF operation opcode.
b getContext())
static bool contains(SMRange range, SMLoc loc)
Returns true if the given range contains the given source location.
This base class exposes generic asm parser hooks, usable across the various derived parsers.
virtual ParseResult parseCommaSeparatedList(Delimiter delimiter, function_ref< ParseResult()> parseElementFn, StringRef contextMessage=StringRef())=0
Parse a list of comma-separated items with an optional delimiter.
virtual ParseResult parseOptionalKeyword(StringRef keyword)=0
Parse the given keyword if present.
MLIRContext * getContext() const
virtual InFlightDiagnostic emitError(SMLoc loc, const Twine &message={})=0
Emit a diagnostic at the specified location and return failure.
ParseResult parseInteger(IntT &result)
Parse an integer value from the stream.
virtual ParseResult parseLess()=0
Parse a '<' token.
virtual SMLoc getCurrentLocation()=0
Get the location of the next token and store it into the argument.
auto getChecked(SMLoc loc, ParamsT &&...params)
Invoke the getChecked method of the given Attribute or Type class, using the provided location to emi...
virtual ParseResult parseGreater()=0
Parse a '>' token.
virtual ParseResult parseType(Type &result)=0
Parse a type.
virtual ParseResult parseComma()=0
Parse a , token.
This base class exposes generic asm printer hooks, usable across the various derived printers.
Attributes are known-constant values of operations.
Definition Attributes.h:25
MLIRContext * getContext() const
Return the context this attribute belongs to.
static BoolAttr get(MLIRContext *context, bool value)
This class represents a diagnostic that is inflight and set to be reported.
This class represents a LLVM attribute that describes a local debug info scope.
Definition LLVMAttrs.h:48
static bool classof(Attribute attr)
Support LLVM type casting.
constexpr Attribute()=default
static bool classof(Attribute attr)
This class represents a LLVM attribute that describes a debug info scope.
Definition LLVMAttrs.h:38
static bool classof(Attribute attr)
Support LLVM type casting.
This class represents a LLVM attribute that describes a debug info type.
Definition LLVMAttrs.h:57
static bool classof(Attribute attr)
Support LLVM type casting.
static bool classof(Attribute attr)
Support LLVM type casting.
static bool classof(Attribute attr)
Support LLVM type casting.
constexpr Attribute()=default
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
Definition Operation.h:255
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
bool isValidLoadStoreImpl(Type type, ptr::AtomicOrdering ordering, std::optional< int64_t > alignment, const ::mlir::DataLayout *dataLayout, function_ref< InFlightDiagnostic()> emitError)
Checks whether the given type is an LLVM type that can be loaded or stored.
Definition LLVMAttrs.cpp:60
bool isLoadableType(Type type)
Returns true if the given type is a loadable type compatible with the LLVM dialect.
bool isTypeCompatibleWithAtomicOp(Type type, const DataLayout &dataLayout)
Returns true if the given type is supported by atomic operations.
Include the generated interface declarations.
llvm::PointerUnion< Type, StringAttr > DataLayoutEntryKey
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
Definition Utils.cpp:307
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
auto getChecked(function_ref< InFlightDiagnostic()> emitError, MLIRContext *context, Ts &&...params)
Helper method analogous to get, but uses getChecked when available to allow graceful failure on inval...
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
llvm::function_ref< Fn > function_ref
Definition LLVM.h:147