MLIR 24.0.0git
GPUBase.cpp
Go to the documentation of this file.
1//===- GPUBase.cpp - GPU types and attributes -----------------------------===//
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 implements GPU types, attributes, and enums.
10//
11//===----------------------------------------------------------------------===//
12
14
15#include "mlir/IR/Builders.h"
17#include "llvm/ADT/TypeSwitch.h"
18#include "llvm/Support/CommandLine.h"
19#include "llvm/Support/StringSaver.h"
20
21using namespace mlir;
22using namespace mlir::gpu;
23
24//===----------------------------------------------------------------------===//
25// GPU Device Mapping Attributes
26//===----------------------------------------------------------------------===//
27
28int64_t GPUBlockMappingAttr::getMappingId() const {
29 return static_cast<int64_t>(getBlock());
30}
31
32bool GPUBlockMappingAttr::isLinearMapping() const {
33 return getMappingId() >= static_cast<int64_t>(MappingId::LinearDim0);
34}
35
36int64_t GPUBlockMappingAttr::getRelativeIndex() const {
37 return isLinearMapping()
38 ? getMappingId() - static_cast<int64_t>(MappingId::LinearDim0)
39 : getMappingId();
40}
41
42int64_t GPUWarpgroupMappingAttr::getMappingId() const {
43 return static_cast<int64_t>(getWarpgroup());
44}
45
46bool GPUWarpgroupMappingAttr::isLinearMapping() const {
47 return getMappingId() >= static_cast<int64_t>(MappingId::LinearDim0);
48}
49
50int64_t GPUWarpgroupMappingAttr::getRelativeIndex() const {
51 return isLinearMapping()
52 ? getMappingId() - static_cast<int64_t>(MappingId::LinearDim0)
53 : getMappingId();
54}
55
56int64_t GPUWarpMappingAttr::getMappingId() const {
57 return static_cast<int64_t>(getWarp());
58}
59
60bool GPUWarpMappingAttr::isLinearMapping() const {
61 return getMappingId() >= static_cast<int64_t>(MappingId::LinearDim0);
62}
63
64int64_t GPUWarpMappingAttr::getRelativeIndex() const {
65 return isLinearMapping()
66 ? getMappingId() - static_cast<int64_t>(MappingId::LinearDim0)
67 : getMappingId();
68}
69
70int64_t GPUThreadMappingAttr::getMappingId() const {
71 return static_cast<int64_t>(getThread());
72}
73
74bool GPUThreadMappingAttr::isLinearMapping() const {
75 return getMappingId() >= static_cast<int64_t>(MappingId::LinearDim0);
76}
77
78int64_t GPUThreadMappingAttr::getRelativeIndex() const {
79 return isLinearMapping()
80 ? getMappingId() - static_cast<int64_t>(MappingId::LinearDim0)
81 : getMappingId();
82}
83
84int64_t GPULaneMappingAttr::getMappingId() const {
85 return static_cast<int64_t>(getLane());
86}
87
88bool GPULaneMappingAttr::isLinearMapping() const {
89 return getMappingId() >= static_cast<int64_t>(MappingId::LinearDim0);
90}
91
92int64_t GPULaneMappingAttr::getRelativeIndex() const {
93 return isLinearMapping()
94 ? getMappingId() - static_cast<int64_t>(MappingId::LinearDim0)
95 : getMappingId();
96}
97
98int64_t GPUMemorySpaceMappingAttr::getMappingId() const {
99 return static_cast<int64_t>(getAddressSpace());
100}
101
102bool GPUMemorySpaceMappingAttr::isLinearMapping() const {
103 llvm_unreachable("GPUMemorySpaceMappingAttr does not support linear mapping");
104}
105
106int64_t GPUMemorySpaceMappingAttr::getRelativeIndex() const {
107 llvm_unreachable("GPUMemorySpaceMappingAttr does not support relative index");
108}
109
110//===----------------------------------------------------------------------===//
111// MMAMatrixType
112//===----------------------------------------------------------------------===//
113
115 StringRef operand) {
116 return Base::get(elementType.getContext(), shape, elementType, operand);
117}
118
121 ArrayRef<int64_t> shape, Type elementType,
122 StringRef operand) {
123 return Base::getChecked(emitError, elementType.getContext(), shape,
124 elementType, operand);
125}
126
127unsigned MMAMatrixType::getNumDims() const { return getImpl()->numDims; }
128
130 return getImpl()->getShape();
131}
132
133Type MMAMatrixType::getElementType() const { return getImpl()->elementType; }
134
135StringRef MMAMatrixType::getOperand() const { return getImpl()->getOperand(); }
136
138 return elementType.isF16() || elementType.isF32() || elementType.isF64() ||
139 elementType.isUnsignedInteger(8) || elementType.isSignedInteger(8) ||
140 elementType.isInteger(32);
141}
142
143LogicalResult
145 ArrayRef<int64_t> shape, Type elementType,
146 StringRef operand) {
147 if (operand != "AOp" && operand != "BOp" && operand != "COp")
148 return emitError() << "operand expected to be one of AOp, BOp or COp";
149
150 if (shape.size() != 2)
151 return emitError() << "MMAMatrixType must have exactly two dimensions";
152
153 if (!MMAMatrixType::isValidElementType(elementType))
154 return emitError()
155 << "MMAMatrixType elements must be SI8, UI8, I32, F16, F32, or F64";
156
157 return success();
158}
159
160//===----------------------------------------------------------------------===//
161// GPUDialect
162//===----------------------------------------------------------------------===//
163
164bool GPUDialect::isWorkgroupMemoryAddressSpace(Attribute memorySpace) {
165 if (!memorySpace)
166 return false;
167 if (auto gpuAttr = llvm::dyn_cast<gpu::AddressSpaceAttr>(memorySpace))
168 return gpuAttr.getValue() == getWorkgroupAddressSpace();
169 return false;
170}
171
172bool GPUDialect::hasWorkgroupMemoryAddressSpace(MemRefType type) {
173 Attribute memorySpace = type.getMemorySpace();
174 return isWorkgroupMemoryAddressSpace(memorySpace);
175}
176
177bool GPUDialect::isConstantMemoryAddressSpace(Attribute memorySpace) {
178 if (!memorySpace)
179 return false;
180 if (auto gpuAttr = llvm::dyn_cast<gpu::AddressSpaceAttr>(memorySpace))
181 return gpuAttr.getValue() == getConstantAddressSpace();
182 return false;
183}
184
185bool GPUDialect::hasConstantMemoryAddressSpace(MemRefType type) {
186 Attribute memorySpace = type.getMemorySpace();
187 return isConstantMemoryAddressSpace(memorySpace);
188}
189
190//===----------------------------------------------------------------------===//
191// GPU object attribute
192//===----------------------------------------------------------------------===//
193
194LogicalResult ObjectAttr::verify(function_ref<InFlightDiagnostic()> emitError,
195 Attribute target, CompilationTarget format,
196 StringAttr object, DictionaryAttr properties,
197 KernelTableAttr kernels) {
198 if (!target)
199 return emitError() << "the target attribute cannot be null";
200 if (target.hasPromiseOrImplementsInterface<TargetAttrInterface>())
201 return success();
202 return emitError() << "the target attribute must implement or promise the "
203 "`gpu::TargetAttrInterface`";
204}
205
206namespace {
207ParseResult parseObject(AsmParser &odsParser, CompilationTarget &format,
208 StringAttr &object) {
209 std::optional<CompilationTarget> formatResult;
210 StringRef enumKeyword;
211 auto loc = odsParser.getCurrentLocation();
212 if (failed(odsParser.parseOptionalKeyword(&enumKeyword)))
213 formatResult = CompilationTarget::Fatbin;
214 if (!formatResult &&
215 (formatResult =
216 gpu::symbolizeEnum<gpu::CompilationTarget>(enumKeyword)) &&
217 odsParser.parseEqual())
218 return odsParser.emitError(loc, "expected an equal sign");
219 if (!formatResult)
220 return odsParser.emitError(loc, "expected keyword for GPU object format");
221 FailureOr<StringAttr> objectResult =
222 FieldParser<StringAttr>::parse(odsParser);
223 if (failed(objectResult))
224 return odsParser.emitError(odsParser.getCurrentLocation(),
225 "failed to parse GPU_ObjectAttr parameter "
226 "'object' which is to be a `StringAttr`");
227 format = *formatResult;
228 object = *objectResult;
229 return success();
230}
231
232void printObject(AsmPrinter &odsParser, CompilationTarget format,
233 StringAttr object) {
234 if (format != CompilationTarget::Fatbin)
235 odsParser << stringifyEnum(format) << " = ";
236 odsParser << object;
237}
238} // namespace
239
240//===----------------------------------------------------------------------===//
241// GPU select object attribute
242//===----------------------------------------------------------------------===//
243
244LogicalResult
245gpu::SelectObjectAttr::verify(function_ref<InFlightDiagnostic()> emitError,
246 Attribute target) {
247 // Check `target`, it can be null, an integer attr or a GPU Target attribute.
248 if (target) {
249 if (auto intAttr = mlir::dyn_cast<IntegerAttr>(target)) {
250 if (intAttr.getInt() < 0) {
251 return emitError() << "the object index must be positive";
252 }
253 } else if (!target.hasPromiseOrImplementsInterface<TargetAttrInterface>()) {
254 return emitError()
255 << "the target attribute must be a GPU Target attribute";
256 }
257 }
258 return success();
259}
260
261//===----------------------------------------------------------------------===//
262// GPU KernelMetadataAttr
263//===----------------------------------------------------------------------===//
264
265KernelMetadataAttr KernelMetadataAttr::get(FunctionOpInterface kernel,
266 DictionaryAttr metadata) {
267 assert(kernel && "invalid kernel");
268 return get(kernel.getNameAttr(), kernel.getFunctionType(),
269 kernel.getAllArgAttrs(), metadata);
270}
271
272KernelMetadataAttr
273KernelMetadataAttr::getChecked(function_ref<InFlightDiagnostic()> emitError,
274 FunctionOpInterface kernel,
275 DictionaryAttr metadata) {
276 assert(kernel && "invalid kernel");
277 return getChecked(emitError, kernel.getNameAttr(), kernel.getFunctionType(),
278 kernel.getAllArgAttrs(), metadata);
279}
280
281KernelMetadataAttr
282KernelMetadataAttr::appendMetadata(ArrayRef<NamedAttribute> attrs) const {
283 if (attrs.empty())
284 return *this;
285 NamedAttrList attrList;
286 if (DictionaryAttr dict = getMetadata())
287 attrList.append(dict);
288 attrList.append(attrs);
289 return KernelMetadataAttr::get(getName(), getFunctionType(), getArgAttrs(),
290 attrList.getDictionary(getContext()));
291}
292
293LogicalResult
294KernelMetadataAttr::verify(function_ref<InFlightDiagnostic()> emitError,
295 StringAttr name, Type functionType,
296 ArrayAttr argAttrs, DictionaryAttr metadata) {
297 if (name.empty())
298 return emitError() << "the kernel name can't be empty";
299 if (argAttrs) {
300 if (llvm::any_of(argAttrs, [](Attribute attr) {
301 return !llvm::isa<DictionaryAttr>(attr);
302 }))
303 return emitError()
304 << "all attributes in the array must be a dictionary attribute";
305 }
306 return success();
307}
308
309//===----------------------------------------------------------------------===//
310// GPU KernelTableAttr
311//===----------------------------------------------------------------------===//
312
313KernelTableAttr KernelTableAttr::get(MLIRContext *context,
314 ArrayRef<KernelMetadataAttr> kernels,
315 bool isSorted) {
316 // Note that `is_sorted` is always only invoked once even with assertions ON.
317 assert((!isSorted || llvm::is_sorted(kernels)) &&
318 "expected a sorted kernel array");
319 // Immediately return the attribute if the array is sorted.
320 if (isSorted || llvm::is_sorted(kernels))
321 return Base::get(context, kernels);
322 // Sort the array.
323 SmallVector<KernelMetadataAttr> kernelsTmp(kernels);
324 llvm::array_pod_sort(kernelsTmp.begin(), kernelsTmp.end());
325 return Base::get(context, kernelsTmp);
326}
327
328KernelTableAttr KernelTableAttr::getChecked(
329 function_ref<InFlightDiagnostic()> emitError, MLIRContext *context,
330 ArrayRef<KernelMetadataAttr> kernels, bool isSorted) {
331 // Note that `is_sorted` is always only invoked once even with assertions ON.
332 assert((!isSorted || llvm::is_sorted(kernels)) &&
333 "expected a sorted kernel array");
334 // Immediately return the attribute if the array is sorted.
335 if (isSorted || llvm::is_sorted(kernels))
336 return Base::getChecked(emitError, context, kernels);
337 // Sort the array.
338 SmallVector<KernelMetadataAttr> kernelsTmp(kernels);
339 llvm::array_pod_sort(kernelsTmp.begin(), kernelsTmp.end());
340 return Base::getChecked(emitError, context, kernelsTmp);
341}
342
343LogicalResult
344KernelTableAttr::verify(function_ref<InFlightDiagnostic()> emitError,
345 ArrayRef<KernelMetadataAttr> kernels) {
346 if (kernels.size() < 2)
347 return success();
348 // Check that the kernels are uniquely named.
349 if (std::adjacent_find(kernels.begin(), kernels.end(),
350 [](KernelMetadataAttr l, KernelMetadataAttr r) {
351 return l.getName() == r.getName();
352 }) != kernels.end()) {
353 return emitError() << "expected all kernels to be uniquely named";
354 }
355 return success();
356}
357
358KernelMetadataAttr KernelTableAttr::lookup(StringRef key) const {
359 auto [iterator, found] = impl::findAttrSorted(begin(), end(), key);
360 return found ? *iterator : KernelMetadataAttr();
361}
362
363KernelMetadataAttr KernelTableAttr::lookup(StringAttr key) const {
364 auto [iterator, found] = impl::findAttrSorted(begin(), end(), key);
365 return found ? *iterator : KernelMetadataAttr();
366}
367
368//===----------------------------------------------------------------------===//
369// GPU target options
370//===----------------------------------------------------------------------===//
371
386
404
405TypeID TargetOptions::getTypeID() const { return typeID; }
406
407StringRef TargetOptions::getToolkitPath() const { return toolkitPath; }
408
412
413StringRef TargetOptions::getCmdOptions() const { return cmdOptions; }
414
415StringRef TargetOptions::getELFSection() const { return elfSection; }
416
420
421function_ref<void(llvm::Module &)>
425
426function_ref<void(llvm::Module &)>
430
431function_ref<void(llvm::Module &)>
435
437 return isaCallback;
438}
439
440CompilationTarget TargetOptions::getCompilationTarget() const {
441 return compilationTarget;
442}
443
445 return CompilationTarget::Fatbin;
446}
447
448std::pair<llvm::BumpPtrAllocator, SmallVector<const char *>>
450 std::pair<llvm::BumpPtrAllocator, SmallVector<const char *>> options;
451 llvm::StringSaver stringSaver(options.first);
452 StringRef opts = cmdOptions;
453 // For a correct tokenization of the command line options `opts` must be
454 // unquoted, otherwise the tokenization function returns a single string: the
455 // unquoted `cmdOptions` -which is not the desired behavior.
456 // Remove any quotes if they are at the beginning and end of the string:
457 if (!opts.empty() && opts.front() == '"' && opts.back() == '"')
458 opts.consume_front("\""), opts.consume_back("\"");
459 if (!opts.empty() && opts.front() == '\'' && opts.back() == '\'')
460 opts.consume_front("'"), opts.consume_back("'");
461#ifdef _WIN32
462 llvm::cl::TokenizeWindowsCommandLine(opts, stringSaver, options.second,
463 /*MarkEOLs=*/false);
464#else
465 llvm::cl::TokenizeGNUCommandLine(opts, stringSaver, options.second,
466 /*MarkEOLs=*/false);
467#endif // _WIN32
468 return options;
469}
470
471std::pair<llvm::BumpPtrAllocator, SmallVector<const char *>>
475
476std::pair<llvm::BumpPtrAllocator, SmallVector<const char *>>
478 size_t startPos = cmdOptions.find(startsWith);
479 if (startPos == std::string::npos)
480 return {llvm::BumpPtrAllocator(), SmallVector<const char *>()};
481
482 auto tokenized =
483 tokenizeCmdOptions(cmdOptions.substr(startPos + startsWith.size()));
484 cmdOptions.resize(startPos);
485 return tokenized;
486}
487
489
490#include "mlir/Dialect/GPU/IR/GPUOpsEnums.cpp.inc"
491
492#define GET_ATTRDEF_CLASSES
493#include "mlir/Dialect/GPU/IR/GPUOpsAttributes.cpp.inc"
494
495namespace {
496template <typename... Attrs>
497void registerAttributeStorageImpl(MLIRContext *context) {
499}
500} // namespace
501
503 registerAttributeStorageImpl<
504#define GET_ATTRDEF_LIST
505#include "mlir/Dialect/GPU/IR/GPUOpsAttributes.cpp.inc"
506 >(context);
507}
508
509#include "mlir/Dialect/GPU/IR/CompilationAttrInterfaces.cpp.inc"
return success()
ArrayAttr()
b getContext())
static llvm::ManagedStatic< PassManagerOptions > options
#define MLIR_DEFINE_EXPLICIT_TYPE_ID(CLASS_NAME)
Definition TypeID.h:323
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.
virtual ParseResult parseEqual()=0
Parse a = token.
virtual SMLoc getCurrentLocation()=0
Get the location of the next token and store it into the argument.
Attributes are known-constant values of operations.
Definition Attributes.h:25
This class represents a diagnostic that is inflight and set to be reported.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:64
DictionaryAttr getDictionary(MLIRContext *context) const
Return a dictionary attribute for the underlying dictionary.
void append(StringRef name, Attribute attr)
Add an attribute with the specified name.
This class allows for representing and managing the symbol table used by operations with the 'SymbolT...
Definition SymbolTable.h:25
This class provides an efficient unique identifier for a specific C++ type.
Definition TypeID.h:107
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
bool isF64() const
Definition Types.cpp:41
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
Definition Types.cpp:35
bool isSignedInteger() const
Return true if this is a signed integer type (with the specified width).
Definition Types.cpp:78
bool isF32() const
Definition Types.cpp:40
bool isUnsignedInteger() const
Return true if this is an unsigned integer type (with the specified width).
Definition Types.cpp:90
bool isInteger() const
Return true if this is an integer type (with the specified width).
Definition Types.cpp:58
bool isF16() const
Definition Types.cpp:38
static void registerAttribute(MLIRContext *ctx)
Register an attribute instance T with the uniquer.
MMAMatrix represents a matrix held by a subgroup for matrix-matrix multiply accumulate operations.
Definition GPUBase.h:132
ArrayRef< int64_t > getShape() const
Get shape of the matrix.
Definition GPUBase.cpp:129
static MMAMatrixType get(ArrayRef< int64_t > shape, Type elementType, StringRef operand)
Get MMAMatrixType and verify construction Invariants.
Definition GPUBase.cpp:114
Type getElementType() const
Get elementType of a single element.
Definition GPUBase.cpp:133
static bool isValidElementType(Type elementType)
Check if a type is valid a MMAMatrixType elementType.
Definition GPUBase.cpp:137
static LogicalResult verifyInvariants(function_ref< InFlightDiagnostic()> emitError, ArrayRef< int64_t > shape, Type elementType, StringRef operand)
Verify that shape and elementType are actually allowed for the MMAMatrixType.
Definition GPUBase.cpp:144
StringRef getOperand() const
The general form of operation this type supports is given by the equation C += A*B.
Definition GPUBase.cpp:135
static MMAMatrixType getChecked(function_ref< InFlightDiagnostic()> emitError, ArrayRef< int64_t > shape, Type elementType, StringRef operand)
Get MMAMatrixType at a particular location and verify construction Invariants.
Definition GPUBase.cpp:120
unsigned getNumDims() const
Get number of dims.
Definition GPUBase.cpp:127
This class serves as an opaque interface for passing options to the TargetAttrInterface methods.
function_ref< void(llvm::Module &)> optimizedLlvmIRCallback
Callback invoked with LLVM IR for the device module after LLVM optimizations but before codegen.
function_ref< void(StringRef)> getISACallback() const
Returns the callback invoked with the target ISA for the device, for example PTX assembly.
Definition GPUBase.cpp:436
TypeID getTypeID() const
Returns the typeID.
Definition GPUBase.cpp:405
std::string toolkitPath
Path to the target toolkit.
SymbolTable * getSymbolTable() const
Returns the result of the getSymbolTableCallback callback or a nullptr if no callback was provided.
Definition GPUBase.cpp:417
StringRef getELFSection() const
Returns the ELF section.
Definition GPUBase.cpp:415
StringRef getCmdOptions() const
Returns the command line options.
Definition GPUBase.cpp:413
std::string cmdOptions
An optional set of command line options to be used by the compilation process.
function_ref< void(StringRef)> isaCallback
Callback invoked with the target ISA for the device, for example PTX assembly.
CompilationTarget compilationTarget
Compilation process target format.
std::pair< llvm::BumpPtrAllocator, SmallVector< const char * > > tokenizeCmdOptions() const
Returns a tokenization of the command line options.
Definition GPUBase.cpp:472
function_ref< void(llvm::Module &)> initialLlvmIRCallback
Callback invoked with the initial LLVM IR for the device module.
ArrayRef< Attribute > getLibrariesToLink() const
Returns the LLVM libraries to link to.
Definition GPUBase.cpp:409
TargetOptions(StringRef toolkitPath={}, ArrayRef< Attribute > librariesToLink={}, StringRef cmdOptions={}, StringRef elfSection={}, CompilationTarget compilationTarget=getDefaultCompilationTarget(), function_ref< SymbolTable *()> getSymbolTableCallback={}, function_ref< void(llvm::Module &)> initialLlvmIRCallback={}, function_ref< void(llvm::Module &)> linkedLlvmIRCallback={}, function_ref< void(llvm::Module &)> optimizedLlvmIRCallback={}, function_ref< void(StringRef)> isaCallback={})
Constructor initializing the toolkit path, the list of files to link to, extra command line options,...
Definition GPUBase.cpp:372
function_ref< void(llvm::Module &)> getOptimizedLlvmIRCallback() const
Returns the callback invoked with LLVM IR for the device module after LLVM optimizations but before c...
Definition GPUBase.cpp:432
std::pair< llvm::BumpPtrAllocator, SmallVector< const char * > > tokenizeAndRemoveSuffixCmdOptions(llvm::StringRef startsWith)
Returns a tokenization of the substr of the command line options that starts with startsWith and ends...
Definition GPUBase.cpp:477
StringRef getToolkitPath() const
Returns the toolkit path.
Definition GPUBase.cpp:407
SmallVector< Attribute > librariesToLink
List of files to link with the LLVM module.
function_ref< void(llvm::Module &)> linkedLlvmIRCallback
Callback invoked with LLVM IR for the device module after linking the device libraries.
function_ref< void(llvm::Module &)> getInitialLlvmIRCallback() const
Returns the callback invoked with the initial LLVM IR for the device module.
Definition GPUBase.cpp:422
function_ref< SymbolTable *()> getSymbolTableCallback
Callback for obtaining the parent symbol table of all the GPU modules being serialized.
static CompilationTarget getDefaultCompilationTarget()
Returns the default compilation target: CompilationTarget::Fatbin.
Definition GPUBase.cpp:444
function_ref< void(llvm::Module &)> getLinkedLlvmIRCallback() const
Returns the callback invoked with LLVM IR for the device module after linking the device libraries.
Definition GPUBase.cpp:427
std::string elfSection
ELF Section where the binary needs to be located.
CompilationTarget getCompilationTarget() const
Returns the compilation target.
Definition GPUBase.cpp:440
ArrayRef< NamedAttribute > getArgAttrs(FunctionOpInterface op, unsigned index)
Return all of the attributes for the argument at 'index'.
void registerAttributeStorage(MLIRContext *context)
Register storage whose definitions are private to MLIRGPUBase.
Definition GPUBase.cpp:502
std::pair< IteratorT, bool > findAttrSorted(IteratorT first, IteratorT last, StringRef name)
Using llvm::lower_bound requires an extra string comparison to check whether the returned iterator po...
detail::InFlightRemark failed(Location loc, RemarkOpts opts)
Report an optimization remark that failed.
Definition Remarks.h:734
Include the generated interface declarations.
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:155