30 #include "llvm/ADT/DepthFirstIterator.h"
31 #include "llvm/ADT/PostOrderIterator.h"
32 #include "llvm/ADT/ScopeExit.h"
33 #include "llvm/ADT/StringExtras.h"
34 #include "llvm/ADT/TypeSwitch.h"
35 #include "llvm/IR/Comdat.h"
36 #include "llvm/IR/Constants.h"
37 #include "llvm/IR/InlineAsm.h"
38 #include "llvm/IR/InstIterator.h"
39 #include "llvm/IR/Instructions.h"
40 #include "llvm/IR/IntrinsicInst.h"
41 #include "llvm/IR/Metadata.h"
42 #include "llvm/IR/Operator.h"
43 #include "llvm/Support/ModRef.h"
50 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
55 static std::string
diag(
const llvm::Value &value) {
57 llvm::raw_string_ostream os(str);
65 static std::string
diagMD(
const llvm::Metadata *node,
66 const llvm::Module *module) {
68 llvm::raw_string_ostream os(str);
69 node->print(os, module,
true);
75 return "llvm.global_ctors";
80 return "mlir.llvm.nameless_global";
85 return "llvm.global_dtors";
91 return "__llvm_global_comdat";
100 std::optional<llvm::SyncScope::ID> syncScopeID =
101 llvm::getAtomicSyncScopeID(inst);
108 llvm::LLVMContext &llvmContext = inst->getContext();
109 llvmContext.getSyncScopeNames(syncScopeName);
110 auto *it = llvm::find_if(syncScopeName, [&](StringRef name) {
111 return *syncScopeID == llvmContext.getOrInsertSyncScopeID(name);
113 if (it != syncScopeName.end())
115 llvm_unreachable(
"incorrect sync scope identifier");
121 llvm::append_range(position, indices);
132 llvm::Instruction *inst,
145 #include "mlir/Dialect/LLVMIR/LLVMOpFromLLVMIRConversions.inc"
154 for (llvm::BasicBlock *basicBlock : basicBlocks) {
155 if (!blocks.contains(basicBlock)) {
156 llvm::ReversePostOrderTraversal<llvm::BasicBlock *> traversal(basicBlock);
157 blocks.insert_range(traversal);
160 assert(blocks.size() == basicBlocks.size() &&
"some blocks are not sorted");
165 std::unique_ptr<llvm::Module> llvmModule,
166 bool emitExpensiveWarnings,
167 bool importEmptyDICompositeTypes,
168 bool preferUnregisteredIntrinsics,
169 bool importStructsAsLiterals)
171 mlirModule(mlirModule), llvmModule(std::move(llvmModule)),
173 typeTranslator(*mlirModule->
getContext(), importStructsAsLiterals),
175 mlirModule, importEmptyDICompositeTypes)),
176 loopAnnotationImporter(
178 emitExpensiveWarnings(emitExpensiveWarnings),
179 preferUnregisteredIntrinsics(preferUnregisteredIntrinsics) {
183 ComdatOp ModuleImport::getGlobalComdatOp() {
185 return globalComdatOp;
191 globalInsertionOp = globalComdatOp;
192 return globalComdatOp;
195 LogicalResult ModuleImport::processTBAAMetadata(
const llvm::MDNode *node) {
200 auto getIdentityIfRootNode =
201 [&](
const llvm::MDNode *node) -> FailureOr<std::optional<StringRef>> {
205 if (node->getNumOperands() > 1)
208 if (node->getNumOperands() == 1)
209 if (
const auto *op0 = dyn_cast<const llvm::MDString>(node->getOperand(0)))
210 return std::optional<StringRef>{op0->getString()};
211 return std::optional<StringRef>{};
221 auto isTypeDescriptorNode = [&](
const llvm::MDNode *node,
222 StringRef *identity =
nullptr,
224 nullptr) -> std::optional<bool> {
225 unsigned numOperands = node->getNumOperands();
234 const auto *identityNode =
235 dyn_cast<const llvm::MDString>(node->getOperand(0));
241 *identity = identityNode->getString();
243 for (
unsigned pairNum = 0, e = numOperands / 2; pairNum < e; ++pairNum) {
244 const auto *memberNode =
245 dyn_cast<const llvm::MDNode>(node->getOperand(2 * pairNum + 1));
247 emitError(loc) <<
"operand '" << 2 * pairNum + 1 <<
"' must be MDNode: "
248 <<
diagMD(node, llvmModule.get());
252 if (2 * pairNum + 2 >= numOperands) {
254 if (numOperands != 2) {
255 emitError(loc) <<
"missing member offset: "
256 <<
diagMD(node, llvmModule.get());
260 auto *offsetCI = llvm::mdconst::dyn_extract<llvm::ConstantInt>(
261 node->getOperand(2 * pairNum + 2));
263 emitError(loc) <<
"operand '" << 2 * pairNum + 2
264 <<
"' must be ConstantInt: "
265 <<
diagMD(node, llvmModule.get());
268 offset = offsetCI->getZExtValue();
273 cast<TBAANodeAttr>(tbaaMapping.lookup(memberNode)), offset));
286 auto isTagNode = [&](
const llvm::MDNode *node,
287 TBAATypeDescriptorAttr *baseAttr =
nullptr,
288 TBAATypeDescriptorAttr *accessAttr =
nullptr,
289 int64_t *offset =
nullptr,
290 bool *isConstant =
nullptr) -> std::optional<bool> {
298 unsigned numOperands = node->getNumOperands();
299 if (numOperands != 3 && numOperands != 4)
301 const auto *baseMD = dyn_cast<const llvm::MDNode>(node->getOperand(0));
302 const auto *accessMD = dyn_cast<const llvm::MDNode>(node->getOperand(1));
304 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(2));
305 if (!baseMD || !accessMD || !offsetCI)
312 if (accessMD->getNumOperands() < 1 ||
313 !isa<llvm::MDString>(accessMD->getOperand(0)))
315 bool isConst =
false;
316 if (numOperands == 4) {
318 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(3));
320 emitError(loc) <<
"operand '3' must be ConstantInt: "
321 <<
diagMD(node, llvmModule.get());
324 isConst = isConstantCI->getValue()[0];
327 *baseAttr = cast<TBAATypeDescriptorAttr>(tbaaMapping.lookup(baseMD));
329 *accessAttr = cast<TBAATypeDescriptorAttr>(tbaaMapping.lookup(accessMD));
331 *offset = offsetCI->getZExtValue();
333 *isConstant = isConst;
342 workList.push_back(node);
343 while (!workList.empty()) {
344 const llvm::MDNode *current = workList.back();
345 if (tbaaMapping.contains(current)) {
354 bool anyChildNotConverted =
false;
355 for (
const llvm::MDOperand &operand : current->operands())
356 if (
auto *childNode = dyn_cast_or_null<const llvm::MDNode>(operand.get()))
357 if (!tbaaMapping.contains(childNode)) {
358 workList.push_back(childNode);
359 anyChildNotConverted =
true;
362 if (anyChildNotConverted) {
367 if (!seen.insert(current).second)
368 return emitError(loc) <<
"has cycle in TBAA graph: "
369 <<
diagMD(current, llvmModule.get());
377 FailureOr<std::optional<StringRef>> rootNodeIdentity =
378 getIdentityIfRootNode(current);
379 if (succeeded(rootNodeIdentity)) {
380 StringAttr stringAttr = *rootNodeIdentity
385 tbaaMapping.insert({current, builder.
getAttr<TBAARootAttr>(stringAttr)});
391 if (std::optional<bool> isValid =
392 isTypeDescriptorNode(current, &identity, &members)) {
393 assert(isValid.value() &&
"type descriptor node must be valid");
395 tbaaMapping.insert({current, builder.
getAttr<TBAATypeDescriptorAttr>(
396 identity, members)});
400 TBAATypeDescriptorAttr baseAttr, accessAttr;
403 if (std::optional<bool> isValid =
404 isTagNode(current, &baseAttr, &accessAttr, &offset, &isConstant)) {
405 assert(isValid.value() &&
"access tag node must be valid");
407 {current, builder.
getAttr<TBAATagAttr>(baseAttr, accessAttr, offset,
412 return emitError(loc) <<
"unsupported TBAA node format: "
413 <<
diagMD(current, llvmModule.get());
419 ModuleImport::processAccessGroupMetadata(
const llvm::MDNode *node) {
421 if (
failed(loopAnnotationImporter->translateAccessGroup(node, loc)))
422 return emitError(loc) <<
"unsupported access group node: "
423 <<
diagMD(node, llvmModule.get());
428 ModuleImport::processAliasScopeMetadata(
const llvm::MDNode *node) {
431 auto verifySelfRef = [](
const llvm::MDNode *node) {
432 return node->getNumOperands() != 0 &&
433 node == dyn_cast<llvm::MDNode>(node->getOperand(0));
435 auto verifySelfRefOrString = [](
const llvm::MDNode *node) {
436 return node->getNumOperands() != 0 &&
437 (node == dyn_cast<llvm::MDNode>(node->getOperand(0)) ||
438 isa<llvm::MDString>(node->getOperand(0)));
441 auto verifyDescription = [](
const llvm::MDNode *node,
unsigned idx) {
442 return idx >= node->getNumOperands() ||
443 isa<llvm::MDString>(node->getOperand(idx));
446 auto getIdAttr = [&](
const llvm::MDNode *node) ->
Attribute {
447 if (verifySelfRef(node))
450 auto name = cast<llvm::MDString>(node->getOperand(0));
455 auto createAliasScopeDomainOp = [&](
const llvm::MDNode *aliasDomain) {
456 StringAttr description =
nullptr;
457 if (aliasDomain->getNumOperands() >= 2)
458 if (
auto *operand = dyn_cast<llvm::MDString>(aliasDomain->getOperand(1)))
460 Attribute idAttr = getIdAttr(aliasDomain);
461 return builder.
getAttr<AliasScopeDomainAttr>(idAttr, description);
465 for (
const llvm::MDOperand &operand : node->operands()) {
466 if (
const auto *scope = dyn_cast<llvm::MDNode>(operand)) {
467 llvm::AliasScopeNode aliasScope(scope);
468 const llvm::MDNode *domain = aliasScope.getDomain();
474 if (!verifySelfRefOrString(scope) || !domain ||
475 !verifyDescription(scope, 2))
476 return emitError(loc) <<
"unsupported alias scope node: "
477 <<
diagMD(scope, llvmModule.get());
478 if (!verifySelfRefOrString(domain) || !verifyDescription(domain, 1))
479 return emitError(loc) <<
"unsupported alias domain node: "
480 <<
diagMD(domain, llvmModule.get());
482 if (aliasScopeMapping.contains(scope))
486 auto it = aliasScopeMapping.find(aliasScope.getDomain());
487 if (it == aliasScopeMapping.end()) {
488 auto aliasScopeDomainOp = createAliasScopeDomainOp(domain);
489 it = aliasScopeMapping.try_emplace(domain, aliasScopeDomainOp).first;
493 StringAttr description =
nullptr;
494 if (!aliasScope.getName().empty())
497 auto aliasScopeOp = builder.
getAttr<AliasScopeAttr>(
498 idAttr, cast<AliasScopeDomainAttr>(it->second), description);
500 aliasScopeMapping.try_emplace(aliasScope.getNode(), aliasScopeOp);
506 FailureOr<SmallVector<AliasScopeAttr>>
509 aliasScopes.reserve(node->getNumOperands());
510 for (
const llvm::MDOperand &operand : node->operands()) {
511 auto *node = cast<llvm::MDNode>(operand.get());
512 aliasScopes.push_back(
513 dyn_cast_or_null<AliasScopeAttr>(aliasScopeMapping.lookup(node)));
516 if (llvm::is_contained(aliasScopes,
nullptr))
522 debugIntrinsics.insert(intrinsic);
526 llvm::MDTuple *mdTuple) {
527 auto getLLVMFunction =
528 [&](
const llvm::MDOperand &funcMDO) -> llvm::Function * {
529 auto *f = cast_or_null<llvm::ValueAsMetadata>(funcMDO);
533 auto *llvmFn = cast<llvm::Function>(f->getValue()->stripPointerCasts());
539 for (
unsigned i = 0; i < mdTuple->getNumOperands(); i++) {
540 const llvm::MDOperand &mdo = mdTuple->getOperand(i);
541 auto *cgEntry = cast<llvm::MDNode>(mdo);
542 llvm::Constant *llvmConstant =
543 cast<llvm::ConstantAsMetadata>(cgEntry->getOperand(2))->getValue();
544 uint64_t count = cast<llvm::ConstantInt>(llvmConstant)->getZExtValue();
545 auto *fromFn = getLLVMFunction(cgEntry->getOperand(0));
546 auto *toFn = getLLVMFunction(cgEntry->getOperand(1));
549 mlirModule->getContext(),
563 const llvm::Module *llvmModule,
564 const llvm::MDOperand &md) {
565 auto *tupleEntry = dyn_cast_or_null<llvm::MDTuple>(md);
566 if (!tupleEntry || tupleEntry->getNumOperands() != 2)
568 <<
"expected 2-element tuple metadata: " <<
diagMD(md, llvmModule);
576 ModuleOp mlirModule,
const llvm::Module *llvmModule,
577 const llvm::MDOperand &md, StringRef matchKey,
bool optional =
false) {
581 auto *keyMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(0));
582 if (!keyMD || keyMD->getString() != matchKey) {
585 <<
"expected '" << matchKey <<
"' key, but found: "
586 <<
diagMD(tupleEntry->getOperand(0), llvmModule);
590 return dyn_cast<llvm::ConstantAsMetadata>(tupleEntry->getOperand(1));
596 static FailureOr<uint64_t>
598 const llvm::Module *llvmModule,
599 const llvm::MDOperand &md, StringRef matchKey) {
600 llvm::ConstantAsMetadata *valMD =
605 if (
auto *cstInt = dyn_cast<llvm::ConstantInt>(valMD->getValue()))
606 return cstInt->getZExtValue();
609 <<
"expected integer metadata value for key '" << matchKey
610 <<
"': " <<
diagMD(md, llvmModule);
614 static std::optional<ProfileSummaryFormatKind>
616 const llvm::MDOperand &formatMD) {
621 llvm::MDString *keyMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(0));
622 if (!keyMD || keyMD->getString() !=
"ProfileFormat") {
624 <<
"expected 'ProfileFormat' key: "
625 <<
diagMD(tupleEntry->getOperand(0), llvmModule);
629 llvm::MDString *valMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(1));
630 std::optional<ProfileSummaryFormatKind> fmtKind =
631 symbolizeProfileSummaryFormatKind(valMD->getString());
634 <<
"expected 'SampleProfile', 'InstrProf' or 'CSInstrProf' values, "
636 <<
diagMD(valMD, llvmModule);
643 static FailureOr<SmallVector<ModuleFlagProfileSummaryDetailedAttr>>
645 const llvm::Module *llvmModule,
646 const llvm::MDOperand &summaryMD) {
651 llvm::MDString *keyMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(0));
652 if (!keyMD || keyMD->getString() !=
"DetailedSummary") {
654 <<
"expected 'DetailedSummary' key: "
655 <<
diagMD(tupleEntry->getOperand(0), llvmModule);
659 llvm::MDTuple *entriesMD = dyn_cast<llvm::MDTuple>(tupleEntry->getOperand(1));
662 <<
"expected tuple value for 'DetailedSummary' key: "
663 <<
diagMD(tupleEntry->getOperand(1), llvmModule);
668 for (
auto &&entry : entriesMD->operands()) {
669 llvm::MDTuple *entryMD = dyn_cast<llvm::MDTuple>(entry);
670 if (!entryMD || entryMD->getNumOperands() != 3) {
672 <<
"'DetailedSummary' entry expects 3 operands: "
673 <<
diagMD(entry, llvmModule);
677 auto *op0 = dyn_cast<llvm::ConstantAsMetadata>(entryMD->getOperand(0));
678 auto *op1 = dyn_cast<llvm::ConstantAsMetadata>(entryMD->getOperand(1));
679 auto *op2 = dyn_cast<llvm::ConstantAsMetadata>(entryMD->getOperand(2));
680 if (!op0 || !op1 || !op2) {
682 <<
"expected only integer entries in 'DetailedSummary': "
683 <<
diagMD(entry, llvmModule);
688 mlirModule->getContext(),
689 cast<llvm::ConstantInt>(op0->getValue())->getZExtValue(),
690 cast<llvm::ConstantInt>(op1->getValue())->getZExtValue(),
691 cast<llvm::ConstantInt>(op2->getValue())->getZExtValue());
692 detailedSummary.push_back(detaildSummaryEntry);
694 return detailedSummary;
699 const llvm::Module *llvmModule,
700 llvm::MDTuple *mdTuple) {
701 unsigned profileNumEntries = mdTuple->getNumOperands();
702 if (profileNumEntries < 8) {
704 <<
"expected at 8 entries in 'ProfileSummary': "
705 <<
diagMD(mdTuple, llvmModule);
709 unsigned summayIdx = 0;
710 auto checkOptionalPosition = [&](
const llvm::MDOperand &md,
711 StringRef matchKey) -> LogicalResult {
715 if (summayIdx + 1 >= profileNumEntries) {
717 <<
"the last summary entry is '" << matchKey
718 <<
"', expected 'DetailedSummary': " <<
diagMD(md, llvmModule);
725 auto getOptIntValue =
726 [&](
const llvm::MDOperand &md,
727 StringRef matchKey) -> FailureOr<std::optional<uint64_t>> {
730 return FailureOr<std::optional<uint64_t>>(std::nullopt);
731 if (checkOptionalPosition(md, matchKey).failed())
733 FailureOr<uint64_t> val =
740 auto getOptDoubleValue = [&](
const llvm::MDOperand &md,
741 StringRef matchKey) -> FailureOr<FloatAttr> {
746 if (
auto *cstFP = dyn_cast<llvm::ConstantFP>(valMD->getValue())) {
747 if (checkOptionalPosition(md, matchKey).
failed())
750 cstFP->getValueAPF());
753 <<
"expected double metadata value for key '" << matchKey
754 <<
"': " <<
diagMD(md, llvmModule);
761 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++));
762 if (!format.has_value())
766 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
"TotalCount");
771 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
"MaxCount");
776 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
778 if (
failed(maxInternalCount))
782 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
784 if (
failed(maxFunctionCount))
788 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
"NumCounts");
793 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
"NumFunctions");
798 FailureOr<std::optional<uint64_t>> isPartialProfile =
799 getOptIntValue(mdTuple->getOperand(summayIdx),
"IsPartialProfile");
800 if (
failed(isPartialProfile))
802 if (isPartialProfile->has_value())
805 FailureOr<FloatAttr> partialProfileRatio =
806 getOptDoubleValue(mdTuple->getOperand(summayIdx),
"PartialProfileRatio");
807 if (
failed(partialProfileRatio))
809 if (*partialProfileRatio)
813 FailureOr<SmallVector<ModuleFlagProfileSummaryDetailedAttr>> detailed =
815 mdTuple->getOperand(summayIdx));
821 mlirModule->getContext(), *format, *totalCount, *maxCount,
822 *maxInternalCount, *maxFunctionCount, *numCounts, *numFunctions,
823 *isPartialProfile, *partialProfileRatio, *detailed);
830 const llvm::Module *llvmModule, StringRef key,
831 llvm::MDTuple *mdTuple) {
832 if (key == LLVMDialect::getModuleFlagKeyCGProfileName())
834 if (key == LLVMDialect::getModuleFlagKeyProfileSummaryName())
842 llvmModule->getModuleFlagsMetadata(llvmModuleFlags);
845 for (
const auto [behavior, key, val] : llvmModuleFlags) {
847 if (
auto *constInt = llvm::mdconst::dyn_extract<llvm::ConstantInt>(val)) {
849 }
else if (
auto *mdString = dyn_cast<llvm::MDString>(val)) {
851 }
else if (
auto *mdTuple = dyn_cast<llvm::MDTuple>(val)) {
853 key->getString(), mdTuple);
858 <<
"unsupported module flag value for key '" << key->getString()
859 <<
"' : " <<
diagMD(val, llvmModule.get());
863 moduleFlags.push_back(builder.
getAttr<ModuleFlagAttr>(
864 convertModFlagBehaviorFromLLVM(behavior),
868 if (!moduleFlags.empty())
869 LLVM::ModuleFlagsOp::create(builder, mlirModule.getLoc(),
876 for (
const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
877 if (named.getName() !=
"llvm.linker.options")
880 for (
const llvm::MDNode *node : named.operands()) {
882 options.reserve(node->getNumOperands());
883 for (
const llvm::MDOperand &option : node->operands())
884 options.push_back(cast<llvm::MDString>(option)->getString());
885 LLVM::LinkerOptionsOp::create(builder, mlirModule.getLoc(),
893 for (
const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
894 if (named.getName() !=
"llvm.dependent-libraries")
897 for (
const llvm::MDNode *node : named.operands()) {
898 if (node->getNumOperands() == 1)
899 if (
auto *mdString = dyn_cast<llvm::MDString>(node->getOperand(0)))
900 libraries.push_back(mdString->getString());
902 if (!libraries.empty())
903 mlirModule->setAttr(LLVM::LLVMDialect::getDependentLibrariesAttrName(),
910 for (
const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
913 if (named.getName() != LLVMDialect::getIdentAttrName())
916 if (named.getNumOperands() == 1)
917 if (
auto *md = dyn_cast<llvm::MDNode>(named.getOperand(0)))
918 if (md->getNumOperands() == 1)
919 if (
auto *mdStr = dyn_cast<llvm::MDString>(md->getOperand(0)))
920 mlirModule->setAttr(LLVMDialect::getIdentAttrName(),
927 for (
const llvm::NamedMDNode &nmd : llvmModule->named_metadata()) {
930 if (nmd.getName() != LLVMDialect::getCommandlineAttrName())
933 if (nmd.getNumOperands() == 1)
934 if (
auto *md = dyn_cast<llvm::MDNode>(nmd.getOperand(0)))
935 if (md->getNumOperands() == 1)
936 if (
auto *mdStr = dyn_cast<llvm::MDString>(md->getOperand(0)))
937 mlirModule->setAttr(LLVMDialect::getCommandlineAttrName(),
946 for (
const llvm::Function &func : llvmModule->functions()) {
947 for (
const llvm::Instruction &inst : llvm::instructions(func)) {
949 if (llvm::MDNode *node =
950 inst.getMetadata(llvm::LLVMContext::MD_access_group))
951 if (
failed(processAccessGroupMetadata(node)))
955 llvm::AAMDNodes aliasAnalysisNodes = inst.getAAMetadata();
956 if (!aliasAnalysisNodes)
958 if (aliasAnalysisNodes.TBAA)
959 if (
failed(processTBAAMetadata(aliasAnalysisNodes.TBAA)))
961 if (aliasAnalysisNodes.Scope)
962 if (
failed(processAliasScopeMetadata(aliasAnalysisNodes.Scope)))
964 if (aliasAnalysisNodes.NoAlias)
965 if (
failed(processAliasScopeMetadata(aliasAnalysisNodes.NoAlias)))
982 void ModuleImport::processComdat(
const llvm::Comdat *comdat) {
983 if (comdatMapping.contains(comdat))
986 ComdatOp comdatOp = getGlobalComdatOp();
989 auto selectorOp = ComdatSelectorOp::create(
990 builder, mlirModule.getLoc(), comdat->getName(),
991 convertComdatFromLLVM(comdat->getSelectionKind()));
995 comdatMapping.try_emplace(comdat, symbolRef);
999 for (llvm::GlobalVariable &globalVar : llvmModule->globals())
1000 if (globalVar.hasComdat())
1001 processComdat(globalVar.getComdat());
1002 for (llvm::Function &func : llvmModule->functions())
1003 if (func.hasComdat())
1004 processComdat(func.getComdat());
1009 for (llvm::GlobalVariable &globalVar : llvmModule->globals()) {
1012 if (
failed(convertGlobalCtorsAndDtors(&globalVar))) {
1014 <<
"unhandled global variable: " <<
diag(globalVar);
1018 if (
failed(convertGlobal(&globalVar))) {
1020 <<
"unhandled global variable: " <<
diag(globalVar);
1027 for (llvm::GlobalAlias &alias : llvmModule->aliases()) {
1028 if (
failed(convertAlias(&alias))) {
1030 <<
"unhandled global alias: " <<
diag(alias);
1037 for (llvm::GlobalIFunc &ifunc : llvmModule->ifuncs()) {
1038 if (
failed(convertIFunc(&ifunc))) {
1040 <<
"unhandled global ifunc: " <<
diag(ifunc);
1047 Location loc = mlirModule.getLoc();
1049 context, llvmModule->getDataLayout().getStringRepresentation());
1051 return emitError(loc,
"cannot translate data layout: ")
1055 emitWarning(loc,
"unhandled data layout token: ") << token;
1057 mlirModule->setAttr(DLTIDialect::kDataLayoutAttrName,
1063 mlirModule->setAttr(
1064 LLVM::LLVMDialect::getTargetTripleAttrName(),
1065 builder.
getStringAttr(llvmModule->getTargetTriple().str()));
1069 llvm::StringRef asmStr = llvmModule->getModuleInlineAsm();
1072 for (llvm::StringRef line : llvm::split(asmStr,
'\n'))
1076 mlirModule->setAttr(LLVM::LLVMDialect::getModuleLevelAsmAttrName(),
1081 for (llvm::Function &func : llvmModule->functions())
1087 void ModuleImport::setNonDebugMetadataAttrs(llvm::Instruction *inst,
1090 inst->getAllMetadataOtherThanDebugLoc(allMetadata);
1091 for (
auto &[
kind, node] : allMetadata) {
1095 if (emitExpensiveWarnings) {
1096 Location loc = debugImporter->translateLoc(inst->getDebugLoc());
1098 <<
diagMD(node, llvmModule.get()) <<
" on "
1107 auto iface = cast<IntegerOverflowFlagsInterface>(op);
1109 IntegerOverflowFlags value = {};
1110 value = bitEnumSet(value, IntegerOverflowFlags::nsw, inst->hasNoSignedWrap());
1112 bitEnumSet(value, IntegerOverflowFlags::nuw, inst->hasNoUnsignedWrap());
1114 iface.setOverflowFlags(value);
1118 auto iface = cast<ExactFlagInterface>(op);
1120 iface.setIsExact(inst->isExact());
1125 auto iface = cast<DisjointFlagInterface>(op);
1126 auto instDisjoint = cast<llvm::PossiblyDisjointInst>(inst);
1128 iface.setIsDisjoint(instDisjoint->isDisjoint());
1132 auto iface = cast<NonNegFlagInterface>(op);
1134 iface.setNonNeg(inst->hasNonNeg());
1139 auto iface = cast<FastmathFlagsInterface>(op);
1145 if (!isa<llvm::FPMathOperator>(inst))
1147 llvm::FastMathFlags flags = inst->getFastMathFlags();
1150 FastmathFlags value = {};
1151 value = bitEnumSet(value, FastmathFlags::nnan, flags.noNaNs());
1152 value = bitEnumSet(value, FastmathFlags::ninf, flags.noInfs());
1153 value = bitEnumSet(value, FastmathFlags::nsz, flags.noSignedZeros());
1154 value = bitEnumSet(value, FastmathFlags::arcp, flags.allowReciprocal());
1156 value = bitEnumSet(value, FastmathFlags::afn, flags.approxFunc());
1157 value = bitEnumSet(value, FastmathFlags::reassoc, flags.allowReassoc());
1159 iface->setAttr(iface.getFastmathAttrName(), attr);
1171 if (numElements.isScalable()) {
1173 <<
"scalable vectors not supported";
1178 Type elementType = cast<VectorType>(type).getElementType();
1183 shape.push_back(numElements.getKnownMinValue());
1187 Type ModuleImport::getBuiltinTypeForAttr(
Type type) {
1202 while (
auto arrayType = dyn_cast<LLVMArrayType>(type)) {
1203 arrayShape.push_back(arrayType.getNumElements());
1204 type = arrayType.getElementType();
1214 llvm::Constant *constScalar) {
1218 if (
auto *constInt = dyn_cast<llvm::ConstantInt>(constScalar)) {
1221 constInt->getValue());
1225 if (
auto *constFloat = dyn_cast<llvm::ConstantFP>(constScalar)) {
1226 llvm::Type *type = constFloat->getType();
1227 FloatType floatType =
1233 <<
"unexpected floating-point type";
1236 return builder.
getFloatAttr(floatType, constFloat->getValueAPF());
1245 llvm::ConstantDataSequential *constSequence) {
1247 elementAttrs.reserve(constSequence->getNumElements());
1248 for (
auto idx : llvm::seq<int64_t>(0, constSequence->getNumElements())) {
1249 llvm::Constant *constElement = constSequence->getElementAsConstant(idx);
1252 return elementAttrs;
1255 Attribute ModuleImport::getConstantAsAttr(llvm::Constant *constant) {
1261 auto getConstantShape = [&](llvm::Type *type) {
1262 return llvm::dyn_cast_if_present<ShapedType>(
1268 if (
auto *constArray = dyn_cast<llvm::ConstantDataSequential>(constant)) {
1269 if (constArray->isString())
1271 auto shape = getConstantShape(constArray->getType());
1275 auto *constVector = dyn_cast<llvm::ConstantDataVector>(constant);
1276 if (constVector && constVector->isSplat()) {
1279 builder, constVector->getElementAsConstant(0));
1290 if (
auto *constAggregate = dyn_cast<llvm::ConstantAggregate>(constant)) {
1291 auto shape = getConstantShape(constAggregate->getType());
1297 while (!workList.empty()) {
1298 llvm::Constant *current = workList.pop_back_val();
1301 if (
auto *constAggregate = dyn_cast<llvm::ConstantAggregate>(current)) {
1303 reverse(llvm::seq<int64_t>(0, constAggregate->getNumOperands())))
1304 workList.push_back(constAggregate->getAggregateElement(idx));
1309 if (
auto *constArray = dyn_cast<llvm::ConstantDataSequential>(current)) {
1312 elementAttrs.append(attrs.begin(), attrs.end());
1318 elementAttrs.push_back(scalarAttr);
1329 if (
auto *constZero = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1330 auto shape = llvm::dyn_cast_if_present<ShapedType>(
1331 getBuiltinTypeForAttr(
convertType(constZero->getType())));
1336 assert(splatAttr &&
"expected non-null zero attribute for scalar types");
1343 ModuleImport::getOrCreateNamelessSymbolName(llvm::GlobalVariable *globalVar) {
1344 assert(globalVar->getName().empty() &&
1345 "expected to work with a nameless global");
1346 auto [it, success] = namelessGlobals.try_emplace(globalVar);
1353 [
this](StringRef newName) {
return llvmModule->getNamedValue(newName); },
1356 it->getSecond() = symbolRef;
1362 if (globalInsertionOp)
1369 LogicalResult ModuleImport::convertAlias(llvm::GlobalAlias *alias) {
1374 AliasOp aliasOp = AliasOp::create(builder, mlirModule.getLoc(), type,
1375 convertLinkageFromLLVM(alias->getLinkage()),
1377 alias->isDSOLocal(),
1378 alias->isThreadLocal(),
1380 globalInsertionOp = aliasOp;
1384 setConstantInsertionPointToStart(block);
1385 FailureOr<Value> initializer = convertConstantExpr(alias->getAliasee());
1388 ReturnOp::create(builder, aliasOp.getLoc(), *initializer);
1390 if (alias->hasAtLeastLocalUnnamedAddr())
1391 aliasOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(alias->getUnnamedAddr()));
1392 aliasOp.setVisibility_(convertVisibilityFromLLVM(alias->getVisibility()));
1397 LogicalResult ModuleImport::convertIFunc(llvm::GlobalIFunc *ifunc) {
1401 llvm::Constant *resolver = ifunc->getResolver();
1403 IFuncOp::create(builder, mlirModule.getLoc(), ifunc->getName(), type,
1404 resolver->getName(), resolverType,
1405 convertLinkageFromLLVM(ifunc->getLinkage()),
1406 ifunc->isDSOLocal(), ifunc->getAddressSpace(),
1407 convertUnnamedAddrFromLLVM(ifunc->getUnnamedAddr()),
1408 convertVisibilityFromLLVM(ifunc->getVisibility()));
1412 LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
1417 if (globalVar->hasInitializer())
1418 valueAttr = getConstantAsAttr(globalVar->getInitializer());
1421 uint64_t alignment = 0;
1422 llvm::MaybeAlign maybeAlign = globalVar->getAlign();
1423 if (maybeAlign.has_value()) {
1424 llvm::Align align = *maybeAlign;
1425 alignment = align.value();
1432 globalVar->getDebugInfo(globalExpressions);
1434 for (llvm::DIGlobalVariableExpression *expr : globalExpressions) {
1435 DIGlobalVariableExpressionAttr globalExpressionAttr =
1436 debugImporter->translateGlobalVariableExpression(expr);
1437 globalExpressionAttrs.push_back(globalExpressionAttr);
1442 StringRef globalName = globalVar->getName();
1443 if (globalName.empty())
1444 globalName = getOrCreateNamelessSymbolName(globalVar).
getValue();
1446 GlobalOp globalOp = GlobalOp::create(
1447 builder, mlirModule.getLoc(), type, globalVar->isConstant(),
1448 convertLinkageFromLLVM(globalVar->getLinkage()), StringRef(globalName),
1449 valueAttr, alignment, globalVar->getAddressSpace(),
1450 globalVar->isDSOLocal(),
1451 globalVar->isThreadLocal(), SymbolRefAttr(),
1453 globalInsertionOp = globalOp;
1455 if (globalVar->hasInitializer() && !valueAttr) {
1458 setConstantInsertionPointToStart(block);
1459 FailureOr<Value> initializer =
1460 convertConstantExpr(globalVar->getInitializer());
1463 ReturnOp::create(builder, globalOp.getLoc(), *initializer);
1465 if (globalVar->hasAtLeastLocalUnnamedAddr()) {
1466 globalOp.setUnnamedAddr(
1467 convertUnnamedAddrFromLLVM(globalVar->getUnnamedAddr()));
1469 if (globalVar->hasSection())
1470 globalOp.setSection(globalVar->getSection());
1471 globalOp.setVisibility_(
1472 convertVisibilityFromLLVM(globalVar->getVisibility()));
1474 if (globalVar->hasComdat())
1475 globalOp.setComdatAttr(comdatMapping.lookup(globalVar->getComdat()));
1481 ModuleImport::convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar) {
1482 if (!globalVar->hasInitializer() || !globalVar->hasAppendingLinkage())
1484 llvm::Constant *initializer = globalVar->getInitializer();
1486 bool knownInit = isa<llvm::ConstantArray>(initializer) ||
1487 isa<llvm::ConstantAggregateZero>(initializer);
1494 if (
auto *caz = dyn_cast<llvm::ConstantAggregateZero>(initializer)) {
1495 if (caz->getElementCount().getFixedValue() != 0)
1502 for (llvm::Value *operand : initializer->operands()) {
1503 auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
1504 if (!aggregate || aggregate->getNumOperands() != 3)
1507 auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
1508 auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
1509 auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
1510 if (!priority || !func || !data)
1513 auto *gv = dyn_cast_or_null<llvm::GlobalValue>(data);
1517 else if (data->isNullValue())
1523 priorities.push_back(priority->getValue().getZExtValue());
1524 dataList.push_back(dataAttr);
1531 globalInsertionOp = LLVM::GlobalCtorsOp::create(
1532 builder, mlirModule.getLoc(), builder.
getArrayAttr(funcs),
1536 globalInsertionOp = LLVM::GlobalDtorsOp::create(
1537 builder, mlirModule.getLoc(), builder.
getArrayAttr(funcs),
1543 ModuleImport::getConstantsToConvert(llvm::Constant *constant) {
1545 if (valueMapping.contains(constant))
1554 workList.insert(constant);
1555 while (!workList.empty()) {
1556 llvm::Constant *current = workList.back();
1559 if (isa<llvm::GlobalObject>(current) || isa<llvm::GlobalAlias>(current)) {
1560 orderedSet.insert(current);
1561 workList.pop_back();
1567 auto [adjacencyIt, inserted] = adjacencyLists.try_emplace(current);
1571 for (llvm::Value *operand : current->operands())
1572 if (
auto *constDependency = dyn_cast<llvm::Constant>(operand))
1573 adjacencyIt->getSecond().push_back(constDependency);
1576 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(current)) {
1577 unsigned numElements = constAgg->getElementCount().getFixedValue();
1578 for (
unsigned i = 0, e = numElements; i != e; ++i)
1579 adjacencyIt->getSecond().push_back(constAgg->getElementValue(i));
1585 if (adjacencyIt->getSecond().empty()) {
1586 orderedSet.insert(current);
1587 workList.pop_back();
1595 llvm::Constant *dependency = adjacencyIt->getSecond().pop_back_val();
1596 if (valueMapping.contains(dependency) || workList.contains(dependency) ||
1597 orderedSet.contains(dependency))
1599 workList.insert(dependency);
1605 FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
1609 if (
Attribute attr = getConstantAsAttr(constant)) {
1611 if (
auto symbolRef = dyn_cast<FlatSymbolRefAttr>(attr)) {
1612 return AddressOfOp::create(builder, loc, type, symbolRef.getValue())
1615 return ConstantOp::create(builder, loc, type, attr).getResult();
1619 if (
auto *nullPtr = dyn_cast<llvm::ConstantPointerNull>(constant)) {
1621 return ZeroOp::create(builder, loc, type).getResult();
1625 if (isa<llvm::ConstantTokenNone>(constant)) {
1626 return NoneTokenOp::create(builder, loc).getResult();
1630 if (
auto *poisonVal = dyn_cast<llvm::PoisonValue>(constant)) {
1632 return PoisonOp::create(builder, loc, type).getResult();
1636 if (
auto *undefVal = dyn_cast<llvm::UndefValue>(constant)) {
1638 return UndefOp::create(builder, loc, type).getResult();
1642 if (
auto *dsoLocalEquivalent = dyn_cast<llvm::DSOLocalEquivalent>(constant)) {
1644 return DSOLocalEquivalentOp::create(
1648 dsoLocalEquivalent->getGlobalValue()->getName()))
1653 if (
auto *globalObj = dyn_cast<llvm::GlobalObject>(constant)) {
1655 StringRef globalName = globalObj->getName();
1658 if (globalName.empty())
1660 getOrCreateNamelessSymbolName(cast<llvm::GlobalVariable>(globalObj));
1663 return AddressOfOp::create(builder, loc, type, symbolRef).getResult();
1667 if (
auto *globalAliasObj = dyn_cast<llvm::GlobalAlias>(constant)) {
1669 StringRef aliaseeName = globalAliasObj->getName();
1671 return AddressOfOp::create(builder, loc, type, symbolRef).getResult();
1675 if (
auto *constExpr = dyn_cast<llvm::ConstantExpr>(constant)) {
1681 llvm::Instruction *inst = constExpr->getAsInstruction();
1682 auto guard = llvm::make_scope_exit([&]() {
1683 assert(!noResultOpMapping.contains(inst) &&
1684 "expected constant expression to return a result");
1685 valueMapping.erase(inst);
1686 inst->deleteValue();
1690 assert(llvm::all_of(inst->operands(), [&](llvm::Value *value) {
1691 return valueMapping.contains(value);
1693 if (
failed(processInstruction(inst)))
1699 if (isa<llvm::ConstantAggregate>(constant) ||
1700 isa<llvm::ConstantAggregateZero>(constant)) {
1703 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregate>(constant)) {
1704 elementValues.reserve(constAgg->getNumOperands());
1705 for (llvm::Value *operand : constAgg->operands())
1708 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1709 unsigned numElements = constAgg->getElementCount().getFixedValue();
1710 elementValues.reserve(numElements);
1711 for (
unsigned i = 0, e = numElements; i != e; ++i)
1712 elementValues.push_back(
lookupValue(constAgg->getElementValue(i)));
1714 assert(llvm::count(elementValues,
nullptr) == 0 &&
1715 "expected all elements have been converted before");
1719 bool isArrayOrStruct = isa<LLVMArrayType, LLVMStructType>(rootType);
1721 "unrecognized aggregate type");
1722 Value root = UndefOp::create(builder, loc, rootType);
1724 if (isArrayOrStruct) {
1726 InsertValueOp::create(builder, loc, root, it.value(), it.index());
1730 ConstantOp::create(builder, loc, builder.
getI32Type(), indexAttr);
1731 root = InsertElementOp::create(builder, loc, rootType, root, it.value(),
1738 if (
auto *constTargetNone = dyn_cast<llvm::ConstantTargetNone>(constant)) {
1739 LLVMTargetExtType targetExtType =
1740 cast<LLVMTargetExtType>(
convertType(constTargetNone->getType()));
1741 assert(targetExtType.hasProperty(LLVMTargetExtType::HasZeroInit) &&
1742 "target extension type does not support zero-initialization");
1745 return LLVM::ZeroOp::create(builder, loc, targetExtType).getRes();
1748 if (
auto *blockAddr = dyn_cast<llvm::BlockAddress>(constant)) {
1753 return BlockAddressOp::create(
1759 StringRef error =
"";
1761 if (isa<llvm::ConstantPtrAuth>(constant))
1762 error =
" since ptrauth(...) is unsupported";
1764 if (isa<llvm::NoCFIValue>(constant))
1765 error =
" since no_cfi is unsupported";
1767 if (isa<llvm::GlobalValue>(constant))
1768 error =
" since global value is unsupported";
1770 return emitError(loc) <<
"unhandled constant: " <<
diag(*constant) << error;
1773 FailureOr<Value> ModuleImport::convertConstantExpr(llvm::Constant *constant) {
1777 assert(!valueMapping.contains(constant) &&
1778 "expected constant has not been converted before");
1779 assert(constantInsertionBlock &&
1780 "expected the constant insertion block to be non-null");
1784 if (!constantInsertionOp)
1791 getConstantsToConvert(constant);
1792 for (llvm::Constant *constantToConvert : constantsToConvert) {
1793 FailureOr<Value> converted = convertConstant(constantToConvert);
1796 mapValue(constantToConvert, *converted);
1806 assert(!isa<llvm::MetadataAsValue>(value) &&
1807 "expected value to not be metadata");
1810 auto it = valueMapping.find(value);
1811 if (it != valueMapping.end())
1812 return it->getSecond();
1815 if (
auto *constant = dyn_cast<llvm::Constant>(value))
1816 return convertConstantExpr(constant);
1819 if (
auto *inst = dyn_cast<llvm::Instruction>(value))
1821 return emitError(loc) <<
"unhandled value: " <<
diag(*value);
1827 auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
1830 auto *node = dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
1833 value = node->getValue();
1836 auto it = valueMapping.find(value);
1837 if (it != valueMapping.end())
1838 return it->getSecond();
1841 if (
auto *constant = dyn_cast<llvm::Constant>(value))
1842 return convertConstantExpr(constant);
1846 FailureOr<SmallVector<Value>>
1849 remapped.reserve(values.size());
1850 for (llvm::Value *value : values) {
1854 remapped.push_back(*converted);
1864 assert(immArgPositions.size() == immArgAttrNames.size() &&
1865 "LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
1869 for (
auto [immArgPos, immArgName] :
1870 llvm::zip(immArgPositions, immArgAttrNames)) {
1871 auto &value = operands[immArgPos];
1872 auto *constant = llvm::cast<llvm::Constant>(value);
1874 assert(attr && attr.getType().isIntOrFloat() &&
1875 "expected immarg to be float or integer constant");
1877 attrsOut.push_back({nameAttr, attr});
1882 for (llvm::Value *value : operands) {
1888 valuesOut.push_back(*mlirValue);
1893 if (requiresOpBundles) {
1894 opBundleSizes.reserve(opBundles.size());
1895 opBundleTagAttrs.reserve(opBundles.size());
1897 for (
const llvm::OperandBundleUse &bundle : opBundles) {
1898 opBundleSizes.push_back(bundle.Inputs.size());
1899 opBundleTagAttrs.push_back(
StringAttr::get(context, bundle.getTagName()));
1901 for (
const llvm::Use &opBundleOperand : bundle.Inputs) {
1902 auto operandMlirValue =
convertValue(opBundleOperand.get());
1903 if (
failed(operandMlirValue))
1905 valuesOut.push_back(*operandMlirValue);
1910 auto opBundleSizesAttrNameAttr =
1912 attrsOut.push_back({opBundleSizesAttrNameAttr, opBundleSizesAttr});
1914 auto opBundleTagsAttr =
ArrayAttr::get(context, opBundleTagAttrs);
1915 auto opBundleTagsAttrNameAttr =
1917 attrsOut.push_back({opBundleTagsAttrNameAttr, opBundleTagsAttr});
1924 IntegerAttr integerAttr;
1926 bool success = succeeded(converted) &&
1928 assert(success &&
"expected a constant integer value");
1934 FloatAttr floatAttr;
1938 assert(success &&
"expected a constant float value");
1944 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1945 auto *node = cast<llvm::DILocalVariable>(nodeAsVal->getMetadata());
1946 return debugImporter->translate(node);
1950 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1951 auto *node = cast<llvm::DILabel>(nodeAsVal->getMetadata());
1952 return debugImporter->translate(node);
1955 FPExceptionBehaviorAttr
1957 auto *metadata = cast<llvm::MetadataAsValue>(value);
1958 auto *mdstr = cast<llvm::MDString>(metadata->getMetadata());
1959 std::optional<llvm::fp::ExceptionBehavior> optLLVM =
1960 llvm::convertStrToExceptionBehavior(mdstr->getString());
1961 assert(optLLVM &&
"Expecting FP exception behavior");
1962 return builder.
getAttr<FPExceptionBehaviorAttr>(
1963 convertFPExceptionBehaviorFromLLVM(*optLLVM));
1967 auto *metadata = cast<llvm::MetadataAsValue>(value);
1968 auto *mdstr = cast<llvm::MDString>(metadata->getMetadata());
1969 std::optional<llvm::RoundingMode> optLLVM =
1970 llvm::convertStrToRoundingMode(mdstr->getString());
1971 assert(optLLVM &&
"Expecting rounding mode");
1972 return builder.
getAttr<RoundingModeAttr>(
1973 convertRoundingModeFromLLVM(*optLLVM));
1976 FailureOr<SmallVector<AliasScopeAttr>>
1978 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1979 auto *node = cast<llvm::MDNode>(nodeAsVal->getMetadata());
1984 return debugImporter->translateLoc(loc);
1988 ModuleImport::convertBranchArgs(llvm::Instruction *branch,
1989 llvm::BasicBlock *target,
1991 for (
auto inst = target->begin(); isa<llvm::PHINode>(inst); ++inst) {
1992 auto *phiInst = cast<llvm::PHINode>(&*inst);
1993 llvm::Value *value = phiInst->getIncomingValueForBlock(branch->getParent());
1997 blockArguments.push_back(*converted);
2002 FailureOr<SmallVector<Value>>
2003 ModuleImport::convertCallOperands(llvm::CallBase *callInst,
2004 bool allowInlineAsm) {
2005 bool isInlineAsm = callInst->isInlineAsm();
2006 if (isInlineAsm && !allowInlineAsm)
2016 llvm::Value *calleeOperand = callInst->getCalledOperand();
2017 if (!isa<llvm::Function, llvm::GlobalIFunc>(calleeOperand) && !isInlineAsm) {
2021 operands.push_back(*called);
2025 FailureOr<SmallVector<Value>> arguments =
convertValues(args);
2029 llvm::append_range(operands, *arguments);
2035 static LogicalResult
2037 LLVMFunctionType calleeType) {
2038 if (callType.getReturnType() != calleeType.getReturnType())
2041 if (calleeType.isVarArg()) {
2044 if (callType.getNumParams() < calleeType.getNumParams())
2049 if (callType.getNumParams() != calleeType.getNumParams())
2054 for (
auto [operandType, argumentType] :
2055 llvm::zip(callType.getParams(), calleeType.getParams()))
2056 if (operandType != argumentType)
2062 FailureOr<LLVMFunctionType>
2063 ModuleImport::convertFunctionType(llvm::CallBase *callInst,
2064 bool &isIncompatibleCall) {
2065 isIncompatibleCall =
false;
2066 auto castOrFailure = [](
Type convertedType) -> FailureOr<LLVMFunctionType> {
2067 auto funcTy = dyn_cast_or_null<LLVMFunctionType>(convertedType);
2073 llvm::Value *calledOperand = callInst->getCalledOperand();
2074 FailureOr<LLVMFunctionType> callType =
2075 castOrFailure(
convertType(callInst->getFunctionType()));
2078 auto *callee = dyn_cast<llvm::Function>(calledOperand);
2080 llvm::FunctionType *origCalleeType =
nullptr;
2082 origCalleeType = callee->getFunctionType();
2083 }
else if (
auto *ifunc = dyn_cast<llvm::GlobalIFunc>(calledOperand)) {
2084 origCalleeType = cast<llvm::FunctionType>(ifunc->getValueType());
2088 if (!origCalleeType)
2091 FailureOr<LLVMFunctionType> calleeType =
2099 isIncompatibleCall =
true;
2101 emitWarning(loc) <<
"incompatible call and callee types: " << *callType
2102 <<
" and " << *calleeType;
2110 llvm::Value *calledOperand = callInst->getCalledOperand();
2111 if (isa<llvm::Function, llvm::GlobalIFunc>(calledOperand))
2116 LogicalResult ModuleImport::convertIntrinsic(llvm::CallInst *inst) {
2121 return emitError(loc) <<
"unhandled intrinsic: " <<
diag(*inst);
2125 ModuleImport::convertAsmInlineOperandAttrs(
const llvm::CallBase &llvmCall) {
2126 const auto *ia = cast<llvm::InlineAsm>(llvmCall.getCalledOperand());
2127 unsigned argIdx = 0;
2129 bool hasIndirect =
false;
2131 for (
const llvm::InlineAsm::ConstraintInfo &ci : ia->ParseConstraints()) {
2133 if (ci.Type == llvm::InlineAsm::isLabel || !ci.hasArg())
2138 if (ci.isIndirect) {
2139 if (llvm::Type *paramEltType = llvmCall.getParamElementType(argIdx)) {
2142 mlir::LLVM::InlineAsmOp::getElementTypeAttrName(),
2154 return hasIndirect ?
ArrayAttr::get(mlirModule->getContext(), opAttrs)
2158 LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
2161 if (inst->getOpcode() == llvm::Instruction::Br) {
2162 auto *brInst = cast<llvm::BranchInst>(inst);
2166 for (
auto i : llvm::seq<unsigned>(0, brInst->getNumSuccessors())) {
2167 llvm::BasicBlock *succ = brInst->getSuccessor(i);
2169 if (
failed(convertBranchArgs(brInst, succ, blockArgs)))
2172 succBlockArgs.push_back(blockArgs);
2175 if (!brInst->isConditional()) {
2176 auto brOp = LLVM::BrOp::create(builder, loc, succBlockArgs.front(),
2177 succBlocks.front());
2181 FailureOr<Value> condition =
convertValue(brInst->getCondition());
2184 auto condBrOp = LLVM::CondBrOp::create(
2185 builder, loc, *condition, succBlocks.front(), succBlockArgs.front(),
2186 succBlocks.back(), succBlockArgs.back());
2190 if (inst->getOpcode() == llvm::Instruction::Switch) {
2191 auto *swInst = cast<llvm::SwitchInst>(inst);
2193 FailureOr<Value> condition =
convertValue(swInst->getCondition());
2198 llvm::BasicBlock *defaultBB = swInst->getDefaultDest();
2199 if (
failed(convertBranchArgs(swInst, defaultBB, defaultBlockArgs)))
2203 unsigned numCases = swInst->getNumCases();
2209 const llvm::SwitchInst::CaseHandle &caseHandle = it.value();
2210 llvm::BasicBlock *succBB = caseHandle.getCaseSuccessor();
2211 if (
failed(convertBranchArgs(swInst, succBB, caseOperands[it.index()])))
2213 caseOperandRefs[it.index()] = caseOperands[it.index()];
2214 caseValues[it.index()] = caseHandle.getCaseValue()->getValue();
2218 auto switchOp = SwitchOp::create(builder, loc, *condition,
2220 caseValues, caseBlocks, caseOperandRefs);
2224 if (inst->getOpcode() == llvm::Instruction::PHI) {
2230 if (inst->getOpcode() == llvm::Instruction::Call) {
2231 auto *callInst = cast<llvm::CallInst>(inst);
2232 llvm::Value *calledOperand = callInst->getCalledOperand();
2234 FailureOr<SmallVector<Value>> operands =
2235 convertCallOperands(callInst,
true);
2239 auto callOp = [&]() -> FailureOr<Operation *> {
2240 if (
auto *asmI = dyn_cast<llvm::InlineAsm>(calledOperand)) {
2244 ArrayAttr operandAttrs = convertAsmInlineOperandAttrs(*callInst);
2245 return InlineAsmOp::create(
2246 builder, loc, resultTy, *operands,
2249 asmI->hasSideEffects(), asmI->isAlignStack(),
2250 convertTailCallKindFromLLVM(callInst->getTailCallKind()),
2252 mlirModule.getContext(),
2253 convertAsmDialectFromLLVM(asmI->getDialect())),
2257 bool isIncompatibleCall;
2258 FailureOr<LLVMFunctionType> funcTy =
2259 convertFunctionType(callInst, isIncompatibleCall);
2264 if (isIncompatibleCall) {
2269 Value indirectCallVal = LLVM::AddressOfOp::create(
2271 operands->insert(operands->begin(), indirectCallVal);
2274 callee = convertCalleeName(callInst);
2276 CallOp callOp = CallOp::create(builder, loc, *funcTy, callee, *operands);
2278 if (
failed(convertCallAttributes(callInst, callOp)))
2283 if (!isIncompatibleCall)
2285 return callOp.getOperation();
2291 if (!callInst->getType()->isVoidTy())
2292 mapValue(inst, (*callOp)->getResult(0));
2297 if (inst->getOpcode() == llvm::Instruction::LandingPad) {
2298 auto *lpInst = cast<llvm::LandingPadInst>(inst);
2301 operands.reserve(lpInst->getNumClauses());
2302 for (
auto i : llvm::seq<unsigned>(0, lpInst->getNumClauses())) {
2303 FailureOr<Value> operand =
convertValue(lpInst->getClause(i));
2306 operands.push_back(*operand);
2311 LandingpadOp::create(builder, loc, type, lpInst->isCleanup(), operands);
2315 if (inst->getOpcode() == llvm::Instruction::Invoke) {
2316 auto *invokeInst = cast<llvm::InvokeInst>(inst);
2318 if (invokeInst->isInlineAsm())
2319 return emitError(loc) <<
"invoke of inline assembly is not supported";
2321 FailureOr<SmallVector<Value>> operands = convertCallOperands(invokeInst);
2327 bool invokeResultUsedInPhi = llvm::any_of(
2328 invokeInst->getNormalDest()->phis(), [&](
const llvm::PHINode &phi) {
2329 return phi.getIncomingValueForBlock(invokeInst->getParent()) ==
2334 Block *directNormalDest = normalDest;
2335 if (invokeResultUsedInPhi) {
2341 directNormalDest = builder.
createBlock(normalDest);
2345 if (
failed(convertBranchArgs(invokeInst, invokeInst->getUnwindDest(),
2349 bool isIncompatibleInvoke;
2350 FailureOr<LLVMFunctionType> funcTy =
2351 convertFunctionType(invokeInst, isIncompatibleInvoke);
2356 if (isIncompatibleInvoke) {
2361 Value indirectInvokeVal = LLVM::AddressOfOp::create(
2363 operands->insert(operands->begin(), indirectInvokeVal);
2366 calleeName = convertCalleeName(invokeInst);
2371 auto invokeOp = InvokeOp::create(
2372 builder, loc, *funcTy, calleeName, *operands, directNormalDest,
2375 if (
failed(convertInvokeAttributes(invokeInst, invokeOp)))
2380 if (!isIncompatibleInvoke)
2383 if (!invokeInst->getType()->isVoidTy())
2384 mapValue(inst, invokeOp.getResults().front());
2389 if (
failed(convertBranchArgs(invokeInst, invokeInst->getNormalDest(),
2393 if (invokeResultUsedInPhi) {
2399 LLVM::BrOp::create(builder, loc, normalArgs, normalDest);
2403 assert(llvm::none_of(
2406 "An llvm.invoke operation cannot pass its result as a block "
2408 invokeOp.getNormalDestOperandsMutable().append(normalArgs);
2413 if (inst->getOpcode() == llvm::Instruction::GetElementPtr) {
2414 auto *gepInst = cast<llvm::GetElementPtrInst>(inst);
2415 Type sourceElementType =
convertType(gepInst->getSourceElementType());
2416 FailureOr<Value> basePtr =
convertValue(gepInst->getOperand(0));
2425 for (llvm::Value *operand : llvm::drop_begin(gepInst->operand_values())) {
2429 indices.push_back(*index);
2433 auto gepOp = GEPOp::create(
2434 builder, loc, type, sourceElementType, *basePtr, indices,
2435 static_cast<GEPNoWrapFlags
>(gepInst->getNoWrapFlags().getRaw()));
2440 if (inst->getOpcode() == llvm::Instruction::IndirectBr) {
2441 auto *indBrInst = cast<llvm::IndirectBrInst>(inst);
2443 FailureOr<Value> basePtr =
convertValue(indBrInst->getAddress());
2449 for (
auto i : llvm::seq<unsigned>(0, indBrInst->getNumSuccessors())) {
2450 llvm::BasicBlock *succ = indBrInst->getSuccessor(i);
2452 if (
failed(convertBranchArgs(indBrInst, succ, blockArgs)))
2455 succBlockArgs.push_back(blockArgs);
2458 llvm::to_vector_of<ValueRange>(succBlockArgs);
2460 auto indBrOp = LLVM::IndirectBrOp::create(builder, loc, *basePtr,
2461 succBlockArgsRange, succBlocks);
2471 return emitError(loc) <<
"unhandled instruction: " <<
diag(*inst);
2474 LogicalResult ModuleImport::processInstruction(llvm::Instruction *inst) {
2481 if (
auto *intrinsic = dyn_cast<llvm::IntrinsicInst>(inst))
2482 return convertIntrinsic(intrinsic);
2485 return convertInstruction(inst);
2489 if (!f->hasPersonalityFn())
2492 llvm::Constant *pf = f->getPersonalityFn();
2500 if (
auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) {
2501 if (ce->getOpcode() == llvm::Instruction::BitCast &&
2502 ce->getType() == llvm::PointerType::getUnqual(f->getContext())) {
2503 if (
auto *func = dyn_cast<llvm::Function>(ce->getOperand(0)))
2511 llvm::MemoryEffects memEffects = func->getMemoryEffects();
2513 auto othermem = convertModRefInfoFromLLVM(
2514 memEffects.getModRef(llvm::MemoryEffects::Location::Other));
2515 auto argMem = convertModRefInfoFromLLVM(
2516 memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
2517 auto inaccessibleMem = convertModRefInfoFromLLVM(
2518 memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
2522 if (memAttr.isReadWrite())
2524 funcOp.setMemoryEffectsAttr(memAttr);
2530 StringLiteral(
"aarch64_in_za"),
2531 StringLiteral(
"aarch64_inout_za"),
2532 StringLiteral(
"aarch64_new_za"),
2533 StringLiteral(
"aarch64_out_za"),
2534 StringLiteral(
"aarch64_preserves_za"),
2535 StringLiteral(
"aarch64_pstate_sm_body"),
2536 StringLiteral(
"aarch64_pstate_sm_compatible"),
2537 StringLiteral(
"aarch64_pstate_sm_enabled"),
2538 StringLiteral(
"alwaysinline"),
2539 StringLiteral(
"convergent"),
2540 StringLiteral(
"denormal-fp-math"),
2541 StringLiteral(
"denormal-fp-math-f32"),
2542 StringLiteral(
"fp-contract"),
2543 StringLiteral(
"frame-pointer"),
2544 StringLiteral(
"instrument-function-entry"),
2545 StringLiteral(
"instrument-function-exit"),
2546 StringLiteral(
"no-infs-fp-math"),
2547 StringLiteral(
"no-nans-fp-math"),
2548 StringLiteral(
"no-signed-zeros-fp-math"),
2549 StringLiteral(
"noinline"),
2550 StringLiteral(
"nounwind"),
2551 StringLiteral(
"optnone"),
2552 StringLiteral(
"target-features"),
2553 StringLiteral(
"tune-cpu"),
2554 StringLiteral(
"unsafe-fp-math"),
2555 StringLiteral(
"uwtable"),
2556 StringLiteral(
"vscale_range"),
2557 StringLiteral(
"willreturn"),
2563 llvm::AttributeSet funcAttrs = func->getAttributes().getAttributes(
2564 llvm::AttributeList::AttrIndex::FunctionIndex);
2565 for (llvm::Attribute attr : funcAttrs) {
2568 if (attr.hasAttribute(llvm::Attribute::Memory))
2572 if (attr.isTypeAttribute()) {
2574 "type attributes on a function are invalid, skipping it");
2579 if (attr.isStringAttribute())
2580 attrName = attr.getKindAsString();
2582 attrName = llvm::Attribute::getNameFromAttrKind(attr.getKindAsEnum());
2589 if (attr.isStringAttribute()) {
2590 StringRef val = attr.getValueAsString();
2592 passthroughs.push_back(keyAttr);
2595 passthroughs.push_back(
2599 if (attr.isIntAttribute()) {
2600 auto val = std::to_string(attr.getValueAsInt());
2601 passthroughs.push_back(
2605 if (attr.isEnumAttribute()) {
2606 passthroughs.push_back(keyAttr);
2610 llvm_unreachable(
"unexpected attribute kind");
2613 if (!passthroughs.empty())
2614 funcOp.setPassthroughAttr(
ArrayAttr::get(context, passthroughs));
2618 LLVMFuncOp funcOp) {
2622 if (func->hasFnAttribute(llvm::Attribute::NoInline))
2623 funcOp.setNoInline(
true);
2624 if (func->hasFnAttribute(llvm::Attribute::AlwaysInline))
2625 funcOp.setAlwaysInline(
true);
2626 if (func->hasFnAttribute(llvm::Attribute::OptimizeNone))
2627 funcOp.setOptimizeNone(
true);
2628 if (func->hasFnAttribute(llvm::Attribute::Convergent))
2629 funcOp.setConvergent(
true);
2630 if (func->hasFnAttribute(llvm::Attribute::NoUnwind))
2631 funcOp.setNoUnwind(
true);
2632 if (func->hasFnAttribute(llvm::Attribute::WillReturn))
2633 funcOp.setWillReturn(
true);
2635 if (func->hasFnAttribute(
"aarch64_pstate_sm_enabled"))
2636 funcOp.setArmStreaming(
true);
2637 else if (func->hasFnAttribute(
"aarch64_pstate_sm_body"))
2638 funcOp.setArmLocallyStreaming(
true);
2639 else if (func->hasFnAttribute(
"aarch64_pstate_sm_compatible"))
2640 funcOp.setArmStreamingCompatible(
true);
2642 if (func->hasFnAttribute(
"aarch64_new_za"))
2643 funcOp.setArmNewZa(
true);
2644 else if (func->hasFnAttribute(
"aarch64_in_za"))
2645 funcOp.setArmInZa(
true);
2646 else if (func->hasFnAttribute(
"aarch64_out_za"))
2647 funcOp.setArmOutZa(
true);
2648 else if (func->hasFnAttribute(
"aarch64_inout_za"))
2649 funcOp.setArmInoutZa(
true);
2650 else if (func->hasFnAttribute(
"aarch64_preserves_za"))
2651 funcOp.setArmPreservesZa(
true);
2653 llvm::Attribute attr = func->getFnAttribute(llvm::Attribute::VScaleRange);
2654 if (attr.isValid()) {
2663 if (func->hasFnAttribute(
"frame-pointer")) {
2664 StringRef stringRefFramePointerKind =
2665 func->getFnAttribute(
"frame-pointer").getValueAsString();
2667 funcOp.getContext(), LLVM::framePointerKind::symbolizeFramePointerKind(
2668 stringRefFramePointerKind)
2672 if (llvm::Attribute attr = func->getFnAttribute(
"target-cpu");
2673 attr.isStringAttribute())
2674 funcOp.setTargetCpuAttr(
StringAttr::get(context, attr.getValueAsString()));
2676 if (llvm::Attribute attr = func->getFnAttribute(
"tune-cpu");
2677 attr.isStringAttribute())
2678 funcOp.setTuneCpuAttr(
StringAttr::get(context, attr.getValueAsString()));
2680 if (llvm::Attribute attr = func->getFnAttribute(
"target-features");
2681 attr.isStringAttribute())
2682 funcOp.setTargetFeaturesAttr(
2685 if (llvm::Attribute attr = func->getFnAttribute(
"reciprocal-estimates");
2686 attr.isStringAttribute())
2687 funcOp.setReciprocalEstimatesAttr(
2690 if (llvm::Attribute attr = func->getFnAttribute(
"prefer-vector-width");
2691 attr.isStringAttribute())
2692 funcOp.setPreferVectorWidth(attr.getValueAsString());
2694 if (llvm::Attribute attr = func->getFnAttribute(
"unsafe-fp-math");
2695 attr.isStringAttribute())
2696 funcOp.setUnsafeFpMath(attr.getValueAsBool());
2698 if (llvm::Attribute attr = func->getFnAttribute(
"no-infs-fp-math");
2699 attr.isStringAttribute())
2700 funcOp.setNoInfsFpMath(attr.getValueAsBool());
2702 if (llvm::Attribute attr = func->getFnAttribute(
"no-nans-fp-math");
2703 attr.isStringAttribute())
2704 funcOp.setNoNansFpMath(attr.getValueAsBool());
2706 if (llvm::Attribute attr = func->getFnAttribute(
"instrument-function-entry");
2707 attr.isStringAttribute())
2708 funcOp.setInstrumentFunctionEntry(
2711 if (llvm::Attribute attr = func->getFnAttribute(
"instrument-function-exit");
2712 attr.isStringAttribute())
2713 funcOp.setInstrumentFunctionExit(
2716 if (llvm::Attribute attr = func->getFnAttribute(
"no-signed-zeros-fp-math");
2717 attr.isStringAttribute())
2718 funcOp.setNoSignedZerosFpMath(attr.getValueAsBool());
2720 if (llvm::Attribute attr = func->getFnAttribute(
"denormal-fp-math");
2721 attr.isStringAttribute())
2722 funcOp.setDenormalFpMathAttr(
2725 if (llvm::Attribute attr = func->getFnAttribute(
"denormal-fp-math-f32");
2726 attr.isStringAttribute())
2727 funcOp.setDenormalFpMathF32Attr(
2730 if (llvm::Attribute attr = func->getFnAttribute(
"fp-contract");
2731 attr.isStringAttribute())
2732 funcOp.setFpContractAttr(
StringAttr::get(context, attr.getValueAsString()));
2734 if (func->hasUWTable()) {
2735 ::llvm::UWTableKind uwtableKind = func->getUWTableKind();
2737 funcOp.getContext(), convertUWTableKindFromLLVM(uwtableKind)));
2742 ModuleImport::convertArgOrResultAttrSet(llvm::AttributeSet llvmAttrSet) {
2745 auto llvmAttr = llvmAttrSet.getAttribute(llvmKind);
2747 if (!llvmAttr.isValid())
2752 if (llvmAttr.hasKindAsEnum() &&
2753 llvmAttr.getKindAsEnum() == llvm::Attribute::Captures) {
2754 if (llvm::capturesNothing(llvmAttr.getCaptureInfo()))
2755 paramAttrs.push_back(
2761 if (llvmAttr.isTypeAttribute())
2763 else if (llvmAttr.isIntAttribute())
2765 else if (llvmAttr.isEnumAttribute())
2767 else if (llvmAttr.isConstantRangeAttribute()) {
2768 const llvm::ConstantRange &value = llvmAttr.getValueAsConstantRange();
2769 mlirAttr = builder.
getAttr<LLVM::ConstantRangeAttr>(value.getLower(),
2772 llvm_unreachable(
"unexpected parameter attribute kind");
2774 paramAttrs.push_back(builder.
getNamedAttr(mlirName, mlirAttr));
2781 LLVMFuncOp funcOp) {
2782 auto llvmAttrs = func->getAttributes();
2783 for (
size_t i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
2784 llvm::AttributeSet llvmArgAttrs = llvmAttrs.getParamAttrs(i);
2785 funcOp.setArgAttrs(i, convertArgOrResultAttrSet(llvmArgAttrs));
2789 llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
2790 if (!llvmResAttr.hasAttributes())
2792 funcOp.setResAttrsAttr(
2793 builder.
getArrayAttr({convertArgOrResultAttrSet(llvmResAttr)}));
2797 llvm::CallBase *call, ArgAndResultAttrsOpInterface attrsOp,
2800 llvm::SmallDenseSet<unsigned> immArgPositionsSet(immArgPositions.begin(),
2801 immArgPositions.end());
2803 llvm::AttributeList llvmAttrs = call->getAttributes();
2805 bool anyArgAttrs =
false;
2806 for (
size_t i = 0, e = call->arg_size(); i < e; ++i) {
2808 if (immArgPositionsSet.contains(i))
2810 llvmArgAttrsSet.emplace_back(llvmAttrs.getParamAttrs(i));
2811 if (llvmArgAttrsSet.back().hasAttributes())
2816 for (
auto &dict : dictAttrs)
2822 for (
auto &llvmArgAttrs : llvmArgAttrsSet)
2823 argAttrs.emplace_back(convertArgOrResultAttrSet(llvmArgAttrs));
2824 attrsOp.setArgAttrsAttr(getArrayAttr(argAttrs));
2828 llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
2829 if (!llvmResAttr.hasAttributes())
2831 DictionaryAttr resAttrs = convertArgOrResultAttrSet(llvmResAttr);
2832 attrsOp.setResAttrsAttr(getArrayAttr({resAttrs}));
2835 template <
typename Op>
2837 op.setCConv(convertCConvFromLLVM(inst->getCallingConv()));
2841 LogicalResult ModuleImport::convertInvokeAttributes(llvm::InvokeInst *inst,
2846 LogicalResult ModuleImport::convertCallAttributes(llvm::CallInst *inst,
2852 llvm::AttributeList callAttrs = inst->getAttributes();
2854 op.setTailCallKind(convertTailCallKindFromLLVM(inst->getTailCallKind()));
2855 op.setConvergent(callAttrs.getFnAttr(llvm::Attribute::Convergent).isValid());
2856 op.setNoUnwind(callAttrs.getFnAttr(llvm::Attribute::NoUnwind).isValid());
2857 op.setWillReturn(callAttrs.getFnAttr(llvm::Attribute::WillReturn).isValid());
2858 op.setNoInline(callAttrs.getFnAttr(llvm::Attribute::NoInline).isValid());
2860 callAttrs.getFnAttr(llvm::Attribute::AlwaysInline).isValid());
2861 op.setInlineHint(callAttrs.getFnAttr(llvm::Attribute::InlineHint).isValid());
2863 llvm::MemoryEffects memEffects = inst->getMemoryEffects();
2864 ModRefInfo othermem = convertModRefInfoFromLLVM(
2865 memEffects.getModRef(llvm::MemoryEffects::Location::Other));
2866 ModRefInfo argMem = convertModRefInfoFromLLVM(
2867 memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
2868 ModRefInfo inaccessibleMem = convertModRefInfoFromLLVM(
2869 memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
2873 if (!memAttr.isReadWrite())
2874 op.setMemoryEffectsAttr(memAttr);
2883 dyn_cast<LLVMFunctionType>(
convertType(func->getFunctionType()));
2884 if (func->isIntrinsic() &&
2888 bool dsoLocal = func->isDSOLocal();
2889 CConv cconv = convertCConvFromLLVM(func->getCallingConv());
2895 Location loc = debugImporter->translateFuncLocation(func);
2896 LLVMFuncOp funcOp = LLVMFuncOp::create(
2897 builder, loc, func->getName(), functionType,
2898 convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv);
2903 funcOp.setPersonalityAttr(personality);
2904 else if (func->hasPersonalityFn())
2905 emitWarning(funcOp.getLoc(),
"could not deduce personality, skipping it");
2908 funcOp.setGarbageCollector(StringRef(func->getGC()));
2910 if (func->hasAtLeastLocalUnnamedAddr())
2911 funcOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(func->getUnnamedAddr()));
2913 if (func->hasSection())
2914 funcOp.setSection(StringRef(func->getSection()));
2916 funcOp.setVisibility_(convertVisibilityFromLLVM(func->getVisibility()));
2918 if (func->hasComdat())
2919 funcOp.setComdatAttr(comdatMapping.lookup(func->getComdat()));
2921 if (llvm::MaybeAlign maybeAlign = func->getAlign())
2922 funcOp.setAlignment(maybeAlign->value());
2929 func->getAllMetadata(allMetadata);
2930 for (
auto &[
kind, node] : allMetadata) {
2935 <<
"unhandled function metadata: " <<
diagMD(node, llvmModule.get())
2936 <<
" on " <<
diag(*func);
2940 if (func->isDeclaration())
2949 llvm::df_iterator_default_set<llvm::BasicBlock *> reachable;
2950 for (llvm::BasicBlock *basicBlock : llvm::depth_first_ext(func, reachable))
2955 for (llvm::BasicBlock &basicBlock : *func) {
2957 if (!reachable.contains(&basicBlock)) {
2958 if (basicBlock.hasAddressTaken())
2960 <<
"unreachable block '" << basicBlock.getName()
2961 <<
"' with address taken";
2964 Region &body = funcOp.getBody();
2967 reachableBasicBlocks.push_back(&basicBlock);
2972 BlockArgument blockArg = funcOp.getFunctionBody().addArgument(
2973 functionType.getParamType(it.index()), funcOp.getLoc());
2982 setConstantInsertionPointToStart(
lookupBlock(blocks.front()));
2983 for (llvm::BasicBlock *basicBlock : blocks)
2989 if (
failed(processDebugIntrinsics()))
2998 if (!dbgIntr->isKillLocation())
3000 llvm::Value *value = dbgIntr->getArgOperand(0);
3001 auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
3004 return !isa<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
3008 ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
3011 auto emitUnsupportedWarning = [&]() {
3012 if (emitExpensiveWarnings)
3018 if (dbgIntr->hasArgList())
3019 return emitUnsupportedWarning();
3024 return emitUnsupportedWarning();
3028 DILocalVariableAttr localVariableAttr =
3030 if (!localVariableAttr)
3031 return emitUnsupportedWarning();
3034 return emitError(loc) <<
"failed to convert a debug intrinsic operand: "
3042 if (
Operation *op = argOperand->getDefiningOp();
3045 auto dominatedBlocks = domInfo.
getNode(op->getBlock())->children();
3048 if (dominatedBlocks.empty())
3049 return emitUnsupportedWarning();
3052 Block *dominatedBlock = (*dominatedBlocks.begin())->getBlock();
3055 Value insertPt = *argOperand;
3056 if (
auto blockArg = dyn_cast<BlockArgument>(*argOperand)) {
3061 Block *insertionBlock = argOperand->getParentBlock();
3062 if (!insertionBlock->
empty() &&
3063 isa<LandingpadOp>(insertionBlock->
front()))
3064 insertPt = cast<LandingpadOp>(insertionBlock->
front()).getRes();
3069 auto locationExprAttr =
3070 debugImporter->translateExpression(dbgIntr->getExpression());
3073 .Case([&](llvm::DbgDeclareInst *) {
3074 return LLVM::DbgDeclareOp::create(
3075 builder, loc, *argOperand, localVariableAttr, locationExprAttr);
3077 .Case([&](llvm::DbgValueInst *) {
3078 return LLVM::DbgValueOp::create(
3079 builder, loc, *argOperand, localVariableAttr, locationExprAttr);
3082 setNonDebugMetadataAttrs(dbgIntr, op);
3086 LogicalResult ModuleImport::processDebugIntrinsics() {
3088 for (llvm::Instruction *inst : debugIntrinsics) {
3089 auto *intrCall = cast<llvm::DbgVariableIntrinsic>(inst);
3090 if (
failed(processDebugIntrinsic(intrCall, domInfo)))
3096 LogicalResult ModuleImport::processBasicBlock(llvm::BasicBlock *bb,
3099 for (llvm::Instruction &inst : *bb) {
3100 if (
failed(processInstruction(&inst)))
3105 if (debugIntrinsics.contains(&inst))
3112 setNonDebugMetadataAttrs(&inst, op);
3113 }
else if (inst.getOpcode() != llvm::Instruction::PHI) {
3114 if (emitExpensiveWarnings) {
3115 Location loc = debugImporter->translateLoc(inst.getDebugLoc());
3121 if (bb->hasAddressTaken()) {
3130 FailureOr<SmallVector<AccessGroupAttr>>
3132 return loopAnnotationImporter->lookupAccessGroupAttrs(node);
3138 return loopAnnotationImporter->translateLoopAnnotation(node, loc);
3141 FailureOr<DereferenceableAttr>
3144 Location loc = mlirModule.getLoc();
3148 if (node->getNumOperands() != 1)
3149 return emitError(loc) <<
"dereferenceable metadata must have one operand: "
3150 <<
diagMD(node, llvmModule.get());
3152 auto *numBytesMD = dyn_cast<llvm::ConstantAsMetadata>(node->getOperand(0));
3153 auto *numBytesCst = dyn_cast<llvm::ConstantInt>(numBytesMD->getValue());
3154 if (!numBytesCst || !numBytesCst->getValue().isNonNegative())
3155 return emitError(loc) <<
"dereferenceable metadata operand must be a "
3156 "non-negative constant integer: "
3157 <<
diagMD(node, llvmModule.get());
3159 bool mayBeNull = kindID == llvm::LLVMContext::MD_dereferenceable_or_null;
3160 auto derefAttr = builder.
getAttr<DereferenceableAttr>(
3161 numBytesCst->getZExtValue(), mayBeNull);
3167 std::unique_ptr<llvm::Module> llvmModule,
MLIRContext *context,
3168 bool emitExpensiveWarnings,
bool dropDICompositeTypeElements,
3169 bool loadAllDialects,
bool preferUnregisteredIntrinsics,
3170 bool importStructsAsLiterals) {
3177 LLVMDialect::getDialectNamespace()));
3179 DLTIDialect::getDialectNamespace()));
3180 if (loadAllDialects)
3187 emitExpensiveWarnings, dropDICompositeTypeElements,
3188 preferUnregisteredIntrinsics,
3189 importStructsAsLiterals);
static MLIRContext * getContext(OpFoldResult val)
union mlir::linalg::@1242::ArityGroupAndKind::Kind kind
static SmallVector< int64_t > getPositionFromIndices(ArrayRef< unsigned > indices)
Converts an array of unsigned indices to a signed integer position array.
static constexpr std::array kExplicitAttributes
static StringRef getLLVMSyncScope(llvm::Instruction *inst)
Converts the sync scope identifier of inst to the string representation necessary to build an atomic ...
static std::string diag(const llvm::Value &value)
static void processPassthroughAttrs(llvm::Function *func, LLVMFuncOp funcOp)
static LogicalResult convertCallBaseAttributes(llvm::CallBase *inst, Op op)
static void processMemoryEffects(llvm::Function *func, LLVMFuncOp funcOp)
static Attribute convertCGProfileModuleFlagValue(ModuleOp mlirModule, llvm::MDTuple *mdTuple)
static constexpr StringRef getGlobalDtorsVarName()
Returns the name of the global_dtors global variables.
static llvm::ConstantAsMetadata * getConstantMDFromKeyValueTuple(ModuleOp mlirModule, const llvm::Module *llvmModule, const llvm::MDOperand &md, StringRef matchKey, bool optional=false)
Extract a constant metadata value from a two element tuple (<key, value>).
static Type getVectorTypeForAttr(Type type, ArrayRef< int64_t > arrayShape={})
Returns type if it is a builtin integer or floating-point vector type that can be used to create an a...
static LogicalResult convertInstructionImpl(OpBuilder &odsBuilder, llvm::Instruction *inst, ModuleImport &moduleImport, LLVMImportInterface &iface)
Converts the LLVM instructions that have a generated MLIR builder.
static constexpr StringRef getNamelessGlobalPrefix()
Prefix used for symbols of nameless llvm globals.
static Attribute convertModuleFlagValueFromMDTuple(ModuleOp mlirModule, const llvm::Module *llvmModule, StringRef key, llvm::MDTuple *mdTuple)
Invoke specific handlers for each known module flag value, returns nullptr if the key is unknown or u...
static constexpr StringRef getGlobalComdatOpName()
Returns the symbol name for the module-level comdat operation.
static LogicalResult checkFunctionTypeCompatibility(LLVMFunctionType callType, LLVMFunctionType calleeType)
Checks if callType and calleeType are compatible and can be represented in MLIR.
static constexpr StringRef getGlobalCtorsVarName()
Returns the name of the global_ctors global variables.
static Attribute convertProfileSummaryModuleFlagValue(ModuleOp mlirModule, const llvm::Module *llvmModule, llvm::MDTuple *mdTuple)
static std::optional< ProfileSummaryFormatKind > convertProfileSummaryFormat(ModuleOp mlirModule, const llvm::Module *llvmModule, const llvm::MDOperand &formatMD)
static bool isMetadataKillLocation(llvm::DbgVariableIntrinsic *dbgIntr)
Checks if dbgIntr is a kill location that holds metadata instead of an SSA value.
static llvm::MDTuple * getTwoElementMDTuple(ModuleOp mlirModule, const llvm::Module *llvmModule, const llvm::MDOperand &md)
Extract a two element MDTuple from a MDOperand.
static TypedAttr getScalarConstantAsAttr(OpBuilder &builder, llvm::Constant *constScalar)
Returns an integer or float attribute for the provided scalar constant constScalar or nullptr if the ...
static SetVector< llvm::BasicBlock * > getTopologicallySortedBlocks(ArrayRef< llvm::BasicBlock * > basicBlocks)
Get a topologically sorted list of blocks for the given basic blocks.
static std::string diagMD(const llvm::Metadata *node, const llvm::Module *module)
static FailureOr< SmallVector< ModuleFlagProfileSummaryDetailedAttr > > convertProfileSummaryDetailed(ModuleOp mlirModule, const llvm::Module *llvmModule, const llvm::MDOperand &summaryMD)
static FailureOr< uint64_t > convertInt64FromKeyValueTuple(ModuleOp mlirModule, const llvm::Module *llvmModule, const llvm::MDOperand &md, StringRef matchKey)
Extract an integer value from a two element tuple (<key, value>).
static SmallVector< Attribute > getSequenceConstantAsAttrs(OpBuilder &builder, llvm::ConstantDataSequential *constSequence)
Returns an integer or float attribute array for the provided constant sequence constSequence or nullp...
static llvm::ManagedStatic< PassManagerOptions > options
static void contract(RootOrderingGraph &graph, ArrayRef< Value > cycle, const DenseMap< Value, unsigned > &parentDepths, DenseMap< Value, Value > &actualSource, DenseMap< Value, Value > &actualTarget)
Contracts the specified cycle in the given graph in-place.
Attributes are known-constant values of operations.
This class represents an argument of a Block.
Block represents an ordered list of Operations.
Operation * getTerminator()
Get the terminator operation of this block.
BlockArgument addArgument(Type type, Location loc)
Add one value to the argument list.
Operation * getParentOp()
Returns the closest surrounding operation that contains this block.
IntegerAttr getI32IntegerAttr(int32_t value)
IntegerAttr getIntegerAttr(Type type, int64_t value)
ArrayAttr getI32ArrayAttr(ArrayRef< int32_t > values)
FloatAttr getFloatAttr(Type type, double value)
IntegerAttr getI64IntegerAttr(int64_t value)
StringAttr getStringAttr(const Twine &bytes)
TypedAttr getZeroAttr(Type type)
MLIRContext * getContext() const
ArrayAttr getArrayAttr(ArrayRef< Attribute > value)
DictionaryAttr getDictionaryAttr(ArrayRef< NamedAttribute > value)
NamedAttribute getNamedAttr(StringRef name, Attribute val)
ArrayAttr getStrArrayAttr(ArrayRef< StringRef > values)
Attr getAttr(Args &&...args)
Get or construct an instance of the attribute Attr with provided arguments.
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
static DistinctAttr create(Attribute referencedAttr)
Creates a distinct attribute that associates a referenced attribute with a unique identifier.
A class for computing basic dominance information.
static FileLineColLoc get(StringAttr filename, unsigned line, unsigned column)
A symbol reference with a reference path containing a single element.
static FlatSymbolRefAttr get(StringAttr value)
Construct a symbol reference for the given value name.
StringRef getValue() const
Returns the name of the held symbol reference.
Interface collection for the import of LLVM IR that dispatches to a concrete dialect interface implem...
LogicalResult convertInstruction(OpBuilder &builder, llvm::Instruction *inst, ArrayRef< llvm::Value * > llvmOperands, LLVM::ModuleImport &moduleImport) const
Converts the LLVM instruction to an MLIR operation if a conversion exists.
LogicalResult convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst, LLVM::ModuleImport &moduleImport) const
Converts the LLVM intrinsic to an MLIR operation if a conversion exists.
LogicalResult setMetadataAttrs(OpBuilder &builder, unsigned kind, llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport) const
Attaches the given LLVM metadata to the imported operation if a conversion to one or more MLIR dialec...
bool isConvertibleMetadata(unsigned kind)
Returns true if the given LLVM IR metadata is convertible to an MLIR attribute.
bool isConvertibleInstruction(unsigned id)
Returns true if the given LLVM IR instruction is convertible to an MLIR operation.
bool isConvertibleIntrinsic(llvm::Intrinsic::ID id)
Returns true if the given LLVM IR intrinsic is convertible to an MLIR operation.
Module import implementation class that provides methods to import globals and functions from an LLVM...
LogicalResult convertIFuncs()
Converts all ifuncs of the LLVM module to MLIR variables.
LogicalResult convertIntrinsicArguments(ArrayRef< llvm::Value * > values, ArrayRef< llvm::OperandBundleUse > opBundles, bool requiresOpBundles, ArrayRef< unsigned > immArgPositions, ArrayRef< StringLiteral > immArgAttrNames, SmallVectorImpl< Value > &valuesOut, SmallVectorImpl< NamedAttribute > &attrsOut)
Converts the LLVM values for an intrinsic to mixed MLIR values and attributes for LLVM_IntrOpBase.
Location translateLoc(llvm::DILocation *loc)
Translates the debug location.
LogicalResult convertComdats()
Converts all comdat selectors of the LLVM module to MLIR comdat operations.
LogicalResult convertAliases()
Converts all aliases of the LLVM module to MLIR variables.
LogicalResult convertFunctions()
Converts all functions of the LLVM module to MLIR functions.
FailureOr< SmallVector< Value > > convertValues(ArrayRef< llvm::Value * > values)
Converts a range of LLVM values to a range of MLIR values using the convertValue method,...
DILocalVariableAttr matchLocalVariableAttr(llvm::Value *value)
Converts value to a local variable attribute.
LogicalResult convertLinkerOptionsMetadata()
Converts !llvm.linker.options metadata to the llvm.linker.options LLVM dialect operation.
void mapBlock(llvm::BasicBlock *llvm, Block *mlir)
Stores the mapping between an LLVM block and its MLIR counterpart.
void processFunctionAttributes(llvm::Function *func, LLVMFuncOp funcOp)
Converts function attributes of LLVM Function func into LLVM dialect attributes of LLVMFuncOp funcOp.
LogicalResult convertMetadata()
Converts all LLVM metadata nodes that translate to attributes such as alias analysis or access group ...
FailureOr< Value > convertValue(llvm::Value *value)
Converts an LLVM value to an MLIR value, or returns failure if the conversion fails.
LogicalResult initializeImportInterface()
Calls the LLVMImportInterface initialization that queries the registered dialect interfaces for the s...
void addDebugIntrinsic(llvm::CallInst *intrinsic)
Adds a debug intrinsics to the list of intrinsics that should be converted after the function convers...
LogicalResult convertIdentMetadata()
Converts !llvm.ident metadata to the llvm.ident LLVM ModuleOp attribute.
Block * lookupBlock(llvm::BasicBlock *block) const
Returns the MLIR block mapped to the given LLVM block.
FailureOr< Value > convertMetadataValue(llvm::Value *value)
Converts an LLVM metadata value to an MLIR value, or returns failure if the conversion fails.
FailureOr< SmallVector< AliasScopeAttr > > lookupAliasScopeAttrs(const llvm::MDNode *node) const
Returns the alias scope attributes that map to the alias scope nodes starting from the metadata node.
void setDisjointFlag(llvm::Instruction *inst, Operation *op) const
Sets the disjoint flag attribute for the imported operation op given the original instruction inst.
void mapNoResultOp(llvm::Instruction *llvm, Operation *mlir)
Stores a mapping between an LLVM instruction and the imported MLIR operation if the operation returns...
void convertModuleLevelAsm()
Converts the module level asm of the LLVM module to an MLIR module level asm specification.
void setExactFlag(llvm::Instruction *inst, Operation *op) const
Sets the exact flag attribute for the imported operation op given the original instruction inst.
Type convertType(llvm::Type *type)
Converts the type from LLVM to MLIR LLVM dialect.
Operation * lookupOperation(llvm::Instruction *inst)
Returns the MLIR operation mapped to the given LLVM instruction.
ModuleImport(ModuleOp mlirModule, std::unique_ptr< llvm::Module > llvmModule, bool emitExpensiveWarnings, bool importEmptyDICompositeTypes, bool preferUnregisteredIntrinsics, bool importStructsAsLiterals)
DILabelAttr matchLabelAttr(llvm::Value *value)
Converts value to a label attribute. Asserts if the matching fails.
FloatAttr matchFloatAttr(llvm::Value *value)
Converts value to a float attribute. Asserts if the matching fails.
LoopAnnotationAttr translateLoopAnnotationAttr(const llvm::MDNode *node, Location loc) const
Returns the loop annotation attribute that corresponds to the given LLVM loop metadata node.
void setFastmathFlagsAttr(llvm::Instruction *inst, Operation *op) const
Sets the fastmath flags attribute for the imported operation op given the original instruction inst.
FailureOr< SmallVector< AliasScopeAttr > > matchAliasScopeAttrs(llvm::Value *value)
Converts value to an array of alias scopes or returns failure if the conversion fails.
Value lookupValue(llvm::Value *value)
Returns the MLIR value mapped to the given LLVM value.
LogicalResult processFunction(llvm::Function *func)
Imports func into the current module.
LogicalResult convertDependentLibrariesMetadata()
Converts !llvm.dependent-libraries metadata to llvm.dependent_libraries LLVM ModuleOp attribute.
RoundingModeAttr matchRoundingModeAttr(llvm::Value *value)
Converts value to a rounding mode attribute.
void convertTargetTriple()
Converts target triple of the LLVM module to an MLIR target triple specification.
void convertArgAndResultAttrs(llvm::CallBase *call, ArgAndResultAttrsOpInterface attrsOp, ArrayRef< unsigned > immArgPositions={})
Converts the argument and result attributes attached to call and adds them to attrsOp.
LogicalResult convertModuleFlagsMetadata()
Converts !llvm.module.flags metadata.
void mapValue(llvm::Value *llvm, Value mlir)
Stores the mapping between an LLVM value and its MLIR counterpart.
FailureOr< SmallVector< AccessGroupAttr > > lookupAccessGroupAttrs(const llvm::MDNode *node) const
Returns the access group attributes that map to the access group nodes starting from the access group...
LogicalResult convertGlobals()
Converts all global variables of the LLVM module to MLIR global variables.
void setIntegerOverflowFlags(llvm::Instruction *inst, Operation *op) const
Sets the integer overflow flags (nsw/nuw) attribute for the imported operation op given the original ...
LogicalResult convertCommandlineMetadata()
Converts !llvm.commandline metadata to the llvm.commandline LLVM ModuleOp attribute.
FPExceptionBehaviorAttr matchFPExceptionBehaviorAttr(llvm::Value *value)
Converts value to a FP exception behavior attribute.
void setNonNegFlag(llvm::Instruction *inst, Operation *op) const
Sets the nneg flag attribute for the imported operation op given the original instruction inst.
FailureOr< DereferenceableAttr > translateDereferenceableAttr(const llvm::MDNode *node, unsigned kindID)
Returns the dereferenceable attribute that corresponds to the given LLVM dereferenceable or dereferen...
LogicalResult convertDataLayout()
Converts the data layout of the LLVM module to an MLIR data layout specification.
IntegerAttr matchIntegerAttr(llvm::Value *value)
Converts value to an integer attribute. Asserts if the matching fails.
Helper class that translates an LLVM data layout string to an MLIR data layout specification.
StringRef getLastToken() const
Returns the last data layout token that has been processed before the data layout translation failed.
ArrayRef< StringRef > getUnhandledTokens() const
Returns the data layout tokens that have not been handled during the data layout translation.
DataLayoutSpecInterface getDataLayoutSpec() const
Returns the MLIR data layout specification translated from the LLVM data layout.
A helper class that converts llvm.loop metadata nodes into corresponding LoopAnnotationAttrs and llvm...
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
std::vector< StringRef > getAvailableDialects()
Return information about all available dialects in the registry in this context.
void loadAllAvailableDialects()
Load all dialects available in the registry in this context.
RAII guard to reset the insertion point of the builder when destroyed.
This class helps build Operations.
Block * createBlock(Region *parent, Region::iterator insertPt={}, TypeRange argTypes={}, ArrayRef< Location > locs={})
Add new block with 'argTypes' arguments and set the insertion point to the end of it.
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
void setInsertionPointAfterValue(Value val)
Sets the insertion point to the node after the specified value.
void setInsertionPointAfter(Operation *op)
Sets the insertion point to the node after the specified operation, which will cause subsequent inser...
Block * getInsertionBlock() const
Return the block the current insertion point belongs to.
This class provides the API for ops that are known to be terminators.
This provides public APIs that all operations should have.
Operation is the basic unit of execution within MLIR.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
Location getLoc()
The source location the operation was defined or derived from.
OpTy get() const
Allow accessing the internal op.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
bool isIntOrFloat() const
Return true if this is an integer (of any signedness) or a float type.
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
static DenseArrayAttrImpl get(MLIRContext *context, ArrayRef< int32_t > content)
Builder from ArrayRef<T>.
DominanceInfoNode * getNode(Block *a)
Return the dominance node from the Region containing block A.
static llvm::ArrayRef< std::pair< llvm::Attribute::AttrKind, llvm::StringRef > > getAttrKindToNameMapping()
Returns a list of pairs that each hold a mapping from LLVM attribute kinds to their corresponding str...
FloatType getFloatType(MLIRContext *context, unsigned width)
Returns a supported MLIR floating point type of the given bit width or null if the bit width is not s...
bool isCompatibleVectorType(Type type)
Returns true if the given type is a vector type compatible with the LLVM dialect.
llvm::ElementCount getVectorNumElements(Type type)
Returns the element count of any LLVM-compatible vector type.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Include the generated interface declarations.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
InFlightDiagnostic emitWarning(Location loc)
Utility method to emit a warning message using this location.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.
OwningOpRef< ModuleOp > translateLLVMIRToModule(std::unique_ptr< llvm::Module > llvmModule, MLIRContext *context, bool emitExpensiveWarnings=true, bool dropDICompositeTypeElements=false, bool loadAllDialects=true, bool preferUnregisteredIntrinsics=false, bool importStructsAsLiterals=false)
Translates the LLVM module into an MLIR module living in the given context.