321 StringRef key, ModuleFlagProfileSummaryAttr summaryAttr,
323 llvm::LLVMContext &context = builder.getContext();
324 llvm::MDBuilder mdb(context);
326 auto getIntTuple = [&](StringRef key, uint64_t val) -> llvm::MDTuple * {
328 mdb.createString(key), mdb.createConstant(llvm::ConstantInt::get(
329 llvm::Type::getInt64Ty(context), val))};
330 return llvm::MDTuple::get(context, tupleNodes);
334 mdb.createString(
"ProfileFormat"),
336 stringifyProfileSummaryFormatKind(summaryAttr.getFormat()))};
339 llvm::MDTuple::get(context, fmtNode),
340 getIntTuple(
"TotalCount", summaryAttr.getTotalCount()),
341 getIntTuple(
"MaxCount", summaryAttr.getMaxCount()),
342 getIntTuple(
"MaxInternalCount", summaryAttr.getMaxInternalCount()),
343 getIntTuple(
"MaxFunctionCount", summaryAttr.getMaxFunctionCount()),
344 getIntTuple(
"NumCounts", summaryAttr.getNumCounts()),
345 getIntTuple(
"NumFunctions", summaryAttr.getNumFunctions()),
348 if (summaryAttr.getIsPartialProfile())
350 getIntTuple(
"IsPartialProfile", *summaryAttr.getIsPartialProfile()));
352 if (summaryAttr.getPartialProfileRatio()) {
354 mdb.createString(
"PartialProfileRatio"),
355 mdb.createConstant(llvm::ConstantFP::get(
356 llvm::Type::getDoubleTy(context),
357 summaryAttr.getPartialProfileRatio().getValue()))};
358 vals.push_back(llvm::MDTuple::get(context, tupleNodes));
362 llvm::Type *llvmInt64Type = llvm::Type::getInt64Ty(context);
363 for (ModuleFlagProfileSummaryDetailedAttr detailedEntry :
364 summaryAttr.getDetailedSummary()) {
367 llvm::ConstantInt::get(llvmInt64Type, detailedEntry.getCutOff())),
369 llvm::ConstantInt::get(llvmInt64Type, detailedEntry.getMinCount())),
370 mdb.createConstant(llvm::ConstantInt::get(
371 llvmInt64Type, detailedEntry.getNumCounts()))};
372 detailedEntries.push_back(llvm::MDTuple::get(context, tupleNodes));
375 mdb.createString(
"DetailedSummary"),
376 llvm::MDTuple::get(context, detailedEntries)};
377 vals.push_back(llvm::MDTuple::get(context, detailedSummary));
379 return llvm::MDNode::get(context, vals);
451 llvm::IRBuilder<>::FastMathFlagGuard fmfGuard(builder);
452 if (
auto fmf = dyn_cast<FastmathFlagsInterface>(opInst))
455#include "mlir/Dialect/LLVMIR/LLVMConversions.inc"
456#include "mlir/Dialect/LLVMIR/LLVMIntrinsicConversions.inc"
462 if (
auto callOp = dyn_cast<LLVM::CallOp>(opInst)) {
463 auto operands = moduleTranslation.
lookupValues(callOp.getCalleeOperands());
466 callOp.getOpBundleTags(), moduleTranslation);
468 llvm::CallInst *call;
469 if (
auto attr = callOp.getCalleeAttr()) {
470 if (llvm::Function *function =
472 call = builder.CreateCall(function, operandsRef, opBundles);
475 attr, callOp.getCalleeFunctionType(), opInst, moduleTranslation);
476 call = builder.CreateCall(calleeType, calleeGV, operandsRef, opBundles);
479 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
480 moduleTranslation.
convertType(callOp.getCalleeFunctionType()));
481 call = builder.CreateCall(calleeType, operandsRef.front(),
482 operandsRef.drop_front(), opBundles);
484 call->setCallingConv(convertCConvToLLVM(callOp.getCConv()));
485 call->setTailCallKind(convertTailCallKindToLLVM(callOp.getTailCallKind()));
486 if (callOp.getConvergentAttr())
487 call->addFnAttr(llvm::Attribute::Convergent);
488 if (callOp.getNoUnwindAttr())
489 call->addFnAttr(llvm::Attribute::NoUnwind);
490 if (callOp.getWillReturnAttr())
491 call->addFnAttr(llvm::Attribute::WillReturn);
492 if (callOp.getNoreturnAttr())
493 call->addFnAttr(llvm::Attribute::NoReturn);
494 if (callOp.getOptsizeAttr())
495 call->addFnAttr(llvm::Attribute::OptimizeForSize);
496 if (callOp.getMinsizeAttr())
497 call->addFnAttr(llvm::Attribute::MinSize);
498 if (callOp.getSaveRegParamsAttr())
499 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
501 if (callOp.getBuiltinAttr())
502 call->addFnAttr(llvm::Attribute::Builtin);
503 if (callOp.getNobuiltinAttr())
504 call->addFnAttr(llvm::Attribute::NoBuiltin);
505 if (callOp.getReturnsTwiceAttr())
506 call->addFnAttr(llvm::Attribute::ReturnsTwice);
507 if (callOp.getColdAttr())
508 call->addFnAttr(llvm::Attribute::Cold);
509 if (callOp.getHotAttr())
510 call->addFnAttr(llvm::Attribute::Hot);
511 if (callOp.getNoduplicateAttr())
512 call->addFnAttr(llvm::Attribute::NoDuplicate);
513 if (callOp.getNoInlineAttr())
514 call->addFnAttr(llvm::Attribute::NoInline);
515 if (callOp.getAlwaysInlineAttr())
516 call->addFnAttr(llvm::Attribute::AlwaysInline);
517 if (callOp.getInlineHintAttr())
518 call->addFnAttr(llvm::Attribute::InlineHint);
519 if (callOp.getNoCallerSavedRegistersAttr())
520 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
521 "no_caller_saved_registers"));
522 if (callOp.getNocallbackAttr())
523 call->addFnAttr(llvm::Attribute::NoCallback);
524 if (StringAttr modFormat = callOp.getModularFormatAttr())
525 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
527 modFormat.getValue()));
528 if (StringAttr zcsr = callOp.getZeroCallUsedRegsAttr())
529 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
530 "zero-call-used-regs",
532 if (StringAttr trapFunc = callOp.getTrapFuncNameAttr())
533 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
535 trapFunc.getValue()));
537 if (
ArrayAttr noBuiltins = callOp.getNobuiltinsAttr()) {
538 if (noBuiltins.empty())
539 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
547 callOp.getDefaultFuncAttrsAttr(), call,
550 if (llvm::Attribute attr =
553 call->addFnAttr(attr);
558 if (MemoryEffectsAttr memAttr = callOp.getMemoryEffectsAttr()) {
559 llvm::MemoryEffects memEffects =
560 llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
561 convertModRefInfoToLLVM(memAttr.getArgMem())) |
563 llvm::MemoryEffects::Location::InaccessibleMem,
564 convertModRefInfoToLLVM(memAttr.getInaccessibleMem())) |
565 llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
566 convertModRefInfoToLLVM(memAttr.getOther())) |
567 llvm::MemoryEffects(llvm::MemoryEffects::Location::ErrnoMem,
568 convertModRefInfoToLLVM(memAttr.getErrnoMem())) |
570 llvm::MemoryEffects::Location::TargetMem0,
571 convertModRefInfoToLLVM(memAttr.getTargetMem0())) |
572 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem1,
573 convertModRefInfoToLLVM(memAttr.getTargetMem1()));
574 call->setMemoryEffects(memEffects);
585 else if (!call->getType()->isVoidTy())
587 moduleTranslation.
mapCall(callOp, call);
591 if (
auto inlineAsmOp = dyn_cast<LLVM::InlineAsmOp>(opInst)) {
595 llvm::append_range(operandTypes, inlineAsmOp.getOperands().getTypes());
598 if (inlineAsmOp.getNumResults() == 0) {
599 resultType = LLVM::LLVMVoidType::get(&moduleTranslation.
getContext());
601 assert(inlineAsmOp.getNumResults() == 1);
602 resultType = inlineAsmOp.getResultTypes()[0];
604 auto ft = LLVM::LLVMFunctionType::get(resultType, operandTypes);
605 llvm::InlineAsm *inlineAsmInst =
606 inlineAsmOp.getAsmDialect()
607 ? llvm::InlineAsm::get(
608 static_cast<llvm::FunctionType *
>(
610 inlineAsmOp.getAsmString(), inlineAsmOp.getConstraints(),
611 inlineAsmOp.getHasSideEffects(),
612 inlineAsmOp.getIsAlignStack(),
613 convertAsmDialectToLLVM(*inlineAsmOp.getAsmDialect()))
614 : llvm::InlineAsm::get(
static_cast<llvm::FunctionType *
>(
616 inlineAsmOp.getAsmString(),
617 inlineAsmOp.getConstraints(),
618 inlineAsmOp.getHasSideEffects(),
619 inlineAsmOp.getIsAlignStack());
620 llvm::CallInst *inst = builder.CreateCall(
622 moduleTranslation.
lookupValues(inlineAsmOp.getOperands()));
623 inst->setTailCallKind(convertTailCallKindToLLVM(
624 inlineAsmOp.getTailCallKindAttr().getTailCallKind()));
625 if (
auto maybeOperandAttrs = inlineAsmOp.getOperandAttrs()) {
626 llvm::AttributeList attrList;
627 for (
const auto &it : llvm::enumerate(*maybeOperandAttrs)) {
631 DictionaryAttr dAttr = cast<DictionaryAttr>(attr);
635 cast<TypeAttr>(dAttr.get(InlineAsmOp::getElementTypeAttrName()));
637 llvm::Type *ty = moduleTranslation.
convertType(tAttr.getValue());
638 b.addTypeAttr(llvm::Attribute::ElementType, ty);
642 attrList = attrList.addAttributesAtIndex(
645 inst->setAttributes(attrList);
653 if (
auto invOp = dyn_cast<LLVM::InvokeOp>(opInst)) {
654 auto operands = moduleTranslation.
lookupValues(invOp.getCalleeOperands());
657 invOp.getOpBundleTags(), moduleTranslation);
661 if (llvm::Function *function =
663 result = builder.CreateInvoke(
664 function, moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
665 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)), operandsRef,
669 attr, invOp.getCalleeFunctionType(), opInst, moduleTranslation);
670 result = builder.CreateInvoke(
671 calleeType, calleeGV,
672 moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
673 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)), operandsRef,
677 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
678 moduleTranslation.
convertType(invOp.getCalleeFunctionType()));
679 result = builder.CreateInvoke(
680 calleeType, operandsRef.front(),
681 moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
682 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)),
683 operandsRef.drop_front(), opBundles);
685 result->setCallingConv(convertCConvToLLVM(invOp.getCConv()));
690 if (invOp->getNumResults() != 0) {
697 if (
auto lpOp = dyn_cast<LLVM::LandingpadOp>(opInst)) {
698 llvm::Type *ty = moduleTranslation.
convertType(lpOp.getType());
699 llvm::LandingPadInst *lpi =
700 builder.CreateLandingPad(ty, lpOp.getNumOperands());
701 lpi->setCleanup(lpOp.getCleanup());
704 for (llvm::Value *operand :
707 if (
auto *constOperand = dyn_cast<llvm::Constant>(operand))
708 lpi->addClause(constOperand);
710 moduleTranslation.
mapValue(lpOp.getResult(), lpi);
716 if (
auto brOp = dyn_cast<LLVM::BrOp>(opInst)) {
717 llvm::UncondBrInst *branch =
718 builder.CreateBr(moduleTranslation.
lookupBlock(brOp.getSuccessor()));
719 moduleTranslation.
mapBranch(&opInst, branch);
723 if (
auto condbrOp = dyn_cast<LLVM::CondBrOp>(opInst)) {
724 llvm::CondBrInst *branch = builder.CreateCondBr(
725 moduleTranslation.
lookupValue(condbrOp.getOperand(0)),
726 moduleTranslation.
lookupBlock(condbrOp.getSuccessor(0)),
727 moduleTranslation.
lookupBlock(condbrOp.getSuccessor(1)));
728 moduleTranslation.
mapBranch(&opInst, branch);
732 if (
auto switchOp = dyn_cast<LLVM::SwitchOp>(opInst)) {
733 llvm::SwitchInst *switchInst = builder.CreateSwitch(
734 moduleTranslation.
lookupValue(switchOp.getValue()),
735 moduleTranslation.
lookupBlock(switchOp.getDefaultDestination()),
736 switchOp.getCaseDestinations().size());
739 if (!switchOp.getCaseValues())
742 auto *ty = llvm::cast<llvm::IntegerType>(
743 moduleTranslation.
convertType(switchOp.getValue().getType()));
745 llvm::zip(llvm::cast<DenseIntElementsAttr>(*switchOp.getCaseValues()),
746 switchOp.getCaseDestinations()))
748 llvm::ConstantInt::get(ty, std::get<0>(i).getLimitedValue()),
751 moduleTranslation.
mapBranch(&opInst, switchInst);
754 if (
auto indBrOp = dyn_cast<LLVM::IndirectBrOp>(opInst)) {
755 llvm::IndirectBrInst *indBr = builder.CreateIndirectBr(
757 indBrOp->getNumSuccessors());
758 for (
auto *succ : indBrOp.getSuccessors())
759 indBr->addDestination(moduleTranslation.
lookupBlock(succ));
760 moduleTranslation.
mapBranch(&opInst, indBr);
767 if (
auto addressOfOp = dyn_cast<LLVM::AddressOfOp>(opInst)) {
768 LLVM::GlobalOp global =
769 addressOfOp.getGlobal(moduleTranslation.
symbolTable());
770 LLVM::LLVMFuncOp function =
771 addressOfOp.getFunction(moduleTranslation.
symbolTable());
772 LLVM::AliasOp alias = addressOfOp.getAlias(moduleTranslation.
symbolTable());
773 LLVM::IFuncOp ifunc = addressOfOp.getIFunc(moduleTranslation.
symbolTable());
776 assert((global || function || alias || ifunc) &&
777 "referencing an undefined global, function, alias, or ifunc");
779 llvm::Value *llvmValue =
nullptr;
789 moduleTranslation.
mapValue(addressOfOp.getResult(), llvmValue);
795 if (
auto dsoLocalEquivalentOp =
796 dyn_cast<LLVM::DSOLocalEquivalentOp>(opInst)) {
797 LLVM::LLVMFuncOp function =
798 dsoLocalEquivalentOp.getFunction(moduleTranslation.
symbolTable());
799 LLVM::AliasOp alias =
800 dsoLocalEquivalentOp.getAlias(moduleTranslation.
symbolTable());
803 assert((function || alias) &&
804 "referencing an undefined function, or alias");
806 llvm::Value *llvmValue =
nullptr;
813 dsoLocalEquivalentOp.getResult(),
814 llvm::DSOLocalEquivalent::get(cast<llvm::GlobalValue>(llvmValue)));
820 if (
auto blockAddressOp = dyn_cast<LLVM::BlockAddressOp>(opInst)) {
821 BlockAddressAttr blockAddressAttr = blockAddressOp.getBlockAddr();
822 llvm::BasicBlock *llvmBlock =
825 llvm::Value *llvmValue =
nullptr;
826 StringRef fnName = blockAddressAttr.getFunction().getValue();
828 llvm::Function *llvmFn = moduleTranslation.
lookupFunction(fnName);
829 llvmValue = llvm::BlockAddress::get(llvmFn, llvmBlock);
837 llvmValue =
new llvm::GlobalVariable(
840 true, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
842 Twine(
"__mlir_block_address_")
843 .concat(Twine(fnName))
844 .concat(Twine((uint64_t)blockAddressOp.getOperation())));
848 moduleTranslation.
mapValue(blockAddressOp.getResult(), llvmValue);
854 if (
auto blockTagOp = dyn_cast<LLVM::BlockTagOp>(opInst)) {
855 auto funcOp = blockTagOp->getParentOfType<LLVMFuncOp>();
856 BlockAddressAttr blockAddressAttr = BlockAddressAttr::get(
860 blockTagOp.getTag());
862 builder.GetInsertBlock());