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)) {
594 auto intTy = dyn_cast<IntegerType>(intAttr.getType());
596 if (intTy && (intTy.isUnsigned() || intTy.getWidth() == 1))
597 value = intAttr.getValue().zextOrTrunc(llvmType->getIntegerBitWidth());
599 value = intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth());
600 return llvm::ConstantInt::get(llvmType, value);
602 if (
auto floatAttr = dyn_cast<FloatAttr>(attr)) {
603 const llvm::fltSemantics &sem = floatAttr.getValue().getSemantics();
608 unsigned floatWidth = APFloat::getSizeInBits(sem);
609 if (llvmType->isIntegerTy(floatWidth))
610 return llvm::ConstantInt::get(llvmType,
611 floatAttr.getValue().bitcastToAPInt());
613 llvm::Type::getFloatingPointTy(llvmType->getContext(),
614 floatAttr.getValue().getSemantics())) {
615 emitError(loc,
"FloatAttr does not match expected type of the constant");
618 return llvm::ConstantFP::get(llvmType, floatAttr.getValue());
620 if (
auto funcAttr = dyn_cast<FlatSymbolRefAttr>(attr))
621 return llvm::ConstantExpr::getBitCast(
623 if (
auto splatAttr = dyn_cast<SplatElementsAttr>(attr)) {
624 llvm::Type *elementType;
625 uint64_t numElements;
626 bool isScalable =
false;
627 if (
auto *arrayTy = dyn_cast<llvm::ArrayType>(llvmType)) {
628 elementType = arrayTy->getElementType();
629 numElements = arrayTy->getNumElements();
630 }
else if (
auto *fVectorTy = dyn_cast<llvm::FixedVectorType>(llvmType)) {
631 elementType = fVectorTy->getElementType();
632 numElements = fVectorTy->getNumElements();
633 }
else if (
auto *sVectorTy = dyn_cast<llvm::ScalableVectorType>(llvmType)) {
634 elementType = sVectorTy->getElementType();
635 numElements = sVectorTy->getMinNumElements();
638 llvm_unreachable(
"unrecognized constant vector type");
643 bool elementTypeSequential =
644 isa<llvm::ArrayType, llvm::VectorType>(elementType);
647 elementTypeSequential ? splatAttr
649 loc, moduleTranslation);
652 if (llvmType->isVectorTy())
653 return llvm::ConstantVector::getSplat(
654 llvm::ElementCount::get(numElements, isScalable), child);
655 if (llvmType->isArrayTy()) {
656 auto *arrayType = llvm::ArrayType::get(elementType, numElements);
657 if (child->isNullValue() && !elementType->isFPOrFPVectorTy()) {
658 return llvm::ConstantAggregateZero::get(arrayType);
660 if (llvm::ConstantDataSequential::isElementTypeCompatible(elementType)) {
662 if (isa<llvm::IntegerType>(elementType)) {
663 if (llvm::ConstantInt *ci = dyn_cast<llvm::ConstantInt>(child)) {
664 if (ci->getBitWidth() == 8) {
666 return llvm::ConstantDataArray::get(elementType->getContext(),
669 if (ci->getBitWidth() == 16) {
671 return llvm::ConstantDataArray::get(elementType->getContext(),
674 if (ci->getBitWidth() == 32) {
676 return llvm::ConstantDataArray::get(elementType->getContext(),
679 if (ci->getBitWidth() == 64) {
681 return llvm::ConstantDataArray::get(elementType->getContext(),
689 std::vector<llvm::Constant *> constants(numElements, child);
690 return llvm::ConstantArray::get(arrayType, constants);
695 if (llvm::Constant *
result =
697 llvmType, moduleTranslation)) {
701 if (
auto denseResourceAttr = dyn_cast<DenseResourceElementsAttr>(attr)) {
707 if (
auto elementsAttr = dyn_cast<ElementsAttr>(attr)) {
708 assert(elementsAttr.getShapedType().hasStaticShape());
709 assert(!elementsAttr.getShapedType().getShape().empty() &&
710 "unexpected empty elements attribute shape");
713 constants.reserve(elementsAttr.getNumElements());
715 for (
auto n : elementsAttr.getValues<
Attribute>()) {
718 if (!constants.back())
723 constantsRef, elementsAttr.getShapedType().getShape(), llvmType, loc);
724 assert(constantsRef.empty() &&
"did not consume all elemental constants");
728 if (
auto stringAttr = dyn_cast<StringAttr>(attr)) {
729 return llvm::ConstantDataArray::get(moduleTranslation.
getLLVMContext(),
735 if (
auto arrayAttr = dyn_cast<ArrayAttr>(attr)) {
736 if (
auto *arrayTy = dyn_cast<llvm::ArrayType>(llvmType)) {
737 llvm::Type *elementType = arrayTy->getElementType();
739 llvm::Constant *elementCst =
nullptr;
741 constants.reserve(arrayTy->getNumElements());
742 for (
Attribute elementAttr : arrayAttr) {
746 if (!previousElementAttr || previousElementAttr != elementAttr) {
747 previousElementAttr = elementAttr;
753 constants.push_back(elementCst);
755 return llvm::ConstantArray::get(arrayTy, constants);
759 emitError(loc,
"unsupported constant value");
763ModuleTranslation::ModuleTranslation(
Operation *module,
764 std::unique_ptr<llvm::Module> llvmModule)
765 : mlirModule(module), llvmModule(std::move(llvmModule)),
769 *this, *this->llvmModule)),
770 typeTranslator(this->llvmModule->
getContext()),
773 "mlirModule should honor LLVM's module semantics.");
776ModuleTranslation::~ModuleTranslation() {
777 if (ompBuilder && !ompBuilder->isFinalized())
778 ompBuilder->finalize();
783 toProcess.push_back(®ion);
784 while (!toProcess.empty()) {
785 Region *current = toProcess.pop_back_val();
786 for (
Block &block : *current) {
787 blockMapping.erase(&block);
788 for (
Value arg : block.getArguments())
789 valueMapping.erase(arg);
791 for (
Value value : op.getResults())
792 valueMapping.erase(value);
793 if (op.hasSuccessors())
794 branchMapping.erase(&op);
795 if (isa<LLVM::GlobalOp>(op))
796 globalsMapping.erase(&op);
797 if (isa<LLVM::AliasOp>(op))
798 aliasesMapping.erase(&op);
799 if (isa<LLVM::IFuncOp>(op))
800 ifuncMapping.erase(&op);
801 if (isa<LLVM::CallOp>(op))
802 callMapping.erase(&op);
805 llvm::map_range(op.getRegions(), [](
Region &r) { return &r; }));
814 unsigned numArguments,
unsigned index) {
816 if (isa<LLVM::BrOp>(terminator))
823 auto branch = cast<BranchOpInterface>(terminator);
826 (!seenSuccessors.contains(successor) || successorOperands.
empty()) &&
827 "successors with arguments in LLVM branches must be different blocks");
828 seenSuccessors.insert(successor);
834 if (
auto condBranchOp = dyn_cast<LLVM::CondBrOp>(terminator)) {
837 return condBranchOp.getSuccessor(0) == current
838 ? condBranchOp.getTrueDestOperands()[
index]
839 : condBranchOp.getFalseDestOperands()[
index];
842 if (
auto switchOp = dyn_cast<LLVM::SwitchOp>(terminator)) {
845 if (switchOp.getDefaultDestination() == current)
846 return switchOp.getDefaultOperands()[
index];
847 for (
const auto &i : llvm::enumerate(switchOp.getCaseDestinations()))
848 if (i.value() == current)
849 return switchOp.getCaseOperands(i.index())[
index];
852 if (
auto indBrOp = dyn_cast<LLVM::IndirectBrOp>(terminator)) {
854 for (
const auto &i : llvm::enumerate(indBrOp->getSuccessors())) {
855 if (indBrOp->getSuccessor(i.index()) == current)
856 return indBrOp.getSuccessorOperands(i.index())[
index];
860 if (
auto invokeOp = dyn_cast<LLVM::InvokeOp>(terminator)) {
861 return invokeOp.getNormalDest() == current
862 ? invokeOp.getNormalDestOperands()[
index]
863 : invokeOp.getUnwindDestOperands()[
index];
867 "only branch, switch or invoke operations can be terminators "
868 "of a block that has successors");
876 for (
Block &bb : llvm::drop_begin(region)) {
878 auto phis = llvmBB->phis();
879 auto numArguments = bb.getNumArguments();
880 assert(numArguments == std::distance(phis.begin(), phis.end()));
881 for (
auto [
index, phiNode] : llvm::enumerate(phis)) {
882 for (
auto *pred : bb.getPredecessors()) {
888 llvm::Instruction *terminator =
890 assert(terminator &&
"missing the mapping for a terminator");
892 &bb, pred, numArguments,
index)),
893 terminator->getParent());
900 llvm::IRBuilderBase &builder, llvm::Intrinsic::ID intrinsic,
902 return builder.CreateIntrinsic(intrinsic, tys, args);
906 llvm::IRBuilderBase &builder, llvm::Intrinsic::ID intrinsic,
908 return builder.CreateIntrinsic(retTy, intrinsic, args);
913 Operation *intrOp, llvm::Intrinsic::ID intrinsic,
unsigned numResults,
917 assert(immArgPositions.size() == immArgAttrNames.size() &&
918 "LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
922 size_t numOpBundleOperands = 0;
923 auto opBundleSizesAttr = cast_if_present<DenseI32ArrayAttr>(
924 intrOp->
getAttr(LLVMDialect::getOpBundleSizesAttrName()));
925 auto opBundleTagsAttr = cast_if_present<ArrayAttr>(
926 intrOp->
getAttr(LLVMDialect::getOpBundleTagsAttrName()));
928 if (opBundleSizesAttr && opBundleTagsAttr) {
929 ArrayRef<int> opBundleSizes = opBundleSizesAttr.asArrayRef();
930 assert(opBundleSizes.size() == opBundleTagsAttr.size() &&
931 "operand bundles and tags do not match");
933 numOpBundleOperands = llvm::sum_of(opBundleSizes);
934 assert(numOpBundleOperands <= intrOp->getNumOperands() &&
935 "operand bundle operands is more than the number of operands");
938 size_t nextOperandIdx = 0;
939 opBundles.reserve(opBundleSizesAttr.size());
941 for (
auto [opBundleTagAttr, bundleSize] :
942 llvm::zip(opBundleTagsAttr, opBundleSizes)) {
943 auto bundleTag = cast<StringAttr>(opBundleTagAttr).str();
945 operands.slice(nextOperandIdx, bundleSize));
946 opBundles.emplace_back(std::move(bundleTag), std::move(bundleOperands));
947 nextOperandIdx += bundleSize;
952 auto opOperands = intrOp->
getOperands().drop_back(numOpBundleOperands);
953 auto operands = moduleTranslation.
lookupValues(opOperands);
955 for (
auto [immArgPos, immArgName] :
956 llvm::zip(immArgPositions, immArgAttrNames)) {
957 auto attr = llvm::cast<TypedAttr>(intrOp->
getAttr(immArgName));
958 assert(attr.getType().isIntOrFloat() &&
"expected int or float immarg");
959 auto *type = moduleTranslation.
convertType(attr.getType());
961 type, attr, intrOp->
getLoc(), moduleTranslation);
964 for (
auto &arg : args) {
966 arg = operands[opArg++];
971 for (
unsigned overloadedResultIdx : overloadedResults) {
972 if (numResults > 1) {
974 overloadedTypes.push_back(moduleTranslation.
convertType(
976 .getBody()[overloadedResultIdx]));
978 overloadedTypes.push_back(
982 for (
unsigned overloadedOperandIdx : overloadedOperands)
983 overloadedTypes.push_back(args[overloadedOperandIdx]->
getType());
984 llvm::Module *module = builder.GetInsertBlock()->getModule();
985 llvm::Function *llvmIntr = llvm::Intrinsic::getOrInsertDeclaration(
986 module, intrinsic, overloadedTypes);
988 return builder.CreateCall(llvmIntr, args, opBundles);
993LogicalResult ModuleTranslation::convertOperation(
Operation &op,
994 llvm::IRBuilderBase &builder,
995 bool recordInsertions) {
996 const LLVMTranslationDialectInterface *opIface = iface.
getInterfaceFor(&op);
998 return op.
emitError(
"cannot be converted to LLVM IR: missing "
999 "`LLVMTranslationDialectInterface` registration for "
1003 InstructionCapturingInserter::CollectionScope scope(builder,
1005 if (failed(opIface->convertOperation(&op, builder, *
this)))
1006 return op.
emitError(
"LLVM Translation failed for operation: ")
1009 return convertDialectAttributes(&op, scope.getCapturedInstructions());
1019LogicalResult ModuleTranslation::convertBlockImpl(
Block &bb,
1020 bool ignoreArguments,
1021 llvm::IRBuilderBase &builder,
1022 bool recordInsertions) {
1024 auto *subprogram = builder.GetInsertBlock()->getParent()->getSubprogram();
1032 if (!ignoreArguments) {
1034 unsigned numPredecessors =
1035 std::distance(predecessors.begin(), predecessors.end());
1037 auto wrappedType = arg.getType();
1040 "block argument does not have an LLVM type");
1041 builder.SetCurrentDebugLocation(
1042 debugTranslation->translateLoc(arg.getLoc(), subprogram));
1044 llvm::PHINode *phi = builder.CreatePHI(type, numPredecessors);
1050 for (
auto &op : bb) {
1052 builder.SetCurrentDebugLocation(
1053 debugTranslation->translateLoc(op.
getLoc(), subprogram));
1055 if (
failed(convertOperation(op, builder, recordInsertions)))
1059 if (
auto iface = dyn_cast<WeightedBranchOpInterface>(op))
1069 return module->getRegion(0).front();
1078 llvm::Constant *cst) {
1079 return (linkage == llvm::GlobalVariable::ExternalLinkage && !cst) ||
1080 linkage == llvm::GlobalVariable::ExternalWeakLinkage;
1086 llvm::GlobalValue *gv) {
1087 if (dsoLocalRequested)
1088 gv->setDSOLocal(
true);
1097static FailureOr<llvm::Attribute>
1099 StringRef value = StringRef()) {
1100 auto kind = llvm::Attribute::getAttrKindFromName(key);
1101 if (kind == llvm::Attribute::None)
1102 return llvm::Attribute::get(ctx, key, value);
1104 if (llvm::Attribute::isIntAttrKind(kind)) {
1106 return emitError(loc) <<
"LLVM attribute '" << key <<
"' expects a value";
1109 if (!value.getAsInteger(0,
result))
1110 return llvm::Attribute::get(ctx, kind,
result);
1111 return llvm::Attribute::get(ctx, key, value);
1115 return emitError(loc) <<
"LLVM attribute '" << key
1116 <<
"' does not expect a value, found '" << value
1119 return llvm::Attribute::get(ctx, kind);
1130static FailureOr<llvm::AttrBuilder>
1132 ArrayAttr arrayAttr, StringRef arrayAttrName) {
1133 llvm::AttrBuilder attrBuilder(ctx);
1138 if (
auto stringAttr = dyn_cast<StringAttr>(attr)) {
1139 FailureOr<llvm::Attribute> llvmAttr =
1141 if (failed(llvmAttr))
1143 attrBuilder.addAttribute(*llvmAttr);
1147 auto arrayAttr = dyn_cast<ArrayAttr>(attr);
1148 if (!arrayAttr || arrayAttr.size() != 2)
1149 return emitError(loc) <<
"expected '" << arrayAttrName
1150 <<
"' to contain string or array attributes";
1152 auto keyAttr = dyn_cast<StringAttr>(arrayAttr[0]);
1153 auto valueAttr = dyn_cast<StringAttr>(arrayAttr[1]);
1154 if (!keyAttr || !valueAttr)
1155 return emitError(loc) <<
"expected arrays within '" << arrayAttrName
1156 <<
"' to contain two strings";
1159 loc, ctx, keyAttr.getValue(), valueAttr.getValue());
1160 if (failed(llvmAttr))
1162 attrBuilder.addAttribute(*llvmAttr);
1168LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
1177 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
1179 llvm::Constant *cst =
nullptr;
1180 if (op.getValueOrNull()) {
1183 if (
auto strAttr = dyn_cast_or_null<StringAttr>(op.getValueOrNull())) {
1184 cst = llvm::ConstantDataArray::getString(
1185 llvmModule->getContext(), strAttr.getValue(),
false);
1186 type = cst->getType();
1193 auto linkage = convertLinkageToLLVM(op.getLinkage());
1199 if (!dropInitializer && !cst)
1200 cst = llvm::UndefValue::get(type);
1201 else if (dropInitializer && cst)
1204 auto *var =
new llvm::GlobalVariable(
1205 *llvmModule, type, op.getConstant(), linkage, cst, op.getSymName(),
1207 op.getThreadLocal_() ? llvm::GlobalValue::GeneralDynamicTLSModel
1208 : llvm::GlobalValue::NotThreadLocal,
1209 op.getAddrSpace(), op.getExternallyInitialized());
1211 if (std::optional<mlir::SymbolRefAttr> comdat = op.getComdat()) {
1212 auto selectorOp = cast<ComdatSelectorOp>(
1214 var->setComdat(comdatMapping.lookup(selectorOp));
1217 if (op.getUnnamedAddr().has_value())
1218 var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
1220 if (op.getSection().has_value())
1221 var->setSection(*op.getSection());
1225 std::optional<uint64_t> alignment = op.getAlignment();
1226 if (alignment.has_value())
1227 var->setAlignment(llvm::MaybeAlign(alignment.value()));
1229 var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
1231 globalsMapping.try_emplace(op, var);
1234 if (op.getDbgExprs()) {
1235 for (
auto exprAttr :
1236 op.getDbgExprs()->getAsRange<DIGlobalVariableExpressionAttr>()) {
1237 llvm::DIGlobalVariableExpression *diGlobalExpr =
1238 debugTranslation->translateGlobalVariableExpression(exprAttr);
1239 llvm::DIGlobalVariable *diGlobalVar = diGlobalExpr->getVariable();
1240 var->addDebugInfo(diGlobalExpr);
1259 llvm::DIScope *scope = diGlobalVar->getScope();
1260 if (
auto *mod = dyn_cast_if_present<llvm::DIModule>(scope))
1261 scope = mod->getScope();
1262 else if (
auto *cb = dyn_cast_if_present<llvm::DICommonBlock>(scope)) {
1264 dyn_cast_if_present<llvm::DISubprogram>(cb->getScope()))
1265 scope = sp->getUnit();
1266 }
else if (
auto *sp = dyn_cast_if_present<llvm::DISubprogram>(scope))
1267 scope = sp->getUnit();
1270 if (llvm::DICompileUnit *compileUnit =
1271 dyn_cast_if_present<llvm::DICompileUnit>(scope)) {
1274 allGVars[compileUnit].push_back(diGlobalExpr);
1280 FailureOr<llvm::AttrBuilder> convertedTargetSpecificAttrs =
1282 op.getTargetSpecificAttrsAttr(),
1283 op.getTargetSpecificAttrsAttrName());
1284 if (
failed(convertedTargetSpecificAttrs))
1286 var->addAttributes(*convertedTargetSpecificAttrs);
1290 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
1292 llvm::Constant *cst =
nullptr;
1293 llvm::GlobalValue::LinkageTypes linkage =
1294 convertLinkageToLLVM(op.getLinkage());
1295 llvm::Module &llvmMod = *llvmModule;
1298 llvm::GlobalAlias *var = llvm::GlobalAlias::create(
1299 type, op.getAddrSpace(), linkage, op.getSymName(), cst,
1302 var->setThreadLocalMode(op.getThreadLocal_()
1303 ? llvm::GlobalAlias::GeneralDynamicTLSModel
1304 : llvm::GlobalAlias::NotThreadLocal);
1309 if (op.getUnnamedAddr().has_value())
1310 var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
1312 var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
1314 aliasesMapping.try_emplace(op, var);
1318 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
1319 if (
Block *initializer = op.getInitializerBlock()) {
1320 llvm::IRBuilder<llvm::TargetFolder> builder(
1321 llvmModule->getContext(),
1322 llvm::TargetFolder(llvmModule->getDataLayout()));
1324 [[maybe_unused]]
int numConstantsHit = 0;
1325 [[maybe_unused]]
int numConstantsErased = 0;
1328 for (
auto &op : initializer->without_terminator()) {
1329 if (
failed(convertOperation(op, builder)))
1342 if (
auto *agg = dyn_cast<llvm::ConstantAggregate>(cst)) {
1345 int numUsers = std::distance(
result.use_begin(),
result.use_end());
1347 constantAggregateUseMap.try_emplace(agg, numUsers);
1350 iterator->second += numUsers;
1356 auto *cst = dyn_cast<llvm::ConstantAggregate>(
lookupValue(v));
1359 auto iter = constantAggregateUseMap.find(cst);
1360 assert(iter != constantAggregateUseMap.end() &&
"constant not found");
1362 if (iter->second == 0) {
1365 if (cst->user_empty()) {
1366 cst->destroyConstant();
1367 numConstantsErased++;
1369 constantAggregateUseMap.erase(iter);
1374 ReturnOp ret = cast<ReturnOp>(initializer->getTerminator());
1375 llvm::Constant *cst =
1376 cast<llvm::Constant>(
lookupValue(ret.getOperand(0)));
1377 auto *global = cast<llvm::GlobalVariable>(
lookupGlobal(op));
1379 global->setInitializer(cst);
1383 for (
auto it : constantAggregateUseMap) {
1384 auto *cst = it.first;
1385 cst->removeDeadConstantUsers();
1386 if (cst->user_empty()) {
1387 cst->destroyConstant();
1388 numConstantsErased++;
1392 LLVM_DEBUG(llvm::dbgs()
1393 <<
"Convert initializer for " << op.
getName() <<
"\n";
1394 llvm::dbgs() << numConstantsHit <<
" new constants hit\n";
1396 << numConstantsErased <<
" dangling constants erased\n";);
1402 auto ctorOp = dyn_cast<GlobalCtorsOp>(op);
1403 auto dtorOp = dyn_cast<GlobalDtorsOp>(op);
1404 if (!ctorOp && !dtorOp)
1410 if ((ctorOp && ctorOp.getCtors().empty()) ||
1411 (dtorOp && dtorOp.getDtors().empty())) {
1412 llvm::IRBuilder<llvm::TargetFolder> builder(
1413 llvmModule->getContext(),
1414 llvm::TargetFolder(llvmModule->getDataLayout()));
1415 llvm::Type *eltTy = llvm::StructType::get(
1416 builder.getInt32Ty(), builder.getPtrTy(), builder.getPtrTy());
1417 llvm::ArrayType *at = llvm::ArrayType::get(eltTy, 0);
1418 llvm::Constant *zeroInit = llvm::Constant::getNullValue(at);
1419 (void)
new llvm::GlobalVariable(
1420 *llvmModule, zeroInit->getType(),
false,
1421 llvm::GlobalValue::AppendingLinkage, zeroInit,
1422 ctorOp ?
"llvm.global_ctors" :
"llvm.global_dtors");
1425 ? llvm::zip(ctorOp.getCtors(), ctorOp.getPriorities())
1426 : llvm::zip(dtorOp.getDtors(), dtorOp.getPriorities());
1427 auto appendGlobalFn =
1428 ctorOp ? llvm::appendToGlobalCtors : llvm::appendToGlobalDtors;
1429 for (
const auto &[sym, prio] : range) {
1432 appendGlobalFn(*llvmModule, f, cast<IntegerAttr>(prio).getInt(),
1438 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>())
1439 if (
failed(convertDialectAttributes(op, {})))
1444 for (
const auto &[compileUnit, globals] : allGVars) {
1445 compileUnit->replaceGlobalVariables(
1450 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
1451 Block &initializer = op.getInitializerBlock();
1452 llvm::IRBuilder<llvm::TargetFolder> builder(
1453 llvmModule->getContext(),
1454 llvm::TargetFolder(llvmModule->getDataLayout()));
1457 if (
failed(convertOperation(op, builder)))
1464 auto *cst = cast<llvm::Constant>(
lookupValue(ret.getOperand(0)));
1465 assert(aliasesMapping.count(op));
1466 auto *alias = cast<llvm::GlobalAlias>(aliasesMapping[op]);
1467 alias->setAliasee(cst);
1470 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::AliasOp>())
1471 if (
failed(convertDialectAttributes(op, {})))
1479 const llvm::APInt &value) {
1480 llvm::Constant *constant = llvm::ConstantInt::get(context, value);
1481 return llvm::ConstantAsMetadata::get(constant);
1486 const llvm::APInt &value) {
1494 llvm::Metadata *typeMD =
1495 llvm::ConstantAsMetadata::get(llvm::UndefValue::get(type));
1496 llvm::Metadata *isSignedMD =
1498 return llvm::MDNode::get(context, {typeMD, isSignedMD});
1506 values, std::back_inserter(mdValues), [&context](int32_t value) {
1509 return llvm::MDNode::get(context, mdValues);
1512LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
1515 blockMapping.clear();
1516 valueMapping.clear();
1517 branchMapping.clear();
1519 llvm::LLVMContext &llvmContext = llvmFunc->getContext();
1522 for (
auto [mlirArg, llvmArg] :
1523 llvm::zip(func.getArguments(), llvmFunc->args()))
1527 if (func.getPersonality()) {
1528 llvm::Type *ty = llvm::PointerType::getUnqual(llvmFunc->getContext());
1529 if (llvm::Constant *pfunc =
getLLVMConstant(ty, func.getPersonalityAttr(),
1530 func.getLoc(), *
this))
1531 llvmFunc->setPersonalityFn(pfunc);
1534 if (std::optional<StringRef> section = func.getSection())
1535 llvmFunc->setSection(*section);
1537 if (func.getArmStreaming())
1538 llvmFunc->addFnAttr(
"aarch64_pstate_sm_enabled");
1539 else if (func.getArmLocallyStreaming())
1540 llvmFunc->addFnAttr(
"aarch64_pstate_sm_body");
1541 else if (func.getArmStreamingCompatible())
1542 llvmFunc->addFnAttr(
"aarch64_pstate_sm_compatible");
1544 if (func.getArmNewZa())
1545 llvmFunc->addFnAttr(
"aarch64_new_za");
1546 else if (func.getArmInZa())
1547 llvmFunc->addFnAttr(
"aarch64_in_za");
1548 else if (func.getArmOutZa())
1549 llvmFunc->addFnAttr(
"aarch64_out_za");
1550 else if (func.getArmInoutZa())
1551 llvmFunc->addFnAttr(
"aarch64_inout_za");
1552 else if (func.getArmPreservesZa())
1553 llvmFunc->addFnAttr(
"aarch64_preserves_za");
1555 if (
auto targetCpu = func.getTargetCpu())
1556 llvmFunc->addFnAttr(
"target-cpu", *targetCpu);
1558 if (
auto tuneCpu = func.getTuneCpu())
1559 llvmFunc->addFnAttr(
"tune-cpu", *tuneCpu);
1561 if (
auto reciprocalEstimates = func.getReciprocalEstimates())
1562 llvmFunc->addFnAttr(
"reciprocal-estimates", *reciprocalEstimates);
1564 if (
auto preferVectorWidth = func.getPreferVectorWidth())
1565 llvmFunc->addFnAttr(
"prefer-vector-width", *preferVectorWidth);
1567 if (
auto attr = func.getVscaleRange())
1568 llvmFunc->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
1570 attr->getMaxRange().getInt()));
1572 if (
auto noSignedZerosFpMath = func.getNoSignedZerosFpMath())
1573 llvmFunc->addFnAttr(
"no-signed-zeros-fp-math",
1574 llvm::toStringRef(*noSignedZerosFpMath));
1576 if (
auto fpContract = func.getFpContract())
1577 llvmFunc->addFnAttr(
"fp-contract", *fpContract);
1579 if (
auto instrumentFunctionEntry = func.getInstrumentFunctionEntry())
1580 llvmFunc->addFnAttr(
"instrument-function-entry", *instrumentFunctionEntry);
1582 if (
auto instrumentFunctionExit = func.getInstrumentFunctionExit())
1583 llvmFunc->addFnAttr(
"instrument-function-exit", *instrumentFunctionExit);
1586 for (
auto &bb : func) {
1587 auto *llvmBB = llvm::BasicBlock::Create(llvmContext);
1588 llvmBB->insertInto(llvmFunc);
1595 for (
Block *bb : blocks) {
1596 CapturingIRBuilder builder(llvmContext,
1597 llvm::TargetFolder(llvmModule->getDataLayout()));
1598 if (
failed(convertBlockImpl(*bb, bb->isEntryBlock(), builder,
1608 return convertDialectAttributes(func, {});
1611LogicalResult ModuleTranslation::convertDialectAttributes(
1612 Operation *op, ArrayRef<llvm::Instruction *> instructions) {
1614 if (
failed(iface.amendOperation(op, instructions, attribute, *
this)))
1622 llvm::Function *llvmFunc) {
1623 if (!
func.getMemoryEffects())
1626 MemoryEffectsAttr memEffects =
func.getMemoryEffectsAttr();
1629 llvm::MemoryEffects newMemEffects =
1630 llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
1631 convertModRefInfoToLLVM(memEffects.getArgMem()));
1632 newMemEffects |= llvm::MemoryEffects(
1633 llvm::MemoryEffects::Location::InaccessibleMem,
1634 convertModRefInfoToLLVM(memEffects.getInaccessibleMem()));
1636 llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
1637 convertModRefInfoToLLVM(memEffects.getOther()));
1639 llvm::MemoryEffects(llvm::MemoryEffects::Location::ErrnoMem,
1640 convertModRefInfoToLLVM(memEffects.getErrnoMem()));
1642 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem0,
1643 convertModRefInfoToLLVM(memEffects.getTargetMem0()));
1645 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem1,
1646 convertModRefInfoToLLVM(memEffects.getTargetMem1()));
1647 llvmFunc->setMemoryEffects(newMemEffects);
1652 if (!allocSizeAttr || allocSizeAttr.empty())
1653 return llvm::Attribute{};
1655 unsigned elemSize =
static_cast<unsigned>(allocSizeAttr[0]);
1656 std::optional<unsigned> numElems;
1657 if (allocSizeAttr.size() > 1)
1658 numElems =
static_cast<unsigned>(allocSizeAttr[1]);
1660 return llvm::Attribute::getWithAllocSizeArgs(
getLLVMContext(), elemSize,
1664 llvm::AttrBuilder &Attrs) {
1665 std::optional<DenormalFPEnvAttr> denormalFpEnv =
func.getDenormalFpenv();
1669 llvm::DenormalMode DefaultMode(
1670 convertDenormalModeKindToLLVM(denormalFpEnv->getDefaultOutputMode()),
1671 convertDenormalModeKindToLLVM(denormalFpEnv->getDefaultInputMode()));
1672 llvm::DenormalMode FloatMode(
1673 convertDenormalModeKindToLLVM(denormalFpEnv->getFloatOutputMode()),
1674 convertDenormalModeKindToLLVM(denormalFpEnv->getFloatInputMode()));
1676 llvm::DenormalFPEnv FPEnv(DefaultMode, FloatMode);
1677 Attrs.addDenormalFPEnvAttr(FPEnv);
1682 llvm::Function *llvmFunc) {
1684 llvm::AttrBuilder AttrBuilder(llvmFunc->getContext());
1686 if (
func.getNoInlineAttr())
1687 llvmFunc->addFnAttr(llvm::Attribute::NoInline);
1688 if (
func.getAlwaysInlineAttr())
1689 llvmFunc->addFnAttr(llvm::Attribute::AlwaysInline);
1690 if (
func.getInlineHintAttr())
1691 llvmFunc->addFnAttr(llvm::Attribute::InlineHint);
1692 if (
func.getOptimizeNoneAttr())
1693 llvmFunc->addFnAttr(llvm::Attribute::OptimizeNone);
1694 if (
func.getReturnsTwiceAttr())
1695 llvmFunc->addFnAttr(llvm::Attribute::ReturnsTwice);
1696 if (
func.getColdAttr())
1697 llvmFunc->addFnAttr(llvm::Attribute::Cold);
1698 if (
func.getHotAttr())
1699 llvmFunc->addFnAttr(llvm::Attribute::Hot);
1700 if (
func.getNoduplicateAttr())
1701 llvmFunc->addFnAttr(llvm::Attribute::NoDuplicate);
1702 if (
func.getConvergentAttr())
1703 llvmFunc->addFnAttr(llvm::Attribute::Convergent);
1704 if (
func.getNoUnwindAttr())
1705 llvmFunc->addFnAttr(llvm::Attribute::NoUnwind);
1706 if (
func.getWillReturnAttr())
1707 llvmFunc->addFnAttr(llvm::Attribute::WillReturn);
1708 if (
func.getNoreturnAttr())
1709 llvmFunc->addFnAttr(llvm::Attribute::NoReturn);
1710 if (
func.getOptsizeAttr())
1711 llvmFunc->addFnAttr(llvm::Attribute::OptimizeForSize);
1712 if (
func.getMinsizeAttr())
1713 llvmFunc->addFnAttr(llvm::Attribute::MinSize);
1714 if (
func.getSaveRegParamsAttr())
1715 llvmFunc->addFnAttr(
"save-reg-params");
1716 if (
func.getNoCallerSavedRegistersAttr())
1717 llvmFunc->addFnAttr(
"no_caller_saved_registers");
1718 if (
func.getNocallbackAttr())
1719 llvmFunc->addFnAttr(llvm::Attribute::NoCallback);
1720 if (StringAttr modFormat =
func.getModularFormatAttr())
1721 llvmFunc->addFnAttr(
"modular-format", modFormat.getValue());
1722 if (TargetFeaturesAttr targetFeatAttr =
func.getTargetFeaturesAttr())
1723 llvmFunc->addFnAttr(
"target-features", targetFeatAttr.getFeaturesString());
1724 if (FramePointerKindAttr fpAttr =
func.getFramePointerAttr())
1725 llvmFunc->addFnAttr(
"frame-pointer", stringifyFramePointerKind(
1726 fpAttr.getFramePointerKind()));
1727 if (UWTableKindAttr uwTableKindAttr =
func.getUwtableKindAttr())
1728 llvmFunc->setUWTableKind(
1729 convertUWTableKindToLLVM(uwTableKindAttr.getUwtableKind()));
1730 if (StringAttr zcsr =
func.getZeroCallUsedRegsAttr())
1731 llvmFunc->addFnAttr(
"zero-call-used-regs", zcsr.getValue());
1734 if (noBuiltins.empty())
1735 llvmFunc->addFnAttr(
"no-builtins");
1746 llvmFunc->addFnAttr(attr);
1751 llvmFunc->addFnAttrs(AttrBuilder);
1756 llvm::Function *llvmFunc,
1758 llvm::LLVMContext &llvmContext = llvmFunc->getContext();
1760 if (VecTypeHintAttr vecTypeHint =
func.getVecTypeHintAttr()) {
1761 Type type = vecTypeHint.getHint().getValue();
1762 llvm::Type *llvmType = translation.
convertType(type);
1763 bool isSigned = vecTypeHint.getIsSigned();
1764 llvmFunc->setMetadata(
1765 func.getVecTypeHintAttrName(),
1770 func.getWorkGroupSizeHint()) {
1771 llvmFunc->setMetadata(
1772 func.getWorkGroupSizeHintAttrName(),
1777 func.getReqdWorkGroupSize()) {
1778 llvmFunc->setMetadata(
1779 func.getReqdWorkGroupSizeAttrName(),
1783 if (std::optional<uint32_t> intelReqdSubGroupSize =
1784 func.getIntelReqdSubGroupSize()) {
1785 llvmFunc->setMetadata(
1786 func.getIntelReqdSubGroupSizeAttrName(),
1788 llvm::APInt(32, *intelReqdSubGroupSize)));
1793 llvm::Attribute::AttrKind llvmKind,
1798 .Case([&](TypeAttr typeAttr) {
1799 attrBuilder.addTypeAttr(
1800 llvmKind, moduleTranslation.
convertType(typeAttr.getValue()));
1803 .Case([&](IntegerAttr intAttr) {
1804 attrBuilder.addRawIntAttr(llvmKind, intAttr.getInt());
1807 .Case([&](UnitAttr) {
1808 attrBuilder.addAttribute(llvmKind);
1811 .Case([&](LLVM::ConstantRangeAttr rangeAttr) {
1812 attrBuilder.addConstantRangeAttr(
1814 llvm::ConstantRange(rangeAttr.getLower(), rangeAttr.getUpper()));
1817 .Default([loc](
auto) {
1818 return emitError(loc,
"unsupported parameter attribute type");
1822FailureOr<llvm::AttrBuilder>
1823ModuleTranslation::convertParameterAttrs(LLVMFuncOp func,
int argIdx,
1824 DictionaryAttr paramAttrs) {
1825 llvm::AttrBuilder attrBuilder(llvmModule->getContext());
1827 Location loc = func.getLoc();
1829 for (
auto namedAttr : paramAttrs) {
1830 auto it = attrNameToKindMapping.find(namedAttr.getName());
1831 if (it != attrNameToKindMapping.end()) {
1832 llvm::Attribute::AttrKind llvmKind = it->second;
1836 }
else if (namedAttr.getNameDialect()) {
1837 if (
failed(iface.convertParameterAttr(func, argIdx, namedAttr, *
this)))
1846 ArgAndResultAttrsOpInterface attrsOp, llvm::CallBase *call,
1849 if (ArrayAttr argAttrsArray = attrsOp.getArgAttrsAttr()) {
1850 unsigned argAttrIdx = 0;
1851 llvm::SmallDenseSet<unsigned> immArgPositionsSet(immArgPositions.begin(),
1852 immArgPositions.end());
1853 for (
unsigned argIdx : llvm::seq<unsigned>(call->arg_size())) {
1854 if (argAttrIdx >= argAttrsArray.size())
1857 if (immArgPositionsSet.contains(argIdx))
1860 auto argAttrs = cast<DictionaryAttr>(argAttrsArray[argAttrIdx++]);
1861 if (argAttrs.empty())
1864 FailureOr<llvm::AttrBuilder> attrBuilder =
1865 convertParameterAttrs(attrsOp->getLoc(), argAttrs);
1866 if (failed(attrBuilder))
1868 call->addParamAttrs(argIdx, *attrBuilder);
1873 if (ArrayAttr resAttrsArray = attrsOp.getResAttrsAttr()) {
1874 if (!resAttrsArray.empty()) {
1875 auto resAttrs = cast<DictionaryAttr>(resAttrsArray[0]);
1876 FailureOr<llvm::AttrBuilder> attrBuilder =
1877 convertParameterAttrs(attrsOp->getLoc(), resAttrs);
1878 if (failed(attrBuilder))
1880 call->addRetAttrs(*attrBuilder);
1887std::optional<llvm::Attribute>
1889 if (
auto str = dyn_cast<StringAttr>(a))
1890 return llvm::Attribute::get(ctx, (
"no-builtin-" + str.getValue()).str());
1891 return std::nullopt;
1894std::optional<llvm::Attribute>
1897 StringAttr name = namedAttr.
getName();
1900 if (
auto strVal = dyn_cast<StringAttr>(value))
1901 return llvm::Attribute::get(ctx, name.getValue(), strVal.getValue());
1902 if (mlir::isa<UnitAttr>(value))
1903 return llvm::Attribute::get(ctx, name.getValue());
1904 return std::nullopt;
1907FailureOr<llvm::AttrBuilder>
1908ModuleTranslation::convertParameterAttrs(
Location loc,
1909 DictionaryAttr paramAttrs) {
1910 llvm::AttrBuilder attrBuilder(llvmModule->getContext());
1913 for (
auto namedAttr : paramAttrs) {
1914 auto it = attrNameToKindMapping.find(namedAttr.getName());
1915 if (it != attrNameToKindMapping.end()) {
1916 llvm::Attribute::AttrKind llvmKind = it->second;
1926LogicalResult ModuleTranslation::convertFunctionSignatures() {
1929 for (
auto function :
getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
1930 llvm::FunctionCallee llvmFuncCst = llvmModule->getOrInsertFunction(
1932 cast<llvm::FunctionType>(
convertType(function.getFunctionType())));
1933 llvm::Function *llvmFunc = cast<llvm::Function>(llvmFuncCst.getCallee());
1934 llvmFunc->setLinkage(convertLinkageToLLVM(function.getLinkage()));
1935 llvmFunc->setCallingConv(convertCConvToLLVM(function.getCConv()));
1946 if (std::optional<uint64_t> entryCount = function.getFunctionEntryCount())
1947 llvmFunc->setEntryCount(entryCount.value());
1950 if (
ArrayAttr allResultAttrs = function.getAllResultAttrs()) {
1951 DictionaryAttr resultAttrs = cast<DictionaryAttr>(allResultAttrs[0]);
1952 FailureOr<llvm::AttrBuilder> attrBuilder =
1953 convertParameterAttrs(function, -1, resultAttrs);
1956 llvmFunc->addRetAttrs(*attrBuilder);
1960 for (
auto [argIdx, llvmArg] : llvm::enumerate(llvmFunc->args())) {
1961 if (DictionaryAttr argAttrs = function.getArgAttrDict(argIdx)) {
1962 FailureOr<llvm::AttrBuilder> attrBuilder =
1963 convertParameterAttrs(function, argIdx, argAttrs);
1966 llvmArg.addAttrs(*attrBuilder);
1971 FailureOr<llvm::AttrBuilder> convertedPassthroughAttrs =
1973 function.getPassthroughAttr(),
1974 function.getPassthroughAttrName());
1975 if (
failed(convertedPassthroughAttrs))
1977 llvmFunc->addFnAttrs(*convertedPassthroughAttrs);
1980 llvmFunc->setVisibility(convertVisibilityToLLVM(function.getVisibility_()));
1983 if (std::optional<mlir::SymbolRefAttr> comdat = function.getComdat()) {
1984 auto selectorOp = cast<ComdatSelectorOp>(
1986 llvmFunc->setComdat(comdatMapping.lookup(selectorOp));
1989 if (
auto gc = function.getGarbageCollector())
1990 llvmFunc->setGC(gc->str());
1992 if (
auto unnamedAddr = function.getUnnamedAddr())
1993 llvmFunc->setUnnamedAddr(convertUnnamedAddrToLLVM(*unnamedAddr));
1995 if (
auto alignment = function.getAlignment())
1996 llvmFunc->setAlignment(llvm::MaybeAlign(*alignment));
1999 debugTranslation->translate(function, *llvmFunc);
2005LogicalResult ModuleTranslation::convertFunctions() {
2007 for (
auto function :
getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
2010 if (function.isExternal()) {
2011 if (
failed(convertDialectAttributes(function, {})))
2016 if (
failed(convertOneFunction(function)))
2023LogicalResult ModuleTranslation::convertIFuncs() {
2024 for (
auto op :
getModuleBody(mlirModule).getOps<IFuncOp>()) {
2025 llvm::Type *type =
convertType(op.getIFuncType());
2026 llvm::GlobalValue::LinkageTypes linkage =
2027 convertLinkageToLLVM(op.getLinkage());
2028 llvm::Constant *resolver;
2030 resolver = cast<llvm::Constant>(resolverFn);
2033 op.getResolverAttr());
2034 resolver = cast<llvm::Constant>(
lookupAlias(aliasOp));
2038 llvm::GlobalIFunc::create(type, op.getAddressSpace(), linkage,
2039 op.getSymName(), resolver, llvmModule.get());
2041 ifunc->setUnnamedAddr(convertUnnamedAddrToLLVM(op.getUnnamedAddr()));
2042 ifunc->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
2044 ifuncMapping.try_emplace(op, ifunc);
2050LogicalResult ModuleTranslation::convertComdats() {
2051 for (
auto comdatOp :
getModuleBody(mlirModule).getOps<ComdatOp>()) {
2052 for (
auto selectorOp : comdatOp.getOps<ComdatSelectorOp>()) {
2054 if (module->getComdatSymbolTable().contains(selectorOp.getSymName()))
2056 <<
"comdat selection symbols must be unique even in different "
2058 llvm::Comdat *comdat =
module->getOrInsertComdat(selectorOp.getSymName());
2059 comdat->setSelectionKind(convertComdatToLLVM(selectorOp.getComdat()));
2060 comdatMapping.try_emplace(selectorOp, comdat);
2066LogicalResult ModuleTranslation::convertUnresolvedBlockAddress() {
2067 for (
auto &[blockAddressOp, llvmCst] : unresolvedBlockAddressMapping) {
2068 BlockAddressAttr blockAddressAttr = blockAddressOp.getBlockAddr();
2070 assert(llvmBlock &&
"expected LLVM blocks to be already translated");
2073 auto *llvmBlockAddr = llvm::BlockAddress::get(
2074 lookupFunction(blockAddressAttr.getFunction().getValue()), llvmBlock);
2075 llvmCst->replaceAllUsesWith(llvmBlockAddr);
2076 assert(llvmCst->use_empty() &&
"expected all uses to be replaced");
2077 cast<llvm::GlobalVariable>(llvmCst)->eraseFromParent();
2079 unresolvedBlockAddressMapping.clear();
2084 llvm::Instruction *inst) {
2085 if (llvm::MDNode *node = loopAnnotationTranslation->getAccessGroups(op))
2086 inst->setMetadata(llvm::LLVMContext::MD_access_group, node);
2091 auto [scopeIt, scopeInserted] =
2092 aliasScopeMetadataMapping.try_emplace(aliasScopeAttr,
nullptr);
2094 return scopeIt->second;
2095 llvm::LLVMContext &ctx = llvmModule->getContext();
2096 auto dummy = llvm::MDNode::getTemporary(ctx, {});
2098 auto [domainIt, insertedDomain] = aliasDomainMetadataMapping.try_emplace(
2099 aliasScopeAttr.getDomain(),
nullptr);
2100 if (insertedDomain) {
2103 operands.push_back(dummy.get());
2104 if (StringAttr description = aliasScopeAttr.getDomain().getDescription())
2105 operands.push_back(llvm::MDString::get(ctx, description));
2106 domainIt->second = llvm::MDNode::get(ctx, operands);
2109 if (
auto stringAttr =
2110 dyn_cast<StringAttr>(aliasScopeAttr.getDomain().getId()))
2111 replacement = llvm::MDString::get(ctx, stringAttr.getValue());
2114 domainIt->second->replaceOperandWith(0,
replacement);
2117 assert(domainIt->second &&
"Scope's domain should already be valid");
2120 operands.push_back(dummy.get());
2121 operands.push_back(domainIt->second);
2122 if (StringAttr description = aliasScopeAttr.getDescription())
2123 operands.push_back(llvm::MDString::get(ctx, description));
2124 scopeIt->second = llvm::MDNode::get(ctx, operands);
2127 if (
auto stringAttr = dyn_cast<StringAttr>(aliasScopeAttr.getId()))
2128 replacement = llvm::MDString::get(ctx, stringAttr.getValue());
2131 scopeIt->second->replaceOperandWith(0,
replacement);
2132 return scopeIt->second;
2138 nodes.reserve(aliasScopeAttrs.size());
2139 for (AliasScopeAttr aliasScopeAttr : aliasScopeAttrs)
2145 llvm::Instruction *inst) {
2146 auto populateScopeMetadata = [&](ArrayAttr aliasScopeAttrs,
unsigned kind) {
2147 if (!aliasScopeAttrs || aliasScopeAttrs.empty())
2150 llvm::to_vector(aliasScopeAttrs.getAsRange<AliasScopeAttr>()));
2151 inst->setMetadata(kind, node);
2154 populateScopeMetadata(op.getAliasScopesOrNull(),
2155 llvm::LLVMContext::MD_alias_scope);
2156 populateScopeMetadata(op.getNoAliasScopesOrNull(),
2157 llvm::LLVMContext::MD_noalias);
2160llvm::MDNode *ModuleTranslation::getTBAANode(TBAATagAttr tbaaAttr)
const {
2161 return tbaaMetadataMapping.lookup(tbaaAttr);
2165 llvm::Instruction *inst) {
2166 ArrayAttr tagRefs = op.getTBAATagsOrNull();
2167 if (!tagRefs || tagRefs.empty())
2174 if (tagRefs.size() > 1) {
2175 op.emitWarning() <<
"TBAA access tags were not translated, because LLVM "
2176 "IR only supports a single tag per instruction";
2180 llvm::MDNode *node = getTBAANode(cast<TBAATagAttr>(tagRefs[0]));
2181 inst->setMetadata(llvm::LLVMContext::MD_tbaa, node);
2185 DereferenceableOpInterface op, llvm::Instruction *inst) {
2186 DereferenceableAttr derefAttr = op.getDereferenceableOrNull();
2190 llvm::MDNode *derefSizeNode = llvm::MDNode::get(
2192 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2193 llvm::IntegerType::get(
getLLVMContext(), 64), derefAttr.getBytes())));
2194 unsigned kindId = derefAttr.getMayBeNull()
2195 ? llvm::LLVMContext::MD_dereferenceable_or_null
2196 : llvm::LLVMContext::MD_dereferenceable;
2197 inst->setMetadata(kindId, derefSizeNode);
2202 llvm::transform(op.getWeights(), std::back_inserter(weights),
2203 [](int32_t value) { return static_cast<uint32_t>(value); });
2204 if (weights.empty())
2208 assert(inst &&
"expected the operation to have a mapping to an instruction");
2210 llvm::LLVMContext::MD_prof,
2214LogicalResult ModuleTranslation::createTBAAMetadata() {
2215 llvm::LLVMContext &ctx = llvmModule->getContext();
2216 llvm::IntegerType *offsetTy = llvm::IntegerType::get(ctx, 64);
2227 walker.
addWalk([&](TBAARootAttr root) {
2229 if (StringAttr
id = root.getId()) {
2230 node = llvm::MDNode::get(ctx, llvm::MDString::get(ctx,
id));
2233 auto selfRef = llvm::MDNode::getTemporary(ctx, {});
2234 node = llvm::MDNode::get(ctx, {selfRef.get()});
2235 node->replaceOperandWith(0, node);
2237 tbaaMetadataMapping.insert({root, node});
2240 walker.
addWalk([&](TBAATypeDescriptorAttr descriptor) {
2241 SmallVector<llvm::Metadata *> operands;
2242 operands.push_back(llvm::MDString::get(ctx, descriptor.getId()));
2243 for (TBAAMemberAttr member : descriptor.getMembers()) {
2244 operands.push_back(tbaaMetadataMapping.lookup(member.getTypeDesc()));
2245 operands.push_back(llvm::ConstantAsMetadata::get(
2246 llvm::ConstantInt::get(offsetTy, member.getOffset())));
2249 tbaaMetadataMapping.insert({descriptor, llvm::MDNode::get(ctx, operands)});
2252 walker.
addWalk([&](TBAATagAttr tag) {
2253 SmallVector<llvm::Metadata *> operands;
2255 operands.push_back(tbaaMetadataMapping.lookup(tag.getBaseType()));
2256 operands.push_back(tbaaMetadataMapping.lookup(tag.getAccessType()));
2258 operands.push_back(llvm::ConstantAsMetadata::get(
2259 llvm::ConstantInt::get(offsetTy, tag.getOffset())));
2260 if (tag.getConstant())
2262 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(offsetTy, 1)));
2264 tbaaMetadataMapping.insert({tag, llvm::MDNode::get(ctx, operands)});
2267 mlirModule->walk([&](AliasAnalysisOpInterface analysisOpInterface) {
2268 if (
auto attr = analysisOpInterface.getTBAATagsOrNull())
2275LogicalResult ModuleTranslation::createIdentMetadata() {
2276 if (
auto attr = mlirModule->getAttrOfType<StringAttr>(
2277 LLVMDialect::getIdentAttrName())) {
2278 StringRef ident = attr;
2279 llvm::LLVMContext &ctx = llvmModule->getContext();
2280 llvm::NamedMDNode *namedMd =
2281 llvmModule->getOrInsertNamedMetadata(LLVMDialect::getIdentAttrName());
2282 llvm::MDNode *md = llvm::MDNode::get(ctx, llvm::MDString::get(ctx, ident));
2283 namedMd->addOperand(md);
2289LogicalResult ModuleTranslation::createCommandlineMetadata() {
2290 if (
auto attr = mlirModule->getAttrOfType<StringAttr>(
2291 LLVMDialect::getCommandlineAttrName())) {
2292 StringRef cmdLine = attr;
2293 llvm::LLVMContext &ctx = llvmModule->getContext();
2294 llvm::NamedMDNode *nmd = llvmModule->getOrInsertNamedMetadata(
2295 LLVMDialect::getCommandlineAttrName());
2297 llvm::MDNode::get(ctx, llvm::MDString::get(ctx, cmdLine));
2298 nmd->addOperand(md);
2304LogicalResult ModuleTranslation::createDependentLibrariesMetadata() {
2305 if (
auto dependentLibrariesAttr = mlirModule->getDiscardableAttr(
2306 LLVM::LLVMDialect::getDependentLibrariesAttrName())) {
2308 llvmModule->getOrInsertNamedMetadata(
"llvm.dependent-libraries");
2309 llvm::LLVMContext &ctx = llvmModule->getContext();
2311 cast<ArrayAttr>(dependentLibrariesAttr).getAsRange<StringAttr>()) {
2313 llvm::MDNode::get(ctx, llvm::MDString::get(ctx, libAttr.getValue()));
2314 nmd->addOperand(md);
2321 llvm::Instruction *inst) {
2322 LoopAnnotationAttr attr =
2324 .Case<LLVM::BrOp, LLVM::CondBrOp>(
2325 [](
auto branchOp) {
return branchOp.getLoopAnnotationAttr(); });
2328 llvm::MDNode *loopMD =
2329 loopAnnotationTranslation->translateLoopAnnotation(attr, op);
2330 inst->setMetadata(llvm::LLVMContext::MD_loop, loopMD);
2334 auto iface = cast<DisjointFlagInterface>(op);
2336 if (
auto *disjointInst = dyn_cast<llvm::PossiblyDisjointInst>(value))
2337 disjointInst->setIsDisjoint(iface.getIsDisjoint());
2341 return typeTranslator.translateType(type);
2347 remapped.reserve(values.size());
2348 for (
Value v : values)
2355 ompBuilder = std::make_unique<llvm::OpenMPIRBuilder>(*llvmModule);
2360 llvm::OpenMPIRBuilderConfig config(
2367 unsigned int defaultAS =
2368 llvmModule->getDataLayout().getProgramAddressSpace();
2369 config.setDefaultTargetAS(defaultAS);
2370 config.setRuntimeCC(llvmModule->getTargetTriple().isSPIRV()
2371 ? llvm::CallingConv::SPIR_FUNC
2372 : llvm::CallingConv::C);
2373 ompBuilder->setConfig(std::move(config));
2374 ompBuilder->initialize();
2376 return ompBuilder.get();
2380 llvm::DILocalScope *scope) {
2381 return debugTranslation->translateLoc(loc, scope);
2386 return debugTranslation->translateExpression(attr);
2389llvm::DIGlobalVariableExpression *
2391 LLVM::DIGlobalVariableExpressionAttr attr) {
2392 return debugTranslation->translateGlobalVariableExpression(attr);
2396 return debugTranslation->translate(attr);
2401 return convertRoundingModeToLLVM(rounding);
2405 LLVM::FPExceptionBehavior exceptionBehavior) {
2406 return convertFPExceptionBehaviorToLLVM(exceptionBehavior);
2411 return llvmModule->getOrInsertNamedMetadata(name);
2414static std::unique_ptr<llvm::Module>
2418 auto llvmModule = std::make_unique<llvm::Module>(name, llvmContext);
2419 if (
auto dataLayoutAttr =
2421 llvmModule->setDataLayout(cast<StringAttr>(dataLayoutAttr).getValue());
2423 FailureOr<llvm::DataLayout> llvmDataLayout(llvm::DataLayout(
""));
2424 if (
auto iface = dyn_cast<DataLayoutOpInterface>(m)) {
2425 if (DataLayoutSpecInterface spec = iface.getDataLayoutSpec()) {
2429 }
else if (
auto mod = dyn_cast<ModuleOp>(m)) {
2430 if (DataLayoutSpecInterface spec = mod.getDataLayoutSpec()) {
2435 if (failed(llvmDataLayout))
2437 llvmModule->setDataLayout(*llvmDataLayout);
2439 if (
auto targetTripleAttr =
2441 llvmModule->setTargetTriple(
2442 llvm::Triple(cast<StringAttr>(targetTripleAttr).getValue()));
2445 LLVM::LLVMDialect::getModuleLevelAsmAttrName())) {
2446 auto asmArrayAttr = dyn_cast<ArrayAttr>(asmAttr);
2447 if (!asmArrayAttr) {
2448 m->
emitError(
"expected an array attribute for a module level asm");
2453 auto asmStrAttr = dyn_cast<StringAttr>(elt);
2456 "expected a string attribute for each entry of a module level asm");
2459 llvmModule->appendModuleInlineAsm(asmStrAttr.getValue());
2466std::unique_ptr<llvm::Module>
2468 StringRef name,
bool disableVerification) {
2470 module->emitOpError("can not be translated to an LLVMIR module");
2474 std::unique_ptr<llvm::Module> llvmModule =
2483 llvm::IRBuilder<llvm::TargetFolder> llvmBuilder(
2485 llvm::TargetFolder(translator.getLLVMModule()->getDataLayout()));
2491 if (
failed(translator.convertOperation(*module, llvmBuilder)))
2494 if (
failed(translator.convertComdats()))
2496 if (
failed(translator.convertFunctionSignatures()))
2498 if (
failed(translator.convertGlobalsAndAliases()))
2500 if (
failed(translator.convertIFuncs()))
2502 if (
failed(translator.createTBAAMetadata()))
2504 if (
failed(translator.createIdentMetadata()))
2506 if (
failed(translator.createCommandlineMetadata()))
2508 if (
failed(translator.createDependentLibrariesMetadata()))
2512 for (Operation &o :
getModuleBody(module).getOperations()) {
2513 if (!isa<LLVM::LLVMFuncOp, LLVM::AliasOp, LLVM::GlobalOp,
2514 LLVM::GlobalCtorsOp, LLVM::GlobalDtorsOp, LLVM::ComdatOp,
2515 LLVM::IFuncOp>(&o) &&
2516 !o.hasTrait<OpTrait::IsTerminator>() &&
2517 failed(translator.convertOperation(o, llvmBuilder))) {
2525 if (
failed(translator.convertFunctions()))
2530 if (
failed(translator.convertUnresolvedBlockAddress()))
2535 translator.debugTranslation->addModuleFlagsIfNotPresent();
2538 if (
auto *ompBuilder = translator.getOpenMPBuilder())
2539 ompBuilder->finalize();
2541 if (!disableVerification &&
2542 llvm::verifyModule(*translator.llvmModule, &llvm::errs()))
2545 return std::move(translator.llvmModule);