297 StringRef key, ModuleFlagProfileSummaryAttr summaryAttr,
299 llvm::LLVMContext &context = builder.getContext();
300 llvm::MDBuilder mdb(context);
302 auto getIntTuple = [&](StringRef key, uint64_t val) -> llvm::MDTuple * {
304 mdb.createString(key), mdb.createConstant(llvm::ConstantInt::get(
305 llvm::Type::getInt64Ty(context), val))};
306 return llvm::MDTuple::get(context, tupleNodes);
310 mdb.createString(
"ProfileFormat"),
312 stringifyProfileSummaryFormatKind(summaryAttr.getFormat()))};
315 llvm::MDTuple::get(context, fmtNode),
316 getIntTuple(
"TotalCount", summaryAttr.getTotalCount()),
317 getIntTuple(
"MaxCount", summaryAttr.getMaxCount()),
318 getIntTuple(
"MaxInternalCount", summaryAttr.getMaxInternalCount()),
319 getIntTuple(
"MaxFunctionCount", summaryAttr.getMaxFunctionCount()),
320 getIntTuple(
"NumCounts", summaryAttr.getNumCounts()),
321 getIntTuple(
"NumFunctions", summaryAttr.getNumFunctions()),
324 if (summaryAttr.getIsPartialProfile())
326 getIntTuple(
"IsPartialProfile", *summaryAttr.getIsPartialProfile()));
328 if (summaryAttr.getPartialProfileRatio()) {
330 mdb.createString(
"PartialProfileRatio"),
331 mdb.createConstant(llvm::ConstantFP::get(
332 llvm::Type::getDoubleTy(context),
333 summaryAttr.getPartialProfileRatio().getValue()))};
334 vals.push_back(llvm::MDTuple::get(context, tupleNodes));
338 llvm::Type *llvmInt64Type = llvm::Type::getInt64Ty(context);
339 for (ModuleFlagProfileSummaryDetailedAttr detailedEntry :
340 summaryAttr.getDetailedSummary()) {
343 llvm::ConstantInt::get(llvmInt64Type, detailedEntry.getCutOff())),
345 llvm::ConstantInt::get(llvmInt64Type, detailedEntry.getMinCount())),
346 mdb.createConstant(llvm::ConstantInt::get(
347 llvmInt64Type, detailedEntry.getNumCounts()))};
348 detailedEntries.push_back(llvm::MDTuple::get(context, tupleNodes));
351 mdb.createString(
"DetailedSummary"),
352 llvm::MDTuple::get(context, detailedEntries)};
353 vals.push_back(llvm::MDTuple::get(context, detailedSummary));
355 return llvm::MDNode::get(context, vals);
433 llvm::IRBuilder<>::FastMathFlagGuard fmfGuard(builder);
434 if (
auto fmf = dyn_cast<FastmathFlagsInterface>(opInst))
437#include "mlir/Dialect/LLVMIR/LLVMConversions.inc"
438#include "mlir/Dialect/LLVMIR/LLVMIntrinsicConversions.inc"
444 if (
auto callOp = dyn_cast<LLVM::CallOp>(opInst)) {
445 auto operands = moduleTranslation.
lookupValues(callOp.getCalleeOperands());
448 callOp.getOpBundleTags(), moduleTranslation);
450 llvm::CallInst *call;
451 if (
auto attr = callOp.getCalleeAttr()) {
452 if (llvm::Function *function =
454 call = builder.CreateCall(function, operandsRef, opBundles);
457 attr, callOp.getCalleeFunctionType(), opInst, moduleTranslation);
458 call = builder.CreateCall(calleeType, calleeGV, operandsRef, opBundles);
461 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
462 moduleTranslation.
convertType(callOp.getCalleeFunctionType()));
463 call = builder.CreateCall(calleeType, operandsRef.front(),
464 operandsRef.drop_front(), opBundles);
466 call->setCallingConv(convertCConvToLLVM(callOp.getCConv()));
467 call->setTailCallKind(convertTailCallKindToLLVM(callOp.getTailCallKind()));
468 if (callOp.getConvergentAttr())
469 call->addFnAttr(llvm::Attribute::Convergent);
470 if (callOp.getNoUnwindAttr())
471 call->addFnAttr(llvm::Attribute::NoUnwind);
472 if (callOp.getWillReturnAttr())
473 call->addFnAttr(llvm::Attribute::WillReturn);
474 if (callOp.getNoreturnAttr())
475 call->addFnAttr(llvm::Attribute::NoReturn);
476 if (callOp.getOptsizeAttr())
477 call->addFnAttr(llvm::Attribute::OptimizeForSize);
478 if (callOp.getMinsizeAttr())
479 call->addFnAttr(llvm::Attribute::MinSize);
480 if (callOp.getSaveRegParamsAttr())
481 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
483 if (callOp.getBuiltinAttr())
484 call->addFnAttr(llvm::Attribute::Builtin);
485 if (callOp.getNobuiltinAttr())
486 call->addFnAttr(llvm::Attribute::NoBuiltin);
487 if (callOp.getReturnsTwiceAttr())
488 call->addFnAttr(llvm::Attribute::ReturnsTwice);
489 if (callOp.getColdAttr())
490 call->addFnAttr(llvm::Attribute::Cold);
491 if (callOp.getHotAttr())
492 call->addFnAttr(llvm::Attribute::Hot);
493 if (callOp.getNoduplicateAttr())
494 call->addFnAttr(llvm::Attribute::NoDuplicate);
495 if (callOp.getNoInlineAttr())
496 call->addFnAttr(llvm::Attribute::NoInline);
497 if (callOp.getAlwaysInlineAttr())
498 call->addFnAttr(llvm::Attribute::AlwaysInline);
499 if (callOp.getInlineHintAttr())
500 call->addFnAttr(llvm::Attribute::InlineHint);
501 if (callOp.getNoCallerSavedRegistersAttr())
502 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
503 "no_caller_saved_registers"));
504 if (callOp.getNocallbackAttr())
505 call->addFnAttr(llvm::Attribute::NoCallback);
506 if (StringAttr modFormat = callOp.getModularFormatAttr())
507 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
509 modFormat.getValue()));
510 if (StringAttr zcsr = callOp.getZeroCallUsedRegsAttr())
511 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
512 "zero-call-used-regs",
514 if (callOp.getUniformWorkGroupSizeAttr())
515 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
516 "uniform-work-group-size"));
517 if (StringAttr trapFunc = callOp.getTrapFuncNameAttr())
518 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
520 trapFunc.getValue()));
522 if (
ArrayAttr noBuiltins = callOp.getNobuiltinsAttr()) {
523 if (noBuiltins.empty())
524 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
532 callOp.getDefaultFuncAttrsAttr(), call,
535 if (llvm::Attribute attr =
538 call->addFnAttr(attr);
543 if (MemoryEffectsAttr memAttr = callOp.getMemoryEffectsAttr()) {
544 llvm::MemoryEffects memEffects =
545 llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
546 convertModRefInfoToLLVM(memAttr.getArgMem())) |
548 llvm::MemoryEffects::Location::InaccessibleMem,
549 convertModRefInfoToLLVM(memAttr.getInaccessibleMem())) |
550 llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
551 convertModRefInfoToLLVM(memAttr.getOther())) |
552 llvm::MemoryEffects(llvm::MemoryEffects::Location::ErrnoMem,
553 convertModRefInfoToLLVM(memAttr.getErrnoMem())) |
555 llvm::MemoryEffects::Location::TargetMem0,
556 convertModRefInfoToLLVM(memAttr.getTargetMem0())) |
557 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem1,
558 convertModRefInfoToLLVM(memAttr.getTargetMem1()));
559 call->setMemoryEffects(memEffects);
570 else if (!call->getType()->isVoidTy())
572 moduleTranslation.
mapCall(callOp, call);
576 if (
auto inlineAsmOp = dyn_cast<LLVM::InlineAsmOp>(opInst)) {
580 llvm::append_range(operandTypes, inlineAsmOp.getOperands().getTypes());
583 if (inlineAsmOp.getNumResults() == 0) {
584 resultType = LLVM::LLVMVoidType::get(&moduleTranslation.
getContext());
586 assert(inlineAsmOp.getNumResults() == 1);
587 resultType = inlineAsmOp.getResultTypes()[0];
589 auto ft = LLVM::LLVMFunctionType::get(resultType, operandTypes);
590 llvm::InlineAsm *inlineAsmInst =
591 inlineAsmOp.getAsmDialect()
592 ? llvm::InlineAsm::get(
593 static_cast<llvm::FunctionType *
>(
595 inlineAsmOp.getAsmString(), inlineAsmOp.getConstraints(),
596 inlineAsmOp.getHasSideEffects(),
597 inlineAsmOp.getIsAlignStack(),
598 convertAsmDialectToLLVM(*inlineAsmOp.getAsmDialect()))
599 : llvm::InlineAsm::get(
static_cast<llvm::FunctionType *
>(
601 inlineAsmOp.getAsmString(),
602 inlineAsmOp.getConstraints(),
603 inlineAsmOp.getHasSideEffects(),
604 inlineAsmOp.getIsAlignStack());
605 llvm::CallInst *inst = builder.CreateCall(
607 moduleTranslation.
lookupValues(inlineAsmOp.getOperands()));
608 inst->setTailCallKind(convertTailCallKindToLLVM(
609 inlineAsmOp.getTailCallKindAttr().getTailCallKind()));
610 if (inlineAsmOp.getConvergent())
611 inst->addFnAttr(llvm::Attribute::Convergent);
612 if (
auto maybeOperandAttrs = inlineAsmOp.getOperandAttrs()) {
613 llvm::AttributeList attrList;
614 for (
const auto &it : llvm::enumerate(*maybeOperandAttrs)) {
618 DictionaryAttr dAttr = cast<DictionaryAttr>(attr);
622 cast<TypeAttr>(dAttr.get(InlineAsmOp::getElementTypeAttrName()));
624 llvm::Type *ty = moduleTranslation.
convertType(tAttr.getValue());
625 b.addTypeAttr(llvm::Attribute::ElementType, ty);
629 attrList = attrList.addAttributesAtIndex(
632 inst->setAttributes(attrList);
640 if (
auto invOp = dyn_cast<LLVM::InvokeOp>(opInst)) {
641 auto operands = moduleTranslation.
lookupValues(invOp.getCalleeOperands());
644 invOp.getOpBundleTags(), moduleTranslation);
647 if (
auto attr = invOp.getCalleeAttr()) {
648 if (llvm::Function *function =
650 result = builder.CreateInvoke(
651 function, moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
652 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)), operandsRef,
656 attr, invOp.getCalleeFunctionType(), opInst, moduleTranslation);
657 result = builder.CreateInvoke(
658 calleeType, calleeGV,
659 moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
660 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)), operandsRef,
664 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
665 moduleTranslation.
convertType(invOp.getCalleeFunctionType()));
666 result = builder.CreateInvoke(
667 calleeType, operandsRef.front(),
668 moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
669 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)),
670 operandsRef.drop_front(), opBundles);
672 result->setCallingConv(convertCConvToLLVM(invOp.getCConv()));
673 if (invOp.getUniformWorkGroupSizeAttr())
675 "uniform-work-group-size"));
677 invOp.getDefaultFuncAttrsAttr(),
result,
683 if (invOp->getNumResults() != 0) {
690 if (
auto lpOp = dyn_cast<LLVM::LandingpadOp>(opInst)) {
691 llvm::Type *ty = moduleTranslation.
convertType(lpOp.getType());
692 llvm::LandingPadInst *lpi =
693 builder.CreateLandingPad(ty, lpOp.getNumOperands());
694 lpi->setCleanup(lpOp.getCleanup());
697 for (llvm::Value *operand :
700 if (
auto *constOperand = dyn_cast<llvm::Constant>(operand))
701 lpi->addClause(constOperand);
703 moduleTranslation.
mapValue(lpOp.getResult(), lpi);
709 if (
auto brOp = dyn_cast<LLVM::BrOp>(opInst)) {
710 llvm::UncondBrInst *branch =
711 builder.CreateBr(moduleTranslation.
lookupBlock(brOp.getSuccessor()));
712 moduleTranslation.
mapBranch(&opInst, branch);
716 if (
auto condbrOp = dyn_cast<LLVM::CondBrOp>(opInst)) {
717 llvm::CondBrInst *branch = builder.CreateCondBr(
718 moduleTranslation.
lookupValue(condbrOp.getOperand(0)),
719 moduleTranslation.
lookupBlock(condbrOp.getSuccessor(0)),
720 moduleTranslation.
lookupBlock(condbrOp.getSuccessor(1)));
721 moduleTranslation.
mapBranch(&opInst, branch);
725 if (
auto switchOp = dyn_cast<LLVM::SwitchOp>(opInst)) {
726 llvm::SwitchInst *switchInst = builder.CreateSwitch(
727 moduleTranslation.
lookupValue(switchOp.getValue()),
728 moduleTranslation.
lookupBlock(switchOp.getDefaultDestination()),
729 switchOp.getCaseDestinations().size());
732 if (!switchOp.getCaseValues())
735 auto *ty = llvm::cast<llvm::IntegerType>(
736 moduleTranslation.
convertType(switchOp.getValue().getType()));
738 llvm::zip(llvm::cast<DenseIntElementsAttr>(*switchOp.getCaseValues()),
739 switchOp.getCaseDestinations()))
741 llvm::ConstantInt::get(ty, std::get<0>(i).getLimitedValue()),
744 moduleTranslation.
mapBranch(&opInst, switchInst);
747 if (
auto indBrOp = dyn_cast<LLVM::IndirectBrOp>(opInst)) {
748 llvm::IndirectBrInst *indBr = builder.CreateIndirectBr(
750 indBrOp->getNumSuccessors());
751 for (
auto *succ : indBrOp.getSuccessors())
752 indBr->addDestination(moduleTranslation.
lookupBlock(succ));
753 moduleTranslation.
mapBranch(&opInst, indBr);
760 if (
auto addressOfOp = dyn_cast<LLVM::AddressOfOp>(opInst)) {
761 LLVM::GlobalOp global =
762 addressOfOp.getGlobal(moduleTranslation.
symbolTable());
763 LLVM::LLVMFuncOp function =
764 addressOfOp.getFunction(moduleTranslation.
symbolTable());
765 LLVM::AliasOp alias = addressOfOp.getAlias(moduleTranslation.
symbolTable());
766 LLVM::IFuncOp ifunc = addressOfOp.getIFunc(moduleTranslation.
symbolTable());
769 assert((global || function || alias || ifunc) &&
770 "referencing an undefined global, function, alias, or ifunc");
772 llvm::Value *llvmValue =
nullptr;
782 moduleTranslation.
mapValue(addressOfOp.getResult(), llvmValue);
788 if (
auto dsoLocalEquivalentOp =
789 dyn_cast<LLVM::DSOLocalEquivalentOp>(opInst)) {
790 LLVM::LLVMFuncOp function =
791 dsoLocalEquivalentOp.getFunction(moduleTranslation.
symbolTable());
792 LLVM::AliasOp alias =
793 dsoLocalEquivalentOp.getAlias(moduleTranslation.
symbolTable());
796 assert((function || alias) &&
797 "referencing an undefined function, or alias");
799 llvm::Value *llvmValue =
nullptr;
806 dsoLocalEquivalentOp.getResult(),
807 llvm::DSOLocalEquivalent::get(cast<llvm::GlobalValue>(llvmValue)));
813 if (
auto blockAddressOp = dyn_cast<LLVM::BlockAddressOp>(opInst)) {
814 BlockAddressAttr blockAddressAttr = blockAddressOp.getBlockAddr();
815 llvm::BasicBlock *llvmBlock =
818 llvm::Value *llvmValue =
nullptr;
819 StringRef fnName = blockAddressAttr.getFunction().getValue();
821 llvm::Function *llvmFn = moduleTranslation.
lookupFunction(fnName);
822 llvmValue = llvm::BlockAddress::get(llvmFn, llvmBlock);
830 llvmValue =
new llvm::GlobalVariable(
833 true, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
835 Twine(
"__mlir_block_address_")
836 .concat(Twine(fnName))
837 .concat(Twine((uint64_t)blockAddressOp.getOperation())));
841 moduleTranslation.
mapValue(blockAddressOp.getResult(), llvmValue);
847 if (
auto blockTagOp = dyn_cast<LLVM::BlockTagOp>(opInst)) {
848 auto funcOp = blockTagOp->getParentOfType<LLVMFuncOp>();
849 BlockAddressAttr blockAddressAttr = BlockAddressAttr::get(
853 blockTagOp.getTag());
855 builder.GetInsertBlock());