269 StringRef key, ModuleFlagProfileSummaryAttr summaryAttr,
271 llvm::LLVMContext &context = builder.getContext();
272 llvm::MDBuilder mdb(context);
274 auto getIntTuple = [&](StringRef key, uint64_t val) -> llvm::MDTuple * {
276 mdb.createString(key), mdb.createConstant(llvm::ConstantInt::get(
277 llvm::Type::getInt64Ty(context), val))};
278 return llvm::MDTuple::get(context, tupleNodes);
282 mdb.createString(
"ProfileFormat"),
284 stringifyProfileSummaryFormatKind(summaryAttr.getFormat()))};
287 llvm::MDTuple::get(context, fmtNode),
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"),
303 mdb.createConstant(llvm::ConstantFP::get(
304 llvm::Type::getDoubleTy(context),
305 summaryAttr.getPartialProfileRatio().getValue()))};
306 vals.push_back(llvm::MDTuple::get(context, tupleNodes));
310 llvm::Type *llvmInt64Type = llvm::Type::getInt64Ty(context);
311 for (ModuleFlagProfileSummaryDetailedAttr detailedEntry :
312 summaryAttr.getDetailedSummary()) {
315 llvm::ConstantInt::get(llvmInt64Type, detailedEntry.getCutOff())),
317 llvm::ConstantInt::get(llvmInt64Type, detailedEntry.getMinCount())),
318 mdb.createConstant(llvm::ConstantInt::get(
319 llvmInt64Type, detailedEntry.getNumCounts()))};
320 detailedEntries.push_back(llvm::MDTuple::get(context, tupleNodes));
323 mdb.createString(
"DetailedSummary"),
324 llvm::MDTuple::get(context, detailedEntries)};
325 vals.push_back(llvm::MDTuple::get(context, detailedSummary));
327 return llvm::MDNode::get(context, vals);
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 =
400 call = builder.CreateCall(function, operandsRef, opBundles);
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.getNoreturnAttr())
425 call->addFnAttr(llvm::Attribute::NoReturn);
426 if (callOp.getOptsizeAttr())
427 call->addFnAttr(llvm::Attribute::OptimizeForSize);
428 if (callOp.getMinsizeAttr())
429 call->addFnAttr(llvm::Attribute::MinSize);
430 if (callOp.getSaveRegParamsAttr())
431 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
433 if (callOp.getNobuiltinAttr())
434 call->addFnAttr(llvm::Attribute::NoBuiltin);
435 if (callOp.getReturnsTwiceAttr())
436 call->addFnAttr(llvm::Attribute::ReturnsTwice);
437 if (callOp.getColdAttr())
438 call->addFnAttr(llvm::Attribute::Cold);
439 if (callOp.getHotAttr())
440 call->addFnAttr(llvm::Attribute::Hot);
441 if (callOp.getNoduplicateAttr())
442 call->addFnAttr(llvm::Attribute::NoDuplicate);
443 if (callOp.getNoInlineAttr())
444 call->addFnAttr(llvm::Attribute::NoInline);
445 if (callOp.getAlwaysInlineAttr())
446 call->addFnAttr(llvm::Attribute::AlwaysInline);
447 if (callOp.getInlineHintAttr())
448 call->addFnAttr(llvm::Attribute::InlineHint);
449 if (callOp.getNoCallerSavedRegistersAttr())
450 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
451 "no_caller_saved_registers"));
452 if (callOp.getNocallbackAttr())
453 call->addFnAttr(llvm::Attribute::NoCallback);
454 if (StringAttr modFormat = callOp.getModularFormatAttr())
455 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
457 modFormat.getValue()));
458 if (StringAttr zcsr = callOp.getZeroCallUsedRegsAttr())
459 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
460 "zero-call-used-regs",
462 if (StringAttr trapFunc = callOp.getTrapFuncNameAttr())
463 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
465 trapFunc.getValue()));
467 if (
ArrayAttr noBuiltins = callOp.getNobuiltinsAttr()) {
468 if (noBuiltins.empty())
469 call->addFnAttr(llvm::Attribute::get(moduleTranslation.
getLLVMContext(),
477 callOp.getDefaultFuncAttrsAttr(), call,
480 if (llvm::Attribute attr =
483 call->addFnAttr(attr);
488 if (MemoryEffectsAttr memAttr = callOp.getMemoryEffectsAttr()) {
489 llvm::MemoryEffects memEffects =
490 llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
491 convertModRefInfoToLLVM(memAttr.getArgMem())) |
493 llvm::MemoryEffects::Location::InaccessibleMem,
494 convertModRefInfoToLLVM(memAttr.getInaccessibleMem())) |
495 llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
496 convertModRefInfoToLLVM(memAttr.getOther())) |
497 llvm::MemoryEffects(llvm::MemoryEffects::Location::ErrnoMem,
498 convertModRefInfoToLLVM(memAttr.getErrnoMem())) |
500 llvm::MemoryEffects::Location::TargetMem0,
501 convertModRefInfoToLLVM(memAttr.getTargetMem0())) |
502 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem1,
503 convertModRefInfoToLLVM(memAttr.getTargetMem1()));
504 call->setMemoryEffects(memEffects);
515 else if (!call->getType()->isVoidTy())
517 moduleTranslation.
mapCall(callOp, call);
521 if (
auto inlineAsmOp = dyn_cast<LLVM::InlineAsmOp>(opInst)) {
525 llvm::append_range(operandTypes, inlineAsmOp.getOperands().getTypes());
528 if (inlineAsmOp.getNumResults() == 0) {
529 resultType = LLVM::LLVMVoidType::get(&moduleTranslation.
getContext());
531 assert(inlineAsmOp.getNumResults() == 1);
532 resultType = inlineAsmOp.getResultTypes()[0];
534 auto ft = LLVM::LLVMFunctionType::get(resultType, operandTypes);
535 llvm::InlineAsm *inlineAsmInst =
536 inlineAsmOp.getAsmDialect()
537 ? llvm::InlineAsm::get(
538 static_cast<llvm::FunctionType *
>(
540 inlineAsmOp.getAsmString(), inlineAsmOp.getConstraints(),
541 inlineAsmOp.getHasSideEffects(),
542 inlineAsmOp.getIsAlignStack(),
543 convertAsmDialectToLLVM(*inlineAsmOp.getAsmDialect()))
544 : llvm::InlineAsm::get(
static_cast<llvm::FunctionType *
>(
546 inlineAsmOp.getAsmString(),
547 inlineAsmOp.getConstraints(),
548 inlineAsmOp.getHasSideEffects(),
549 inlineAsmOp.getIsAlignStack());
550 llvm::CallInst *inst = builder.CreateCall(
552 moduleTranslation.
lookupValues(inlineAsmOp.getOperands()));
553 inst->setTailCallKind(convertTailCallKindToLLVM(
554 inlineAsmOp.getTailCallKindAttr().getTailCallKind()));
555 if (
auto maybeOperandAttrs = inlineAsmOp.getOperandAttrs()) {
556 llvm::AttributeList attrList;
557 for (
const auto &it : llvm::enumerate(*maybeOperandAttrs)) {
561 DictionaryAttr dAttr = cast<DictionaryAttr>(attr);
565 cast<TypeAttr>(dAttr.get(InlineAsmOp::getElementTypeAttrName()));
567 llvm::Type *ty = moduleTranslation.
convertType(tAttr.getValue());
568 b.addTypeAttr(llvm::Attribute::ElementType, ty);
572 attrList = attrList.addAttributesAtIndex(
575 inst->setAttributes(attrList);
583 if (
auto invOp = dyn_cast<LLVM::InvokeOp>(opInst)) {
584 auto operands = moduleTranslation.
lookupValues(invOp.getCalleeOperands());
587 invOp.getOpBundleTags(), moduleTranslation);
591 result = builder.CreateInvoke(
593 moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
594 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)), operandsRef,
597 llvm::FunctionType *calleeType = llvm::cast<llvm::FunctionType>(
598 moduleTranslation.
convertType(invOp.getCalleeFunctionType()));
599 result = builder.CreateInvoke(
600 calleeType, operandsRef.front(),
601 moduleTranslation.
lookupBlock(invOp.getSuccessor(0)),
602 moduleTranslation.
lookupBlock(invOp.getSuccessor(1)),
603 operandsRef.drop_front(), opBundles);
605 result->setCallingConv(convertCConvToLLVM(invOp.getCConv()));
610 if (invOp->getNumResults() != 0) {
617 if (
auto lpOp = dyn_cast<LLVM::LandingpadOp>(opInst)) {
618 llvm::Type *ty = moduleTranslation.
convertType(lpOp.getType());
619 llvm::LandingPadInst *lpi =
620 builder.CreateLandingPad(ty, lpOp.getNumOperands());
621 lpi->setCleanup(lpOp.getCleanup());
624 for (llvm::Value *operand :
627 if (
auto *constOperand = dyn_cast<llvm::Constant>(operand))
628 lpi->addClause(constOperand);
630 moduleTranslation.
mapValue(lpOp.getResult(), lpi);
636 if (
auto brOp = dyn_cast<LLVM::BrOp>(opInst)) {
637 llvm::BranchInst *branch =
638 builder.CreateBr(moduleTranslation.
lookupBlock(brOp.getSuccessor()));
639 moduleTranslation.
mapBranch(&opInst, branch);
643 if (
auto condbrOp = dyn_cast<LLVM::CondBrOp>(opInst)) {
644 llvm::BranchInst *branch = builder.CreateCondBr(
645 moduleTranslation.
lookupValue(condbrOp.getOperand(0)),
646 moduleTranslation.
lookupBlock(condbrOp.getSuccessor(0)),
647 moduleTranslation.
lookupBlock(condbrOp.getSuccessor(1)));
648 moduleTranslation.
mapBranch(&opInst, branch);
652 if (
auto switchOp = dyn_cast<LLVM::SwitchOp>(opInst)) {
653 llvm::SwitchInst *switchInst = builder.CreateSwitch(
654 moduleTranslation.
lookupValue(switchOp.getValue()),
655 moduleTranslation.
lookupBlock(switchOp.getDefaultDestination()),
656 switchOp.getCaseDestinations().size());
659 if (!switchOp.getCaseValues())
662 auto *ty = llvm::cast<llvm::IntegerType>(
663 moduleTranslation.
convertType(switchOp.getValue().getType()));
665 llvm::zip(llvm::cast<DenseIntElementsAttr>(*switchOp.getCaseValues()),
666 switchOp.getCaseDestinations()))
668 llvm::ConstantInt::get(ty, std::get<0>(i).getLimitedValue()),
671 moduleTranslation.
mapBranch(&opInst, switchInst);
674 if (
auto indBrOp = dyn_cast<LLVM::IndirectBrOp>(opInst)) {
675 llvm::IndirectBrInst *indBr = builder.CreateIndirectBr(
677 indBrOp->getNumSuccessors());
678 for (
auto *succ : indBrOp.getSuccessors())
679 indBr->addDestination(moduleTranslation.
lookupBlock(succ));
680 moduleTranslation.
mapBranch(&opInst, indBr);
687 if (
auto addressOfOp = dyn_cast<LLVM::AddressOfOp>(opInst)) {
688 LLVM::GlobalOp global =
689 addressOfOp.getGlobal(moduleTranslation.
symbolTable());
690 LLVM::LLVMFuncOp function =
691 addressOfOp.getFunction(moduleTranslation.
symbolTable());
692 LLVM::AliasOp alias = addressOfOp.getAlias(moduleTranslation.
symbolTable());
693 LLVM::IFuncOp ifunc = addressOfOp.getIFunc(moduleTranslation.
symbolTable());
696 assert((global || function || alias || ifunc) &&
697 "referencing an undefined global, function, alias, or ifunc");
699 llvm::Value *llvmValue =
nullptr;
709 moduleTranslation.
mapValue(addressOfOp.getResult(), llvmValue);
715 if (
auto dsoLocalEquivalentOp =
716 dyn_cast<LLVM::DSOLocalEquivalentOp>(opInst)) {
717 LLVM::LLVMFuncOp function =
718 dsoLocalEquivalentOp.getFunction(moduleTranslation.
symbolTable());
719 LLVM::AliasOp alias =
720 dsoLocalEquivalentOp.getAlias(moduleTranslation.
symbolTable());
723 assert((function || alias) &&
724 "referencing an undefined function, or alias");
726 llvm::Value *llvmValue =
nullptr;
733 dsoLocalEquivalentOp.getResult(),
734 llvm::DSOLocalEquivalent::get(cast<llvm::GlobalValue>(llvmValue)));
740 if (
auto blockAddressOp = dyn_cast<LLVM::BlockAddressOp>(opInst)) {
741 BlockAddressAttr blockAddressAttr = blockAddressOp.getBlockAddr();
742 llvm::BasicBlock *llvmBlock =
745 llvm::Value *llvmValue =
nullptr;
746 StringRef fnName = blockAddressAttr.getFunction().getValue();
748 llvm::Function *llvmFn = moduleTranslation.
lookupFunction(fnName);
749 llvmValue = llvm::BlockAddress::get(llvmFn, llvmBlock);
757 llvmValue =
new llvm::GlobalVariable(
760 true, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
762 Twine(
"__mlir_block_address_")
763 .concat(Twine(fnName))
764 .concat(Twine((uint64_t)blockAddressOp.getOperation())));
768 moduleTranslation.
mapValue(blockAddressOp.getResult(), llvmValue);
774 if (
auto blockTagOp = dyn_cast<LLVM::BlockTagOp>(opInst)) {
775 auto funcOp = blockTagOp->getParentOfType<LLVMFuncOp>();
776 BlockAddressAttr blockAddressAttr = BlockAddressAttr::get(
780 blockTagOp.getTag());
782 builder.GetInsertBlock());