19 #include "llvm/ADT/TypeSwitch.h"
20 #include "llvm/IR/IRBuilder.h"
21 #include "llvm/IR/InlineAsm.h"
22 #include "llvm/IR/MDBuilder.h"
23 #include "llvm/IR/MatrixBuilder.h"
24 #include "llvm/IR/Operator.h"
30 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsToLLVM.inc"
33 using llvmFMF = llvm::FastMathFlags;
34 using FuncT = void (llvmFMF::*)(bool);
35 const std::pair<FastmathFlags, FuncT> handlers[] = {
37 {FastmathFlags::nnan, &llvmFMF::setNoNaNs},
38 {FastmathFlags::ninf, &llvmFMF::setNoInfs},
39 {FastmathFlags::nsz, &llvmFMF::setNoSignedZeros},
40 {FastmathFlags::arcp, &llvmFMF::setAllowReciprocal},
42 {FastmathFlags::afn, &llvmFMF::setApproxFunc},
43 {FastmathFlags::reassoc, &llvmFMF::setAllowReassoc},
46 llvm::FastMathFlags ret;
47 ::mlir::LLVM::FastmathFlags fmfMlir = op.getFastmathAttr().getValue();
48 for (
auto it : handlers)
49 if (bitEnumContainsAll(fmfMlir, it.first))
50 (ret.*(it.second))(
true);
57 llvm::append_range(position, indices);
62 static std::string
diagStr(
const llvm::Type *type) {
64 llvm::raw_string_ostream os(str);
72 static FailureOr<llvm::Function *>
77 for (
Type type : op->getOperandTypes())
78 allArgTys.push_back(moduleTranslation.
convertType(type));
81 if (op.getNumResults() == 0)
82 resTy = llvm::Type::getVoidTy(module->getContext());
84 resTy = moduleTranslation.
convertType(op.getResult(0).getType());
90 getIntrinsicInfoTableEntries(
id,
table);
94 if (llvm::Intrinsic::matchIntrinsicSignature(ft, tableRef,
96 llvm::Intrinsic::MatchIntrinsicTypesResult::MatchIntrinsicTypes_Match) {
98 <<
diagStr(ft) <<
" to overloaded intrinsic " << op.getIntrinAttr()
99 <<
" does not match any of the overloads";
103 return llvm::Intrinsic::getOrInsertDeclaration(module,
id,
104 overloadedArgTysRef);
107 static llvm::OperandBundleDef
110 std::vector<llvm::Value *> operands;
111 operands.reserve(bundleOperands.size());
112 for (
Value bundleArg : bundleOperands)
113 operands.push_back(moduleTranslation.
lookupValue(bundleArg));
114 return llvm::OperandBundleDef(bundleTag.str(), std::move(operands));
121 bundles.reserve(bundleOperands.size());
123 for (
auto [operands, tagAttr] : llvm::zip_equal(bundleOperands, bundleTags)) {
124 StringRef tag = cast<StringAttr>(tagAttr).getValue();
132 std::optional<ArrayAttr> bundleTags,
141 ArrayAttr resAttrsArray, llvm::CallBase *call,
145 if (
auto argAttrs = cast<DictionaryAttr>(argAttrsAttr);
147 FailureOr<llvm::AttrBuilder> attrBuilder =
149 if (failed(attrBuilder))
151 call->addParamAttrs(argIdx, *attrBuilder);
156 if (resAttrsArray && resAttrsArray.size() > 0) {
157 if (resAttrsArray.size() != 1)
159 if (
auto resAttrs = cast<DictionaryAttr>(resAttrsArray[0]);
161 FailureOr<llvm::AttrBuilder> attrBuilder =
163 if (failed(attrBuilder))
165 call->addRetAttrs(*attrBuilder);
175 callOp.getLoc(), callOp.getArgAttrsAttr(), callOp.getResAttrsAttr(), call,
183 llvm::Module *module = builder.GetInsertBlock()->getModule();
185 llvm::Intrinsic::lookupIntrinsicID(op.getIntrinAttr());
188 << op.getIntrinAttr();
190 llvm::Function *fn =
nullptr;
191 if (llvm::Intrinsic::isOverloaded(
id)) {
194 if (failed(fnOrFailure))
198 fn = llvm::Intrinsic::getOrInsertDeclaration(module,
id, {});
202 const llvm::Type *intrinType =
203 op.getNumResults() == 0
204 ? llvm::Type::getVoidTy(module->getContext())
205 : moduleTranslation.
convertType(op.getResultTypes().front());
206 if (intrinType != fn->getReturnType()) {
208 <<
diagStr(intrinType) <<
" but " << op.getIntrinAttr()
209 <<
" actually returns " <<
diagStr(fn->getReturnType());
214 if (!fn->getFunctionType()->isVarArg() &&
215 op.getArgs().size() != fn->arg_size()) {
217 << op.getArgs().size() <<
" operands but " << op.getIntrinAttr()
218 <<
" expects " << fn->arg_size();
220 if (fn->getFunctionType()->isVarArg() &&
221 op.getArgs().size() < fn->arg_size()) {
223 << op.getArgs().size() <<
" operands but variadic "
224 << op.getIntrinAttr() <<
" expects at least " << fn->arg_size();
227 for (
unsigned i = 0, e = fn->arg_size(); i != e; ++i) {
228 const llvm::Type *expected = fn->getArg(i)->getType();
229 const llvm::Type *actual =
230 moduleTranslation.
convertType(op.getOperandTypes()[i]);
231 if (actual != expected) {
233 << i <<
" has type " <<
diagStr(actual) <<
" but "
234 << op.getIntrinAttr() <<
" expects " <<
diagStr(expected);
238 FastmathFlagsInterface itf = op;
241 auto *inst = builder.CreateCall(
247 op.getResAttrsAttr(), inst,
251 if (op.getNumResults() == 1)
252 moduleTranslation.
mapValue(op->getResults().front()) = inst;
257 llvm::IRBuilderBase &builder,
259 llvm::Module *llvmModule = moduleTranslation.
getLLVMModule();
260 llvm::LLVMContext &context = llvmModule->getContext();
261 llvm::NamedMDNode *linkerMDNode =
262 llvmModule->getOrInsertNamedMetadata(
"llvm.linker.options");
264 MDNodes.reserve(
options.size());
265 for (
auto s :
options.getAsRange<StringAttr>()) {
267 MDNodes.push_back(MDNode);
271 linkerMDNode->addOperand(listMDNode);
274 static llvm::Metadata *
276 llvm::IRBuilderBase &builder,
278 llvm::LLVMContext &context = builder.getContext();
279 llvm::MDBuilder mdb(context);
282 if (key == LLVMDialect::getModuleFlagKeyCGProfileName()) {
283 for (
auto entry : arrayAttr.getAsRange<ModuleFlagCGProfileEntryAttr>()) {
284 llvm::Metadata *fromMetadata =
287 entry.getFrom().getValue()))
289 llvm::Metadata *toMetadata =
295 llvm::Metadata *vals[] = {
296 fromMetadata, toMetadata,
298 llvm::Type::getInt64Ty(context), entry.getCount()))};
301 return llvm::MDTuple::getDistinct(context, nodes);
308 llvm::Module *llvmModule = moduleTranslation.
getLLVMModule();
309 for (
auto flagAttr : flags.getAsRange<ModuleFlagAttr>()) {
310 llvm::Metadata *valueMetadata =
312 .Case<StringAttr>([&](
auto strAttr) {
316 .Case<IntegerAttr>([&](
auto intAttr) {
318 llvm::Type::getInt32Ty(builder.getContext()),
321 .Case<ArrayAttr>([&](
auto arrayAttr) {
326 .Default([](
auto) {
return nullptr; });
328 assert(valueMetadata &&
"expected valid metadata");
329 llvmModule->addModuleFlag(
330 convertModFlagBehaviorToLLVM(flagAttr.getBehavior()),
331 flagAttr.getKey().getValue(), valueMetadata);
339 llvm::IRBuilder<>::FastMathFlagGuard fmfGuard(builder);
340 if (
auto fmf = dyn_cast<FastmathFlagsInterface>(opInst))
343 #include "mlir/Dialect/LLVMIR/LLVMConversions.inc"
344 #include "mlir/Dialect/LLVMIR/LLVMIntrinsicConversions.inc"
350 if (
auto callOp = dyn_cast<LLVM::CallOp>(opInst)) {
351 auto operands = moduleTranslation.
lookupValues(callOp.getCalleeOperands());
354 callOp.getOpBundleTags(), moduleTranslation);
356 llvm::CallInst *call;
357 if (
auto attr = callOp.getCalleeAttr()) {
359 builder.CreateCall(moduleTranslation.
lookupFunction(attr.getValue()),
360 operandsRef, opBundles);
362 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
363 moduleTranslation.
convertType(callOp.getCalleeFunctionType()));
364 call = builder.CreateCall(calleeType, operandsRef.front(),
365 operandsRef.drop_front(), opBundles);
367 call->setCallingConv(convertCConvToLLVM(callOp.getCConv()));
368 call->setTailCallKind(convertTailCallKindToLLVM(callOp.getTailCallKind()));
369 if (callOp.getConvergentAttr())
370 call->addFnAttr(llvm::Attribute::Convergent);
371 if (callOp.getNoUnwindAttr())
372 call->addFnAttr(llvm::Attribute::NoUnwind);
373 if (callOp.getWillReturnAttr())
374 call->addFnAttr(llvm::Attribute::WillReturn);
375 if (callOp.getNoInlineAttr())
376 call->addFnAttr(llvm::Attribute::NoInline);
377 if (callOp.getAlwaysInlineAttr())
378 call->addFnAttr(llvm::Attribute::AlwaysInline);
379 if (callOp.getInlineHintAttr())
380 call->addFnAttr(llvm::Attribute::InlineHint);
385 if (MemoryEffectsAttr memAttr = callOp.getMemoryEffectsAttr()) {
386 llvm::MemoryEffects memEffects =
387 llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
388 convertModRefInfoToLLVM(memAttr.getArgMem())) |
390 llvm::MemoryEffects::Location::InaccessibleMem,
391 convertModRefInfoToLLVM(memAttr.getInaccessibleMem())) |
392 llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
393 convertModRefInfoToLLVM(memAttr.getOther()));
394 call->setMemoryEffects(memEffects);
405 else if (!call->getType()->isVoidTy())
407 moduleTranslation.
mapCall(callOp, call);
411 if (
auto inlineAsmOp = dyn_cast<LLVM::InlineAsmOp>(opInst)) {
415 llvm::append_range(operandTypes, inlineAsmOp.getOperands().getTypes());
418 if (inlineAsmOp.getNumResults() == 0) {
421 assert(inlineAsmOp.getNumResults() == 1);
422 resultType = inlineAsmOp.getResultTypes()[0];
425 llvm::InlineAsm *inlineAsmInst =
426 inlineAsmOp.getAsmDialect()
428 static_cast<llvm::FunctionType *
>(
430 inlineAsmOp.getAsmString(), inlineAsmOp.getConstraints(),
431 inlineAsmOp.getHasSideEffects(),
432 inlineAsmOp.getIsAlignStack(),
433 convertAsmDialectToLLVM(*inlineAsmOp.getAsmDialect()))
436 inlineAsmOp.getAsmString(),
437 inlineAsmOp.getConstraints(),
438 inlineAsmOp.getHasSideEffects(),
439 inlineAsmOp.getIsAlignStack());
440 llvm::CallInst *inst = builder.CreateCall(
442 moduleTranslation.
lookupValues(inlineAsmOp.getOperands()));
443 if (
auto maybeOperandAttrs = inlineAsmOp.getOperandAttrs()) {
444 llvm::AttributeList attrList;
449 DictionaryAttr dAttr = cast<DictionaryAttr>(attr);
451 cast<TypeAttr>(dAttr.get(InlineAsmOp::getElementTypeAttrName()));
453 llvm::Type *ty = moduleTranslation.
convertType(tAttr.getValue());
454 b.addTypeAttr(llvm::Attribute::ElementType, ty);
458 attrList = attrList.addAttributesAtIndex(
461 inst->setAttributes(attrList);
469 if (
auto invOp = dyn_cast<LLVM::InvokeOp>(opInst)) {
470 auto operands = moduleTranslation.
lookupValues(invOp.getCalleeOperands());
473 invOp.getOpBundleTags(), moduleTranslation);
475 llvm::InvokeInst *result;
477 result = builder.CreateInvoke(
479 moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
480 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)), operandsRef,
483 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
484 moduleTranslation.
convertType(invOp.getCalleeFunctionType()));
485 result = builder.CreateInvoke(
486 calleeType, operandsRef.front(),
487 moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
488 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)),
489 operandsRef.drop_front(), opBundles);
491 result->setCallingConv(convertCConvToLLVM(invOp.getCConv()));
495 moduleTranslation.
mapBranch(invOp, result);
497 if (invOp->getNumResults() != 0) {
501 return success(result->getType()->isVoidTy());
504 if (
auto lpOp = dyn_cast<LLVM::LandingpadOp>(opInst)) {
505 llvm::Type *ty = moduleTranslation.
convertType(lpOp.getType());
506 llvm::LandingPadInst *lpi =
507 builder.CreateLandingPad(ty, lpOp.getNumOperands());
508 lpi->setCleanup(lpOp.getCleanup());
511 for (llvm::Value *operand :
514 if (
auto *constOperand = dyn_cast<llvm::Constant>(operand))
515 lpi->addClause(constOperand);
517 moduleTranslation.
mapValue(lpOp.getResult(), lpi);
523 if (
auto brOp = dyn_cast<LLVM::BrOp>(opInst)) {
524 llvm::BranchInst *branch =
525 builder.CreateBr(moduleTranslation.
lookupBlock(brOp.getSuccessor()));
526 moduleTranslation.
mapBranch(&opInst, branch);
530 if (
auto condbrOp = dyn_cast<LLVM::CondBrOp>(opInst)) {
531 llvm::BranchInst *branch = builder.CreateCondBr(
532 moduleTranslation.
lookupValue(condbrOp.getOperand(0)),
533 moduleTranslation.
lookupBlock(condbrOp.getSuccessor(0)),
534 moduleTranslation.
lookupBlock(condbrOp.getSuccessor(1)));
535 moduleTranslation.
mapBranch(&opInst, branch);
539 if (
auto switchOp = dyn_cast<LLVM::SwitchOp>(opInst)) {
540 llvm::SwitchInst *switchInst = builder.CreateSwitch(
541 moduleTranslation.
lookupValue(switchOp.getValue()),
542 moduleTranslation.
lookupBlock(switchOp.getDefaultDestination()),
543 switchOp.getCaseDestinations().size());
546 if (!switchOp.getCaseValues())
549 auto *ty = llvm::cast<llvm::IntegerType>(
550 moduleTranslation.
convertType(switchOp.getValue().getType()));
552 llvm::zip(llvm::cast<DenseIntElementsAttr>(*switchOp.getCaseValues()),
553 switchOp.getCaseDestinations()))
558 moduleTranslation.
mapBranch(&opInst, switchInst);
561 if (
auto indBrOp = dyn_cast<LLVM::IndirectBrOp>(opInst)) {
562 llvm::IndirectBrInst *indBr = builder.CreateIndirectBr(
564 indBrOp->getNumSuccessors());
565 for (
auto *succ : indBrOp.getSuccessors())
566 indBr->addDestination(moduleTranslation.
lookupBlock(succ));
567 moduleTranslation.
mapBranch(&opInst, indBr);
574 if (
auto addressOfOp = dyn_cast<LLVM::AddressOfOp>(opInst)) {
575 LLVM::GlobalOp global =
576 addressOfOp.getGlobal(moduleTranslation.
symbolTable());
577 LLVM::LLVMFuncOp
function =
578 addressOfOp.getFunction(moduleTranslation.
symbolTable());
579 LLVM::AliasOp alias = addressOfOp.getAlias(moduleTranslation.
symbolTable());
582 assert((global ||
function || alias) &&
583 "referencing an undefined global, function, or alias");
585 llvm::Value *llvmValue =
nullptr;
593 moduleTranslation.
mapValue(addressOfOp.getResult(), llvmValue);
599 if (
auto dsoLocalEquivalentOp =
600 dyn_cast<LLVM::DSOLocalEquivalentOp>(opInst)) {
601 LLVM::LLVMFuncOp
function =
602 dsoLocalEquivalentOp.getFunction(moduleTranslation.
symbolTable());
603 LLVM::AliasOp alias =
604 dsoLocalEquivalentOp.getAlias(moduleTranslation.
symbolTable());
607 assert((
function || alias) &&
608 "referencing an undefined function, or alias");
610 llvm::Value *llvmValue =
nullptr;
617 dsoLocalEquivalentOp.getResult(),
624 if (
auto blockAddressOp = dyn_cast<LLVM::BlockAddressOp>(opInst)) {
627 BlockAddressAttr blockAddressAttr = blockAddressOp.getBlockAddr();
628 BlockTagOp blockTagOp = moduleTranslation.
lookupBlockTag(blockAddressAttr);
630 blockTagOp = blockAddressOp.getBlockTagOp();
631 moduleTranslation.
mapBlockTag(blockAddressAttr, blockTagOp);
634 llvm::Value *llvmValue =
nullptr;
635 StringRef fnName = blockAddressAttr.getFunction().getValue();
636 if (llvm::BasicBlock *llvmBlock =
637 moduleTranslation.
lookupBlock(blockTagOp->getBlock())) {
638 llvm::Function *llvmFn = moduleTranslation.
lookupFunction(fnName);
647 llvmValue =
new llvm::GlobalVariable(
650 true, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
652 Twine(
"__mlir_block_address_")
654 .
concat(Twine((uint64_t)blockAddressOp.getOperation())));
658 moduleTranslation.
mapValue(blockAddressOp.getResult(), llvmValue);
664 if (
auto blockTagOp = dyn_cast<LLVM::BlockTagOp>(opInst)) {
665 auto funcOp = blockTagOp->getParentOfType<LLVMFuncOp>();
670 blockTagOp.getTag());
671 moduleTranslation.
mapBlockTag(blockAddressAttr, blockTagOp);
681 class LLVMDialectLLVMIRTranslationInterface
689 convertOperation(
Operation *op, llvm::IRBuilderBase &builder,
697 registry.
insert<LLVM::LLVMDialect>();
699 dialect->addInterfaces<LLVMDialectLLVMIRTranslationInterface>();
static SmallVector< unsigned > extractPosition(ArrayRef< int64_t > indices)
Convert the value of a DenseI64ArrayAttr to a vector of unsigned indices.
static std::string diagStr(const llvm::Type *type)
Convert an LLVM type to a string for printing in diagnostics.
static LogicalResult convertParameterAndResultAttrs(mlir::Location loc, ArrayAttr argAttrsArray, ArrayAttr resAttrsArray, llvm::CallBase *call, LLVM::ModuleTranslation &moduleTranslation)
static void convertModuleFlagsOp(ArrayAttr flags, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation)
static FailureOr< llvm::Function * > getOverloadedDeclaration(CallIntrinsicOp op, llvm::Intrinsic::ID id, llvm::Module *module, LLVM::ModuleTranslation &moduleTranslation)
Get the declaration of an overloaded llvm intrinsic.
static LogicalResult convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation)
static SmallVector< llvm::OperandBundleDef > convertOperandBundles(OperandRangeRange bundleOperands, ArrayAttr bundleTags, LLVM::ModuleTranslation &moduleTranslation)
static LogicalResult convertCallLLVMIntrinsicOp(CallIntrinsicOp op, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation)
Builder for LLVM_CallIntrinsicOp.
static llvm::FastMathFlags getFastmathFlags(FastmathFlagsInterface &op)
static llvm::OperandBundleDef convertOperandBundle(OperandRange bundleOperands, StringRef bundleTag, LLVM::ModuleTranslation &moduleTranslation)
static llvm::Metadata * convertModuleFlagValue(StringRef key, ArrayAttr arrayAttr, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation)
static void convertLinkerOptionsOp(ArrayAttr options, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation)
static llvm::ManagedStatic< PassManagerOptions > options
static void contract(RootOrderingGraph &graph, ArrayRef< Value > cycle, const DenseMap< Value, unsigned > &parentDepths, DenseMap< Value, Value > &actualSource, DenseMap< Value, Value > &actualTarget)
Contracts the specified cycle in the given graph in-place.
Attributes are known-constant values of operations.
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
A symbol reference with a reference path containing a single element.
static FlatSymbolRefAttr get(StringAttr value)
Construct a symbol reference for the given value name.
Base class for dialect interfaces providing translation to LLVM IR.
LLVMTranslationDialectInterface(Dialect *dialect)
Implementation class for module translation.
void mapUnresolvedBlockAddress(BlockAddressOp op, llvm::Value *cst)
Maps a blockaddress operation to its corresponding placeholder LLVM value.
void mapBlockTag(BlockAddressAttr attr, BlockTagOp blockTag)
Maps a blockaddress operation to its corresponding placeholder LLVM value.
llvm::Value * lookupValue(Value value) const
Finds an LLVM IR value corresponding to the given MLIR value.
void mapCall(Operation *mlir, llvm::CallInst *llvm)
Stores a mapping between an MLIR call operation and a corresponding LLVM call instruction.
FailureOr< llvm::AttrBuilder > convertParameterAttrs(mlir::Location loc, DictionaryAttr paramAttrs)
Translates parameter attributes of a call and adds them to the returned AttrBuilder.
void mapBranch(Operation *mlir, llvm::Instruction *llvm)
Stores the mapping between an MLIR operation with successors and a corresponding LLVM IR instruction.
SmallVector< llvm::Value * > lookupValues(ValueRange values)
Looks up remapped a list of remapped values.
llvm::BasicBlock * lookupBlock(Block *block) const
Finds an LLVM IR basic block that corresponds to the given MLIR block.
SymbolTableCollection & symbolTable()
llvm::Type * convertType(Type type)
Converts the type from MLIR LLVM dialect to LLVM.
llvm::GlobalValue * lookupAlias(Operation *op)
Finds an LLVM IR global value that corresponds to the given MLIR operation defining a global alias va...
void setTBAAMetadata(AliasAnalysisOpInterface op, llvm::Instruction *inst)
Sets LLVM TBAA metadata for memory operations that have TBAA attributes.
BlockTagOp lookupBlockTag(BlockAddressAttr attr) const
Finds an MLIR block that corresponds to the given MLIR call operation.
llvm::LLVMContext & getLLVMContext() const
Returns the LLVM context in which the IR is being constructed.
llvm::GlobalValue * lookupGlobal(Operation *op)
Finds an LLVM IR global value that corresponds to the given MLIR operation defining a global value.
llvm::Module * getLLVMModule()
Returns the LLVM module in which the IR is being constructed.
llvm::Function * lookupFunction(StringRef name) const
Finds an LLVM IR function by its name.
void setAliasScopeMetadata(AliasAnalysisOpInterface op, llvm::Instruction *inst)
void setAccessGroupsMetadata(AccessGroupOpInterface op, llvm::Instruction *inst)
MLIRContext & getContext()
Returns the MLIR context of the module being translated.
void mapValue(Value mlir, llvm::Value *llvm)
Stores the mapping between an MLIR value and its LLVM IR counterpart.
void setLoopMetadata(Operation *op, llvm::Instruction *inst)
Sets LLVM loop metadata for branch operations that have a loop annotation attribute.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
void appendDialectRegistry(const DialectRegistry ®istry)
Append the contents of the given dialect registry to the registry associated with this context.
This class represents a contiguous range of operand ranges, e.g.
This class implements the operand iterators for the Operation class.
Operation is the basic unit of execution within MLIR.
AttrClass getAttrOfType(StringAttr name)
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
unsigned getNumResults()
Return the number of results held by this operation.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
llvm::Constant * getLLVMConstant(llvm::Type *llvmType, Attribute attr, Location loc, const ModuleTranslation &moduleTranslation)
Create an LLVM IR constant of llvmType from the MLIR attribute attr.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
SmallVector< AffineExpr, 4 > concat(ArrayRef< AffineExpr > a, ArrayRef< AffineExpr > b)
Return the vector that is the concatenation of a and b.
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
void registerLLVMDialectTranslation(DialectRegistry ®istry)
Register the LLVM dialect and the translation from it to the LLVM IR in the given registry;.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...