20 #include "llvm/ADT/TypeSwitch.h"
21 #include "llvm/IR/DIBuilder.h"
22 #include "llvm/IR/IRBuilder.h"
23 #include "llvm/IR/InlineAsm.h"
24 #include "llvm/IR/Instructions.h"
25 #include "llvm/IR/MDBuilder.h"
26 #include "llvm/IR/MatrixBuilder.h"
27 #include "llvm/IR/MemoryModelRelaxationAnnotations.h"
28 #include "llvm/Support/LogicalResult.h"
34 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsToLLVM.inc"
37 using llvmFMF = llvm::FastMathFlags;
38 using FuncT = void (llvmFMF::*)(bool);
39 const std::pair<FastmathFlags, FuncT> handlers[] = {
41 {FastmathFlags::nnan, &llvmFMF::setNoNaNs},
42 {FastmathFlags::ninf, &llvmFMF::setNoInfs},
43 {FastmathFlags::nsz, &llvmFMF::setNoSignedZeros},
44 {FastmathFlags::arcp, &llvmFMF::setAllowReciprocal},
46 {FastmathFlags::afn, &llvmFMF::setApproxFunc},
47 {FastmathFlags::reassoc, &llvmFMF::setAllowReassoc},
50 llvm::FastMathFlags ret;
51 ::mlir::LLVM::FastmathFlags fmfMlir = op.getFastmathAttr().getValue();
52 for (
auto it : handlers)
53 if (bitEnumContainsAll(fmfMlir, it.first))
54 (ret.*(it.second))(
true);
61 llvm::append_range(position, indices);
66 static std::string
diagStr(
const llvm::Type *type) {
68 llvm::raw_string_ostream os(str);
76 static FailureOr<llvm::Function *>
79 LLVM::ModuleTranslation &moduleTranslation) {
81 for (
Type type : op->getOperandTypes())
82 allArgTys.push_back(moduleTranslation.convertType(type));
85 if (op.getNumResults() == 0)
86 resTy = llvm::Type::getVoidTy(module->getContext());
88 resTy = moduleTranslation.convertType(op.getResult(0).getType());
94 getIntrinsicInfoTableEntries(
id,
table);
98 if (llvm::Intrinsic::matchIntrinsicSignature(ft, tableRef,
100 llvm::Intrinsic::MatchIntrinsicTypesResult::MatchIntrinsicTypes_Match) {
102 <<
diagStr(ft) <<
" to overloaded intrinsic " << op.getIntrinAttr()
103 <<
" does not match any of the overloads";
107 return llvm::Intrinsic::getOrInsertDeclaration(module,
id,
108 overloadedArgTysRef);
111 static llvm::OperandBundleDef
113 LLVM::ModuleTranslation &moduleTranslation) {
114 std::vector<llvm::Value *> operands;
115 operands.reserve(bundleOperands.size());
116 for (
Value bundleArg : bundleOperands)
117 operands.push_back(moduleTranslation.lookupValue(bundleArg));
118 return llvm::OperandBundleDef(bundleTag.str(), std::move(operands));
123 LLVM::ModuleTranslation &moduleTranslation) {
125 bundles.reserve(bundleOperands.size());
127 for (
auto [operands, tagAttr] : llvm::zip_equal(bundleOperands, bundleTags)) {
128 StringRef tag = cast<StringAttr>(tagAttr).getValue();
136 std::optional<ArrayAttr> bundleTags,
137 LLVM::ModuleTranslation &moduleTranslation) {
146 LLVM::ModuleTranslation &moduleTranslation) {
147 llvm::Module *module = builder.GetInsertBlock()->getModule();
149 llvm::Intrinsic::lookupIntrinsicID(op.getIntrinAttr());
152 << op.getIntrinAttr();
154 llvm::Function *fn =
nullptr;
155 if (llvm::Intrinsic::isOverloaded(
id)) {
162 fn = llvm::Intrinsic::getOrInsertDeclaration(module,
id, {});
166 const llvm::Type *intrinType =
167 op.getNumResults() == 0
168 ? llvm::Type::getVoidTy(module->getContext())
169 : moduleTranslation.convertType(op.getResultTypes().front());
170 if (intrinType != fn->getReturnType()) {
172 <<
diagStr(intrinType) <<
" but " << op.getIntrinAttr()
173 <<
" actually returns " <<
diagStr(fn->getReturnType());
178 if (!fn->getFunctionType()->isVarArg() &&
179 op.getArgs().size() != fn->arg_size()) {
181 << op.getArgs().size() <<
" operands but " << op.getIntrinAttr()
182 <<
" expects " << fn->arg_size();
184 if (fn->getFunctionType()->isVarArg() &&
185 op.getArgs().size() < fn->arg_size()) {
187 << op.getArgs().size() <<
" operands but variadic "
188 << op.getIntrinAttr() <<
" expects at least " << fn->arg_size();
191 for (
unsigned i = 0, e = fn->arg_size(); i != e; ++i) {
192 const llvm::Type *expected = fn->getArg(i)->getType();
193 const llvm::Type *actual =
194 moduleTranslation.convertType(op.getOperandTypes()[i]);
195 if (actual != expected) {
197 << i <<
" has type " <<
diagStr(actual) <<
" but "
198 << op.getIntrinAttr() <<
" expects " <<
diagStr(expected);
202 FastmathFlagsInterface itf = op;
205 auto *inst = builder.CreateCall(
206 fn, moduleTranslation.lookupValues(op.getArgs()),
210 if (
failed(moduleTranslation.convertArgAndResultAttrs(op, inst)))
213 if (op.getNumResults() == 1)
214 moduleTranslation.mapValue(op->getResults().front()) = inst;
219 llvm::IRBuilderBase &builder,
220 LLVM::ModuleTranslation &moduleTranslation) {
221 llvm::Module *llvmModule = moduleTranslation.getLLVMModule();
222 llvm::LLVMContext &context = llvmModule->getContext();
223 llvm::NamedMDNode *linkerMDNode =
224 llvmModule->getOrInsertNamedMetadata(
"llvm.linker.options");
226 MDNodes.reserve(
options.size());
227 for (
auto s :
options.getAsRange<StringAttr>()) {
229 MDNodes.push_back(MDNode);
233 linkerMDNode->addOperand(listMDNode);
236 static llvm::Metadata *
238 llvm::IRBuilderBase &builder,
239 LLVM::ModuleTranslation &moduleTranslation) {
240 llvm::LLVMContext &context = builder.getContext();
241 llvm::MDBuilder mdb(context);
244 if (key == LLVMDialect::getModuleFlagKeyCGProfileName()) {
245 for (
auto entry : arrayAttr.getAsRange<ModuleFlagCGProfileEntryAttr>()) {
246 llvm::Metadata *fromMetadata =
249 entry.getFrom().getValue()))
251 llvm::Metadata *toMetadata =
254 moduleTranslation.lookupFunction(entry.getTo().getValue()))
257 llvm::Metadata *vals[] = {
258 fromMetadata, toMetadata,
260 llvm::Type::getInt64Ty(context), entry.getCount()))};
263 return llvm::MDTuple::getDistinct(context, nodes);
269 StringRef key, ModuleFlagProfileSummaryAttr summaryAttr,
270 llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation) {
271 llvm::LLVMContext &context = builder.getContext();
272 llvm::MDBuilder mdb(context);
274 auto getIntTuple = [&](StringRef key, uint64_t val) -> llvm::MDTuple * {
277 llvm::Type::getInt64Ty(context), val))};
282 mdb.createString(
"ProfileFormat"),
284 stringifyProfileSummaryFormatKind(summaryAttr.getFormat()))};
288 getIntTuple(
"TotalCount", summaryAttr.getTotalCount()),
289 getIntTuple(
"MaxCount", summaryAttr.getMaxCount()),
290 getIntTuple(
"MaxInternalCount", summaryAttr.getMaxInternalCount()),
291 getIntTuple(
"MaxFunctionCount", summaryAttr.getMaxFunctionCount()),
292 getIntTuple(
"NumCounts", summaryAttr.getNumCounts()),
293 getIntTuple(
"NumFunctions", summaryAttr.getNumFunctions()),
296 if (summaryAttr.getIsPartialProfile())
298 getIntTuple(
"IsPartialProfile", *summaryAttr.getIsPartialProfile()));
300 if (summaryAttr.getPartialProfileRatio()) {
302 mdb.createString(
"PartialProfileRatio"),
304 llvm::Type::getDoubleTy(context),
305 summaryAttr.getPartialProfileRatio().getValue()))};
310 llvm::Type *llvmInt64Type = llvm::Type::getInt64Ty(context);
311 for (ModuleFlagProfileSummaryDetailedAttr detailedEntry :
312 summaryAttr.getDetailedSummary()) {
319 llvmInt64Type, detailedEntry.getNumCounts()))};
323 mdb.createString(
"DetailedSummary"),
331 LLVM::ModuleTranslation &moduleTranslation) {
332 llvm::Module *llvmModule = moduleTranslation.getLLVMModule();
333 for (
auto flagAttr : flags.getAsRange<ModuleFlagAttr>()) {
334 llvm::Metadata *valueMetadata =
336 .Case<StringAttr>([&](
auto strAttr) {
340 .Case<IntegerAttr>([&](
auto intAttr) {
342 llvm::Type::getInt32Ty(builder.getContext()),
345 .Case<ArrayAttr>([&](
auto arrayAttr) {
350 .Case([&](ModuleFlagProfileSummaryAttr summaryAttr) {
352 flagAttr.getKey().getValue(), summaryAttr, builder,
355 .Default([](
auto) {
return nullptr; });
357 assert(valueMetadata &&
"expected valid metadata");
358 llvmModule->addModuleFlag(
359 convertModFlagBehaviorToLLVM(flagAttr.getBehavior()),
360 flagAttr.getKey().getValue(), valueMetadata);
364 static llvm::DILocalScope *
366 LLVM::ModuleTranslation &moduleTranslation) {
369 if (
auto *localScope = llvm::dyn_cast<llvm::DILocalScope>(
370 moduleTranslation.translateDebugInfo(scopeLoc.getMetadata())))
372 return builder.GetInsertBlock()->getParent()->getSubprogram();
377 LLVM::ModuleTranslation &moduleTranslation) {
379 llvm::IRBuilder<>::FastMathFlagGuard fmfGuard(builder);
380 if (
auto fmf = dyn_cast<FastmathFlagsInterface>(opInst))
383 #include "mlir/Dialect/LLVMIR/LLVMConversions.inc"
384 #include "mlir/Dialect/LLVMIR/LLVMIntrinsicConversions.inc"
390 if (
auto callOp = dyn_cast<LLVM::CallOp>(opInst)) {
391 auto operands = moduleTranslation.lookupValues(callOp.getCalleeOperands());
394 callOp.getOpBundleTags(), moduleTranslation);
396 llvm::CallInst *call;
397 if (
auto attr = callOp.getCalleeAttr()) {
398 if (llvm::Function *
function =
399 moduleTranslation.lookupFunction(attr.getValue())) {
400 call = builder.CreateCall(
function, operandsRef, opBundles);
404 moduleTranslation.symbolTable().lookupSymbolIn(moduleOp, attr);
405 llvm::GlobalValue *ifunc = moduleTranslation.lookupIFunc(ifuncOp);
406 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
407 moduleTranslation.convertType(callOp.getCalleeFunctionType()));
408 call = builder.CreateCall(calleeType, ifunc, operandsRef, opBundles);
411 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
412 moduleTranslation.convertType(callOp.getCalleeFunctionType()));
413 call = builder.CreateCall(calleeType, operandsRef.front(),
414 operandsRef.drop_front(), opBundles);
416 call->setCallingConv(convertCConvToLLVM(callOp.getCConv()));
417 call->setTailCallKind(convertTailCallKindToLLVM(callOp.getTailCallKind()));
418 if (callOp.getConvergentAttr())
419 call->addFnAttr(llvm::Attribute::Convergent);
420 if (callOp.getNoUnwindAttr())
421 call->addFnAttr(llvm::Attribute::NoUnwind);
422 if (callOp.getWillReturnAttr())
423 call->addFnAttr(llvm::Attribute::WillReturn);
424 if (callOp.getNoInlineAttr())
425 call->addFnAttr(llvm::Attribute::NoInline);
426 if (callOp.getAlwaysInlineAttr())
427 call->addFnAttr(llvm::Attribute::AlwaysInline);
428 if (callOp.getInlineHintAttr())
429 call->addFnAttr(llvm::Attribute::InlineHint);
431 if (
failed(moduleTranslation.convertArgAndResultAttrs(callOp, call)))
434 if (MemoryEffectsAttr memAttr = callOp.getMemoryEffectsAttr()) {
435 llvm::MemoryEffects memEffects =
436 llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
437 convertModRefInfoToLLVM(memAttr.getArgMem())) |
439 llvm::MemoryEffects::Location::InaccessibleMem,
440 convertModRefInfoToLLVM(memAttr.getInaccessibleMem())) |
441 llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
442 convertModRefInfoToLLVM(memAttr.getOther()));
443 call->setMemoryEffects(memEffects);
446 moduleTranslation.setAccessGroupsMetadata(callOp, call);
447 moduleTranslation.setAliasScopeMetadata(callOp, call);
448 moduleTranslation.setTBAAMetadata(callOp, call);
452 moduleTranslation.mapValue(opInst.
getResult(0), call);
454 else if (!call->getType()->isVoidTy())
456 moduleTranslation.mapCall(callOp, call);
460 if (
auto inlineAsmOp = dyn_cast<LLVM::InlineAsmOp>(opInst)) {
464 llvm::append_range(operandTypes, inlineAsmOp.getOperands().getTypes());
467 if (inlineAsmOp.getNumResults() == 0) {
470 assert(inlineAsmOp.getNumResults() == 1);
471 resultType = inlineAsmOp.getResultTypes()[0];
474 llvm::InlineAsm *inlineAsmInst =
475 inlineAsmOp.getAsmDialect()
477 static_cast<llvm::FunctionType *
>(
478 moduleTranslation.convertType(ft)),
479 inlineAsmOp.getAsmString(), inlineAsmOp.getConstraints(),
480 inlineAsmOp.getHasSideEffects(),
481 inlineAsmOp.getIsAlignStack(),
482 convertAsmDialectToLLVM(*inlineAsmOp.getAsmDialect()))
484 moduleTranslation.convertType(ft)),
485 inlineAsmOp.getAsmString(),
486 inlineAsmOp.getConstraints(),
487 inlineAsmOp.getHasSideEffects(),
488 inlineAsmOp.getIsAlignStack());
489 llvm::CallInst *inst = builder.CreateCall(
491 moduleTranslation.lookupValues(inlineAsmOp.getOperands()));
492 inst->setTailCallKind(convertTailCallKindToLLVM(
493 inlineAsmOp.getTailCallKindAttr().getTailCallKind()));
494 if (
auto maybeOperandAttrs = inlineAsmOp.getOperandAttrs()) {
495 llvm::AttributeList attrList;
500 DictionaryAttr dAttr = cast<DictionaryAttr>(attr);
504 cast<TypeAttr>(dAttr.get(InlineAsmOp::getElementTypeAttrName()));
505 llvm::AttrBuilder b(moduleTranslation.getLLVMContext());
506 llvm::Type *ty = moduleTranslation.convertType(tAttr.getValue());
507 b.addTypeAttr(llvm::Attribute::ElementType, ty);
511 attrList = attrList.addAttributesAtIndex(
512 moduleTranslation.getLLVMContext(), it.index() + shift, b);
514 inst->setAttributes(attrList);
518 moduleTranslation.mapValue(opInst.
getResult(0), inst);
522 if (
auto invOp = dyn_cast<LLVM::InvokeOp>(opInst)) {
523 auto operands = moduleTranslation.lookupValues(invOp.getCalleeOperands());
526 invOp.getOpBundleTags(), moduleTranslation);
528 llvm::InvokeInst *result;
530 result = builder.CreateInvoke(
531 moduleTranslation.lookupFunction(attr.getValue()),
532 moduleTranslation.lookupBlock(invOp.getSuccessor(0)),
533 moduleTranslation.lookupBlock(invOp.getSuccessor(1)), operandsRef,
536 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
537 moduleTranslation.convertType(invOp.getCalleeFunctionType()));
538 result = builder.CreateInvoke(
539 calleeType, operandsRef.front(),
540 moduleTranslation.lookupBlock(invOp.getSuccessor(0)),
541 moduleTranslation.lookupBlock(invOp.getSuccessor(1)),
542 operandsRef.drop_front(), opBundles);
544 result->setCallingConv(convertCConvToLLVM(invOp.getCConv()));
545 if (
failed(moduleTranslation.convertArgAndResultAttrs(invOp, result)))
547 moduleTranslation.mapBranch(invOp, result);
549 if (invOp->getNumResults() != 0) {
550 moduleTranslation.mapValue(opInst.
getResult(0), result);
553 return success(result->getType()->isVoidTy());
556 if (
auto lpOp = dyn_cast<LLVM::LandingpadOp>(opInst)) {
557 llvm::Type *ty = moduleTranslation.convertType(lpOp.getType());
558 llvm::LandingPadInst *lpi =
559 builder.CreateLandingPad(ty, lpOp.getNumOperands());
560 lpi->setCleanup(lpOp.getCleanup());
563 for (llvm::Value *operand :
564 moduleTranslation.lookupValues(lpOp.getOperands())) {
566 if (
auto *constOperand = dyn_cast<llvm::Constant>(operand))
567 lpi->addClause(constOperand);
569 moduleTranslation.mapValue(lpOp.getResult(), lpi);
575 if (
auto brOp = dyn_cast<LLVM::BrOp>(opInst)) {
576 llvm::BranchInst *branch =
577 builder.CreateBr(moduleTranslation.lookupBlock(brOp.getSuccessor()));
578 moduleTranslation.mapBranch(&opInst, branch);
579 moduleTranslation.setLoopMetadata(&opInst, branch);
582 if (
auto condbrOp = dyn_cast<LLVM::CondBrOp>(opInst)) {
583 llvm::BranchInst *branch = builder.CreateCondBr(
584 moduleTranslation.lookupValue(condbrOp.getOperand(0)),
585 moduleTranslation.lookupBlock(condbrOp.getSuccessor(0)),
586 moduleTranslation.lookupBlock(condbrOp.getSuccessor(1)));
587 moduleTranslation.mapBranch(&opInst, branch);
588 moduleTranslation.setLoopMetadata(&opInst, branch);
591 if (
auto switchOp = dyn_cast<LLVM::SwitchOp>(opInst)) {
592 llvm::SwitchInst *switchInst = builder.CreateSwitch(
593 moduleTranslation.lookupValue(switchOp.getValue()),
594 moduleTranslation.lookupBlock(switchOp.getDefaultDestination()),
595 switchOp.getCaseDestinations().size());
598 if (!switchOp.getCaseValues())
601 auto *ty = llvm::cast<llvm::IntegerType>(
602 moduleTranslation.convertType(switchOp.getValue().getType()));
604 llvm::zip(llvm::cast<DenseIntElementsAttr>(*switchOp.getCaseValues()),
605 switchOp.getCaseDestinations()))
608 moduleTranslation.lookupBlock(std::get<1>(i)));
610 moduleTranslation.mapBranch(&opInst, switchInst);
613 if (
auto indBrOp = dyn_cast<LLVM::IndirectBrOp>(opInst)) {
614 llvm::IndirectBrInst *indBr = builder.CreateIndirectBr(
615 moduleTranslation.lookupValue(indBrOp.getAddr()),
616 indBrOp->getNumSuccessors());
617 for (
auto *succ : indBrOp.getSuccessors())
618 indBr->addDestination(moduleTranslation.lookupBlock(succ));
619 moduleTranslation.mapBranch(&opInst, indBr);
626 if (
auto addressOfOp = dyn_cast<LLVM::AddressOfOp>(opInst)) {
627 LLVM::GlobalOp global =
628 addressOfOp.getGlobal(moduleTranslation.symbolTable());
629 LLVM::LLVMFuncOp
function =
630 addressOfOp.getFunction(moduleTranslation.symbolTable());
631 LLVM::AliasOp alias = addressOfOp.getAlias(moduleTranslation.symbolTable());
632 LLVM::IFuncOp ifunc = addressOfOp.getIFunc(moduleTranslation.symbolTable());
635 assert((global ||
function || alias || ifunc) &&
636 "referencing an undefined global, function, alias, or ifunc");
638 llvm::Value *llvmValue =
nullptr;
640 llvmValue = moduleTranslation.lookupGlobal(global);
642 llvmValue = moduleTranslation.lookupAlias(alias);
644 llvmValue = moduleTranslation.lookupFunction(
function.getName());
646 llvmValue = moduleTranslation.lookupIFunc(ifunc);
648 moduleTranslation.mapValue(addressOfOp.getResult(), llvmValue);
654 if (
auto dsoLocalEquivalentOp =
655 dyn_cast<LLVM::DSOLocalEquivalentOp>(opInst)) {
656 LLVM::LLVMFuncOp
function =
657 dsoLocalEquivalentOp.getFunction(moduleTranslation.symbolTable());
658 LLVM::AliasOp alias =
659 dsoLocalEquivalentOp.getAlias(moduleTranslation.symbolTable());
662 assert((
function || alias) &&
663 "referencing an undefined function, or alias");
665 llvm::Value *llvmValue =
nullptr;
667 llvmValue = moduleTranslation.lookupAlias(alias);
669 llvmValue = moduleTranslation.lookupFunction(
function.getName());
671 moduleTranslation.mapValue(
672 dsoLocalEquivalentOp.getResult(),
679 if (
auto blockAddressOp = dyn_cast<LLVM::BlockAddressOp>(opInst)) {
680 BlockAddressAttr blockAddressAttr = blockAddressOp.getBlockAddr();
681 llvm::BasicBlock *llvmBlock =
682 moduleTranslation.lookupBlockAddress(blockAddressAttr);
684 llvm::Value *llvmValue =
nullptr;
685 StringRef fnName = blockAddressAttr.getFunction().getValue();
687 llvm::Function *llvmFn = moduleTranslation.lookupFunction(fnName);
696 llvmValue =
new llvm::GlobalVariable(
697 *moduleTranslation.getLLVMModule(),
698 llvm::PointerType::getUnqual(moduleTranslation.getLLVMContext()),
699 true, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
701 Twine(
"__mlir_block_address_")
703 .
concat(Twine((uint64_t)blockAddressOp.getOperation())));
704 moduleTranslation.mapUnresolvedBlockAddress(blockAddressOp, llvmValue);
707 moduleTranslation.mapValue(blockAddressOp.getResult(), llvmValue);
713 if (
auto blockTagOp = dyn_cast<LLVM::BlockTagOp>(opInst)) {
714 auto funcOp = blockTagOp->getParentOfType<LLVMFuncOp>();
716 &moduleTranslation.getContext(),
719 blockTagOp.getTag());
720 moduleTranslation.mapBlockAddress(blockAddressAttr,
721 builder.GetInsertBlock());
731 LLVM::ModuleTranslation &moduleTranslation) {
732 StringRef name = attribute.
getName();
733 if (name == LLVMDialect::getMmraAttrName()) {
735 if (
auto oneTag = dyn_cast<LLVM::MMRATagAttr>(attribute.
getValue())) {
736 tags.emplace_back(oneTag.getPrefix(), oneTag.getSuffix());
737 }
else if (
auto manyTags = dyn_cast<ArrayAttr>(attribute.
getValue())) {
739 auto tag = dyn_cast<MMRATagAttr>(attr);
742 "MMRA annotations array contains value that isn't an MMRA tag");
743 tags.emplace_back(tag.getPrefix(), tag.getSuffix());
747 "llvm.mmra is something other than an MMRA tag or an array of them");
749 llvm::MDTuple *mmraMd =
750 llvm::MMRAMetadata::getMD(moduleTranslation.getLLVMContext(), tags);
755 for (llvm::Instruction *inst : instructions)
756 inst->setMetadata(llvm::LLVMContext::MD_mmra, mmraMd);
765 class LLVMDialectLLVMIRTranslationInterface
773 convertOperation(
Operation *op, llvm::IRBuilderBase &builder,
774 LLVM::ModuleTranslation &moduleTranslation)
const final {
782 LLVM::ModuleTranslation &moduleTranslation)
const final {
789 registry.
insert<LLVM::LLVMDialect>();
791 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 llvm::Metadata * convertModuleFlagProfileSummaryAttr(StringRef key, ModuleFlagProfileSummaryAttr summaryAttr, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation)
static llvm::DILocalScope * getLocalScopeFromLoc(llvm::IRBuilderBase &builder, Location loc, 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 LogicalResult amendOperationImpl(Operation &op, ArrayRef< llvm::Instruction * > instructions, NamedAttribute attribute, LLVM::ModuleTranslation &moduleTranslation)
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.
This class represents a fused location whose metadata is known to be an instance of the given type.
Base class for dialect interfaces providing translation to LLVM IR.
LLVMTranslationDialectInterface(Dialect *dialect)
T findInstanceOf()
Return an instance of the given location type if one is nested under the current location.
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.
NamedAttribute represents a combination of a name and an Attribute value.
StringAttr getName() const
Return the name of the attribute.
Attribute getValue() const
Return the value of the attribute.
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.
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
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.
Operation * parentLLVMModule(Operation *op)
Lookup parent Module satisfying LLVM conditions on the Module Operation.
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...