MLIR  20.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 
237 LogicalResult
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:313
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.
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