509 bool hasVectorElementType = isa<VectorType>(type.getElementType());
511 numElements / (hasVectorElementType
513 : denseResourceAttr.getType().
getShape().back());
515 if (!hasVectorElementType)
516 outerShape = outerShape.drop_back();
519 std::function<llvm::Constant *(StringRef)> buildCstData;
520 if (isa<TensorType>(type)) {
521 auto vectorElementType = dyn_cast<VectorType>(type.getElementType());
522 if (vectorElementType && vectorElementType.getRank() == 1) {
523 buildCstData = [&](StringRef data) {
524 return llvm::ConstantDataVector::getRaw(
525 data, vectorElementType.getShape().back(), innermostLLVMType);
527 }
else if (!vectorElementType) {
528 buildCstData = [&](StringRef data) {
529 return llvm::ConstantDataArray::getRaw(data, type.getShape().back(),
533 }
else if (isa<VectorType>(type)) {
534 buildCstData = [&](StringRef data) {
535 return llvm::ConstantDataVector::getRaw(data, type.getShape().back(),
540 emitError(loc,
"unsupported dense_resource type");
546 SmallVector<llvm::Constant *> constants;
547 int64_t aggregateSize = denseResourceAttr.getType().getShape().back() *
548 (innermostLLVMType->getScalarSizeInBits() / 8);
549 constants.reserve(numAggregates);
550 for (
unsigned i = 0; i < numAggregates; ++i) {
551 StringRef data(rawData.data() + i * aggregateSize, aggregateSize);
552 constants.push_back(buildCstData(data));
555 ArrayRef<llvm::Constant *> constantsRef = constants;
567 if (!attr || isa<UndefAttr>(attr))
568 return llvm::UndefValue::get(llvmType);
569 if (isa<ZeroAttr>(attr))
570 return llvm::Constant::getNullValue(llvmType);
571 if (
auto *structType = dyn_cast<::llvm::StructType>(llvmType)) {
572 auto arrayAttr = dyn_cast<ArrayAttr>(attr);
574 emitError(loc,
"expected an array attribute for a struct constant");
578 structElements.reserve(structType->getNumElements());
579 for (
auto [elemType, elemAttr] :
580 zip_equal(structType->elements(), arrayAttr)) {
581 llvm::Constant *element =
585 structElements.push_back(element);
587 return llvm::ConstantStruct::get(structType, structElements);
591 if (
auto intAttr = dyn_cast<IntegerAttr>(attr))
592 return llvm::ConstantInt::get(
594 intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth()));
595 if (
auto floatAttr = dyn_cast<FloatAttr>(attr)) {
596 const llvm::fltSemantics &sem = floatAttr.getValue().getSemantics();
601 unsigned floatWidth = APFloat::getSizeInBits(sem);
602 if (llvmType->isIntegerTy(floatWidth))
603 return llvm::ConstantInt::get(llvmType,
604 floatAttr.getValue().bitcastToAPInt());
606 llvm::Type::getFloatingPointTy(llvmType->getContext(),
607 floatAttr.getValue().getSemantics())) {
608 emitError(loc,
"FloatAttr does not match expected type of the constant");
611 return llvm::ConstantFP::get(llvmType, floatAttr.getValue());
613 if (
auto funcAttr = dyn_cast<FlatSymbolRefAttr>(attr))
614 return llvm::ConstantExpr::getBitCast(
616 if (
auto splatAttr = dyn_cast<SplatElementsAttr>(attr)) {
617 llvm::Type *elementType;
618 uint64_t numElements;
619 bool isScalable =
false;
620 if (
auto *arrayTy = dyn_cast<llvm::ArrayType>(llvmType)) {
621 elementType = arrayTy->getElementType();
622 numElements = arrayTy->getNumElements();
623 }
else if (
auto *fVectorTy = dyn_cast<llvm::FixedVectorType>(llvmType)) {
624 elementType = fVectorTy->getElementType();
625 numElements = fVectorTy->getNumElements();
626 }
else if (
auto *sVectorTy = dyn_cast<llvm::ScalableVectorType>(llvmType)) {
627 elementType = sVectorTy->getElementType();
628 numElements = sVectorTy->getMinNumElements();
631 llvm_unreachable(
"unrecognized constant vector type");
636 bool elementTypeSequential =
637 isa<llvm::ArrayType, llvm::VectorType>(elementType);
640 elementTypeSequential ? splatAttr
642 loc, moduleTranslation);
645 if (llvmType->isVectorTy())
646 return llvm::ConstantVector::getSplat(
647 llvm::ElementCount::get(numElements, isScalable), child);
648 if (llvmType->isArrayTy()) {
649 auto *arrayType = llvm::ArrayType::get(elementType, numElements);
650 if (child->isZeroValue() && !elementType->isFPOrFPVectorTy()) {
651 return llvm::ConstantAggregateZero::get(arrayType);
653 if (llvm::ConstantDataSequential::isElementTypeCompatible(elementType)) {
655 if (isa<llvm::IntegerType>(elementType)) {
656 if (llvm::ConstantInt *ci = dyn_cast<llvm::ConstantInt>(child)) {
657 if (ci->getBitWidth() == 8) {
659 return llvm::ConstantDataArray::get(elementType->getContext(),
662 if (ci->getBitWidth() == 16) {
664 return llvm::ConstantDataArray::get(elementType->getContext(),
667 if (ci->getBitWidth() == 32) {
669 return llvm::ConstantDataArray::get(elementType->getContext(),
672 if (ci->getBitWidth() == 64) {
674 return llvm::ConstantDataArray::get(elementType->getContext(),
682 std::vector<llvm::Constant *> constants(numElements, child);
683 return llvm::ConstantArray::get(arrayType, constants);
688 if (llvm::Constant *
result =
690 llvmType, moduleTranslation)) {
694 if (
auto denseResourceAttr = dyn_cast<DenseResourceElementsAttr>(attr)) {
700 if (
auto elementsAttr = dyn_cast<ElementsAttr>(attr)) {
701 assert(elementsAttr.getShapedType().hasStaticShape());
702 assert(!elementsAttr.getShapedType().getShape().empty() &&
703 "unexpected empty elements attribute shape");
706 constants.reserve(elementsAttr.getNumElements());
708 for (
auto n : elementsAttr.getValues<
Attribute>()) {
711 if (!constants.back())
716 constantsRef, elementsAttr.getShapedType().getShape(), llvmType, loc);
717 assert(constantsRef.empty() &&
"did not consume all elemental constants");
721 if (
auto stringAttr = dyn_cast<StringAttr>(attr)) {
722 return llvm::ConstantDataArray::get(moduleTranslation.
getLLVMContext(),
728 if (
auto arrayAttr = dyn_cast<ArrayAttr>(attr)) {
729 if (
auto *arrayTy = dyn_cast<llvm::ArrayType>(llvmType)) {
730 llvm::Type *elementType = arrayTy->getElementType();
732 llvm::Constant *elementCst =
nullptr;
734 constants.reserve(arrayTy->getNumElements());
735 for (
Attribute elementAttr : arrayAttr) {
739 if (!previousElementAttr || previousElementAttr != elementAttr) {
740 previousElementAttr = elementAttr;
746 constants.push_back(elementCst);
748 return llvm::ConstantArray::get(arrayTy, constants);
752 emitError(loc,
"unsupported constant value");
756ModuleTranslation::ModuleTranslation(
Operation *module,
757 std::unique_ptr<llvm::Module> llvmModule)
758 : mlirModule(module), llvmModule(std::move(llvmModule)),
762 *this, *this->llvmModule)),
763 typeTranslator(this->llvmModule->
getContext()),
766 "mlirModule should honor LLVM's module semantics.");
769ModuleTranslation::~ModuleTranslation() {
770 if (ompBuilder && !ompBuilder->isFinalized())
771 ompBuilder->finalize();
776 toProcess.push_back(®ion);
777 while (!toProcess.empty()) {
778 Region *current = toProcess.pop_back_val();
779 for (
Block &block : *current) {
780 blockMapping.erase(&block);
781 for (
Value arg : block.getArguments())
782 valueMapping.erase(arg);
784 for (
Value value : op.getResults())
785 valueMapping.erase(value);
786 if (op.hasSuccessors())
787 branchMapping.erase(&op);
788 if (isa<LLVM::GlobalOp>(op))
789 globalsMapping.erase(&op);
790 if (isa<LLVM::AliasOp>(op))
791 aliasesMapping.erase(&op);
792 if (isa<LLVM::IFuncOp>(op))
793 ifuncMapping.erase(&op);
794 if (isa<LLVM::CallOp>(op))
795 callMapping.erase(&op);
798 llvm::map_range(op.getRegions(), [](
Region &r) { return &r; }));
807 unsigned numArguments,
unsigned index) {
809 if (isa<LLVM::BrOp>(terminator))
816 auto branch = cast<BranchOpInterface>(terminator);
819 (!seenSuccessors.contains(successor) || successorOperands.
empty()) &&
820 "successors with arguments in LLVM branches must be different blocks");
821 seenSuccessors.insert(successor);
827 if (
auto condBranchOp = dyn_cast<LLVM::CondBrOp>(terminator)) {
830 return condBranchOp.getSuccessor(0) == current
831 ? condBranchOp.getTrueDestOperands()[
index]
832 : condBranchOp.getFalseDestOperands()[
index];
835 if (
auto switchOp = dyn_cast<LLVM::SwitchOp>(terminator)) {
838 if (switchOp.getDefaultDestination() == current)
839 return switchOp.getDefaultOperands()[
index];
840 for (
const auto &i : llvm::enumerate(switchOp.getCaseDestinations()))
841 if (i.value() == current)
842 return switchOp.getCaseOperands(i.index())[
index];
845 if (
auto indBrOp = dyn_cast<LLVM::IndirectBrOp>(terminator)) {
847 for (
const auto &i : llvm::enumerate(indBrOp->getSuccessors())) {
848 if (indBrOp->getSuccessor(i.index()) == current)
849 return indBrOp.getSuccessorOperands(i.index())[
index];
853 if (
auto invokeOp = dyn_cast<LLVM::InvokeOp>(terminator)) {
854 return invokeOp.getNormalDest() == current
855 ? invokeOp.getNormalDestOperands()[
index]
856 : invokeOp.getUnwindDestOperands()[
index];
860 "only branch, switch or invoke operations can be terminators "
861 "of a block that has successors");
869 for (
Block &bb : llvm::drop_begin(region)) {
871 auto phis = llvmBB->phis();
872 auto numArguments = bb.getNumArguments();
873 assert(numArguments == std::distance(phis.begin(), phis.end()));
874 for (
auto [
index, phiNode] : llvm::enumerate(phis)) {
875 for (
auto *pred : bb.getPredecessors()) {
881 llvm::Instruction *terminator =
883 assert(terminator &&
"missing the mapping for a terminator");
885 &bb, pred, numArguments,
index)),
886 terminator->getParent());
893 llvm::IRBuilderBase &builder, llvm::Intrinsic::ID intrinsic,
895 llvm::Module *module = builder.GetInsertBlock()->getModule();
897 llvm::Intrinsic::getOrInsertDeclaration(module, intrinsic, tys);
898 return builder.CreateCall(fn, args);
903 Operation *intrOp, llvm::Intrinsic::ID intrinsic,
unsigned numResults,
907 assert(immArgPositions.size() == immArgAttrNames.size() &&
908 "LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
912 size_t numOpBundleOperands = 0;
913 auto opBundleSizesAttr = cast_if_present<DenseI32ArrayAttr>(
914 intrOp->
getAttr(LLVMDialect::getOpBundleSizesAttrName()));
915 auto opBundleTagsAttr = cast_if_present<ArrayAttr>(
916 intrOp->
getAttr(LLVMDialect::getOpBundleTagsAttrName()));
918 if (opBundleSizesAttr && opBundleTagsAttr) {
919 ArrayRef<int> opBundleSizes = opBundleSizesAttr.asArrayRef();
920 assert(opBundleSizes.size() == opBundleTagsAttr.size() &&
921 "operand bundles and tags do not match");
923 numOpBundleOperands = llvm::sum_of(opBundleSizes);
924 assert(numOpBundleOperands <= intrOp->getNumOperands() &&
925 "operand bundle operands is more than the number of operands");
928 size_t nextOperandIdx = 0;
929 opBundles.reserve(opBundleSizesAttr.size());
931 for (
auto [opBundleTagAttr, bundleSize] :
932 llvm::zip(opBundleTagsAttr, opBundleSizes)) {
933 auto bundleTag = cast<StringAttr>(opBundleTagAttr).str();
935 operands.slice(nextOperandIdx, bundleSize));
936 opBundles.emplace_back(std::move(bundleTag), std::move(bundleOperands));
937 nextOperandIdx += bundleSize;
942 auto opOperands = intrOp->
getOperands().drop_back(numOpBundleOperands);
943 auto operands = moduleTranslation.
lookupValues(opOperands);
945 for (
auto [immArgPos, immArgName] :
946 llvm::zip(immArgPositions, immArgAttrNames)) {
947 auto attr = llvm::cast<TypedAttr>(intrOp->
getAttr(immArgName));
948 assert(attr.getType().isIntOrFloat() &&
"expected int or float immarg");
949 auto *type = moduleTranslation.
convertType(attr.getType());
951 type, attr, intrOp->
getLoc(), moduleTranslation);
954 for (
auto &arg : args) {
956 arg = operands[opArg++];
961 for (
unsigned overloadedResultIdx : overloadedResults) {
962 if (numResults > 1) {
964 overloadedTypes.push_back(moduleTranslation.
convertType(
966 .getBody()[overloadedResultIdx]));
968 overloadedTypes.push_back(
972 for (
unsigned overloadedOperandIdx : overloadedOperands)
973 overloadedTypes.push_back(args[overloadedOperandIdx]->
getType());
974 llvm::Module *module = builder.GetInsertBlock()->getModule();
975 llvm::Function *llvmIntr = llvm::Intrinsic::getOrInsertDeclaration(
976 module, intrinsic, overloadedTypes);
978 return builder.CreateCall(llvmIntr, args, opBundles);
983LogicalResult ModuleTranslation::convertOperation(
Operation &op,
984 llvm::IRBuilderBase &builder,
985 bool recordInsertions) {
988 return op.
emitError(
"cannot be converted to LLVM IR: missing "
989 "`LLVMTranslationDialectInterface` registration for "
993 InstructionCapturingInserter::CollectionScope scope(builder,
996 return op.
emitError(
"LLVM Translation failed for operation: ")
999 return convertDialectAttributes(&op, scope.getCapturedInstructions());
1009LogicalResult ModuleTranslation::convertBlockImpl(
Block &bb,
1010 bool ignoreArguments,
1011 llvm::IRBuilderBase &builder,
1012 bool recordInsertions) {
1014 auto *subprogram = builder.GetInsertBlock()->getParent()->getSubprogram();
1022 if (!ignoreArguments) {
1024 unsigned numPredecessors =
1025 std::distance(predecessors.begin(), predecessors.end());
1027 auto wrappedType = arg.getType();
1030 "block argument does not have an LLVM type");
1031 builder.SetCurrentDebugLocation(
1032 debugTranslation->translateLoc(arg.getLoc(), subprogram));
1034 llvm::PHINode *phi = builder.CreatePHI(type, numPredecessors);
1040 for (
auto &op : bb) {
1042 builder.SetCurrentDebugLocation(
1043 debugTranslation->translateLoc(op.
getLoc(), subprogram));
1045 if (
failed(convertOperation(op, builder, recordInsertions)))
1049 if (
auto iface = dyn_cast<WeightedBranchOpInterface>(op))
1059 return module->getRegion(0).front();
1068 llvm::Constant *cst) {
1069 return (linkage == llvm::GlobalVariable::ExternalLinkage && !cst) ||
1070 linkage == llvm::GlobalVariable::ExternalWeakLinkage;
1076 llvm::GlobalValue *gv) {
1077 if (dsoLocalRequested)
1078 gv->setDSOLocal(
true);
1087static FailureOr<llvm::Attribute>
1089 StringRef value = StringRef()) {
1090 auto kind = llvm::Attribute::getAttrKindFromName(key);
1091 if (kind == llvm::Attribute::None)
1092 return llvm::Attribute::get(ctx, key, value);
1094 if (llvm::Attribute::isIntAttrKind(kind)) {
1096 return emitError(loc) <<
"LLVM attribute '" << key <<
"' expects a value";
1099 if (!value.getAsInteger(0,
result))
1100 return llvm::Attribute::get(ctx, kind,
result);
1101 return llvm::Attribute::get(ctx, key, value);
1105 return emitError(loc) <<
"LLVM attribute '" << key
1106 <<
"' does not expect a value, found '" << value
1109 return llvm::Attribute::get(ctx, kind);
1120static FailureOr<llvm::AttrBuilder>
1122 ArrayAttr arrayAttr, StringRef arrayAttrName) {
1123 llvm::AttrBuilder attrBuilder(ctx);
1128 if (
auto stringAttr = dyn_cast<StringAttr>(attr)) {
1129 FailureOr<llvm::Attribute> llvmAttr =
1131 if (failed(llvmAttr))
1133 attrBuilder.addAttribute(*llvmAttr);
1137 auto arrayAttr = dyn_cast<ArrayAttr>(attr);
1138 if (!arrayAttr || arrayAttr.size() != 2)
1139 return emitError(loc) <<
"expected '" << arrayAttrName
1140 <<
"' to contain string or array attributes";
1142 auto keyAttr = dyn_cast<StringAttr>(arrayAttr[0]);
1143 auto valueAttr = dyn_cast<StringAttr>(arrayAttr[1]);
1144 if (!keyAttr || !valueAttr)
1145 return emitError(loc) <<
"expected arrays within '" << arrayAttrName
1146 <<
"' to contain two strings";
1149 loc, ctx, keyAttr.getValue(), valueAttr.getValue());
1150 if (failed(llvmAttr))
1152 attrBuilder.addAttribute(*llvmAttr);
1158LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
1167 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
1169 llvm::Constant *cst =
nullptr;
1170 if (op.getValueOrNull()) {
1173 if (
auto strAttr = dyn_cast_or_null<StringAttr>(op.getValueOrNull())) {
1174 cst = llvm::ConstantDataArray::getString(
1175 llvmModule->getContext(), strAttr.getValue(),
false);
1176 type = cst->getType();
1183 auto linkage = convertLinkageToLLVM(op.getLinkage());
1189 if (!dropInitializer && !cst)
1190 cst = llvm::UndefValue::get(type);
1191 else if (dropInitializer && cst)
1194 auto *var =
new llvm::GlobalVariable(
1195 *llvmModule, type, op.getConstant(), linkage, cst, op.getSymName(),
1197 op.getThreadLocal_() ? llvm::GlobalValue::GeneralDynamicTLSModel
1198 : llvm::GlobalValue::NotThreadLocal,
1199 op.getAddrSpace(), op.getExternallyInitialized());
1201 if (std::optional<mlir::SymbolRefAttr> comdat = op.getComdat()) {
1202 auto selectorOp = cast<ComdatSelectorOp>(
1204 var->setComdat(comdatMapping.lookup(selectorOp));
1207 if (op.getUnnamedAddr().has_value())
1208 var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
1210 if (op.getSection().has_value())
1211 var->setSection(*op.getSection());
1215 std::optional<uint64_t> alignment = op.getAlignment();
1216 if (alignment.has_value())
1217 var->setAlignment(llvm::MaybeAlign(alignment.value()));
1219 var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
1221 globalsMapping.try_emplace(op, var);
1224 if (op.getDbgExprs()) {
1225 for (
auto exprAttr :
1226 op.getDbgExprs()->getAsRange<DIGlobalVariableExpressionAttr>()) {
1227 llvm::DIGlobalVariableExpression *diGlobalExpr =
1228 debugTranslation->translateGlobalVariableExpression(exprAttr);
1229 llvm::DIGlobalVariable *diGlobalVar = diGlobalExpr->getVariable();
1230 var->addDebugInfo(diGlobalExpr);
1249 llvm::DIScope *scope = diGlobalVar->getScope();
1250 if (
auto *mod = dyn_cast_if_present<llvm::DIModule>(scope))
1251 scope = mod->getScope();
1252 else if (
auto *cb = dyn_cast_if_present<llvm::DICommonBlock>(scope)) {
1254 dyn_cast_if_present<llvm::DISubprogram>(cb->getScope()))
1255 scope = sp->getUnit();
1256 }
else if (
auto *sp = dyn_cast_if_present<llvm::DISubprogram>(scope))
1257 scope = sp->getUnit();
1260 if (llvm::DICompileUnit *compileUnit =
1261 dyn_cast_if_present<llvm::DICompileUnit>(scope)) {
1264 allGVars[compileUnit].push_back(diGlobalExpr);
1270 FailureOr<llvm::AttrBuilder> convertedTargetSpecificAttrs =
1272 op.getTargetSpecificAttrsAttr(),
1273 op.getTargetSpecificAttrsAttrName());
1274 if (
failed(convertedTargetSpecificAttrs))
1276 var->addAttributes(*convertedTargetSpecificAttrs);
1280 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
1282 llvm::Constant *cst =
nullptr;
1283 llvm::GlobalValue::LinkageTypes linkage =
1284 convertLinkageToLLVM(op.getLinkage());
1285 llvm::Module &llvmMod = *llvmModule;
1288 llvm::GlobalAlias *var = llvm::GlobalAlias::create(
1289 type, op.getAddrSpace(), linkage, op.getSymName(), cst,
1292 var->setThreadLocalMode(op.getThreadLocal_()
1293 ? llvm::GlobalAlias::GeneralDynamicTLSModel
1294 : llvm::GlobalAlias::NotThreadLocal);
1299 if (op.getUnnamedAddr().has_value())
1300 var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
1302 var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
1304 aliasesMapping.try_emplace(op, var);
1308 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
1309 if (
Block *initializer = op.getInitializerBlock()) {
1310 llvm::IRBuilder<llvm::TargetFolder> builder(
1311 llvmModule->getContext(),
1312 llvm::TargetFolder(llvmModule->getDataLayout()));
1314 [[maybe_unused]]
int numConstantsHit = 0;
1315 [[maybe_unused]]
int numConstantsErased = 0;
1318 for (
auto &op : initializer->without_terminator()) {
1319 if (
failed(convertOperation(op, builder)))
1332 if (
auto *agg = dyn_cast<llvm::ConstantAggregate>(cst)) {
1335 int numUsers = std::distance(
result.use_begin(),
result.use_end());
1337 constantAggregateUseMap.try_emplace(agg, numUsers);
1340 iterator->second += numUsers;
1346 auto cst = dyn_cast<llvm::ConstantAggregate>(
lookupValue(v));
1349 auto iter = constantAggregateUseMap.find(cst);
1350 assert(iter != constantAggregateUseMap.end() &&
"constant not found");
1352 if (iter->second == 0) {
1355 if (cst->user_empty()) {
1356 cst->destroyConstant();
1357 numConstantsErased++;
1359 constantAggregateUseMap.erase(iter);
1364 ReturnOp ret = cast<ReturnOp>(initializer->getTerminator());
1365 llvm::Constant *cst =
1366 cast<llvm::Constant>(
lookupValue(ret.getOperand(0)));
1367 auto *global = cast<llvm::GlobalVariable>(
lookupGlobal(op));
1369 global->setInitializer(cst);
1373 for (
auto it : constantAggregateUseMap) {
1374 auto cst = it.first;
1375 cst->removeDeadConstantUsers();
1376 if (cst->user_empty()) {
1377 cst->destroyConstant();
1378 numConstantsErased++;
1382 LLVM_DEBUG(llvm::dbgs()
1383 <<
"Convert initializer for " << op.
getName() <<
"\n";
1384 llvm::dbgs() << numConstantsHit <<
" new constants hit\n";
1386 << numConstantsErased <<
" dangling constants erased\n";);
1392 auto ctorOp = dyn_cast<GlobalCtorsOp>(op);
1393 auto dtorOp = dyn_cast<GlobalDtorsOp>(op);
1394 if (!ctorOp && !dtorOp)
1400 if ((ctorOp && ctorOp.getCtors().empty()) ||
1401 (dtorOp && dtorOp.getDtors().empty())) {
1402 llvm::IRBuilder<llvm::TargetFolder> builder(
1403 llvmModule->getContext(),
1404 llvm::TargetFolder(llvmModule->getDataLayout()));
1405 llvm::Type *eltTy = llvm::StructType::get(
1406 builder.getInt32Ty(), builder.getPtrTy(), builder.getPtrTy());
1407 llvm::ArrayType *at = llvm::ArrayType::get(eltTy, 0);
1408 llvm::Constant *zeroInit = llvm::Constant::getNullValue(at);
1409 (void)
new llvm::GlobalVariable(
1410 *llvmModule, zeroInit->getType(),
false,
1411 llvm::GlobalValue::AppendingLinkage, zeroInit,
1412 ctorOp ?
"llvm.global_ctors" :
"llvm.global_dtors");
1415 ? llvm::zip(ctorOp.getCtors(), ctorOp.getPriorities())
1416 : llvm::zip(dtorOp.getDtors(), dtorOp.getPriorities());
1417 auto appendGlobalFn =
1418 ctorOp ? llvm::appendToGlobalCtors : llvm::appendToGlobalDtors;
1419 for (
const auto &[sym, prio] : range) {
1422 appendGlobalFn(*llvmModule, f, cast<IntegerAttr>(prio).getInt(),
1428 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>())
1429 if (
failed(convertDialectAttributes(op, {})))
1434 for (
const auto &[compileUnit, globals] : allGVars) {
1435 compileUnit->replaceGlobalVariables(
1440 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
1441 Block &initializer = op.getInitializerBlock();
1442 llvm::IRBuilder<llvm::TargetFolder> builder(
1443 llvmModule->getContext(),
1444 llvm::TargetFolder(llvmModule->getDataLayout()));
1447 if (
failed(convertOperation(op, builder)))
1454 auto *cst = cast<llvm::Constant>(
lookupValue(ret.getOperand(0)));
1455 assert(aliasesMapping.count(op));
1456 auto *alias = cast<llvm::GlobalAlias>(aliasesMapping[op]);
1457 alias->setAliasee(cst);
1460 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::AliasOp>())
1461 if (
failed(convertDialectAttributes(op, {})))
1469 const llvm::APInt &value) {
1470 llvm::Constant *constant = llvm::ConstantInt::get(context, value);
1471 return llvm::ConstantAsMetadata::get(constant);
1476 const llvm::APInt &value) {
1484 llvm::Metadata *typeMD =
1485 llvm::ConstantAsMetadata::get(llvm::UndefValue::get(type));
1486 llvm::Metadata *isSignedMD =
1488 return llvm::MDNode::get(context, {typeMD, isSignedMD});
1496 values, std::back_inserter(mdValues), [&context](int32_t value) {
1499 return llvm::MDNode::get(context, mdValues);
1502LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
1505 blockMapping.clear();
1506 valueMapping.clear();
1507 branchMapping.clear();
1511 for (
auto [mlirArg, llvmArg] :
1512 llvm::zip(func.getArguments(), llvmFunc->args()))
1516 if (func.getPersonality()) {
1517 llvm::Type *ty = llvm::PointerType::getUnqual(llvmFunc->getContext());
1518 if (llvm::Constant *pfunc =
getLLVMConstant(ty, func.getPersonalityAttr(),
1519 func.getLoc(), *
this))
1520 llvmFunc->setPersonalityFn(pfunc);
1523 if (std::optional<StringRef> section = func.getSection())
1524 llvmFunc->setSection(*section);
1526 if (func.getArmStreaming())
1527 llvmFunc->addFnAttr(
"aarch64_pstate_sm_enabled");
1528 else if (func.getArmLocallyStreaming())
1529 llvmFunc->addFnAttr(
"aarch64_pstate_sm_body");
1530 else if (func.getArmStreamingCompatible())
1531 llvmFunc->addFnAttr(
"aarch64_pstate_sm_compatible");
1533 if (func.getArmNewZa())
1534 llvmFunc->addFnAttr(
"aarch64_new_za");
1535 else if (func.getArmInZa())
1536 llvmFunc->addFnAttr(
"aarch64_in_za");
1537 else if (func.getArmOutZa())
1538 llvmFunc->addFnAttr(
"aarch64_out_za");
1539 else if (func.getArmInoutZa())
1540 llvmFunc->addFnAttr(
"aarch64_inout_za");
1541 else if (func.getArmPreservesZa())
1542 llvmFunc->addFnAttr(
"aarch64_preserves_za");
1544 if (
auto targetCpu = func.getTargetCpu())
1545 llvmFunc->addFnAttr(
"target-cpu", *targetCpu);
1547 if (
auto tuneCpu = func.getTuneCpu())
1548 llvmFunc->addFnAttr(
"tune-cpu", *tuneCpu);
1550 if (
auto reciprocalEstimates = func.getReciprocalEstimates())
1551 llvmFunc->addFnAttr(
"reciprocal-estimates", *reciprocalEstimates);
1553 if (
auto preferVectorWidth = func.getPreferVectorWidth())
1554 llvmFunc->addFnAttr(
"prefer-vector-width", *preferVectorWidth);
1556 if (
auto attr = func.getVscaleRange())
1557 llvmFunc->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
1559 attr->getMaxRange().getInt()));
1561 if (
auto noInfsFpMath = func.getNoInfsFpMath())
1562 llvmFunc->addFnAttr(
"no-infs-fp-math", llvm::toStringRef(*noInfsFpMath));
1564 if (
auto noNansFpMath = func.getNoNansFpMath())
1565 llvmFunc->addFnAttr(
"no-nans-fp-math", llvm::toStringRef(*noNansFpMath));
1567 if (
auto noSignedZerosFpMath = func.getNoSignedZerosFpMath())
1568 llvmFunc->addFnAttr(
"no-signed-zeros-fp-math",
1569 llvm::toStringRef(*noSignedZerosFpMath));
1571 if (
auto denormalFpMath = func.getDenormalFpMath())
1572 llvmFunc->addFnAttr(
"denormal-fp-math", *denormalFpMath);
1574 if (
auto denormalFpMathF32 = func.getDenormalFpMathF32())
1575 llvmFunc->addFnAttr(
"denormal-fp-math-f32", *denormalFpMathF32);
1577 if (
auto fpContract = func.getFpContract())
1578 llvmFunc->addFnAttr(
"fp-contract", *fpContract);
1580 if (
auto instrumentFunctionEntry = func.getInstrumentFunctionEntry())
1581 llvmFunc->addFnAttr(
"instrument-function-entry", *instrumentFunctionEntry);
1583 if (
auto instrumentFunctionExit = func.getInstrumentFunctionExit())
1584 llvmFunc->addFnAttr(
"instrument-function-exit", *instrumentFunctionExit);
1587 llvm::LLVMContext &llvmContext = llvmFunc->getContext();
1588 for (
auto &bb : func) {
1589 auto *llvmBB = llvm::BasicBlock::Create(llvmContext);
1590 llvmBB->insertInto(llvmFunc);
1597 for (
Block *bb : blocks) {
1598 CapturingIRBuilder builder(llvmContext,
1599 llvm::TargetFolder(llvmModule->getDataLayout()));
1600 if (
failed(convertBlockImpl(*bb, bb->isEntryBlock(), builder,
1610 return convertDialectAttributes(func, {});
1613LogicalResult ModuleTranslation::convertDialectAttributes(
1614 Operation *op, ArrayRef<llvm::Instruction *> instructions) {
1616 if (
failed(iface.amendOperation(op, instructions, attribute, *
this)))
1624 llvm::Function *llvmFunc) {
1625 if (!
func.getMemoryEffects())
1628 MemoryEffectsAttr memEffects =
func.getMemoryEffectsAttr();
1631 llvm::MemoryEffects newMemEffects =
1632 llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
1633 convertModRefInfoToLLVM(memEffects.getArgMem()));
1634 newMemEffects |= llvm::MemoryEffects(
1635 llvm::MemoryEffects::Location::InaccessibleMem,
1636 convertModRefInfoToLLVM(memEffects.getInaccessibleMem()));
1638 llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
1639 convertModRefInfoToLLVM(memEffects.getOther()));
1641 llvm::MemoryEffects(llvm::MemoryEffects::Location::ErrnoMem,
1642 convertModRefInfoToLLVM(memEffects.getErrnoMem()));
1644 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem0,
1645 convertModRefInfoToLLVM(memEffects.getTargetMem0()));
1647 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem1,
1648 convertModRefInfoToLLVM(memEffects.getTargetMem1()));
1649 llvmFunc->setMemoryEffects(newMemEffects);
1654 llvm::Function *llvmFunc) {
1655 if (
func.getNoInlineAttr())
1656 llvmFunc->addFnAttr(llvm::Attribute::NoInline);
1657 if (
func.getAlwaysInlineAttr())
1658 llvmFunc->addFnAttr(llvm::Attribute::AlwaysInline);
1659 if (
func.getInlineHintAttr())
1660 llvmFunc->addFnAttr(llvm::Attribute::InlineHint);
1661 if (
func.getOptimizeNoneAttr())
1662 llvmFunc->addFnAttr(llvm::Attribute::OptimizeNone);
1663 if (
func.getConvergentAttr())
1664 llvmFunc->addFnAttr(llvm::Attribute::Convergent);
1665 if (
func.getNoUnwindAttr())
1666 llvmFunc->addFnAttr(llvm::Attribute::NoUnwind);
1667 if (
func.getWillReturnAttr())
1668 llvmFunc->addFnAttr(llvm::Attribute::WillReturn);
1669 if (TargetFeaturesAttr targetFeatAttr =
func.getTargetFeaturesAttr())
1670 llvmFunc->addFnAttr(
"target-features", targetFeatAttr.getFeaturesString());
1671 if (FramePointerKindAttr fpAttr =
func.getFramePointerAttr())
1672 llvmFunc->addFnAttr(
"frame-pointer", stringifyFramePointerKind(
1673 fpAttr.getFramePointerKind()));
1674 if (UWTableKindAttr uwTableKindAttr =
func.getUwtableKindAttr())
1675 llvmFunc->setUWTableKind(
1676 convertUWTableKindToLLVM(uwTableKindAttr.getUwtableKind()));
1682 llvm::Function *llvmFunc,
1684 llvm::LLVMContext &llvmContext = llvmFunc->getContext();
1686 if (VecTypeHintAttr vecTypeHint =
func.getVecTypeHintAttr()) {
1687 Type type = vecTypeHint.getHint().getValue();
1688 llvm::Type *llvmType = translation.
convertType(type);
1689 bool isSigned = vecTypeHint.getIsSigned();
1690 llvmFunc->setMetadata(
1691 func.getVecTypeHintAttrName(),
1696 func.getWorkGroupSizeHint()) {
1697 llvmFunc->setMetadata(
1698 func.getWorkGroupSizeHintAttrName(),
1703 func.getReqdWorkGroupSize()) {
1704 llvmFunc->setMetadata(
1705 func.getReqdWorkGroupSizeAttrName(),
1709 if (std::optional<uint32_t> intelReqdSubGroupSize =
1710 func.getIntelReqdSubGroupSize()) {
1711 llvmFunc->setMetadata(
1712 func.getIntelReqdSubGroupSizeAttrName(),
1714 llvm::APInt(32, *intelReqdSubGroupSize)));
1719 llvm::Attribute::AttrKind llvmKind,
1724 .Case<TypeAttr>([&](
auto typeAttr) {
1725 attrBuilder.addTypeAttr(
1726 llvmKind, moduleTranslation.
convertType(typeAttr.getValue()));
1729 .Case<IntegerAttr>([&](
auto intAttr) {
1730 attrBuilder.addRawIntAttr(llvmKind, intAttr.getInt());
1733 .Case<UnitAttr>([&](
auto) {
1734 attrBuilder.addAttribute(llvmKind);
1737 .Case<LLVM::ConstantRangeAttr>([&](
auto rangeAttr) {
1738 attrBuilder.addConstantRangeAttr(
1740 llvm::ConstantRange(rangeAttr.getLower(), rangeAttr.getUpper()));
1743 .Default([loc](
auto) {
1744 return emitError(loc,
"unsupported parameter attribute type");
1748FailureOr<llvm::AttrBuilder>
1749ModuleTranslation::convertParameterAttrs(LLVMFuncOp func,
int argIdx,
1750 DictionaryAttr paramAttrs) {
1751 llvm::AttrBuilder attrBuilder(llvmModule->getContext());
1753 Location loc = func.getLoc();
1755 for (
auto namedAttr : paramAttrs) {
1756 auto it = attrNameToKindMapping.find(namedAttr.getName());
1757 if (it != attrNameToKindMapping.end()) {
1758 llvm::Attribute::AttrKind llvmKind = it->second;
1762 }
else if (namedAttr.getNameDialect()) {
1763 if (
failed(iface.convertParameterAttr(func, argIdx, namedAttr, *
this)))
1772 ArgAndResultAttrsOpInterface attrsOp, llvm::CallBase *call,
1775 if (
ArrayAttr argAttrsArray = attrsOp.getArgAttrsAttr()) {
1776 unsigned argAttrIdx = 0;
1777 llvm::SmallDenseSet<unsigned> immArgPositionsSet(immArgPositions.begin(),
1778 immArgPositions.end());
1779 for (
unsigned argIdx : llvm::seq<unsigned>(call->arg_size())) {
1780 if (argAttrIdx >= argAttrsArray.size())
1783 if (immArgPositionsSet.contains(argIdx))
1786 auto argAttrs = cast<DictionaryAttr>(argAttrsArray[argAttrIdx++]);
1787 if (argAttrs.empty())
1790 FailureOr<llvm::AttrBuilder> attrBuilder =
1791 convertParameterAttrs(attrsOp->getLoc(), argAttrs);
1792 if (failed(attrBuilder))
1794 call->addParamAttrs(argIdx, *attrBuilder);
1799 if (
ArrayAttr resAttrsArray = attrsOp.getResAttrsAttr()) {
1800 if (!resAttrsArray.empty()) {
1801 auto resAttrs = cast<DictionaryAttr>(resAttrsArray[0]);
1802 FailureOr<llvm::AttrBuilder> attrBuilder =
1803 convertParameterAttrs(attrsOp->getLoc(), resAttrs);
1804 if (failed(attrBuilder))
1806 call->addRetAttrs(*attrBuilder);
1813FailureOr<llvm::AttrBuilder>
1814ModuleTranslation::convertParameterAttrs(
Location loc,
1815 DictionaryAttr paramAttrs) {
1816 llvm::AttrBuilder attrBuilder(llvmModule->getContext());
1819 for (
auto namedAttr : paramAttrs) {
1820 auto it = attrNameToKindMapping.find(namedAttr.getName());
1821 if (it != attrNameToKindMapping.end()) {
1822 llvm::Attribute::AttrKind llvmKind = it->second;
1832LogicalResult ModuleTranslation::convertFunctionSignatures() {
1835 for (
auto function :
getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
1836 llvm::FunctionCallee llvmFuncCst = llvmModule->getOrInsertFunction(
1838 cast<llvm::FunctionType>(
convertType(function.getFunctionType())));
1839 llvm::Function *llvmFunc = cast<llvm::Function>(llvmFuncCst.getCallee());
1840 llvmFunc->setLinkage(convertLinkageToLLVM(function.getLinkage()));
1841 llvmFunc->setCallingConv(convertCConvToLLVM(function.getCConv()));
1852 if (std::optional<uint64_t> entryCount = function.getFunctionEntryCount())
1853 llvmFunc->setEntryCount(entryCount.value());
1856 if (
ArrayAttr allResultAttrs = function.getAllResultAttrs()) {
1857 DictionaryAttr resultAttrs = cast<DictionaryAttr>(allResultAttrs[0]);
1858 FailureOr<llvm::AttrBuilder> attrBuilder =
1859 convertParameterAttrs(function, -1, resultAttrs);
1862 llvmFunc->addRetAttrs(*attrBuilder);
1866 for (
auto [argIdx, llvmArg] : llvm::enumerate(llvmFunc->args())) {
1867 if (DictionaryAttr argAttrs = function.getArgAttrDict(argIdx)) {
1868 FailureOr<llvm::AttrBuilder> attrBuilder =
1869 convertParameterAttrs(function, argIdx, argAttrs);
1872 llvmArg.addAttrs(*attrBuilder);
1877 FailureOr<llvm::AttrBuilder> convertedPassthroughAttrs =
1879 function.getPassthroughAttr(),
1880 function.getPassthroughAttrName());
1881 if (
failed(convertedPassthroughAttrs))
1883 llvmFunc->addFnAttrs(*convertedPassthroughAttrs);
1886 llvmFunc->setVisibility(convertVisibilityToLLVM(function.getVisibility_()));
1889 if (std::optional<mlir::SymbolRefAttr> comdat = function.getComdat()) {
1890 auto selectorOp = cast<ComdatSelectorOp>(
1892 llvmFunc->setComdat(comdatMapping.lookup(selectorOp));
1895 if (
auto gc = function.getGarbageCollector())
1896 llvmFunc->setGC(gc->str());
1898 if (
auto unnamedAddr = function.getUnnamedAddr())
1899 llvmFunc->setUnnamedAddr(convertUnnamedAddrToLLVM(*unnamedAddr));
1901 if (
auto alignment = function.getAlignment())
1902 llvmFunc->setAlignment(llvm::MaybeAlign(*alignment));
1905 debugTranslation->translate(function, *llvmFunc);
1911LogicalResult ModuleTranslation::convertFunctions() {
1913 for (
auto function :
getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
1916 if (function.isExternal()) {
1917 if (
failed(convertDialectAttributes(function, {})))
1922 if (
failed(convertOneFunction(function)))
1929LogicalResult ModuleTranslation::convertIFuncs() {
1930 for (
auto op :
getModuleBody(mlirModule).getOps<IFuncOp>()) {
1931 llvm::Type *type =
convertType(op.getIFuncType());
1932 llvm::GlobalValue::LinkageTypes linkage =
1933 convertLinkageToLLVM(op.getLinkage());
1934 llvm::Constant *resolver;
1936 resolver = cast<llvm::Constant>(resolverFn);
1939 op.getResolverAttr());
1940 resolver = cast<llvm::Constant>(
lookupAlias(aliasOp));
1944 llvm::GlobalIFunc::create(type, op.getAddressSpace(), linkage,
1945 op.getSymName(), resolver, llvmModule.get());
1947 ifunc->setUnnamedAddr(convertUnnamedAddrToLLVM(op.getUnnamedAddr()));
1948 ifunc->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
1950 ifuncMapping.try_emplace(op, ifunc);
1956LogicalResult ModuleTranslation::convertComdats() {
1957 for (
auto comdatOp :
getModuleBody(mlirModule).getOps<ComdatOp>()) {
1958 for (
auto selectorOp : comdatOp.getOps<ComdatSelectorOp>()) {
1960 if (module->getComdatSymbolTable().contains(selectorOp.getSymName()))
1962 <<
"comdat selection symbols must be unique even in different "
1964 llvm::Comdat *comdat =
module->getOrInsertComdat(selectorOp.getSymName());
1965 comdat->setSelectionKind(convertComdatToLLVM(selectorOp.getComdat()));
1966 comdatMapping.try_emplace(selectorOp, comdat);
1972LogicalResult ModuleTranslation::convertUnresolvedBlockAddress() {
1973 for (
auto &[blockAddressOp, llvmCst] : unresolvedBlockAddressMapping) {
1974 BlockAddressAttr blockAddressAttr = blockAddressOp.getBlockAddr();
1976 assert(llvmBlock &&
"expected LLVM blocks to be already translated");
1979 auto *llvmBlockAddr = llvm::BlockAddress::get(
1980 lookupFunction(blockAddressAttr.getFunction().getValue()), llvmBlock);
1981 llvmCst->replaceAllUsesWith(llvmBlockAddr);
1982 assert(llvmCst->use_empty() &&
"expected all uses to be replaced");
1983 cast<llvm::GlobalVariable>(llvmCst)->eraseFromParent();
1985 unresolvedBlockAddressMapping.clear();
1990 llvm::Instruction *inst) {
1991 if (llvm::MDNode *node = loopAnnotationTranslation->getAccessGroups(op))
1992 inst->setMetadata(llvm::LLVMContext::MD_access_group, node);
1997 auto [scopeIt, scopeInserted] =
1998 aliasScopeMetadataMapping.try_emplace(aliasScopeAttr,
nullptr);
2000 return scopeIt->second;
2001 llvm::LLVMContext &ctx = llvmModule->getContext();
2002 auto dummy = llvm::MDNode::getTemporary(ctx, {});
2004 auto [domainIt, insertedDomain] = aliasDomainMetadataMapping.try_emplace(
2005 aliasScopeAttr.getDomain(),
nullptr);
2006 if (insertedDomain) {
2009 operands.push_back(dummy.get());
2010 if (StringAttr description = aliasScopeAttr.getDomain().getDescription())
2011 operands.push_back(llvm::MDString::get(ctx, description));
2012 domainIt->second = llvm::MDNode::get(ctx, operands);
2015 if (
auto stringAttr =
2016 dyn_cast<StringAttr>(aliasScopeAttr.getDomain().getId()))
2017 replacement = llvm::MDString::get(ctx, stringAttr.getValue());
2020 domainIt->second->replaceOperandWith(0,
replacement);
2023 assert(domainIt->second &&
"Scope's domain should already be valid");
2026 operands.push_back(dummy.get());
2027 operands.push_back(domainIt->second);
2028 if (StringAttr description = aliasScopeAttr.getDescription())
2029 operands.push_back(llvm::MDString::get(ctx, description));
2030 scopeIt->second = llvm::MDNode::get(ctx, operands);
2033 if (
auto stringAttr = dyn_cast<StringAttr>(aliasScopeAttr.getId()))
2034 replacement = llvm::MDString::get(ctx, stringAttr.getValue());
2037 scopeIt->second->replaceOperandWith(0,
replacement);
2038 return scopeIt->second;
2044 nodes.reserve(aliasScopeAttrs.size());
2045 for (AliasScopeAttr aliasScopeAttr : aliasScopeAttrs)
2051 llvm::Instruction *inst) {
2052 auto populateScopeMetadata = [&](
ArrayAttr aliasScopeAttrs,
unsigned kind) {
2053 if (!aliasScopeAttrs || aliasScopeAttrs.empty())
2056 llvm::to_vector(aliasScopeAttrs.getAsRange<AliasScopeAttr>()));
2057 inst->setMetadata(kind, node);
2060 populateScopeMetadata(op.getAliasScopesOrNull(),
2061 llvm::LLVMContext::MD_alias_scope);
2062 populateScopeMetadata(op.getNoAliasScopesOrNull(),
2063 llvm::LLVMContext::MD_noalias);
2066llvm::MDNode *ModuleTranslation::getTBAANode(TBAATagAttr tbaaAttr)
const {
2067 return tbaaMetadataMapping.lookup(tbaaAttr);
2071 llvm::Instruction *inst) {
2072 ArrayAttr tagRefs = op.getTBAATagsOrNull();
2073 if (!tagRefs || tagRefs.empty())
2080 if (tagRefs.size() > 1) {
2081 op.emitWarning() <<
"TBAA access tags were not translated, because LLVM "
2082 "IR only supports a single tag per instruction";
2086 llvm::MDNode *node = getTBAANode(cast<TBAATagAttr>(tagRefs[0]));
2087 inst->setMetadata(llvm::LLVMContext::MD_tbaa, node);
2091 DereferenceableOpInterface op, llvm::Instruction *inst) {
2092 DereferenceableAttr derefAttr = op.getDereferenceableOrNull();
2096 llvm::MDNode *derefSizeNode = llvm::MDNode::get(
2098 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2099 llvm::IntegerType::get(
getLLVMContext(), 64), derefAttr.getBytes())));
2100 unsigned kindId = derefAttr.getMayBeNull()
2101 ? llvm::LLVMContext::MD_dereferenceable_or_null
2102 : llvm::LLVMContext::MD_dereferenceable;
2103 inst->setMetadata(kindId, derefSizeNode);
2108 llvm::transform(op.getWeights(), std::back_inserter(weights),
2109 [](int32_t value) { return static_cast<uint32_t>(value); });
2110 if (weights.empty())
2114 assert(inst &&
"expected the operation to have a mapping to an instruction");
2116 llvm::LLVMContext::MD_prof,
2120LogicalResult ModuleTranslation::createTBAAMetadata() {
2121 llvm::LLVMContext &ctx = llvmModule->getContext();
2122 llvm::IntegerType *offsetTy = llvm::IntegerType::get(ctx, 64);
2133 walker.
addWalk([&](TBAARootAttr root) {
2134 tbaaMetadataMapping.insert(
2135 {root, llvm::MDNode::get(ctx, llvm::MDString::get(ctx, root.getId()))});
2138 walker.
addWalk([&](TBAATypeDescriptorAttr descriptor) {
2140 operands.push_back(llvm::MDString::get(ctx, descriptor.getId()));
2141 for (TBAAMemberAttr member : descriptor.getMembers()) {
2142 operands.push_back(tbaaMetadataMapping.lookup(member.getTypeDesc()));
2143 operands.push_back(llvm::ConstantAsMetadata::get(
2144 llvm::ConstantInt::get(offsetTy, member.getOffset())));
2147 tbaaMetadataMapping.insert({descriptor, llvm::MDNode::get(ctx, operands)});
2150 walker.
addWalk([&](TBAATagAttr tag) {
2151 SmallVector<llvm::Metadata *> operands;
2153 operands.push_back(tbaaMetadataMapping.lookup(tag.getBaseType()));
2154 operands.push_back(tbaaMetadataMapping.lookup(tag.getAccessType()));
2156 operands.push_back(llvm::ConstantAsMetadata::get(
2157 llvm::ConstantInt::get(offsetTy, tag.getOffset())));
2158 if (tag.getConstant())
2160 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(offsetTy, 1)));
2162 tbaaMetadataMapping.insert({tag, llvm::MDNode::get(ctx, operands)});
2165 mlirModule->walk([&](AliasAnalysisOpInterface analysisOpInterface) {
2166 if (
auto attr = analysisOpInterface.getTBAATagsOrNull())
2173LogicalResult ModuleTranslation::createIdentMetadata() {
2174 if (
auto attr = mlirModule->getAttrOfType<StringAttr>(
2175 LLVMDialect::getIdentAttrName())) {
2176 StringRef ident = attr;
2177 llvm::LLVMContext &ctx = llvmModule->getContext();
2178 llvm::NamedMDNode *namedMd =
2179 llvmModule->getOrInsertNamedMetadata(LLVMDialect::getIdentAttrName());
2180 llvm::MDNode *md = llvm::MDNode::get(ctx, llvm::MDString::get(ctx, ident));
2181 namedMd->addOperand(md);
2187LogicalResult ModuleTranslation::createCommandlineMetadata() {
2188 if (
auto attr = mlirModule->getAttrOfType<StringAttr>(
2189 LLVMDialect::getCommandlineAttrName())) {
2190 StringRef cmdLine = attr;
2191 llvm::LLVMContext &ctx = llvmModule->getContext();
2192 llvm::NamedMDNode *nmd = llvmModule->getOrInsertNamedMetadata(
2193 LLVMDialect::getCommandlineAttrName());
2195 llvm::MDNode::get(ctx, llvm::MDString::get(ctx, cmdLine));
2196 nmd->addOperand(md);
2202LogicalResult ModuleTranslation::createDependentLibrariesMetadata() {
2203 if (
auto dependentLibrariesAttr = mlirModule->getDiscardableAttr(
2204 LLVM::LLVMDialect::getDependentLibrariesAttrName())) {
2206 llvmModule->getOrInsertNamedMetadata(
"llvm.dependent-libraries");
2207 llvm::LLVMContext &ctx = llvmModule->getContext();
2209 cast<ArrayAttr>(dependentLibrariesAttr).getAsRange<StringAttr>()) {
2211 llvm::MDNode::get(ctx, llvm::MDString::get(ctx, libAttr.getValue()));
2212 nmd->addOperand(md);
2219 llvm::Instruction *inst) {
2220 LoopAnnotationAttr attr =
2222 .Case<LLVM::BrOp, LLVM::CondBrOp>(
2223 [](
auto branchOp) {
return branchOp.getLoopAnnotationAttr(); });
2226 llvm::MDNode *loopMD =
2227 loopAnnotationTranslation->translateLoopAnnotation(attr, op);
2228 inst->setMetadata(llvm::LLVMContext::MD_loop, loopMD);
2232 auto iface = cast<DisjointFlagInterface>(op);
2234 if (
auto disjointInst = dyn_cast<llvm::PossiblyDisjointInst>(value))
2235 disjointInst->setIsDisjoint(iface.getIsDisjoint());
2239 return typeTranslator.translateType(type);
2245 remapped.reserve(values.size());
2246 for (
Value v : values)
2253 ompBuilder = std::make_unique<llvm::OpenMPIRBuilder>(*llvmModule);
2258 llvm::OpenMPIRBuilderConfig
config(
2265 unsigned int defaultAS =
2266 llvmModule->getDataLayout().getProgramAddressSpace();
2267 config.setDefaultTargetAS(defaultAS);
2268 config.setRuntimeCC(llvmModule->getTargetTriple().isSPIRV()
2269 ? llvm::CallingConv::SPIR_FUNC
2270 : llvm::CallingConv::C);
2271 ompBuilder->setConfig(std::move(
config));
2272 ompBuilder->initialize();
2274 return ompBuilder.get();
2278 llvm::DILocalScope *scope) {
2279 return debugTranslation->translateLoc(loc, scope);
2284 return debugTranslation->translateExpression(attr);
2287llvm::DIGlobalVariableExpression *
2289 LLVM::DIGlobalVariableExpressionAttr attr) {
2290 return debugTranslation->translateGlobalVariableExpression(attr);
2294 return debugTranslation->translate(attr);
2299 return convertRoundingModeToLLVM(rounding);
2303 LLVM::FPExceptionBehavior exceptionBehavior) {
2304 return convertFPExceptionBehaviorToLLVM(exceptionBehavior);
2309 return llvmModule->getOrInsertNamedMetadata(name);
2312static std::unique_ptr<llvm::Module>
2316 auto llvmModule = std::make_unique<llvm::Module>(name, llvmContext);
2317 if (
auto dataLayoutAttr =
2319 llvmModule->setDataLayout(cast<StringAttr>(dataLayoutAttr).getValue());
2321 FailureOr<llvm::DataLayout> llvmDataLayout(llvm::DataLayout(
""));
2322 if (
auto iface = dyn_cast<DataLayoutOpInterface>(m)) {
2323 if (DataLayoutSpecInterface spec = iface.getDataLayoutSpec()) {
2327 }
else if (
auto mod = dyn_cast<ModuleOp>(m)) {
2328 if (DataLayoutSpecInterface spec = mod.getDataLayoutSpec()) {
2333 if (failed(llvmDataLayout))
2335 llvmModule->setDataLayout(*llvmDataLayout);
2337 if (
auto targetTripleAttr =
2339 llvmModule->setTargetTriple(
2340 llvm::Triple(cast<StringAttr>(targetTripleAttr).getValue()));
2343 LLVM::LLVMDialect::getModuleLevelAsmAttrName())) {
2344 auto asmArrayAttr = dyn_cast<ArrayAttr>(asmAttr);
2345 if (!asmArrayAttr) {
2346 m->
emitError(
"expected an array attribute for a module level asm");
2351 auto asmStrAttr = dyn_cast<StringAttr>(elt);
2354 "expected a string attribute for each entry of a module level asm");
2357 llvmModule->appendModuleInlineAsm(asmStrAttr.getValue());
2364std::unique_ptr<llvm::Module>
2366 StringRef name,
bool disableVerification) {
2368 module->emitOpError("can not be translated to an LLVMIR module");
2372 std::unique_ptr<llvm::Module> llvmModule =
2381 llvm::IRBuilder<llvm::TargetFolder> llvmBuilder(
2383 llvm::TargetFolder(translator.getLLVMModule()->getDataLayout()));
2389 if (
failed(translator.convertOperation(*module, llvmBuilder)))
2392 if (
failed(translator.convertComdats()))
2394 if (
failed(translator.convertFunctionSignatures()))
2396 if (
failed(translator.convertGlobalsAndAliases()))
2398 if (
failed(translator.convertIFuncs()))
2400 if (
failed(translator.createTBAAMetadata()))
2402 if (
failed(translator.createIdentMetadata()))
2404 if (
failed(translator.createCommandlineMetadata()))
2406 if (
failed(translator.createDependentLibrariesMetadata()))
2410 for (Operation &o :
getModuleBody(module).getOperations()) {
2411 if (!isa<LLVM::LLVMFuncOp, LLVM::AliasOp, LLVM::GlobalOp,
2412 LLVM::GlobalCtorsOp, LLVM::GlobalDtorsOp, LLVM::ComdatOp,
2413 LLVM::IFuncOp>(&o) &&
2414 !o.hasTrait<OpTrait::IsTerminator>() &&
2415 failed(translator.convertOperation(o, llvmBuilder))) {
2423 if (
failed(translator.convertFunctions()))
2428 if (
failed(translator.convertUnresolvedBlockAddress()))
2433 translator.debugTranslation->addModuleFlagsIfNotPresent();
2436 if (
auto *ompBuilder = translator.getOpenMPBuilder())
2437 ompBuilder->finalize();
2439 if (!disableVerification &&
2440 llvm::verifyModule(*translator.llvmModule, &llvm::errs()))
2443 return std::move(translator.llvmModule);