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()));
1155 for (
const llvm::Module::GlobalAsmFragment &Frag :
1156 llvmModule->getModuleInlineAsm()) {
1158 for (llvm::StringRef line : llvm::split(Frag.Asm,
'\n'))
1160 asmArrayAttr.push_back(builder.getStringAttr(line));
1163 mlirModule->setAttr(LLVM::LLVMDialect::getModuleLevelAsmAttrName(),
1164 builder.getArrayAttr(asmArrayAttr));
1168 for (llvm::Function &
func : llvmModule->functions())
1174void ModuleImport::setNonDebugMetadataAttrs(llvm::Instruction *inst,
1177 inst->getAllMetadataOtherThanDebugLoc(allMetadata);
1178 for (
auto &[kind, node] : allMetadata) {
1182 if (emitExpensiveWarnings) {
1183 Location loc = debugImporter->translateLoc(inst->getDebugLoc());
1185 <<
diagMD(node, llvmModule.get()) <<
" on "
1194 auto iface = cast<IntegerOverflowFlagsInterface>(op);
1196 IntegerOverflowFlags value = {};
1197 value = bitEnumSet(value, IntegerOverflowFlags::nsw, inst->hasNoSignedWrap());
1199 bitEnumSet(value, IntegerOverflowFlags::nuw, inst->hasNoUnsignedWrap());
1201 iface.setOverflowFlags(value);
1205 auto iface = cast<ExactFlagInterface>(op);
1207 iface.setIsExact(inst->isExact());
1212 auto iface = cast<DisjointFlagInterface>(op);
1213 auto *instDisjoint = cast<llvm::PossiblyDisjointInst>(inst);
1215 iface.setIsDisjoint(instDisjoint->isDisjoint());
1219 auto iface = cast<NonNegFlagInterface>(op);
1221 iface.setNonNeg(inst->hasNonNeg());
1226 auto iface = cast<FastmathFlagsInterface>(op);
1232 if (!isa<llvm::FPMathOperator>(inst))
1234 llvm::FastMathFlags flags = inst->getFastMathFlags();
1237 FastmathFlags value = {};
1238 value = bitEnumSet(value, FastmathFlags::nnan, flags.noNaNs());
1239 value = bitEnumSet(value, FastmathFlags::ninf, flags.noInfs());
1240 value = bitEnumSet(value, FastmathFlags::nsz, flags.noSignedZeros());
1241 value = bitEnumSet(value, FastmathFlags::arcp, flags.allowReciprocal());
1242 value = bitEnumSet(value, FastmathFlags::contract, flags.allowContract());
1243 value = bitEnumSet(value, FastmathFlags::afn, flags.approxFunc());
1244 value = bitEnumSet(value, FastmathFlags::reassoc, flags.allowReassoc());
1245 FastmathFlagsAttr attr = FastmathFlagsAttr::get(builder.getContext(), value);
1246 iface->setAttr(iface.getFastmathAttrName(), attr);
1258 if (numElements.isScalable()) {
1260 <<
"scalable vectors not supported";
1265 Type elementType = cast<VectorType>(type).getElementType();
1269 SmallVector<int64_t> shape(arrayShape);
1270 shape.push_back(numElements.getKnownMinValue());
1271 return VectorType::get(shape, elementType);
1274Type ModuleImport::getBuiltinTypeForAttr(Type type) {
1288 SmallVector<int64_t> arrayShape;
1289 while (
auto arrayType = dyn_cast<LLVMArrayType>(type)) {
1290 arrayShape.push_back(arrayType.getNumElements());
1291 type = arrayType.getElementType();
1294 return RankedTensorType::get(arrayShape, type);
1301 llvm::Constant *constScalar) {
1304 if (constScalar->getType()->isVectorTy())
1308 if (
auto *constInt = dyn_cast<llvm::ConstantInt>(constScalar)) {
1310 IntegerType::get(context, constInt->getBitWidth()),
1311 constInt->getValue());
1315 if (
auto *constFloat = dyn_cast<llvm::ConstantFP>(constScalar)) {
1316 llvm::Type *type = constFloat->getType();
1317 FloatType floatType =
1319 ? BFloat16Type::get(context)
1323 <<
"unexpected floating-point type";
1326 return builder.
getFloatAttr(floatType, constFloat->getValueAPF());
1333static SmallVector<Attribute>
1335 llvm::ConstantDataSequential *constSequence) {
1337 elementAttrs.reserve(constSequence->getNumElements());
1338 for (
auto idx : llvm::seq<int64_t>(0, constSequence->getNumElements())) {
1339 llvm::Constant *constElement = constSequence->getElementAsConstant(idx);
1342 return elementAttrs;
1345Attribute ModuleImport::getConstantAsAttr(llvm::Constant *constant) {
1351 auto getConstantShape = [&](llvm::Type *type) {
1352 return llvm::dyn_cast_if_present<ShapedType>(
1357 if (isa<llvm::ConstantInt, llvm::ConstantFP>(constant)) {
1358 assert(constant->getType()->isVectorTy() &&
"expected a vector splat");
1359 auto shape = getConstantShape(constant->getType());
1362 Attribute splatAttr =
1369 if (
auto *constArray = dyn_cast<llvm::ConstantDataSequential>(constant)) {
1370 if (constArray->isString())
1371 return builder.getStringAttr(constArray->getAsString());
1372 auto shape = getConstantShape(constArray->getType());
1376 auto *constVector = dyn_cast<llvm::ConstantDataVector>(constant);
1377 if (constVector && constVector->isSplat()) {
1380 builder, constVector->getElementAsConstant(0));
1384 SmallVector<Attribute> elementAttrs =
1391 if (
auto *constAggregate = dyn_cast<llvm::ConstantAggregate>(constant)) {
1392 auto shape = getConstantShape(constAggregate->getType());
1396 SmallVector<Attribute> elementAttrs;
1397 SmallVector<llvm::Constant *> workList = {constAggregate};
1398 while (!workList.empty()) {
1399 llvm::Constant *current = workList.pop_back_val();
1402 if (
auto *constAggregate = dyn_cast<llvm::ConstantAggregate>(current)) {
1404 reverse(llvm::seq<int64_t>(0, constAggregate->getNumOperands())))
1405 workList.push_back(constAggregate->getAggregateElement(idx));
1410 if (
auto *constArray = dyn_cast<llvm::ConstantDataSequential>(current)) {
1411 SmallVector<Attribute> attrs =
1413 elementAttrs.append(attrs.begin(), attrs.end());
1419 elementAttrs.push_back(scalarAttr);
1430 if (
auto *constZero = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1431 auto shape = llvm::dyn_cast_if_present<ShapedType>(
1432 getBuiltinTypeForAttr(
convertType(constZero->getType())));
1436 Attribute splatAttr = builder.getZeroAttr(shape.getElementType());
1437 assert(splatAttr &&
"expected non-null zero attribute for scalar types");
1444ModuleImport::getOrCreateNamelessSymbolName(llvm::GlobalVariable *globalVar) {
1445 assert(globalVar->getName().empty() &&
1446 "expected to work with a nameless global");
1447 auto [it,
success] = namelessGlobals.try_emplace(globalVar);
1454 [
this](StringRef newName) {
return llvmModule->getNamedValue(newName); },
1457 it->getSecond() = symbolRef;
1461OpBuilder::InsertionGuard ModuleImport::setGlobalInsertionPoint() {
1462 OpBuilder::InsertionGuard guard(builder);
1463 if (globalInsertionOp)
1464 builder.setInsertionPointAfter(globalInsertionOp);
1466 builder.setInsertionPointToStart(mlirModule.getBody());
1470LogicalResult ModuleImport::convertAlias(llvm::GlobalAlias *alias) {
1472 OpBuilder::InsertionGuard guard = setGlobalInsertionPoint();
1475 AliasOp aliasOp = AliasOp::create(builder, mlirModule.getLoc(), type,
1476 convertLinkageFromLLVM(alias->getLinkage()),
1478 alias->isDSOLocal(),
1479 alias->isThreadLocal(),
1480 ArrayRef<NamedAttribute>());
1481 globalInsertionOp = aliasOp;
1484 Block *block = builder.createBlock(&aliasOp.getInitializerRegion());
1485 setConstantInsertionPointToStart(block);
1486 FailureOr<Value> initializer = convertConstantExpr(alias->getAliasee());
1489 ReturnOp::create(builder, aliasOp.getLoc(), *initializer);
1491 if (alias->hasAtLeastLocalUnnamedAddr())
1492 aliasOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(alias->getUnnamedAddr()));
1493 aliasOp.setVisibility_(convertVisibilityFromLLVM(alias->getVisibility()));
1498LogicalResult ModuleImport::convertIFunc(llvm::GlobalIFunc *ifunc) {
1499 OpBuilder::InsertionGuard guard = setGlobalInsertionPoint();
1502 llvm::Constant *resolver = ifunc->getResolver();
1503 Type resolverType =
convertType(resolver->getType());
1504 IFuncOp::create(builder, mlirModule.getLoc(), ifunc->getName(), type,
1505 resolver->getName(), resolverType,
1506 convertLinkageFromLLVM(ifunc->getLinkage()),
1507 ifunc->isDSOLocal(), ifunc->getAddressSpace(),
1508 convertUnnamedAddrFromLLVM(ifunc->getUnnamedAddr()),
1509 convertVisibilityFromLLVM(ifunc->getVisibility()));
1519 ArrayRef<StringLiteral> attributePrefixesToSkip = {}) {
1520 SmallVector<Attribute> mlirAttributes;
1521 for (llvm::Attribute attr : attributes) {
1523 if (attr.isStringAttribute())
1524 attrName = attr.getKindAsString();
1526 attrName = llvm::Attribute::getNameFromAttrKind(attr.getKindAsEnum());
1527 if (llvm::is_contained(attributesToSkip, attrName))
1530 auto attrNameStartsWith = [attrName](StringLiteral sl) {
1531 return attrName.starts_with(sl);
1533 if (attributePrefixesToSkip.end() !=
1534 llvm::find_if(attributePrefixesToSkip, attrNameStartsWith))
1537 auto keyAttr = StringAttr::get(context, attrName);
1538 if (attr.isStringAttribute()) {
1539 StringRef val = attr.getValueAsString();
1542 mlirAttributes.push_back(keyAttr);
1546 mlirAttributes.push_back(
1547 ArrayAttr::get(context, {keyAttr, StringAttr::get(context, val)}));
1550 if (attr.isIntAttribute()) {
1553 auto val = std::to_string(attr.getValueAsInt());
1554 mlirAttributes.push_back(
1555 ArrayAttr::get(context, {keyAttr, StringAttr::get(context, val)}));
1558 if (attr.isEnumAttribute()) {
1560 mlirAttributes.push_back(keyAttr);
1566 <<
"' attribute is invalid on current operation, skipping it";
1568 return ArrayAttr::get(context, mlirAttributes);
1574 GlobalOp globalOp) {
1576 globalOp.getLoc(), globalOp.getContext(), globalVar->getAttributes());
1577 if (!targetSpecificAttrs.empty())
1578 globalOp.setTargetSpecificAttrsAttr(targetSpecificAttrs);
1581LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
1583 OpBuilder::InsertionGuard guard = setGlobalInsertionPoint();
1585 Attribute valueAttr;
1586 if (globalVar->hasInitializer())
1587 valueAttr = getConstantAsAttr(globalVar->getInitializer());
1588 Type type =
convertType(globalVar->getValueType());
1590 uint64_t alignment = 0;
1591 llvm::MaybeAlign maybeAlign = globalVar->getAlign();
1592 if (maybeAlign.has_value()) {
1593 llvm::Align align = *maybeAlign;
1594 alignment = align.value();
1599 SmallVector<Attribute> globalExpressionAttrs;
1600 SmallVector<llvm::DIGlobalVariableExpression *> globalExpressions;
1601 globalVar->getDebugInfo(globalExpressions);
1603 for (llvm::DIGlobalVariableExpression *expr : globalExpressions) {
1604 DIGlobalVariableExpressionAttr globalExpressionAttr =
1605 debugImporter->translateGlobalVariableExpression(expr);
1606 globalExpressionAttrs.push_back(globalExpressionAttr);
1611 StringRef globalName = globalVar->getName();
1612 if (globalName.empty())
1613 globalName = getOrCreateNamelessSymbolName(globalVar).getValue();
1615 GlobalOp globalOp = GlobalOp::create(
1616 builder, mlirModule.getLoc(), type, globalVar->isConstant(),
1617 convertLinkageFromLLVM(globalVar->getLinkage()), StringRef(globalName),
1618 valueAttr, alignment, globalVar->getAddressSpace(),
1619 globalVar->isDSOLocal(),
1620 globalVar->isThreadLocal(), SymbolRefAttr(),
1621 ArrayRef<NamedAttribute>(), globalExpressionAttrs);
1622 globalInsertionOp = globalOp;
1624 if (globalVar->hasInitializer() && !valueAttr) {
1626 Block *block = builder.createBlock(&globalOp.getInitializerRegion());
1627 setConstantInsertionPointToStart(block);
1628 FailureOr<Value> initializer =
1629 convertConstantExpr(globalVar->getInitializer());
1632 ReturnOp::create(builder, globalOp.getLoc(), *initializer);
1634 if (globalVar->hasAtLeastLocalUnnamedAddr()) {
1635 globalOp.setUnnamedAddr(
1636 convertUnnamedAddrFromLLVM(globalVar->getUnnamedAddr()));
1638 if (globalVar->hasSection())
1639 globalOp.setSection(globalVar->getSection());
1640 globalOp.setVisibility_(
1641 convertVisibilityFromLLVM(globalVar->getVisibility()));
1643 if (globalVar->hasComdat())
1644 globalOp.setComdatAttr(comdatMapping.lookup(globalVar->getComdat()));
1652ModuleImport::convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar) {
1653 if (!globalVar->hasInitializer() || !globalVar->hasAppendingLinkage())
1655 llvm::Constant *initializer = globalVar->getInitializer();
1657 bool knownInit = isa<llvm::ConstantArray>(initializer) ||
1658 isa<llvm::ConstantAggregateZero>(initializer);
1665 if (
auto *caz = dyn_cast<llvm::ConstantAggregateZero>(initializer)) {
1666 if (caz->getElementCount().getFixedValue() != 0)
1670 SmallVector<Attribute> funcs;
1671 SmallVector<int32_t> priorities;
1672 SmallVector<Attribute> dataList;
1673 for (llvm::Value *operand : initializer->operands()) {
1674 auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
1675 if (!aggregate || aggregate->getNumOperands() != 3)
1678 auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
1679 auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
1680 auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
1681 if (!priority || !func || !data)
1684 auto *gv = dyn_cast_or_null<llvm::GlobalValue>(data);
1688 else if (data->isNullValue())
1689 dataAttr = ZeroAttr::get(context);
1694 priorities.push_back(priority->getValue().getZExtValue());
1695 dataList.push_back(dataAttr);
1699 OpBuilder::InsertionGuard guard = setGlobalInsertionPoint();
1702 globalInsertionOp = LLVM::GlobalCtorsOp::create(
1703 builder, mlirModule.getLoc(), builder.getArrayAttr(funcs),
1704 builder.getI32ArrayAttr(priorities), builder.getArrayAttr(dataList));
1707 globalInsertionOp = LLVM::GlobalDtorsOp::create(
1708 builder, mlirModule.getLoc(), builder.getArrayAttr(funcs),
1709 builder.getI32ArrayAttr(priorities), builder.getArrayAttr(dataList));
1714ModuleImport::getConstantsToConvert(llvm::Constant *constant) {
1716 if (valueMapping.contains(constant))
1725 workList.insert(constant);
1726 while (!workList.empty()) {
1727 llvm::Constant *current = workList.back();
1730 if (isa<llvm::GlobalObject>(current) || isa<llvm::GlobalAlias>(current)) {
1731 orderedSet.insert(current);
1732 workList.pop_back();
1738 auto [adjacencyIt,
inserted] = adjacencyLists.try_emplace(current);
1742 for (llvm::Value *operand : current->operands())
1743 if (
auto *constDependency = dyn_cast<llvm::Constant>(operand))
1744 adjacencyIt->getSecond().push_back(constDependency);
1747 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(current)) {
1748 unsigned numElements = constAgg->getElementCount().getFixedValue();
1749 for (
unsigned i = 0, e = numElements; i != e; ++i)
1750 adjacencyIt->getSecond().push_back(constAgg->getElementValue(i));
1756 if (adjacencyIt->getSecond().empty()) {
1757 orderedSet.insert(current);
1758 workList.pop_back();
1766 llvm::Constant *dependency = adjacencyIt->getSecond().pop_back_val();
1767 if (valueMapping.contains(dependency) || workList.contains(dependency) ||
1768 orderedSet.contains(dependency))
1770 workList.insert(dependency);
1776FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
1777 Location loc = UnknownLoc::get(context);
1780 if (Attribute attr = getConstantAsAttr(constant)) {
1782 if (
auto symbolRef = dyn_cast<FlatSymbolRefAttr>(attr)) {
1783 return AddressOfOp::create(builder, loc, type, symbolRef.getValue())
1786 return ConstantOp::create(builder, loc, type, attr).getResult();
1790 if (
auto *nullPtr = dyn_cast<llvm::ConstantPointerNull>(constant)) {
1792 return ZeroOp::create(builder, loc, type).getResult();
1796 if (isa<llvm::ConstantTokenNone>(constant)) {
1797 return NoneTokenOp::create(builder, loc).getResult();
1801 if (
auto *poisonVal = dyn_cast<llvm::PoisonValue>(constant)) {
1803 return PoisonOp::create(builder, loc, type).getResult();
1807 if (
auto *undefVal = dyn_cast<llvm::UndefValue>(constant)) {
1809 return UndefOp::create(builder, loc, type).getResult();
1813 if (
auto *dsoLocalEquivalent = dyn_cast<llvm::DSOLocalEquivalent>(constant)) {
1814 Type type =
convertType(dsoLocalEquivalent->getType());
1815 return DSOLocalEquivalentOp::create(
1818 builder.getContext(),
1819 dsoLocalEquivalent->getGlobalValue()->getName()))
1824 if (
auto *globalObj = dyn_cast<llvm::GlobalObject>(constant)) {
1826 StringRef globalName = globalObj->getName();
1827 FlatSymbolRefAttr symbolRef;
1829 if (globalName.empty())
1831 getOrCreateNamelessSymbolName(cast<llvm::GlobalVariable>(globalObj));
1834 return AddressOfOp::create(builder, loc, type, symbolRef).getResult();
1838 if (
auto *globalAliasObj = dyn_cast<llvm::GlobalAlias>(constant)) {
1839 Type type =
convertType(globalAliasObj->getType());
1840 StringRef aliaseeName = globalAliasObj->getName();
1842 return AddressOfOp::create(builder, loc, type, symbolRef).getResult();
1846 if (
auto *constExpr = dyn_cast<llvm::ConstantExpr>(constant)) {
1852 llvm::Instruction *inst = constExpr->getAsInstruction();
1853 llvm::scope_exit guard([&]() {
1854 assert(!noResultOpMapping.contains(inst) &&
1855 "expected constant expression to return a result");
1856 valueMapping.erase(inst);
1857 inst->deleteValue();
1861 assert(llvm::all_of(inst->operands(), [&](llvm::Value *value) {
1862 return valueMapping.contains(value);
1864 if (
failed(processInstruction(inst)))
1870 if (
auto *aggregateZero = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1871 Type type =
convertType(aggregateZero->getType());
1872 return ZeroOp::create(builder, loc, type).getResult();
1876 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregate>(constant)) {
1878 SmallVector<Value> elementValues;
1880 elementValues.reserve(constAgg->getNumOperands());
1881 for (llvm::Value *operand : constAgg->operands())
1884 assert(llvm::count(elementValues,
nullptr) == 0 &&
1885 "expected all elements have been converted before");
1889 bool isArrayOrStruct = isa<LLVMArrayType, LLVMStructType>(rootType);
1891 "unrecognized aggregate type");
1892 Value root = UndefOp::create(builder, loc, rootType);
1893 for (
const auto &it : llvm::enumerate(elementValues)) {
1894 if (isArrayOrStruct) {
1896 InsertValueOp::create(builder, loc, root, it.value(), it.index());
1898 Attribute indexAttr = builder.getI32IntegerAttr(it.index());
1900 ConstantOp::create(builder, loc, builder.getI32Type(), indexAttr);
1901 root = InsertElementOp::create(builder, loc, rootType, root, it.value(),
1908 if (
auto *constTargetNone = dyn_cast<llvm::ConstantTargetNone>(constant)) {
1909 LLVMTargetExtType targetExtType =
1910 cast<LLVMTargetExtType>(
convertType(constTargetNone->getType()));
1911 assert(targetExtType.hasProperty(LLVMTargetExtType::HasZeroInit) &&
1912 "target extension type does not support zero-initialization");
1915 return LLVM::ZeroOp::create(builder, loc, targetExtType).getRes();
1918 if (
auto *blockAddr = dyn_cast<llvm::BlockAddress>(constant)) {
1922 BlockTagAttr::get(context, blockAddr->getBasicBlock()->getNumber());
1923 return BlockAddressOp::create(
1925 BlockAddressAttr::get(context, fnSym, blockTag))
1929 StringRef error =
"";
1931 if (isa<llvm::ConstantPtrAuth>(constant))
1932 error =
" since ptrauth(...) is unsupported";
1934 if (isa<llvm::NoCFIValue>(constant))
1935 error =
" since no_cfi is unsupported";
1937 if (isa<llvm::GlobalValue>(constant))
1938 error =
" since global value is unsupported";
1940 return emitError(loc) <<
"unhandled constant: " <<
diag(*constant) << error;
1943FailureOr<Value> ModuleImport::convertConstantExpr(llvm::Constant *constant) {
1947 assert(!valueMapping.contains(constant) &&
1948 "expected constant has not been converted before");
1949 assert(constantInsertionBlock &&
1950 "expected the constant insertion block to be non-null");
1953 OpBuilder::InsertionGuard guard(builder);
1954 if (!constantInsertionOp)
1955 builder.setInsertionPointToStart(constantInsertionBlock);
1957 builder.setInsertionPointAfter(constantInsertionOp);
1961 getConstantsToConvert(constant);
1962 for (llvm::Constant *constantToConvert : constantsToConvert) {
1963 FailureOr<Value> converted = convertConstant(constantToConvert);
1966 mapValue(constantToConvert, *converted);
1971 constantInsertionOp =
result.getDefiningOp();
1977 auto it = valueMapping.find(value);
1978 if (it != valueMapping.end())
1979 return it->getSecond();
1986 if (
auto *mdAsVal = dyn_cast<llvm::MetadataAsValue>(value)) {
1987 llvm::Metadata *md = mdAsVal->getMetadata();
1991 <<
"unsupported metadata: " <<
diagMD(md, llvmModule.get());
1993 MetadataAsValueOp::create(builder, UnknownLoc::get(context), mdAttr)
2000 if (
auto *constant = dyn_cast<llvm::Constant>(value))
2001 return convertConstantExpr(constant);
2003 Location loc = UnknownLoc::get(context);
2004 if (
auto *inst = dyn_cast<llvm::Instruction>(value))
2006 return emitError(loc) <<
"unhandled value: " <<
diag(*value);
2012 auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
2015 auto *node = dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
2018 value = node->getValue();
2021 auto it = valueMapping.find(value);
2022 if (it != valueMapping.end())
2023 return it->getSecond();
2026 if (
auto *constant = dyn_cast<llvm::Constant>(value))
2027 return convertConstantExpr(constant);
2031FailureOr<SmallVector<Value>>
2034 remapped.reserve(values.size());
2035 for (llvm::Value *value : values) {
2037 if (failed(converted))
2039 remapped.push_back(*converted);
2049 assert(immArgPositions.size() == immArgAttrNames.size() &&
2050 "LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
2054 for (
auto [immArgPos, immArgName] :
2055 llvm::zip(immArgPositions, immArgAttrNames)) {
2056 auto &value = operands[immArgPos];
2057 auto *constant = llvm::cast<llvm::Constant>(value);
2059 assert(attr && attr.getType().isIntOrFloat() &&
2060 "expected immarg to be float or integer constant");
2061 auto nameAttr = StringAttr::get(attr.getContext(), immArgName);
2062 attrsOut.push_back({nameAttr, attr});
2067 for (llvm::Value *value : operands) {
2071 if (failed(mlirValue))
2073 valuesOut.push_back(*mlirValue);
2078 if (requiresOpBundles) {
2079 opBundleSizes.reserve(opBundles.size());
2080 opBundleTagAttrs.reserve(opBundles.size());
2082 for (
const llvm::OperandBundleUse &bundle : opBundles) {
2083 opBundleSizes.push_back(bundle.Inputs.size());
2084 opBundleTagAttrs.push_back(StringAttr::get(context, bundle.getTagName()));
2086 for (
const llvm::Use &opBundleOperand : bundle.Inputs) {
2087 auto operandMlirValue =
convertValue(opBundleOperand.get());
2088 if (failed(operandMlirValue))
2090 valuesOut.push_back(*operandMlirValue);
2095 auto opBundleSizesAttrNameAttr =
2096 StringAttr::get(context, LLVMDialect::getOpBundleSizesAttrName());
2097 attrsOut.push_back({opBundleSizesAttrNameAttr, opBundleSizesAttr});
2099 auto opBundleTagsAttr = ArrayAttr::get(context, opBundleTagAttrs);
2100 auto opBundleTagsAttrNameAttr =
2101 StringAttr::get(context, LLVMDialect::getOpBundleTagsAttrName());
2102 attrsOut.push_back({opBundleTagsAttrNameAttr, opBundleTagsAttr});
2109 IntegerAttr integerAttr;
2111 bool success = succeeded(converted) &&
2113 assert(
success &&
"expected a constant integer value");
2119 FloatAttr floatAttr;
2123 assert(
success &&
"expected a constant float value");
2130 llvm::DILocalVariable *node =
nullptr;
2131 if (
auto *value = dyn_cast<llvm::Value *>(valOrVariable)) {
2132 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
2133 node = cast<llvm::DILocalVariable>(nodeAsVal->getMetadata());
2135 node = cast<llvm::DILocalVariable *>(valOrVariable);
2137 return debugImporter->translate(node);
2141 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
2142 auto *node = cast<llvm::DILabel>(nodeAsVal->getMetadata());
2143 return debugImporter->translate(node);
2146FPExceptionBehaviorAttr
2148 auto *metadata = cast<llvm::MetadataAsValue>(value);
2149 auto *mdstr = cast<llvm::MDString>(metadata->getMetadata());
2150 std::optional<llvm::fp::ExceptionBehavior> optLLVM =
2151 llvm::convertStrToExceptionBehavior(mdstr->getString());
2152 assert(optLLVM &&
"Expecting FP exception behavior");
2153 return builder.getAttr<FPExceptionBehaviorAttr>(
2154 convertFPExceptionBehaviorFromLLVM(*optLLVM));
2158 auto *metadata = cast<llvm::MetadataAsValue>(value);
2159 auto *mdstr = cast<llvm::MDString>(metadata->getMetadata());
2160 std::optional<llvm::RoundingMode> optLLVM =
2161 llvm::convertStrToRoundingMode(mdstr->getString());
2162 assert(optLLVM &&
"Expecting rounding mode");
2163 return builder.getAttr<RoundingModeAttr>(
2164 convertRoundingModeFromLLVM(*optLLVM));
2167FailureOr<SmallVector<AliasScopeAttr>>
2169 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
2170 auto *node = cast<llvm::MDNode>(nodeAsVal->getMetadata());
2175 return debugImporter->translateLoc(loc);
2179ModuleImport::convertBranchArgs(llvm::Instruction *branch,
2180 llvm::BasicBlock *
target,
2182 for (
auto inst =
target->begin(); isa<llvm::PHINode>(inst); ++inst) {
2183 auto *phiInst = cast<llvm::PHINode>(&*inst);
2184 llvm::Value *value = phiInst->getIncomingValueForBlock(branch->getParent());
2186 if (failed(converted))
2188 blockArguments.push_back(*converted);
2193FailureOr<SmallVector<Value>>
2194ModuleImport::convertCallOperands(llvm::CallBase *callInst,
2195 bool allowInlineAsm) {
2196 bool isInlineAsm = callInst->isInlineAsm();
2197 if (isInlineAsm && !allowInlineAsm)
2207 llvm::Value *calleeOperand = callInst->getCalledOperand();
2208 if (!isa<llvm::Function, llvm::GlobalIFunc>(calleeOperand) && !isInlineAsm) {
2212 operands.push_back(*called);
2215 SmallVector<llvm::Value *> args(callInst->args());
2216 FailureOr<SmallVector<Value>> arguments =
convertValues(args);
2220 llvm::append_range(operands, *arguments);
2228 LLVMFunctionType calleeType) {
2229 if (callType.getReturnType() != calleeType.getReturnType())
2232 if (calleeType.isVarArg()) {
2235 if (callType.getNumParams() < calleeType.getNumParams())
2240 if (callType.getNumParams() != calleeType.getNumParams())
2245 for (
auto [operandType, argumentType] :
2246 llvm::zip(callType.getParams(), calleeType.getParams()))
2247 if (operandType != argumentType)
2253FailureOr<LLVMFunctionType>
2254ModuleImport::convertFunctionType(llvm::CallBase *callInst,
2255 bool &isIncompatibleCall) {
2256 isIncompatibleCall =
false;
2257 auto castOrFailure = [](Type convertedType) -> FailureOr<LLVMFunctionType> {
2258 auto funcTy = dyn_cast_or_null<LLVMFunctionType>(convertedType);
2264 llvm::Value *calledOperand = callInst->getCalledOperand();
2265 FailureOr<LLVMFunctionType> callType =
2266 castOrFailure(
convertType(callInst->getFunctionType()));
2269 auto *callee = dyn_cast<llvm::Function>(calledOperand);
2271 llvm::FunctionType *origCalleeType =
nullptr;
2273 origCalleeType = callee->getFunctionType();
2274 }
else if (
auto *ifunc = dyn_cast<llvm::GlobalIFunc>(calledOperand)) {
2275 origCalleeType = cast<llvm::FunctionType>(ifunc->getValueType());
2279 if (!origCalleeType)
2282 FailureOr<LLVMFunctionType> calleeType =
2290 isIncompatibleCall =
true;
2292 emitWarning(loc) <<
"incompatible call and callee types: " << *callType
2293 <<
" and " << *calleeType;
2300FlatSymbolRefAttr ModuleImport::convertCalleeName(llvm::CallBase *callInst) {
2301 llvm::Value *calledOperand = callInst->getCalledOperand();
2302 if (isa<llvm::Function, llvm::GlobalIFunc>(calledOperand))
2303 return SymbolRefAttr::get(context, calledOperand->getName());
2307LogicalResult ModuleImport::convertIntrinsic(llvm::CallInst *inst) {
2308 if (succeeded(iface.convertIntrinsic(builder, inst, *
this)))
2312 return emitError(loc) <<
"unhandled intrinsic: " <<
diag(*inst);
2316ModuleImport::convertAsmInlineOperandAttrs(
const llvm::CallBase &llvmCall) {
2317 const auto *ia = cast<llvm::InlineAsm>(llvmCall.getCalledOperand());
2318 unsigned argIdx = 0;
2319 SmallVector<mlir::Attribute> opAttrs;
2320 bool hasIndirect =
false;
2322 for (
const llvm::InlineAsm::ConstraintInfo &ci : ia->ParseConstraints()) {
2324 if (ci.Type == llvm::InlineAsm::isLabel || !ci.hasArg())
2329 if (ci.isIndirect) {
2330 if (llvm::Type *paramEltType = llvmCall.getParamElementType(argIdx)) {
2331 SmallVector<mlir::NamedAttribute> attrs;
2332 attrs.push_back(builder.getNamedAttr(
2333 mlir::LLVM::InlineAsmOp::getElementTypeAttrName(),
2335 opAttrs.push_back(builder.getDictionaryAttr(attrs));
2339 opAttrs.push_back(builder.getDictionaryAttr({}));
2345 return hasIndirect ? ArrayAttr::get(mlirModule->getContext(), opAttrs)
2349LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
2352 if (
auto *brInst = dyn_cast<llvm::UncondBrInst>(inst)) {
2353 llvm::BasicBlock *succ = brInst->getSuccessor();
2354 SmallVector<Value> blockArgs;
2355 if (
failed(convertBranchArgs(brInst, succ, blockArgs)))
2358 auto brOp = LLVM::BrOp::create(builder, loc, blockArgs,
lookupBlock(succ));
2362 if (
auto *brInst = dyn_cast<llvm::CondBrInst>(inst)) {
2363 SmallVector<Block *> succBlocks;
2364 SmallVector<SmallVector<Value>> succBlockArgs;
2365 for (
auto i : llvm::seq<unsigned>(0, brInst->getNumSuccessors())) {
2366 llvm::BasicBlock *succ = brInst->getSuccessor(i);
2367 SmallVector<Value> blockArgs;
2368 if (
failed(convertBranchArgs(brInst, succ, blockArgs)))
2371 succBlockArgs.push_back(blockArgs);
2374 FailureOr<Value> condition =
convertValue(brInst->getCondition());
2377 auto condBrOp = LLVM::CondBrOp::create(
2378 builder, loc, *condition, succBlocks.front(), succBlockArgs.front(),
2379 succBlocks.back(), succBlockArgs.back());
2383 if (inst->getOpcode() == llvm::Instruction::Switch) {
2384 auto *swInst = cast<llvm::SwitchInst>(inst);
2386 FailureOr<Value> condition =
convertValue(swInst->getCondition());
2389 SmallVector<Value> defaultBlockArgs;
2391 llvm::BasicBlock *defaultBB = swInst->getDefaultDest();
2392 if (
failed(convertBranchArgs(swInst, defaultBB, defaultBlockArgs)))
2396 unsigned numCases = swInst->getNumCases();
2397 SmallVector<SmallVector<Value>> caseOperands(numCases);
2398 SmallVector<ValueRange> caseOperandRefs(numCases);
2399 SmallVector<APInt> caseValues(numCases);
2400 SmallVector<Block *> caseBlocks(numCases);
2401 for (
const auto &it : llvm::enumerate(swInst->cases())) {
2402 const llvm::SwitchInst::CaseHandle &caseHandle = it.value();
2403 llvm::BasicBlock *succBB = caseHandle.getCaseSuccessor();
2404 if (
failed(convertBranchArgs(swInst, succBB, caseOperands[it.index()])))
2406 caseOperandRefs[it.index()] = caseOperands[it.index()];
2407 caseValues[it.index()] = caseHandle.getCaseValue()->getValue();
2411 auto switchOp = SwitchOp::create(builder, loc, *condition,
2413 caseValues, caseBlocks, caseOperandRefs);
2417 if (inst->getOpcode() == llvm::Instruction::PHI) {
2419 mapValue(inst, builder.getInsertionBlock()->addArgument(
2423 if (inst->getOpcode() == llvm::Instruction::Call) {
2424 auto *callInst = cast<llvm::CallInst>(inst);
2425 llvm::Value *calledOperand = callInst->getCalledOperand();
2427 FailureOr<SmallVector<Value>> operands =
2428 convertCallOperands(callInst,
true);
2432 auto callOp = [&]() -> FailureOr<Operation *> {
2433 if (
auto *asmI = dyn_cast<llvm::InlineAsm>(calledOperand)) {
2437 ArrayAttr operandAttrs = convertAsmInlineOperandAttrs(*callInst);
2438 return InlineAsmOp::create(
2439 builder, loc, resultTy, *operands,
2440 builder.getStringAttr(asmI->getAsmString()),
2441 builder.getStringAttr(asmI->getConstraintString()),
2442 asmI->hasSideEffects(), asmI->isAlignStack(),
2443 convertTailCallKindFromLLVM(callInst->getTailCallKind()),
2444 AsmDialectAttr::get(
2445 mlirModule.getContext(),
2446 convertAsmDialectFromLLVM(asmI->getDialect())),
2450 bool isIncompatibleCall;
2451 FailureOr<LLVMFunctionType> funcTy =
2452 convertFunctionType(callInst, isIncompatibleCall);
2456 FlatSymbolRefAttr callee =
nullptr;
2457 if (isIncompatibleCall) {
2461 FlatSymbolRefAttr calleeSym = convertCalleeName(callInst);
2462 Value indirectCallVal = LLVM::AddressOfOp::create(
2463 builder, loc, LLVM::LLVMPointerType::get(context), calleeSym);
2464 operands->insert(operands->begin(), indirectCallVal);
2467 callee = convertCalleeName(callInst);
2469 CallOp callOp = CallOp::create(builder, loc, *funcTy, callee, *operands);
2471 if (
failed(convertCallAttributes(callInst, callOp)))
2476 if (!isIncompatibleCall)
2478 return callOp.getOperation();
2484 if (!callInst->getType()->isVoidTy())
2485 mapValue(inst, (*callOp)->getResult(0));
2490 if (inst->getOpcode() == llvm::Instruction::LandingPad) {
2491 auto *lpInst = cast<llvm::LandingPadInst>(inst);
2493 SmallVector<Value> operands;
2494 operands.reserve(lpInst->getNumClauses());
2495 for (
auto i : llvm::seq<unsigned>(0, lpInst->getNumClauses())) {
2496 FailureOr<Value> operand =
convertValue(lpInst->getClause(i));
2499 operands.push_back(*operand);
2504 LandingpadOp::create(builder, loc, type, lpInst->isCleanup(), operands);
2508 if (inst->getOpcode() == llvm::Instruction::Invoke) {
2509 auto *invokeInst = cast<llvm::InvokeInst>(inst);
2511 if (invokeInst->isInlineAsm())
2512 return emitError(loc) <<
"invoke of inline assembly is not supported";
2514 FailureOr<SmallVector<Value>> operands = convertCallOperands(invokeInst);
2520 bool invokeResultUsedInPhi = llvm::any_of(
2521 invokeInst->getNormalDest()->phis(), [&](
const llvm::PHINode &phi) {
2522 return phi.getIncomingValueForBlock(invokeInst->getParent()) ==
2527 Block *directNormalDest = normalDest;
2528 if (invokeResultUsedInPhi) {
2533 OpBuilder::InsertionGuard g(builder);
2534 directNormalDest = builder.createBlock(normalDest);
2537 SmallVector<Value> unwindArgs;
2538 if (
failed(convertBranchArgs(invokeInst, invokeInst->getUnwindDest(),
2542 bool isIncompatibleInvoke;
2543 FailureOr<LLVMFunctionType> funcTy =
2544 convertFunctionType(invokeInst, isIncompatibleInvoke);
2548 FlatSymbolRefAttr calleeName =
nullptr;
2549 if (isIncompatibleInvoke) {
2553 FlatSymbolRefAttr calleeSym = convertCalleeName(invokeInst);
2554 Value indirectInvokeVal = LLVM::AddressOfOp::create(
2555 builder, loc, LLVM::LLVMPointerType::get(context), calleeSym);
2556 operands->insert(operands->begin(), indirectInvokeVal);
2559 calleeName = convertCalleeName(invokeInst);
2564 auto invokeOp = InvokeOp::create(
2565 builder, loc, *funcTy, calleeName, *operands, directNormalDest,
2568 if (
failed(convertInvokeAttributes(invokeInst, invokeOp)))
2573 if (!isIncompatibleInvoke)
2576 if (!invokeInst->getType()->isVoidTy())
2577 mapValue(inst, invokeOp.getResults().front());
2581 SmallVector<Value> normalArgs;
2582 if (
failed(convertBranchArgs(invokeInst, invokeInst->getNormalDest(),
2586 if (invokeResultUsedInPhi) {
2590 OpBuilder::InsertionGuard g(builder);
2591 builder.setInsertionPointToStart(directNormalDest);
2592 LLVM::BrOp::create(builder, loc, normalArgs, normalDest);
2596 assert(llvm::none_of(
2598 [&](Value val) {
return val.
getDefiningOp() == invokeOp; }) &&
2599 "An llvm.invoke operation cannot pass its result as a block "
2601 invokeOp.getNormalDestOperandsMutable().append(normalArgs);
2606 if (inst->getOpcode() == llvm::Instruction::GetElementPtr) {
2607 auto *gepInst = cast<llvm::GetElementPtrInst>(inst);
2608 Type sourceElementType =
convertType(gepInst->getSourceElementType());
2609 FailureOr<Value> basePtr =
convertValue(gepInst->getOperand(0));
2618 for (llvm::Value *operand : llvm::drop_begin(gepInst->operand_values())) {
2626 auto gepOp = GEPOp::create(
2627 builder, loc, type, sourceElementType, *basePtr,
indices,
2628 static_cast<GEPNoWrapFlags
>(gepInst->getNoWrapFlags().getRaw()));
2633 if (inst->getOpcode() == llvm::Instruction::IndirectBr) {
2634 auto *indBrInst = cast<llvm::IndirectBrInst>(inst);
2636 FailureOr<Value> basePtr =
convertValue(indBrInst->getAddress());
2640 SmallVector<Block *> succBlocks;
2641 SmallVector<SmallVector<Value>> succBlockArgs;
2642 for (
auto i : llvm::seq<unsigned>(0, indBrInst->getNumSuccessors())) {
2643 llvm::BasicBlock *succ = indBrInst->getSuccessor(i);
2644 SmallVector<Value> blockArgs;
2645 if (
failed(convertBranchArgs(indBrInst, succ, blockArgs)))
2648 succBlockArgs.push_back(blockArgs);
2650 SmallVector<ValueRange> succBlockArgsRange =
2651 llvm::to_vector_of<ValueRange>(succBlockArgs);
2653 auto indBrOp = LLVM::IndirectBrOp::create(builder, loc, *basePtr,
2654 succBlockArgsRange, succBlocks);
2664 return emitError(loc) <<
"unhandled instruction: " <<
diag(*inst);
2667LogicalResult ModuleImport::processInstruction(llvm::Instruction *inst) {
2674 if (
auto *intrinsic = dyn_cast<llvm::IntrinsicInst>(inst))
2675 return convertIntrinsic(intrinsic);
2680 if (inst->DebugMarker) {
2681 for (llvm::DbgRecord &dbgRecord : inst->DebugMarker->getDbgRecordRange()) {
2683 if (
auto *dbgVariableRecord =
2684 dyn_cast<llvm::DbgVariableRecord>(&dbgRecord)) {
2689 auto emitUnsupportedWarning = [&]() -> LogicalResult {
2690 if (!emitExpensiveWarnings)
2693 llvm::raw_string_ostream optionsStream(
options);
2694 dbgRecord.print(optionsStream);
2695 emitWarning(loc) <<
"unhandled debug record " << optionsStream.str();
2699 if (
auto *dbgLabelRecord = dyn_cast<llvm::DbgLabelRecord>(&dbgRecord)) {
2700 DILabelAttr labelAttr =
2701 debugImporter->translate(dbgLabelRecord->getLabel());
2703 return emitUnsupportedWarning();
2704 LLVM::DbgLabelOp::create(builder, loc, labelAttr);
2708 return emitUnsupportedWarning();
2713 return convertInstruction(inst);
2716FlatSymbolRefAttr ModuleImport::getPersonalityAsAttr(llvm::Function *f) {
2717 if (!f->hasPersonalityFn())
2720 llvm::Constant *pf = f->getPersonalityFn();
2724 return SymbolRefAttr::get(builder.getContext(), pf->getName());
2728 if (
auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) {
2729 if (ce->getOpcode() == llvm::Instruction::BitCast &&
2730 ce->getType() == llvm::PointerType::getUnqual(f->getContext())) {
2731 if (
auto *func = dyn_cast<llvm::Function>(ce->getOperand(0)))
2732 return SymbolRefAttr::get(builder.getContext(), func->getName());
2735 return FlatSymbolRefAttr();
2739 llvm::MemoryEffects memEffects =
func->getMemoryEffects();
2741 auto othermem = convertModRefInfoFromLLVM(
2742 memEffects.getModRef(llvm::MemoryEffects::Location::Other));
2743 auto argMem = convertModRefInfoFromLLVM(
2744 memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
2745 auto inaccessibleMem = convertModRefInfoFromLLVM(
2746 memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
2747 auto errnoMem = convertModRefInfoFromLLVM(
2748 memEffects.getModRef(llvm::MemoryEffects::Location::ErrnoMem));
2749 auto targetMem0 = convertModRefInfoFromLLVM(
2750 memEffects.getModRef(llvm::MemoryEffects::Location::TargetMem0));
2751 auto targetMem1 = convertModRefInfoFromLLVM(
2752 memEffects.getModRef(llvm::MemoryEffects::Location::TargetMem1));
2754 MemoryEffectsAttr::get(funcOp.getContext(), othermem, argMem,
2755 inaccessibleMem, errnoMem, targetMem0, targetMem1);
2757 if (memAttr.isReadWrite())
2759 funcOp.setMemoryEffectsAttr(memAttr);
2763 llvm::DenormalFPEnv denormalFpEnv =
func->getDenormalFPEnv();
2765 if (denormalFpEnv == llvm::DenormalFPEnv::getDefault())
2768 llvm::DenormalMode defaultMode = denormalFpEnv.DefaultMode;
2769 llvm::DenormalMode floatMode = denormalFpEnv.F32Mode;
2771 auto denormalFpEnvAttr = DenormalFPEnvAttr::get(
2772 funcOp.getContext(), convertDenormalModeKindFromLLVM(defaultMode.Output),
2773 convertDenormalModeKindFromLLVM(defaultMode.Input),
2774 convertDenormalModeKindFromLLVM(floatMode.Output),
2775 convertDenormalModeKindFromLLVM(floatMode.Input));
2776 funcOp.setDenormalFpenvAttr(denormalFpEnvAttr);
2782 StringLiteral(
"aarch64_in_za"),
2783 StringLiteral(
"aarch64_inout_za"),
2784 StringLiteral(
"aarch64_new_za"),
2785 StringLiteral(
"aarch64_out_za"),
2786 StringLiteral(
"aarch64_preserves_za"),
2787 StringLiteral(
"aarch64_pstate_sm_body"),
2788 StringLiteral(
"aarch64_pstate_sm_compatible"),
2789 StringLiteral(
"aarch64_pstate_sm_enabled"),
2790 StringLiteral(
"allocsize"),
2791 StringLiteral(
"alwaysinline"),
2792 StringLiteral(
"cold"),
2793 StringLiteral(
"convergent"),
2794 StringLiteral(
"fp-contract"),
2795 StringLiteral(
"frame-pointer"),
2796 StringLiteral(
"hot"),
2797 StringLiteral(
"inlinehint"),
2798 StringLiteral(
"instrument-function-entry"),
2799 StringLiteral(
"instrument-function-exit"),
2800 StringLiteral(
"modular-format"),
2801 StringLiteral(
"memory"),
2802 StringLiteral(
"minsize"),
2803 StringLiteral(
"no_caller_saved_registers"),
2804 StringLiteral(
"no-signed-zeros-fp-math"),
2805 StringLiteral(
"no-builtins"),
2806 StringLiteral(
"nocallback"),
2807 StringLiteral(
"noduplicate"),
2808 StringLiteral(
"noinline"),
2809 StringLiteral(
"noreturn"),
2810 StringLiteral(
"nounwind"),
2811 StringLiteral(
"optnone"),
2812 StringLiteral(
"optsize"),
2813 StringLiteral(
"returns_twice"),
2814 StringLiteral(
"save-reg-params"),
2815 StringLiteral(
"target-features"),
2816 StringLiteral(
"trap-func-name"),
2817 StringLiteral(
"tune-cpu"),
2818 StringLiteral(
"uwtable"),
2819 StringLiteral(
"vscale_range"),
2820 StringLiteral(
"willreturn"),
2821 StringLiteral(
"zero-call-used-regs"),
2822 StringLiteral(
"denormal_fpenv"),
2828 StringLiteral(
"no-builtin-"),
2831template <
typename OpTy>
2833 const llvm::AttributeSet &attrs,
2836 if (attrs.hasAttribute(
"no-builtins")) {
2837 target.setNobuiltinsAttr(ArrayAttr::get(ctx, {}));
2842 for (llvm::Attribute attr : attrs) {
2845 if (attr.hasKindAsEnum())
2848 StringRef val = attr.getKindAsString();
2850 if (val.starts_with(
"no-builtin-"))
2852 StringAttr::get(ctx, val.drop_front(
sizeof(
"no-builtin-") - 1)));
2855 if (!nbAttrs.empty())
2856 target.setNobuiltinsAttr(ArrayAttr::get(ctx, nbAttrs.getArrayRef()));
2859template <
typename OpTy>
2861 const llvm::AttributeSet &attrs, OpTy
target) {
2862 llvm::Attribute attr = attrs.getAttribute(llvm::Attribute::AllocSize);
2863 if (!attr.isValid())
2866 auto [elemSize, numElems] = attr.getAllocSizeArgs();
2870 static_cast<int32_t
>(*numElems)}));
2881 llvm::AttributeSet funcAttrs =
func->getAttributes().getAttributes(
2882 llvm::AttributeList::AttrIndex::FunctionIndex);
2884 funcOp.getLoc(), funcOp.getContext(), funcAttrs,
2886 if (!passthroughAttr.empty())
2887 funcOp.setPassthroughAttr(passthroughAttr);
2891 LLVMFuncOp funcOp) {
2896 if (
func->hasFnAttribute(llvm::Attribute::NoInline))
2897 funcOp.setNoInline(
true);
2898 if (
func->hasFnAttribute(llvm::Attribute::AlwaysInline))
2899 funcOp.setAlwaysInline(
true);
2900 if (
func->hasFnAttribute(llvm::Attribute::InlineHint))
2901 funcOp.setInlineHint(
true);
2902 if (
func->hasFnAttribute(llvm::Attribute::OptimizeNone))
2903 funcOp.setOptimizeNone(
true);
2904 if (
func->hasFnAttribute(llvm::Attribute::Convergent))
2905 funcOp.setConvergent(
true);
2906 if (
func->hasFnAttribute(llvm::Attribute::NoUnwind))
2907 funcOp.setNoUnwind(
true);
2908 if (
func->hasFnAttribute(llvm::Attribute::WillReturn))
2909 funcOp.setWillReturn(
true);
2910 if (
func->hasFnAttribute(llvm::Attribute::NoReturn))
2911 funcOp.setNoreturn(
true);
2912 if (
func->hasFnAttribute(llvm::Attribute::OptimizeForSize))
2913 funcOp.setOptsize(
true);
2914 if (
func->hasFnAttribute(
"save-reg-params"))
2915 funcOp.setSaveRegParams(
true);
2916 if (
func->hasFnAttribute(llvm::Attribute::MinSize))
2917 funcOp.setMinsize(
true);
2918 if (
func->hasFnAttribute(llvm::Attribute::ReturnsTwice))
2919 funcOp.setReturnsTwice(
true);
2920 if (
func->hasFnAttribute(llvm::Attribute::Cold))
2921 funcOp.setCold(
true);
2922 if (
func->hasFnAttribute(llvm::Attribute::Hot))
2923 funcOp.setHot(
true);
2924 if (
func->hasFnAttribute(llvm::Attribute::NoDuplicate))
2925 funcOp.setNoduplicate(
true);
2926 if (
func->hasFnAttribute(
"no_caller_saved_registers"))
2927 funcOp.setNoCallerSavedRegisters(
true);
2928 if (
func->hasFnAttribute(llvm::Attribute::NoCallback))
2929 funcOp.setNocallback(
true);
2930 if (llvm::Attribute attr =
func->getFnAttribute(
"modular-format");
2931 attr.isStringAttribute())
2932 funcOp.setModularFormat(StringAttr::get(context, attr.getValueAsString()));
2933 if (llvm::Attribute attr =
func->getFnAttribute(
"zero-call-used-regs");
2934 attr.isStringAttribute())
2935 funcOp.setZeroCallUsedRegsAttr(
2936 StringAttr::get(context, attr.getValueAsString()));
2938 if (
func->hasFnAttribute(
"aarch64_pstate_sm_enabled"))
2939 funcOp.setArmStreaming(
true);
2940 else if (
func->hasFnAttribute(
"aarch64_pstate_sm_body"))
2941 funcOp.setArmLocallyStreaming(
true);
2942 else if (
func->hasFnAttribute(
"aarch64_pstate_sm_compatible"))
2943 funcOp.setArmStreamingCompatible(
true);
2945 if (
func->hasFnAttribute(
"aarch64_new_za"))
2946 funcOp.setArmNewZa(
true);
2947 else if (
func->hasFnAttribute(
"aarch64_in_za"))
2948 funcOp.setArmInZa(
true);
2949 else if (
func->hasFnAttribute(
"aarch64_out_za"))
2950 funcOp.setArmOutZa(
true);
2951 else if (
func->hasFnAttribute(
"aarch64_inout_za"))
2952 funcOp.setArmInoutZa(
true);
2953 else if (
func->hasFnAttribute(
"aarch64_preserves_za"))
2954 funcOp.setArmPreservesZa(
true);
2959 llvm::Attribute attr =
func->getFnAttribute(llvm::Attribute::VScaleRange);
2960 if (attr.isValid()) {
2962 auto intTy = IntegerType::get(context, 32);
2963 funcOp.setVscaleRangeAttr(LLVM::VScaleRangeAttr::get(
2964 context, IntegerAttr::get(intTy, attr.getVScaleRangeMin()),
2965 IntegerAttr::get(intTy, attr.getVScaleRangeMax().value_or(0))));
2969 if (
func->hasFnAttribute(
"frame-pointer")) {
2970 StringRef stringRefFramePointerKind =
2971 func->getFnAttribute(
"frame-pointer").getValueAsString();
2972 funcOp.setFramePointerAttr(LLVM::FramePointerKindAttr::get(
2973 funcOp.getContext(), LLVM::framePointerKind::symbolizeFramePointerKind(
2974 stringRefFramePointerKind)
2978 if (
func->hasFnAttribute(
"use-sample-profile"))
2979 funcOp.setUseSampleProfile(
true);
2981 if (llvm::Attribute attr =
func->getFnAttribute(
"target-cpu");
2982 attr.isStringAttribute())
2983 funcOp.setTargetCpuAttr(StringAttr::get(context, attr.getValueAsString()));
2985 if (llvm::Attribute attr =
func->getFnAttribute(
"tune-cpu");
2986 attr.isStringAttribute())
2987 funcOp.setTuneCpuAttr(StringAttr::get(context, attr.getValueAsString()));
2989 if (llvm::Attribute attr =
func->getFnAttribute(
"target-features");
2990 attr.isStringAttribute())
2991 funcOp.setTargetFeaturesAttr(
2992 LLVM::TargetFeaturesAttr::get(context, attr.getValueAsString()));
2994 if (llvm::Attribute attr =
func->getFnAttribute(
"reciprocal-estimates");
2995 attr.isStringAttribute())
2996 funcOp.setReciprocalEstimatesAttr(
2997 StringAttr::get(context, attr.getValueAsString()));
2999 if (llvm::Attribute attr =
func->getFnAttribute(
"prefer-vector-width");
3000 attr.isStringAttribute())
3001 funcOp.setPreferVectorWidth(attr.getValueAsString());
3003 if (llvm::Attribute attr =
func->getFnAttribute(
"instrument-function-entry");
3004 attr.isStringAttribute())
3005 funcOp.setInstrumentFunctionEntry(
3006 StringAttr::get(context, attr.getValueAsString()));
3008 if (llvm::Attribute attr =
func->getFnAttribute(
"instrument-function-exit");
3009 attr.isStringAttribute())
3010 funcOp.setInstrumentFunctionExit(
3011 StringAttr::get(context, attr.getValueAsString()));
3013 if (llvm::Attribute attr =
func->getFnAttribute(
"no-signed-zeros-fp-math");
3014 attr.isStringAttribute())
3015 funcOp.setNoSignedZerosFpMath(attr.getValueAsBool());
3017 if (llvm::Attribute attr =
func->getFnAttribute(
"fp-contract");
3018 attr.isStringAttribute())
3019 funcOp.setFpContractAttr(StringAttr::get(context, attr.getValueAsString()));
3021 if (
func->hasUWTable()) {
3022 ::llvm::UWTableKind uwtableKind =
func->getUWTableKind();
3023 funcOp.setUwtableKindAttr(LLVM::UWTableKindAttr::get(
3024 funcOp.getContext(), convertUWTableKindFromLLVM(uwtableKind)));
3029ModuleImport::convertArgOrResultAttrSet(llvm::AttributeSet llvmAttrSet) {
3032 auto llvmAttr = llvmAttrSet.getAttribute(llvmKind);
3034 if (!llvmAttr.isValid())
3039 if (llvmAttr.hasKindAsEnum() &&
3040 llvmAttr.getKindAsEnum() == llvm::Attribute::Captures) {
3041 if (llvm::capturesNothing(llvmAttr.getCaptureInfo()))
3042 paramAttrs.push_back(
3048 if (llvmAttr.isTypeAttribute())
3049 mlirAttr = TypeAttr::get(
convertType(llvmAttr.getValueAsType()));
3050 else if (llvmAttr.isIntAttribute())
3052 else if (llvmAttr.isEnumAttribute())
3054 else if (llvmAttr.isConstantRangeAttribute()) {
3055 const llvm::ConstantRange &value = llvmAttr.getValueAsConstantRange();
3056 mlirAttr = builder.
getAttr<LLVM::ConstantRangeAttr>(value.getLower(),
3059 llvm_unreachable(
"unexpected parameter attribute kind");
3061 paramAttrs.push_back(builder.getNamedAttr(mlirName, mlirAttr));
3064 return builder.getDictionaryAttr(paramAttrs);
3068 LLVMFuncOp funcOp) {
3069 auto llvmAttrs = func->getAttributes();
3070 for (
size_t i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
3071 llvm::AttributeSet llvmArgAttrs = llvmAttrs.getParamAttrs(i);
3072 funcOp.setArgAttrs(i, convertArgOrResultAttrSet(llvmArgAttrs));
3076 llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
3077 if (!llvmResAttr.hasAttributes())
3079 funcOp.setResAttrsAttr(
3080 builder.getArrayAttr({convertArgOrResultAttrSet(llvmResAttr)}));
3084 llvm::CallBase *call, ArgAndResultAttrsOpInterface attrsOp,
3087 llvm::SmallDenseSet<unsigned> immArgPositionsSet(immArgPositions.begin(),
3088 immArgPositions.end());
3090 llvm::AttributeList llvmAttrs = call->getAttributes();
3092 bool anyArgAttrs =
false;
3093 for (
size_t i = 0, e = call->arg_size(); i < e; ++i) {
3095 if (immArgPositionsSet.contains(i))
3097 llvmArgAttrsSet.emplace_back(llvmAttrs.getParamAttrs(i));
3098 if (llvmArgAttrsSet.back().hasAttributes())
3103 for (
auto &dict : dictAttrs)
3104 attrs.push_back(dict ? dict : builder.getDictionaryAttr({}));
3105 return builder.getArrayAttr(attrs);
3109 for (
auto &llvmArgAttrs : llvmArgAttrsSet)
3110 argAttrs.emplace_back(convertArgOrResultAttrSet(llvmArgAttrs));
3111 attrsOp.setArgAttrsAttr(getArrayAttr(argAttrs));
3115 llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
3116 if (!llvmResAttr.hasAttributes())
3118 DictionaryAttr resAttrs = convertArgOrResultAttrSet(llvmResAttr);
3119 attrsOp.setResAttrsAttr(getArrayAttr({resAttrs}));
3122template <
typename Op>
3124 op.setCConv(convertCConvFromLLVM(inst->getCallingConv()));
3128LogicalResult ModuleImport::convertInvokeAttributes(llvm::InvokeInst *inst,
3133LogicalResult ModuleImport::convertCallAttributes(llvm::CallInst *inst,
3139 llvm::AttributeList callAttrs = inst->getAttributes();
3141 op.setTailCallKind(convertTailCallKindFromLLVM(inst->getTailCallKind()));
3142 op.setConvergent(callAttrs.getFnAttr(llvm::Attribute::Convergent).isValid());
3143 op.setNoUnwind(callAttrs.getFnAttr(llvm::Attribute::NoUnwind).isValid());
3144 op.setWillReturn(callAttrs.getFnAttr(llvm::Attribute::WillReturn).isValid());
3145 op.setNoreturn(callAttrs.getFnAttr(llvm::Attribute::NoReturn).isValid());
3147 callAttrs.getFnAttr(llvm::Attribute::OptimizeForSize).isValid());
3148 op.setSaveRegParams(callAttrs.getFnAttr(
"save-reg-params").isValid());
3149 op.setBuiltin(callAttrs.getFnAttr(llvm::Attribute::Builtin).isValid());
3150 op.setNobuiltin(callAttrs.getFnAttr(llvm::Attribute::NoBuiltin).isValid());
3151 op.setMinsize(callAttrs.getFnAttr(llvm::Attribute::MinSize).isValid());
3154 callAttrs.getFnAttr(llvm::Attribute::ReturnsTwice).isValid());
3155 op.setHot(callAttrs.getFnAttr(llvm::Attribute::Hot).isValid());
3156 op.setCold(callAttrs.getFnAttr(llvm::Attribute::Cold).isValid());
3158 callAttrs.getFnAttr(llvm::Attribute::NoDuplicate).isValid());
3159 op.setNoCallerSavedRegisters(
3160 callAttrs.getFnAttr(
"no_caller_saved_registers").isValid());
3161 op.setNocallback(callAttrs.getFnAttr(llvm::Attribute::NoCallback).isValid());
3163 if (llvm::Attribute attr = callAttrs.getFnAttr(
"modular-format");
3164 attr.isStringAttribute())
3165 op.setModularFormat(StringAttr::get(context, attr.getValueAsString()));
3166 if (llvm::Attribute attr = callAttrs.getFnAttr(
"zero-call-used-regs");
3167 attr.isStringAttribute())
3168 op.setZeroCallUsedRegsAttr(
3169 StringAttr::get(context, attr.getValueAsString()));
3170 if (llvm::Attribute attr = callAttrs.getFnAttr(
"trap-func-name");
3171 attr.isStringAttribute())
3172 op.setTrapFuncNameAttr(StringAttr::get(context, attr.getValueAsString()));
3173 op.setNoInline(callAttrs.getFnAttr(llvm::Attribute::NoInline).isValid());
3175 callAttrs.getFnAttr(llvm::Attribute::AlwaysInline).isValid());
3176 op.setInlineHint(callAttrs.getFnAttr(llvm::Attribute::InlineHint).isValid());
3178 llvm::MemoryEffects memEffects = inst->getMemoryEffects();
3179 ModRefInfo othermem = convertModRefInfoFromLLVM(
3180 memEffects.getModRef(llvm::MemoryEffects::Location::Other));
3181 ModRefInfo argMem = convertModRefInfoFromLLVM(
3182 memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
3183 ModRefInfo inaccessibleMem = convertModRefInfoFromLLVM(
3184 memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
3185 ModRefInfo errnoMem = convertModRefInfoFromLLVM(
3186 memEffects.getModRef(llvm::MemoryEffects::Location::ErrnoMem));
3187 ModRefInfo targetMem0 = convertModRefInfoFromLLVM(
3188 memEffects.getModRef(llvm::MemoryEffects::Location::TargetMem0));
3189 ModRefInfo targetMem1 = convertModRefInfoFromLLVM(
3190 memEffects.getModRef(llvm::MemoryEffects::Location::TargetMem1));
3192 MemoryEffectsAttr::get(op.getContext(), othermem, argMem, inaccessibleMem,
3193 errnoMem, targetMem0, targetMem1);
3195 if (!memAttr.isReadWrite())
3196 op.setMemoryEffectsAttr(memAttr);
3209 if (
func->isIntrinsic() &&
3210 iface.isConvertibleIntrinsic(
func->getIntrinsicID()))
3213 bool dsoLocal =
func->isDSOLocal();
3214 CConv cconv = convertCConvFromLLVM(
func->getCallingConv());
3218 builder.setInsertionPointToEnd(mlirModule.getBody());
3220 Location loc = debugImporter->translateFuncLocation(
func);
3221 LLVMFuncOp funcOp = LLVMFuncOp::create(
3222 builder, loc,
func->getName(), functionType,
3223 convertLinkageFromLLVM(
func->getLinkage()), dsoLocal, cconv);
3228 funcOp.setPersonalityAttr(personality);
3229 else if (
func->hasPersonalityFn())
3230 emitWarning(funcOp.getLoc(),
"could not deduce personality, skipping it");
3233 funcOp.setGarbageCollector(StringRef(
func->getGC()));
3235 if (
func->hasAtLeastLocalUnnamedAddr())
3236 funcOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(
func->getUnnamedAddr()));
3238 if (
func->hasSection())
3239 funcOp.setSection(StringRef(
func->getSection()));
3241 funcOp.setVisibility_(convertVisibilityFromLLVM(
func->getVisibility()));
3243 if (
func->hasComdat())
3244 funcOp.setComdatAttr(comdatMapping.lookup(
func->getComdat()));
3246 if (llvm::MaybeAlign maybeAlign =
func->getAlign())
3247 funcOp.setAlignment(maybeAlign->value());
3254 func->getAllMetadata(allMetadata);
3255 for (
auto &[kind, node] : allMetadata) {
3256 if (!iface.isConvertibleMetadata(kind))
3258 if (failed(iface.setMetadataAttrs(builder, kind, node, funcOp, *
this))) {
3260 <<
"unhandled function metadata: " <<
diagMD(node, llvmModule.get())
3265 if (
func->isDeclaration())
3274 llvm::df_iterator_default_set<llvm::BasicBlock *> reachable;
3275 for (llvm::BasicBlock *basicBlock : llvm::depth_first_ext(
func, reachable))
3280 for (llvm::BasicBlock &basicBlock : *
func) {
3282 if (!reachable.contains(&basicBlock)) {
3283 if (basicBlock.hasAddressTaken())
3285 <<
"unreachable block '" << basicBlock.getName()
3286 <<
"' with address taken";
3289 Region &body = funcOp.getBody();
3290 Block *block = builder.createBlock(&body, body.
end());
3292 reachableBasicBlocks.push_back(&basicBlock);
3296 for (
const auto &it : llvm::enumerate(
func->args())) {
3297 BlockArgument blockArg = funcOp.getFunctionBody().addArgument(
3298 functionType.getParamType(it.index()), funcOp.getLoc());
3307 setConstantInsertionPointToStart(
lookupBlock(blocks.front()));
3308 for (llvm::BasicBlock *basicBlock : blocks)
3309 if (failed(processBasicBlock(basicBlock,
lookupBlock(basicBlock))))
3314 if (failed(processDebugIntrinsics()))
3319 if (failed(processDebugRecords()))
3328 if (!dbgIntr->isKillLocation())
3330 llvm::Value *value = dbgIntr->getArgOperand(0);
3331 auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
3334 return !isa<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
3346 auto dominatedBlocks = domInfo.
getNode(op->getBlock())->children();
3349 if (dominatedBlocks.empty())
3353 Block *dominatedBlock = (*dominatedBlocks.begin())->getBlock();
3356 Value insertPt = argOperand;
3357 if (
auto blockArg = dyn_cast<BlockArgument>(argOperand)) {
3363 if (!insertionBlock->
empty() &&
3364 isa<LandingpadOp>(insertionBlock->
front()))
3365 insertPt = cast<LandingpadOp>(insertionBlock->
front()).getRes();
3373std::tuple<DILocalVariableAttr, DIExpressionAttr, Value>
3374ModuleImport::processDebugOpArgumentsAndInsertionPt(
3376 llvm::function_ref<FailureOr<Value>()> convertArgOperandToValue,
3377 llvm::Value *address,
3378 llvm::PointerUnion<llvm::Value *, llvm::DILocalVariable *> variable,
3379 llvm::DIExpression *expression, DominanceInfo &domInfo) {
3385 FailureOr<Value> argOperand = convertArgOperandToValue();
3386 if (
failed(argOperand)) {
3387 emitError(loc) <<
"failed to convert a debug operand: " <<
diag(*address);
3395 return {localVarAttr, debugImporter->translateExpression(expression),
3400ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
3401 DominanceInfo &domInfo) {
3403 auto emitUnsupportedWarning = [&]() {
3404 if (emitExpensiveWarnings)
3409 OpBuilder::InsertionGuard guard(builder);
3410 auto convertArgOperandToValue = [&]() {
3416 if (dbgIntr->hasArgList())
3417 return emitUnsupportedWarning();
3424 return emitUnsupportedWarning();
3426 auto [localVariableAttr, locationExprAttr, locVal] =
3427 processDebugOpArgumentsAndInsertionPt(
3428 loc, convertArgOperandToValue, dbgIntr->getArgOperand(0),
3429 dbgIntr->getArgOperand(1), dbgIntr->getExpression(), domInfo);
3431 if (!localVariableAttr)
3432 return emitUnsupportedWarning();
3437 Operation *op =
nullptr;
3438 if (isa<llvm::DbgDeclareInst>(dbgIntr))
3439 op = LLVM::DbgDeclareOp::create(builder, loc, locVal, localVariableAttr,
3441 else if (isa<llvm::DbgValueInst>(dbgIntr))
3442 op = LLVM::DbgValueOp::create(builder, loc, locVal, localVariableAttr,
3445 return emitUnsupportedWarning();
3448 setNonDebugMetadataAttrs(dbgIntr, op);
3453ModuleImport::processDebugRecord(llvm::DbgVariableRecord &dbgRecord,
3454 DominanceInfo &domInfo) {
3455 OpBuilder::InsertionGuard guard(builder);
3457 auto emitUnsupportedWarning = [&]() -> LogicalResult {
3458 if (!emitExpensiveWarnings)
3461 llvm::raw_string_ostream optionsStream(
options);
3462 dbgRecord.print(optionsStream);
3463 emitWarning(loc) <<
"unhandled debug variable record "
3464 << optionsStream.str();
3470 if (dbgRecord.hasArgList())
3471 return emitUnsupportedWarning();
3476 if (!dbgRecord.getAddress())
3477 return emitUnsupportedWarning();
3479 auto convertArgOperandToValue = [&]() -> FailureOr<Value> {
3480 llvm::Value *value = dbgRecord.getAddress();
3483 auto it = valueMapping.find(value);
3484 if (it != valueMapping.end())
3485 return it->getSecond();
3488 if (
auto *constant = dyn_cast<llvm::Constant>(value))
3489 return convertConstantExpr(constant);
3493 auto [localVariableAttr, locationExprAttr, locVal] =
3494 processDebugOpArgumentsAndInsertionPt(
3495 loc, convertArgOperandToValue, dbgRecord.getAddress(),
3496 dbgRecord.getVariable(), dbgRecord.getExpression(), domInfo);
3498 if (!localVariableAttr)
3499 return emitUnsupportedWarning();
3504 if (dbgRecord.isDbgDeclare())
3505 LLVM::DbgDeclareOp::create(builder, loc, locVal, localVariableAttr,
3507 else if (dbgRecord.isDbgValue())
3508 LLVM::DbgValueOp::create(builder, loc, locVal, localVariableAttr,
3511 return emitUnsupportedWarning();
3516LogicalResult ModuleImport::processDebugIntrinsics() {
3517 DominanceInfo domInfo;
3518 for (llvm::Instruction *inst : debugIntrinsics) {
3519 auto *intrCall = cast<llvm::DbgVariableIntrinsic>(inst);
3520 if (
failed(processDebugIntrinsic(intrCall, domInfo)))
3526LogicalResult ModuleImport::processDebugRecords() {
3527 DominanceInfo domInfo;
3528 for (llvm::DbgVariableRecord *dbgRecord : dbgRecords)
3529 if (
failed(processDebugRecord(*dbgRecord, domInfo)))
3535LogicalResult ModuleImport::processBasicBlock(llvm::BasicBlock *bb,
3537 builder.setInsertionPointToStart(block);
3538 for (llvm::Instruction &inst : *bb) {
3539 if (
failed(processInstruction(&inst)))
3544 if (debugIntrinsics.contains(&inst))
3551 setNonDebugMetadataAttrs(&inst, op);
3552 }
else if (inst.getOpcode() != llvm::Instruction::PHI) {
3553 if (emitExpensiveWarnings) {
3554 Location loc = debugImporter->translateLoc(inst.getDebugLoc());
3560 if (bb->hasAddressTaken()) {
3561 OpBuilder::InsertionGuard guard(builder);
3562 builder.setInsertionPointToStart(block);
3564 BlockTagAttr::get(context, bb->getNumber()));
3569FailureOr<SmallVector<AccessGroupAttr>>
3571 return loopAnnotationImporter->lookupAccessGroupAttrs(node);
3577 return loopAnnotationImporter->translateLoopAnnotation(node, loc);
3580FailureOr<DereferenceableAttr>
3583 Location loc = mlirModule.getLoc();
3587 if (node->getNumOperands() != 1)
3588 return emitError(loc) <<
"dereferenceable metadata must have one operand: "
3589 <<
diagMD(node, llvmModule.get());
3591 auto *numBytesMD = dyn_cast<llvm::ConstantAsMetadata>(node->getOperand(0));
3592 auto *numBytesCst = dyn_cast<llvm::ConstantInt>(numBytesMD->getValue());
3593 if (!numBytesCst || !numBytesCst->getValue().isNonNegative())
3594 return emitError(loc) <<
"dereferenceable metadata operand must be a "
3595 "non-negative constant integer: "
3596 <<
diagMD(node, llvmModule.get());
3598 bool mayBeNull = kindID == llvm::LLVMContext::MD_dereferenceable_or_null;
3599 auto derefAttr = builder.getAttr<DereferenceableAttr>(
3600 numBytesCst->getZExtValue(), mayBeNull);
3606 std::unique_ptr<llvm::Module> llvmModule,
MLIRContext *context,
3607 bool emitExpensiveWarnings,
bool dropDICompositeTypeElements,
3608 bool loadAllDialects,
bool preferUnregisteredIntrinsics,
3609 bool importStructsAsLiterals) {
3616 LLVMDialect::getDialectNamespace()));
3618 DLTIDialect::getDialectNamespace()));
3619 if (loadAllDialects)
3622 StringAttr::get(context, llvmModule->getSourceFileName()), 0,
3626 emitExpensiveWarnings, dropDICompositeTypeElements,
3627 preferUnregisteredIntrinsics,
3628 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.