356 StringRef key, ModuleFlagProfileSummaryAttr summaryAttr,
358 llvm::LLVMContext &context = builder.getContext();
359 llvm::MDBuilder mdb(context);
361 auto getIntTuple = [&](StringRef key, uint64_t val) -> llvm::MDTuple * {
363 mdb.createString(key), mdb.createConstant(llvm::ConstantInt::get(
364 llvm::Type::getInt64Ty(context), val))};
365 return llvm::MDTuple::get(context, tupleNodes);
369 mdb.createString(
"ProfileFormat"),
371 stringifyProfileSummaryFormatKind(summaryAttr.getFormat()))};
374 llvm::MDTuple::get(context, fmtNode),
375 getIntTuple(
"TotalCount", summaryAttr.getTotalCount()),
376 getIntTuple(
"MaxCount", summaryAttr.getMaxCount()),
377 getIntTuple(
"MaxInternalCount", summaryAttr.getMaxInternalCount()),
378 getIntTuple(
"MaxFunctionCount", summaryAttr.getMaxFunctionCount()),
379 getIntTuple(
"NumCounts", summaryAttr.getNumCounts()),
380 getIntTuple(
"NumFunctions", summaryAttr.getNumFunctions()),
383 if (summaryAttr.getIsPartialProfile())
385 getIntTuple(
"IsPartialProfile", *summaryAttr.getIsPartialProfile()));
387 if (summaryAttr.getPartialProfileRatio()) {
389 mdb.createString(
"PartialProfileRatio"),
390 mdb.createConstant(llvm::ConstantFP::get(
391 llvm::Type::getDoubleTy(context),
392 summaryAttr.getPartialProfileRatio().getValue()))};
393 vals.push_back(llvm::MDTuple::get(context, tupleNodes));
397 llvm::Type *llvmInt64Type = llvm::Type::getInt64Ty(context);
398 for (ModuleFlagProfileSummaryDetailedAttr detailedEntry :
399 summaryAttr.getDetailedSummary()) {
402 llvm::ConstantInt::get(llvmInt64Type, detailedEntry.getCutOff())),
404 llvm::ConstantInt::get(llvmInt64Type, detailedEntry.getMinCount())),
405 mdb.createConstant(llvm::ConstantInt::get(
406 llvmInt64Type, detailedEntry.getNumCounts()))};
407 detailedEntries.push_back(llvm::MDTuple::get(context, tupleNodes));
410 mdb.createString(
"DetailedSummary"),
411 llvm::MDTuple::get(context, detailedEntries)};
412 vals.push_back(llvm::MDTuple::get(context, detailedSummary));
414 return llvm::MDNode::get(context, vals);
492 llvm::IRBuilder<>::FastMathFlagGuard fmfGuard(builder);
493 if (
auto fmf = dyn_cast<FastmathFlagsInterface>(opInst))
496#include "mlir/Dialect/LLVMIR/LLVMConversions.inc"
497#include "mlir/Dialect/LLVMIR/LLVMIntrinsicConversions.inc"
503 if (
auto callOp = dyn_cast<LLVM::CallOp>(opInst)) {
504 auto operands = moduleTranslation.
lookupValues(callOp.getCalleeOperands());
507 callOp.getOpBundleTags(), moduleTranslation);
509 llvm::CallInst *call;
510 if (
auto attr = callOp.getCalleeAttr()) {
511 if (llvm::Function *function =
513 call = builder.CreateCall(function, operandsRef, opBundles);
516 attr, callOp.getCalleeFunctionType(), opInst, moduleTranslation);
517 call = builder.CreateCall(calleeType, calleeGV, operandsRef, opBundles);
520 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
521 moduleTranslation.
convertType(callOp.getCalleeFunctionType()));
522 call = builder.CreateCall(calleeType, operandsRef.front(),
523 operandsRef.drop_front(), opBundles);
525 call->setCallingConv(convertCConvToLLVM(callOp.getCConv()));
526 call->setTailCallKind(convertTailCallKindToLLVM(callOp.getTailCallKind()));
527 if (callOp.getConvergentAttr())
528 call->addFnAttr(llvm::Attribute::Convergent);
529 if (callOp.getNoUnwindAttr())
530 call->addFnAttr(llvm::Attribute::NoUnwind);
531 if (callOp.getWillReturnAttr())
532 call->addFnAttr(llvm::Attribute::WillReturn);
533 if (callOp.getNoreturnAttr())
534 call->addFnAttr(llvm::Attribute::NoReturn);
535 if (callOp.getOptsizeAttr())
536 call->addFnAttr(llvm::Attribute::OptimizeForSize);
537 if (callOp.getMinsizeAttr())
538 call->addFnAttr(llvm::Attribute::MinSize);
539 if (callOp.getSaveRegParamsAttr())
540 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
542 if (callOp.getBuiltinAttr())
543 call->addFnAttr(llvm::Attribute::Builtin);
544 if (callOp.getNobuiltinAttr())
545 call->addFnAttr(llvm::Attribute::NoBuiltin);
546 if (callOp.getReturnsTwiceAttr())
547 call->addFnAttr(llvm::Attribute::ReturnsTwice);
548 if (callOp.getColdAttr())
549 call->addFnAttr(llvm::Attribute::Cold);
550 if (callOp.getHotAttr())
551 call->addFnAttr(llvm::Attribute::Hot);
552 if (callOp.getNoduplicateAttr())
553 call->addFnAttr(llvm::Attribute::NoDuplicate);
554 if (callOp.getNoInlineAttr())
555 call->addFnAttr(llvm::Attribute::NoInline);
556 if (callOp.getAlwaysInlineAttr())
557 call->addFnAttr(llvm::Attribute::AlwaysInline);
558 if (callOp.getInlineHintAttr())
559 call->addFnAttr(llvm::Attribute::InlineHint);
560 if (callOp.getNoCallerSavedRegistersAttr())
561 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
562 "no_caller_saved_registers"));
563 if (callOp.getNocallbackAttr())
564 call->addFnAttr(llvm::Attribute::NoCallback);
565 if (StringAttr modFormat = callOp.getModularFormatAttr())
566 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
568 modFormat.getValue()));
569 if (StringAttr zcsr = callOp.getZeroCallUsedRegsAttr())
570 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
571 "zero-call-used-regs",
573 if (callOp.getUniformWorkGroupSizeAttr())
574 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
575 "uniform-work-group-size"));
576 if (StringAttr trapFunc = callOp.getTrapFuncNameAttr())
577 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
579 trapFunc.getValue()));
581 if (
ArrayAttr noBuiltins = callOp.getNobuiltinsAttr()) {
582 if (noBuiltins.empty())
583 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
591 callOp.getDefaultFuncAttrsAttr(), call,
594 if (llvm::Attribute attr =
597 call->addFnAttr(attr);
602 if (MemoryEffectsAttr memAttr = callOp.getMemoryEffectsAttr()) {
603 llvm::MemoryEffects memEffects =
604 llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
605 convertModRefInfoToLLVM(memAttr.getArgMem())) |
607 llvm::MemoryEffects::Location::InaccessibleMem,
608 convertModRefInfoToLLVM(memAttr.getInaccessibleMem())) |
609 llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
610 convertModRefInfoToLLVM(memAttr.getOther())) |
611 llvm::MemoryEffects(llvm::MemoryEffects::Location::ErrnoMem,
612 convertModRefInfoToLLVM(memAttr.getErrnoMem())) |
614 llvm::MemoryEffects::Location::TargetMem0,
615 convertModRefInfoToLLVM(memAttr.getTargetMem0())) |
616 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem1,
617 convertModRefInfoToLLVM(memAttr.getTargetMem1()));
618 call->setMemoryEffects(memEffects);
629 else if (!call->getType()->isVoidTy())
631 moduleTranslation.
mapCall(callOp, call);
635 if (
auto inlineAsmOp = dyn_cast<LLVM::InlineAsmOp>(opInst)) {
639 llvm::append_range(operandTypes, inlineAsmOp.getOperands().getTypes());
642 if (inlineAsmOp.getNumResults() == 0) {
643 resultType = LLVM::LLVMVoidType::get(&moduleTranslation.
getContext());
645 assert(inlineAsmOp.getNumResults() == 1);
646 resultType = inlineAsmOp.getResultTypes()[0];
648 auto ft = LLVM::LLVMFunctionType::get(resultType, operandTypes);
649 llvm::InlineAsm *inlineAsmInst =
650 inlineAsmOp.getAsmDialect()
651 ? llvm::InlineAsm::get(
652 static_cast<llvm::FunctionType *
>(
654 inlineAsmOp.getAsmString(), inlineAsmOp.getConstraints(),
655 inlineAsmOp.getHasSideEffects(),
656 inlineAsmOp.getIsAlignStack(),
657 convertAsmDialectToLLVM(*inlineAsmOp.getAsmDialect()))
658 : llvm::InlineAsm::get(
static_cast<llvm::FunctionType *
>(
660 inlineAsmOp.getAsmString(),
661 inlineAsmOp.getConstraints(),
662 inlineAsmOp.getHasSideEffects(),
663 inlineAsmOp.getIsAlignStack());
664 llvm::CallInst *inst = builder.CreateCall(
666 moduleTranslation.
lookupValues(inlineAsmOp.getOperands()));
667 inst->setTailCallKind(convertTailCallKindToLLVM(
668 inlineAsmOp.getTailCallKindAttr().getTailCallKind()));
669 if (inlineAsmOp.getConvergent())
670 inst->addFnAttr(llvm::Attribute::Convergent);
671 if (
auto maybeOperandAttrs = inlineAsmOp.getOperandAttrs()) {
672 llvm::AttributeList attrList;
673 for (
const auto &it : llvm::enumerate(*maybeOperandAttrs)) {
677 DictionaryAttr dAttr = cast<DictionaryAttr>(attr);
681 cast<TypeAttr>(dAttr.get(InlineAsmOp::getElementTypeAttrName()));
683 llvm::Type *ty = moduleTranslation.
convertType(tAttr.getValue());
684 b.addTypeAttr(llvm::Attribute::ElementType, ty);
688 attrList = attrList.addAttributesAtIndex(
691 inst->setAttributes(attrList);
699 if (
auto invOp = dyn_cast<LLVM::InvokeOp>(opInst)) {
700 auto operands = moduleTranslation.
lookupValues(invOp.getCalleeOperands());
703 invOp.getOpBundleTags(), moduleTranslation);
706 if (
auto attr = invOp.getCalleeAttr()) {
707 if (llvm::Function *function =
709 result = builder.CreateInvoke(
710 function, moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
711 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)), operandsRef,
715 attr, invOp.getCalleeFunctionType(), opInst, moduleTranslation);
716 result = builder.CreateInvoke(
717 calleeType, calleeGV,
718 moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
719 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)), operandsRef,
723 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
724 moduleTranslation.
convertType(invOp.getCalleeFunctionType()));
725 result = builder.CreateInvoke(
726 calleeType, operandsRef.front(),
727 moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
728 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)),
729 operandsRef.drop_front(), opBundles);
731 result->setCallingConv(convertCConvToLLVM(invOp.getCConv()));
732 if (invOp.getUniformWorkGroupSizeAttr())
734 "uniform-work-group-size"));
736 invOp.getDefaultFuncAttrsAttr(),
result,
742 if (invOp->getNumResults() != 0) {
749 if (
auto lpOp = dyn_cast<LLVM::LandingpadOp>(opInst)) {
750 llvm::Type *ty = moduleTranslation.
convertType(lpOp.getType());
751 llvm::LandingPadInst *lpi =
752 builder.CreateLandingPad(ty, lpOp.getNumOperands());
753 lpi->setCleanup(lpOp.getCleanup());
756 for (llvm::Value *operand :
759 if (
auto *constOperand = dyn_cast<llvm::Constant>(operand))
760 lpi->addClause(constOperand);
762 moduleTranslation.
mapValue(lpOp.getResult(), lpi);
768 if (
auto brOp = dyn_cast<LLVM::BrOp>(opInst)) {
769 llvm::UncondBrInst *branch =
770 builder.CreateBr(moduleTranslation.
lookupBlock(brOp.getSuccessor()));
771 moduleTranslation.
mapBranch(&opInst, branch);
775 if (
auto condbrOp = dyn_cast<LLVM::CondBrOp>(opInst)) {
776 llvm::CondBrInst *branch = builder.CreateCondBr(
777 moduleTranslation.
lookupValue(condbrOp.getOperand(0)),
778 moduleTranslation.
lookupBlock(condbrOp.getSuccessor(0)),
779 moduleTranslation.
lookupBlock(condbrOp.getSuccessor(1)));
780 moduleTranslation.
mapBranch(&opInst, branch);
784 if (
auto switchOp = dyn_cast<LLVM::SwitchOp>(opInst)) {
785 llvm::SwitchInst *switchInst = builder.CreateSwitch(
786 moduleTranslation.
lookupValue(switchOp.getValue()),
787 moduleTranslation.
lookupBlock(switchOp.getDefaultDestination()),
788 switchOp.getCaseDestinations().size());
791 if (!switchOp.getCaseValues())
794 auto *ty = llvm::cast<llvm::IntegerType>(
795 moduleTranslation.
convertType(switchOp.getValue().getType()));
797 llvm::zip(llvm::cast<DenseIntElementsAttr>(*switchOp.getCaseValues()),
798 switchOp.getCaseDestinations()))
800 llvm::ConstantInt::get(ty, std::get<0>(i).getLimitedValue()),
803 moduleTranslation.
mapBranch(&opInst, switchInst);
806 if (
auto indBrOp = dyn_cast<LLVM::IndirectBrOp>(opInst)) {
807 llvm::IndirectBrInst *indBr = builder.CreateIndirectBr(
809 indBrOp->getNumSuccessors());
810 for (
auto *succ : indBrOp.getSuccessors())
811 indBr->addDestination(moduleTranslation.
lookupBlock(succ));
812 moduleTranslation.
mapBranch(&opInst, indBr);
819 if (
auto addressOfOp = dyn_cast<LLVM::AddressOfOp>(opInst)) {
820 LLVM::GlobalOp global =
821 addressOfOp.getGlobal(moduleTranslation.
symbolTable());
822 LLVM::LLVMFuncOp function =
823 addressOfOp.getFunction(moduleTranslation.
symbolTable());
824 LLVM::AliasOp alias = addressOfOp.getAlias(moduleTranslation.
symbolTable());
825 LLVM::IFuncOp ifunc = addressOfOp.getIFunc(moduleTranslation.
symbolTable());
828 assert((global || function || alias || ifunc) &&
829 "referencing an undefined global, function, alias, or ifunc");
831 llvm::Value *llvmValue =
nullptr;
841 moduleTranslation.
mapValue(addressOfOp.getResult(), llvmValue);
847 if (
auto dsoLocalEquivalentOp =
848 dyn_cast<LLVM::DSOLocalEquivalentOp>(opInst)) {
849 LLVM::LLVMFuncOp function =
850 dsoLocalEquivalentOp.getFunction(moduleTranslation.
symbolTable());
851 LLVM::AliasOp alias =
852 dsoLocalEquivalentOp.getAlias(moduleTranslation.
symbolTable());
855 assert((function || alias) &&
856 "referencing an undefined function, or alias");
858 llvm::Value *llvmValue =
nullptr;
865 dsoLocalEquivalentOp.getResult(),
866 llvm::DSOLocalEquivalent::get(cast<llvm::GlobalValue>(llvmValue)));
872 if (
auto blockAddressOp = dyn_cast<LLVM::BlockAddressOp>(opInst)) {
873 BlockAddressAttr blockAddressAttr = blockAddressOp.getBlockAddr();
874 llvm::BasicBlock *llvmBlock =
877 llvm::Value *llvmValue =
nullptr;
878 StringRef fnName = blockAddressAttr.getFunction().getValue();
880 llvm::Function *llvmFn = moduleTranslation.
lookupFunction(fnName);
881 llvmValue = llvm::BlockAddress::get(llvmFn, llvmBlock);
889 llvmValue =
new llvm::GlobalVariable(
892 true, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
894 Twine(
"__mlir_block_address_")
895 .concat(Twine(fnName))
896 .concat(Twine((uint64_t)blockAddressOp.getOperation())));
900 moduleTranslation.
mapValue(blockAddressOp.getResult(), llvmValue);
906 if (
auto blockTagOp = dyn_cast<LLVM::BlockTagOp>(opInst)) {
907 auto funcOp = blockTagOp->getParentOfType<LLVMFuncOp>();
908 BlockAddressAttr blockAddressAttr = BlockAddressAttr::get(
912 blockTagOp.getTag());
914 builder.GetInsertBlock());