18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/ADT/TypeSwitch.h"
20 #include "llvm/BinaryFormat/Dwarf.h"
29 SmallVector<uint64_t> &args);
34 ArrayRef<uint64_t> args);
36 #include "mlir/Dialect/LLVMIR/LLVMAttrInterfaces.cpp.inc"
37 #include "mlir/Dialect/LLVMIR/LLVMOpsEnums.cpp.inc"
38 #define GET_ATTRDEF_CLASSES
39 #include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.cpp.inc"
45 void LLVMDialect::registerAttributes() {
47 #define GET_ATTRDEF_LIST
48 #include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.cpp.inc"
59 Attribute id, AliasScopeDomainAttr domain,
60 StringAttr description) {
63 if (!llvm::isa<StringAttr, DistinctAttr>(
id))
65 <<
"id of an alias scope must be a StringAttr or a DistrinctAttr";
76 DIBasicTypeAttr, DICommonBlockAttr, DICompileUnitAttr,
77 DICompositeTypeAttr, DIDerivedTypeAttr, DIFileAttr, DIGenericSubrangeAttr,
78 DIGlobalVariableAttr, DIImportedEntityAttr, DILabelAttr,
79 DILexicalBlockAttr, DILexicalBlockFileAttr, DILocalVariableAttr,
80 DIModuleAttr, DINamespaceAttr, DINullTypeAttr, DIAnnotationAttr,
81 DIStringTypeAttr, DISubprogramAttr, DISubrangeAttr, DISubroutineTypeAttr>(
90 return llvm::isa<DICommonBlockAttr, DICompileUnitAttr, DICompositeTypeAttr,
92 DIModuleAttr, DINamespaceAttr>(attr);
100 return llvm::isa<DILexicalBlockAttr, DILexicalBlockFileAttr,
101 DISubprogramAttr>(attr);
109 return llvm::isa<DILocalVariableAttr, DIGlobalVariableAttr>(attr);
117 return llvm::isa<DINullTypeAttr, DIBasicTypeAttr, DICompositeTypeAttr,
118 DIDerivedTypeAttr, DIStringTypeAttr, DISubroutineTypeAttr>(
127 return llvm::isa<TBAATypeDescriptorAttr, TBAARootAttr>(attr);
136 if (memInfoArgs.empty())
138 ModRefInfo::ModRef, ModRefInfo::ModRef);
139 if (memInfoArgs.size() == 3)
145 bool MemoryEffectsAttr::isReadWrite() {
146 if (this->getArgMem() != ModRefInfo::ModRef)
148 if (this->getInaccessibleMem() != ModRefInfo::ModRef)
150 if (this->getOther() != ModRefInfo::ModRef)
160 return get(context, ArrayRef<DIExpressionElemAttr>({}));
164 SmallVector<uint64_t> &args) {
165 auto operandParser = [&]() -> LogicalResult {
166 uint64_t operand = 0;
167 if (!args.empty() && opcode == llvm::dwarf::DW_OP_LLVM_convert) {
171 operand = llvm::dwarf::getAttributeEncoding(keyword);
175 <<
"encountered unknown attribute encoding \"" << keyword
187 <<
"expected integer operand";
191 args.push_back(operand);
200 ArrayRef<uint64_t> args) {
202 llvm::interleaveComma(args, printer, [&](uint64_t operand) {
203 if (i > 0 && opcode == llvm::dwarf::DW_OP_LLVM_convert) {
204 if (
const StringRef keyword =
205 llvm::dwarf::AttributeEncodingString(operand);
221 DIRecursiveTypeAttrInterface
224 getContext(), recId, getIsRecSelf(), getTag(), getName(), getFile(),
225 getLine(), getScope(), getBaseType(), getFlags(), getSizeInBits(),
226 getAlignInBits(), getElements(), getDataLocation(), getRank(),
227 getAllocated(), getAssociated());
230 DIRecursiveTypeAttrInterface
233 0, {}, {}, 0, {}, {}, DIFlags(), 0, 0, {}, {},
241 DIRecursiveTypeAttrInterface DISubprogramAttr::withRecId(
DistinctAttr recId) {
243 getCompileUnit(), getScope(), getName(),
244 getLinkageName(), getFile(), getLine(),
245 getScopeLine(), getSubprogramFlags(),
getType(),
246 getRetainedNodes(), getAnnotations());
249 DIRecursiveTypeAttrInterface DISubprogramAttr::getRecSelf(
DistinctAttr recId) {
251 {}, {}, {}, {}, {}, {}, 0, 0, {}, {}, {}, {});
260 IntegerType widthType;
265 unsigned bitWidth = widthType.getWidth();
266 APInt lower(bitWidth, 0);
267 APInt upper(bitWidth, 0);
272 lower = lower.sextOrTrunc(bitWidth);
273 upper = upper.sextOrTrunc(bitWidth);
279 printer <<
"<i" << getLower().getBitWidth() <<
", " << getLower() <<
", "
280 << getUpper() <<
">";
285 APInt lower, APInt upper) {
286 if (lower.getBitWidth() != upper.getBitWidth())
288 <<
"expected lower and upper to have matching bitwidths but got "
289 << lower.getBitWidth() <<
" vs. " << upper.getBitWidth();
300 llvm::map_to_vector(features, [&](StringRef feature) {
309 return Base::getChecked(
emitError, context,
310 llvm::map_to_vector(features, [&](StringRef feature) {
316 StringRef targetFeatures) {
317 SmallVector<StringRef> features;
318 targetFeatures.split(features,
',', -1,
320 return get(context, features);
326 SmallVector<StringRef> features;
327 targetFeatures.split(features,
',', -1,
329 ArrayRef featuresRef(features);
330 return getChecked(
emitError, context, featuresRef);
336 for (StringAttr featureAttr : features) {
337 if (!featureAttr || featureAttr.empty())
338 return emitError() <<
"target features can not be null or empty";
339 auto feature = featureAttr.strref();
340 if (feature[0] !=
'+' && feature[0] !=
'-')
341 return emitError() <<
"target features must start with '+' or '-'";
342 if (feature.contains(
','))
343 return emitError() <<
"target features can not contain ','";
352 return llvm::is_contained(getFeatures(), feature);
358 return llvm::is_contained(getFeatures(), feature);
361 std::string TargetFeaturesAttr::getFeaturesString()
const {
362 std::string featuresString;
363 llvm::raw_string_ostream ss(featuresString);
365 getFeatures(), ss, [&](
auto &feature) { ss << feature.strref(); },
",");
366 return featuresString;
369 TargetFeaturesAttr TargetFeaturesAttr::featuresAt(
Operation *op) {
373 return parentFunction.getOperation()->getAttrOfType<TargetFeaturesAttr>(
379 LLVM::ModFlagBehavior flagBehavior, StringAttr key,
381 if (key == LLVMDialect::getModuleFlagKeyCGProfileName()) {
382 auto arrayAttr = dyn_cast<ArrayAttr>(value);
383 if ((!arrayAttr) || (!llvm::all_of(arrayAttr, [](
Attribute attr) {
384 return isa<ModuleFlagCGProfileEntryAttr>(attr);
387 <<
"'CG Profile' key expects an array of '#llvm.cgprofile_entry'";
391 if (key == LLVMDialect::getModuleFlagKeyProfileSummaryName()) {
392 if (!isa<ModuleFlagProfileSummaryAttr>(value))
393 return emitError() <<
"'ProfileSummary' key expects a "
394 "'#llvm.profile_summary' attribute";
398 if (isa<IntegerAttr, StringAttr>(value))
401 return emitError() <<
"only integer and string values are currently "
402 "supported for unknown key '"
static MLIRContext * getContext(OpFoldResult val)
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.
static bool contains(SMRange range, SMLoc loc)
Returns true if the given range contains the given source location.
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
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.
MLIRContext * getContext() const
Return the context this attribute belongs to.
An attribute that associates a referenced attribute with a unique identifier.
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.
static bool classof(Attribute attr)
Support LLVM type casting.
static bool classof(Attribute attr)
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.
static bool classof(Attribute attr)
Support LLVM type casting.
MLIRContext is the top-level object for a collection of MLIR operations.
Operation is the basic unit of execution within MLIR.
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Include the generated interface declarations.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...