MLIR  19.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 
15 #include "mlir/IR/Builders.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/ADT/TypeSwitch.h"
20 #include "llvm/BinaryFormat/Dwarf.h"
21 #include "llvm/IR/DebugInfoMetadata.h"
22 #include <optional>
23 
24 using namespace mlir;
25 using 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.
30 static LogicalResult parseExpressionArg(AsmParser &parser, uint64_t opcode,
31  SmallVector<uint64_t> &args);
32 
33 /// Prints DWARF expression arguments with respect to the specific DWARF
34 /// operation. Some operands are printed in their textual form.
35 static void printExpressionArg(AsmPrinter &printer, uint64_t opcode,
36  ArrayRef<uint64_t> args);
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 
47 void LLVMDialect::registerAttributes() {
48  addAttributes<
49 #define GET_ATTRDEF_LIST
50 #include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.cpp.inc"
51  >();
52 }
53 
54 //===----------------------------------------------------------------------===//
55 // DINodeAttr
56 //===----------------------------------------------------------------------===//
57 
59  return llvm::isa<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
60  DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
61  DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr,
62  DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
63  DINullTypeAttr, DIStringTypeAttr, DISubprogramAttr,
64  DISubrangeAttr, DISubroutineTypeAttr>(attr);
65 }
66 
67 //===----------------------------------------------------------------------===//
68 // DIScopeAttr
69 //===----------------------------------------------------------------------===//
70 
72  return llvm::isa<DICompileUnitAttr, DICompositeTypeAttr, DIFileAttr,
73  DILocalScopeAttr, DIModuleAttr, DINamespaceAttr>(attr);
74 }
75 
76 //===----------------------------------------------------------------------===//
77 // DILocalScopeAttr
78 //===----------------------------------------------------------------------===//
79 
81  return llvm::isa<DILexicalBlockAttr, DILexicalBlockFileAttr,
82  DISubprogramAttr>(attr);
83 }
84 
85 //===----------------------------------------------------------------------===//
86 // DIVariableAttr
87 //===----------------------------------------------------------------------===//
88 
90  return llvm::isa<DILocalVariableAttr, DIGlobalVariableAttr>(attr);
91 }
92 
93 //===----------------------------------------------------------------------===//
94 // DITypeAttr
95 //===----------------------------------------------------------------------===//
96 
98  return llvm::isa<DINullTypeAttr, DIBasicTypeAttr, DICompositeTypeAttr,
99  DIDerivedTypeAttr, DIStringTypeAttr, DISubroutineTypeAttr>(
100  attr);
101 }
102 
103 //===----------------------------------------------------------------------===//
104 // TBAANodeAttr
105 //===----------------------------------------------------------------------===//
106 
108  return llvm::isa<TBAATypeDescriptorAttr, TBAARootAttr>(attr);
109 }
110 
111 //===----------------------------------------------------------------------===//
112 // MemoryEffectsAttr
113 //===----------------------------------------------------------------------===//
114 
115 MemoryEffectsAttr MemoryEffectsAttr::get(MLIRContext *context,
116  ArrayRef<ModRefInfo> memInfoArgs) {
117  if (memInfoArgs.empty())
118  return MemoryEffectsAttr::get(context, ModRefInfo::ModRef,
119  ModRefInfo::ModRef, ModRefInfo::ModRef);
120  if (memInfoArgs.size() == 3)
121  return MemoryEffectsAttr::get(context, memInfoArgs[0], memInfoArgs[1],
122  memInfoArgs[2]);
123  return {};
124 }
125 
126 bool MemoryEffectsAttr::isReadWrite() {
127  if (this->getArgMem() != ModRefInfo::ModRef)
128  return false;
129  if (this->getInaccessibleMem() != ModRefInfo::ModRef)
130  return false;
131  if (this->getOther() != ModRefInfo::ModRef)
132  return false;
133  return true;
134 }
135 
136 //===----------------------------------------------------------------------===//
137 // DIExpression
138 //===----------------------------------------------------------------------===//
139 
140 DIExpressionAttr DIExpressionAttr::get(MLIRContext *context) {
141  return get(context, ArrayRef<DIExpressionElemAttr>({}));
142 }
143 
144 LogicalResult parseExpressionArg(AsmParser &parser, uint64_t opcode,
145  SmallVector<uint64_t> &args) {
146  auto operandParser = [&]() -> LogicalResult {
147  uint64_t operand = 0;
148  if (!args.empty() && opcode == llvm::dwarf::DW_OP_LLVM_convert) {
149  // Attempt to parse a keyword.
150  StringRef keyword;
151  if (succeeded(parser.parseOptionalKeyword(&keyword))) {
152  operand = llvm::dwarf::getAttributeEncoding(keyword);
153  if (operand == 0) {
154  // The keyword is invalid.
155  return parser.emitError(parser.getCurrentLocation())
156  << "encountered unknown attribute encoding \"" << keyword
157  << "\"";
158  }
159  }
160  }
161 
162  // operand should be non-zero if a keyword was parsed. Otherwise, the
163  // operand MUST be an integer.
164  if (operand == 0) {
165  // Parse the next operand as an integer.
166  if (parser.parseInteger(operand)) {
167  return parser.emitError(parser.getCurrentLocation())
168  << "expected integer operand";
169  }
170  }
171 
172  args.push_back(operand);
173  return success();
174  };
175 
176  // Parse operands as a comma-separated list.
177  return parser.parseCommaSeparatedList(operandParser);
178 }
179 
180 void printExpressionArg(AsmPrinter &printer, uint64_t opcode,
181  ArrayRef<uint64_t> args) {
182  size_t i = 0;
183  llvm::interleaveComma(args, printer, [&](uint64_t operand) {
184  if (i > 0 && opcode == llvm::dwarf::DW_OP_LLVM_convert) {
185  if (const StringRef keyword =
186  llvm::dwarf::AttributeEncodingString(operand);
187  !keyword.empty()) {
188  printer << keyword;
189  return;
190  }
191  }
192  // All operands are expected to be printed as integers.
193  printer << operand;
194  i++;
195  });
196 }
197 
198 //===----------------------------------------------------------------------===//
199 // DICompositeTypeAttr
200 //===----------------------------------------------------------------------===//
201 
202 DIRecursiveTypeAttrInterface
203 DICompositeTypeAttr::withRecId(DistinctAttr recId) {
205  getContext(), getTag(), recId, getName(), getFile(), getLine(),
206  getScope(), getBaseType(), getFlags(), getSizeInBits(), getAlignInBits(),
207  getElements(), getDataLocation(), getRank(), getAllocated(),
208  getAssociated());
209 }
210 
211 DIRecursiveTypeAttrInterface
212 DICompositeTypeAttr::getRecSelf(DistinctAttr recId) {
213  return DICompositeTypeAttr::get(recId.getContext(), 0, recId, {}, {}, 0, {},
214  {}, DIFlags(), 0, 0, {}, {}, {}, {}, {});
215 }
216 
217 //===----------------------------------------------------------------------===//
218 // TargetFeaturesAttr
219 //===----------------------------------------------------------------------===//
220 
221 TargetFeaturesAttr TargetFeaturesAttr::get(MLIRContext *context,
222  llvm::ArrayRef<StringRef> features) {
223  return Base::get(context,
224  llvm::map_to_vector(features, [&](StringRef feature) {
225  return StringAttr::get(context, feature);
226  }));
227 }
228 
229 TargetFeaturesAttr TargetFeaturesAttr::get(MLIRContext *context,
230  StringRef targetFeatures) {
231  SmallVector<StringRef> features;
232  targetFeatures.split(features, ',', /*MaxSplit=*/-1,
233  /*KeepEmpty=*/false);
234  return get(context, features);
235 }
236 
239  llvm::ArrayRef<StringAttr> features) {
240  for (StringAttr featureAttr : features) {
241  if (!featureAttr || featureAttr.empty())
242  return emitError() << "target features can not be null or empty";
243  auto feature = featureAttr.strref();
244  if (feature[0] != '+' && feature[0] != '-')
245  return emitError() << "target features must start with '+' or '-'";
246  if (feature.contains(','))
247  return emitError() << "target features can not contain ','";
248  }
249  return success();
250 }
251 
252 bool TargetFeaturesAttr::contains(StringAttr feature) const {
253  if (nullOrEmpty())
254  return false;
255  // Note: Using StringAttr does pointer comparisons.
256  return llvm::is_contained(getFeatures(), feature);
257 }
258 
259 bool TargetFeaturesAttr::contains(StringRef feature) const {
260  if (nullOrEmpty())
261  return false;
262  return llvm::is_contained(getFeatures(), feature);
263 }
264 
265 std::string TargetFeaturesAttr::getFeaturesString() const {
266  std::string featuresString;
267  llvm::raw_string_ostream ss(featuresString);
268  llvm::interleave(
269  getFeatures(), ss, [&](auto &feature) { ss << feature.strref(); }, ",");
270  return ss.str();
271 }
272 
273 TargetFeaturesAttr TargetFeaturesAttr::featuresAt(Operation *op) {
274  auto parentFunction = op->getParentOfType<FunctionOpInterface>();
275  if (!parentFunction)
276  return {};
277  return parentFunction.getOperation()->getAttrOfType<TargetFeaturesAttr>(
278  getAttributeName());
279 }
static MLIRContext * getContext(OpFoldResult val)
static LogicalResult parseExpressionArg(AsmParser &parser, uint64_t opcode, SmallVector< uint64_t > &args)
Parses DWARF expression arguments with respect to the DWARF operation opcode.
Definition: LLVMAttrs.cpp:144
static void printExpressionArg(AsmPrinter &printer, uint64_t opcode, ArrayRef< uint64_t > args)
Prints DWARF expression arguments with respect to the specific DWARF operation.
Definition: LLVMAttrs.cpp:180
static bool contains(SMRange range, SMLoc loc)
Returns true if the given range contains the given source location.
Definition: MLIRServer.cpp:111
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.
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 SMLoc getCurrentLocation()=0
Get the location of the next token and store it into the argument.
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.
Definition: Attributes.cpp:37
An attribute that associates a referenced attribute with a unique identifier.
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:308
This class represents a LLVM attribute that describes a local debug info scope.
Definition: LLVMAttrs.h:46
static bool classof(Attribute attr)
Support LLVM type casting.
Definition: LLVMAttrs.cpp:80
static bool classof(Attribute attr)
Definition: LLVMAttrs.cpp:58
static bool classof(Attribute attr)
Support LLVM type casting.
Definition: LLVMAttrs.cpp:71
static bool classof(Attribute attr)
Support LLVM type casting.
Definition: LLVMAttrs.cpp:97
static bool classof(Attribute attr)
Support LLVM type casting.
Definition: LLVMAttrs.cpp:89
static bool classof(Attribute attr)
Support LLVM type casting.
Definition: LLVMAttrs.cpp:107
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
Definition: Operation.h:238
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
Definition: LogicalResult.h:68
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
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,...
Definition: Verifier.cpp:421
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26