28 #include "llvm/ADT/PostOrderIterator.h"
29 #include "llvm/ADT/ScopeExit.h"
30 #include "llvm/ADT/StringSet.h"
31 #include "llvm/IR/Constants.h"
32 #include "llvm/IR/InlineAsm.h"
33 #include "llvm/IR/InstIterator.h"
34 #include "llvm/IR/Instructions.h"
35 #include "llvm/IR/IntrinsicInst.h"
36 #include "llvm/IR/Metadata.h"
37 #include "llvm/IR/Operator.h"
38 #include "llvm/Support/ModRef.h"
44 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
49 static std::string
diag(
const llvm::Value &value) {
51 llvm::raw_string_ostream os(str);
59 static std::string
diagMD(
const llvm::Metadata *node,
60 const llvm::Module *module) {
62 llvm::raw_string_ostream os(str);
63 node->print(os, module,
true);
69 return "llvm.global_ctors";
74 return "llvm.global_dtors";
80 return "__llvm_global_metadata";
108 std::optional<llvm::SyncScope::ID> syncScopeID =
109 llvm::getAtomicSyncScopeID(inst);
116 llvm::LLVMContext &llvmContext = inst->getContext();
117 llvmContext.getSyncScopeNames(syncScopeName);
118 auto *it = llvm::find_if(syncScopeName, [&](StringRef name) {
119 return *syncScopeID == llvmContext.getOrInsertSyncScopeID(name);
121 if (it != syncScopeName.end())
123 llvm_unreachable(
"incorrect sync scope identifier");
129 llvm::append_range(position, indices);
140 llvm::Instruction *inst,
147 #include "mlir/Dialect/LLVMIR/LLVMOpFromLLVMIRConversions.inc"
156 auto i32 = IntegerType::get(&ctx, 32);
158 StringRef abiString, preferredString;
159 std::tie(abiString, preferredString) = spec.split(
':');
161 if (abiString.getAsInteger(10, abi))
164 if (preferredString.empty())
166 else if (preferredString.getAsInteger(10, preferred))
174 DataLayoutSpecInterface
177 assert(context &&
"expected MLIR context");
178 std::string layoutstr = dataLayout.getStringRepresentation();
185 "p:64:64:64-S0-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f16:16:16-f64:"
186 "64:64-f128:128:128-v64:64:64-v128:128:128-a:0:64-A0";
187 if (layoutstr.empty())
190 layoutstr = layoutstr +
"-" + append;
192 StringRef layout(layoutstr);
196 while (!layout.empty()) {
198 std::pair<StringRef, StringRef> split = layout.split(
'-');
200 std::tie(current, layout) = split;
203 StringRef kind, spec;
204 std::tie(kind, spec) = current.split(
':');
205 if (seen.contains(kind))
209 char symbol = kind.front();
210 StringRef parameter = kind.substr(1);
212 if (symbol ==
'i' || symbol ==
'f') {
214 if (parameter.getAsInteger(10, bitwidth))
220 symbol ==
'i' ?
static_cast<Type>(IntegerType::get(context, bitwidth))
223 entries.emplace_back(entry);
224 }
else if (symbol ==
'e' || symbol ==
'E') {
225 auto value = StringAttr::get(
226 context, symbol ==
'e' ? DLTIDialect::kDataLayoutEndiannessLittle
227 : DLTIDialect::kDataLayoutEndiannessBig);
229 StringAttr::get(context, DLTIDialect::kDataLayoutEndiannessKey),
231 entries.emplace_back(entry);
232 }
else if (symbol ==
'A') {
233 unsigned addressSpace;
234 if (parameter.getAsInteger(10, addressSpace))
237 if (addressSpace != 0) {
239 StringAttr::get(context,
240 DLTIDialect::kDataLayoutAllocaMemorySpaceKey),
242 entries.emplace_back(entry);
254 for (llvm::BasicBlock &bb : *func) {
255 if (blocks.count(&bb) == 0) {
256 llvm::ReversePostOrderTraversal<llvm::BasicBlock *> traversal(&bb);
257 blocks.insert(traversal.begin(), traversal.end());
260 assert(blocks.size() == func->size() &&
"some blocks are not sorted");
266 std::unique_ptr<llvm::Module> llvmModule)
267 : builder(mlirModule->getContext()), context(mlirModule->getContext()),
268 mlirModule(mlirModule), llvmModule(std::move(llvmModule)),
269 iface(mlirModule->getContext()),
270 typeTranslator(*mlirModule->getContext()),
272 loopAnnotationImporter(
277 MetadataOp ModuleImport::getGlobalMetadataOp() {
278 if (globalMetadataOp)
279 return globalMetadataOp;
283 return globalMetadataOp = builder.
create<MetadataOp>(
287 LogicalResult ModuleImport::processTBAAMetadata(
const llvm::MDNode *node) {
291 workList.push_back(node);
292 while (!workList.empty()) {
293 const llvm::MDNode *current = workList.pop_back_val();
294 if (tbaaMapping.count(current))
298 if (!nodesToConvert.insert(current))
300 for (
const llvm::MDOperand &operand : current->operands())
301 if (
auto *opNode = dyn_cast_or_null<const llvm::MDNode>(operand.get()))
302 workList.push_back(opNode);
307 auto getIdentityIfRootNode =
308 [&](
const llvm::MDNode *node) -> std::optional<StringRef> {
311 if (node->getNumOperands() != 1)
314 if (
const auto *op0 = dyn_cast<const llvm::MDString>(node->getOperand(0)))
315 return op0->getString();
326 auto isTypeDescriptorNode =
327 [&](
const llvm::MDNode *node, StringRef *identity =
nullptr,
330 nullptr) -> std::optional<bool> {
331 unsigned numOperands = node->getNumOperands();
340 const auto *identityNode =
341 dyn_cast<const llvm::MDString>(node->getOperand(0));
347 *identity = identityNode->getString();
349 for (
unsigned pairNum = 0, e = numOperands / 2; pairNum < e; ++pairNum) {
350 const auto *memberNode =
351 dyn_cast<const llvm::MDNode>(node->getOperand(2 * pairNum + 1));
353 emitError(loc) <<
"operand '" << 2 * pairNum + 1 <<
"' must be MDNode: "
354 <<
diagMD(node, llvmModule.get());
358 if (2 * pairNum + 2 >= numOperands) {
360 if (numOperands != 2) {
361 emitError(loc) <<
"missing member offset: "
362 <<
diagMD(node, llvmModule.get());
366 auto *offsetCI = llvm::mdconst::dyn_extract<llvm::ConstantInt>(
367 node->getOperand(2 * pairNum + 2));
369 emitError(loc) <<
"operand '" << 2 * pairNum + 2
370 <<
"' must be ConstantInt: "
371 <<
diagMD(node, llvmModule.get());
374 offset = offsetCI->getZExtValue();
378 memberTypes->push_back(tbaaMapping.lookup(memberNode));
380 memberOffsets->push_back(offset);
394 [&](
const llvm::MDNode *node, SymbolRefAttr *baseSymRef =
nullptr,
395 SymbolRefAttr *accessSymRef =
nullptr, int64_t *offset =
nullptr,
396 bool *isConstant =
nullptr) -> std::optional<bool> {
404 unsigned numOperands = node->getNumOperands();
405 if (numOperands != 3 && numOperands != 4)
407 const auto *baseMD = dyn_cast<const llvm::MDNode>(node->getOperand(0));
408 const auto *accessMD = dyn_cast<const llvm::MDNode>(node->getOperand(1));
410 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(2));
411 if (!baseMD || !accessMD || !offsetCI)
418 if (accessMD->getNumOperands() < 1 ||
419 !isa<llvm::MDString>(accessMD->getOperand(0)))
421 bool isConst =
false;
422 if (numOperands == 4) {
424 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(3));
426 emitError(loc) <<
"operand '3' must be ConstantInt: "
427 <<
diagMD(node, llvmModule.get());
430 isConst = isConstantCI->getValue()[0];
433 *baseSymRef = tbaaMapping.lookup(baseMD);
435 *accessSymRef = tbaaMapping.lookup(accessMD);
437 *offset = offsetCI->getZExtValue();
439 *isConstant = isConst;
445 auto getUniqueSymbolName = [&](StringRef baseName) {
446 return (Twine(
"tbaa_") + Twine(baseName) + Twine(
'_') +
447 Twine(tbaaMapping.size()))
458 for (
const auto *current : nodesToConvert) {
459 if (std::optional<StringRef> identity = getIdentityIfRootNode(current)) {
460 if (identity.value().empty())
461 return emitError(loc) <<
"TBAA root node must have non-empty identity: "
462 <<
diagMD(current, llvmModule.get());
466 auto rootNode = builder.
create<TBAARootMetadataOp>(
467 loc, getUniqueSymbolName(
"root"), identity.value());
471 if (std::optional<bool> isValid = isTypeDescriptorNode(current)) {
472 if (!isValid.value())
474 tbaaMapping.try_emplace(
476 getUniqueSymbolName(
"type_desc")));
479 if (std::optional<bool> isValid = isTagNode(current)) {
480 if (!isValid.value())
484 tbaaMapping.try_emplace(
485 current, SymbolRefAttr::get(
488 getUniqueSymbolName(
"tag"))));
491 return emitError(loc) <<
"unsupported TBAA node format: "
492 <<
diagMD(current, llvmModule.get());
497 for (
const auto *current : nodesToConvert) {
501 if (std::optional<bool> isValid = isTypeDescriptorNode(
502 current, &identity, &memberTypes, &memberOffsets)) {
503 assert(isValid.value() &&
"type descriptor node must be valid");
505 builder.
create<TBAATypeDescriptorOp>(
506 loc, tbaaMapping.lookup(current).getLeafReference(),
511 SymbolRefAttr baseSymRef, accessSymRef;
514 if (std::optional<bool> isValid = isTagNode(
515 current, &baseSymRef, &accessSymRef, &offset, &isConstant)) {
516 assert(isValid.value() &&
"access tag node must be valid");
517 builder.
create<TBAATagOp>(
518 loc, tbaaMapping.lookup(current).getLeafReference(),
519 baseSymRef.getLeafReference(), accessSymRef.getLeafReference(),
529 ModuleImport::processAccessGroupMetadata(
const llvm::MDNode *node) {
531 if (
failed(loopAnnotationImporter->translateAccessGroup(
532 node, loc, getGlobalMetadataOp())))
533 return emitError(loc) <<
"unsupported access group node: "
534 <<
diagMD(node, llvmModule.get());
539 ModuleImport::processAliasScopeMetadata(
const llvm::MDNode *node) {
542 auto verifySelfRef = [](
const llvm::MDNode *node) {
543 return node->getNumOperands() != 0 &&
544 node == dyn_cast<llvm::MDNode>(node->getOperand(0));
547 auto verifyDescription = [](
const llvm::MDNode *node,
unsigned idx) {
548 return idx >= node->getNumOperands() ||
549 isa<llvm::MDString>(node->getOperand(idx));
552 auto createAliasScopeDomainOp = [&](
const llvm::MDNode *aliasDomain) {
553 StringAttr description =
nullptr;
554 if (aliasDomain->getNumOperands() >= 2)
555 if (
auto *operand = dyn_cast<llvm::MDString>(aliasDomain->getOperand(1)))
557 std::string name = llvm::formatv(
"domain_{0}", aliasScopeMapping.size());
558 return builder.
create<AliasScopeDomainMetadataOp>(loc, name, description);
562 for (
const llvm::MDOperand &operand : node->operands()) {
563 if (
const auto *scope = dyn_cast<llvm::MDNode>(operand)) {
564 llvm::AliasScopeNode aliasScope(scope);
565 const llvm::MDNode *domain = aliasScope.getDomain();
571 if (!verifySelfRef(scope) || !domain || !verifyDescription(scope, 2))
572 return emitError(loc) <<
"unsupported alias scope node: "
573 <<
diagMD(scope, llvmModule.get());
574 if (!verifySelfRef(domain) || !verifyDescription(domain, 1))
575 return emitError(loc) <<
"unsupported alias domain node: "
576 <<
diagMD(domain, llvmModule.get());
578 if (aliasScopeMapping.count(scope))
582 MetadataOp metadataOp = getGlobalMetadataOp();
583 StringAttr metadataOpName =
589 auto it = aliasScopeMapping.find(aliasScope.getDomain());
590 if (it == aliasScopeMapping.end()) {
591 auto aliasScopeDomainOp = createAliasScopeDomainOp(domain);
592 auto symbolRef = SymbolRefAttr::get(
595 aliasScopeDomainOp.getSymName()));
596 it = aliasScopeMapping.try_emplace(domain, symbolRef).first;
600 StringAttr description =
nullptr;
601 if (!aliasScope.getName().empty())
603 std::string name = llvm::formatv(
"scope_{0}", aliasScopeMapping.size());
604 auto aliasScopeOp = builder.
create<AliasScopeMetadataOp>(
605 loc, name, it->getSecond().getLeafReference().getValue(),
608 SymbolRefAttr::get(builder.
getContext(), metadataOpName,
610 aliasScopeOp.getSymName()));
611 aliasScopeMapping.try_emplace(aliasScope.getNode(), symbolRef);
620 aliasScopes.reserve(node->getNumOperands());
621 for (
const llvm::MDOperand &operand : node->operands()) {
622 auto *node = cast<llvm::MDNode>(operand.get());
623 aliasScopes.push_back(aliasScopeMapping.lookup(node));
626 if (llvm::is_contained(aliasScopes,
nullptr))
634 for (
const llvm::Function &func : llvmModule->functions()) {
635 for (
const llvm::Instruction &inst : llvm::instructions(func)) {
637 if (llvm::MDNode *node =
638 inst.getMetadata(llvm::LLVMContext::MD_access_group))
639 if (
failed(processAccessGroupMetadata(node)))
643 llvm::AAMDNodes aliasAnalysisNodes = inst.getAAMetadata();
644 if (!aliasAnalysisNodes)
646 if (aliasAnalysisNodes.TBAA)
647 if (
failed(processTBAAMetadata(aliasAnalysisNodes.TBAA)))
649 if (aliasAnalysisNodes.Scope)
650 if (
failed(processAliasScopeMetadata(aliasAnalysisNodes.Scope)))
652 if (aliasAnalysisNodes.NoAlias)
653 if (
failed(processAliasScopeMetadata(aliasAnalysisNodes.NoAlias)))
661 for (llvm::GlobalVariable &globalVar : llvmModule->globals()) {
664 if (
failed(convertGlobalCtorsAndDtors(&globalVar))) {
666 <<
"unhandled global variable: " <<
diag(globalVar);
670 if (
failed(convertGlobal(&globalVar))) {
672 <<
"unhandled global variable: " <<
diag(globalVar);
679 for (llvm::Function &func : llvmModule->functions())
685 void ModuleImport::setNonDebugMetadataAttrs(llvm::Instruction *inst,
688 inst->getAllMetadataOtherThanDebugLoc(allMetadata);
689 for (
auto &[kind, node] : allMetadata) {
693 Location loc = debugImporter->translateLoc(inst->getDebugLoc());
695 <<
diagMD(node, llvmModule.get()) <<
" on "
703 auto iface = cast<FastmathFlagsInterface>(op);
709 if (!isa<llvm::FPMathOperator>(inst))
711 llvm::FastMathFlags flags = inst->getFastMathFlags();
714 FastmathFlags value = {};
715 value = bitEnumSet(value, FastmathFlags::nnan, flags.noNaNs());
716 value = bitEnumSet(value, FastmathFlags::ninf, flags.noInfs());
717 value = bitEnumSet(value, FastmathFlags::nsz, flags.noSignedZeros());
718 value = bitEnumSet(value, FastmathFlags::arcp, flags.allowReciprocal());
720 value = bitEnumSet(value, FastmathFlags::afn, flags.approxFunc());
721 value = bitEnumSet(value, FastmathFlags::reassoc, flags.allowReassoc());
722 FastmathFlagsAttr attr = FastmathFlagsAttr::get(builder.
getContext(), value);
723 iface->setAttr(iface.getFastmathAttrName(), attr);
731 Type ModuleImport::getStdTypeForAttr(
Type type) {
741 if (numElements.isScalable()) {
742 emitError(UnknownLoc::get(context)) <<
"scalable vectors not supported";
748 return VectorType::get(numElements.getKnownMinValue(), elementType);
752 if (
auto arrayType = type.
dyn_cast<LLVMArrayType>()) {
755 shape.push_back(arrayType.getNumElements());
756 while (arrayType.getElementType().isa<LLVMArrayType>()) {
757 arrayType = arrayType.getElementType().cast<LLVMArrayType>();
758 shape.push_back(arrayType.getNumElements());
764 llvm::ElementCount numElements =
766 if (numElements.isScalable()) {
767 emitError(UnknownLoc::get(context)) <<
"scalable vectors not supported";
770 shape.push_back(numElements.getKnownMinValue());
772 Type elementType = getStdTypeForAttr(
776 return VectorType::get(shape, elementType);
780 Type elementType = getStdTypeForAttr(arrayType.getElementType());
783 return RankedTensorType::get(shape, elementType);
791 Attribute ModuleImport::getConstantAsAttr(llvm::Constant *value) {
792 if (
auto *ci = dyn_cast<llvm::ConstantInt>(value))
794 IntegerType::get(context, ci->getType()->getBitWidth()),
796 if (
auto *c = dyn_cast<llvm::ConstantDataArray>(value))
799 if (
auto *c = dyn_cast<llvm::ConstantFP>(value)) {
800 llvm::Type *type = c->getType();
802 if (type->isBFloatTy())
806 assert(floatTy &&
"unsupported floating point type");
809 if (
auto *f = dyn_cast<llvm::Function>(value))
810 return SymbolRefAttr::get(builder.
getContext(), f->getName());
813 if (
auto *cd = dyn_cast<llvm::ConstantDataSequential>(value)) {
815 auto attrType = getStdTypeForAttr(
convertType(cd->getType()))
820 if (type.
isa<IntegerType>()) {
822 values.reserve(cd->getNumElements());
823 for (
unsigned i = 0, e = cd->getNumElements(); i < e; ++i)
824 values.push_back(cd->getElementAsAPInt(i));
828 if (type.
isa<Float32Type, Float64Type>()) {
830 values.reserve(cd->getNumElements());
831 for (
unsigned i = 0, e = cd->getNumElements(); i < e; ++i)
832 values.push_back(cd->getElementAsAPFloat(i));
841 if (isa<llvm::ConstantAggregate>(value)) {
842 auto outerType = getStdTypeForAttr(
convertType(value->getType()))
850 for (
unsigned i = 0, e = value->getNumOperands(); i < e; ++i) {
851 auto nested = getConstantAsAttr(value->getAggregateElement(i))
856 values.append(nested.value_begin<
Attribute>(),
866 LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
869 if (!globalInsertionOp)
875 if (globalVar->hasInitializer())
876 valueAttr = getConstantAsAttr(globalVar->getInitializer());
879 uint64_t alignment = 0;
880 llvm::MaybeAlign maybeAlign = globalVar->getAlign();
881 if (maybeAlign.has_value()) {
882 llvm::Align align = *maybeAlign;
883 alignment = align.value();
886 GlobalOp globalOp = builder.
create<GlobalOp>(
887 mlirModule.getLoc(), type, globalVar->isConstant(),
888 convertLinkageFromLLVM(globalVar->getLinkage()), globalVar->getName(),
889 valueAttr, alignment, globalVar->getAddressSpace(),
890 globalVar->isDSOLocal(),
891 globalVar->isThreadLocal());
892 globalInsertionOp = globalOp;
894 if (globalVar->hasInitializer() && !valueAttr) {
895 clearBlockAndValueMapping();
897 setConstantInsertionPointToStart(block);
899 convertConstantExpr(globalVar->getInitializer());
902 builder.
create<ReturnOp>(globalOp.getLoc(), *initializer);
904 if (globalVar->hasAtLeastLocalUnnamedAddr()) {
905 globalOp.setUnnamedAddr(
906 convertUnnamedAddrFromLLVM(globalVar->getUnnamedAddr()));
908 if (globalVar->hasSection())
909 globalOp.setSection(globalVar->getSection());
910 globalOp.setVisibility_(
911 convertVisibilityFromLLVM(globalVar->getVisibility()));
917 ModuleImport::convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar) {
918 if (!globalVar->hasInitializer() || !globalVar->hasAppendingLinkage())
921 dyn_cast<llvm::ConstantArray>(globalVar->getInitializer());
927 for (llvm::Value *operand : initializer->operands()) {
928 auto *aggregate = dyn_cast<llvm::ConstantAggregate>(operand);
929 if (!aggregate || aggregate->getNumOperands() != 3)
932 auto *priority = dyn_cast<llvm::ConstantInt>(aggregate->getOperand(0));
933 auto *func = dyn_cast<llvm::Function>(aggregate->getOperand(1));
934 auto *data = dyn_cast<llvm::Constant>(aggregate->getOperand(2));
935 if (!priority || !func || !data)
939 if (!data->isNullValue())
943 priorities.push_back(priority->getValue().getZExtValue());
947 if (!globalInsertionOp)
953 globalInsertionOp = builder.
create<LLVM::GlobalCtorsOp>(
958 globalInsertionOp = builder.
create<LLVM::GlobalDtorsOp>(
965 ModuleImport::getConstantsToConvert(llvm::Constant *constant) {
967 if (valueMapping.count(constant))
976 workList.insert(constant);
977 while (!workList.empty()) {
978 llvm::Constant *current = workList.back();
981 auto adjacencyIt = adjacencyLists.find(current);
982 if (adjacencyIt == adjacencyLists.end()) {
983 adjacencyIt = adjacencyLists.try_emplace(current).first;
986 for (llvm::Value *operand : current->operands())
987 if (
auto *constDependency = dyn_cast<llvm::Constant>(operand))
988 adjacencyIt->getSecond().push_back(constDependency);
991 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(current)) {
992 unsigned numElements = constAgg->getElementCount().getFixedValue();
993 for (
unsigned i = 0, e = numElements; i != e; ++i)
994 adjacencyIt->getSecond().push_back(constAgg->getElementValue(i));
1000 if (adjacencyIt->getSecond().empty()) {
1001 orderedSet.insert(current);
1002 workList.pop_back();
1010 llvm::Constant *dependency = adjacencyIt->getSecond().pop_back_val();
1011 if (valueMapping.count(dependency) || workList.count(dependency) ||
1012 orderedSet.count(dependency))
1014 workList.insert(dependency);
1021 Location loc = mlirModule.getLoc();
1024 if (
Attribute attr = getConstantAsAttr(constant)) {
1027 return builder.
create<AddressOfOp>(loc, type, symbolRef.getValue())
1030 return builder.
create<ConstantOp>(loc, type, attr).getResult();
1034 if (
auto *nullPtr = dyn_cast<llvm::ConstantPointerNull>(constant)) {
1036 return builder.
create<NullOp>(loc, type).getResult();
1040 if (
auto *poisonVal = dyn_cast<llvm::PoisonValue>(constant)) {
1042 return builder.
create<PoisonOp>(loc, type).getResult();
1046 if (
auto *undefVal = dyn_cast<llvm::UndefValue>(constant)) {
1048 return builder.
create<UndefOp>(loc, type).getResult();
1052 if (
auto *globalVar = dyn_cast<llvm::GlobalVariable>(constant)) {
1055 return builder.
create<AddressOfOp>(loc, type, symbolRef).getResult();
1059 if (
auto *constExpr = dyn_cast<llvm::ConstantExpr>(constant)) {
1065 llvm::Instruction *inst = constExpr->getAsInstruction();
1066 auto guard = llvm::make_scope_exit([&]() {
1067 assert(!noResultOpMapping.contains(inst) &&
1068 "expected constant expression to return a result");
1069 valueMapping.erase(inst);
1070 inst->deleteValue();
1074 assert(llvm::all_of(inst->operands(), [&](llvm::Value *value) {
1075 return valueMapping.count(value);
1077 if (
failed(processInstruction(inst)))
1083 if (isa<llvm::ConstantAggregate>(constant) ||
1084 isa<llvm::ConstantAggregateZero>(constant)) {
1087 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregate>(constant)) {
1088 elementValues.reserve(constAgg->getNumOperands());
1089 for (llvm::Value *operand : constAgg->operands())
1092 if (
auto *constAgg = dyn_cast<llvm::ConstantAggregateZero>(constant)) {
1093 unsigned numElements = constAgg->getElementCount().getFixedValue();
1094 elementValues.reserve(numElements);
1095 for (
unsigned i = 0, e = numElements; i != e; ++i)
1096 elementValues.push_back(
lookupValue(constAgg->getElementValue(i)));
1098 assert(llvm::count(elementValues,
nullptr) == 0 &&
1099 "expected all elements have been converted before");
1105 "unrecognized aggregate type");
1106 Value root = builder.
create<UndefOp>(loc, rootType);
1108 if (isArrayOrStruct) {
1109 root = builder.
create<InsertValueOp>(loc, root, it.value(), it.index());
1114 root = builder.
create<InsertElementOp>(loc, rootType, root, it.value(),
1121 if (isa<llvm::BlockAddress>(constant)) {
1123 <<
"blockaddress is not implemented in the LLVM dialect";
1126 return emitError(loc) <<
"unhandled constant: " <<
diag(*constant);
1129 FailureOr<Value> ModuleImport::convertConstantExpr(llvm::Constant *constant) {
1130 assert(constantInsertionBlock &&
1131 "expected the constant insertion block to be non-null");
1135 if (!constantInsertionOp)
1142 getConstantsToConvert(constant);
1143 for (llvm::Constant *constantToConvert : constantsToConvert) {
1147 mapValue(constantToConvert, *converted);
1157 assert(!isa<llvm::MetadataAsValue>(value) &&
1158 "expected value to not be metadata");
1161 if (valueMapping.count(value))
1165 if (
auto *constant = dyn_cast<llvm::Constant>(value))
1166 return convertConstantExpr(constant);
1168 Location loc = mlirModule.getLoc();
1169 if (
auto *inst = dyn_cast<llvm::Instruction>(value))
1171 return emitError(loc) <<
"unhandled value: " <<
diag(*value);
1177 auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
1180 auto *node = dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
1183 value = node->getValue();
1186 if (valueMapping.count(value))
1190 if (
auto *constant = dyn_cast<llvm::Constant>(value))
1191 return convertConstantExpr(constant);
1198 remapped.reserve(values.size());
1199 for (llvm::Value *value : values) {
1203 remapped.push_back(*converted);
1209 IntegerAttr integerAttr;
1213 assert(
success &&
"expected a constant value");
1219 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1220 auto *node = cast<llvm::DILocalVariable>(nodeAsVal->getMetadata());
1221 return debugImporter->translate(node);
1226 auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
1227 auto *node = cast<llvm::MDNode>(nodeAsVal->getMetadata());
1232 return debugImporter->translateLoc(loc);
1236 ModuleImport::convertBranchArgs(llvm::Instruction *branch,
1237 llvm::BasicBlock *target,
1239 for (
auto inst = target->begin(); isa<llvm::PHINode>(inst); ++inst) {
1240 auto *phiInst = cast<llvm::PHINode>(&*inst);
1241 llvm::Value *value = phiInst->getIncomingValueForBlock(branch->getParent());
1245 blockArguments.push_back(*converted);
1251 ModuleImport::convertCallTypeAndOperands(llvm::CallBase *callInst,
1254 if (!callInst->getType()->isVoidTy())
1255 types.push_back(
convertType(callInst->getType()));
1257 if (!callInst->getCalledFunction()) {
1261 operands.push_back(*called);
1267 llvm::append_range(operands, *arguments);
1271 LogicalResult ModuleImport::convertIntrinsic(llvm::CallInst *inst) {
1276 return emitError(loc) <<
"unhandled intrinsic: " <<
diag(*inst);
1279 LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
1282 if (inst->getOpcode() == llvm::Instruction::Br) {
1283 auto *brInst = cast<llvm::BranchInst>(inst);
1287 for (
auto i : llvm::seq<unsigned>(0, brInst->getNumSuccessors())) {
1288 llvm::BasicBlock *succ = brInst->getSuccessor(i);
1290 if (
failed(convertBranchArgs(brInst, succ, blockArgs)))
1293 succBlockArgs.push_back(blockArgs);
1296 if (!brInst->isConditional()) {
1297 auto brOp = builder.
create<LLVM::BrOp>(loc, succBlockArgs.front(),
1298 succBlocks.front());
1305 auto condBrOp = builder.
create<LLVM::CondBrOp>(
1306 loc, *condition, succBlocks.front(), succBlockArgs.front(),
1307 succBlocks.back(), succBlockArgs.back());
1311 if (inst->getOpcode() == llvm::Instruction::Switch) {
1312 auto *swInst = cast<llvm::SwitchInst>(inst);
1319 llvm::BasicBlock *defaultBB = swInst->getDefaultDest();
1320 if (
failed(convertBranchArgs(swInst, defaultBB, defaultBlockArgs)))
1324 unsigned numCases = swInst->getNumCases();
1330 const llvm::SwitchInst::CaseHandle &caseHandle = it.value();
1331 llvm::BasicBlock *succBB = caseHandle.getCaseSuccessor();
1332 if (
failed(convertBranchArgs(swInst, succBB, caseOperands[it.index()])))
1334 caseOperandRefs[it.index()] = caseOperands[it.index()];
1335 caseValues[it.index()] = caseHandle.getCaseValue()->getSExtValue();
1339 auto switchOp = builder.
create<SwitchOp>(
1340 loc, *condition,
lookupBlock(defaultBB), defaultBlockArgs, caseValues,
1341 caseBlocks, caseOperandRefs);
1345 if (inst->getOpcode() == llvm::Instruction::PHI) {
1351 if (inst->getOpcode() == llvm::Instruction::Call) {
1352 auto *callInst = cast<llvm::CallInst>(inst);
1356 if (
failed(convertCallTypeAndOperands(callInst, types, operands)))
1360 if (llvm::Function *callee = callInst->getCalledFunction()) {
1361 callOp = builder.
create<CallOp>(
1362 loc, types, SymbolRefAttr::get(context, callee->getName()), operands);
1364 callOp = builder.
create<CallOp>(loc, types, operands);
1367 if (!callInst->getType()->isVoidTy())
1368 mapValue(inst, callOp.getResult());
1373 if (inst->getOpcode() == llvm::Instruction::LandingPad) {
1374 auto *lpInst = cast<llvm::LandingPadInst>(inst);
1377 operands.reserve(lpInst->getNumClauses());
1378 for (
auto i : llvm::seq<unsigned>(0, lpInst->getNumClauses())) {
1382 operands.push_back(*operand);
1387 builder.
create<LandingpadOp>(loc, type, lpInst->isCleanup(), operands);
1391 if (inst->getOpcode() == llvm::Instruction::Invoke) {
1392 auto *invokeInst = cast<llvm::InvokeInst>(inst);
1396 if (
failed(convertCallTypeAndOperands(invokeInst, types, operands)))
1400 (void)convertBranchArgs(invokeInst, invokeInst->getNormalDest(),
1402 (void)convertBranchArgs(invokeInst, invokeInst->getUnwindDest(),
1406 if (llvm::Function *callee = invokeInst->getCalledFunction()) {
1407 invokeOp = builder.
create<InvokeOp>(
1409 SymbolRefAttr::get(builder.
getContext(), callee->getName()), operands,
1410 lookupBlock(invokeInst->getNormalDest()), normalArgs,
1411 lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
1413 invokeOp = builder.
create<InvokeOp>(
1414 loc, types, operands,
lookupBlock(invokeInst->getNormalDest()),
1415 normalArgs,
lookupBlock(invokeInst->getUnwindDest()), unwindArgs);
1417 if (!invokeInst->getType()->isVoidTy())
1418 mapValue(inst, invokeOp.getResults().front());
1423 if (inst->getOpcode() == llvm::Instruction::GetElementPtr) {
1424 auto *gepInst = cast<llvm::GetElementPtrInst>(inst);
1425 Type sourceElementType =
convertType(gepInst->getSourceElementType());
1435 for (llvm::Value *operand : llvm::drop_begin(gepInst->operand_values())) {
1439 indices.push_back(*index);
1443 auto gepOp = builder.
create<GEPOp>(loc, type, sourceElementType, *basePtr,
1444 indices, gepInst->isInBounds());
1453 return emitError(loc) <<
"unhandled instruction: " <<
diag(*inst);
1456 LogicalResult ModuleImport::processInstruction(llvm::Instruction *inst) {
1463 if (
auto *callInst = dyn_cast<llvm::CallInst>(inst)) {
1464 llvm::Function *callee = callInst->getCalledFunction();
1465 if (callee && callee->isIntrinsic())
1466 return convertIntrinsic(callInst);
1470 return convertInstruction(inst);
1474 if (!f->hasPersonalityFn())
1477 llvm::Constant *pf = f->getPersonalityFn();
1481 return SymbolRefAttr::get(builder.
getContext(), pf->getName());
1485 if (
auto *ce = dyn_cast<llvm::ConstantExpr>(pf)) {
1486 if (ce->getOpcode() == llvm::Instruction::BitCast &&
1487 ce->getType() == llvm::Type::getInt8PtrTy(f->getContext())) {
1488 if (
auto *func = dyn_cast<llvm::Function>(ce->getOperand(0)))
1489 return SymbolRefAttr::get(builder.
getContext(), func->getName());
1496 llvm::MemoryEffects memEffects = func->getMemoryEffects();
1498 auto othermem = convertModRefInfoFromLLVM(
1499 memEffects.getModRef(llvm::MemoryEffects::Location::Other));
1500 auto argMem = convertModRefInfoFromLLVM(
1501 memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
1502 auto inaccessibleMem = convertModRefInfoFromLLVM(
1503 memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
1504 auto memAttr = MemoryEffectsAttr::get(funcOp.getContext(), othermem, argMem,
1507 if (memAttr.isReadWrite())
1509 funcOp.setMemoryAttr(memAttr);
1515 llvm::AttributeSet funcAttrs = func->getAttributes().getAttributes(
1516 llvm::AttributeList::AttrIndex::FunctionIndex);
1517 for (llvm::Attribute attr : funcAttrs) {
1520 if (attr.hasAttribute(llvm::Attribute::Memory))
1524 if (attr.isTypeAttribute()) {
1526 "type attributes on a function are invalid, skipping it");
1531 if (attr.isStringAttribute())
1532 attrName = attr.getKindAsString();
1534 attrName = llvm::Attribute::getNameFromAttrKind(attr.getKindAsEnum());
1535 auto keyAttr = StringAttr::get(context, attrName);
1537 if (attr.isStringAttribute()) {
1538 StringRef val = attr.getValueAsString();
1540 passthroughs.push_back(keyAttr);
1543 passthroughs.push_back(
1544 ArrayAttr::get(context, {keyAttr, StringAttr::get(context, val)}));
1547 if (attr.isIntAttribute()) {
1548 auto val = std::to_string(attr.getValueAsInt());
1549 passthroughs.push_back(
1550 ArrayAttr::get(context, {keyAttr, StringAttr::get(context, val)}));
1553 if (attr.isEnumAttribute()) {
1554 passthroughs.push_back(keyAttr);
1558 llvm_unreachable(
"unexpected attribute kind");
1561 if (!passthroughs.empty())
1562 funcOp.setPassthroughAttr(ArrayAttr::get(context, passthroughs));
1566 LLVMFuncOp funcOp) {
1572 ModuleImport::convertParameterAttribute(llvm::AttributeSet llvmParamAttrs,
1576 auto llvmAttr = llvmParamAttrs.getAttribute(llvmKind);
1578 if (!llvmAttr.isValid())
1581 if (llvmAttr.isTypeAttribute())
1582 mlirAttr = TypeAttr::get(
convertType(llvmAttr.getValueAsType()));
1583 else if (llvmAttr.isIntAttribute())
1585 else if (llvmAttr.isEnumAttribute())
1588 llvm_unreachable(
"unexpected parameter attribute kind");
1589 paramAttrs.push_back(builder.
getNamedAttr(mlirName, mlirAttr));
1595 void ModuleImport::convertParameterAttributes(llvm::Function *func,
1598 auto llvmAttrs = func->getAttributes();
1599 for (
size_t i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
1600 llvm::AttributeSet llvmArgAttrs = llvmAttrs.getParamAttrs(i);
1601 funcOp.setArgAttrs(i, convertParameterAttribute(llvmArgAttrs, builder));
1605 llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
1606 funcOp.setResAttrsAttr(
1607 builder.
getArrayAttr(convertParameterAttribute(llvmResAttr, builder)));
1611 clearBlockAndValueMapping();
1615 if (func->isIntrinsic() &&
1619 bool dsoLocal = func->hasLocalLinkage();
1620 CConv cconv = convertCConvFromLLVM(func->getCallingConv());
1626 LLVMFuncOp funcOp = builder.
create<LLVMFuncOp>(
1627 mlirModule.getLoc(), func->getName(), functionType,
1628 convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv);
1631 debugImporter->translate(func, funcOp);
1633 convertParameterAttributes(func, funcOp, builder);
1636 funcOp.setPersonalityAttr(personality);
1637 else if (func->hasPersonalityFn())
1638 emitWarning(funcOp.getLoc(),
"could not deduce personality, skipping it");
1641 funcOp.setGarbageCollector(StringRef(func->getGC()));
1643 funcOp.setVisibility_(convertVisibilityFromLLVM(func->getVisibility()));
1650 func->getAllMetadata(allMetadata);
1651 for (
auto &[kind, node] : allMetadata) {
1656 <<
"unhandled function metadata: " <<
diagMD(node, llvmModule.get())
1657 <<
" on " <<
diag(*func);
1661 if (func->isDeclaration())
1665 for (llvm::BasicBlock &bb : *func) {
1667 builder.
createBlock(&funcOp.getBody(), funcOp.getBody().end());
1673 BlockArgument blockArg = funcOp.getFunctionBody().addArgument(
1674 functionType.getParamType(it.index()), funcOp.getLoc());
1682 setConstantInsertionPointToStart(
lookupBlock(blocks.front()));
1683 for (llvm::BasicBlock *bb : blocks) {
1691 LogicalResult ModuleImport::processBasicBlock(llvm::BasicBlock *bb,
1694 for (llvm::Instruction &inst : *bb) {
1695 if (
failed(processInstruction(&inst)))
1702 setNonDebugMetadataAttrs(&inst, op);
1703 }
else if (inst.getOpcode() != llvm::Instruction::PHI) {
1704 Location loc = debugImporter->translateLoc(inst.getDebugLoc());
1713 return loopAnnotationImporter->lookupAccessGroupAttrs(node);
1719 return loopAnnotationImporter->translateLoopAnnotation(node, loc);
1731 LLVMDialect::getDialectNamespace()));
1733 DLTIDialect::getDialectNamespace()));
1737 StringAttr::get(context, llvmModule->getSourceFileName()), 0,
1740 DataLayoutSpecInterface dlSpec =
1743 emitError(UnknownLoc::get(context),
"can't translate data layout");
1746 module.
get()->setAttr(DLTIDialect::kDataLayoutAttrName, dlSpec);
static SmallVector< int64_t > getPositionFromIndices(ArrayRef< unsigned > indices)
Converts an array of unsigned indices to a signed integer position array.
static StringRef getLLVMSyncScope(llvm::Instruction *inst)
Converts the sync scope identifier of inst to the string representation necessary to build an atomic ...
static std::string diag(const llvm::Value &value)
static void processPassthroughAttrs(llvm::Function *func, LLVMFuncOp funcOp)
static void processMemoryEffects(llvm::Function *func, LLVMFuncOp funcOp)
static FloatType getDLFloatType(MLIRContext &ctx, int32_t bitwidth)
Returns a supported MLIR floating point type of the given bit width or null if the bit width is not s...
static constexpr StringRef getGlobalMetadataOpName()
Returns the symbol name for the module-level metadata operation.
static constexpr StringRef getGlobalDtorsVarName()
Returns the name of the global_dtors global variables.
static DenseIntElementsAttr parseDataLayoutAlignment(MLIRContext &ctx, StringRef spec)
Creates an attribute containing ABI and preferred alignment numbers parsed a string.
static LogicalResult convertInstructionImpl(OpBuilder &odsBuilder, llvm::Instruction *inst, ModuleImport &moduleImport)
Converts the LLVM instructions that have a generated MLIR builder.
static constexpr StringRef getGlobalCtorsVarName()
Returns the name of the global_ctors global variables.
static std::string diagMD(const llvm::Metadata *node, const llvm::Module *module)
static SetVector< llvm::BasicBlock * > getTopologicallySortedBlocks(llvm::Function *func)
Get a topologically sorted list of blocks for the given function.
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.
U dyn_cast_or_null() const
This class represents an argument of a Block.
Block represents an ordered list of Operations.
BlockArgument addArgument(Type type, Location loc)
Add one value to the argument list.
This class is a general helper class for creating context-global objects like types,...
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)
MLIRContext * getContext() const
ArrayAttr getArrayAttr(ArrayRef< Attribute > value)
DictionaryAttr getDictionaryAttr(ArrayRef< NamedAttribute > value)
NamedAttribute getNamedAttr(StringRef name, Attribute val)
static DataLayoutEntryAttr get(StringAttr key, Attribute value)
Returns the entry with the given key and value.
static DataLayoutSpecAttr get(MLIRContext *ctx, ArrayRef< DataLayoutEntryInterface > entries)
Returns the specification containing the given list of keys.
An attribute that represents a reference to a dense vector or tensor object.
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
An attribute that represents a reference to a dense integer vector or tensor object.
static DenseIntElementsAttr get(const ShapedType &type, Arg &&arg)
Get an instance of a DenseIntElementsAttr with the given arguments.
This class provides support for representing a failure result, or a valid value of type T.
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.
static FloatType getF64(MLIRContext *ctx)
static FloatType getF80(MLIRContext *ctx)
static FloatType getF16(MLIRContext *ctx)
static FloatType getBF16(MLIRContext *ctx)
static FloatType getF128(MLIRContext *ctx)
static FloatType getF32(MLIRContext *ctx)
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 isConvertibleIntrinsic(llvm::Intrinsic::ID id)
Returns true if the given LLVM IR intrinsic is convertible to an MLIR operation.
LLVM dialect structure type representing a collection of different-typed elements manipulated togethe...
Module import implementation class that provides methods to import globals and functions from an LLVM...
Location translateLoc(llvm::DILocation *loc)
Translates the debug location.
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.
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 operations nested in a global metadata operation,...
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...
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.
void mapNoResultOp(llvm::Instruction *llvm, Operation *mlir)
Stores a mapping between an LLVM instruction and the imported MLIR operation if the operation returns...
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.
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< SymbolRefAttr > > lookupAccessGroupAttrs(const llvm::MDNode *node) const
Returns the symbol references pointing to the access group operations that map to the access group no...
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.
ModuleImport(ModuleOp mlirModule, std::unique_ptr< llvm::Module > llvmModule)
void mapValue(llvm::Value *llvm, Value mlir)
Stores the mapping between an LLVM value and its MLIR counterpart.
FailureOr< SmallVector< SymbolRefAttr > > matchAliasScopeAttrs(llvm::Value *value)
Converts value to an array of symbol references pointing to alias scope operations,...
LogicalResult convertGlobals()
Converts all global variables of the LLVM module to MLIR global variables.
FailureOr< SmallVector< SymbolRefAttr > > lookupAliasScopeAttrs(const llvm::MDNode *node) const
Returns the symbol references pointing to the alias scope operations that map to the alias scope node...
IntegerAttr matchIntegerAttr(llvm::Value *value)
Converts value to an integer attribute. Asserts if the matching fails.
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.
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.
Operation is the basic unit of execution within MLIR.
OpTy get() const
Allow accessing the internal op.
static StringAttr getSymbolName(Operation *symbol)
Returns the name of the given symbol operation, aborting if no symbol is present.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
U dyn_cast_or_null() const
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 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...
SetVector< Block * > getTopologicallySortedBlocks(Region ®ion)
Get a topologically sorted list of blocks of the given region.
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)
This header declares functions that assit transformations in the MemRef dialect.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
InFlightDiagnostic emitWarning(Location loc)
Utility method to emit a warning message using this location.
DataLayoutSpecInterface translateDataLayout(const llvm::DataLayout &dataLayout, MLIRContext *context)
Translate the given LLVM data layout into an MLIR equivalent using the DLTI dialect.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
OwningOpRef< ModuleOp > translateLLVMIRToModule(std::unique_ptr< llvm::Module > llvmModule, MLIRContext *context)
Translates the LLVM module into an MLIR module living in the given context.
This class represents an efficient way to signal success or failure.