30#include "llvm/ADT/DepthFirstIterator.h"
31#include "llvm/ADT/PostOrderIterator.h"
32#include "llvm/ADT/ScopeExit.h"
33#include "llvm/ADT/SmallPtrSet.h"
34#include "llvm/ADT/StringExtras.h"
35#include "llvm/ADT/TypeSwitch.h"
36#include "llvm/IR/Comdat.h"
37#include "llvm/IR/Constants.h"
38#include "llvm/IR/DebugProgramInstruction.h"
39#include "llvm/IR/InlineAsm.h"
40#include "llvm/IR/InstIterator.h"
41#include "llvm/IR/Instructions.h"
42#include "llvm/IR/IntrinsicInst.h"
43#include "llvm/IR/Metadata.h"
44#include "llvm/IR/Operator.h"
45#include "llvm/Support/LogicalResult.h"
46#include "llvm/Support/ModRef.h"
53#include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
58static std::string
diag(
const llvm::Value &value) {
60 llvm::raw_string_ostream os(str);
68static std::string
diagMD(
const llvm::Metadata *node,
69 const llvm::Module *module) {
71 llvm::raw_string_ostream os(str);
72 node->print(os, module,
true);
78 return "llvm.global_ctors";
83 return "mlir.llvm.nameless_global";
88 return "llvm.global_dtors";
94 return "__llvm_global_comdat";
103 std::optional<llvm::SyncScope::ID> syncScopeID =
104 llvm::getAtomicSyncScopeID(inst);
111 llvm::LLVMContext &llvmContext = inst->getContext();
112 llvmContext.getSyncScopeNames(syncScopeName);
113 auto *it = llvm::find_if(syncScopeName, [&](StringRef name) {
114 return *syncScopeID == llvmContext.getOrInsertSyncScopeID(name);
116 if (it != syncScopeName.end())
118 llvm_unreachable(
"incorrect sync scope identifier");
124 llvm::append_range(position,
indices);
135 llvm::Instruction *inst,
148#include "mlir/Dialect/LLVMIR/LLVMOpFromLLVMIRConversions.inc"
168 if (
auto *mdStr = dyn_cast<llvm::MDString>(md))
169 return MDStringAttr::get(ctx, StringAttr::get(ctx, mdStr->getString()));
170 if (
auto *cam = dyn_cast<llvm::ConstantAsMetadata>(md)) {
171 auto *ci = dyn_cast<llvm::ConstantInt>(cam->getValue());
174 auto intType = IntegerType::get(ctx, ci->getBitWidth());
175 return MDConstantAttr::get(ctx, IntegerAttr::get(intType, ci->getValue()));
177 if (
auto *vam = dyn_cast<llvm::ValueAsMetadata>(md)) {
178 auto *fn = dyn_cast<llvm::Function>(vam->getValue());
183 if (
auto *node = dyn_cast<llvm::MDNode>(md)) {
184 if (
Attribute cached = attrMap.lookup(node))
188 if (!path.insert(node).second)
191 operands.reserve(node->getNumOperands());
192 for (
const llvm::MDOperand &op : node->operands()) {
197 operands.push_back(opAttr);
200 Attribute nodeAttr = MDNodeAttr::get(ctx, operands);
201 attrMap.try_emplace(node, nodeAttr);
212 const llvm::Metadata *md) {
222 for (llvm::BasicBlock *basicBlock : basicBlocks) {
223 if (!blocks.contains(basicBlock)) {
224 llvm::ReversePostOrderTraversal<llvm::BasicBlock *> traversal(basicBlock);
225 blocks.insert_range(traversal);
228 assert(blocks.size() == basicBlocks.size() &&
"some blocks are not sorted");
233 std::unique_ptr<llvm::Module> llvmModule,
234 bool emitExpensiveWarnings,
235 bool importEmptyDICompositeTypes,
236 bool preferUnregisteredIntrinsics,
237 bool importStructsAsLiterals)
239 mlirModule(mlirModule), llvmModule(std::move(llvmModule)),
241 typeTranslator(*mlirModule->
getContext(), importStructsAsLiterals),
243 mlirModule, importEmptyDICompositeTypes)),
244 loopAnnotationImporter(
246 emitExpensiveWarnings(emitExpensiveWarnings),
247 preferUnregisteredIntrinsics(preferUnregisteredIntrinsics) {
248 builder.setInsertionPointToStart(mlirModule.getBody());
251ComdatOp ModuleImport::getGlobalComdatOp() {
253 return globalComdatOp;
259 globalInsertionOp = globalComdatOp;
260 return globalComdatOp;
263LogicalResult ModuleImport::processTBAAMetadata(
const llvm::MDNode *node) {
268 auto getIdentityIfRootNode =
269 [&](
const llvm::MDNode *node) -> FailureOr<std::optional<StringRef>> {
273 if (node->getNumOperands() > 1)
276 if (node->getNumOperands() == 1)
277 if (
const auto *op0 = dyn_cast<const llvm::MDString>(node->getOperand(0)))
278 return std::optional<StringRef>{op0->getString()};
279 return std::optional<StringRef>{};
289 auto isTypeDescriptorNode = [&](
const llvm::MDNode *node,
290 StringRef *identity =
nullptr,
291 SmallVectorImpl<TBAAMemberAttr> *members =
292 nullptr) -> std::optional<bool> {
293 unsigned numOperands = node->getNumOperands();
302 const auto *identityNode =
303 dyn_cast<const llvm::MDString>(node->getOperand(0));
309 *identity = identityNode->getString();
311 for (
unsigned pairNum = 0, e = numOperands / 2; pairNum < e; ++pairNum) {
312 const auto *memberNode =
313 dyn_cast<const llvm::MDNode>(node->getOperand(2 * pairNum + 1));
315 emitError(loc) <<
"operand '" << 2 * pairNum + 1 <<
"' must be MDNode: "
316 <<
diagMD(node, llvmModule.get());
320 if (2 * pairNum + 2 >= numOperands) {
322 if (numOperands != 2) {
323 emitError(loc) <<
"missing member offset: "
324 <<
diagMD(node, llvmModule.get());
328 auto *offsetCI = llvm::mdconst::dyn_extract<llvm::ConstantInt>(
329 node->getOperand(2 * pairNum + 2));
331 emitError(loc) <<
"operand '" << 2 * pairNum + 2
332 <<
"' must be ConstantInt: "
333 <<
diagMD(node, llvmModule.get());
336 offset = offsetCI->getZExtValue();
340 members->push_back(TBAAMemberAttr::get(
341 cast<TBAANodeAttr>(tbaaMapping.lookup(memberNode)), offset));
354 auto isTagNode = [&](
const llvm::MDNode *node,
355 TBAATypeDescriptorAttr *baseAttr =
nullptr,
356 TBAATypeDescriptorAttr *accessAttr =
nullptr,
357 int64_t *offset =
nullptr,
358 bool *isConstant =
nullptr) -> std::optional<bool> {
366 unsigned numOperands = node->getNumOperands();
367 if (numOperands != 3 && numOperands != 4)
369 const auto *baseMD = dyn_cast<const llvm::MDNode>(node->getOperand(0));
370 const auto *accessMD = dyn_cast<const llvm::MDNode>(node->getOperand(1));
372 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(2));
373 if (!baseMD || !accessMD || !offsetCI)
380 if (accessMD->getNumOperands() < 1 ||
381 !isa<llvm::MDString>(accessMD->getOperand(0)))
383 bool isConst =
false;
384 if (numOperands == 4) {
386 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(3));
388 emitError(loc) <<
"operand '3' must be ConstantInt: "
389 <<
diagMD(node, llvmModule.get());
392 isConst = isConstantCI->getValue()[0];
395 *baseAttr = cast<TBAATypeDescriptorAttr>(tbaaMapping.lookup(baseMD));
397 *accessAttr = cast<TBAATypeDescriptorAttr>(tbaaMapping.lookup(accessMD));
399 *offset = offsetCI->getZExtValue();
401 *isConstant = isConst;
409 SmallVector<const llvm::MDNode *> workList;
410 workList.push_back(node);
411 while (!workList.empty()) {
412 const llvm::MDNode *current = workList.back();
413 if (tbaaMapping.contains(current)) {
422 bool anyChildNotConverted =
false;
423 for (
const llvm::MDOperand &operand : current->operands())
424 if (
auto *childNode = dyn_cast_or_null<const llvm::MDNode>(operand.get()))
425 if (!tbaaMapping.contains(childNode)) {
426 workList.push_back(childNode);
427 anyChildNotConverted =
true;
430 if (anyChildNotConverted) {
435 if (!seen.insert(current).second)
436 return emitError(loc) <<
"has cycle in TBAA graph: "
437 <<
diagMD(current, llvmModule.get());
445 FailureOr<std::optional<StringRef>> rootNodeIdentity =
446 getIdentityIfRootNode(current);
447 if (succeeded(rootNodeIdentity)) {
448 StringAttr stringAttr = *rootNodeIdentity
449 ? builder.getStringAttr(**rootNodeIdentity)
453 tbaaMapping.insert({current, builder.getAttr<TBAARootAttr>(stringAttr)});
458 SmallVector<TBAAMemberAttr> members;
459 if (std::optional<bool> isValid =
460 isTypeDescriptorNode(current, &identity, &members)) {
461 assert(isValid.value() &&
"type descriptor node must be valid");
463 tbaaMapping.insert({current, builder.getAttr<TBAATypeDescriptorAttr>(
464 identity, members)});
468 TBAATypeDescriptorAttr baseAttr, accessAttr;
471 if (std::optional<bool> isValid =
472 isTagNode(current, &baseAttr, &accessAttr, &offset, &isConstant)) {
473 assert(isValid.value() &&
"access tag node must be valid");
475 {current, builder.getAttr<TBAATagAttr>(baseAttr, accessAttr, offset,
480 return emitError(loc) <<
"unsupported TBAA node format: "
481 <<
diagMD(current, llvmModule.get());
487ModuleImport::processAccessGroupMetadata(
const llvm::MDNode *node) {
488 Location loc = mlirModule.getLoc();
489 if (
failed(loopAnnotationImporter->translateAccessGroup(node, loc)))
490 return emitError(loc) <<
"unsupported access group node: "
491 <<
diagMD(node, llvmModule.get());
496ModuleImport::processAliasScopeMetadata(
const llvm::MDNode *node) {
497 Location loc = mlirModule.getLoc();
499 auto verifySelfRef = [](
const llvm::MDNode *node) {
500 return node->getNumOperands() != 0 &&
501 node == dyn_cast<llvm::MDNode>(node->getOperand(0));
503 auto verifySelfRefOrString = [](
const llvm::MDNode *node) {
504 return node->getNumOperands() != 0 &&
505 (node == dyn_cast<llvm::MDNode>(node->getOperand(0)) ||
506 isa<llvm::MDString>(node->getOperand(0)));
509 auto verifyDescription = [](
const llvm::MDNode *node,
unsigned idx) {
510 return idx >= node->getNumOperands() ||
511 isa<llvm::MDString>(node->getOperand(idx));
514 auto getIdAttr = [&](
const llvm::MDNode *node) -> Attribute {
515 if (verifySelfRef(node))
518 auto *name = cast<llvm::MDString>(node->getOperand(0));
519 return builder.getStringAttr(name->getString());
523 auto createAliasScopeDomainOp = [&](
const llvm::MDNode *aliasDomain) {
524 StringAttr description =
nullptr;
525 if (aliasDomain->getNumOperands() >= 2)
526 if (
auto *operand = dyn_cast<llvm::MDString>(aliasDomain->getOperand(1)))
527 description = builder.getStringAttr(operand->getString());
528 Attribute idAttr = getIdAttr(aliasDomain);
529 return builder.getAttr<AliasScopeDomainAttr>(idAttr, description);
533 for (
const llvm::MDOperand &operand : node->operands()) {
534 if (
const auto *scope = dyn_cast<llvm::MDNode>(operand)) {
535 llvm::AliasScopeNode aliasScope(scope);
536 const llvm::MDNode *domain = aliasScope.getDomain();
542 if (!verifySelfRefOrString(scope) || !domain ||
543 !verifyDescription(scope, 2))
544 return emitError(loc) <<
"unsupported alias scope node: "
545 <<
diagMD(scope, llvmModule.get());
546 if (!verifySelfRefOrString(domain) || !verifyDescription(domain, 1))
547 return emitError(loc) <<
"unsupported alias domain node: "
548 <<
diagMD(domain, llvmModule.get());
550 if (aliasScopeMapping.contains(scope))
554 auto it = aliasScopeMapping.find(aliasScope.getDomain());
555 if (it == aliasScopeMapping.end()) {
556 auto aliasScopeDomainOp = createAliasScopeDomainOp(domain);
557 it = aliasScopeMapping.try_emplace(domain, aliasScopeDomainOp).first;
561 StringAttr description =
nullptr;
562 if (!aliasScope.getName().empty())
563 description = builder.getStringAttr(aliasScope.getName());
564 Attribute idAttr = getIdAttr(scope);
565 auto aliasScopeOp = builder.getAttr<AliasScopeAttr>(
566 idAttr, cast<AliasScopeDomainAttr>(it->second), description);
568 aliasScopeMapping.try_emplace(aliasScope.getNode(), aliasScopeOp);
574FailureOr<SmallVector<AliasScopeAttr>>
577 aliasScopes.reserve(node->getNumOperands());
578 for (
const llvm::MDOperand &operand : node->operands()) {
579 auto *node = cast<llvm::MDNode>(operand.get());
580 aliasScopes.push_back(
581 dyn_cast_or_null<AliasScopeAttr>(aliasScopeMapping.lookup(node)));
584 if (llvm::is_contained(aliasScopes,
nullptr))
590 debugIntrinsics.insert(intrinsic);
594 if (!dbgRecords.contains(dbgRecord))
595 dbgRecords.insert(dbgRecord);
599 llvm::MDTuple *mdTuple) {
600 auto getLLVMFunction =
601 [&](
const llvm::MDOperand &funcMDO) -> llvm::Function * {
602 auto *f = cast_or_null<llvm::ValueAsMetadata>(funcMDO);
606 auto *llvmFn = cast<llvm::Function>(f->getValue()->stripPointerCasts());
612 for (
unsigned i = 0; i < mdTuple->getNumOperands(); i++) {
613 const llvm::MDOperand &mdo = mdTuple->getOperand(i);
614 auto *cgEntry = cast<llvm::MDNode>(mdo);
615 llvm::Constant *llvmConstant =
616 cast<llvm::ConstantAsMetadata>(cgEntry->getOperand(2))->getValue();
617 uint64_t count = cast<llvm::ConstantInt>(llvmConstant)->getZExtValue();
618 auto *fromFn = getLLVMFunction(cgEntry->getOperand(0));
619 auto *toFn = getLLVMFunction(cgEntry->getOperand(1));
621 cgProfile.push_back(ModuleFlagCGProfileEntryAttr::get(
622 mlirModule->getContext(),
630 return ArrayAttr::get(mlirModule->getContext(), cgProfile);
636 const llvm::Module *llvmModule,
637 const llvm::MDOperand &md) {
638 auto *tupleEntry = dyn_cast_or_null<llvm::MDTuple>(md);
639 if (!tupleEntry || tupleEntry->getNumOperands() != 2)
641 <<
"expected 2-element tuple metadata: " <<
diagMD(md, llvmModule);
649 ModuleOp mlirModule,
const llvm::Module *llvmModule,
650 const llvm::MDOperand &md, StringRef matchKey,
bool optional =
false) {
654 auto *keyMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(0));
655 if (!keyMD || keyMD->getString() != matchKey) {
658 <<
"expected '" << matchKey <<
"' key, but found: "
659 <<
diagMD(tupleEntry->getOperand(0), llvmModule);
663 return dyn_cast<llvm::ConstantAsMetadata>(tupleEntry->getOperand(1));
669static FailureOr<uint64_t>
671 const llvm::Module *llvmModule,
672 const llvm::MDOperand &md, StringRef matchKey) {
673 llvm::ConstantAsMetadata *valMD =
678 if (
auto *cstInt = dyn_cast<llvm::ConstantInt>(valMD->getValue()))
679 return cstInt->getZExtValue();
682 <<
"expected integer metadata value for key '" << matchKey
683 <<
"': " <<
diagMD(md, llvmModule);
687static std::optional<ProfileSummaryFormatKind>
689 const llvm::MDOperand &formatMD) {
694 llvm::MDString *keyMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(0));
695 if (!keyMD || keyMD->getString() !=
"ProfileFormat") {
697 <<
"expected 'ProfileFormat' key: "
698 <<
diagMD(tupleEntry->getOperand(0), llvmModule);
702 llvm::MDString *valMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(1));
703 std::optional<ProfileSummaryFormatKind> fmtKind =
704 symbolizeProfileSummaryFormatKind(valMD->getString());
707 <<
"expected 'SampleProfile', 'InstrProf' or 'CSInstrProf' values, "
709 <<
diagMD(valMD, llvmModule);
716static FailureOr<SmallVector<ModuleFlagProfileSummaryDetailedAttr>>
718 const llvm::Module *llvmModule,
719 const llvm::MDOperand &summaryMD) {
724 llvm::MDString *keyMD = dyn_cast<llvm::MDString>(tupleEntry->getOperand(0));
725 if (!keyMD || keyMD->getString() !=
"DetailedSummary") {
727 <<
"expected 'DetailedSummary' key: "
728 <<
diagMD(tupleEntry->getOperand(0), llvmModule);
732 llvm::MDTuple *entriesMD = dyn_cast<llvm::MDTuple>(tupleEntry->getOperand(1));
735 <<
"expected tuple value for 'DetailedSummary' key: "
736 <<
diagMD(tupleEntry->getOperand(1), llvmModule);
741 for (
auto &&entry : entriesMD->operands()) {
742 llvm::MDTuple *entryMD = dyn_cast<llvm::MDTuple>(entry);
743 if (!entryMD || entryMD->getNumOperands() != 3) {
745 <<
"'DetailedSummary' entry expects 3 operands: "
746 <<
diagMD(entry, llvmModule);
750 auto *op0 = dyn_cast<llvm::ConstantAsMetadata>(entryMD->getOperand(0));
751 auto *op1 = dyn_cast<llvm::ConstantAsMetadata>(entryMD->getOperand(1));
752 auto *op2 = dyn_cast<llvm::ConstantAsMetadata>(entryMD->getOperand(2));
753 if (!op0 || !op1 || !op2) {
755 <<
"expected only integer entries in 'DetailedSummary': "
756 <<
diagMD(entry, llvmModule);
760 auto detaildSummaryEntry = ModuleFlagProfileSummaryDetailedAttr::get(
761 mlirModule->getContext(),
762 cast<llvm::ConstantInt>(op0->getValue())->getZExtValue(),
763 cast<llvm::ConstantInt>(op1->getValue())->getZExtValue(),
764 cast<llvm::ConstantInt>(op2->getValue())->getZExtValue());
765 detailedSummary.push_back(detaildSummaryEntry);
767 return detailedSummary;
772 const llvm::Module *llvmModule,
773 llvm::MDTuple *mdTuple) {
774 unsigned profileNumEntries = mdTuple->getNumOperands();
775 if (profileNumEntries < 8) {
777 <<
"expected at 8 entries in 'ProfileSummary': "
778 <<
diagMD(mdTuple, llvmModule);
782 unsigned summayIdx = 0;
783 auto checkOptionalPosition = [&](
const llvm::MDOperand &md,
784 StringRef matchKey) -> LogicalResult {
788 if (summayIdx + 1 >= profileNumEntries) {
790 <<
"the last summary entry is '" << matchKey
791 <<
"', expected 'DetailedSummary': " <<
diagMD(md, llvmModule);
798 auto getOptIntValue =
799 [&](
const llvm::MDOperand &md,
800 StringRef matchKey) -> FailureOr<std::optional<uint64_t>> {
803 return FailureOr<std::optional<uint64_t>>(std::nullopt);
804 if (checkOptionalPosition(md, matchKey).failed())
806 FailureOr<uint64_t> val =
813 auto getOptDoubleValue = [&](
const llvm::MDOperand &md,
814 StringRef matchKey) -> FailureOr<FloatAttr> {
819 if (
auto *cstFP = dyn_cast<llvm::ConstantFP>(valMD->getValue())) {
820 if (checkOptionalPosition(md, matchKey).failed())
822 return FloatAttr::get(Float64Type::get(mlirModule.getContext()),
823 cstFP->getValueAPF());
826 <<
"expected double metadata value for key '" << matchKey
827 <<
"': " <<
diagMD(md, llvmModule);
834 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++));
835 if (!format.has_value())
839 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
"TotalCount");
840 if (failed(totalCount))
844 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
"MaxCount");
845 if (failed(maxCount))
849 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
851 if (failed(maxInternalCount))
855 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
857 if (failed(maxFunctionCount))
861 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
"NumCounts");
862 if (failed(numCounts))
866 mlirModule, llvmModule, mdTuple->getOperand(summayIdx++),
"NumFunctions");
867 if (failed(numFunctions))
871 FailureOr<std::optional<uint64_t>> isPartialProfile =
872 getOptIntValue(mdTuple->getOperand(summayIdx),
"IsPartialProfile");
873 if (failed(isPartialProfile))
875 if (isPartialProfile->has_value())
878 FailureOr<FloatAttr> partialProfileRatio =
879 getOptDoubleValue(mdTuple->getOperand(summayIdx),
"PartialProfileRatio");
880 if (failed(partialProfileRatio))
882 if (*partialProfileRatio)
886 FailureOr<SmallVector<ModuleFlagProfileSummaryDetailedAttr>> detailed =
888 mdTuple->getOperand(summayIdx));
889 if (failed(detailed))
893 return ModuleFlagProfileSummaryAttr::get(
894 mlirModule->getContext(), *format, *totalCount, *maxCount,
895 *maxInternalCount, *maxFunctionCount, *numCounts, *numFunctions,
896 *isPartialProfile, *partialProfileRatio, *detailed);
903 const llvm::Module *llvmModule, StringRef key,
904 llvm::MDTuple *mdTuple) {
905 if (key == LLVMDialect::getModuleFlagKeyCGProfileName())
907 if (key == LLVMDialect::getModuleFlagKeyProfileSummaryName())
912 Builder builder(mlirModule->getContext());
914 strings.reserve(mdTuple->getNumOperands());
915 for (
const llvm::MDOperand &operand : mdTuple->operands()) {
916 auto *mdString = dyn_cast_if_present<llvm::MDString>(operand.get());
919 strings.push_back(builder.
getStringAttr(mdString->getString()));
926 llvmModule->getModuleFlagsMetadata(llvmModuleFlags);
929 for (
const auto [behavior, key, val] : llvmModuleFlags) {
931 if (
auto *constInt = llvm::mdconst::dyn_extract<llvm::ConstantInt>(val)) {
932 valAttr = builder.getI32IntegerAttr(constInt->getZExtValue());
933 }
else if (
auto *mdString = dyn_cast<llvm::MDString>(val)) {
934 valAttr = builder.getStringAttr(mdString->getString());
935 }
else if (
auto *mdTuple = dyn_cast<llvm::MDTuple>(val)) {
937 key->getString(), mdTuple);
942 <<
"unsupported module flag value for key '" << key->getString()
943 <<
"' : " <<
diagMD(val, llvmModule.get());
947 moduleFlags.push_back(builder.getAttr<ModuleFlagAttr>(
948 convertModFlagBehaviorFromLLVM(behavior),
949 builder.getStringAttr(key->getString()), valAttr));
952 if (!moduleFlags.empty())
953 LLVM::ModuleFlagsOp::create(builder, mlirModule.getLoc(),
954 builder.getArrayAttr(moduleFlags));
960 for (
const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
961 if (named.getName() !=
"llvm.linker.options")
964 for (
const llvm::MDNode *node : named.operands()) {
966 options.reserve(node->getNumOperands());
967 for (
const llvm::MDOperand &option : node->operands())
968 options.push_back(cast<llvm::MDString>(option)->getString());
969 LLVM::LinkerOptionsOp::create(builder, mlirModule.getLoc(),
970 builder.getStrArrayAttr(
options));
977 for (
const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
978 if (named.getName() !=
"llvm.dependent-libraries")
981 for (
const llvm::MDNode *node : named.operands()) {
982 if (node->getNumOperands() == 1)
983 if (
auto *mdString = dyn_cast<llvm::MDString>(node->getOperand(0)))
984 libraries.push_back(mdString->getString());
986 if (!libraries.empty())
987 mlirModule->setAttr(LLVM::LLVMDialect::getDependentLibrariesAttrName(),
988 builder.getStrArrayAttr(libraries));
994 for (
const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
997 if (named.getName() != LLVMDialect::getIdentAttrName())
1000 if (named.getNumOperands() == 1)
1001 if (
auto *md = dyn_cast<llvm::MDNode>(named.getOperand(0)))
1002 if (md->getNumOperands() == 1)
1003 if (
auto *mdStr = dyn_cast<llvm::MDString>(md->getOperand(0)))
1004 mlirModule->setAttr(LLVMDialect::getIdentAttrName(),
1005 builder.getStringAttr(mdStr->getString()));
1011 for (
const llvm::NamedMDNode &nmd : llvmModule->named_metadata()) {
1014 if (nmd.getName() != LLVMDialect::getCommandlineAttrName())
1017 if (nmd.getNumOperands() == 1)
1018 if (
auto *md = dyn_cast<llvm::MDNode>(nmd.getOperand(0)))
1019 if (md->getNumOperands() == 1)
1020 if (
auto *mdStr = dyn_cast<llvm::MDString>(md->getOperand(0)))
1021 mlirModule->setAttr(LLVMDialect::getCommandlineAttrName(),
1022 builder.getStringAttr(mdStr->getString()));
1029 builder.setInsertionPointToEnd(mlirModule.getBody());
1030 for (
const llvm::Function &
func : llvmModule->functions()) {
1031 for (
const llvm::Instruction &inst : llvm::instructions(
func)) {
1033 if (llvm::MDNode *node =
1034 inst.getMetadata(llvm::LLVMContext::MD_access_group))
1035 if (failed(processAccessGroupMetadata(node)))
1039 llvm::AAMDNodes aliasAnalysisNodes = inst.getAAMetadata();
1040 if (!aliasAnalysisNodes)
1042 if (aliasAnalysisNodes.TBAA)
1043 if (failed(processTBAAMetadata(aliasAnalysisNodes.TBAA)))
1045 if (aliasAnalysisNodes.Scope)
1046 if (failed(processAliasScopeMetadata(aliasAnalysisNodes.Scope)))
1048 if (aliasAnalysisNodes.NoAlias)
1049 if (failed(processAliasScopeMetadata(aliasAnalysisNodes.NoAlias)))
1066void ModuleImport::processComdat(
const llvm::Comdat *comdat) {
1067 if (comdatMapping.contains(comdat))
1070 ComdatOp comdatOp = getGlobalComdatOp();
1073 auto selectorOp = ComdatSelectorOp::create(
1074 builder, mlirModule.getLoc(), comdat->getName(),
1075 convertComdatFromLLVM(comdat->getSelectionKind()));
1079 comdatMapping.try_emplace(comdat, symbolRef);
1083 for (llvm::GlobalVariable &globalVar : llvmModule->globals())
1084 if (globalVar.hasComdat())
1085 processComdat(globalVar.getComdat());
1086 for (llvm::Function &
func : llvmModule->functions())
1087 if (
func.hasComdat())
1088 processComdat(
func.getComdat());
1093 for (llvm::GlobalVariable &globalVar : llvmModule->globals()) {
1096 if (failed(convertGlobalCtorsAndDtors(&globalVar))) {
1097 return emitError(UnknownLoc::get(context))
1098 <<
"unhandled global variable: " <<
diag(globalVar);
1102 if (failed(convertGlobal(&globalVar))) {
1103 return emitError(UnknownLoc::get(context))
1104 <<
"unhandled global variable: " <<
diag(globalVar);
1111 for (llvm::GlobalAlias &alias : llvmModule->aliases()) {
1112 if (failed(convertAlias(&alias))) {
1113 return emitError(UnknownLoc::get(context))
1114 <<
"unhandled global alias: " <<
diag(alias);
1121 for (llvm::GlobalIFunc &ifunc : llvmModule->ifuncs()) {
1122 if (failed(convertIFunc(&ifunc))) {
1123 return emitError(UnknownLoc::get(context))
1124 <<
"unhandled global ifunc: " <<
diag(ifunc);
1131 Location loc = mlirModule.getLoc();
1133 context, llvmModule->getDataLayout().getStringRepresentation());
1135 return emitError(loc,
"cannot translate data layout: ")
1139 emitWarning(loc,
"unhandled data layout token: ") << token;
1141 mlirModule->setAttr(DLTIDialect::kDataLayoutAttrName,
1147 mlirModule->setAttr(
1148 LLVM::LLVMDialect::getTargetTripleAttrName(),
1149 builder.getStringAttr(llvmModule->getTargetTriple().str()));
1153 llvm::StringRef asmStr = llvmModule->getModuleInlineAsm();
1156 for (llvm::StringRef line : llvm::split(asmStr,
'\n'))
1158 asmArrayAttr.push_back(builder.getStringAttr(line));
1160 mlirModule->setAttr(LLVM::LLVMDialect::getModuleLevelAsmAttrName(),
1161 builder.getArrayAttr(asmArrayAttr));
1165 for (llvm::Function &
func : llvmModule->functions())
1171void ModuleImport::setNonDebugMetadataAttrs(llvm::Instruction *inst,
1174 inst->getAllMetadataOtherThanDebugLoc(allMetadata);
1175 for (
auto &[kind, node] : allMetadata) {
1179 if (emitExpensiveWarnings) {
1180 Location loc = debugImporter->translateLoc(inst->getDebugLoc());
1182 <<
diagMD(node, llvmModule.get()) <<
" on "
1191 auto iface = cast<IntegerOverflowFlagsInterface>(op);
1193 IntegerOverflowFlags value = {};
1194 value = bitEnumSet(value, IntegerOverflowFlags::nsw, inst->hasNoSignedWrap());
1196 bitEnumSet(value, IntegerOverflowFlags::nuw, inst->hasNoUnsignedWrap());
1198 iface.setOverflowFlags(value);
1202 auto iface = cast<ExactFlagInterface>(op);
1204 iface.setIsExact(inst->isExact());
1209 auto iface = cast<DisjointFlagInterface>(op);
1210 auto *instDisjoint = cast<llvm::PossiblyDisjointInst>(inst);
1212 iface.setIsDisjoint(instDisjoint->isDisjoint());
1216 auto iface = cast<NonNegFlagInterface>(op);
1218 iface.setNonNeg(inst->hasNonNeg());
1223 auto iface = cast<FastmathFlagsInterface>(op);
1229 if (!isa<llvm::FPMathOperator>(inst))
1231 llvm::FastMathFlags flags = inst->getFastMathFlags();
1234 FastmathFlags value = {};
1235 value = bitEnumSet(value, FastmathFlags::nnan, flags.noNaNs());
1236 value = bitEnumSet(value, FastmathFlags::ninf, flags.noInfs());
1237 value = bitEnumSet(value, FastmathFlags::nsz, flags.noSignedZeros());
1238 value = bitEnumSet(value, FastmathFlags::arcp, flags.allowReciprocal());
1239 value = bitEnumSet(value, FastmathFlags::contract, flags.allowContract());
1240 value = bitEnumSet(value, FastmathFlags::afn, flags.approxFunc());
1241 value = bitEnumSet(value, FastmathFlags::reassoc, flags.allowReassoc());
1242 FastmathFlagsAttr attr = FastmathFlagsAttr::get(builder.getContext(), value);
1243 iface->setAttr(iface.getFastmathAttrName(), attr);
1255 if (numElements.isScalable()) {
1257 <<
"scalable vectors not supported";
1262 Type elementType = cast<VectorType>(type).getElementType();
1266 SmallVector<int64_t> shape(arrayShape);
1267 shape.push_back(numElements.getKnownMinValue());
1268 return VectorType::get(shape, elementType);
1271Type ModuleImport::getBuiltinTypeForAttr(Type type) {
1285 SmallVector<int64_t> arrayShape;
1286 while (
auto arrayType = dyn_cast<LLVMArrayType>(type)) {
1287 arrayShape.push_back(arrayType.getNumElements());
1288 type = arrayType.getElementType();
1291 return RankedTensorType::get(arrayShape, type);
1298 llvm::Constant *constScalar) {
1301 if (constScalar->getType()->isVectorTy())
1305 if (
auto *constInt = dyn_cast<llvm::ConstantInt>(constScalar)) {
1307 IntegerType::get(context, constInt->getBitWidth()),
1308 constInt->getValue());
1312 if (
auto *constFloat = dyn_cast<llvm::ConstantFP>(constScalar)) {
1313 llvm::Type *type = constFloat->getType();
1314 FloatType floatType =
1316 ? BFloat16Type::get(context)
1320 <<
"unexpected floating-point type";
1323 return builder.
getFloatAttr(floatType, constFloat->getValueAPF());
1330static SmallVector<Attribute>
1332 llvm::ConstantDataSequential *constSequence) {
1334 elementAttrs.reserve(constSequence->getNumElements());
1335 for (
auto idx : llvm::seq<int64_t>(0, constSequence->getNumElements())) {
1336 llvm::Constant *constElement = constSequence->getElementAsConstant(idx);
1339 return elementAttrs;
1342Attribute ModuleImport::getConstantAsAttr(llvm::Constant *constant) {
1348 auto getConstantShape = [&](llvm::Type *type) {
1349 return llvm::dyn_cast_if_present<ShapedType>(
1354 if (isa<llvm::ConstantInt, llvm::ConstantFP>(constant)) {
1355 assert(constant->getType()->isVectorTy() &&
"expected a vector splat");
1356 auto shape = getConstantShape(constant->getType());
1359 Attribute splatAttr =
1366 if (
auto *constArray = dyn_cast<llvm::ConstantDataSequential>(constant)) {
1367 if (constArray->isString())
1368 return builder.getStringAttr(constArray->getAsString());
1369 auto shape = getConstantShape(constArray->getType());
1373 auto *constVector = dyn_cast<llvm::ConstantDataVector>(constant);
1374 if (constVector && constVector->isSplat()) {
1377 builder, constVector->getElementAsConstant(0));
1381 SmallVector<Attribute> elementAttrs =
1388 if (
auto *constAggregate = dyn_cast<llvm::ConstantAggregate>(constant)) {
1389 auto shape = getConstantShape(constAggregate->getType());
1393 SmallVector<Attribute> elementAttrs;
1394 SmallVector<llvm::Constant *> workList = {constAggregate};
1395 while (!workList.empty()) {
1396 llvm::Constant *current = workList.pop_back_val();
1399 if (
auto *constAggregate = dyn_cast<llvm::ConstantAggregate>(current)) {
1401 reverse(llvm::seq<int64_t>(0, constAggregate->getNumOperands())))
1402 workList.push_back(constAggregate->getAggregateElement(idx));
1407 if (
auto *constArray = dyn_cast<llvm::ConstantDataSequential>(current)) {
1408 SmallVector<Attribute> attrs =
1410 elementAttrs.append(attrs.begin(), attrs.end());
1416 elementAttrs.push_back(scalarAttr);
1427 if (
auto *constZero = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1428 auto shape = llvm::dyn_cast_if_present<ShapedType>(
1429 getBuiltinTypeForAttr(
convertType(constZero->getType())));
1433 Attribute splatAttr = builder.getZeroAttr(shape.getElementType());
1434 assert(splatAttr &&
"expected non-null zero attribute for scalar types");
1441ModuleImport::getOrCreateNamelessSymbolName(llvm::GlobalVariable *globalVar) {
1442 assert(globalVar->getName().empty() &&
1443 "expected to work with a nameless global");
1444 auto [it,
success] = namelessGlobals.try_emplace(globalVar);
1451 [
this](StringRef newName) {
return llvmModule->getNamedValue(newName); },
1454 it->getSecond() = symbolRef;
1458OpBuilder::InsertionGuard ModuleImport::setGlobalInsertionPoint() {
1459 OpBuilder::InsertionGuard guard(builder);
1460 if (globalInsertionOp)
1461 builder.setInsertionPointAfter(globalInsertionOp);
1463 builder.setInsertionPointToStart(mlirModule.getBody());
1467LogicalResult ModuleImport::convertAlias(llvm::GlobalAlias *alias) {
1469 OpBuilder::InsertionGuard guard = setGlobalInsertionPoint();
1472 AliasOp aliasOp = AliasOp::create(builder, mlirModule.getLoc(), type,
1473 convertLinkageFromLLVM(alias->getLinkage()),
1475 alias->isDSOLocal(),
1476 alias->isThreadLocal(),
1477 ArrayRef<NamedAttribute>());
1478 globalInsertionOp = aliasOp;
1481 Block *block = builder.createBlock(&aliasOp.getInitializerRegion());
1482 setConstantInsertionPointToStart(block);
1483 FailureOr<Value> initializer = convertConstantExpr(alias->getAliasee());
1486 ReturnOp::create(builder, aliasOp.getLoc(), *initializer);
1488 if (alias->hasAtLeastLocalUnnamedAddr())
1489 aliasOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(alias->getUnnamedAddr()));
1490 aliasOp.setVisibility_(convertVisibilityFromLLVM(alias->getVisibility()));
1495LogicalResult ModuleImport::convertIFunc(llvm::GlobalIFunc *ifunc) {
1496 OpBuilder::InsertionGuard guard = setGlobalInsertionPoint();
1499 llvm::Constant *resolver = ifunc->getResolver();
1500 Type resolverType =
convertType(resolver->getType());
1501 IFuncOp::create(builder, mlirModule.getLoc(), ifunc->getName(), type,
1502 resolver->getName(), resolverType,
1503 convertLinkageFromLLVM(ifunc->getLinkage()),
1504 ifunc->isDSOLocal(), ifunc->getAddressSpace(),
1505 convertUnnamedAddrFromLLVM(ifunc->getUnnamedAddr()),
1506 convertVisibilityFromLLVM(ifunc->getVisibility()));
1516 ArrayRef<StringLiteral> attributePrefixesToSkip = {}) {
1517 SmallVector<Attribute> mlirAttributes;
1518 for (llvm::Attribute attr : attributes) {
1520 if (attr.isStringAttribute())
1521 attrName = attr.getKindAsString();
1523 attrName = llvm::Attribute::getNameFromAttrKind(attr.getKindAsEnum());
1524 if (llvm::is_contained(attributesToSkip, attrName))
1527 auto attrNameStartsWith = [attrName](StringLiteral sl) {
1528 return attrName.starts_with(sl);
1530 if (attributePrefixesToSkip.end() !=
1531 llvm::find_if(attributePrefixesToSkip, attrNameStartsWith))
1534 auto keyAttr = StringAttr::get(context, attrName);
1535 if (attr.isStringAttribute()) {
1536 StringRef val = attr.getValueAsString();
1539 mlirAttributes.push_back(keyAttr);
1543 mlirAttributes.push_back(
1544 ArrayAttr::get(context, {keyAttr, StringAttr::get(context, val)}));
1547 if (attr.isIntAttribute()) {
1550 auto val = std::to_string(attr.getValueAsInt());
1551 mlirAttributes.push_back(
1552 ArrayAttr::get(context, {keyAttr, StringAttr::get(context, val)}));
1555 if (attr.isEnumAttribute()) {
1557 mlirAttributes.push_back(keyAttr);
1563 <<
"' attribute is invalid on current operation, skipping it";
1565 return ArrayAttr::get(context, mlirAttributes);
1571 GlobalOp globalOp) {
1573 globalOp.getLoc(), globalOp.getContext(), globalVar->getAttributes());
1574 if (!targetSpecificAttrs.empty())
1575 globalOp.setTargetSpecificAttrsAttr(targetSpecificAttrs);
1578LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
1580 OpBuilder::InsertionGuard guard = setGlobalInsertionPoint();
1582 Attribute valueAttr;
1583 if (globalVar->hasInitializer())
1584 valueAttr = getConstantAsAttr(globalVar->getInitializer());
1585 Type type =
convertType(globalVar->getValueType());
1587 uint64_t alignment = 0;
1588 llvm::MaybeAlign maybeAlign = globalVar->getAlign();
1589 if (maybeAlign.has_value()) {
1590 llvm::Align align = *maybeAlign;
1591 alignment = align.value();
1596 SmallVector<Attribute> globalExpressionAttrs;
1597 SmallVector<llvm::DIGlobalVariableExpression *> globalExpressions;
1598 globalVar->getDebugInfo(globalExpressions);
1600 for (llvm::DIGlobalVariableExpression *expr : globalExpressions) {
1601 DIGlobalVariableExpressionAttr globalExpressionAttr =
1602 debugImporter->translateGlobalVariableExpression(expr);
1603 globalExpressionAttrs.push_back(globalExpressionAttr);
1608 StringRef globalName = globalVar->getName();
1609 if (globalName.empty())
1610 globalName = getOrCreateNamelessSymbolName(globalVar).getValue();
1612 GlobalOp globalOp = GlobalOp::create(
1613 builder, mlirModule.getLoc(), type, globalVar->isConstant(),
1614 convertLinkageFromLLVM(globalVar->getLinkage()), StringRef(globalName),
1615 valueAttr, alignment, globalVar->getAddressSpace(),
1616 globalVar->isDSOLocal(),
1617 globalVar->isThreadLocal(), SymbolRefAttr(),
1618 ArrayRef<NamedAttribute>(), globalExpressionAttrs);
1619 globalInsertionOp = globalOp;
1621 if (globalVar->hasInitializer() && !valueAttr) {
1623 Block *block = builder.createBlock(&globalOp.getInitializerRegion());
1624 setConstantInsertionPointToStart(block);
1625 FailureOr<Value> initializer =
1626 convertConstantExpr(globalVar->getInitializer());
1629 ReturnOp::create(builder, globalOp.getLoc(), *initializer);
1631 if (globalVar->hasAtLeastLocalUnnamedAddr()) {
1632 globalOp.setUnnamedAddr(
1633 convertUnnamedAddrFromLLVM(globalVar->getUnnamedAddr()));
1635 if (globalVar->hasSection())
1636 globalOp.setSection(globalVar->getSection());
1637 globalOp.setVisibility_(
1638 convertVisibilityFromLLVM(globalVar->getVisibility()));
1640 if (globalVar->hasComdat())
1641 globalOp.setComdatAttr(comdatMapping.lookup(globalVar->getComdat()));
1649ModuleImport::convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar) {
1650 if (!globalVar->hasInitializer() || !globalVar->hasAppendingLinkage())
1652 llvm::Constant *initializer = globalVar->getInitializer();
1654 bool knownInit = isa<llvm::ConstantArray>(initializer) ||
1655 isa<llvm::ConstantAggregateZero>(initializer);
1662 if (
auto *caz = dyn_cast<llvm::ConstantAggregateZero>(initializer)) {
1663 if (caz->getElementCount().getFixedValue() != 0)
1667 SmallVector<Attribute> funcs;
1668 SmallVector<int32_t> priorities;
1669 SmallVector<Attribute> dataList;
1670 for (llvm::Value *operand : initializer->operands()) {
1671 auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
1672 if (!aggregate || aggregate->getNumOperands() != 3)
1675 auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
1676 auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
1677 auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
1678 if (!priority || !func || !data)
1681 auto *gv = dyn_cast_or_null<llvm::GlobalValue>(data);
1685 else if (data->isNullValue())
1686 dataAttr = ZeroAttr::get(context);
1691 priorities.push_back(priority->getValue().getZExtValue());
1692 dataList.push_back(dataAttr);
1696 OpBuilder::InsertionGuard guard = setGlobalInsertionPoint();
1699 globalInsertionOp = LLVM::GlobalCtorsOp::create(
1700 builder, mlirModule.getLoc(), builder.getArrayAttr(funcs),
1701 builder.getI32ArrayAttr(priorities), builder.getArrayAttr(dataList));
1704 globalInsertionOp = LLVM::GlobalDtorsOp::create(
1705 builder, mlirModule.getLoc(), builder.getArrayAttr(funcs),
1706 builder.getI32ArrayAttr(priorities), builder.getArrayAttr(dataList));
1711ModuleImport::getConstantsToConvert(llvm::Constant *constant) {
1713 if (valueMapping.contains(constant))
1722 workList.insert(constant);
1723 while (!workList.empty()) {
1724 llvm::Constant *current = workList.back();
1727 if (isa<llvm::GlobalObject>(current) || isa<llvm::GlobalAlias>(current)) {
1728 orderedSet.insert(current);
1729 workList.pop_back();
1735 auto [adjacencyIt,
inserted] = adjacencyLists.try_emplace(current);
1739 for (llvm::Value *operand : current->operands())
1740 if (
auto *constDependency = dyn_cast<llvm::Constant>(operand))
1741 adjacencyIt->getSecond().push_back(constDependency);
1744 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(current)) {
1745 unsigned numElements = constAgg->getElementCount().getFixedValue();
1746 for (
unsigned i = 0, e = numElements; i != e; ++i)
1747 adjacencyIt->getSecond().push_back(constAgg->getElementValue(i));
1753 if (adjacencyIt->getSecond().empty()) {
1754 orderedSet.insert(current);
1755 workList.pop_back();
1763 llvm::Constant *dependency = adjacencyIt->getSecond().pop_back_val();
1764 if (valueMapping.contains(dependency) || workList.contains(dependency) ||
1765 orderedSet.contains(dependency))
1767 workList.insert(dependency);
1773FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
1774 Location loc = UnknownLoc::get(context);
1777 if (Attribute attr = getConstantAsAttr(constant)) {
1779 if (
auto symbolRef = dyn_cast<FlatSymbolRefAttr>(attr)) {
1780 return AddressOfOp::create(builder, loc, type, symbolRef.getValue())
1783 return ConstantOp::create(builder, loc, type, attr).getResult();
1787 if (
auto *nullPtr = dyn_cast<llvm::ConstantPointerNull>(constant)) {
1789 return ZeroOp::create(builder, loc, type).getResult();
1793 if (isa<llvm::ConstantTokenNone>(constant)) {
1794 return NoneTokenOp::create(builder, loc).getResult();
1798 if (
auto *poisonVal = dyn_cast<llvm::PoisonValue>(constant)) {
1800 return PoisonOp::create(builder, loc, type).getResult();
1804 if (
auto *undefVal = dyn_cast<llvm::UndefValue>(constant)) {
1806 return UndefOp::create(builder, loc, type).getResult();
1810 if (
auto *dsoLocalEquivalent = dyn_cast<llvm::DSOLocalEquivalent>(constant)) {
1811 Type type =
convertType(dsoLocalEquivalent->getType());
1812 return DSOLocalEquivalentOp::create(
1815 builder.getContext(),
1816 dsoLocalEquivalent->getGlobalValue()->getName()))
1821 if (
auto *globalObj = dyn_cast<llvm::GlobalObject>(constant)) {
1823 StringRef globalName = globalObj->getName();
1824 FlatSymbolRefAttr symbolRef;
1826 if (globalName.empty())
1828 getOrCreateNamelessSymbolName(cast<llvm::GlobalVariable>(globalObj));
1831 return AddressOfOp::create(builder, loc, type, symbolRef).getResult();
1835 if (
auto *globalAliasObj = dyn_cast<llvm::GlobalAlias>(constant)) {
1836 Type type =
convertType(globalAliasObj->getType());
1837 StringRef aliaseeName = globalAliasObj->getName();
1839 return AddressOfOp::create(builder, loc, type, symbolRef).getResult();
1843 if (
auto *constExpr = dyn_cast<llvm::ConstantExpr>(constant)) {
1849 llvm::Instruction *inst = constExpr->getAsInstruction();
1850 llvm::scope_exit guard([&]() {
1851 assert(!noResultOpMapping.contains(inst) &&
1852 "expected constant expression to return a result");
1853 valueMapping.erase(inst);
1854 inst->deleteValue();
1858 assert(llvm::all_of(inst->operands(), [&](llvm::Value *value) {
1859 return valueMapping.contains(value);
1861 if (
failed(processInstruction(inst)))
1867 if (
auto *aggregateZero = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1868 Type type =
convertType(aggregateZero->getType());
1869 return ZeroOp::create(builder, loc, type).getResult();
1873 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregate>(constant)) {
1875 SmallVector<Value> elementValues;
1877 elementValues.reserve(constAgg->getNumOperands());
1878 for (llvm::Value *operand : constAgg->operands())
1881 assert(llvm::count(elementValues,
nullptr) == 0 &&
1882 "expected all elements have been converted before");
1886 bool isArrayOrStruct = isa<LLVMArrayType, LLVMStructType>(rootType);
1888 "unrecognized aggregate type");
1889 Value root = UndefOp::create(builder, loc, rootType);
1890 for (
const auto &it : llvm::enumerate(elementValues)) {
1891 if (isArrayOrStruct) {
1893 InsertValueOp::create(builder, loc, root, it.value(), it.index());
1895 Attribute indexAttr = builder.getI32IntegerAttr(it.index());
1897 ConstantOp::create(builder, loc, builder.getI32Type(), indexAttr);
1898 root = InsertElementOp::create(builder, loc, rootType, root, it.value(),
1905 if (
auto *constTargetNone = dyn_cast<llvm::ConstantTargetNone>(constant)) {
1906 LLVMTargetExtType targetExtType =
1907 cast<LLVMTargetExtType>(
convertType(constTargetNone->getType()));
1908 assert(targetExtType.hasProperty(LLVMTargetExtType::HasZeroInit) &&
1909 "target extension type does not support zero-initialization");
1912 return LLVM::ZeroOp::create(builder, loc, targetExtType).getRes();
1915 if (
auto *blockAddr = dyn_cast<llvm::BlockAddress>(constant)) {
1919 BlockTagAttr::get(context, blockAddr->getBasicBlock()->getNumber());
1920 return BlockAddressOp::create(
1922 BlockAddressAttr::get(context, fnSym, blockTag))
1926 StringRef error =
"";
1928 if (isa<llvm::ConstantPtrAuth>(constant))
1929 error =
" since ptrauth(...) is unsupported";
1931 if (isa<llvm::NoCFIValue>(constant))
1932 error =
" since no_cfi is unsupported";
1934 if (isa<llvm::GlobalValue>(constant))
1935 error =
" since global value is unsupported";
1937 return emitError(loc) <<
"unhandled constant: " <<
diag(*constant) << error;
1940FailureOr<Value> ModuleImport::convertConstantExpr(llvm::Constant *constant) {
1944 assert(!valueMapping.contains(constant) &&
1945 "expected constant has not been converted before");
1946 assert(constantInsertionBlock &&
1947 "expected the constant insertion block to be non-null");
1950 OpBuilder::InsertionGuard guard(builder);
1951 if (!constantInsertionOp)
1952 builder.setInsertionPointToStart(constantInsertionBlock);
1954 builder.setInsertionPointAfter(constantInsertionOp);
1958 getConstantsToConvert(constant);
1959 for (llvm::Constant *constantToConvert : constantsToConvert) {
1960 FailureOr<Value> converted = convertConstant(constantToConvert);
1963 mapValue(constantToConvert, *converted);
1968 constantInsertionOp =
result.getDefiningOp();
1974 auto it = valueMapping.find(value);
1975 if (it != valueMapping.end())
1976 return it->getSecond();
1983 if (
auto *mdAsVal = dyn_cast<llvm::MetadataAsValue>(value)) {
1984 llvm::Metadata *md = mdAsVal->getMetadata();
1988 <<
"unsupported metadata: " <<
diagMD(md, llvmModule.get());
1990 MetadataAsValueOp::create(builder, UnknownLoc::get(context), mdAttr)
1997 if (
auto *constant = dyn_cast<llvm::Constant>(value))
1998 return convertConstantExpr(constant);
2000 Location loc = UnknownLoc::get(context);
2001 if (
auto *inst = dyn_cast<llvm::Instruction>(value))
2003 return emitError(loc) <<
"unhandled value: " <<
diag(*value);
2009 auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
2012 auto *node = dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
2015 value = node->getValue();
2018 auto it = valueMapping.find(value);
2019 if (it != valueMapping.end())
2020 return it->getSecond();
2023 if (
auto *constant = dyn_cast<llvm::Constant>(value))
2024 return convertConstantExpr(constant);
2028FailureOr<SmallVector<Value>>
2031 remapped.reserve(values.size());
2032 for (llvm::Value *value : values) {
2034 if (failed(converted))
2036 remapped.push_back(*converted);
2046 assert(immArgPositions.size() == immArgAttrNames.size() &&
2047 "LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
2051 for (
auto [immArgPos, immArgName] :
2052 llvm::zip(immArgPositions, immArgAttrNames)) {
2053 auto &value = operands[immArgPos];
2054 auto *constant = llvm::cast<llvm::Constant>(value);
2056 assert(attr && attr.getType().isIntOrFloat() &&
2057 "expected immarg to be float or integer constant");
2058 auto nameAttr = StringAttr::get(attr.getContext(), immArgName);
2059 attrsOut.push_back({nameAttr, attr});
2064 for (llvm::Value *value : operands) {
2068 if (failed(mlirValue))
2070 valuesOut.push_back(*mlirValue);
2075 if (requiresOpBundles) {
2076 opBundleSizes.reserve(opBundles.size());
2077 opBundleTagAttrs.reserve(opBundles.size());
2079 for (
const llvm::OperandBundleUse &bundle : opBundles) {
2080 opBundleSizes.push_back(bundle.Inputs.size());
2081 opBundleTagAttrs.push_back(StringAttr::get(context, bundle.getTagName()));
2083 for (
const llvm::Use &opBundleOperand : bundle.Inputs) {
2084 auto operandMlirValue =
convertValue(opBundleOperand.get());
2085 if (failed(operandMlirValue))
2087 valuesOut.push_back(*operandMlirValue);
2092 auto opBundleSizesAttrNameAttr =
2093 StringAttr::get(context, LLVMDialect::getOpBundleSizesAttrName());
2094 attrsOut.push_back({opBundleSizesAttrNameAttr, opBundleSizesAttr});
2096 auto opBundleTagsAttr = ArrayAttr::get(context, opBundleTagAttrs);
2097 auto opBundleTagsAttrNameAttr =
2098 StringAttr::get(context, LLVMDialect::getOpBundleTagsAttrName());
2099 attrsOut.push_back({opBundleTagsAttrNameAttr, opBundleTagsAttr});
2106 IntegerAttr integerAttr;
2108 bool success = succeeded(converted) &&
2110 assert(
success &&
"expected a constant integer value");
2116 FloatAttr floatAttr;
2120 assert(
success &&
"expected a constant float value");
2127 llvm::DILocalVariable *node =
nullptr;
2128 if (
auto *value = dyn_cast<llvm::Value *>(valOrVariable)) {
2129 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
2130 node = cast<llvm::DILocalVariable>(nodeAsVal->getMetadata());
2132 node = cast<llvm::DILocalVariable *>(valOrVariable);
2134 return debugImporter->translate(node);
2138 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
2139 auto *node = cast<llvm::DILabel>(nodeAsVal->getMetadata());
2140 return debugImporter->translate(node);
2143FPExceptionBehaviorAttr
2145 auto *metadata = cast<llvm::MetadataAsValue>(value);
2146 auto *mdstr = cast<llvm::MDString>(metadata->getMetadata());
2147 std::optional<llvm::fp::ExceptionBehavior> optLLVM =
2148 llvm::convertStrToExceptionBehavior(mdstr->getString());
2149 assert(optLLVM &&
"Expecting FP exception behavior");
2150 return builder.getAttr<FPExceptionBehaviorAttr>(
2151 convertFPExceptionBehaviorFromLLVM(*optLLVM));
2155 auto *metadata = cast<llvm::MetadataAsValue>(value);
2156 auto *mdstr = cast<llvm::MDString>(metadata->getMetadata());
2157 std::optional<llvm::RoundingMode> optLLVM =
2158 llvm::convertStrToRoundingMode(mdstr->getString());
2159 assert(optLLVM &&
"Expecting rounding mode");
2160 return builder.getAttr<RoundingModeAttr>(
2161 convertRoundingModeFromLLVM(*optLLVM));
2164FailureOr<SmallVector<AliasScopeAttr>>
2166 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
2167 auto *node = cast<llvm::MDNode>(nodeAsVal->getMetadata());
2172 return debugImporter->translateLoc(loc);
2176ModuleImport::convertBranchArgs(llvm::Instruction *branch,
2177 llvm::BasicBlock *
target,
2179 for (
auto inst =
target->begin(); isa<llvm::PHINode>(inst); ++inst) {
2180 auto *phiInst = cast<llvm::PHINode>(&*inst);
2181 llvm::Value *value = phiInst->getIncomingValueForBlock(branch->getParent());
2183 if (failed(converted))
2185 blockArguments.push_back(*converted);
2190FailureOr<SmallVector<Value>>
2191ModuleImport::convertCallOperands(llvm::CallBase *callInst,
2192 bool allowInlineAsm) {
2193 bool isInlineAsm = callInst->isInlineAsm();
2194 if (isInlineAsm && !allowInlineAsm)
2204 llvm::Value *calleeOperand = callInst->getCalledOperand();
2205 if (!isa<llvm::Function, llvm::GlobalIFunc>(calleeOperand) && !isInlineAsm) {
2209 operands.push_back(*called);
2212 SmallVector<llvm::Value *> args(callInst->args());
2213 FailureOr<SmallVector<Value>> arguments =
convertValues(args);
2217 llvm::append_range(operands, *arguments);
2225 LLVMFunctionType calleeType) {
2226 if (callType.getReturnType() != calleeType.getReturnType())
2229 if (calleeType.isVarArg()) {
2232 if (callType.getNumParams() < calleeType.getNumParams())
2237 if (callType.getNumParams() != calleeType.getNumParams())
2242 for (
auto [operandType, argumentType] :
2243 llvm::zip(callType.getParams(), calleeType.getParams()))
2244 if (operandType != argumentType)
2250FailureOr<LLVMFunctionType>
2251ModuleImport::convertFunctionType(llvm::CallBase *callInst,
2252 bool &isIncompatibleCall) {
2253 isIncompatibleCall =
false;
2254 auto castOrFailure = [](Type convertedType) -> FailureOr<LLVMFunctionType> {
2255 auto funcTy = dyn_cast_or_null<LLVMFunctionType>(convertedType);
2261 llvm::Value *calledOperand = callInst->getCalledOperand();
2262 FailureOr<LLVMFunctionType> callType =
2263 castOrFailure(
convertType(callInst->getFunctionType()));
2266 auto *callee = dyn_cast<llvm::Function>(calledOperand);
2268 llvm::FunctionType *origCalleeType =
nullptr;
2270 origCalleeType = callee->getFunctionType();
2271 }
else if (
auto *ifunc = dyn_cast<llvm::GlobalIFunc>(calledOperand)) {
2272 origCalleeType = cast<llvm::FunctionType>(ifunc->getValueType());
2276 if (!origCalleeType)
2279 FailureOr<LLVMFunctionType> calleeType =
2287 isIncompatibleCall =
true;
2289 emitWarning(loc) <<
"incompatible call and callee types: " << *callType
2290 <<
" and " << *calleeType;
2297FlatSymbolRefAttr ModuleImport::convertCalleeName(llvm::CallBase *callInst) {
2298 llvm::Value *calledOperand = callInst->getCalledOperand();
2299 if (isa<llvm::Function, llvm::GlobalIFunc>(calledOperand))
2300 return SymbolRefAttr::get(context, calledOperand->getName());
2304LogicalResult ModuleImport::convertIntrinsic(llvm::CallInst *inst) {
2305 if (succeeded(iface.convertIntrinsic(builder, inst, *
this)))
2309 return emitError(loc) <<
"unhandled intrinsic: " <<
diag(*inst);
2313ModuleImport::convertAsmInlineOperandAttrs(
const llvm::CallBase &llvmCall) {
2314 const auto *ia = cast<llvm::InlineAsm>(llvmCall.getCalledOperand());
2315 unsigned argIdx = 0;
2316 SmallVector<mlir::Attribute> opAttrs;
2317 bool hasIndirect =
false;
2319 for (
const llvm::InlineAsm::ConstraintInfo &ci : ia->ParseConstraints()) {
2321 if (ci.Type == llvm::InlineAsm::isLabel || !ci.hasArg())
2326 if (ci.isIndirect) {
2327 if (llvm::Type *paramEltType = llvmCall.getParamElementType(argIdx)) {
2328 SmallVector<mlir::NamedAttribute> attrs;
2329 attrs.push_back(builder.getNamedAttr(
2330 mlir::LLVM::InlineAsmOp::getElementTypeAttrName(),
2332 opAttrs.push_back(builder.getDictionaryAttr(attrs));
2336 opAttrs.push_back(builder.getDictionaryAttr({}));
2342 return hasIndirect ? ArrayAttr::get(mlirModule->getContext(), opAttrs)
2346LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
2349 if (
auto *brInst = dyn_cast<llvm::UncondBrInst>(inst)) {
2350 llvm::BasicBlock *succ = brInst->getSuccessor();
2351 SmallVector<Value> blockArgs;
2352 if (
failed(convertBranchArgs(brInst, succ, blockArgs)))
2355 auto brOp = LLVM::BrOp::create(builder, loc, blockArgs,
lookupBlock(succ));
2359 if (
auto *brInst = dyn_cast<llvm::CondBrInst>(inst)) {
2360 SmallVector<Block *> succBlocks;
2361 SmallVector<SmallVector<Value>> succBlockArgs;
2362 for (
auto i : llvm::seq<unsigned>(0, brInst->getNumSuccessors())) {
2363 llvm::BasicBlock *succ = brInst->getSuccessor(i);
2364 SmallVector<Value> blockArgs;
2365 if (
failed(convertBranchArgs(brInst, succ, blockArgs)))
2368 succBlockArgs.push_back(blockArgs);
2371 FailureOr<Value> condition =
convertValue(brInst->getCondition());
2374 auto condBrOp = LLVM::CondBrOp::create(
2375 builder, loc, *condition, succBlocks.front(), succBlockArgs.front(),
2376 succBlocks.back(), succBlockArgs.back());
2380 if (inst->getOpcode() == llvm::Instruction::Switch) {
2381 auto *swInst = cast<llvm::SwitchInst>(inst);
2383 FailureOr<Value> condition =
convertValue(swInst->getCondition());
2386 SmallVector<Value> defaultBlockArgs;
2388 llvm::BasicBlock *defaultBB = swInst->getDefaultDest();
2389 if (
failed(convertBranchArgs(swInst, defaultBB, defaultBlockArgs)))
2393 unsigned numCases = swInst->getNumCases();
2394 SmallVector<SmallVector<Value>> caseOperands(numCases);
2395 SmallVector<ValueRange> caseOperandRefs(numCases);
2396 SmallVector<APInt> caseValues(numCases);
2397 SmallVector<Block *> caseBlocks(numCases);
2398 for (
const auto &it : llvm::enumerate(swInst->cases())) {
2399 const llvm::SwitchInst::CaseHandle &caseHandle = it.value();
2400 llvm::BasicBlock *succBB = caseHandle.getCaseSuccessor();
2401 if (
failed(convertBranchArgs(swInst, succBB, caseOperands[it.index()])))
2403 caseOperandRefs[it.index()] = caseOperands[it.index()];
2404 caseValues[it.index()] = caseHandle.getCaseValue()->getValue();
2408 auto switchOp = SwitchOp::create(builder, loc, *condition,
2410 caseValues, caseBlocks, caseOperandRefs);
2414 if (inst->getOpcode() == llvm::Instruction::PHI) {
2416 mapValue(inst, builder.getInsertionBlock()->addArgument(
2420 if (inst->getOpcode() == llvm::Instruction::Call) {
2421 auto *callInst = cast<llvm::CallInst>(inst);
2422 llvm::Value *calledOperand = callInst->getCalledOperand();
2424 FailureOr<SmallVector<Value>> operands =
2425 convertCallOperands(callInst,
true);
2429 auto callOp = [&]() -> FailureOr<Operation *> {
2430 if (
auto *asmI = dyn_cast<llvm::InlineAsm>(calledOperand)) {
2434 ArrayAttr operandAttrs = convertAsmInlineOperandAttrs(*callInst);
2435 return InlineAsmOp::create(
2436 builder, loc, resultTy, *operands,
2437 builder.getStringAttr(asmI->getAsmString()),
2438 builder.getStringAttr(asmI->getConstraintString()),
2439 asmI->hasSideEffects(), asmI->isAlignStack(),
2440 convertTailCallKindFromLLVM(callInst->getTailCallKind()),
2441 AsmDialectAttr::get(
2442 mlirModule.getContext(),
2443 convertAsmDialectFromLLVM(asmI->getDialect())),
2447 bool isIncompatibleCall;
2448 FailureOr<LLVMFunctionType> funcTy =
2449 convertFunctionType(callInst, isIncompatibleCall);
2453 FlatSymbolRefAttr callee =
nullptr;
2454 if (isIncompatibleCall) {
2458 FlatSymbolRefAttr calleeSym = convertCalleeName(callInst);
2459 Value indirectCallVal = LLVM::AddressOfOp::create(
2460 builder, loc, LLVM::LLVMPointerType::get(context), calleeSym);
2461 operands->insert(operands->begin(), indirectCallVal);
2464 callee = convertCalleeName(callInst);
2466 CallOp callOp = CallOp::create(builder, loc, *funcTy, callee, *operands);
2468 if (
failed(convertCallAttributes(callInst, callOp)))
2473 if (!isIncompatibleCall)
2475 return callOp.getOperation();
2481 if (!callInst->getType()->isVoidTy())
2482 mapValue(inst, (*callOp)->getResult(0));
2487 if (inst->getOpcode() == llvm::Instruction::LandingPad) {
2488 auto *lpInst = cast<llvm::LandingPadInst>(inst);
2490 SmallVector<Value> operands;
2491 operands.reserve(lpInst->getNumClauses());
2492 for (
auto i : llvm::seq<unsigned>(0, lpInst->getNumClauses())) {
2493 FailureOr<Value> operand =
convertValue(lpInst->getClause(i));
2496 operands.push_back(*operand);
2501 LandingpadOp::create(builder, loc, type, lpInst->isCleanup(), operands);
2505 if (inst->getOpcode() == llvm::Instruction::Invoke) {
2506 auto *invokeInst = cast<llvm::InvokeInst>(inst);
2508 if (invokeInst->isInlineAsm())
2509 return emitError(loc) <<
"invoke of inline assembly is not supported";
2511 FailureOr<SmallVector<Value>> operands = convertCallOperands(invokeInst);
2517 bool invokeResultUsedInPhi = llvm::any_of(
2518 invokeInst->getNormalDest()->phis(), [&](
const llvm::PHINode &phi) {
2519 return phi.getIncomingValueForBlock(invokeInst->getParent()) ==
2524 Block *directNormalDest = normalDest;
2525 if (invokeResultUsedInPhi) {
2530 OpBuilder::InsertionGuard g(builder);
2531 directNormalDest = builder.createBlock(normalDest);
2534 SmallVector<Value> unwindArgs;
2535 if (
failed(convertBranchArgs(invokeInst, invokeInst->getUnwindDest(),
2539 bool isIncompatibleInvoke;
2540 FailureOr<LLVMFunctionType> funcTy =
2541 convertFunctionType(invokeInst, isIncompatibleInvoke);
2545 FlatSymbolRefAttr calleeName =
nullptr;
2546 if (isIncompatibleInvoke) {
2550 FlatSymbolRefAttr calleeSym = convertCalleeName(invokeInst);
2551 Value indirectInvokeVal = LLVM::AddressOfOp::create(
2552 builder, loc, LLVM::LLVMPointerType::get(context), calleeSym);
2553 operands->insert(operands->begin(), indirectInvokeVal);
2556 calleeName = convertCalleeName(invokeInst);
2561 auto invokeOp = InvokeOp::create(
2562 builder, loc, *funcTy, calleeName, *operands, directNormalDest,
2565 if (
failed(convertInvokeAttributes(invokeInst, invokeOp)))
2570 if (!isIncompatibleInvoke)
2573 if (!invokeInst->getType()->isVoidTy())
2574 mapValue(inst, invokeOp.getResults().front());
2578 SmallVector<Value> normalArgs;
2579 if (
failed(convertBranchArgs(invokeInst, invokeInst->getNormalDest(),
2583 if (invokeResultUsedInPhi) {
2587 OpBuilder::InsertionGuard g(builder);
2588 builder.setInsertionPointToStart(directNormalDest);
2589 LLVM::BrOp::create(builder, loc, normalArgs, normalDest);
2593 assert(llvm::none_of(
2595 [&](Value val) {
return val.
getDefiningOp() == invokeOp; }) &&
2596 "An llvm.invoke operation cannot pass its result as a block "
2598 invokeOp.getNormalDestOperandsMutable().append(normalArgs);
2603 if (inst->getOpcode() == llvm::Instruction::GetElementPtr) {
2604 auto *gepInst = cast<llvm::GetElementPtrInst>(inst);
2605 Type sourceElementType =
convertType(gepInst->getSourceElementType());
2606 FailureOr<Value> basePtr =
convertValue(gepInst->getOperand(0));
2615 for (llvm::Value *operand : llvm::drop_begin(gepInst->operand_values())) {
2623 auto gepOp = GEPOp::create(
2624 builder, loc, type, sourceElementType, *basePtr,
indices,
2625 static_cast<GEPNoWrapFlags
>(gepInst->getNoWrapFlags().getRaw()));
2630 if (inst->getOpcode() == llvm::Instruction::IndirectBr) {
2631 auto *indBrInst = cast<llvm::IndirectBrInst>(inst);
2633 FailureOr<Value> basePtr =
convertValue(indBrInst->getAddress());
2637 SmallVector<Block *> succBlocks;
2638 SmallVector<SmallVector<Value>> succBlockArgs;
2639 for (
auto i : llvm::seq<unsigned>(0, indBrInst->getNumSuccessors())) {
2640 llvm::BasicBlock *succ = indBrInst->getSuccessor(i);
2641 SmallVector<Value> blockArgs;
2642 if (
failed(convertBranchArgs(indBrInst, succ, blockArgs)))
2645 succBlockArgs.push_back(blockArgs);
2647 SmallVector<ValueRange> succBlockArgsRange =
2648 llvm::to_vector_of<ValueRange>(succBlockArgs);
2650 auto indBrOp = LLVM::IndirectBrOp::create(builder, loc, *basePtr,
2651 succBlockArgsRange, succBlocks);
2661 return emitError(loc) <<
"unhandled instruction: " <<
diag(*inst);
2664LogicalResult ModuleImport::processInstruction(llvm::Instruction *inst) {
2671 if (
auto *intrinsic = dyn_cast<llvm::IntrinsicInst>(inst))
2672 return convertIntrinsic(intrinsic);
2677 if (inst->DebugMarker) {
2678 for (llvm::DbgRecord &dbgRecord : inst->DebugMarker->getDbgRecordRange()) {
2680 if (
auto *dbgVariableRecord =
2681 dyn_cast<llvm::DbgVariableRecord>(&dbgRecord)) {
2686 auto emitUnsupportedWarning = [&]() -> LogicalResult {
2687 if (!emitExpensiveWarnings)
2690 llvm::raw_string_ostream optionsStream(
options);
2691 dbgRecord.print(optionsStream);
2692 emitWarning(loc) <<
"unhandled debug record " << optionsStream.str();
2696 if (
auto *dbgLabelRecord = dyn_cast<llvm::DbgLabelRecord>(&dbgRecord)) {
2697 DILabelAttr labelAttr =
2698 debugImporter->translate(dbgLabelRecord->getLabel());
2700 return emitUnsupportedWarning();
2701 LLVM::DbgLabelOp::create(builder, loc, labelAttr);
2705 return emitUnsupportedWarning();
2710 return convertInstruction(inst);
2713FlatSymbolRefAttr ModuleImport::getPersonalityAsAttr(llvm::Function *f) {
2714 if (!f->hasPersonalityFn())
2717 llvm::Constant *pf = f->getPersonalityFn();
2721 return SymbolRefAttr::get(builder.getContext(), pf->getName());
2725 if (
auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) {
2726 if (ce->getOpcode() == llvm::Instruction::BitCast &&
2727 ce->getType() == llvm::PointerType::getUnqual(f->getContext())) {
2728 if (
auto *func = dyn_cast<llvm::Function>(ce->getOperand(0)))
2729 return SymbolRefAttr::get(builder.getContext(), func->getName());
2732 return FlatSymbolRefAttr();
2736 llvm::MemoryEffects memEffects =
func->getMemoryEffects();
2738 auto othermem = convertModRefInfoFromLLVM(
2739 memEffects.getModRef(llvm::MemoryEffects::Location::Other));
2740 auto argMem = convertModRefInfoFromLLVM(
2741 memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
2742 auto inaccessibleMem = convertModRefInfoFromLLVM(
2743 memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
2744 auto errnoMem = convertModRefInfoFromLLVM(
2745 memEffects.getModRef(llvm::MemoryEffects::Location::ErrnoMem));
2746 auto targetMem0 = convertModRefInfoFromLLVM(
2747 memEffects.getModRef(llvm::MemoryEffects::Location::TargetMem0));
2748 auto targetMem1 = convertModRefInfoFromLLVM(
2749 memEffects.getModRef(llvm::MemoryEffects::Location::TargetMem1));
2751 MemoryEffectsAttr::get(funcOp.getContext(), othermem, argMem,
2752 inaccessibleMem, errnoMem, targetMem0, targetMem1);
2754 if (memAttr.isReadWrite())
2756 funcOp.setMemoryEffectsAttr(memAttr);
2760 llvm::DenormalFPEnv denormalFpEnv =
func->getDenormalFPEnv();
2762 if (denormalFpEnv == llvm::DenormalFPEnv::getDefault())
2765 llvm::DenormalMode defaultMode = denormalFpEnv.DefaultMode;
2766 llvm::DenormalMode floatMode = denormalFpEnv.F32Mode;
2768 auto denormalFpEnvAttr = DenormalFPEnvAttr::get(
2769 funcOp.getContext(), convertDenormalModeKindFromLLVM(defaultMode.Output),
2770 convertDenormalModeKindFromLLVM(defaultMode.Input),
2771 convertDenormalModeKindFromLLVM(floatMode.Output),
2772 convertDenormalModeKindFromLLVM(floatMode.Input));
2773 funcOp.setDenormalFpenvAttr(denormalFpEnvAttr);
2779 StringLiteral(
"aarch64_in_za"),
2780 StringLiteral(
"aarch64_inout_za"),
2781 StringLiteral(
"aarch64_new_za"),
2782 StringLiteral(
"aarch64_out_za"),
2783 StringLiteral(
"aarch64_preserves_za"),
2784 StringLiteral(
"aarch64_pstate_sm_body"),
2785 StringLiteral(
"aarch64_pstate_sm_compatible"),
2786 StringLiteral(
"aarch64_pstate_sm_enabled"),
2787 StringLiteral(
"allocsize"),
2788 StringLiteral(
"alwaysinline"),
2789 StringLiteral(
"cold"),
2790 StringLiteral(
"convergent"),
2791 StringLiteral(
"fp-contract"),
2792 StringLiteral(
"frame-pointer"),
2793 StringLiteral(
"hot"),
2794 StringLiteral(
"inlinehint"),
2795 StringLiteral(
"instrument-function-entry"),
2796 StringLiteral(
"instrument-function-exit"),
2797 StringLiteral(
"modular-format"),
2798 StringLiteral(
"memory"),
2799 StringLiteral(
"minsize"),
2800 StringLiteral(
"no_caller_saved_registers"),
2801 StringLiteral(
"no-signed-zeros-fp-math"),
2802 StringLiteral(
"no-builtins"),
2803 StringLiteral(
"nocallback"),
2804 StringLiteral(
"noduplicate"),
2805 StringLiteral(
"noinline"),
2806 StringLiteral(
"noreturn"),
2807 StringLiteral(
"nounwind"),
2808 StringLiteral(
"optnone"),
2809 StringLiteral(
"optsize"),
2810 StringLiteral(
"returns_twice"),
2811 StringLiteral(
"save-reg-params"),
2812 StringLiteral(
"target-features"),
2813 StringLiteral(
"trap-func-name"),
2814 StringLiteral(
"tune-cpu"),
2815 StringLiteral(
"uwtable"),
2816 StringLiteral(
"vscale_range"),
2817 StringLiteral(
"willreturn"),
2818 StringLiteral(
"zero-call-used-regs"),
2819 StringLiteral(
"denormal_fpenv"),
2825 StringLiteral(
"no-builtin-"),
2828template <
typename OpTy>
2830 const llvm::AttributeSet &attrs,
2833 if (attrs.hasAttribute(
"no-builtins")) {
2834 target.setNobuiltinsAttr(ArrayAttr::get(ctx, {}));
2839 for (llvm::Attribute attr : attrs) {
2842 if (attr.hasKindAsEnum())
2845 StringRef val = attr.getKindAsString();
2847 if (val.starts_with(
"no-builtin-"))
2849 StringAttr::get(ctx, val.drop_front(
sizeof(
"no-builtin-") - 1)));
2852 if (!nbAttrs.empty())
2853 target.setNobuiltinsAttr(ArrayAttr::get(ctx, nbAttrs.getArrayRef()));
2856template <
typename OpTy>
2858 const llvm::AttributeSet &attrs, OpTy
target) {
2859 llvm::Attribute attr = attrs.getAttribute(llvm::Attribute::AllocSize);
2860 if (!attr.isValid())
2863 auto [elemSize, numElems] = attr.getAllocSizeArgs();
2867 static_cast<int32_t
>(*numElems)}));
2878 llvm::AttributeSet funcAttrs =
func->getAttributes().getAttributes(
2879 llvm::AttributeList::AttrIndex::FunctionIndex);
2881 funcOp.getLoc(), funcOp.getContext(), funcAttrs,
2883 if (!passthroughAttr.empty())
2884 funcOp.setPassthroughAttr(passthroughAttr);
2888 LLVMFuncOp funcOp) {
2893 if (
func->hasFnAttribute(llvm::Attribute::NoInline))
2894 funcOp.setNoInline(
true);
2895 if (
func->hasFnAttribute(llvm::Attribute::AlwaysInline))
2896 funcOp.setAlwaysInline(
true);
2897 if (
func->hasFnAttribute(llvm::Attribute::InlineHint))
2898 funcOp.setInlineHint(
true);
2899 if (
func->hasFnAttribute(llvm::Attribute::OptimizeNone))
2900 funcOp.setOptimizeNone(
true);
2901 if (
func->hasFnAttribute(llvm::Attribute::Convergent))
2902 funcOp.setConvergent(
true);
2903 if (
func->hasFnAttribute(llvm::Attribute::NoUnwind))
2904 funcOp.setNoUnwind(
true);
2905 if (
func->hasFnAttribute(llvm::Attribute::WillReturn))
2906 funcOp.setWillReturn(
true);
2907 if (
func->hasFnAttribute(llvm::Attribute::NoReturn))
2908 funcOp.setNoreturn(
true);
2909 if (
func->hasFnAttribute(llvm::Attribute::OptimizeForSize))
2910 funcOp.setOptsize(
true);
2911 if (
func->hasFnAttribute(
"save-reg-params"))
2912 funcOp.setSaveRegParams(
true);
2913 if (
func->hasFnAttribute(llvm::Attribute::MinSize))
2914 funcOp.setMinsize(
true);
2915 if (
func->hasFnAttribute(llvm::Attribute::ReturnsTwice))
2916 funcOp.setReturnsTwice(
true);
2917 if (
func->hasFnAttribute(llvm::Attribute::Cold))
2918 funcOp.setCold(
true);
2919 if (
func->hasFnAttribute(llvm::Attribute::Hot))
2920 funcOp.setHot(
true);
2921 if (
func->hasFnAttribute(llvm::Attribute::NoDuplicate))
2922 funcOp.setNoduplicate(
true);
2923 if (
func->hasFnAttribute(
"no_caller_saved_registers"))
2924 funcOp.setNoCallerSavedRegisters(
true);
2925 if (
func->hasFnAttribute(llvm::Attribute::NoCallback))
2926 funcOp.setNocallback(
true);
2927 if (llvm::Attribute attr =
func->getFnAttribute(
"modular-format");
2928 attr.isStringAttribute())
2929 funcOp.setModularFormat(StringAttr::get(context, attr.getValueAsString()));
2930 if (llvm::Attribute attr =
func->getFnAttribute(
"zero-call-used-regs");
2931 attr.isStringAttribute())
2932 funcOp.setZeroCallUsedRegsAttr(
2933 StringAttr::get(context, attr.getValueAsString()));
2935 if (
func->hasFnAttribute(
"aarch64_pstate_sm_enabled"))
2936 funcOp.setArmStreaming(
true);
2937 else if (
func->hasFnAttribute(
"aarch64_pstate_sm_body"))
2938 funcOp.setArmLocallyStreaming(
true);
2939 else if (
func->hasFnAttribute(
"aarch64_pstate_sm_compatible"))
2940 funcOp.setArmStreamingCompatible(
true);
2942 if (
func->hasFnAttribute(
"aarch64_new_za"))
2943 funcOp.setArmNewZa(
true);
2944 else if (
func->hasFnAttribute(
"aarch64_in_za"))
2945 funcOp.setArmInZa(
true);
2946 else if (
func->hasFnAttribute(
"aarch64_out_za"))
2947 funcOp.setArmOutZa(
true);
2948 else if (
func->hasFnAttribute(
"aarch64_inout_za"))
2949 funcOp.setArmInoutZa(
true);
2950 else if (
func->hasFnAttribute(
"aarch64_preserves_za"))
2951 funcOp.setArmPreservesZa(
true);
2956 llvm::Attribute attr =
func->getFnAttribute(llvm::Attribute::VScaleRange);
2957 if (attr.isValid()) {
2959 auto intTy = IntegerType::get(context, 32);
2960 funcOp.setVscaleRangeAttr(LLVM::VScaleRangeAttr::get(
2961 context, IntegerAttr::get(intTy, attr.getVScaleRangeMin()),
2962 IntegerAttr::get(intTy, attr.getVScaleRangeMax().value_or(0))));
2966 if (
func->hasFnAttribute(
"frame-pointer")) {
2967 StringRef stringRefFramePointerKind =
2968 func->getFnAttribute(
"frame-pointer").getValueAsString();
2969 funcOp.setFramePointerAttr(LLVM::FramePointerKindAttr::get(
2970 funcOp.getContext(), LLVM::framePointerKind::symbolizeFramePointerKind(
2971 stringRefFramePointerKind)
2975 if (
func->hasFnAttribute(
"use-sample-profile"))
2976 funcOp.setUseSampleProfile(
true);
2978 if (llvm::Attribute attr =
func->getFnAttribute(
"target-cpu");
2979 attr.isStringAttribute())
2980 funcOp.setTargetCpuAttr(StringAttr::get(context, attr.getValueAsString()));
2982 if (llvm::Attribute attr =
func->getFnAttribute(
"tune-cpu");
2983 attr.isStringAttribute())
2984 funcOp.setTuneCpuAttr(StringAttr::get(context, attr.getValueAsString()));
2986 if (llvm::Attribute attr =
func->getFnAttribute(
"target-features");
2987 attr.isStringAttribute())
2988 funcOp.setTargetFeaturesAttr(
2989 LLVM::TargetFeaturesAttr::get(context, attr.getValueAsString()));
2991 if (llvm::Attribute attr =
func->getFnAttribute(
"reciprocal-estimates");
2992 attr.isStringAttribute())
2993 funcOp.setReciprocalEstimatesAttr(
2994 StringAttr::get(context, attr.getValueAsString()));
2996 if (llvm::Attribute attr =
func->getFnAttribute(
"prefer-vector-width");
2997 attr.isStringAttribute())
2998 funcOp.setPreferVectorWidth(attr.getValueAsString());
3000 if (llvm::Attribute attr =
func->getFnAttribute(
"instrument-function-entry");
3001 attr.isStringAttribute())
3002 funcOp.setInstrumentFunctionEntry(
3003 StringAttr::get(context, attr.getValueAsString()));
3005 if (llvm::Attribute attr =
func->getFnAttribute(
"instrument-function-exit");
3006 attr.isStringAttribute())
3007 funcOp.setInstrumentFunctionExit(
3008 StringAttr::get(context, attr.getValueAsString()));
3010 if (llvm::Attribute attr =
func->getFnAttribute(
"no-signed-zeros-fp-math");
3011 attr.isStringAttribute())
3012 funcOp.setNoSignedZerosFpMath(attr.getValueAsBool());
3014 if (llvm::Attribute attr =
func->getFnAttribute(
"fp-contract");
3015 attr.isStringAttribute())
3016 funcOp.setFpContractAttr(StringAttr::get(context, attr.getValueAsString()));
3018 if (
func->hasUWTable()) {
3019 ::llvm::UWTableKind uwtableKind =
func->getUWTableKind();
3020 funcOp.setUwtableKindAttr(LLVM::UWTableKindAttr::get(
3021 funcOp.getContext(), convertUWTableKindFromLLVM(uwtableKind)));
3026ModuleImport::convertArgOrResultAttrSet(llvm::AttributeSet llvmAttrSet) {
3029 auto llvmAttr = llvmAttrSet.getAttribute(llvmKind);
3031 if (!llvmAttr.isValid())
3036 if (llvmAttr.hasKindAsEnum() &&
3037 llvmAttr.getKindAsEnum() == llvm::Attribute::Captures) {
3038 if (llvm::capturesNothing(llvmAttr.getCaptureInfo()))
3039 paramAttrs.push_back(
3045 if (llvmAttr.isTypeAttribute())
3046 mlirAttr = TypeAttr::get(
convertType(llvmAttr.getValueAsType()));
3047 else if (llvmAttr.isIntAttribute())
3049 else if (llvmAttr.isEnumAttribute())
3051 else if (llvmAttr.isConstantRangeAttribute()) {
3052 const llvm::ConstantRange &value = llvmAttr.getValueAsConstantRange();
3053 mlirAttr = builder.
getAttr<LLVM::ConstantRangeAttr>(value.getLower(),
3056 llvm_unreachable(
"unexpected parameter attribute kind");
3058 paramAttrs.push_back(builder.getNamedAttr(mlirName, mlirAttr));
3061 return builder.getDictionaryAttr(paramAttrs);
3065 LLVMFuncOp funcOp) {
3066 auto llvmAttrs = func->getAttributes();
3067 for (
size_t i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
3068 llvm::AttributeSet llvmArgAttrs = llvmAttrs.getParamAttrs(i);
3069 funcOp.setArgAttrs(i, convertArgOrResultAttrSet(llvmArgAttrs));
3073 llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
3074 if (!llvmResAttr.hasAttributes())
3076 funcOp.setResAttrsAttr(
3077 builder.getArrayAttr({convertArgOrResultAttrSet(llvmResAttr)}));
3081 llvm::CallBase *call, ArgAndResultAttrsOpInterface attrsOp,
3084 llvm::SmallDenseSet<unsigned> immArgPositionsSet(immArgPositions.begin(),
3085 immArgPositions.end());
3087 llvm::AttributeList llvmAttrs = call->getAttributes();
3089 bool anyArgAttrs =
false;
3090 for (
size_t i = 0, e = call->arg_size(); i < e; ++i) {
3092 if (immArgPositionsSet.contains(i))
3094 llvmArgAttrsSet.emplace_back(llvmAttrs.getParamAttrs(i));
3095 if (llvmArgAttrsSet.back().hasAttributes())
3100 for (
auto &dict : dictAttrs)
3101 attrs.push_back(dict ? dict : builder.getDictionaryAttr({}));
3102 return builder.getArrayAttr(attrs);
3106 for (
auto &llvmArgAttrs : llvmArgAttrsSet)
3107 argAttrs.emplace_back(convertArgOrResultAttrSet(llvmArgAttrs));
3108 attrsOp.setArgAttrsAttr(getArrayAttr(argAttrs));
3112 llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
3113 if (!llvmResAttr.hasAttributes())
3115 DictionaryAttr resAttrs = convertArgOrResultAttrSet(llvmResAttr);
3116 attrsOp.setResAttrsAttr(getArrayAttr({resAttrs}));
3119template <
typename Op>
3121 op.setCConv(convertCConvFromLLVM(inst->getCallingConv()));
3125LogicalResult ModuleImport::convertInvokeAttributes(llvm::InvokeInst *inst,
3130LogicalResult ModuleImport::convertCallAttributes(llvm::CallInst *inst,
3136 llvm::AttributeList callAttrs = inst->getAttributes();
3138 op.setTailCallKind(convertTailCallKindFromLLVM(inst->getTailCallKind()));
3139 op.setConvergent(callAttrs.getFnAttr(llvm::Attribute::Convergent).isValid());
3140 op.setNoUnwind(callAttrs.getFnAttr(llvm::Attribute::NoUnwind).isValid());
3141 op.setWillReturn(callAttrs.getFnAttr(llvm::Attribute::WillReturn).isValid());
3142 op.setNoreturn(callAttrs.getFnAttr(llvm::Attribute::NoReturn).isValid());
3144 callAttrs.getFnAttr(llvm::Attribute::OptimizeForSize).isValid());
3145 op.setSaveRegParams(callAttrs.getFnAttr(
"save-reg-params").isValid());
3146 op.setBuiltin(callAttrs.getFnAttr(llvm::Attribute::Builtin).isValid());
3147 op.setNobuiltin(callAttrs.getFnAttr(llvm::Attribute::NoBuiltin).isValid());
3148 op.setMinsize(callAttrs.getFnAttr(llvm::Attribute::MinSize).isValid());
3151 callAttrs.getFnAttr(llvm::Attribute::ReturnsTwice).isValid());
3152 op.setHot(callAttrs.getFnAttr(llvm::Attribute::Hot).isValid());
3153 op.setCold(callAttrs.getFnAttr(llvm::Attribute::Cold).isValid());
3155 callAttrs.getFnAttr(llvm::Attribute::NoDuplicate).isValid());
3156 op.setNoCallerSavedRegisters(
3157 callAttrs.getFnAttr(
"no_caller_saved_registers").isValid());
3158 op.setNocallback(callAttrs.getFnAttr(llvm::Attribute::NoCallback).isValid());
3160 if (llvm::Attribute attr = callAttrs.getFnAttr(
"modular-format");
3161 attr.isStringAttribute())
3162 op.setModularFormat(StringAttr::get(context, attr.getValueAsString()));
3163 if (llvm::Attribute attr = callAttrs.getFnAttr(
"zero-call-used-regs");
3164 attr.isStringAttribute())
3165 op.setZeroCallUsedRegsAttr(
3166 StringAttr::get(context, attr.getValueAsString()));
3167 if (llvm::Attribute attr = callAttrs.getFnAttr(
"trap-func-name");
3168 attr.isStringAttribute())
3169 op.setTrapFuncNameAttr(StringAttr::get(context, attr.getValueAsString()));
3170 op.setNoInline(callAttrs.getFnAttr(llvm::Attribute::NoInline).isValid());
3172 callAttrs.getFnAttr(llvm::Attribute::AlwaysInline).isValid());
3173 op.setInlineHint(callAttrs.getFnAttr(llvm::Attribute::InlineHint).isValid());
3175 llvm::MemoryEffects memEffects = inst->getMemoryEffects();
3176 ModRefInfo othermem = convertModRefInfoFromLLVM(
3177 memEffects.getModRef(llvm::MemoryEffects::Location::Other));
3178 ModRefInfo argMem = convertModRefInfoFromLLVM(
3179 memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
3180 ModRefInfo inaccessibleMem = convertModRefInfoFromLLVM(
3181 memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
3182 ModRefInfo errnoMem = convertModRefInfoFromLLVM(
3183 memEffects.getModRef(llvm::MemoryEffects::Location::ErrnoMem));
3184 ModRefInfo targetMem0 = convertModRefInfoFromLLVM(
3185 memEffects.getModRef(llvm::MemoryEffects::Location::TargetMem0));
3186 ModRefInfo targetMem1 = convertModRefInfoFromLLVM(
3187 memEffects.getModRef(llvm::MemoryEffects::Location::TargetMem1));
3189 MemoryEffectsAttr::get(op.getContext(), othermem, argMem, inaccessibleMem,
3190 errnoMem, targetMem0, targetMem1);
3192 if (!memAttr.isReadWrite())
3193 op.setMemoryEffectsAttr(memAttr);
3206 if (
func->isIntrinsic() &&
3207 iface.isConvertibleIntrinsic(
func->getIntrinsicID()))
3210 bool dsoLocal =
func->isDSOLocal();
3211 CConv cconv = convertCConvFromLLVM(
func->getCallingConv());
3215 builder.setInsertionPointToEnd(mlirModule.getBody());
3217 Location loc = debugImporter->translateFuncLocation(
func);
3218 LLVMFuncOp funcOp = LLVMFuncOp::create(
3219 builder, loc,
func->getName(), functionType,
3220 convertLinkageFromLLVM(
func->getLinkage()), dsoLocal, cconv);
3225 funcOp.setPersonalityAttr(personality);
3226 else if (
func->hasPersonalityFn())
3227 emitWarning(funcOp.getLoc(),
"could not deduce personality, skipping it");
3230 funcOp.setGarbageCollector(StringRef(
func->getGC()));
3232 if (
func->hasAtLeastLocalUnnamedAddr())
3233 funcOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(
func->getUnnamedAddr()));
3235 if (
func->hasSection())
3236 funcOp.setSection(StringRef(
func->getSection()));
3238 funcOp.setVisibility_(convertVisibilityFromLLVM(
func->getVisibility()));
3240 if (
func->hasComdat())
3241 funcOp.setComdatAttr(comdatMapping.lookup(
func->getComdat()));
3243 if (llvm::MaybeAlign maybeAlign =
func->getAlign())
3244 funcOp.setAlignment(maybeAlign->value());
3251 func->getAllMetadata(allMetadata);
3252 for (
auto &[kind, node] : allMetadata) {
3253 if (!iface.isConvertibleMetadata(kind))
3255 if (failed(iface.setMetadataAttrs(builder, kind, node, funcOp, *
this))) {
3257 <<
"unhandled function metadata: " <<
diagMD(node, llvmModule.get())
3262 if (
func->isDeclaration())
3271 llvm::df_iterator_default_set<llvm::BasicBlock *> reachable;
3272 for (llvm::BasicBlock *basicBlock : llvm::depth_first_ext(
func, reachable))
3277 for (llvm::BasicBlock &basicBlock : *
func) {
3279 if (!reachable.contains(&basicBlock)) {
3280 if (basicBlock.hasAddressTaken())
3282 <<
"unreachable block '" << basicBlock.getName()
3283 <<
"' with address taken";
3286 Region &body = funcOp.getBody();
3287 Block *block = builder.createBlock(&body, body.
end());
3289 reachableBasicBlocks.push_back(&basicBlock);
3293 for (
const auto &it : llvm::enumerate(
func->args())) {
3294 BlockArgument blockArg = funcOp.getFunctionBody().addArgument(
3295 functionType.getParamType(it.index()), funcOp.getLoc());
3304 setConstantInsertionPointToStart(
lookupBlock(blocks.front()));
3305 for (llvm::BasicBlock *basicBlock : blocks)
3306 if (failed(processBasicBlock(basicBlock,
lookupBlock(basicBlock))))
3311 if (failed(processDebugIntrinsics()))
3316 if (failed(processDebugRecords()))
3325 if (!dbgIntr->isKillLocation())
3327 llvm::Value *value = dbgIntr->getArgOperand(0);
3328 auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
3331 return !isa<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
3343 auto dominatedBlocks = domInfo.
getNode(op->getBlock())->children();
3346 if (dominatedBlocks.empty())
3350 Block *dominatedBlock = (*dominatedBlocks.begin())->getBlock();
3353 Value insertPt = argOperand;
3354 if (
auto blockArg = dyn_cast<BlockArgument>(argOperand)) {
3360 if (!insertionBlock->
empty() &&
3361 isa<LandingpadOp>(insertionBlock->
front()))
3362 insertPt = cast<LandingpadOp>(insertionBlock->
front()).getRes();
3370std::tuple<DILocalVariableAttr, DIExpressionAttr, Value>
3371ModuleImport::processDebugOpArgumentsAndInsertionPt(
3373 llvm::function_ref<FailureOr<Value>()> convertArgOperandToValue,
3374 llvm::Value *address,
3375 llvm::PointerUnion<llvm::Value *, llvm::DILocalVariable *> variable,
3376 llvm::DIExpression *expression, DominanceInfo &domInfo) {
3382 FailureOr<Value> argOperand = convertArgOperandToValue();
3383 if (
failed(argOperand)) {
3384 emitError(loc) <<
"failed to convert a debug operand: " <<
diag(*address);
3392 return {localVarAttr, debugImporter->translateExpression(expression),
3397ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
3398 DominanceInfo &domInfo) {
3400 auto emitUnsupportedWarning = [&]() {
3401 if (emitExpensiveWarnings)
3406 OpBuilder::InsertionGuard guard(builder);
3407 auto convertArgOperandToValue = [&]() {
3413 if (dbgIntr->hasArgList())
3414 return emitUnsupportedWarning();
3421 return emitUnsupportedWarning();
3423 auto [localVariableAttr, locationExprAttr, locVal] =
3424 processDebugOpArgumentsAndInsertionPt(
3425 loc, convertArgOperandToValue, dbgIntr->getArgOperand(0),
3426 dbgIntr->getArgOperand(1), dbgIntr->getExpression(), domInfo);
3428 if (!localVariableAttr)
3429 return emitUnsupportedWarning();
3434 Operation *op =
nullptr;
3435 if (isa<llvm::DbgDeclareInst>(dbgIntr))
3436 op = LLVM::DbgDeclareOp::create(builder, loc, locVal, localVariableAttr,
3438 else if (isa<llvm::DbgValueInst>(dbgIntr))
3439 op = LLVM::DbgValueOp::create(builder, loc, locVal, localVariableAttr,
3442 return emitUnsupportedWarning();
3445 setNonDebugMetadataAttrs(dbgIntr, op);
3450ModuleImport::processDebugRecord(llvm::DbgVariableRecord &dbgRecord,
3451 DominanceInfo &domInfo) {
3452 OpBuilder::InsertionGuard guard(builder);
3454 auto emitUnsupportedWarning = [&]() -> LogicalResult {
3455 if (!emitExpensiveWarnings)
3458 llvm::raw_string_ostream optionsStream(
options);
3459 dbgRecord.print(optionsStream);
3460 emitWarning(loc) <<
"unhandled debug variable record "
3461 << optionsStream.str();
3467 if (dbgRecord.hasArgList())
3468 return emitUnsupportedWarning();
3473 if (!dbgRecord.getAddress())
3474 return emitUnsupportedWarning();
3476 auto convertArgOperandToValue = [&]() -> FailureOr<Value> {
3477 llvm::Value *value = dbgRecord.getAddress();
3480 auto it = valueMapping.find(value);
3481 if (it != valueMapping.end())
3482 return it->getSecond();
3485 if (
auto *constant = dyn_cast<llvm::Constant>(value))
3486 return convertConstantExpr(constant);
3490 auto [localVariableAttr, locationExprAttr, locVal] =
3491 processDebugOpArgumentsAndInsertionPt(
3492 loc, convertArgOperandToValue, dbgRecord.getAddress(),
3493 dbgRecord.getVariable(), dbgRecord.getExpression(), domInfo);
3495 if (!localVariableAttr)
3496 return emitUnsupportedWarning();
3501 if (dbgRecord.isDbgDeclare())
3502 LLVM::DbgDeclareOp::create(builder, loc, locVal, localVariableAttr,
3504 else if (dbgRecord.isDbgValue())
3505 LLVM::DbgValueOp::create(builder, loc, locVal, localVariableAttr,
3508 return emitUnsupportedWarning();
3513LogicalResult ModuleImport::processDebugIntrinsics() {
3514 DominanceInfo domInfo;
3515 for (llvm::Instruction *inst : debugIntrinsics) {
3516 auto *intrCall = cast<llvm::DbgVariableIntrinsic>(inst);
3517 if (
failed(processDebugIntrinsic(intrCall, domInfo)))
3523LogicalResult ModuleImport::processDebugRecords() {
3524 DominanceInfo domInfo;
3525 for (llvm::DbgVariableRecord *dbgRecord : dbgRecords)
3526 if (
failed(processDebugRecord(*dbgRecord, domInfo)))
3532LogicalResult ModuleImport::processBasicBlock(llvm::BasicBlock *bb,
3534 builder.setInsertionPointToStart(block);
3535 for (llvm::Instruction &inst : *bb) {
3536 if (
failed(processInstruction(&inst)))
3541 if (debugIntrinsics.contains(&inst))
3548 setNonDebugMetadataAttrs(&inst, op);
3549 }
else if (inst.getOpcode() != llvm::Instruction::PHI) {
3550 if (emitExpensiveWarnings) {
3551 Location loc = debugImporter->translateLoc(inst.getDebugLoc());
3557 if (bb->hasAddressTaken()) {
3558 OpBuilder::InsertionGuard guard(builder);
3559 builder.setInsertionPointToStart(block);
3561 BlockTagAttr::get(context, bb->getNumber()));
3566FailureOr<SmallVector<AccessGroupAttr>>
3568 return loopAnnotationImporter->lookupAccessGroupAttrs(node);
3574 return loopAnnotationImporter->translateLoopAnnotation(node, loc);
3577FailureOr<DereferenceableAttr>
3580 Location loc = mlirModule.getLoc();
3584 if (node->getNumOperands() != 1)
3585 return emitError(loc) <<
"dereferenceable metadata must have one operand: "
3586 <<
diagMD(node, llvmModule.get());
3588 auto *numBytesMD = dyn_cast<llvm::ConstantAsMetadata>(node->getOperand(0));
3589 auto *numBytesCst = dyn_cast<llvm::ConstantInt>(numBytesMD->getValue());
3590 if (!numBytesCst || !numBytesCst->getValue().isNonNegative())
3591 return emitError(loc) <<
"dereferenceable metadata operand must be a "
3592 "non-negative constant integer: "
3593 <<
diagMD(node, llvmModule.get());
3595 bool mayBeNull = kindID == llvm::LLVMContext::MD_dereferenceable_or_null;
3596 auto derefAttr = builder.getAttr<DereferenceableAttr>(
3597 numBytesCst->getZExtValue(), mayBeNull);
3603 std::unique_ptr<llvm::Module> llvmModule,
MLIRContext *context,
3604 bool emitExpensiveWarnings,
bool dropDICompositeTypeElements,
3605 bool loadAllDialects,
bool preferUnregisteredIntrinsics,
3606 bool importStructsAsLiterals) {
3613 LLVMDialect::getDialectNamespace()));
3615 DLTIDialect::getDialectNamespace()));
3616 if (loadAllDialects)
3619 StringAttr::get(context, llvmModule->getSourceFileName()), 0,
3623 emitExpensiveWarnings, dropDICompositeTypeElements,
3624 preferUnregisteredIntrinsics,
3625 importStructsAsLiterals);
*if copies could not be generated due to yet unimplemented cases *copyInPlacementStart and copyOutPlacementStart in copyPlacementBlock *specify the insertion points where the incoming copies and outgoing should be inserted(the insertion happens right before the *insertion point). Since `begin` can itself be invalidated due to the memref *rewriting done from this method
static ArrayAttr convertLLVMAttributesToMLIR(Location loc, MLIRContext *context, llvm::AttributeSet attributes, ArrayRef< StringLiteral > attributesToSkip={}, ArrayRef< StringLiteral > attributePrefixesToSkip={})
Converts LLVM string, integer, and enum attributes into MLIR attributes, skipping those in attributes...
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)
Converts LLVM attributes from func into MLIR attributes and adds them to funcOp as passthrough attrib...
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 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 std::array kExplicitLLVMFuncOpAttributePrefixes
static constexpr StringRef getGlobalDtorsVarName()
Returns the name of the global_dtors global variables.
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 Attribute convertMetadataToAttr(MLIRContext *ctx, const llvm::Metadata *md)
Converts the metadata node md to the matching LLVM dialect metadata attribute.
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 std::array kExplicitLLVMFuncOpAttributes
static constexpr StringRef getGlobalComdatOpName()
Returns the symbol name for the module-level comdat operation.
static void convertNoBuiltinAttrs(MLIRContext *ctx, const llvm::AttributeSet &attrs, OpTy target)
static SmallVector< int64_t > getPositionFromIndices(ArrayRef< unsigned > indices)
Converts an array of unsigned indices to a signed integer position array.
static LogicalResult setDebugIntrinsicBuilderInsertionPoint(mlir::OpBuilder &builder, DominanceInfo &domInfo, Value argOperand)
Ensure that the debug intrinsic is inserted right after the operand definition.
static LogicalResult checkFunctionTypeCompatibility(LLVMFunctionType callType, LLVMFunctionType calleeType)
Checks if callType and calleeType are compatible and can be represented in MLIR.
static void processDenormalFPEnv(llvm::Function *func, LLVMFuncOp funcOp)
static std::optional< ProfileSummaryFormatKind > convertProfileSummaryFormat(ModuleOp mlirModule, const llvm::Module *llvmModule, const llvm::MDOperand &formatMD)
static constexpr StringRef getGlobalCtorsVarName()
Returns the name of the global_ctors global variables.
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 void processTargetSpecificAttrs(llvm::GlobalVariable *globalVar, GlobalOp globalOp)
Converts LLVM attributes from globalVar into MLIR attributes and adds them to globalOp as target-spec...
static Attribute convertMetadataToAttrImpl(MLIRContext *ctx, const llvm::Metadata *md, SmallPtrSetImpl< const llvm::Metadata * > &path, DenseMap< const llvm::Metadata *, Attribute > &attrMap)
Depth-first conversion of the metadata node md to the matching LLVM dialect metadata attribute.
static Attribute convertProfileSummaryModuleFlagValue(ModuleOp mlirModule, const llvm::Module *llvmModule, llvm::MDTuple *mdTuple)
static llvm::MDTuple * getTwoElementMDTuple(ModuleOp mlirModule, const llvm::Module *llvmModule, const llvm::MDOperand &md)
Extract a two element MDTuple from a MDOperand.
static bool isMetadataKillLocation(llvm::DbgVariableIntrinsic *dbgIntr)
Checks if dbgIntr is a kill location that holds metadata instead of an SSA value.
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 void convertAllocsizeAttr(MLIRContext *ctx, const llvm::AttributeSet &attrs, OpTy target)
static std::string diagMD(const llvm::Metadata *node, const llvm::Module *module)
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 FailureOr< SmallVector< ModuleFlagProfileSummaryDetailedAttr > > convertProfileSummaryDetailed(ModuleOp mlirModule, const llvm::Module *llvmModule, const llvm::MDOperand &summaryMD)
static SetVector< llvm::BasicBlock * > getTopologicallySortedBlocks(ArrayRef< llvm::BasicBlock * > basicBlocks)
Get a topologically sorted list of blocks for the given basic blocks.
static llvm::ManagedStatic< PassManagerOptions > options
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.
Operation * getParentOp()
Returns the closest surrounding operation that contains this block.
This class is a general helper class for creating context-global objects like types,...
IntegerAttr getIntegerAttr(Type type, int64_t value)
FloatAttr getFloatAttr(Type type, double value)
IntegerAttr getI64IntegerAttr(int64_t value)
StringAttr getStringAttr(const Twine &bytes)
ArrayAttr getArrayAttr(ArrayRef< Attribute > value)
MLIRContext * getContext() const
NamedAttribute getNamedAttr(StringRef name, Attribute val)
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.
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 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.
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,...
LogicalResult convertLinkerOptionsMetadata()
Converts !llvm.linker.options metadata to the llvm.linker.options LLVM dialect operation.
Block * lookupBlock(llvm::BasicBlock *block) const
Returns the MLIR block mapped to the given LLVM block.
void mapBlock(llvm::BasicBlock *llvm, Block *mlir)
Stores the mapping between an LLVM block and its MLIR counterpart.
DILocalVariableAttr matchLocalVariableAttr(llvm::PointerUnion< llvm::Value *, llvm::DILocalVariable * > valOrVariable)
Converts valOrVariable to a local variable attribute.
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.
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.
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.
Operation * lookupOperation(llvm::Instruction *inst)
Returns the MLIR operation mapped to the given LLVM instruction.
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 addDebugRecord(llvm::DbgVariableRecord *dbgRecord)
Adds a debug record to the list of debug records that need to be imported after the function conversi...
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.
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.
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.
This class acts as an owning reference to an op, and will automatically destroy the held op on destru...
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.
static SmallString< N > generateSymbolName(StringRef name, UniqueChecker uniqueChecker, unsigned &uniquingCounter)
Generate a unique symbol name.
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 represents an instance of an SSA value in the MLIR system, representing a computable value...
Block * getParentBlock()
Return the Block in which this Value is defined.
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)
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.
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.
llvm::DenseSet< ValueT, ValueInfoT > DenseSet
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
llvm::SetVector< T, Vector, Set, N > SetVector
llvm::DenseMap< KeyT, ValueT, KeyInfoT, BucketT > DenseMap
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.