30 #include "llvm/ADT/DepthFirstIterator.h"
31 #include "llvm/ADT/PostOrderIterator.h"
32 #include "llvm/ADT/ScopeExit.h"
33 #include "llvm/ADT/StringSet.h"
34 #include "llvm/ADT/TypeSwitch.h"
35 #include "llvm/IR/Comdat.h"
36 #include "llvm/IR/Constants.h"
37 #include "llvm/IR/InlineAsm.h"
38 #include "llvm/IR/InstIterator.h"
39 #include "llvm/IR/Instructions.h"
40 #include "llvm/IR/IntrinsicInst.h"
41 #include "llvm/IR/Metadata.h"
42 #include "llvm/IR/Operator.h"
43 #include "llvm/Support/ModRef.h"
49 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
54 static std::string
diag(
const llvm::Value &value) {
56 llvm::raw_string_ostream os(str);
64 static std::string
diagMD(
const llvm::Metadata *node,
65 const llvm::Module *module) {
67 llvm::raw_string_ostream os(str);
68 node->print(os, module,
true);
74 return "llvm.global_ctors";
79 return "mlir.llvm.nameless_global";
84 return "llvm.global_dtors";
90 return "__llvm_global_comdat";
99 std::optional<llvm::SyncScope::ID> syncScopeID =
100 llvm::getAtomicSyncScopeID(inst);
107 llvm::LLVMContext &llvmContext = inst->getContext();
108 llvmContext.getSyncScopeNames(syncScopeName);
109 auto *it = llvm::find_if(syncScopeName, [&](StringRef name) {
110 return *syncScopeID == llvmContext.getOrInsertSyncScopeID(name);
112 if (it != syncScopeName.end())
114 llvm_unreachable(
"incorrect sync scope identifier");
120 llvm::append_range(position, indices);
131 llvm::Instruction *inst,
144 #include "mlir/Dialect/LLVMIR/LLVMOpFromLLVMIRConversions.inc"
152 for (llvm::BasicBlock *basicBlock : basicBlocks) {
153 if (!blocks.contains(basicBlock)) {
154 llvm::ReversePostOrderTraversal<llvm::BasicBlock *> traversal(basicBlock);
155 blocks.insert(traversal.begin(), traversal.end());
158 assert(blocks.size() == basicBlocks.size() &&
"some blocks are not sorted");
163 std::unique_ptr<llvm::Module> llvmModule,
164 bool emitExpensiveWarnings,
165 bool importEmptyDICompositeTypes)
167 mlirModule(mlirModule), llvmModule(std::move(llvmModule)),
171 mlirModule, importEmptyDICompositeTypes)),
172 loopAnnotationImporter(
174 emitExpensiveWarnings(emitExpensiveWarnings) {
178 ComdatOp ModuleImport::getGlobalComdatOp() {
180 return globalComdatOp;
186 globalInsertionOp = globalComdatOp;
187 return globalComdatOp;
190 LogicalResult ModuleImport::processTBAAMetadata(
const llvm::MDNode *node) {
195 auto getIdentityIfRootNode =
196 [&](
const llvm::MDNode *node) -> FailureOr<std::optional<StringRef>> {
200 if (node->getNumOperands() > 1)
203 if (node->getNumOperands() == 1)
204 if (
const auto *op0 = dyn_cast<const llvm::MDString>(node->getOperand(0)))
205 return std::optional<StringRef>{op0->getString()};
206 return std::optional<StringRef>{};
216 auto isTypeDescriptorNode = [&](
const llvm::MDNode *node,
217 StringRef *identity =
nullptr,
219 nullptr) -> std::optional<bool> {
220 unsigned numOperands = node->getNumOperands();
229 const auto *identityNode =
230 dyn_cast<const llvm::MDString>(node->getOperand(0));
236 *identity = identityNode->getString();
238 for (
unsigned pairNum = 0, e = numOperands / 2; pairNum < e; ++pairNum) {
239 const auto *memberNode =
240 dyn_cast<const llvm::MDNode>(node->getOperand(2 * pairNum + 1));
242 emitError(loc) <<
"operand '" << 2 * pairNum + 1 <<
"' must be MDNode: "
243 <<
diagMD(node, llvmModule.get());
247 if (2 * pairNum + 2 >= numOperands) {
249 if (numOperands != 2) {
250 emitError(loc) <<
"missing member offset: "
251 <<
diagMD(node, llvmModule.get());
255 auto *offsetCI = llvm::mdconst::dyn_extract<llvm::ConstantInt>(
256 node->getOperand(2 * pairNum + 2));
258 emitError(loc) <<
"operand '" << 2 * pairNum + 2
259 <<
"' must be ConstantInt: "
260 <<
diagMD(node, llvmModule.get());
263 offset = offsetCI->getZExtValue();
268 cast<TBAANodeAttr>(tbaaMapping.lookup(memberNode)), offset));
281 auto isTagNode = [&](
const llvm::MDNode *node,
282 TBAATypeDescriptorAttr *baseAttr =
nullptr,
283 TBAATypeDescriptorAttr *accessAttr =
nullptr,
284 int64_t *offset =
nullptr,
285 bool *isConstant =
nullptr) -> std::optional<bool> {
293 unsigned numOperands = node->getNumOperands();
294 if (numOperands != 3 && numOperands != 4)
296 const auto *baseMD = dyn_cast<const llvm::MDNode>(node->getOperand(0));
297 const auto *accessMD = dyn_cast<const llvm::MDNode>(node->getOperand(1));
299 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(2));
300 if (!baseMD || !accessMD || !offsetCI)
307 if (accessMD->getNumOperands() < 1 ||
308 !isa<llvm::MDString>(accessMD->getOperand(0)))
310 bool isConst =
false;
311 if (numOperands == 4) {
313 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(3));
315 emitError(loc) <<
"operand '3' must be ConstantInt: "
316 <<
diagMD(node, llvmModule.get());
319 isConst = isConstantCI->getValue()[0];
322 *baseAttr = cast<TBAATypeDescriptorAttr>(tbaaMapping.lookup(baseMD));
324 *accessAttr = cast<TBAATypeDescriptorAttr>(tbaaMapping.lookup(accessMD));
326 *offset = offsetCI->getZExtValue();
328 *isConstant = isConst;
337 workList.push_back(node);
338 while (!workList.empty()) {
339 const llvm::MDNode *current = workList.back();
340 if (tbaaMapping.contains(current)) {
349 bool anyChildNotConverted =
false;
350 for (
const llvm::MDOperand &operand : current->operands())
351 if (
auto *childNode = dyn_cast_or_null<const llvm::MDNode>(operand.get()))
352 if (!tbaaMapping.contains(childNode)) {
353 workList.push_back(childNode);
354 anyChildNotConverted =
true;
357 if (anyChildNotConverted) {
362 if (!seen.insert(current).second)
363 return emitError(loc) <<
"has cycle in TBAA graph: "
364 <<
diagMD(current, llvmModule.get());
372 FailureOr<std::optional<StringRef>> rootNodeIdentity =
373 getIdentityIfRootNode(current);
374 if (succeeded(rootNodeIdentity)) {
375 StringAttr stringAttr = *rootNodeIdentity
380 tbaaMapping.insert({current, builder.
getAttr<TBAARootAttr>(stringAttr)});
386 if (std::optional<bool> isValid =
387 isTypeDescriptorNode(current, &identity, &members)) {
388 assert(isValid.value() &&
"type descriptor node must be valid");
390 tbaaMapping.insert({current, builder.
getAttr<TBAATypeDescriptorAttr>(
391 identity, members)});
395 TBAATypeDescriptorAttr baseAttr, accessAttr;
398 if (std::optional<bool> isValid =
399 isTagNode(current, &baseAttr, &accessAttr, &offset, &isConstant)) {
400 assert(isValid.value() &&
"access tag node must be valid");
402 {current, builder.
getAttr<TBAATagAttr>(baseAttr, accessAttr, offset,
407 return emitError(loc) <<
"unsupported TBAA node format: "
408 <<
diagMD(current, llvmModule.get());
414 ModuleImport::processAccessGroupMetadata(
const llvm::MDNode *node) {
416 if (failed(loopAnnotationImporter->translateAccessGroup(node, loc)))
417 return emitError(loc) <<
"unsupported access group node: "
418 <<
diagMD(node, llvmModule.get());
423 ModuleImport::processAliasScopeMetadata(
const llvm::MDNode *node) {
426 auto verifySelfRef = [](
const llvm::MDNode *node) {
427 return node->getNumOperands() != 0 &&
428 node == dyn_cast<llvm::MDNode>(node->getOperand(0));
430 auto verifySelfRefOrString = [](
const llvm::MDNode *node) {
431 return node->getNumOperands() != 0 &&
432 (node == dyn_cast<llvm::MDNode>(node->getOperand(0)) ||
433 isa<llvm::MDString>(node->getOperand(0)));
436 auto verifyDescription = [](
const llvm::MDNode *node,
unsigned idx) {
437 return idx >= node->getNumOperands() ||
438 isa<llvm::MDString>(node->getOperand(idx));
441 auto getIdAttr = [&](
const llvm::MDNode *node) ->
Attribute {
442 if (verifySelfRef(node))
445 auto name = cast<llvm::MDString>(node->getOperand(0));
450 auto createAliasScopeDomainOp = [&](
const llvm::MDNode *aliasDomain) {
451 StringAttr description =
nullptr;
452 if (aliasDomain->getNumOperands() >= 2)
453 if (
auto *operand = dyn_cast<llvm::MDString>(aliasDomain->getOperand(1)))
455 Attribute idAttr = getIdAttr(aliasDomain);
456 return builder.
getAttr<AliasScopeDomainAttr>(idAttr, description);
460 for (
const llvm::MDOperand &operand : node->operands()) {
461 if (
const auto *scope = dyn_cast<llvm::MDNode>(operand)) {
462 llvm::AliasScopeNode aliasScope(scope);
463 const llvm::MDNode *domain = aliasScope.getDomain();
469 if (!verifySelfRefOrString(scope) || !domain ||
470 !verifyDescription(scope, 2))
471 return emitError(loc) <<
"unsupported alias scope node: "
472 <<
diagMD(scope, llvmModule.get());
473 if (!verifySelfRefOrString(domain) || !verifyDescription(domain, 1))
474 return emitError(loc) <<
"unsupported alias domain node: "
475 <<
diagMD(domain, llvmModule.get());
477 if (aliasScopeMapping.contains(scope))
481 auto it = aliasScopeMapping.find(aliasScope.getDomain());
482 if (it == aliasScopeMapping.end()) {
483 auto aliasScopeDomainOp = createAliasScopeDomainOp(domain);
484 it = aliasScopeMapping.try_emplace(domain, aliasScopeDomainOp).first;
488 StringAttr description =
nullptr;
489 if (!aliasScope.getName().empty())
492 auto aliasScopeOp = builder.
getAttr<AliasScopeAttr>(
493 idAttr, cast<AliasScopeDomainAttr>(it->second), description);
495 aliasScopeMapping.try_emplace(aliasScope.getNode(), aliasScopeOp);
501 FailureOr<SmallVector<AliasScopeAttr>>
504 aliasScopes.reserve(node->getNumOperands());
505 for (
const llvm::MDOperand &operand : node->operands()) {
506 auto *node = cast<llvm::MDNode>(operand.get());
507 aliasScopes.push_back(
508 dyn_cast_or_null<AliasScopeAttr>(aliasScopeMapping.lookup(node)));
511 if (llvm::is_contained(aliasScopes,
nullptr))
517 debugIntrinsics.insert(intrinsic);
521 for (
const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
522 if (named.getName() !=
"llvm.linker.options")
525 for (
const llvm::MDNode *node : named.operands()) {
527 options.reserve(node->getNumOperands());
528 for (
const llvm::MDOperand &option : node->operands())
529 options.push_back(cast<llvm::MDString>(option)->getString());
530 builder.
create<LLVM::LinkerOptionsOp>(mlirModule.getLoc(),
538 for (
const llvm::NamedMDNode &named : llvmModule->named_metadata()) {
541 if (named.getName() != LLVMDialect::getIdentAttrName())
544 if (named.getNumOperands() == 1)
545 if (
auto *md = dyn_cast<llvm::MDNode>(named.getOperand(0)))
546 if (md->getNumOperands() == 1)
547 if (
auto *mdStr = dyn_cast<llvm::MDString>(md->getOperand(0)))
548 mlirModule->setAttr(LLVMDialect::getIdentAttrName(),
555 for (
const llvm::NamedMDNode &nmd : llvmModule->named_metadata()) {
558 if (nmd.getName() != LLVMDialect::getCommandlineAttrName())
561 if (nmd.getNumOperands() == 1)
562 if (
auto *md = dyn_cast<llvm::MDNode>(nmd.getOperand(0)))
563 if (md->getNumOperands() == 1)
564 if (
auto *mdStr = dyn_cast<llvm::MDString>(md->getOperand(0)))
565 mlirModule->setAttr(LLVMDialect::getCommandlineAttrName(),
574 for (
const llvm::Function &func : llvmModule->functions()) {
575 for (
const llvm::Instruction &inst : llvm::instructions(func)) {
577 if (llvm::MDNode *node =
578 inst.getMetadata(llvm::LLVMContext::MD_access_group))
579 if (failed(processAccessGroupMetadata(node)))
583 llvm::AAMDNodes aliasAnalysisNodes = inst.getAAMetadata();
584 if (!aliasAnalysisNodes)
586 if (aliasAnalysisNodes.TBAA)
587 if (failed(processTBAAMetadata(aliasAnalysisNodes.TBAA)))
589 if (aliasAnalysisNodes.Scope)
590 if (failed(processAliasScopeMetadata(aliasAnalysisNodes.Scope)))
592 if (aliasAnalysisNodes.NoAlias)
593 if (failed(processAliasScopeMetadata(aliasAnalysisNodes.NoAlias)))
606 void ModuleImport::processComdat(
const llvm::Comdat *comdat) {
607 if (comdatMapping.contains(comdat))
610 ComdatOp comdatOp = getGlobalComdatOp();
613 auto selectorOp = builder.
create<ComdatSelectorOp>(
614 mlirModule.getLoc(), comdat->getName(),
615 convertComdatFromLLVM(comdat->getSelectionKind()));
619 comdatMapping.try_emplace(comdat, symbolRef);
623 for (llvm::GlobalVariable &globalVar : llvmModule->globals())
624 if (globalVar.hasComdat())
625 processComdat(globalVar.getComdat());
626 for (llvm::Function &func : llvmModule->functions())
627 if (func.hasComdat())
628 processComdat(func.getComdat());
633 for (llvm::GlobalVariable &globalVar : llvmModule->globals()) {
636 if (failed(convertGlobalCtorsAndDtors(&globalVar))) {
638 <<
"unhandled global variable: " <<
diag(globalVar);
642 if (failed(convertGlobal(&globalVar))) {
644 <<
"unhandled global variable: " <<
diag(globalVar);
651 for (llvm::GlobalAlias &alias : llvmModule->aliases()) {
652 if (failed(convertAlias(&alias))) {
654 <<
"unhandled global alias: " <<
diag(alias);
664 return emitError(loc,
"cannot translate data layout: ")
668 emitWarning(loc,
"unhandled data layout token: ") << token;
670 mlirModule->setAttr(DLTIDialect::kDataLayoutAttrName,
676 mlirModule->setAttr(LLVM::LLVMDialect::getTargetTripleAttrName(),
681 for (llvm::Function &func : llvmModule->functions())
687 void ModuleImport::setNonDebugMetadataAttrs(llvm::Instruction *inst,
690 inst->getAllMetadataOtherThanDebugLoc(allMetadata);
691 for (
auto &[kind, node] : allMetadata) {
695 if (emitExpensiveWarnings) {
696 Location loc = debugImporter->translateLoc(inst->getDebugLoc());
698 <<
diagMD(node, llvmModule.get()) <<
" on "
707 auto iface = cast<IntegerOverflowFlagsInterface>(op);
709 IntegerOverflowFlags value = {};
710 value = bitEnumSet(value, IntegerOverflowFlags::nsw, inst->hasNoSignedWrap());
712 bitEnumSet(value, IntegerOverflowFlags::nuw, inst->hasNoUnsignedWrap());
714 iface.setOverflowFlags(value);
718 auto iface = cast<ExactFlagInterface>(op);
720 iface.setIsExact(inst->isExact());
725 auto iface = cast<DisjointFlagInterface>(op);
726 auto instDisjoint = cast<llvm::PossiblyDisjointInst>(inst);
728 iface.setIsDisjoint(instDisjoint->isDisjoint());
732 auto iface = cast<NonNegFlagInterface>(op);
734 iface.setNonNeg(inst->hasNonNeg());
739 auto iface = cast<FastmathFlagsInterface>(op);
745 if (!isa<llvm::FPMathOperator>(inst))
747 llvm::FastMathFlags flags = inst->getFastMathFlags();
750 FastmathFlags value = {};
751 value = bitEnumSet(value, FastmathFlags::nnan, flags.noNaNs());
752 value = bitEnumSet(value, FastmathFlags::ninf, flags.noInfs());
753 value = bitEnumSet(value, FastmathFlags::nsz, flags.noSignedZeros());
754 value = bitEnumSet(value, FastmathFlags::arcp, flags.allowReciprocal());
756 value = bitEnumSet(value, FastmathFlags::afn, flags.approxFunc());
757 value = bitEnumSet(value, FastmathFlags::reassoc, flags.allowReassoc());
759 iface->setAttr(iface.getFastmathAttrName(), attr);
764 return isa<IntegerType, FloatType>(type);
776 if (numElements.isScalable()) {
778 <<
"scalable vectors not supported";
788 shape.push_back(numElements.getKnownMinValue());
792 Type ModuleImport::getBuiltinTypeForAttr(
Type type) {
807 while (
auto arrayType = dyn_cast<LLVMArrayType>(type)) {
808 arrayShape.push_back(arrayType.getNumElements());
809 type = arrayType.getElementType();
819 llvm::Constant *constScalar) {
823 if (
auto *constInt = dyn_cast<llvm::ConstantInt>(constScalar)) {
826 constInt->getValue());
830 if (
auto *constFloat = dyn_cast<llvm::ConstantFP>(constScalar)) {
831 llvm::Type *type = constFloat->getType();
832 FloatType floatType =
838 <<
"unexpected floating-point type";
841 return builder.
getFloatAttr(floatType, constFloat->getValueAPF());
850 llvm::ConstantDataSequential *constSequence) {
852 elementAttrs.reserve(constSequence->getNumElements());
853 for (
auto idx : llvm::seq<int64_t>(0, constSequence->getNumElements())) {
854 llvm::Constant *constElement = constSequence->getElementAsConstant(idx);
860 Attribute ModuleImport::getConstantAsAttr(llvm::Constant *constant) {
866 auto getConstantShape = [&](llvm::Type *type) {
867 return llvm::dyn_cast_if_present<ShapedType>(
873 if (
auto *constArray = dyn_cast<llvm::ConstantDataSequential>(constant)) {
874 if (constArray->isString())
876 auto shape = getConstantShape(constArray->getType());
880 auto *constVector = dyn_cast<llvm::ConstantDataVector>(constant);
881 if (constVector && constVector->isSplat()) {
884 builder, constVector->getElementAsConstant(0));
895 if (
auto *constAggregate = dyn_cast<llvm::ConstantAggregate>(constant)) {
896 auto shape = getConstantShape(constAggregate->getType());
902 while (!workList.empty()) {
903 llvm::Constant *current = workList.pop_back_val();
906 if (
auto *constAggregate = dyn_cast<llvm::ConstantAggregate>(current)) {
908 reverse(llvm::seq<int64_t>(0, constAggregate->getNumOperands())))
909 workList.push_back(constAggregate->getAggregateElement(idx));
914 if (
auto *constArray = dyn_cast<llvm::ConstantDataSequential>(current)) {
917 elementAttrs.append(attrs.begin(), attrs.end());
923 elementAttrs.push_back(scalarAttr);
934 if (
auto *constZero = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
935 auto shape = llvm::dyn_cast_if_present<ShapedType>(
936 getBuiltinTypeForAttr(
convertType(constZero->getType())));
941 assert(splatAttr &&
"expected non-null zero attribute for scalar types");
948 ModuleImport::getOrCreateNamelessSymbolName(llvm::GlobalVariable *globalVar) {
949 assert(globalVar->getName().empty() &&
950 "expected to work with a nameless global");
951 auto [it, success] = namelessGlobals.try_emplace(globalVar);
958 [
this](StringRef newName) {
return llvmModule->getNamedValue(newName); },
961 it->getSecond() = symbolRef;
965 LogicalResult ModuleImport::convertAlias(llvm::GlobalAlias *alias) {
968 if (!aliasInsertionOp)
974 AliasOp aliasOp = builder.
create<AliasOp>(
975 mlirModule.getLoc(), type, convertLinkageFromLLVM(alias->getLinkage()),
978 alias->isThreadLocal(),
980 aliasInsertionOp = aliasOp;
984 setConstantInsertionPointToStart(block);
985 FailureOr<Value> initializer = convertConstantExpr(alias->getAliasee());
986 if (failed(initializer))
988 builder.
create<ReturnOp>(aliasOp.getLoc(), *initializer);
990 if (alias->hasAtLeastLocalUnnamedAddr())
991 aliasOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(alias->getUnnamedAddr()));
992 aliasOp.setVisibility_(convertVisibilityFromLLVM(alias->getVisibility()));
997 LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
1000 if (!globalInsertionOp)
1006 if (globalVar->hasInitializer())
1007 valueAttr = getConstantAsAttr(globalVar->getInitializer());
1010 uint64_t alignment = 0;
1011 llvm::MaybeAlign maybeAlign = globalVar->getAlign();
1012 if (maybeAlign.has_value()) {
1013 llvm::Align align = *maybeAlign;
1014 alignment = align.value();
1021 globalVar->getDebugInfo(globalExpressions);
1023 for (llvm::DIGlobalVariableExpression *expr : globalExpressions) {
1024 DIGlobalVariableExpressionAttr globalExpressionAttr =
1025 debugImporter->translateGlobalVariableExpression(expr);
1026 globalExpressionAttrs.push_back(globalExpressionAttr);
1031 StringRef globalName = globalVar->getName();
1032 if (globalName.empty())
1033 globalName = getOrCreateNamelessSymbolName(globalVar).
getValue();
1035 GlobalOp globalOp = builder.
create<GlobalOp>(
1036 mlirModule.getLoc(), type, globalVar->isConstant(),
1037 convertLinkageFromLLVM(globalVar->getLinkage()), StringRef(globalName),
1038 valueAttr, alignment, globalVar->getAddressSpace(),
1039 globalVar->isDSOLocal(),
1040 globalVar->isThreadLocal(), SymbolRefAttr(),
1042 globalInsertionOp = globalOp;
1044 if (globalVar->hasInitializer() && !valueAttr) {
1047 setConstantInsertionPointToStart(block);
1048 FailureOr<Value> initializer =
1049 convertConstantExpr(globalVar->getInitializer());
1050 if (failed(initializer))
1052 builder.
create<ReturnOp>(globalOp.getLoc(), *initializer);
1054 if (globalVar->hasAtLeastLocalUnnamedAddr()) {
1055 globalOp.setUnnamedAddr(
1056 convertUnnamedAddrFromLLVM(globalVar->getUnnamedAddr()));
1058 if (globalVar->hasSection())
1059 globalOp.setSection(globalVar->getSection());
1060 globalOp.setVisibility_(
1061 convertVisibilityFromLLVM(globalVar->getVisibility()));
1063 if (globalVar->hasComdat())
1064 globalOp.setComdatAttr(comdatMapping.lookup(globalVar->getComdat()));
1070 ModuleImport::convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar) {
1071 if (!globalVar->hasInitializer() || !globalVar->hasAppendingLinkage())
1074 dyn_cast<llvm::ConstantArray>(globalVar->getInitializer());
1080 for (llvm::Value *operand : initializer->operands()) {
1081 auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
1082 if (!aggregate || aggregate->getNumOperands() != 3)
1085 auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
1086 auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
1087 auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
1088 if (!priority || !func || !data)
1092 if (!data->isNullValue())
1096 priorities.push_back(priority->getValue().getZExtValue());
1100 if (!globalInsertionOp)
1106 globalInsertionOp = builder.
create<LLVM::GlobalCtorsOp>(
1111 globalInsertionOp = builder.
create<LLVM::GlobalDtorsOp>(
1118 ModuleImport::getConstantsToConvert(llvm::Constant *constant) {
1120 if (valueMapping.contains(constant))
1129 workList.insert(constant);
1130 while (!workList.empty()) {
1131 llvm::Constant *current = workList.back();
1134 if (isa<llvm::GlobalObject>(current) || isa<llvm::GlobalAlias>(current)) {
1135 orderedSet.insert(current);
1136 workList.pop_back();
1142 auto [adjacencyIt, inserted] = adjacencyLists.try_emplace(current);
1146 for (llvm::Value *operand : current->operands())
1147 if (
auto *constDependency = dyn_cast<llvm::Constant>(operand))
1148 adjacencyIt->getSecond().push_back(constDependency);
1151 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(current)) {
1152 unsigned numElements = constAgg->getElementCount().getFixedValue();
1153 for (
unsigned i = 0, e = numElements; i != e; ++i)
1154 adjacencyIt->getSecond().push_back(constAgg->getElementValue(i));
1160 if (adjacencyIt->getSecond().empty()) {
1161 orderedSet.insert(current);
1162 workList.pop_back();
1170 llvm::Constant *dependency = adjacencyIt->getSecond().pop_back_val();
1171 if (valueMapping.contains(dependency) || workList.contains(dependency) ||
1172 orderedSet.contains(dependency))
1174 workList.insert(dependency);
1180 FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
1184 if (
Attribute attr = getConstantAsAttr(constant)) {
1186 if (
auto symbolRef = dyn_cast<FlatSymbolRefAttr>(attr)) {
1187 return builder.
create<AddressOfOp>(loc, type, symbolRef.getValue())
1190 return builder.
create<ConstantOp>(loc, type, attr).getResult();
1194 if (
auto *nullPtr = dyn_cast<llvm::ConstantPointerNull>(constant)) {
1196 return builder.
create<ZeroOp>(loc, type).getResult();
1200 if (isa<llvm::ConstantTokenNone>(constant)) {
1201 return builder.
create<NoneTokenOp>(loc).getResult();
1205 if (
auto *poisonVal = dyn_cast<llvm::PoisonValue>(constant)) {
1207 return builder.
create<PoisonOp>(loc, type).getResult();
1211 if (
auto *undefVal = dyn_cast<llvm::UndefValue>(constant)) {
1213 return builder.
create<UndefOp>(loc, type).getResult();
1217 if (
auto *globalObj = dyn_cast<llvm::GlobalObject>(constant)) {
1219 StringRef globalName = globalObj->getName();
1222 if (globalName.empty())
1224 getOrCreateNamelessSymbolName(cast<llvm::GlobalVariable>(globalObj));
1227 return builder.
create<AddressOfOp>(loc, type, symbolRef).getResult();
1231 if (
auto *globalAliasObj = dyn_cast<llvm::GlobalAlias>(constant)) {
1233 StringRef aliaseeName = globalAliasObj->getName();
1235 return builder.
create<AddressOfOp>(loc, type, symbolRef).getResult();
1239 if (
auto *constExpr = dyn_cast<llvm::ConstantExpr>(constant)) {
1245 llvm::Instruction *inst = constExpr->getAsInstruction();
1246 auto guard = llvm::make_scope_exit([&]() {
1247 assert(!noResultOpMapping.contains(inst) &&
1248 "expected constant expression to return a result");
1249 valueMapping.erase(inst);
1250 inst->deleteValue();
1254 assert(llvm::all_of(inst->operands(), [&](llvm::Value *value) {
1255 return valueMapping.contains(value);
1257 if (failed(processInstruction(inst)))
1263 if (isa<llvm::ConstantAggregate>(constant) ||
1264 isa<llvm::ConstantAggregateZero>(constant)) {
1267 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregate>(constant)) {
1268 elementValues.reserve(constAgg->getNumOperands());
1269 for (llvm::Value *operand : constAgg->operands())
1272 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1273 unsigned numElements = constAgg->getElementCount().getFixedValue();
1274 elementValues.reserve(numElements);
1275 for (
unsigned i = 0, e = numElements; i != e; ++i)
1276 elementValues.push_back(
lookupValue(constAgg->getElementValue(i)));
1278 assert(llvm::count(elementValues,
nullptr) == 0 &&
1279 "expected all elements have been converted before");
1283 bool isArrayOrStruct = isa<LLVMArrayType, LLVMStructType>(rootType);
1285 "unrecognized aggregate type");
1286 Value root = builder.
create<UndefOp>(loc, rootType);
1288 if (isArrayOrStruct) {
1289 root = builder.
create<InsertValueOp>(loc, root, it.value(), it.index());
1294 root = builder.
create<InsertElementOp>(loc, rootType, root, it.value(),
1301 if (
auto *constTargetNone = dyn_cast<llvm::ConstantTargetNone>(constant)) {
1302 LLVMTargetExtType targetExtType =
1303 cast<LLVMTargetExtType>(
convertType(constTargetNone->getType()));
1304 assert(targetExtType.hasProperty(LLVMTargetExtType::HasZeroInit) &&
1305 "target extension type does not support zero-initialization");
1308 return builder.
create<LLVM::ZeroOp>(loc, targetExtType).getRes();
1311 StringRef error =
"";
1312 if (isa<llvm::BlockAddress>(constant))
1313 error =
" since blockaddress(...) is unsupported";
1315 return emitError(loc) <<
"unhandled constant: " <<
diag(*constant) << error;
1318 FailureOr<Value> ModuleImport::convertConstantExpr(llvm::Constant *constant) {
1322 assert(!valueMapping.contains(constant) &&
1323 "expected constant has not been converted before");
1324 assert(constantInsertionBlock &&
1325 "expected the constant insertion block to be non-null");
1329 if (!constantInsertionOp)
1336 getConstantsToConvert(constant);
1337 for (llvm::Constant *constantToConvert : constantsToConvert) {
1338 FailureOr<Value> converted = convertConstant(constantToConvert);
1339 if (failed(converted))
1341 mapValue(constantToConvert, *converted);
1351 assert(!isa<llvm::MetadataAsValue>(value) &&
1352 "expected value to not be metadata");
1355 auto it = valueMapping.find(value);
1356 if (it != valueMapping.end())
1357 return it->getSecond();
1360 if (
auto *constant = dyn_cast<llvm::Constant>(value))
1361 return convertConstantExpr(constant);
1364 if (
auto *inst = dyn_cast<llvm::Instruction>(value))
1366 return emitError(loc) <<
"unhandled value: " <<
diag(*value);
1372 auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
1375 auto *node = dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
1378 value = node->getValue();
1381 auto it = valueMapping.find(value);
1382 if (it != valueMapping.end())
1383 return it->getSecond();
1386 if (
auto *constant = dyn_cast<llvm::Constant>(value))
1387 return convertConstantExpr(constant);
1391 FailureOr<SmallVector<Value>>
1394 remapped.reserve(values.size());
1395 for (llvm::Value *value : values) {
1397 if (failed(converted))
1399 remapped.push_back(*converted);
1409 assert(immArgPositions.size() == immArgAttrNames.size() &&
1410 "LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
1414 for (
auto [immArgPos, immArgName] :
1415 llvm::zip(immArgPositions, immArgAttrNames)) {
1416 auto &value = operands[immArgPos];
1417 auto *constant = llvm::cast<llvm::Constant>(value);
1419 assert(attr && attr.getType().isIntOrFloat() &&
1420 "expected immarg to be float or integer constant");
1422 attrsOut.push_back({nameAttr, attr});
1427 for (llvm::Value *value : operands) {
1431 if (failed(mlirValue))
1433 valuesOut.push_back(*mlirValue);
1438 if (requiresOpBundles) {
1439 opBundleSizes.reserve(opBundles.size());
1440 opBundleTagAttrs.reserve(opBundles.size());
1442 for (
const llvm::OperandBundleUse &bundle : opBundles) {
1443 opBundleSizes.push_back(bundle.Inputs.size());
1444 opBundleTagAttrs.push_back(
StringAttr::get(context, bundle.getTagName()));
1446 for (
const llvm::Use &opBundleOperand : bundle.Inputs) {
1447 auto operandMlirValue =
convertValue(opBundleOperand.get());
1448 if (failed(operandMlirValue))
1450 valuesOut.push_back(*operandMlirValue);
1455 auto opBundleSizesAttrNameAttr =
1457 attrsOut.push_back({opBundleSizesAttrNameAttr, opBundleSizesAttr});
1459 auto opBundleTagsAttr =
ArrayAttr::get(context, opBundleTagAttrs);
1460 auto opBundleTagsAttrNameAttr =
1462 attrsOut.push_back({opBundleTagsAttrNameAttr, opBundleTagsAttr});
1469 IntegerAttr integerAttr;
1471 bool success = succeeded(converted) &&
1473 assert(success &&
"expected a constant integer value");
1479 FloatAttr floatAttr;
1483 assert(success &&
"expected a constant float value");
1489 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1490 auto *node = cast<llvm::DILocalVariable>(nodeAsVal->getMetadata());
1491 return debugImporter->translate(node);
1495 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1496 auto *node = cast<llvm::DILabel>(nodeAsVal->getMetadata());
1497 return debugImporter->translate(node);
1500 FPExceptionBehaviorAttr
1502 auto *metadata = cast<llvm::MetadataAsValue>(value);
1503 auto *mdstr = cast<llvm::MDString>(metadata->getMetadata());
1504 std::optional<llvm::fp::ExceptionBehavior> optLLVM =
1505 llvm::convertStrToExceptionBehavior(mdstr->getString());
1506 assert(optLLVM &&
"Expecting FP exception behavior");
1507 return builder.
getAttr<FPExceptionBehaviorAttr>(
1508 convertFPExceptionBehaviorFromLLVM(*optLLVM));
1512 auto *metadata = cast<llvm::MetadataAsValue>(value);
1513 auto *mdstr = cast<llvm::MDString>(metadata->getMetadata());
1514 std::optional<llvm::RoundingMode> optLLVM =
1515 llvm::convertStrToRoundingMode(mdstr->getString());
1516 assert(optLLVM &&
"Expecting rounding mode");
1517 return builder.
getAttr<RoundingModeAttr>(
1518 convertRoundingModeFromLLVM(*optLLVM));
1521 FailureOr<SmallVector<AliasScopeAttr>>
1523 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1524 auto *node = cast<llvm::MDNode>(nodeAsVal->getMetadata());
1529 return debugImporter->translateLoc(loc);
1533 ModuleImport::convertBranchArgs(llvm::Instruction *branch,
1534 llvm::BasicBlock *target,
1536 for (
auto inst = target->begin(); isa<llvm::PHINode>(inst); ++inst) {
1537 auto *phiInst = cast<llvm::PHINode>(&*inst);
1538 llvm::Value *value = phiInst->getIncomingValueForBlock(branch->getParent());
1540 if (failed(converted))
1542 blockArguments.push_back(*converted);
1547 FailureOr<SmallVector<Value>>
1548 ModuleImport::convertCallOperands(llvm::CallBase *callInst,
1549 bool allowInlineAsm) {
1550 bool isInlineAsm = callInst->isInlineAsm();
1551 if (isInlineAsm && !allowInlineAsm)
1561 if (!isa<llvm::Function>(callInst->getCalledOperand()) && !isInlineAsm) {
1562 FailureOr<Value> called =
convertValue(callInst->getCalledOperand());
1565 operands.push_back(*called);
1569 FailureOr<SmallVector<Value>> arguments =
convertValues(args);
1570 if (failed(arguments))
1573 llvm::append_range(operands, *arguments);
1579 static LogicalResult
1581 LLVMFunctionType calleeType) {
1582 if (callType.getReturnType() != calleeType.getReturnType())
1585 if (calleeType.isVarArg()) {
1588 if (callType.getNumParams() < calleeType.getNumParams())
1593 if (callType.getNumParams() != calleeType.getNumParams())
1598 for (
auto [operandType, argumentType] :
1599 llvm::zip(callType.getParams(), calleeType.getParams()))
1600 if (operandType != argumentType)
1606 FailureOr<LLVMFunctionType>
1607 ModuleImport::convertFunctionType(llvm::CallBase *callInst) {
1608 auto castOrFailure = [](
Type convertedType) -> FailureOr<LLVMFunctionType> {
1609 auto funcTy = dyn_cast_or_null<LLVMFunctionType>(convertedType);
1615 llvm::Value *calledOperand = callInst->getCalledOperand();
1616 FailureOr<LLVMFunctionType> callType =
1617 castOrFailure(
convertType(callInst->getFunctionType()));
1618 if (failed(callType))
1620 auto *callee = dyn_cast<llvm::Function>(calledOperand);
1625 FailureOr<LLVMFunctionType> calleeType =
1626 castOrFailure(
convertType(callee->getFunctionType()));
1627 if (failed(calleeType))
1633 return emitError(loc) <<
"incompatible call and callee types: " << *callType
1634 <<
" and " << *calleeType;
1641 llvm::Value *calledOperand = callInst->getCalledOperand();
1642 if (
auto *callee = dyn_cast<llvm::Function>(calledOperand))
1647 LogicalResult ModuleImport::convertIntrinsic(llvm::CallInst *inst) {
1652 return emitError(loc) <<
"unhandled intrinsic: " <<
diag(*inst);
1655 LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
1658 if (inst->getOpcode() == llvm::Instruction::Br) {
1659 auto *brInst = cast<llvm::BranchInst>(inst);
1663 for (
auto i : llvm::seq<unsigned>(0, brInst->getNumSuccessors())) {
1664 llvm::BasicBlock *succ = brInst->getSuccessor(i);
1666 if (failed(convertBranchArgs(brInst, succ, blockArgs)))
1669 succBlockArgs.push_back(blockArgs);
1672 if (!brInst->isConditional()) {
1673 auto brOp = builder.
create<LLVM::BrOp>(loc, succBlockArgs.front(),
1674 succBlocks.front());
1678 FailureOr<Value> condition =
convertValue(brInst->getCondition());
1679 if (failed(condition))
1681 auto condBrOp = builder.
create<LLVM::CondBrOp>(
1682 loc, *condition, succBlocks.front(), succBlockArgs.front(),
1683 succBlocks.back(), succBlockArgs.back());
1687 if (inst->getOpcode() == llvm::Instruction::Switch) {
1688 auto *swInst = cast<llvm::SwitchInst>(inst);
1690 FailureOr<Value> condition =
convertValue(swInst->getCondition());
1691 if (failed(condition))
1695 llvm::BasicBlock *defaultBB = swInst->getDefaultDest();
1696 if (failed(convertBranchArgs(swInst, defaultBB, defaultBlockArgs)))
1700 unsigned numCases = swInst->getNumCases();
1706 const llvm::SwitchInst::CaseHandle &caseHandle = it.value();
1707 llvm::BasicBlock *succBB = caseHandle.getCaseSuccessor();
1708 if (failed(convertBranchArgs(swInst, succBB, caseOperands[it.index()])))
1710 caseOperandRefs[it.index()] = caseOperands[it.index()];
1711 caseValues[it.index()] = caseHandle.getCaseValue()->getValue();
1715 auto switchOp = builder.
create<SwitchOp>(
1716 loc, *condition,
lookupBlock(defaultBB), defaultBlockArgs, caseValues,
1717 caseBlocks, caseOperandRefs);
1721 if (inst->getOpcode() == llvm::Instruction::PHI) {
1727 if (inst->getOpcode() == llvm::Instruction::Call) {
1728 auto *callInst = cast<llvm::CallInst>(inst);
1729 llvm::Value *calledOperand = callInst->getCalledOperand();
1731 FailureOr<SmallVector<Value>> operands =
1732 convertCallOperands(callInst,
true);
1733 if (failed(operands))
1736 auto callOp = [&]() -> FailureOr<Operation *> {
1737 if (
auto *asmI = dyn_cast<llvm::InlineAsm>(calledOperand)) {
1743 loc, resultTy, *operands,
1751 FailureOr<LLVMFunctionType> funcTy = convertFunctionType(callInst);
1756 auto callOp = builder.
create<CallOp>(loc, *funcTy, callee, *operands);
1757 if (failed(convertCallAttributes(callInst, callOp)))
1760 convertParameterAttributes(callInst, callOp, builder);
1761 return callOp.getOperation();
1767 if (!callInst->getType()->isVoidTy())
1768 mapValue(inst, (*callOp)->getResult(0));
1773 if (inst->getOpcode() == llvm::Instruction::LandingPad) {
1774 auto *lpInst = cast<llvm::LandingPadInst>(inst);
1777 operands.reserve(lpInst->getNumClauses());
1778 for (
auto i : llvm::seq<unsigned>(0, lpInst->getNumClauses())) {
1779 FailureOr<Value> operand =
convertValue(lpInst->getClause(i));
1780 if (failed(operand))
1782 operands.push_back(*operand);
1787 builder.
create<LandingpadOp>(loc, type, lpInst->isCleanup(), operands);
1791 if (inst->getOpcode() == llvm::Instruction::Invoke) {
1792 auto *invokeInst = cast<llvm::InvokeInst>(inst);
1794 if (invokeInst->isInlineAsm())
1795 return emitError(loc) <<
"invoke of inline assembly is not supported";
1797 FailureOr<SmallVector<Value>> operands = convertCallOperands(invokeInst);
1798 if (failed(operands))
1803 bool invokeResultUsedInPhi = llvm::any_of(
1804 invokeInst->getNormalDest()->phis(), [&](
const llvm::PHINode &phi) {
1805 return phi.getIncomingValueForBlock(invokeInst->getParent()) ==
1810 Block *directNormalDest = normalDest;
1811 if (invokeResultUsedInPhi) {
1817 directNormalDest = builder.
createBlock(normalDest);
1821 if (failed(convertBranchArgs(invokeInst, invokeInst->getUnwindDest(),
1825 FailureOr<LLVMFunctionType> funcTy = convertFunctionType(invokeInst);
1834 auto invokeOp = builder.
create<InvokeOp>(
1835 loc, *funcTy, calleeName, *operands, directNormalDest,
ValueRange(),
1836 lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
1838 if (failed(convertInvokeAttributes(invokeInst, invokeOp)))
1842 convertParameterAttributes(invokeInst, invokeOp, builder);
1844 if (!invokeInst->getType()->isVoidTy())
1845 mapValue(inst, invokeOp.getResults().front());
1850 if (failed(convertBranchArgs(invokeInst, invokeInst->getNormalDest(),
1854 if (invokeResultUsedInPhi) {
1860 builder.
create<LLVM::BrOp>(loc, normalArgs, normalDest);
1864 assert(llvm::none_of(
1867 "An llvm.invoke operation cannot pass its result as a block "
1869 invokeOp.getNormalDestOperandsMutable().append(normalArgs);
1874 if (inst->getOpcode() == llvm::Instruction::GetElementPtr) {
1875 auto *gepInst = cast<llvm::GetElementPtrInst>(inst);
1876 Type sourceElementType =
convertType(gepInst->getSourceElementType());
1877 FailureOr<Value> basePtr =
convertValue(gepInst->getOperand(0));
1878 if (failed(basePtr))
1886 for (llvm::Value *operand : llvm::drop_begin(gepInst->operand_values())) {
1890 indices.push_back(*index);
1894 auto gepOp = builder.
create<GEPOp>(loc, type, sourceElementType, *basePtr,
1895 indices, gepInst->isInBounds());
1904 return emitError(loc) <<
"unhandled instruction: " <<
diag(*inst);
1907 LogicalResult ModuleImport::processInstruction(llvm::Instruction *inst) {
1914 if (
auto *intrinsic = dyn_cast<llvm::IntrinsicInst>(inst))
1915 return convertIntrinsic(intrinsic);
1918 return convertInstruction(inst);
1922 if (!f->hasPersonalityFn())
1925 llvm::Constant *pf = f->getPersonalityFn();
1933 if (
auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) {
1934 if (ce->getOpcode() == llvm::Instruction::BitCast &&
1935 ce->getType() == llvm::PointerType::getUnqual(f->getContext())) {
1936 if (
auto *func = dyn_cast<llvm::Function>(ce->getOperand(0)))
1944 llvm::MemoryEffects memEffects = func->getMemoryEffects();
1946 auto othermem = convertModRefInfoFromLLVM(
1947 memEffects.getModRef(llvm::MemoryEffects::Location::Other));
1948 auto argMem = convertModRefInfoFromLLVM(
1949 memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
1950 auto inaccessibleMem = convertModRefInfoFromLLVM(
1951 memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
1955 if (memAttr.isReadWrite())
1957 funcOp.setMemoryEffectsAttr(memAttr);
1963 StringLiteral(
"aarch64_in_za"),
1964 StringLiteral(
"aarch64_inout_za"),
1965 StringLiteral(
"aarch64_new_za"),
1966 StringLiteral(
"aarch64_out_za"),
1967 StringLiteral(
"aarch64_preserves_za"),
1968 StringLiteral(
"aarch64_pstate_sm_body"),
1969 StringLiteral(
"aarch64_pstate_sm_compatible"),
1970 StringLiteral(
"aarch64_pstate_sm_enabled"),
1971 StringLiteral(
"alwaysinline"),
1972 StringLiteral(
"approx-func-fp-math"),
1973 StringLiteral(
"convergent"),
1974 StringLiteral(
"denormal-fp-math"),
1975 StringLiteral(
"denormal-fp-math-f32"),
1976 StringLiteral(
"fp-contract"),
1977 StringLiteral(
"frame-pointer"),
1978 StringLiteral(
"no-infs-fp-math"),
1979 StringLiteral(
"no-nans-fp-math"),
1980 StringLiteral(
"no-signed-zeros-fp-math"),
1981 StringLiteral(
"noinline"),
1982 StringLiteral(
"nounwind"),
1983 StringLiteral(
"optnone"),
1984 StringLiteral(
"target-features"),
1985 StringLiteral(
"tune-cpu"),
1986 StringLiteral(
"unsafe-fp-math"),
1987 StringLiteral(
"vscale_range"),
1988 StringLiteral(
"willreturn"),
1994 llvm::AttributeSet funcAttrs = func->getAttributes().getAttributes(
1995 llvm::AttributeList::AttrIndex::FunctionIndex);
1996 for (llvm::Attribute attr : funcAttrs) {
1999 if (attr.hasAttribute(llvm::Attribute::Memory))
2003 if (attr.isTypeAttribute()) {
2005 "type attributes on a function are invalid, skipping it");
2010 if (attr.isStringAttribute())
2011 attrName = attr.getKindAsString();
2013 attrName = llvm::Attribute::getNameFromAttrKind(attr.getKindAsEnum());
2020 if (attr.isStringAttribute()) {
2021 StringRef val = attr.getValueAsString();
2023 passthroughs.push_back(keyAttr);
2026 passthroughs.push_back(
2030 if (attr.isIntAttribute()) {
2031 auto val = std::to_string(attr.getValueAsInt());
2032 passthroughs.push_back(
2036 if (attr.isEnumAttribute()) {
2037 passthroughs.push_back(keyAttr);
2041 llvm_unreachable(
"unexpected attribute kind");
2044 if (!passthroughs.empty())
2045 funcOp.setPassthroughAttr(
ArrayAttr::get(context, passthroughs));
2049 LLVMFuncOp funcOp) {
2053 if (func->hasFnAttribute(llvm::Attribute::NoInline))
2054 funcOp.setNoInline(
true);
2055 if (func->hasFnAttribute(llvm::Attribute::AlwaysInline))
2056 funcOp.setAlwaysInline(
true);
2057 if (func->hasFnAttribute(llvm::Attribute::OptimizeNone))
2058 funcOp.setOptimizeNone(
true);
2059 if (func->hasFnAttribute(llvm::Attribute::Convergent))
2060 funcOp.setConvergent(
true);
2061 if (func->hasFnAttribute(llvm::Attribute::NoUnwind))
2062 funcOp.setNoUnwind(
true);
2063 if (func->hasFnAttribute(llvm::Attribute::WillReturn))
2064 funcOp.setWillReturn(
true);
2066 if (func->hasFnAttribute(
"aarch64_pstate_sm_enabled"))
2067 funcOp.setArmStreaming(
true);
2068 else if (func->hasFnAttribute(
"aarch64_pstate_sm_body"))
2069 funcOp.setArmLocallyStreaming(
true);
2070 else if (func->hasFnAttribute(
"aarch64_pstate_sm_compatible"))
2071 funcOp.setArmStreamingCompatible(
true);
2073 if (func->hasFnAttribute(
"aarch64_new_za"))
2074 funcOp.setArmNewZa(
true);
2075 else if (func->hasFnAttribute(
"aarch64_in_za"))
2076 funcOp.setArmInZa(
true);
2077 else if (func->hasFnAttribute(
"aarch64_out_za"))
2078 funcOp.setArmOutZa(
true);
2079 else if (func->hasFnAttribute(
"aarch64_inout_za"))
2080 funcOp.setArmInoutZa(
true);
2081 else if (func->hasFnAttribute(
"aarch64_preserves_za"))
2082 funcOp.setArmPreservesZa(
true);
2084 llvm::Attribute attr = func->getFnAttribute(llvm::Attribute::VScaleRange);
2085 if (attr.isValid()) {
2094 if (func->hasFnAttribute(
"frame-pointer")) {
2095 StringRef stringRefFramePointerKind =
2096 func->getFnAttribute(
"frame-pointer").getValueAsString();
2098 funcOp.getContext(), LLVM::framePointerKind::symbolizeFramePointerKind(
2099 stringRefFramePointerKind)
2103 if (llvm::Attribute attr = func->getFnAttribute(
"target-cpu");
2104 attr.isStringAttribute())
2105 funcOp.setTargetCpuAttr(
StringAttr::get(context, attr.getValueAsString()));
2107 if (llvm::Attribute attr = func->getFnAttribute(
"tune-cpu");
2108 attr.isStringAttribute())
2109 funcOp.setTuneCpuAttr(
StringAttr::get(context, attr.getValueAsString()));
2111 if (llvm::Attribute attr = func->getFnAttribute(
"target-features");
2112 attr.isStringAttribute())
2113 funcOp.setTargetFeaturesAttr(
2116 if (llvm::Attribute attr = func->getFnAttribute(
"unsafe-fp-math");
2117 attr.isStringAttribute())
2118 funcOp.setUnsafeFpMath(attr.getValueAsBool());
2120 if (llvm::Attribute attr = func->getFnAttribute(
"no-infs-fp-math");
2121 attr.isStringAttribute())
2122 funcOp.setNoInfsFpMath(attr.getValueAsBool());
2124 if (llvm::Attribute attr = func->getFnAttribute(
"no-nans-fp-math");
2125 attr.isStringAttribute())
2126 funcOp.setNoNansFpMath(attr.getValueAsBool());
2128 if (llvm::Attribute attr = func->getFnAttribute(
"approx-func-fp-math");
2129 attr.isStringAttribute())
2130 funcOp.setApproxFuncFpMath(attr.getValueAsBool());
2132 if (llvm::Attribute attr = func->getFnAttribute(
"no-signed-zeros-fp-math");
2133 attr.isStringAttribute())
2134 funcOp.setNoSignedZerosFpMath(attr.getValueAsBool());
2136 if (llvm::Attribute attr = func->getFnAttribute(
"denormal-fp-math");
2137 attr.isStringAttribute())
2138 funcOp.setDenormalFpMathAttr(
2141 if (llvm::Attribute attr = func->getFnAttribute(
"denormal-fp-math-f32");
2142 attr.isStringAttribute())
2143 funcOp.setDenormalFpMathF32Attr(
2146 if (llvm::Attribute attr = func->getFnAttribute(
"fp-contract");
2147 attr.isStringAttribute())
2148 funcOp.setFpContractAttr(
StringAttr::get(context, attr.getValueAsString()));
2152 ModuleImport::convertParameterAttribute(llvm::AttributeSet llvmParamAttrs,
2156 auto llvmAttr = llvmParamAttrs.getAttribute(llvmKind);
2158 if (!llvmAttr.isValid())
2163 if (llvmAttr.hasKindAsEnum() &&
2164 llvmAttr.getKindAsEnum() == llvm::Attribute::Captures) {
2165 if (llvm::capturesNothing(llvmAttr.getCaptureInfo()))
2166 paramAttrs.push_back(
2172 if (llvmAttr.isTypeAttribute())
2174 else if (llvmAttr.isIntAttribute())
2176 else if (llvmAttr.isEnumAttribute())
2178 else if (llvmAttr.isConstantRangeAttribute()) {
2179 const llvm::ConstantRange &value = llvmAttr.getValueAsConstantRange();
2180 mlirAttr = builder.
getAttr<LLVM::ConstantRangeAttr>(value.getLower(),
2183 llvm_unreachable(
"unexpected parameter attribute kind");
2184 paramAttrs.push_back(builder.
getNamedAttr(mlirName, mlirAttr));
2190 void ModuleImport::convertParameterAttributes(llvm::Function *func,
2193 auto llvmAttrs = func->getAttributes();
2194 for (
size_t i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
2195 llvm::AttributeSet llvmArgAttrs = llvmAttrs.getParamAttrs(i);
2196 funcOp.setArgAttrs(i, convertParameterAttribute(llvmArgAttrs, builder));
2200 llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
2201 if (!llvmResAttr.hasAttributes())
2203 funcOp.setResAttrsAttr(
2204 builder.
getArrayAttr(convertParameterAttribute(llvmResAttr, builder)));
2207 void ModuleImport::convertParameterAttributes(llvm::CallBase *call,
2208 CallOpInterface callOp,
2210 llvm::AttributeList llvmAttrs = call->getAttributes();
2212 bool anyArgAttrs =
false;
2213 for (
size_t i = 0, e = call->arg_size(); i < e; ++i) {
2214 llvmArgAttrsSet.emplace_back(llvmAttrs.getParamAttrs(i));
2215 if (llvmArgAttrsSet.back().hasAttributes())
2220 for (
auto &dict : dictAttrs)
2226 for (
auto &llvmArgAttrs : llvmArgAttrsSet)
2227 argAttrs.emplace_back(convertParameterAttribute(llvmArgAttrs, builder));
2228 callOp.setArgAttrsAttr(getArrayAttr(argAttrs));
2231 llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
2232 if (!llvmResAttr.hasAttributes())
2234 DictionaryAttr resAttrs = convertParameterAttribute(llvmResAttr, builder);
2235 callOp.setResAttrsAttr(getArrayAttr({resAttrs}));
2238 template <
typename Op>
2240 op.setCConv(convertCConvFromLLVM(inst->getCallingConv()));
2244 LogicalResult ModuleImport::convertInvokeAttributes(llvm::InvokeInst *inst,
2249 LogicalResult ModuleImport::convertCallAttributes(llvm::CallInst *inst,
2252 op.setTailCallKind(convertTailCallKindFromLLVM(inst->getTailCallKind()));
2253 op.setConvergent(inst->isConvergent());
2254 op.setNoUnwind(inst->doesNotThrow());
2255 op.setWillReturn(inst->hasFnAttr(llvm::Attribute::WillReturn));
2257 llvm::MemoryEffects memEffects = inst->getMemoryEffects();
2258 ModRefInfo othermem = convertModRefInfoFromLLVM(
2259 memEffects.getModRef(llvm::MemoryEffects::Location::Other));
2260 ModRefInfo argMem = convertModRefInfoFromLLVM(
2261 memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
2262 ModRefInfo inaccessibleMem = convertModRefInfoFromLLVM(
2263 memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
2267 if (!memAttr.isReadWrite())
2268 op.setMemoryEffectsAttr(memAttr);
2277 dyn_cast<LLVMFunctionType>(
convertType(func->getFunctionType()));
2278 if (func->isIntrinsic() &&
2282 bool dsoLocal = func->isDSOLocal();
2283 CConv cconv = convertCConvFromLLVM(func->getCallingConv());
2289 Location loc = debugImporter->translateFuncLocation(func);
2290 LLVMFuncOp funcOp = builder.
create<LLVMFuncOp>(
2291 loc, func->getName(), functionType,
2292 convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv);
2294 convertParameterAttributes(func, funcOp, builder);
2297 funcOp.setPersonalityAttr(personality);
2298 else if (func->hasPersonalityFn())
2299 emitWarning(funcOp.getLoc(),
"could not deduce personality, skipping it");
2302 funcOp.setGarbageCollector(StringRef(func->getGC()));
2304 if (func->hasAtLeastLocalUnnamedAddr())
2305 funcOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(func->getUnnamedAddr()));
2307 if (func->hasSection())
2308 funcOp.setSection(StringRef(func->getSection()));
2310 funcOp.setVisibility_(convertVisibilityFromLLVM(func->getVisibility()));
2312 if (func->hasComdat())
2313 funcOp.setComdatAttr(comdatMapping.lookup(func->getComdat()));
2315 if (llvm::MaybeAlign maybeAlign = func->getAlign())
2316 funcOp.setAlignment(maybeAlign->value());
2323 func->getAllMetadata(allMetadata);
2324 for (
auto &[kind, node] : allMetadata) {
2329 <<
"unhandled function metadata: " <<
diagMD(node, llvmModule.get())
2330 <<
" on " <<
diag(*func);
2334 if (func->isDeclaration())
2343 llvm::df_iterator_default_set<llvm::BasicBlock *> reachable;
2344 for (llvm::BasicBlock *basicBlock : llvm::depth_first_ext(func, reachable))
2349 for (llvm::BasicBlock &basicBlock : *func) {
2351 if (!reachable.contains(&basicBlock))
2353 Region &body = funcOp.getBody();
2356 reachableBasicBlocks.push_back(&basicBlock);
2361 BlockArgument blockArg = funcOp.getFunctionBody().addArgument(
2362 functionType.getParamType(it.index()), funcOp.getLoc());
2371 setConstantInsertionPointToStart(
lookupBlock(blocks.front()));
2372 for (llvm::BasicBlock *basicBlock : blocks)
2373 if (failed(processBasicBlock(basicBlock,
lookupBlock(basicBlock))))
2378 if (failed(processDebugIntrinsics()))
2387 if (!dbgIntr->isKillLocation())
2389 llvm::Value *value = dbgIntr->getArgOperand(0);
2390 auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
2393 return !isa<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
2397 ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
2400 auto emitUnsupportedWarning = [&]() {
2401 if (emitExpensiveWarnings)
2407 if (dbgIntr->hasArgList())
2408 return emitUnsupportedWarning();
2413 return emitUnsupportedWarning();
2417 DILocalVariableAttr localVariableAttr =
2419 if (!localVariableAttr)
2420 return emitUnsupportedWarning();
2422 if (failed(argOperand))
2423 return emitError(loc) <<
"failed to convert a debug intrinsic operand: "
2431 if (
Operation *op = argOperand->getDefiningOp();
2434 auto dominatedBlocks = domInfo.
getNode(op->getBlock())->children();
2437 if (dominatedBlocks.empty())
2438 return emitUnsupportedWarning();
2441 Block *dominatedBlock = (*dominatedBlocks.begin())->getBlock();
2446 auto locationExprAttr =
2447 debugImporter->translateExpression(dbgIntr->getExpression());
2450 .Case([&](llvm::DbgDeclareInst *) {
2451 return builder.
create<LLVM::DbgDeclareOp>(
2452 loc, *argOperand, localVariableAttr, locationExprAttr);
2454 .Case([&](llvm::DbgValueInst *) {
2455 return builder.
create<LLVM::DbgValueOp>(
2456 loc, *argOperand, localVariableAttr, locationExprAttr);
2459 setNonDebugMetadataAttrs(dbgIntr, op);
2463 LogicalResult ModuleImport::processDebugIntrinsics() {
2465 for (llvm::Instruction *inst : debugIntrinsics) {
2466 auto *intrCall = cast<llvm::DbgVariableIntrinsic>(inst);
2467 if (failed(processDebugIntrinsic(intrCall, domInfo)))
2473 LogicalResult ModuleImport::processBasicBlock(llvm::BasicBlock *bb,
2476 for (llvm::Instruction &inst : *bb) {
2477 if (failed(processInstruction(&inst)))
2482 if (debugIntrinsics.contains(&inst))
2489 setNonDebugMetadataAttrs(&inst, op);
2490 }
else if (inst.getOpcode() != llvm::Instruction::PHI) {
2491 if (emitExpensiveWarnings) {
2492 Location loc = debugImporter->translateLoc(inst.getDebugLoc());
2500 FailureOr<SmallVector<AccessGroupAttr>>
2502 return loopAnnotationImporter->lookupAccessGroupAttrs(node);
2508 return loopAnnotationImporter->translateLoopAnnotation(node, loc);
2514 bool dropDICompositeTypeElements,
2515 bool loadAllDialects) {
2522 LLVMDialect::getDialectNamespace()));
2524 DLTIDialect::getDialectNamespace()));
2525 if (loadAllDialects)
2532 emitExpensiveWarnings, dropDICompositeTypeElements);
static MLIRContext * getContext(OpFoldResult val)
static SmallVector< int64_t > getPositionFromIndices(ArrayRef< unsigned > indices)
Converts an array of unsigned indices to a signed integer position array.
static constexpr std::array kExplicitAttributes
static StringRef getLLVMSyncScope(llvm::Instruction *inst)
Converts the sync scope identifier of inst to the string representation necessary to build an atomic ...
static std::string diag(const llvm::Value &value)
static LogicalResult verifyFunctionTypeCompatibility(LLVMFunctionType callType, LLVMFunctionType calleeType)
Checks if callType and calleeType are compatible and can be represented in MLIR.
static void processPassthroughAttrs(llvm::Function *func, LLVMFuncOp funcOp)
static LogicalResult convertCallBaseAttributes(llvm::CallBase *inst, Op op)
static void processMemoryEffects(llvm::Function *func, LLVMFuncOp funcOp)
static 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 constexpr StringRef getNamelessGlobalPrefix()
Prefix used for symbols of nameless llvm globals.
static constexpr StringRef getGlobalComdatOpName()
Returns the symbol name for the module-level comdat operation.
static constexpr StringRef getGlobalCtorsVarName()
Returns the name of the global_ctors global variables.
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 SetVector< llvm::BasicBlock * > getTopologicallySortedBlocks(ArrayRef< llvm::BasicBlock * > basicBlocks)
Get a topologically sorted list of blocks for the given basic blocks.
static std::string diagMD(const llvm::Metadata *node, const llvm::Module *module)
static bool isScalarType(Type type)
Returns if type is a scalar integer or floating-point type.
static SmallVector< Attribute > getSequenceConstantAsAttrs(OpBuilder &builder, llvm::ConstantDataSequential *constSequence)
Returns an integer or float attribute array for the provided constant sequence constSequence or nullp...
static llvm::ManagedStatic< PassManagerOptions > options
static void contract(RootOrderingGraph &graph, ArrayRef< Value > cycle, const DenseMap< Value, unsigned > &parentDepths, DenseMap< Value, Value > &actualSource, DenseMap< Value, Value > &actualTarget)
Contracts the specified cycle in the given graph in-place.
Attributes are known-constant values of operations.
This class represents an argument of a Block.
Block represents an ordered list of Operations.
Operation * getTerminator()
Get the terminator operation of this block.
BlockArgument addArgument(Type type, Location loc)
Add one value to the argument list.
IntegerAttr getI32IntegerAttr(int32_t value)
IntegerAttr getIntegerAttr(Type type, int64_t value)
ArrayAttr getI32ArrayAttr(ArrayRef< int32_t > values)
FloatAttr getFloatAttr(Type type, double value)
IntegerAttr getI64IntegerAttr(int64_t value)
StringAttr getStringAttr(const Twine &bytes)
TypedAttr getZeroAttr(Type type)
MLIRContext * getContext() const
ArrayAttr getArrayAttr(ArrayRef< Attribute > value)
DictionaryAttr getDictionaryAttr(ArrayRef< NamedAttribute > value)
NamedAttribute getNamedAttr(StringRef name, Attribute val)
ArrayAttr getStrArrayAttr(ArrayRef< StringRef > values)
Attr getAttr(Args &&...args)
Get or construct an instance of the attribute Attr with provided arguments.
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
static DistinctAttr create(Attribute referencedAttr)
Creates a distinct attribute that associates a referenced attribute with a unique identifier.
A class for computing basic dominance information.
static FileLineColLoc get(StringAttr filename, unsigned line, unsigned column)
A symbol reference with a reference path containing a single element.
static FlatSymbolRefAttr get(StringAttr value)
Construct a symbol reference for the given value name.
StringRef getValue() const
Returns the name of the held symbol reference.
Interface collection for the import of LLVM IR that dispatches to a concrete dialect interface implem...
LogicalResult convertInstruction(OpBuilder &builder, llvm::Instruction *inst, ArrayRef< llvm::Value * > llvmOperands, LLVM::ModuleImport &moduleImport) const
Converts the LLVM instruction to an MLIR operation if a conversion exists.
LogicalResult convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst, LLVM::ModuleImport &moduleImport) const
Converts the LLVM intrinsic to an MLIR operation if a conversion exists.
LogicalResult setMetadataAttrs(OpBuilder &builder, unsigned kind, llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport) const
Attaches the given LLVM metadata to the imported operation if a conversion to one or more MLIR dialec...
bool isConvertibleMetadata(unsigned kind)
Returns true if the given LLVM IR metadata is convertible to an MLIR attribute.
bool isConvertibleInstruction(unsigned id)
Returns true if the given LLVM IR instruction is convertible to an MLIR operation.
bool isConvertibleIntrinsic(llvm::Intrinsic::ID id)
Returns true if the given LLVM IR intrinsic is convertible to an MLIR operation.
Module import implementation class that provides methods to import globals and functions from an LLVM...
LogicalResult convertIntrinsicArguments(ArrayRef< llvm::Value * > values, ArrayRef< llvm::OperandBundleUse > opBundles, bool requiresOpBundles, ArrayRef< unsigned > immArgPositions, ArrayRef< StringLiteral > immArgAttrNames, SmallVectorImpl< Value > &valuesOut, SmallVectorImpl< NamedAttribute > &attrsOut)
Converts the LLVM values for an intrinsic to mixed MLIR values and attributes for LLVM_IntrOpBase.
Location translateLoc(llvm::DILocation *loc)
Translates the debug location.
LogicalResult convertComdats()
Converts all comdat selectors of the LLVM module to MLIR comdat operations.
LogicalResult convertAliases()
Converts all aliases of the LLVM module to MLIR variables.
LogicalResult convertFunctions()
Converts all functions of the LLVM module to MLIR functions.
FailureOr< SmallVector< Value > > convertValues(ArrayRef< llvm::Value * > values)
Converts a range of LLVM values to a range of MLIR values using the convertValue method,...
DILocalVariableAttr matchLocalVariableAttr(llvm::Value *value)
Converts value to a local variable attribute.
LogicalResult convertLinkerOptionsMetadata()
Converts !llvm.linker.options metadata to the llvm.linker.options LLVM dialect operation.
void mapBlock(llvm::BasicBlock *llvm, Block *mlir)
Stores the mapping between an LLVM block and its MLIR counterpart.
void processFunctionAttributes(llvm::Function *func, LLVMFuncOp funcOp)
Converts function attributes of LLVM Function func into LLVM dialect attributes of LLVMFuncOp funcOp.
LogicalResult convertMetadata()
Converts all LLVM metadata nodes that translate to attributes such as alias analysis or access group ...
FailureOr< Value > convertValue(llvm::Value *value)
Converts an LLVM value to an MLIR value, or returns failure if the conversion fails.
LogicalResult initializeImportInterface()
Calls the LLVMImportInterface initialization that queries the registered dialect interfaces for the s...
void addDebugIntrinsic(llvm::CallInst *intrinsic)
Adds a debug intrinsics to the list of intrinsics that should be converted after the function convers...
LogicalResult convertIdentMetadata()
Converts !llvm.ident metadata to the llvm.ident LLVM ModuleOp attribute.
Block * lookupBlock(llvm::BasicBlock *block) const
Returns the MLIR block mapped to the given LLVM block.
FailureOr< Value > convertMetadataValue(llvm::Value *value)
Converts an LLVM metadata value to an MLIR value, or returns failure if the conversion fails.
FailureOr< SmallVector< AliasScopeAttr > > lookupAliasScopeAttrs(const llvm::MDNode *node) const
Returns the alias scope attributes that map to the alias scope nodes starting from the metadata node.
void setDisjointFlag(llvm::Instruction *inst, Operation *op) const
Sets the disjoint flag attribute for the imported operation op given the original instruction inst.
void mapNoResultOp(llvm::Instruction *llvm, Operation *mlir)
Stores a mapping between an LLVM instruction and the imported MLIR operation if the operation returns...
void setExactFlag(llvm::Instruction *inst, Operation *op) const
Sets the exact flag attribute for the imported operation op given the original instruction inst.
Type convertType(llvm::Type *type)
Converts the type from LLVM to MLIR LLVM dialect.
Operation * lookupOperation(llvm::Instruction *inst)
Returns the MLIR operation mapped to the given LLVM instruction.
DILabelAttr matchLabelAttr(llvm::Value *value)
Converts value to a label attribute. Asserts if the matching fails.
FloatAttr matchFloatAttr(llvm::Value *value)
Converts value to a float attribute. Asserts if the matching fails.
LoopAnnotationAttr translateLoopAnnotationAttr(const llvm::MDNode *node, Location loc) const
Returns the loop annotation attribute that corresponds to the given LLVM loop metadata node.
void setFastmathFlagsAttr(llvm::Instruction *inst, Operation *op) const
Sets the fastmath flags attribute for the imported operation op given the original instruction inst.
FailureOr< SmallVector< AliasScopeAttr > > matchAliasScopeAttrs(llvm::Value *value)
Converts value to an array of alias scopes or returns failure if the conversion fails.
Value lookupValue(llvm::Value *value)
Returns the MLIR value mapped to the given LLVM value.
LogicalResult processFunction(llvm::Function *func)
Imports func into the current module.
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 mapValue(llvm::Value *llvm, Value mlir)
Stores the mapping between an LLVM value and its MLIR counterpart.
ModuleImport(ModuleOp mlirModule, std::unique_ptr< llvm::Module > llvmModule, bool emitExpensiveWarnings, bool importEmptyDICompositeTypes)
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.
LogicalResult convertDataLayout()
Converts the data layout of the LLVM module to an MLIR data layout specification.
IntegerAttr matchIntegerAttr(llvm::Value *value)
Converts value to an integer attribute. Asserts if the matching fails.
Helper class that translates an LLVM data layout to an MLIR data layout specification.
StringRef getLastToken() const
Returns the last data layout token that has been processed before the data layout translation failed.
DataLayoutSpecInterface getDataLayout() const
Returns the MLIR data layout specification translated from the LLVM data layout.
ArrayRef< StringRef > getUnhandledTokens() const
Returns the data layout tokens that have not been handled during the data layout translation.
A helper class that converts llvm.loop metadata nodes into corresponding LoopAnnotationAttrs and llvm...
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
std::vector< StringRef > getAvailableDialects()
Return information about all available dialects in the registry in this context.
void loadAllAvailableDialects()
Load all dialects available in the registry in this context.
RAII guard to reset the insertion point of the builder when destroyed.
This class helps build Operations.
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
Block * createBlock(Region *parent, Region::iterator insertPt={}, TypeRange argTypes=std::nullopt, ArrayRef< Location > locs=std::nullopt)
Add new block with 'argTypes' arguments and set the insertion point to the end of it.
void setInsertionPointAfterValue(Value val)
Sets the insertion point to the node after the specified value.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
void setInsertionPointAfter(Operation *op)
Sets the insertion point to the node after the specified operation, which will cause subsequent inser...
Block * getInsertionBlock() const
Return the block the current insertion point belongs to.
This class provides the API for ops that are known to be terminators.
This provides public APIs that all operations should have.
Operation is the basic unit of execution within MLIR.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
OpTy get() const
Allow accessing the internal op.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
static DenseArrayAttrImpl get(MLIRContext *context, ArrayRef< int32_t > content)
Builder from ArrayRef<T>.
DominanceInfoNode * getNode(Block *a)
Return the dominance node from the Region containing block A.
static llvm::ArrayRef< std::pair< llvm::Attribute::AttrKind, llvm::StringRef > > getAttrKindToNameMapping()
Returns a list of pairs that each hold a mapping from LLVM attribute kinds to their corresponding str...
FloatType getFloatType(MLIRContext *context, unsigned width)
Returns a supported MLIR floating point type of the given bit width or null if the bit width is not s...
bool isCompatibleVectorType(Type type)
Returns true if the given type is a vector type compatible with the LLVM dialect.
llvm::ElementCount getVectorNumElements(Type type)
Returns the element count of any LLVM-compatible vector type.
Type getVectorElementType(Type type)
Returns the element type of any vector type compatible with the LLVM dialect.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Include the generated interface declarations.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
InFlightDiagnostic emitWarning(Location loc)
Utility method to emit a warning message using this location.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
OwningOpRef< ModuleOp > translateLLVMIRToModule(std::unique_ptr< llvm::Module > llvmModule, MLIRContext *context, bool emitExpensiveWarnings=true, bool dropDICompositeTypeElements=false, bool loadAllDialects=true)
Translates the LLVM module into an MLIR module living in the given context.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.