30 #include "llvm/ADT/DepthFirstIterator.h"
31 #include "llvm/ADT/PostOrderIterator.h"
32 #include "llvm/ADT/ScopeExit.h"
33 #include "llvm/ADT/StringSet.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"
153 for (llvm::BasicBlock *basicBlock : basicBlocks) {
154 if (!blocks.contains(basicBlock)) {
155 llvm::ReversePostOrderTraversal<llvm::BasicBlock *> traversal(basicBlock);
156 blocks.insert_range(traversal);
159 assert(blocks.size() == basicBlocks.size() &&
"some blocks are not sorted");
164 std::unique_ptr<llvm::Module> llvmModule,
165 bool emitExpensiveWarnings,
166 bool importEmptyDICompositeTypes,
167 bool preferUnregisteredIntrinsics,
168 bool importStructsAsLiterals)
170 mlirModule(mlirModule), llvmModule(std::move(llvmModule)),
172 typeTranslator(*mlirModule->
getContext(), importStructsAsLiterals),
174 mlirModule, importEmptyDICompositeTypes)),
175 loopAnnotationImporter(
177 emitExpensiveWarnings(emitExpensiveWarnings),
178 preferUnregisteredIntrinsics(preferUnregisteredIntrinsics) {
182 ComdatOp ModuleImport::getGlobalComdatOp() {
184 return globalComdatOp;
190 globalInsertionOp = globalComdatOp;
191 return globalComdatOp;
194 LogicalResult ModuleImport::processTBAAMetadata(
const llvm::MDNode *node) {
199 auto getIdentityIfRootNode =
200 [&](
const llvm::MDNode *node) -> FailureOr<std::optional<StringRef>> {
204 if (node->getNumOperands() > 1)
207 if (node->getNumOperands() == 1)
208 if (
const auto *op0 = dyn_cast<const llvm::MDString>(node->getOperand(0)))
209 return std::optional<StringRef>{op0->getString()};
210 return std::optional<StringRef>{};
220 auto isTypeDescriptorNode = [&](
const llvm::MDNode *node,
221 StringRef *identity =
nullptr,
223 nullptr) -> std::optional<bool> {
224 unsigned numOperands = node->getNumOperands();
233 const auto *identityNode =
234 dyn_cast<const llvm::MDString>(node->getOperand(0));
240 *identity = identityNode->getString();
242 for (
unsigned pairNum = 0, e = numOperands / 2; pairNum < e; ++pairNum) {
243 const auto *memberNode =
244 dyn_cast<const llvm::MDNode>(node->getOperand(2 * pairNum + 1));
246 emitError(loc) <<
"operand '" << 2 * pairNum + 1 <<
"' must be MDNode: "
247 <<
diagMD(node, llvmModule.get());
251 if (2 * pairNum + 2 >= numOperands) {
253 if (numOperands != 2) {
254 emitError(loc) <<
"missing member offset: "
255 <<
diagMD(node, llvmModule.get());
259 auto *offsetCI = llvm::mdconst::dyn_extract<llvm::ConstantInt>(
260 node->getOperand(2 * pairNum + 2));
262 emitError(loc) <<
"operand '" << 2 * pairNum + 2
263 <<
"' must be ConstantInt: "
264 <<
diagMD(node, llvmModule.get());
267 offset = offsetCI->getZExtValue();
272 cast<TBAANodeAttr>(tbaaMapping.lookup(memberNode)), offset));
285 auto isTagNode = [&](
const llvm::MDNode *node,
286 TBAATypeDescriptorAttr *baseAttr =
nullptr,
287 TBAATypeDescriptorAttr *accessAttr =
nullptr,
288 int64_t *offset =
nullptr,
289 bool *isConstant =
nullptr) -> std::optional<bool> {
297 unsigned numOperands = node->getNumOperands();
298 if (numOperands != 3 && numOperands != 4)
300 const auto *baseMD = dyn_cast<const llvm::MDNode>(node->getOperand(0));
301 const auto *accessMD = dyn_cast<const llvm::MDNode>(node->getOperand(1));
303 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(2));
304 if (!baseMD || !accessMD || !offsetCI)
311 if (accessMD->getNumOperands() < 1 ||
312 !isa<llvm::MDString>(accessMD->getOperand(0)))
314 bool isConst =
false;
315 if (numOperands == 4) {
317 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(3));
319 emitError(loc) <<
"operand '3' must be ConstantInt: "
320 <<
diagMD(node, llvmModule.get());
323 isConst = isConstantCI->getValue()[0];
326 *baseAttr = cast<TBAATypeDescriptorAttr>(tbaaMapping.lookup(baseMD));
328 *accessAttr = cast<TBAATypeDescriptorAttr>(tbaaMapping.lookup(accessMD));
330 *offset = offsetCI->getZExtValue();
332 *isConstant = isConst;
341 workList.push_back(node);
342 while (!workList.empty()) {
343 const llvm::MDNode *current = workList.back();
344 if (tbaaMapping.contains(current)) {
353 bool anyChildNotConverted =
false;
354 for (
const llvm::MDOperand &operand : current->operands())
355 if (
auto *childNode = dyn_cast_or_null<const llvm::MDNode>(operand.get()))
356 if (!tbaaMapping.contains(childNode)) {
357 workList.push_back(childNode);
358 anyChildNotConverted =
true;
361 if (anyChildNotConverted) {
366 if (!seen.insert(current).second)
367 return emitError(loc) <<
"has cycle in TBAA graph: "
368 <<
diagMD(current, llvmModule.get());
376 FailureOr<std::optional<StringRef>> rootNodeIdentity =
377 getIdentityIfRootNode(current);
378 if (succeeded(rootNodeIdentity)) {
379 StringAttr stringAttr = *rootNodeIdentity
384 tbaaMapping.insert({current, builder.
getAttr<TBAARootAttr>(stringAttr)});
390 if (std::optional<bool> isValid =
391 isTypeDescriptorNode(current, &identity, &members)) {
392 assert(isValid.value() &&
"type descriptor node must be valid");
394 tbaaMapping.insert({current, builder.
getAttr<TBAATypeDescriptorAttr>(
395 identity, members)});
399 TBAATypeDescriptorAttr baseAttr, accessAttr;
402 if (std::optional<bool> isValid =
403 isTagNode(current, &baseAttr, &accessAttr, &offset, &isConstant)) {
404 assert(isValid.value() &&
"access tag node must be valid");
406 {current, builder.
getAttr<TBAATagAttr>(baseAttr, accessAttr, offset,
411 return emitError(loc) <<
"unsupported TBAA node format: "
412 <<
diagMD(current, llvmModule.get());
418 ModuleImport::processAccessGroupMetadata(
const llvm::MDNode *node) {
420 if (failed(loopAnnotationImporter->translateAccessGroup(node, loc)))
421 return emitError(loc) <<
"unsupported access group node: "
422 <<
diagMD(node, llvmModule.get());
427 ModuleImport::processAliasScopeMetadata(
const llvm::MDNode *node) {
430 auto verifySelfRef = [](
const llvm::MDNode *node) {
431 return node->getNumOperands() != 0 &&
432 node == dyn_cast<llvm::MDNode>(node->getOperand(0));
434 auto verifySelfRefOrString = [](
const llvm::MDNode *node) {
435 return node->getNumOperands() != 0 &&
436 (node == dyn_cast<llvm::MDNode>(node->getOperand(0)) ||
437 isa<llvm::MDString>(node->getOperand(0)));
440 auto verifyDescription = [](
const llvm::MDNode *node,
unsigned idx) {
441 return idx >= node->getNumOperands() ||
442 isa<llvm::MDString>(node->getOperand(idx));
445 auto getIdAttr = [&](
const llvm::MDNode *node) ->
Attribute {
446 if (verifySelfRef(node))
449 auto name = cast<llvm::MDString>(node->getOperand(0));
454 auto createAliasScopeDomainOp = [&](
const llvm::MDNode *aliasDomain) {
455 StringAttr description =
nullptr;
456 if (aliasDomain->getNumOperands() >= 2)
457 if (
auto *operand = dyn_cast<llvm::MDString>(aliasDomain->getOperand(1)))
459 Attribute idAttr = getIdAttr(aliasDomain);
460 return builder.
getAttr<AliasScopeDomainAttr>(idAttr, description);
464 for (
const llvm::MDOperand &operand : node->operands()) {
465 if (
const auto *scope = dyn_cast<llvm::MDNode>(operand)) {
466 llvm::AliasScopeNode aliasScope(scope);
467 const llvm::MDNode *domain = aliasScope.getDomain();
473 if (!verifySelfRefOrString(scope) || !domain ||
474 !verifyDescription(scope, 2))
475 return emitError(loc) <<
"unsupported alias scope node: "
476 <<
diagMD(scope, llvmModule.get());
477 if (!verifySelfRefOrString(domain) || !verifyDescription(domain, 1))
478 return emitError(loc) <<
"unsupported alias domain node: "
479 <<
diagMD(domain, llvmModule.get());
481 if (aliasScopeMapping.contains(scope))
485 auto it = aliasScopeMapping.find(aliasScope.getDomain());
486 if (it == aliasScopeMapping.end()) {
487 auto aliasScopeDomainOp = createAliasScopeDomainOp(domain);
488 it = aliasScopeMapping.try_emplace(domain, aliasScopeDomainOp).first;
492 StringAttr description =
nullptr;
493 if (!aliasScope.getName().empty())
496 auto aliasScopeOp = builder.
getAttr<AliasScopeAttr>(
497 idAttr, cast<AliasScopeDomainAttr>(it->second), description);
499 aliasScopeMapping.try_emplace(aliasScope.getNode(), aliasScopeOp);
505 FailureOr<SmallVector<AliasScopeAttr>>
508 aliasScopes.reserve(node->getNumOperands());
509 for (
const llvm::MDOperand &operand : node->operands()) {
510 auto *node = cast<llvm::MDNode>(operand.get());
511 aliasScopes.push_back(
512 dyn_cast_or_null<AliasScopeAttr>(aliasScopeMapping.lookup(node)));
515 if (llvm::is_contained(aliasScopes,
nullptr))
521 debugIntrinsics.insert(intrinsic);
525 llvm::MDTuple *mdTuple) {
526 auto getLLVMFunction =
527 [&](
const llvm::MDOperand &funcMDO) -> llvm::Function * {
528 auto *f = cast_or_null<llvm::ValueAsMetadata>(funcMDO);
532 auto *llvmFn = cast<llvm::Function>(f->getValue()->stripPointerCasts());
538 for (
unsigned i = 0; i < mdTuple->getNumOperands(); i++) {
539 const llvm::MDOperand &mdo = mdTuple->getOperand(i);
540 auto *cgEntry = cast<llvm::MDNode>(mdo);
541 llvm::Constant *llvmConstant =
542 cast<llvm::ConstantAsMetadata>(cgEntry->getOperand(2))->getValue();
543 uint64_t count = cast<llvm::ConstantInt>(llvmConstant)->getZExtValue();
544 auto *fromFn = getLLVMFunction(cgEntry->getOperand(0));
545 auto *toFn = getLLVMFunction(cgEntry->getOperand(1));
548 mlirModule->getContext(),
562 const llvm::Module *llvmModule,
563 const llvm::MDOperand &md) {
564 auto *tupleEntry = dyn_cast_or_null<llvm::MDTuple>(md);
565 if (!tupleEntry || tupleEntry->getNumOperands() != 2)
567 <<
"expected 2-element tuple metadata: " <<
diagMD(md, llvmModule);
575 ModuleOp mlirModule,
const llvm::Module *llvmModule,
576 const llvm::MDOperand &md, StringRef matchKey,
bool optional =
false) {
580 auto *keyMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(0));
581 if (!keyMD || keyMD->getString() != matchKey) {
584 <<
"expected '" << matchKey <<
"' key, but found: "
585 <<
diagMD(tupleEntry->getOperand(0), llvmModule);
589 return dyn_cast<llvm::ConstantAsMetadata>(tupleEntry->getOperand(1));
595 static FailureOr<uint64_t>
597 const llvm::Module *llvmModule,
598 const llvm::MDOperand &md, StringRef matchKey) {
599 llvm::ConstantAsMetadata *valMD =
604 if (
auto *cstInt = dyn_cast<llvm::ConstantInt>(valMD->getValue()))
605 return cstInt->getZExtValue();
608 <<
"expected integer metadata value for key '" << matchKey
609 <<
"': " <<
diagMD(md, llvmModule);
613 static std::optional<ProfileSummaryFormatKind>
615 const llvm::MDOperand &formatMD) {
620 llvm::MDString *keyMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(0));
621 if (!keyMD || keyMD->getString() !=
"ProfileFormat") {
623 <<
"expected 'ProfileFormat' key: "
624 <<
diagMD(tupleEntry->getOperand(0), llvmModule);
628 llvm::MDString *valMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(1));
629 std::optional<ProfileSummaryFormatKind> fmtKind =
630 symbolizeProfileSummaryFormatKind(valMD->getString());
633 <<
"expected 'SampleProfile', 'InstrProf' or 'CSInstrProf' values, "
635 <<
diagMD(valMD, llvmModule);
642 static FailureOr<SmallVector<ModuleFlagProfileSummaryDetailedAttr>>
644 const llvm::Module *llvmModule,
645 const llvm::MDOperand &summaryMD) {
650 llvm::MDString *keyMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(0));
651 if (!keyMD || keyMD->getString() !=
"DetailedSummary") {
653 <<
"expected 'DetailedSummary' key: "
654 <<
diagMD(tupleEntry->getOperand(0), llvmModule);
658 llvm::MDTuple *entriesMD = dyn_cast<llvm::MDTuple>(tupleEntry->getOperand(1));
661 <<
"expected tuple value for 'DetailedSummary' key: "
662 <<
diagMD(tupleEntry->getOperand(1), llvmModule);
667 for (
auto &&entry : entriesMD->operands()) {
668 llvm::MDTuple *entryMD = dyn_cast<llvm::MDTuple>(entry);
669 if (!entryMD || entryMD->getNumOperands() != 3) {
671 <<
"'DetailedSummary' entry expects 3 operands: "
672 <<
diagMD(entry, llvmModule);
676 auto *op0 = dyn_cast<llvm::ConstantAsMetadata>(entryMD->getOperand(0));
677 auto *op1 = dyn_cast<llvm::ConstantAsMetadata>(entryMD->getOperand(1));
678 auto *op2 = dyn_cast<llvm::ConstantAsMetadata>(entryMD->getOperand(2));
679 if (!op0 || !op1 || !op2) {
681 <<
"expected only integer entries in 'DetailedSummary': "
682 <<
diagMD(entry, llvmModule);
687 mlirModule->getContext(),
688 cast<llvm::ConstantInt>(op0->getValue())->getZExtValue(),
689 cast<llvm::ConstantInt>(op1->getValue())->getZExtValue(),
690 cast<llvm::ConstantInt>(op2->getValue())->getZExtValue());
691 detailedSummary.push_back(detaildSummaryEntry);
693 return detailedSummary;
698 const llvm::Module *llvmModule,
699 llvm::MDTuple *mdTuple) {
700 unsigned profileNumEntries = mdTuple->getNumOperands();
701 if (profileNumEntries < 8) {
703 <<
"expected at 8 entries in 'ProfileSummary': "
704 <<
diagMD(mdTuple, llvmModule);
708 unsigned summayIdx = 0;
709 auto checkOptionalPosition = [&](
const llvm::MDOperand &md,
710 StringRef matchKey) -> LogicalResult {
714 if (summayIdx + 1 >= profileNumEntries) {
716 <<
"the last summary entry is '" << matchKey
717 <<
"', expected 'DetailedSummary': " <<
diagMD(md, llvmModule);
724 auto getOptIntValue =
725 [&](
const llvm::MDOperand &md,
726 StringRef matchKey) -> FailureOr<std::optional<uint64_t>> {
729 return FailureOr<std::optional<uint64_t>>(std::nullopt);
730 if (checkOptionalPosition(md, matchKey).failed())
732 FailureOr<uint64_t> val =
739 auto getOptDoubleValue = [&](
const llvm::MDOperand &md,
740 StringRef matchKey) -> FailureOr<FloatAttr> {
745 if (
auto *cstFP = dyn_cast<llvm::ConstantFP>(valMD->getValue())) {
746 if (checkOptionalPosition(md, matchKey).failed())
749 cstFP->getValueAPF());
752 <<
"expected double metadata value for key '" << matchKey
753 <<
"': " <<
diagMD(md, llvmModule);
760 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++));
761 if (!format.has_value())
765 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
"TotalCount");
766 if (failed(totalCount))
770 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
"MaxCount");
771 if (failed(maxCount))
775 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
777 if (failed(maxInternalCount))
781 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
783 if (failed(maxFunctionCount))
787 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
"NumCounts");
788 if (failed(numCounts))
792 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
"NumFunctions");
793 if (failed(numFunctions))
797 FailureOr<std::optional<uint64_t>> isPartialProfile =
798 getOptIntValue(mdTuple->getOperand(summayIdx),
"IsPartialProfile");
799 if (failed(isPartialProfile))
801 if (isPartialProfile->has_value())
804 FailureOr<FloatAttr> partialProfileRatio =
805 getOptDoubleValue(mdTuple->getOperand(summayIdx),
"PartialProfileRatio");
806 if (failed(partialProfileRatio))
808 if (*partialProfileRatio)
812 FailureOr<SmallVector<ModuleFlagProfileSummaryDetailedAttr>> detailed =
814 mdTuple->getOperand(summayIdx));
815 if (failed(detailed))
820 mlirModule->getContext(), *format, *totalCount, *maxCount,
821 *maxInternalCount, *maxFunctionCount, *numCounts, *numFunctions,
822 *isPartialProfile, *partialProfileRatio, *detailed);
829 const llvm::Module *llvmModule, StringRef key,
830 llvm::MDTuple *mdTuple) {
831 if (key == LLVMDialect::getModuleFlagKeyCGProfileName())
833 if (key == LLVMDialect::getModuleFlagKeyProfileSummaryName())
841 llvmModule->getModuleFlagsMetadata(llvmModuleFlags);
844 for (
const auto [behavior, key, val] : llvmModuleFlags) {
846 if (
auto *constInt = llvm::mdconst::dyn_extract<llvm::ConstantInt>(val)) {
848 }
else if (
auto *mdString = dyn_cast<llvm::MDString>(val)) {
850 }
else if (
auto *mdTuple = dyn_cast<llvm::MDTuple>(val)) {
852 key->getString(), mdTuple);
857 <<
"unsupported module flag value for key '" << key->getString()
858 <<
"' : " <<
diagMD(val, llvmModule.get());
862 moduleFlags.push_back(builder.
getAttr<ModuleFlagAttr>(
863 convertModFlagBehaviorFromLLVM(behavior),
867 if (!moduleFlags.empty())
868 builder.
create<LLVM::ModuleFlagsOp>(mlirModule.getLoc(),
875 for (
const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
876 if (named.getName() !=
"llvm.linker.options")
879 for (
const llvm::MDNode *node : named.operands()) {
881 options.reserve(node->getNumOperands());
882 for (
const llvm::MDOperand &option : node->operands())
883 options.push_back(cast<llvm::MDString>(option)->getString());
884 builder.
create<LLVM::LinkerOptionsOp>(mlirModule.getLoc(),
892 for (
const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
893 if (named.getName() !=
"llvm.dependent-libraries")
896 for (
const llvm::MDNode *node : named.operands()) {
897 if (node->getNumOperands() == 1)
898 if (
auto *mdString = dyn_cast<llvm::MDString>(node->getOperand(0)))
899 libraries.push_back(mdString->getString());
901 if (!libraries.empty())
902 mlirModule->setAttr(LLVM::LLVMDialect::getDependentLibrariesAttrName(),
909 for (
const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
912 if (named.getName() != LLVMDialect::getIdentAttrName())
915 if (named.getNumOperands() == 1)
916 if (
auto *md = dyn_cast<llvm::MDNode>(named.getOperand(0)))
917 if (md->getNumOperands() == 1)
918 if (
auto *mdStr = dyn_cast<llvm::MDString>(md->getOperand(0)))
919 mlirModule->setAttr(LLVMDialect::getIdentAttrName(),
926 for (
const llvm::NamedMDNode &nmd : llvmModule->named_metadata()) {
929 if (nmd.getName() != LLVMDialect::getCommandlineAttrName())
932 if (nmd.getNumOperands() == 1)
933 if (
auto *md = dyn_cast<llvm::MDNode>(nmd.getOperand(0)))
934 if (md->getNumOperands() == 1)
935 if (
auto *mdStr = dyn_cast<llvm::MDString>(md->getOperand(0)))
936 mlirModule->setAttr(LLVMDialect::getCommandlineAttrName(),
945 for (
const llvm::Function &func : llvmModule->functions()) {
946 for (
const llvm::Instruction &inst : llvm::instructions(func)) {
948 if (llvm::MDNode *node =
949 inst.getMetadata(llvm::LLVMContext::MD_access_group))
950 if (failed(processAccessGroupMetadata(node)))
954 llvm::AAMDNodes aliasAnalysisNodes = inst.getAAMetadata();
955 if (!aliasAnalysisNodes)
957 if (aliasAnalysisNodes.TBAA)
958 if (failed(processTBAAMetadata(aliasAnalysisNodes.TBAA)))
960 if (aliasAnalysisNodes.Scope)
961 if (failed(processAliasScopeMetadata(aliasAnalysisNodes.Scope)))
963 if (aliasAnalysisNodes.NoAlias)
964 if (failed(processAliasScopeMetadata(aliasAnalysisNodes.NoAlias)))
981 void ModuleImport::processComdat(
const llvm::Comdat *comdat) {
982 if (comdatMapping.contains(comdat))
985 ComdatOp comdatOp = getGlobalComdatOp();
988 auto selectorOp = builder.
create<ComdatSelectorOp>(
989 mlirModule.getLoc(), comdat->getName(),
990 convertComdatFromLLVM(comdat->getSelectionKind()));
994 comdatMapping.try_emplace(comdat, symbolRef);
998 for (llvm::GlobalVariable &globalVar : llvmModule->globals())
999 if (globalVar.hasComdat())
1000 processComdat(globalVar.getComdat());
1001 for (llvm::Function &func : llvmModule->functions())
1002 if (func.hasComdat())
1003 processComdat(func.getComdat());
1008 for (llvm::GlobalVariable &globalVar : llvmModule->globals()) {
1011 if (failed(convertGlobalCtorsAndDtors(&globalVar))) {
1013 <<
"unhandled global variable: " <<
diag(globalVar);
1017 if (failed(convertGlobal(&globalVar))) {
1019 <<
"unhandled global variable: " <<
diag(globalVar);
1026 for (llvm::GlobalAlias &alias : llvmModule->aliases()) {
1027 if (failed(convertAlias(&alias))) {
1029 <<
"unhandled global alias: " <<
diag(alias);
1036 Location loc = mlirModule.getLoc();
1039 return emitError(loc,
"cannot translate data layout: ")
1043 emitWarning(loc,
"unhandled data layout token: ") << token;
1045 mlirModule->setAttr(DLTIDialect::kDataLayoutAttrName,
1051 mlirModule->setAttr(
1052 LLVM::LLVMDialect::getTargetTripleAttrName(),
1053 builder.
getStringAttr(llvmModule->getTargetTriple().str()));
1057 for (llvm::Function &func : llvmModule->functions())
1063 void ModuleImport::setNonDebugMetadataAttrs(llvm::Instruction *inst,
1066 inst->getAllMetadataOtherThanDebugLoc(allMetadata);
1067 for (
auto &[
kind, node] : allMetadata) {
1071 if (emitExpensiveWarnings) {
1072 Location loc = debugImporter->translateLoc(inst->getDebugLoc());
1074 <<
diagMD(node, llvmModule.get()) <<
" on "
1083 auto iface = cast<IntegerOverflowFlagsInterface>(op);
1085 IntegerOverflowFlags value = {};
1086 value = bitEnumSet(value, IntegerOverflowFlags::nsw, inst->hasNoSignedWrap());
1088 bitEnumSet(value, IntegerOverflowFlags::nuw, inst->hasNoUnsignedWrap());
1090 iface.setOverflowFlags(value);
1094 auto iface = cast<ExactFlagInterface>(op);
1096 iface.setIsExact(inst->isExact());
1101 auto iface = cast<DisjointFlagInterface>(op);
1102 auto instDisjoint = cast<llvm::PossiblyDisjointInst>(inst);
1104 iface.setIsDisjoint(instDisjoint->isDisjoint());
1108 auto iface = cast<NonNegFlagInterface>(op);
1110 iface.setNonNeg(inst->hasNonNeg());
1115 auto iface = cast<FastmathFlagsInterface>(op);
1121 if (!isa<llvm::FPMathOperator>(inst))
1123 llvm::FastMathFlags flags = inst->getFastMathFlags();
1126 FastmathFlags value = {};
1127 value = bitEnumSet(value, FastmathFlags::nnan, flags.noNaNs());
1128 value = bitEnumSet(value, FastmathFlags::ninf, flags.noInfs());
1129 value = bitEnumSet(value, FastmathFlags::nsz, flags.noSignedZeros());
1130 value = bitEnumSet(value, FastmathFlags::arcp, flags.allowReciprocal());
1132 value = bitEnumSet(value, FastmathFlags::afn, flags.approxFunc());
1133 value = bitEnumSet(value, FastmathFlags::reassoc, flags.allowReassoc());
1135 iface->setAttr(iface.getFastmathAttrName(), attr);
1147 if (numElements.isScalable()) {
1149 <<
"scalable vectors not supported";
1154 Type elementType = cast<VectorType>(type).getElementType();
1159 shape.push_back(numElements.getKnownMinValue());
1163 Type ModuleImport::getBuiltinTypeForAttr(
Type type) {
1178 while (
auto arrayType = dyn_cast<LLVMArrayType>(type)) {
1179 arrayShape.push_back(arrayType.getNumElements());
1180 type = arrayType.getElementType();
1190 llvm::Constant *constScalar) {
1194 if (
auto *constInt = dyn_cast<llvm::ConstantInt>(constScalar)) {
1197 constInt->getValue());
1201 if (
auto *constFloat = dyn_cast<llvm::ConstantFP>(constScalar)) {
1202 llvm::Type *type = constFloat->getType();
1203 FloatType floatType =
1209 <<
"unexpected floating-point type";
1212 return builder.
getFloatAttr(floatType, constFloat->getValueAPF());
1221 llvm::ConstantDataSequential *constSequence) {
1223 elementAttrs.reserve(constSequence->getNumElements());
1224 for (
auto idx : llvm::seq<int64_t>(0, constSequence->getNumElements())) {
1225 llvm::Constant *constElement = constSequence->getElementAsConstant(idx);
1228 return elementAttrs;
1231 Attribute ModuleImport::getConstantAsAttr(llvm::Constant *constant) {
1237 auto getConstantShape = [&](llvm::Type *type) {
1238 return llvm::dyn_cast_if_present<ShapedType>(
1244 if (
auto *constArray = dyn_cast<llvm::ConstantDataSequential>(constant)) {
1245 if (constArray->isString())
1247 auto shape = getConstantShape(constArray->getType());
1251 auto *constVector = dyn_cast<llvm::ConstantDataVector>(constant);
1252 if (constVector && constVector->isSplat()) {
1255 builder, constVector->getElementAsConstant(0));
1266 if (
auto *constAggregate = dyn_cast<llvm::ConstantAggregate>(constant)) {
1267 auto shape = getConstantShape(constAggregate->getType());
1273 while (!workList.empty()) {
1274 llvm::Constant *current = workList.pop_back_val();
1277 if (
auto *constAggregate = dyn_cast<llvm::ConstantAggregate>(current)) {
1279 reverse(llvm::seq<int64_t>(0, constAggregate->getNumOperands())))
1280 workList.push_back(constAggregate->getAggregateElement(idx));
1285 if (
auto *constArray = dyn_cast<llvm::ConstantDataSequential>(current)) {
1288 elementAttrs.append(attrs.begin(), attrs.end());
1294 elementAttrs.push_back(scalarAttr);
1305 if (
auto *constZero = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1306 auto shape = llvm::dyn_cast_if_present<ShapedType>(
1307 getBuiltinTypeForAttr(
convertType(constZero->getType())));
1312 assert(splatAttr &&
"expected non-null zero attribute for scalar types");
1319 ModuleImport::getOrCreateNamelessSymbolName(llvm::GlobalVariable *globalVar) {
1320 assert(globalVar->getName().empty() &&
1321 "expected to work with a nameless global");
1322 auto [it, success] = namelessGlobals.try_emplace(globalVar);
1329 [
this](StringRef newName) {
return llvmModule->getNamedValue(newName); },
1332 it->getSecond() = symbolRef;
1338 if (globalInsertionOp)
1345 LogicalResult ModuleImport::convertAlias(llvm::GlobalAlias *alias) {
1350 AliasOp aliasOp = builder.
create<AliasOp>(
1351 mlirModule.getLoc(), type, convertLinkageFromLLVM(alias->getLinkage()),
1353 alias->isDSOLocal(),
1354 alias->isThreadLocal(),
1356 globalInsertionOp = aliasOp;
1360 setConstantInsertionPointToStart(block);
1361 FailureOr<Value> initializer = convertConstantExpr(alias->getAliasee());
1362 if (failed(initializer))
1364 builder.
create<ReturnOp>(aliasOp.getLoc(), *initializer);
1366 if (alias->hasAtLeastLocalUnnamedAddr())
1367 aliasOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(alias->getUnnamedAddr()));
1368 aliasOp.setVisibility_(convertVisibilityFromLLVM(alias->getVisibility()));
1373 LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
1378 if (globalVar->hasInitializer())
1379 valueAttr = getConstantAsAttr(globalVar->getInitializer());
1382 uint64_t alignment = 0;
1383 llvm::MaybeAlign maybeAlign = globalVar->getAlign();
1384 if (maybeAlign.has_value()) {
1385 llvm::Align align = *maybeAlign;
1386 alignment = align.value();
1393 globalVar->getDebugInfo(globalExpressions);
1395 for (llvm::DIGlobalVariableExpression *expr : globalExpressions) {
1396 DIGlobalVariableExpressionAttr globalExpressionAttr =
1397 debugImporter->translateGlobalVariableExpression(expr);
1398 globalExpressionAttrs.push_back(globalExpressionAttr);
1403 StringRef globalName = globalVar->getName();
1404 if (globalName.empty())
1405 globalName = getOrCreateNamelessSymbolName(globalVar).
getValue();
1407 GlobalOp globalOp = builder.
create<GlobalOp>(
1408 mlirModule.getLoc(), type, globalVar->isConstant(),
1409 convertLinkageFromLLVM(globalVar->getLinkage()), StringRef(globalName),
1410 valueAttr, alignment, globalVar->getAddressSpace(),
1411 globalVar->isDSOLocal(),
1412 globalVar->isThreadLocal(), SymbolRefAttr(),
1414 globalInsertionOp = globalOp;
1416 if (globalVar->hasInitializer() && !valueAttr) {
1419 setConstantInsertionPointToStart(block);
1420 FailureOr<Value> initializer =
1421 convertConstantExpr(globalVar->getInitializer());
1422 if (failed(initializer))
1424 builder.
create<ReturnOp>(globalOp.getLoc(), *initializer);
1426 if (globalVar->hasAtLeastLocalUnnamedAddr()) {
1427 globalOp.setUnnamedAddr(
1428 convertUnnamedAddrFromLLVM(globalVar->getUnnamedAddr()));
1430 if (globalVar->hasSection())
1431 globalOp.setSection(globalVar->getSection());
1432 globalOp.setVisibility_(
1433 convertVisibilityFromLLVM(globalVar->getVisibility()));
1435 if (globalVar->hasComdat())
1436 globalOp.setComdatAttr(comdatMapping.lookup(globalVar->getComdat()));
1442 ModuleImport::convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar) {
1443 if (!globalVar->hasInitializer() || !globalVar->hasAppendingLinkage())
1445 llvm::Constant *initializer = globalVar->getInitializer();
1447 bool knownInit = isa<llvm::ConstantArray>(initializer) ||
1448 isa<llvm::ConstantAggregateZero>(initializer);
1455 if (
auto *caz = dyn_cast<llvm::ConstantAggregateZero>(initializer)) {
1456 if (caz->getElementCount().getFixedValue() != 0)
1463 for (llvm::Value *operand : initializer->operands()) {
1464 auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
1465 if (!aggregate || aggregate->getNumOperands() != 3)
1468 auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
1469 auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
1470 auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
1471 if (!priority || !func || !data)
1474 auto *gv = dyn_cast_or_null<llvm::GlobalValue>(data);
1478 else if (data->isNullValue())
1484 priorities.push_back(priority->getValue().getZExtValue());
1485 dataList.push_back(dataAttr);
1492 globalInsertionOp = builder.
create<LLVM::GlobalCtorsOp>(
1497 globalInsertionOp = builder.
create<LLVM::GlobalDtorsOp>(
1504 ModuleImport::getConstantsToConvert(llvm::Constant *constant) {
1506 if (valueMapping.contains(constant))
1515 workList.insert(constant);
1516 while (!workList.empty()) {
1517 llvm::Constant *current = workList.back();
1520 if (isa<llvm::GlobalObject>(current) || isa<llvm::GlobalAlias>(current)) {
1521 orderedSet.insert(current);
1522 workList.pop_back();
1528 auto [adjacencyIt, inserted] = adjacencyLists.try_emplace(current);
1532 for (llvm::Value *operand : current->operands())
1533 if (
auto *constDependency = dyn_cast<llvm::Constant>(operand))
1534 adjacencyIt->getSecond().push_back(constDependency);
1537 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(current)) {
1538 unsigned numElements = constAgg->getElementCount().getFixedValue();
1539 for (
unsigned i = 0, e = numElements; i != e; ++i)
1540 adjacencyIt->getSecond().push_back(constAgg->getElementValue(i));
1546 if (adjacencyIt->getSecond().empty()) {
1547 orderedSet.insert(current);
1548 workList.pop_back();
1556 llvm::Constant *dependency = adjacencyIt->getSecond().pop_back_val();
1557 if (valueMapping.contains(dependency) || workList.contains(dependency) ||
1558 orderedSet.contains(dependency))
1560 workList.insert(dependency);
1566 FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
1570 if (
Attribute attr = getConstantAsAttr(constant)) {
1572 if (
auto symbolRef = dyn_cast<FlatSymbolRefAttr>(attr)) {
1573 return builder.
create<AddressOfOp>(loc, type, symbolRef.getValue())
1576 return builder.
create<ConstantOp>(loc, type, attr).getResult();
1580 if (
auto *nullPtr = dyn_cast<llvm::ConstantPointerNull>(constant)) {
1582 return builder.
create<ZeroOp>(loc, type).getResult();
1586 if (isa<llvm::ConstantTokenNone>(constant)) {
1587 return builder.
create<NoneTokenOp>(loc).getResult();
1591 if (
auto *poisonVal = dyn_cast<llvm::PoisonValue>(constant)) {
1593 return builder.
create<PoisonOp>(loc, type).getResult();
1597 if (
auto *undefVal = dyn_cast<llvm::UndefValue>(constant)) {
1599 return builder.
create<UndefOp>(loc, type).getResult();
1603 if (
auto *dsoLocalEquivalent = dyn_cast<llvm::DSOLocalEquivalent>(constant)) {
1606 .
create<DSOLocalEquivalentOp>(
1610 dsoLocalEquivalent->getGlobalValue()->getName()))
1615 if (
auto *globalObj = dyn_cast<llvm::GlobalObject>(constant)) {
1617 StringRef globalName = globalObj->getName();
1620 if (globalName.empty())
1622 getOrCreateNamelessSymbolName(cast<llvm::GlobalVariable>(globalObj));
1625 return builder.
create<AddressOfOp>(loc, type, symbolRef).getResult();
1629 if (
auto *globalAliasObj = dyn_cast<llvm::GlobalAlias>(constant)) {
1631 StringRef aliaseeName = globalAliasObj->getName();
1633 return builder.
create<AddressOfOp>(loc, type, symbolRef).getResult();
1637 if (
auto *constExpr = dyn_cast<llvm::ConstantExpr>(constant)) {
1643 llvm::Instruction *inst = constExpr->getAsInstruction();
1644 auto guard = llvm::make_scope_exit([&]() {
1645 assert(!noResultOpMapping.contains(inst) &&
1646 "expected constant expression to return a result");
1647 valueMapping.erase(inst);
1648 inst->deleteValue();
1652 assert(llvm::all_of(inst->operands(), [&](llvm::Value *value) {
1653 return valueMapping.contains(value);
1655 if (failed(processInstruction(inst)))
1661 if (isa<llvm::ConstantAggregate>(constant) ||
1662 isa<llvm::ConstantAggregateZero>(constant)) {
1665 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregate>(constant)) {
1666 elementValues.reserve(constAgg->getNumOperands());
1667 for (llvm::Value *operand : constAgg->operands())
1670 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1671 unsigned numElements = constAgg->getElementCount().getFixedValue();
1672 elementValues.reserve(numElements);
1673 for (
unsigned i = 0, e = numElements; i != e; ++i)
1674 elementValues.push_back(
lookupValue(constAgg->getElementValue(i)));
1676 assert(llvm::count(elementValues,
nullptr) == 0 &&
1677 "expected all elements have been converted before");
1681 bool isArrayOrStruct = isa<LLVMArrayType, LLVMStructType>(rootType);
1683 "unrecognized aggregate type");
1684 Value root = builder.
create<UndefOp>(loc, rootType);
1686 if (isArrayOrStruct) {
1687 root = builder.
create<InsertValueOp>(loc, root, it.value(), it.index());
1692 root = builder.
create<InsertElementOp>(loc, rootType, root, it.value(),
1699 if (
auto *constTargetNone = dyn_cast<llvm::ConstantTargetNone>(constant)) {
1700 LLVMTargetExtType targetExtType =
1701 cast<LLVMTargetExtType>(
convertType(constTargetNone->getType()));
1702 assert(targetExtType.hasProperty(LLVMTargetExtType::HasZeroInit) &&
1703 "target extension type does not support zero-initialization");
1706 return builder.
create<LLVM::ZeroOp>(loc, targetExtType).getRes();
1709 if (
auto *blockAddr = dyn_cast<llvm::BlockAddress>(constant)) {
1720 StringRef error =
"";
1722 if (isa<llvm::ConstantPtrAuth>(constant))
1723 error =
" since ptrauth(...) is unsupported";
1725 if (isa<llvm::NoCFIValue>(constant))
1726 error =
" since no_cfi is unsupported";
1728 if (isa<llvm::GlobalValue>(constant))
1729 error =
" since global value is unsupported";
1731 return emitError(loc) <<
"unhandled constant: " <<
diag(*constant) << error;
1734 FailureOr<Value> ModuleImport::convertConstantExpr(llvm::Constant *constant) {
1738 assert(!valueMapping.contains(constant) &&
1739 "expected constant has not been converted before");
1740 assert(constantInsertionBlock &&
1741 "expected the constant insertion block to be non-null");
1745 if (!constantInsertionOp)
1752 getConstantsToConvert(constant);
1753 for (llvm::Constant *constantToConvert : constantsToConvert) {
1754 FailureOr<Value> converted = convertConstant(constantToConvert);
1755 if (failed(converted))
1757 mapValue(constantToConvert, *converted);
1767 assert(!isa<llvm::MetadataAsValue>(value) &&
1768 "expected value to not be metadata");
1771 auto it = valueMapping.find(value);
1772 if (it != valueMapping.end())
1773 return it->getSecond();
1776 if (
auto *constant = dyn_cast<llvm::Constant>(value))
1777 return convertConstantExpr(constant);
1780 if (
auto *inst = dyn_cast<llvm::Instruction>(value))
1782 return emitError(loc) <<
"unhandled value: " <<
diag(*value);
1788 auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
1791 auto *node = dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
1794 value = node->getValue();
1797 auto it = valueMapping.find(value);
1798 if (it != valueMapping.end())
1799 return it->getSecond();
1802 if (
auto *constant = dyn_cast<llvm::Constant>(value))
1803 return convertConstantExpr(constant);
1807 FailureOr<SmallVector<Value>>
1810 remapped.reserve(values.size());
1811 for (llvm::Value *value : values) {
1813 if (failed(converted))
1815 remapped.push_back(*converted);
1825 assert(immArgPositions.size() == immArgAttrNames.size() &&
1826 "LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
1830 for (
auto [immArgPos, immArgName] :
1831 llvm::zip(immArgPositions, immArgAttrNames)) {
1832 auto &value = operands[immArgPos];
1833 auto *constant = llvm::cast<llvm::Constant>(value);
1835 assert(attr && attr.getType().isIntOrFloat() &&
1836 "expected immarg to be float or integer constant");
1838 attrsOut.push_back({nameAttr, attr});
1843 for (llvm::Value *value : operands) {
1847 if (failed(mlirValue))
1849 valuesOut.push_back(*mlirValue);
1854 if (requiresOpBundles) {
1855 opBundleSizes.reserve(opBundles.size());
1856 opBundleTagAttrs.reserve(opBundles.size());
1858 for (
const llvm::OperandBundleUse &bundle : opBundles) {
1859 opBundleSizes.push_back(bundle.Inputs.size());
1860 opBundleTagAttrs.push_back(
StringAttr::get(context, bundle.getTagName()));
1862 for (
const llvm::Use &opBundleOperand : bundle.Inputs) {
1863 auto operandMlirValue =
convertValue(opBundleOperand.get());
1864 if (failed(operandMlirValue))
1866 valuesOut.push_back(*operandMlirValue);
1871 auto opBundleSizesAttrNameAttr =
1873 attrsOut.push_back({opBundleSizesAttrNameAttr, opBundleSizesAttr});
1875 auto opBundleTagsAttr =
ArrayAttr::get(context, opBundleTagAttrs);
1876 auto opBundleTagsAttrNameAttr =
1878 attrsOut.push_back({opBundleTagsAttrNameAttr, opBundleTagsAttr});
1885 IntegerAttr integerAttr;
1887 bool success = succeeded(converted) &&
1889 assert(success &&
"expected a constant integer value");
1895 FloatAttr floatAttr;
1899 assert(success &&
"expected a constant float value");
1905 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1906 auto *node = cast<llvm::DILocalVariable>(nodeAsVal->getMetadata());
1907 return debugImporter->translate(node);
1911 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1912 auto *node = cast<llvm::DILabel>(nodeAsVal->getMetadata());
1913 return debugImporter->translate(node);
1916 FPExceptionBehaviorAttr
1918 auto *metadata = cast<llvm::MetadataAsValue>(value);
1919 auto *mdstr = cast<llvm::MDString>(metadata->getMetadata());
1920 std::optional<llvm::fp::ExceptionBehavior> optLLVM =
1921 llvm::convertStrToExceptionBehavior(mdstr->getString());
1922 assert(optLLVM &&
"Expecting FP exception behavior");
1923 return builder.
getAttr<FPExceptionBehaviorAttr>(
1924 convertFPExceptionBehaviorFromLLVM(*optLLVM));
1928 auto *metadata = cast<llvm::MetadataAsValue>(value);
1929 auto *mdstr = cast<llvm::MDString>(metadata->getMetadata());
1930 std::optional<llvm::RoundingMode> optLLVM =
1931 llvm::convertStrToRoundingMode(mdstr->getString());
1932 assert(optLLVM &&
"Expecting rounding mode");
1933 return builder.
getAttr<RoundingModeAttr>(
1934 convertRoundingModeFromLLVM(*optLLVM));
1937 FailureOr<SmallVector<AliasScopeAttr>>
1939 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1940 auto *node = cast<llvm::MDNode>(nodeAsVal->getMetadata());
1945 return debugImporter->translateLoc(loc);
1949 ModuleImport::convertBranchArgs(llvm::Instruction *branch,
1950 llvm::BasicBlock *target,
1952 for (
auto inst = target->begin(); isa<llvm::PHINode>(inst); ++inst) {
1953 auto *phiInst = cast<llvm::PHINode>(&*inst);
1954 llvm::Value *value = phiInst->getIncomingValueForBlock(branch->getParent());
1956 if (failed(converted))
1958 blockArguments.push_back(*converted);
1963 FailureOr<SmallVector<Value>>
1964 ModuleImport::convertCallOperands(llvm::CallBase *callInst,
1965 bool allowInlineAsm) {
1966 bool isInlineAsm = callInst->isInlineAsm();
1967 if (isInlineAsm && !allowInlineAsm)
1977 if (!isa<llvm::Function>(callInst->getCalledOperand()) && !isInlineAsm) {
1978 FailureOr<Value> called =
convertValue(callInst->getCalledOperand());
1981 operands.push_back(*called);
1985 FailureOr<SmallVector<Value>> arguments =
convertValues(args);
1986 if (failed(arguments))
1989 llvm::append_range(operands, *arguments);
1995 static LogicalResult
1997 LLVMFunctionType calleeType) {
1998 if (callType.getReturnType() != calleeType.getReturnType())
2001 if (calleeType.isVarArg()) {
2004 if (callType.getNumParams() < calleeType.getNumParams())
2009 if (callType.getNumParams() != calleeType.getNumParams())
2014 for (
auto [operandType, argumentType] :
2015 llvm::zip(callType.getParams(), calleeType.getParams()))
2016 if (operandType != argumentType)
2022 FailureOr<LLVMFunctionType>
2023 ModuleImport::convertFunctionType(llvm::CallBase *callInst,
2024 bool &isIncompatibleCall) {
2025 isIncompatibleCall =
false;
2026 auto castOrFailure = [](
Type convertedType) -> FailureOr<LLVMFunctionType> {
2027 auto funcTy = dyn_cast_or_null<LLVMFunctionType>(convertedType);
2033 llvm::Value *calledOperand = callInst->getCalledOperand();
2034 FailureOr<LLVMFunctionType> callType =
2035 castOrFailure(
convertType(callInst->getFunctionType()));
2036 if (failed(callType))
2038 auto *callee = dyn_cast<llvm::Function>(calledOperand);
2043 FailureOr<LLVMFunctionType> calleeType =
2044 castOrFailure(
convertType(callee->getFunctionType()));
2045 if (failed(calleeType))
2051 isIncompatibleCall =
true;
2053 emitWarning(loc) <<
"incompatible call and callee types: " << *callType
2054 <<
" and " << *calleeType;
2062 llvm::Value *calledOperand = callInst->getCalledOperand();
2063 if (
auto *callee = dyn_cast<llvm::Function>(calledOperand))
2068 LogicalResult ModuleImport::convertIntrinsic(llvm::CallInst *inst) {
2073 return emitError(loc) <<
"unhandled intrinsic: " <<
diag(*inst);
2077 ModuleImport::convertAsmInlineOperandAttrs(
const llvm::CallBase &llvmCall) {
2078 const auto *ia = cast<llvm::InlineAsm>(llvmCall.getCalledOperand());
2079 unsigned argIdx = 0;
2081 bool hasIndirect =
false;
2083 for (
const llvm::InlineAsm::ConstraintInfo &ci : ia->ParseConstraints()) {
2085 if (ci.Type == llvm::InlineAsm::isLabel || !ci.hasArg())
2090 if (ci.isIndirect) {
2091 if (llvm::Type *paramEltType = llvmCall.getParamElementType(argIdx)) {
2094 mlir::LLVM::InlineAsmOp::getElementTypeAttrName(),
2106 return hasIndirect ?
ArrayAttr::get(mlirModule->getContext(), opAttrs)
2110 LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
2113 if (inst->getOpcode() == llvm::Instruction::Br) {
2114 auto *brInst = cast<llvm::BranchInst>(inst);
2118 for (
auto i : llvm::seq<unsigned>(0, brInst->getNumSuccessors())) {
2119 llvm::BasicBlock *succ = brInst->getSuccessor(i);
2121 if (failed(convertBranchArgs(brInst, succ, blockArgs)))
2124 succBlockArgs.push_back(blockArgs);
2127 if (!brInst->isConditional()) {
2128 auto brOp = builder.
create<LLVM::BrOp>(loc, succBlockArgs.front(),
2129 succBlocks.front());
2133 FailureOr<Value> condition =
convertValue(brInst->getCondition());
2134 if (failed(condition))
2136 auto condBrOp = builder.
create<LLVM::CondBrOp>(
2137 loc, *condition, succBlocks.front(), succBlockArgs.front(),
2138 succBlocks.back(), succBlockArgs.back());
2142 if (inst->getOpcode() == llvm::Instruction::Switch) {
2143 auto *swInst = cast<llvm::SwitchInst>(inst);
2145 FailureOr<Value> condition =
convertValue(swInst->getCondition());
2146 if (failed(condition))
2150 llvm::BasicBlock *defaultBB = swInst->getDefaultDest();
2151 if (failed(convertBranchArgs(swInst, defaultBB, defaultBlockArgs)))
2155 unsigned numCases = swInst->getNumCases();
2161 const llvm::SwitchInst::CaseHandle &caseHandle = it.value();
2162 llvm::BasicBlock *succBB = caseHandle.getCaseSuccessor();
2163 if (failed(convertBranchArgs(swInst, succBB, caseOperands[it.index()])))
2165 caseOperandRefs[it.index()] = caseOperands[it.index()];
2166 caseValues[it.index()] = caseHandle.getCaseValue()->getValue();
2170 auto switchOp = builder.
create<SwitchOp>(
2171 loc, *condition,
lookupBlock(defaultBB), defaultBlockArgs, caseValues,
2172 caseBlocks, caseOperandRefs);
2176 if (inst->getOpcode() == llvm::Instruction::PHI) {
2182 if (inst->getOpcode() == llvm::Instruction::Call) {
2183 auto *callInst = cast<llvm::CallInst>(inst);
2184 llvm::Value *calledOperand = callInst->getCalledOperand();
2186 FailureOr<SmallVector<Value>> operands =
2187 convertCallOperands(callInst,
true);
2188 if (failed(operands))
2191 auto callOp = [&]() -> FailureOr<Operation *> {
2192 if (
auto *asmI = dyn_cast<llvm::InlineAsm>(calledOperand)) {
2196 ArrayAttr operandAttrs = convertAsmInlineOperandAttrs(*callInst);
2199 loc, resultTy, *operands,
2202 asmI->hasSideEffects(), asmI->isAlignStack(),
2203 convertTailCallKindFromLLVM(callInst->getTailCallKind()),
2205 mlirModule.getContext(),
2206 convertAsmDialectFromLLVM(asmI->getDialect())),
2210 bool isIncompatibleCall;
2211 FailureOr<LLVMFunctionType> funcTy =
2212 convertFunctionType(callInst, isIncompatibleCall);
2217 if (isIncompatibleCall) {
2222 Value indirectCallVal = builder.
create<LLVM::AddressOfOp>(
2224 operands->insert(operands->begin(), indirectCallVal);
2227 callee = convertCalleeName(callInst);
2229 CallOp callOp = builder.
create<CallOp>(loc, *funcTy, callee, *operands);
2231 if (failed(convertCallAttributes(callInst, callOp)))
2236 if (!isIncompatibleCall)
2238 return callOp.getOperation();
2244 if (!callInst->getType()->isVoidTy())
2245 mapValue(inst, (*callOp)->getResult(0));
2250 if (inst->getOpcode() == llvm::Instruction::LandingPad) {
2251 auto *lpInst = cast<llvm::LandingPadInst>(inst);
2254 operands.reserve(lpInst->getNumClauses());
2255 for (
auto i : llvm::seq<unsigned>(0, lpInst->getNumClauses())) {
2256 FailureOr<Value> operand =
convertValue(lpInst->getClause(i));
2257 if (failed(operand))
2259 operands.push_back(*operand);
2264 builder.
create<LandingpadOp>(loc, type, lpInst->isCleanup(), operands);
2268 if (inst->getOpcode() == llvm::Instruction::Invoke) {
2269 auto *invokeInst = cast<llvm::InvokeInst>(inst);
2271 if (invokeInst->isInlineAsm())
2272 return emitError(loc) <<
"invoke of inline assembly is not supported";
2274 FailureOr<SmallVector<Value>> operands = convertCallOperands(invokeInst);
2275 if (failed(operands))
2280 bool invokeResultUsedInPhi = llvm::any_of(
2281 invokeInst->getNormalDest()->phis(), [&](
const llvm::PHINode &phi) {
2282 return phi.getIncomingValueForBlock(invokeInst->getParent()) ==
2287 Block *directNormalDest = normalDest;
2288 if (invokeResultUsedInPhi) {
2294 directNormalDest = builder.
createBlock(normalDest);
2298 if (failed(convertBranchArgs(invokeInst, invokeInst->getUnwindDest(),
2302 bool isIncompatibleInvoke;
2303 FailureOr<LLVMFunctionType> funcTy =
2304 convertFunctionType(invokeInst, isIncompatibleInvoke);
2309 if (isIncompatibleInvoke) {
2314 Value indirectInvokeVal = builder.
create<LLVM::AddressOfOp>(
2316 operands->insert(operands->begin(), indirectInvokeVal);
2319 calleeName = convertCalleeName(invokeInst);
2324 auto invokeOp = builder.
create<InvokeOp>(
2325 loc, *funcTy, calleeName, *operands, directNormalDest,
ValueRange(),
2326 lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
2328 if (failed(convertInvokeAttributes(invokeInst, invokeOp)))
2333 if (!isIncompatibleInvoke)
2336 if (!invokeInst->getType()->isVoidTy())
2337 mapValue(inst, invokeOp.getResults().front());
2342 if (failed(convertBranchArgs(invokeInst, invokeInst->getNormalDest(),
2346 if (invokeResultUsedInPhi) {
2352 builder.
create<LLVM::BrOp>(loc, normalArgs, normalDest);
2356 assert(llvm::none_of(
2359 "An llvm.invoke operation cannot pass its result as a block "
2361 invokeOp.getNormalDestOperandsMutable().append(normalArgs);
2366 if (inst->getOpcode() == llvm::Instruction::GetElementPtr) {
2367 auto *gepInst = cast<llvm::GetElementPtrInst>(inst);
2368 Type sourceElementType =
convertType(gepInst->getSourceElementType());
2369 FailureOr<Value> basePtr =
convertValue(gepInst->getOperand(0));
2370 if (failed(basePtr))
2378 for (llvm::Value *operand : llvm::drop_begin(gepInst->operand_values())) {
2382 indices.push_back(*index);
2386 auto gepOp = builder.
create<GEPOp>(
2387 loc, type, sourceElementType, *basePtr, indices,
2388 static_cast<GEPNoWrapFlags
>(gepInst->getNoWrapFlags().getRaw()));
2393 if (inst->getOpcode() == llvm::Instruction::IndirectBr) {
2394 auto *indBrInst = cast<llvm::IndirectBrInst>(inst);
2396 FailureOr<Value> basePtr =
convertValue(indBrInst->getAddress());
2397 if (failed(basePtr))
2402 for (
auto i : llvm::seq<unsigned>(0, indBrInst->getNumSuccessors())) {
2403 llvm::BasicBlock *succ = indBrInst->getSuccessor(i);
2405 if (failed(convertBranchArgs(indBrInst, succ, blockArgs)))
2408 succBlockArgs.push_back(blockArgs);
2411 llvm::to_vector_of<ValueRange>(succBlockArgs);
2413 auto indBrOp = builder.
create<LLVM::IndirectBrOp>(
2414 loc, *basePtr, succBlockArgsRange, succBlocks);
2424 return emitError(loc) <<
"unhandled instruction: " <<
diag(*inst);
2427 LogicalResult ModuleImport::processInstruction(llvm::Instruction *inst) {
2434 if (
auto *intrinsic = dyn_cast<llvm::IntrinsicInst>(inst))
2435 return convertIntrinsic(intrinsic);
2438 return convertInstruction(inst);
2442 if (!f->hasPersonalityFn())
2445 llvm::Constant *pf = f->getPersonalityFn();
2453 if (
auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) {
2454 if (ce->getOpcode() == llvm::Instruction::BitCast &&
2455 ce->getType() == llvm::PointerType::getUnqual(f->getContext())) {
2456 if (
auto *func = dyn_cast<llvm::Function>(ce->getOperand(0)))
2464 llvm::MemoryEffects memEffects = func->getMemoryEffects();
2466 auto othermem = convertModRefInfoFromLLVM(
2467 memEffects.getModRef(llvm::MemoryEffects::Location::Other));
2468 auto argMem = convertModRefInfoFromLLVM(
2469 memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
2470 auto inaccessibleMem = convertModRefInfoFromLLVM(
2471 memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
2475 if (memAttr.isReadWrite())
2477 funcOp.setMemoryEffectsAttr(memAttr);
2483 StringLiteral(
"aarch64_in_za"),
2484 StringLiteral(
"aarch64_inout_za"),
2485 StringLiteral(
"aarch64_new_za"),
2486 StringLiteral(
"aarch64_out_za"),
2487 StringLiteral(
"aarch64_preserves_za"),
2488 StringLiteral(
"aarch64_pstate_sm_body"),
2489 StringLiteral(
"aarch64_pstate_sm_compatible"),
2490 StringLiteral(
"aarch64_pstate_sm_enabled"),
2491 StringLiteral(
"alwaysinline"),
2492 StringLiteral(
"approx-func-fp-math"),
2493 StringLiteral(
"convergent"),
2494 StringLiteral(
"denormal-fp-math"),
2495 StringLiteral(
"denormal-fp-math-f32"),
2496 StringLiteral(
"fp-contract"),
2497 StringLiteral(
"frame-pointer"),
2498 StringLiteral(
"instrument-function-entry"),
2499 StringLiteral(
"instrument-function-exit"),
2500 StringLiteral(
"no-infs-fp-math"),
2501 StringLiteral(
"no-nans-fp-math"),
2502 StringLiteral(
"no-signed-zeros-fp-math"),
2503 StringLiteral(
"noinline"),
2504 StringLiteral(
"nounwind"),
2505 StringLiteral(
"optnone"),
2506 StringLiteral(
"target-features"),
2507 StringLiteral(
"tune-cpu"),
2508 StringLiteral(
"unsafe-fp-math"),
2509 StringLiteral(
"uwtable"),
2510 StringLiteral(
"vscale_range"),
2511 StringLiteral(
"willreturn"),
2517 llvm::AttributeSet funcAttrs = func->getAttributes().getAttributes(
2518 llvm::AttributeList::AttrIndex::FunctionIndex);
2519 for (llvm::Attribute attr : funcAttrs) {
2522 if (attr.hasAttribute(llvm::Attribute::Memory))
2526 if (attr.isTypeAttribute()) {
2528 "type attributes on a function are invalid, skipping it");
2533 if (attr.isStringAttribute())
2534 attrName = attr.getKindAsString();
2536 attrName = llvm::Attribute::getNameFromAttrKind(attr.getKindAsEnum());
2543 if (attr.isStringAttribute()) {
2544 StringRef val = attr.getValueAsString();
2546 passthroughs.push_back(keyAttr);
2549 passthroughs.push_back(
2553 if (attr.isIntAttribute()) {
2554 auto val = std::to_string(attr.getValueAsInt());
2555 passthroughs.push_back(
2559 if (attr.isEnumAttribute()) {
2560 passthroughs.push_back(keyAttr);
2564 llvm_unreachable(
"unexpected attribute kind");
2567 if (!passthroughs.empty())
2568 funcOp.setPassthroughAttr(
ArrayAttr::get(context, passthroughs));
2572 LLVMFuncOp funcOp) {
2576 if (func->hasFnAttribute(llvm::Attribute::NoInline))
2577 funcOp.setNoInline(
true);
2578 if (func->hasFnAttribute(llvm::Attribute::AlwaysInline))
2579 funcOp.setAlwaysInline(
true);
2580 if (func->hasFnAttribute(llvm::Attribute::OptimizeNone))
2581 funcOp.setOptimizeNone(
true);
2582 if (func->hasFnAttribute(llvm::Attribute::Convergent))
2583 funcOp.setConvergent(
true);
2584 if (func->hasFnAttribute(llvm::Attribute::NoUnwind))
2585 funcOp.setNoUnwind(
true);
2586 if (func->hasFnAttribute(llvm::Attribute::WillReturn))
2587 funcOp.setWillReturn(
true);
2589 if (func->hasFnAttribute(
"aarch64_pstate_sm_enabled"))
2590 funcOp.setArmStreaming(
true);
2591 else if (func->hasFnAttribute(
"aarch64_pstate_sm_body"))
2592 funcOp.setArmLocallyStreaming(
true);
2593 else if (func->hasFnAttribute(
"aarch64_pstate_sm_compatible"))
2594 funcOp.setArmStreamingCompatible(
true);
2596 if (func->hasFnAttribute(
"aarch64_new_za"))
2597 funcOp.setArmNewZa(
true);
2598 else if (func->hasFnAttribute(
"aarch64_in_za"))
2599 funcOp.setArmInZa(
true);
2600 else if (func->hasFnAttribute(
"aarch64_out_za"))
2601 funcOp.setArmOutZa(
true);
2602 else if (func->hasFnAttribute(
"aarch64_inout_za"))
2603 funcOp.setArmInoutZa(
true);
2604 else if (func->hasFnAttribute(
"aarch64_preserves_za"))
2605 funcOp.setArmPreservesZa(
true);
2607 llvm::Attribute attr = func->getFnAttribute(llvm::Attribute::VScaleRange);
2608 if (attr.isValid()) {
2617 if (func->hasFnAttribute(
"frame-pointer")) {
2618 StringRef stringRefFramePointerKind =
2619 func->getFnAttribute(
"frame-pointer").getValueAsString();
2621 funcOp.getContext(), LLVM::framePointerKind::symbolizeFramePointerKind(
2622 stringRefFramePointerKind)
2626 if (llvm::Attribute attr = func->getFnAttribute(
"target-cpu");
2627 attr.isStringAttribute())
2628 funcOp.setTargetCpuAttr(
StringAttr::get(context, attr.getValueAsString()));
2630 if (llvm::Attribute attr = func->getFnAttribute(
"tune-cpu");
2631 attr.isStringAttribute())
2632 funcOp.setTuneCpuAttr(
StringAttr::get(context, attr.getValueAsString()));
2634 if (llvm::Attribute attr = func->getFnAttribute(
"target-features");
2635 attr.isStringAttribute())
2636 funcOp.setTargetFeaturesAttr(
2639 if (llvm::Attribute attr = func->getFnAttribute(
"reciprocal-estimates");
2640 attr.isStringAttribute())
2641 funcOp.setReciprocalEstimatesAttr(
2644 if (llvm::Attribute attr = func->getFnAttribute(
"prefer-vector-width");
2645 attr.isStringAttribute())
2646 funcOp.setPreferVectorWidth(attr.getValueAsString());
2648 if (llvm::Attribute attr = func->getFnAttribute(
"unsafe-fp-math");
2649 attr.isStringAttribute())
2650 funcOp.setUnsafeFpMath(attr.getValueAsBool());
2652 if (llvm::Attribute attr = func->getFnAttribute(
"no-infs-fp-math");
2653 attr.isStringAttribute())
2654 funcOp.setNoInfsFpMath(attr.getValueAsBool());
2656 if (llvm::Attribute attr = func->getFnAttribute(
"no-nans-fp-math");
2657 attr.isStringAttribute())
2658 funcOp.setNoNansFpMath(attr.getValueAsBool());
2660 if (llvm::Attribute attr = func->getFnAttribute(
"approx-func-fp-math");
2661 attr.isStringAttribute())
2662 funcOp.setApproxFuncFpMath(attr.getValueAsBool());
2664 if (llvm::Attribute attr = func->getFnAttribute(
"instrument-function-entry");
2665 attr.isStringAttribute())
2666 funcOp.setInstrumentFunctionEntry(
2669 if (llvm::Attribute attr = func->getFnAttribute(
"instrument-function-exit");
2670 attr.isStringAttribute())
2671 funcOp.setInstrumentFunctionExit(
2674 if (llvm::Attribute attr = func->getFnAttribute(
"no-signed-zeros-fp-math");
2675 attr.isStringAttribute())
2676 funcOp.setNoSignedZerosFpMath(attr.getValueAsBool());
2678 if (llvm::Attribute attr = func->getFnAttribute(
"denormal-fp-math");
2679 attr.isStringAttribute())
2680 funcOp.setDenormalFpMathAttr(
2683 if (llvm::Attribute attr = func->getFnAttribute(
"denormal-fp-math-f32");
2684 attr.isStringAttribute())
2685 funcOp.setDenormalFpMathF32Attr(
2688 if (llvm::Attribute attr = func->getFnAttribute(
"fp-contract");
2689 attr.isStringAttribute())
2690 funcOp.setFpContractAttr(
StringAttr::get(context, attr.getValueAsString()));
2692 if (func->hasUWTable()) {
2693 ::llvm::UWTableKind uwtableKind = func->getUWTableKind();
2695 funcOp.getContext(), convertUWTableKindFromLLVM(uwtableKind)));
2700 ModuleImport::convertParameterAttribute(llvm::AttributeSet llvmParamAttrs,
2704 auto llvmAttr = llvmParamAttrs.getAttribute(llvmKind);
2706 if (!llvmAttr.isValid())
2711 if (llvmAttr.hasKindAsEnum() &&
2712 llvmAttr.getKindAsEnum() == llvm::Attribute::Captures) {
2713 if (llvm::capturesNothing(llvmAttr.getCaptureInfo()))
2714 paramAttrs.push_back(
2720 if (llvmAttr.isTypeAttribute())
2722 else if (llvmAttr.isIntAttribute())
2724 else if (llvmAttr.isEnumAttribute())
2726 else if (llvmAttr.isConstantRangeAttribute()) {
2727 const llvm::ConstantRange &value = llvmAttr.getValueAsConstantRange();
2728 mlirAttr = builder.
getAttr<LLVM::ConstantRangeAttr>(value.getLower(),
2731 llvm_unreachable(
"unexpected parameter attribute kind");
2733 paramAttrs.push_back(builder.
getNamedAttr(mlirName, mlirAttr));
2742 auto llvmAttrs = func->getAttributes();
2743 for (
size_t i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
2744 llvm::AttributeSet llvmArgAttrs = llvmAttrs.getParamAttrs(i);
2745 funcOp.setArgAttrs(i, convertParameterAttribute(llvmArgAttrs, builder));
2749 llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
2750 if (!llvmResAttr.hasAttributes())
2752 funcOp.setResAttrsAttr(
2753 builder.
getArrayAttr(convertParameterAttribute(llvmResAttr, builder)));
2757 ArrayAttr &argsAttr,
2760 llvm::AttributeList llvmAttrs = call->getAttributes();
2762 bool anyArgAttrs =
false;
2763 for (
size_t i = 0, e = call->arg_size(); i < e; ++i) {
2764 llvmArgAttrsSet.emplace_back(llvmAttrs.getParamAttrs(i));
2765 if (llvmArgAttrsSet.back().hasAttributes())
2770 for (
auto &dict : dictAttrs)
2776 for (
auto &llvmArgAttrs : llvmArgAttrsSet)
2777 argAttrs.emplace_back(convertParameterAttribute(llvmArgAttrs, builder));
2778 argsAttr = getArrayAttr(argAttrs);
2781 llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
2782 if (!llvmResAttr.hasAttributes())
2784 DictionaryAttr resAttrs = convertParameterAttribute(llvmResAttr, builder);
2785 resAttr = getArrayAttr({resAttrs});
2789 CallOpInterface callOp,
2791 ArrayAttr argsAttr, resAttr;
2793 callOp.setArgAttrsAttr(argsAttr);
2794 callOp.setResAttrsAttr(resAttr);
2797 template <
typename Op>
2799 op.setCConv(convertCConvFromLLVM(inst->getCallingConv()));
2803 LogicalResult ModuleImport::convertInvokeAttributes(llvm::InvokeInst *inst,
2808 LogicalResult ModuleImport::convertCallAttributes(llvm::CallInst *inst,
2814 llvm::AttributeList callAttrs = inst->getAttributes();
2816 op.setTailCallKind(convertTailCallKindFromLLVM(inst->getTailCallKind()));
2817 op.setConvergent(callAttrs.getFnAttr(llvm::Attribute::Convergent).isValid());
2818 op.setNoUnwind(callAttrs.getFnAttr(llvm::Attribute::NoUnwind).isValid());
2819 op.setWillReturn(callAttrs.getFnAttr(llvm::Attribute::WillReturn).isValid());
2820 op.setNoInline(callAttrs.getFnAttr(llvm::Attribute::NoInline).isValid());
2822 callAttrs.getFnAttr(llvm::Attribute::AlwaysInline).isValid());
2823 op.setInlineHint(callAttrs.getFnAttr(llvm::Attribute::InlineHint).isValid());
2825 llvm::MemoryEffects memEffects = inst->getMemoryEffects();
2826 ModRefInfo othermem = convertModRefInfoFromLLVM(
2827 memEffects.getModRef(llvm::MemoryEffects::Location::Other));
2828 ModRefInfo argMem = convertModRefInfoFromLLVM(
2829 memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
2830 ModRefInfo inaccessibleMem = convertModRefInfoFromLLVM(
2831 memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
2835 if (!memAttr.isReadWrite())
2836 op.setMemoryEffectsAttr(memAttr);
2845 dyn_cast<LLVMFunctionType>(
convertType(func->getFunctionType()));
2846 if (func->isIntrinsic() &&
2850 bool dsoLocal = func->isDSOLocal();
2851 CConv cconv = convertCConvFromLLVM(func->getCallingConv());
2857 Location loc = debugImporter->translateFuncLocation(func);
2858 LLVMFuncOp funcOp = builder.
create<LLVMFuncOp>(
2859 loc, func->getName(), functionType,
2860 convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv);
2865 funcOp.setPersonalityAttr(personality);
2866 else if (func->hasPersonalityFn())
2867 emitWarning(funcOp.getLoc(),
"could not deduce personality, skipping it");
2870 funcOp.setGarbageCollector(StringRef(func->getGC()));
2872 if (func->hasAtLeastLocalUnnamedAddr())
2873 funcOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(func->getUnnamedAddr()));
2875 if (func->hasSection())
2876 funcOp.setSection(StringRef(func->getSection()));
2878 funcOp.setVisibility_(convertVisibilityFromLLVM(func->getVisibility()));
2880 if (func->hasComdat())
2881 funcOp.setComdatAttr(comdatMapping.lookup(func->getComdat()));
2883 if (llvm::MaybeAlign maybeAlign = func->getAlign())
2884 funcOp.setAlignment(maybeAlign->value());
2891 func->getAllMetadata(allMetadata);
2892 for (
auto &[
kind, node] : allMetadata) {
2897 <<
"unhandled function metadata: " <<
diagMD(node, llvmModule.get())
2898 <<
" on " <<
diag(*func);
2902 if (func->isDeclaration())
2911 llvm::df_iterator_default_set<llvm::BasicBlock *> reachable;
2912 for (llvm::BasicBlock *basicBlock : llvm::depth_first_ext(func, reachable))
2917 for (llvm::BasicBlock &basicBlock : *func) {
2919 if (!reachable.contains(&basicBlock)) {
2920 if (basicBlock.hasAddressTaken())
2922 <<
"unreachable block '" << basicBlock.getName()
2923 <<
"' with address taken";
2926 Region &body = funcOp.getBody();
2929 reachableBasicBlocks.push_back(&basicBlock);
2934 BlockArgument blockArg = funcOp.getFunctionBody().addArgument(
2935 functionType.getParamType(it.index()), funcOp.getLoc());
2944 setConstantInsertionPointToStart(
lookupBlock(blocks.front()));
2945 for (llvm::BasicBlock *basicBlock : blocks)
2946 if (failed(processBasicBlock(basicBlock,
lookupBlock(basicBlock))))
2951 if (failed(processDebugIntrinsics()))
2960 if (!dbgIntr->isKillLocation())
2962 llvm::Value *value = dbgIntr->getArgOperand(0);
2963 auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
2966 return !isa<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
2970 ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
2973 auto emitUnsupportedWarning = [&]() {
2974 if (emitExpensiveWarnings)
2980 if (dbgIntr->hasArgList())
2981 return emitUnsupportedWarning();
2986 return emitUnsupportedWarning();
2990 DILocalVariableAttr localVariableAttr =
2992 if (!localVariableAttr)
2993 return emitUnsupportedWarning();
2995 if (failed(argOperand))
2996 return emitError(loc) <<
"failed to convert a debug intrinsic operand: "
3004 if (
Operation *op = argOperand->getDefiningOp();
3007 auto dominatedBlocks = domInfo.
getNode(op->getBlock())->children();
3010 if (dominatedBlocks.empty())
3011 return emitUnsupportedWarning();
3014 Block *dominatedBlock = (*dominatedBlocks.begin())->getBlock();
3017 Value insertPt = *argOperand;
3018 if (
auto blockArg = dyn_cast<BlockArgument>(*argOperand)) {
3023 Block *insertionBlock = argOperand->getParentBlock();
3024 if (!insertionBlock->
empty() &&
3025 isa<LandingpadOp>(insertionBlock->
front()))
3026 insertPt = cast<LandingpadOp>(insertionBlock->
front()).getRes();
3031 auto locationExprAttr =
3032 debugImporter->translateExpression(dbgIntr->getExpression());
3035 .Case([&](llvm::DbgDeclareInst *) {
3036 return builder.
create<LLVM::DbgDeclareOp>(
3037 loc, *argOperand, localVariableAttr, locationExprAttr);
3039 .Case([&](llvm::DbgValueInst *) {
3040 return builder.
create<LLVM::DbgValueOp>(
3041 loc, *argOperand, localVariableAttr, locationExprAttr);
3044 setNonDebugMetadataAttrs(dbgIntr, op);
3048 LogicalResult ModuleImport::processDebugIntrinsics() {
3050 for (llvm::Instruction *inst : debugIntrinsics) {
3051 auto *intrCall = cast<llvm::DbgVariableIntrinsic>(inst);
3052 if (failed(processDebugIntrinsic(intrCall, domInfo)))
3058 LogicalResult ModuleImport::processBasicBlock(llvm::BasicBlock *bb,
3061 for (llvm::Instruction &inst : *bb) {
3062 if (failed(processInstruction(&inst)))
3067 if (debugIntrinsics.contains(&inst))
3074 setNonDebugMetadataAttrs(&inst, op);
3075 }
else if (inst.getOpcode() != llvm::Instruction::PHI) {
3076 if (emitExpensiveWarnings) {
3077 Location loc = debugImporter->translateLoc(inst.getDebugLoc());
3083 if (bb->hasAddressTaken()) {
3092 FailureOr<SmallVector<AccessGroupAttr>>
3094 return loopAnnotationImporter->lookupAccessGroupAttrs(node);
3100 return loopAnnotationImporter->translateLoopAnnotation(node, loc);
3103 FailureOr<DereferenceableAttr>
3106 Location loc = mlirModule.getLoc();
3110 if (node->getNumOperands() != 1)
3111 return emitError(loc) <<
"dereferenceable metadata must have one operand: "
3112 <<
diagMD(node, llvmModule.get());
3114 auto *numBytesMD = dyn_cast<llvm::ConstantAsMetadata>(node->getOperand(0));
3115 auto *numBytesCst = dyn_cast<llvm::ConstantInt>(numBytesMD->getValue());
3116 if (!numBytesCst || !numBytesCst->getValue().isNonNegative())
3117 return emitError(loc) <<
"dereferenceable metadata operand must be a "
3118 "non-negative constant integer: "
3119 <<
diagMD(node, llvmModule.get());
3121 bool mayBeNull = kindID == llvm::LLVMContext::MD_dereferenceable_or_null;
3122 auto derefAttr = builder.
getAttr<DereferenceableAttr>(
3123 numBytesCst->getZExtValue(), mayBeNull);
3129 std::unique_ptr<llvm::Module> llvmModule,
MLIRContext *context,
3130 bool emitExpensiveWarnings,
bool dropDICompositeTypeElements,
3131 bool loadAllDialects,
bool preferUnregisteredIntrinsics,
3132 bool importStructsAsLiterals) {
3139 LLVMDialect::getDialectNamespace()));
3141 DLTIDialect::getDialectNamespace()));
3142 if (loadAllDialects)
3149 emitExpensiveWarnings, dropDICompositeTypeElements,
3150 preferUnregisteredIntrinsics,
3151 importStructsAsLiterals);
static MLIRContext * getContext(OpFoldResult val)
union mlir::linalg::@1205::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 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 ...
void convertParameterAttributes(llvm::CallBase *call, ArrayAttr &argsAttr, ArrayAttr &resAttr, OpBuilder &builder)
Converts the parameter and result attributes in argsAttr and resAttr and add them to the callOp.
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 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.
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 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.
DataLayoutSpecInterface getDataLayout() const
Returns the MLIR data layout specification translated from the LLVM data layout.
ArrayRef< StringRef > getUnhandledTokens() const
Returns the data layout tokens that have not been handled during the data layout translation.
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.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
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.