318 StringRef key, ModuleFlagProfileSummaryAttr summaryAttr,
320 llvm::LLVMContext &context = builder.getContext();
321 llvm::MDBuilder mdb(context);
323 auto getIntTuple = [&](StringRef key, uint64_t val) -> llvm::MDTuple * {
325 mdb.createString(key), mdb.createConstant(llvm::ConstantInt::get(
326 llvm::Type::getInt64Ty(context), val))};
327 return llvm::MDTuple::get(context, tupleNodes);
331 mdb.createString(
"ProfileFormat"),
333 stringifyProfileSummaryFormatKind(summaryAttr.getFormat()))};
336 llvm::MDTuple::get(context, fmtNode),
337 getIntTuple(
"TotalCount", summaryAttr.getTotalCount()),
338 getIntTuple(
"MaxCount", summaryAttr.getMaxCount()),
339 getIntTuple(
"MaxInternalCount", summaryAttr.getMaxInternalCount()),
340 getIntTuple(
"MaxFunctionCount", summaryAttr.getMaxFunctionCount()),
341 getIntTuple(
"NumCounts", summaryAttr.getNumCounts()),
342 getIntTuple(
"NumFunctions", summaryAttr.getNumFunctions()),
345 if (summaryAttr.getIsPartialProfile())
347 getIntTuple(
"IsPartialProfile", *summaryAttr.getIsPartialProfile()));
349 if (summaryAttr.getPartialProfileRatio()) {
351 mdb.createString(
"PartialProfileRatio"),
352 mdb.createConstant(llvm::ConstantFP::get(
353 llvm::Type::getDoubleTy(context),
354 summaryAttr.getPartialProfileRatio().getValue()))};
355 vals.push_back(llvm::MDTuple::get(context, tupleNodes));
359 llvm::Type *llvmInt64Type = llvm::Type::getInt64Ty(context);
360 for (ModuleFlagProfileSummaryDetailedAttr detailedEntry :
361 summaryAttr.getDetailedSummary()) {
364 llvm::ConstantInt::get(llvmInt64Type, detailedEntry.getCutOff())),
366 llvm::ConstantInt::get(llvmInt64Type, detailedEntry.getMinCount())),
367 mdb.createConstant(llvm::ConstantInt::get(
368 llvmInt64Type, detailedEntry.getNumCounts()))};
369 detailedEntries.push_back(llvm::MDTuple::get(context, tupleNodes));
372 mdb.createString(
"DetailedSummary"),
373 llvm::MDTuple::get(context, detailedEntries)};
374 vals.push_back(llvm::MDTuple::get(context, detailedSummary));
376 return llvm::MDNode::get(context, vals);
448 llvm::IRBuilder<>::FastMathFlagGuard fmfGuard(builder);
449 if (
auto fmf = dyn_cast<FastmathFlagsInterface>(opInst))
452#include "mlir/Dialect/LLVMIR/LLVMConversions.inc"
453#include "mlir/Dialect/LLVMIR/LLVMIntrinsicConversions.inc"
459 if (
auto callOp = dyn_cast<LLVM::CallOp>(opInst)) {
460 auto operands = moduleTranslation.
lookupValues(callOp.getCalleeOperands());
463 callOp.getOpBundleTags(), moduleTranslation);
465 llvm::CallInst *call;
466 if (
auto attr = callOp.getCalleeAttr()) {
467 if (llvm::Function *function =
469 call = builder.CreateCall(function, operandsRef, opBundles);
472 attr, callOp.getCalleeFunctionType(), opInst, moduleTranslation);
473 call = builder.CreateCall(calleeType, calleeGV, operandsRef, opBundles);
476 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
477 moduleTranslation.
convertType(callOp.getCalleeFunctionType()));
478 call = builder.CreateCall(calleeType, operandsRef.front(),
479 operandsRef.drop_front(), opBundles);
481 call->setCallingConv(convertCConvToLLVM(callOp.getCConv()));
482 call->setTailCallKind(convertTailCallKindToLLVM(callOp.getTailCallKind()));
483 if (callOp.getConvergentAttr())
484 call->addFnAttr(llvm::Attribute::Convergent);
485 if (callOp.getNoUnwindAttr())
486 call->addFnAttr(llvm::Attribute::NoUnwind);
487 if (callOp.getWillReturnAttr())
488 call->addFnAttr(llvm::Attribute::WillReturn);
489 if (callOp.getNoreturnAttr())
490 call->addFnAttr(llvm::Attribute::NoReturn);
491 if (callOp.getOptsizeAttr())
492 call->addFnAttr(llvm::Attribute::OptimizeForSize);
493 if (callOp.getMinsizeAttr())
494 call->addFnAttr(llvm::Attribute::MinSize);
495 if (callOp.getSaveRegParamsAttr())
496 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
498 if (callOp.getBuiltinAttr())
499 call->addFnAttr(llvm::Attribute::Builtin);
500 if (callOp.getNobuiltinAttr())
501 call->addFnAttr(llvm::Attribute::NoBuiltin);
502 if (callOp.getReturnsTwiceAttr())
503 call->addFnAttr(llvm::Attribute::ReturnsTwice);
504 if (callOp.getColdAttr())
505 call->addFnAttr(llvm::Attribute::Cold);
506 if (callOp.getHotAttr())
507 call->addFnAttr(llvm::Attribute::Hot);
508 if (callOp.getNoduplicateAttr())
509 call->addFnAttr(llvm::Attribute::NoDuplicate);
510 if (callOp.getNoInlineAttr())
511 call->addFnAttr(llvm::Attribute::NoInline);
512 if (callOp.getAlwaysInlineAttr())
513 call->addFnAttr(llvm::Attribute::AlwaysInline);
514 if (callOp.getInlineHintAttr())
515 call->addFnAttr(llvm::Attribute::InlineHint);
516 if (callOp.getNoCallerSavedRegistersAttr())
517 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
518 "no_caller_saved_registers"));
519 if (callOp.getNocallbackAttr())
520 call->addFnAttr(llvm::Attribute::NoCallback);
521 if (StringAttr modFormat = callOp.getModularFormatAttr())
522 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
524 modFormat.getValue()));
525 if (StringAttr zcsr = callOp.getZeroCallUsedRegsAttr())
526 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
527 "zero-call-used-regs",
529 if (StringAttr trapFunc = callOp.getTrapFuncNameAttr())
530 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
532 trapFunc.getValue()));
534 if (
ArrayAttr noBuiltins = callOp.getNobuiltinsAttr()) {
535 if (noBuiltins.empty())
536 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
544 callOp.getDefaultFuncAttrsAttr(), call,
547 if (llvm::Attribute attr =
550 call->addFnAttr(attr);
555 if (MemoryEffectsAttr memAttr = callOp.getMemoryEffectsAttr()) {
556 llvm::MemoryEffects memEffects =
557 llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
558 convertModRefInfoToLLVM(memAttr.getArgMem())) |
560 llvm::MemoryEffects::Location::InaccessibleMem,
561 convertModRefInfoToLLVM(memAttr.getInaccessibleMem())) |
562 llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
563 convertModRefInfoToLLVM(memAttr.getOther())) |
564 llvm::MemoryEffects(llvm::MemoryEffects::Location::ErrnoMem,
565 convertModRefInfoToLLVM(memAttr.getErrnoMem())) |
567 llvm::MemoryEffects::Location::TargetMem0,
568 convertModRefInfoToLLVM(memAttr.getTargetMem0())) |
569 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem1,
570 convertModRefInfoToLLVM(memAttr.getTargetMem1()));
571 call->setMemoryEffects(memEffects);
582 else if (!call->getType()->isVoidTy())
584 moduleTranslation.
mapCall(callOp, call);
588 if (
auto inlineAsmOp = dyn_cast<LLVM::InlineAsmOp>(opInst)) {
592 llvm::append_range(operandTypes, inlineAsmOp.getOperands().getTypes());
595 if (inlineAsmOp.getNumResults() == 0) {
596 resultType = LLVM::LLVMVoidType::get(&moduleTranslation.
getContext());
598 assert(inlineAsmOp.getNumResults() == 1);
599 resultType = inlineAsmOp.getResultTypes()[0];
601 auto ft = LLVM::LLVMFunctionType::get(resultType, operandTypes);
602 llvm::InlineAsm *inlineAsmInst =
603 inlineAsmOp.getAsmDialect()
604 ? llvm::InlineAsm::get(
605 static_cast<llvm::FunctionType *
>(
607 inlineAsmOp.getAsmString(), inlineAsmOp.getConstraints(),
608 inlineAsmOp.getHasSideEffects(),
609 inlineAsmOp.getIsAlignStack(),
610 convertAsmDialectToLLVM(*inlineAsmOp.getAsmDialect()))
611 : llvm::InlineAsm::get(
static_cast<llvm::FunctionType *
>(
613 inlineAsmOp.getAsmString(),
614 inlineAsmOp.getConstraints(),
615 inlineAsmOp.getHasSideEffects(),
616 inlineAsmOp.getIsAlignStack());
617 llvm::CallInst *inst = builder.CreateCall(
619 moduleTranslation.
lookupValues(inlineAsmOp.getOperands()));
620 inst->setTailCallKind(convertTailCallKindToLLVM(
621 inlineAsmOp.getTailCallKindAttr().getTailCallKind()));
622 if (
auto maybeOperandAttrs = inlineAsmOp.getOperandAttrs()) {
623 llvm::AttributeList attrList;
624 for (
const auto &it : llvm::enumerate(*maybeOperandAttrs)) {
628 DictionaryAttr dAttr = cast<DictionaryAttr>(attr);
632 cast<TypeAttr>(dAttr.get(InlineAsmOp::getElementTypeAttrName()));
634 llvm::Type *ty = moduleTranslation.
convertType(tAttr.getValue());
635 b.addTypeAttr(llvm::Attribute::ElementType, ty);
639 attrList = attrList.addAttributesAtIndex(
642 inst->setAttributes(attrList);
650 if (
auto invOp = dyn_cast<LLVM::InvokeOp>(opInst)) {
651 auto operands = moduleTranslation.
lookupValues(invOp.getCalleeOperands());
654 invOp.getOpBundleTags(), moduleTranslation);
658 if (llvm::Function *function =
660 result = builder.CreateInvoke(
661 function, moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
662 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)), operandsRef,
666 attr, invOp.getCalleeFunctionType(), opInst, moduleTranslation);
667 result = builder.CreateInvoke(
668 calleeType, calleeGV,
669 moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
670 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)), operandsRef,
674 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
675 moduleTranslation.
convertType(invOp.getCalleeFunctionType()));
676 result = builder.CreateInvoke(
677 calleeType, operandsRef.front(),
678 moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
679 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)),
680 operandsRef.drop_front(), opBundles);
682 result->setCallingConv(convertCConvToLLVM(invOp.getCConv()));
687 if (invOp->getNumResults() != 0) {
694 if (
auto lpOp = dyn_cast<LLVM::LandingpadOp>(opInst)) {
695 llvm::Type *ty = moduleTranslation.
convertType(lpOp.getType());
696 llvm::LandingPadInst *lpi =
697 builder.CreateLandingPad(ty, lpOp.getNumOperands());
698 lpi->setCleanup(lpOp.getCleanup());
701 for (llvm::Value *operand :
704 if (
auto *constOperand = dyn_cast<llvm::Constant>(operand))
705 lpi->addClause(constOperand);
707 moduleTranslation.
mapValue(lpOp.getResult(), lpi);
713 if (
auto brOp = dyn_cast<LLVM::BrOp>(opInst)) {
714 llvm::UncondBrInst *branch =
715 builder.CreateBr(moduleTranslation.
lookupBlock(brOp.getSuccessor()));
716 moduleTranslation.
mapBranch(&opInst, branch);
720 if (
auto condbrOp = dyn_cast<LLVM::CondBrOp>(opInst)) {
721 llvm::CondBrInst *branch = builder.CreateCondBr(
722 moduleTranslation.
lookupValue(condbrOp.getOperand(0)),
723 moduleTranslation.
lookupBlock(condbrOp.getSuccessor(0)),
724 moduleTranslation.
lookupBlock(condbrOp.getSuccessor(1)));
725 moduleTranslation.
mapBranch(&opInst, branch);
729 if (
auto switchOp = dyn_cast<LLVM::SwitchOp>(opInst)) {
730 llvm::SwitchInst *switchInst = builder.CreateSwitch(
731 moduleTranslation.
lookupValue(switchOp.getValue()),
732 moduleTranslation.
lookupBlock(switchOp.getDefaultDestination()),
733 switchOp.getCaseDestinations().size());
736 if (!switchOp.getCaseValues())
739 auto *ty = llvm::cast<llvm::IntegerType>(
740 moduleTranslation.
convertType(switchOp.getValue().getType()));
742 llvm::zip(llvm::cast<DenseIntElementsAttr>(*switchOp.getCaseValues()),
743 switchOp.getCaseDestinations()))
745 llvm::ConstantInt::get(ty, std::get<0>(i).getLimitedValue()),
748 moduleTranslation.
mapBranch(&opInst, switchInst);
751 if (
auto indBrOp = dyn_cast<LLVM::IndirectBrOp>(opInst)) {
752 llvm::IndirectBrInst *indBr = builder.CreateIndirectBr(
754 indBrOp->getNumSuccessors());
755 for (
auto *succ : indBrOp.getSuccessors())
756 indBr->addDestination(moduleTranslation.
lookupBlock(succ));
757 moduleTranslation.
mapBranch(&opInst, indBr);
764 if (
auto addressOfOp = dyn_cast<LLVM::AddressOfOp>(opInst)) {
765 LLVM::GlobalOp global =
766 addressOfOp.getGlobal(moduleTranslation.
symbolTable());
767 LLVM::LLVMFuncOp function =
768 addressOfOp.getFunction(moduleTranslation.
symbolTable());
769 LLVM::AliasOp alias = addressOfOp.getAlias(moduleTranslation.
symbolTable());
770 LLVM::IFuncOp ifunc = addressOfOp.getIFunc(moduleTranslation.
symbolTable());
773 assert((global || function || alias || ifunc) &&
774 "referencing an undefined global, function, alias, or ifunc");
776 llvm::Value *llvmValue =
nullptr;
786 moduleTranslation.
mapValue(addressOfOp.getResult(), llvmValue);
792 if (
auto dsoLocalEquivalentOp =
793 dyn_cast<LLVM::DSOLocalEquivalentOp>(opInst)) {
794 LLVM::LLVMFuncOp function =
795 dsoLocalEquivalentOp.getFunction(moduleTranslation.
symbolTable());
796 LLVM::AliasOp alias =
797 dsoLocalEquivalentOp.getAlias(moduleTranslation.
symbolTable());
800 assert((function || alias) &&
801 "referencing an undefined function, or alias");
803 llvm::Value *llvmValue =
nullptr;
810 dsoLocalEquivalentOp.getResult(),
811 llvm::DSOLocalEquivalent::get(cast<llvm::GlobalValue>(llvmValue)));
817 if (
auto blockAddressOp = dyn_cast<LLVM::BlockAddressOp>(opInst)) {
818 BlockAddressAttr blockAddressAttr = blockAddressOp.getBlockAddr();
819 llvm::BasicBlock *llvmBlock =
822 llvm::Value *llvmValue =
nullptr;
823 StringRef fnName = blockAddressAttr.getFunction().getValue();
825 llvm::Function *llvmFn = moduleTranslation.
lookupFunction(fnName);
826 llvmValue = llvm::BlockAddress::get(llvmFn, llvmBlock);
834 llvmValue =
new llvm::GlobalVariable(
837 true, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
839 Twine(
"__mlir_block_address_")
840 .concat(Twine(fnName))
841 .concat(Twine((uint64_t)blockAddressOp.getOperation())));
845 moduleTranslation.
mapValue(blockAddressOp.getResult(), llvmValue);
851 if (
auto blockTagOp = dyn_cast<LLVM::BlockTagOp>(opInst)) {
852 auto funcOp = blockTagOp->getParentOfType<LLVMFuncOp>();
853 BlockAddressAttr blockAddressAttr = BlockAddressAttr::get(
857 blockTagOp.getTag());
859 builder.GetInsertBlock());