588 structElements.push_back(element);
590 return llvm::ConstantStruct::get(structType, structElements);
594 if (
auto intAttr = dyn_cast<IntegerAttr>(attr)) {
597 auto intTy = dyn_cast<IntegerType>(intAttr.getType());
599 if (intTy && (intTy.isUnsigned() || intTy.getWidth() == 1))
600 value = intAttr.getValue().zextOrTrunc(llvmType->getIntegerBitWidth());
602 value = intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth());
603 return llvm::ConstantInt::get(llvmType, value);
605 if (
auto floatAttr = dyn_cast<FloatAttr>(attr)) {
606 const llvm::fltSemantics &sem = floatAttr.getValue().getSemantics();
611 unsigned floatWidth = APFloat::getSizeInBits(sem);
612 if (llvmType->isIntegerTy(floatWidth))
613 return llvm::ConstantInt::get(llvmType,
614 floatAttr.getValue().bitcastToAPInt());
616 llvm::Type::getFloatingPointTy(llvmType->getContext(),
617 floatAttr.getValue().getSemantics())) {
618 emitError(loc,
"FloatAttr does not match expected type of the constant");
621 return llvm::ConstantFP::get(llvmType, floatAttr.getValue());
623 if (
auto symAttr = dyn_cast<FlatSymbolRefAttr>(attr)) {
624 StringRef name = symAttr.getValue();
625 if (llvm::Function *func = moduleTranslation.
lookupFunction(name))
626 return llvm::ConstantExpr::getBitCast(func, llvmType);
627 if (llvm::GlobalValue *global = moduleTranslation.
lookupGlobal(name))
628 return llvm::ConstantExpr::getBitCast(global, llvmType);
629 emitError(loc,
"unknown symbol reference '") << name <<
"' in constant";
632 if (
auto splatAttr = dyn_cast<SplatElementsAttr>(attr)) {
633 llvm::Type *elementType;
634 uint64_t numElements;
635 bool isScalable =
false;
636 if (
auto *arrayTy = dyn_cast<llvm::ArrayType>(llvmType)) {
637 elementType = arrayTy->getElementType();
638 numElements = arrayTy->getNumElements();
639 }
else if (
auto *fVectorTy = dyn_cast<llvm::FixedVectorType>(llvmType)) {
640 elementType = fVectorTy->getElementType();
641 numElements = fVectorTy->getNumElements();
642 }
else if (
auto *sVectorTy = dyn_cast<llvm::ScalableVectorType>(llvmType)) {
643 elementType = sVectorTy->getElementType();
644 numElements = sVectorTy->getMinNumElements();
647 llvm_unreachable(
"unrecognized constant vector type");
652 bool elementTypeSequential =
653 isa<llvm::ArrayType, llvm::VectorType>(elementType);
656 elementTypeSequential ? splatAttr
657 : splatAttr.getSplatValue<Attribute>(),
658 loc, moduleTranslation);
661 if (llvmType->isVectorTy())
662 return llvm::ConstantVector::getSplat(
663 llvm::ElementCount::get(numElements, isScalable), child);
664 if (llvmType->isArrayTy()) {
665 auto *arrayType = llvm::ArrayType::get(elementType, numElements);
666 if (child->isNullValue() && !elementType->isFPOrFPVectorTy()) {
667 return llvm::ConstantAggregateZero::get(arrayType);
669 if (llvm::ConstantDataSequential::isElementTypeCompatible(elementType)) {
670 if (isa<llvm::IntegerType>(elementType)) {
671 if (llvm::ConstantInt *ci = dyn_cast<llvm::ConstantInt>(child)) {
672 if (ci->getBitWidth() == 8) {
673 SmallVector<int8_t> constants(numElements, ci->getZExtValue());
674 return llvm::ConstantDataArray::get(elementType->getContext(),
677 if (ci->getBitWidth() == 16) {
678 SmallVector<int16_t> constants(numElements, ci->getZExtValue());
679 return llvm::ConstantDataArray::get(elementType->getContext(),
682 if (ci->getBitWidth() == 32) {
683 SmallVector<int32_t> constants(numElements, ci->getZExtValue());
684 return llvm::ConstantDataArray::get(elementType->getContext(),
687 if (ci->getBitWidth() == 64) {
688 SmallVector<int64_t> constants(numElements, ci->getZExtValue());
689 return llvm::ConstantDataArray::get(elementType->getContext(),
694 if (elementType->isFloatingPointTy()) {
695 if (llvm::ConstantFP *cfp = dyn_cast<llvm::ConstantFP>(child)) {
696 APInt bitPattern = cfp->getValueAPF().bitcastToAPInt();
697 uint64_t value = bitPattern.getZExtValue();
700 if (bitPattern.getBitWidth() == 16) {
701 SmallVector<uint16_t> constants(numElements, value);
702 return llvm::ConstantDataArray::getFP(elementType, constants);
704 if (bitPattern.getBitWidth() == 32) {
705 SmallVector<uint32_t> constants(numElements, value);
706 return llvm::ConstantDataArray::getFP(elementType, constants);
708 if (bitPattern.getBitWidth() == 64) {
709 SmallVector<uint64_t> constants(numElements, value);
710 return llvm::ConstantDataArray::getFP(elementType, constants);
717 std::vector<llvm::Constant *> constants(numElements, child);
718 return llvm::ConstantArray::get(arrayType, constants);
723 if (llvm::Constant *
result =
725 llvmType, moduleTranslation)) {
729 if (
auto denseResourceAttr = dyn_cast<DenseResourceElementsAttr>(attr)) {
735 if (
auto elementsAttr = dyn_cast<ElementsAttr>(attr)) {
736 assert(elementsAttr.getShapedType().hasStaticShape());
737 assert(!elementsAttr.getShapedType().getShape().empty() &&
738 "unexpected empty elements attribute shape");
740 SmallVector<llvm::Constant *, 8> constants;
741 constants.reserve(elementsAttr.getNumElements());
743 for (
auto n : elementsAttr.getValues<Attribute>()) {
746 if (!constants.back())
749 ArrayRef<llvm::Constant *> constantsRef = constants;
751 constantsRef, elementsAttr.getShapedType().getShape(), llvmType, loc);
752 assert(constantsRef.empty() &&
"did not consume all elemental constants");
756 if (
auto stringAttr = dyn_cast<StringAttr>(attr)) {
757 return llvm::ConstantDataArray::get(moduleTranslation.
getLLVMContext(),
758 ArrayRef<char>{stringAttr.getValue()});
763 if (
auto arrayAttr = dyn_cast<ArrayAttr>(attr)) {
764 if (
auto *arrayTy = dyn_cast<llvm::ArrayType>(llvmType)) {
765 llvm::Type *elementType = arrayTy->getElementType();
766 Attribute previousElementAttr;
767 llvm::Constant *elementCst =
nullptr;
768 SmallVector<llvm::Constant *> constants;
769 constants.reserve(arrayTy->getNumElements());
770 for (Attribute elementAttr : arrayAttr) {
774 if (!previousElementAttr || previousElementAttr != elementAttr) {
775 previousElementAttr = elementAttr;
781 constants.push_back(elementCst);
783 return llvm::ConstantArray::get(arrayTy, constants);
787 emitError(loc,
"unsupported constant value");
791ModuleTranslation::ModuleTranslation(Operation *module,
792 std::unique_ptr<llvm::Module> llvmModule,
793 llvm::vfs::FileSystem *fs)
794 : mlirModule(module), llvmModule(std::move(llvmModule)),
796 std::make_unique<DebugTranslation>(module, *this->llvmModule)),
797 loopAnnotationTranslation(std::make_unique<LoopAnnotationTranslation>(
798 *this, *this->llvmModule)),
799 fileSystem(fs), typeTranslator(this->llvmModule->
getContext()),
802 "mlirModule should honor LLVM's module semantics.");
805ModuleTranslation::~ModuleTranslation() {
806 if (ompBuilder && !ompBuilder->isFinalized())
807 ompBuilder->finalize();
812 toProcess.push_back(®ion);
813 while (!toProcess.empty()) {
814 Region *current = toProcess.pop_back_val();
815 for (
Block &block : *current) {
816 blockMapping.erase(&block);
817 for (
Value arg : block.getArguments())
818 valueMapping.erase(arg);
820 for (
Value value : op.getResults())
821 valueMapping.erase(value);
822 if (op.hasSuccessors())
823 branchMapping.erase(&op);
824 if (isa<LLVM::GlobalOp>(op))
825 globalsMapping.erase(&op);
826 if (isa<LLVM::AliasOp>(op))
827 aliasesMapping.erase(&op);
828 if (isa<LLVM::IFuncOp>(op))
829 ifuncMapping.erase(&op);
830 if (isa<LLVM::CallOp>(op))
831 callMapping.erase(&op);
834 llvm::map_range(op.getRegions(), [](
Region &r) { return &r; }));
843 unsigned numArguments,
unsigned index) {
845 if (isa<LLVM::BrOp>(terminator))
852 auto branch = cast<BranchOpInterface>(terminator);
855 (!seenSuccessors.contains(successor) || successorOperands.
empty()) &&
856 "successors with arguments in LLVM branches must be different blocks");
857 seenSuccessors.insert(successor);
863 if (
auto condBranchOp = dyn_cast<LLVM::CondBrOp>(terminator)) {
866 return condBranchOp.getSuccessor(0) == current
867 ? condBranchOp.getTrueDestOperands()[
index]
868 : condBranchOp.getFalseDestOperands()[
index];
871 if (
auto switchOp = dyn_cast<LLVM::SwitchOp>(terminator)) {
874 if (switchOp.getDefaultDestination() == current)
875 return switchOp.getDefaultOperands()[
index];
876 for (
const auto &i : llvm::enumerate(switchOp.getCaseDestinations()))
877 if (i.value() == current)
878 return switchOp.getCaseOperands(i.index())[
index];
881 if (
auto indBrOp = dyn_cast<LLVM::IndirectBrOp>(terminator)) {
883 for (
const auto &i : llvm::enumerate(indBrOp->getSuccessors())) {
884 if (indBrOp->getSuccessor(i.index()) == current)
885 return indBrOp.getSuccessorOperands(i.index())[
index];
889 if (
auto invokeOp = dyn_cast<LLVM::InvokeOp>(terminator)) {
890 return invokeOp.getNormalDest() == current
891 ? invokeOp.getNormalDestOperands()[
index]
892 : invokeOp.getUnwindDestOperands()[
index];
896 "only branch, switch or invoke operations can be terminators "
897 "of a block that has successors");
905 for (
Block &bb : llvm::drop_begin(region)) {
907 auto phis = llvmBB->phis();
908 auto numArguments = bb.getNumArguments();
909 assert(numArguments == std::distance(phis.begin(), phis.end()));
910 for (
auto [
index, phiNode] : llvm::enumerate(phis)) {
911 for (
auto *pred : bb.getPredecessors()) {
917 llvm::Instruction *terminator =
919 assert(terminator &&
"missing the mapping for a terminator");
921 &bb, pred, numArguments,
index)),
922 terminator->getParent());
929 llvm::IRBuilderBase &builder, llvm::Intrinsic::ID intrinsic,
931 return builder.CreateIntrinsicWithoutFolding(intrinsic, tys, args);
935 llvm::IRBuilderBase &builder, llvm::Intrinsic::ID intrinsic,
937 return builder.CreateIntrinsicWithoutFolding(retTy, intrinsic, args);
942 Operation *intrOp, llvm::Intrinsic::ID intrinsic,
unsigned numResults,
946 assert(immArgPositions.size() == immArgAttrNames.size() &&
947 "LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
951 size_t numOpBundleOperands = 0;
952 auto opBundleSizesAttr = cast_if_present<DenseI32ArrayAttr>(
955 auto opBundleTagsAttr = cast_if_present<ArrayAttr>(
959 if (opBundleSizesAttr && opBundleTagsAttr) {
960 ArrayRef<int> opBundleSizes = opBundleSizesAttr.asArrayRef();
961 assert(opBundleSizes.size() == opBundleTagsAttr.size() &&
962 "operand bundles and tags do not match");
964 numOpBundleOperands = llvm::sum_of(opBundleSizes);
966 "operand bundle operands is more than the number of operands");
969 size_t nextOperandIdx = 0;
970 opBundles.reserve(opBundleSizesAttr.size());
972 for (
auto [opBundleTagAttr, bundleSize] :
973 llvm::zip(opBundleTagsAttr, opBundleSizes)) {
974 auto bundleTag = cast<StringAttr>(opBundleTagAttr).str();
976 operands.slice(nextOperandIdx, bundleSize));
977 opBundles.emplace_back(std::move(bundleTag), std::move(bundleOperands));
978 nextOperandIdx += bundleSize;
983 auto opOperands = intrOp->
getOperands().drop_back(numOpBundleOperands);
984 auto operands = moduleTranslation.
lookupValues(opOperands);
986 for (
auto [immArgPos, immArgName] :
987 llvm::zip(immArgPositions, immArgAttrNames)) {
989 if (
auto intrinsicIntegerAttr =
990 dyn_cast<LLVM::IntrinsicIntegerAttrInterface>(attr))
991 attr = intrinsicIntegerAttr.getIntegerAttr();
992 auto typedAttr = llvm::cast<TypedAttr>(attr);
993 assert(typedAttr.getType().isIntOrFloat() &&
994 "expected int or float immarg");
995 auto *type = moduleTranslation.
convertType(typedAttr.getType());
997 type, typedAttr, intrOp->
getLoc(), moduleTranslation);
1000 for (
auto &arg : args) {
1002 arg = operands[opArg++];
1007 for (
unsigned overloadedResultIdx : overloadedResults) {
1008 if (numResults > 1) {
1010 overloadedTypes.push_back(moduleTranslation.
convertType(
1012 .getBody()[overloadedResultIdx]));
1014 overloadedTypes.push_back(
1018 for (
unsigned overloadedOperandIdx : overloadedOperands)
1019 overloadedTypes.push_back(args[overloadedOperandIdx]->
getType());
1020 llvm::Module *module = builder.GetInsertBlock()->getModule();
1021 llvm::Function *llvmIntr = llvm::Intrinsic::getOrInsertDeclaration(
1022 module, intrinsic, overloadedTypes);
1024 return builder.CreateCall(llvmIntr, args, opBundles);
1029LogicalResult ModuleTranslation::convertOperationImpl(
1030 Operation &op, llvm::IRBuilderBase &builder,
bool recordInsertions) {
1031 const LLVMTranslationDialectInterface *opIface = iface.
getInterfaceFor(&op);
1033 return op.
emitError(
"cannot be converted to LLVM IR: missing "
1034 "`LLVMTranslationDialectInterface` registration for "
1038 InstructionCapturingInserter::CollectionScope scope(builder,
1040 if (failed(opIface->convertOperation(&op, builder, *
this)))
1041 return op.
emitError(
"LLVM Translation failed for operation: ")
1044 return convertDialectAttributes(&op, scope.getCapturedInstructions());
1054LogicalResult ModuleTranslation::convertBlockImpl(
Block &bb,
1055 bool ignoreArguments,
1056 llvm::IRBuilderBase &builder,
1057 bool recordInsertions) {
1059 auto *subprogram = builder.GetInsertBlock()->getParent()->getSubprogram();
1067 if (!ignoreArguments) {
1069 unsigned numPredecessors =
1070 std::distance(predecessors.begin(), predecessors.end());
1072 auto wrappedType = arg.getType();
1075 "block argument does not have an LLVM type");
1076 builder.SetCurrentDebugLocation(
1077 debugTranslation->translateLoc(arg.getLoc(), subprogram));
1079 llvm::PHINode *phi = builder.CreatePHI(type, numPredecessors);
1085 for (
auto &op : bb) {
1087 builder.SetCurrentDebugLocation(
1088 debugTranslation->translateLoc(op.
getLoc(), subprogram));
1090 if (
failed(convertOperationImpl(op, builder, recordInsertions)))
1094 if (
auto iface = dyn_cast<WeightedBranchOpInterface>(op))
1104 return module->getRegion(0).front();
1113 llvm::Constant *cst) {
1114 return (linkage == llvm::GlobalVariable::ExternalLinkage && !cst) ||
1115 linkage == llvm::GlobalVariable::ExternalWeakLinkage;
1121 llvm::GlobalValue *gv) {
1122 if (dsoLocalRequested)
1123 gv->setDSOLocal(
true);
1132static FailureOr<llvm::Attribute>
1134 StringRef value = StringRef()) {
1135 auto kind = llvm::Attribute::getAttrKindFromName(key);
1136 if (kind == llvm::Attribute::None)
1137 return llvm::Attribute::get(ctx, key, value);
1139 if (llvm::Attribute::isIntAttrKind(kind)) {
1141 return emitError(loc) <<
"LLVM attribute '" << key <<
"' expects a value";
1144 if (!value.getAsInteger(0,
result))
1145 return llvm::Attribute::get(ctx, kind,
result);
1146 return llvm::Attribute::get(ctx, key, value);
1150 return emitError(loc) <<
"LLVM attribute '" << key
1151 <<
"' does not expect a value, found '" << value
1154 return llvm::Attribute::get(ctx, kind);
1165static FailureOr<llvm::AttrBuilder>
1167 ArrayAttr arrayAttr, StringRef arrayAttrName) {
1168 llvm::AttrBuilder attrBuilder(ctx);
1173 if (
auto stringAttr = dyn_cast<StringAttr>(attr)) {
1174 FailureOr<llvm::Attribute> llvmAttr =
1176 if (failed(llvmAttr))
1178 attrBuilder.addAttribute(*llvmAttr);
1182 auto arrayAttr = dyn_cast<ArrayAttr>(attr);
1183 if (!arrayAttr || arrayAttr.size() != 2)
1184 return emitError(loc) <<
"expected '" << arrayAttrName
1185 <<
"' to contain string or array attributes";
1187 auto keyAttr = dyn_cast<StringAttr>(arrayAttr[0]);
1188 auto valueAttr = dyn_cast<StringAttr>(arrayAttr[1]);
1189 if (!keyAttr || !valueAttr)
1190 return emitError(loc) <<
"expected arrays within '" << arrayAttrName
1191 <<
"' to contain two strings";
1194 loc, ctx, keyAttr.getValue(), valueAttr.getValue());
1195 if (failed(llvmAttr))
1197 attrBuilder.addAttribute(*llvmAttr);
1203LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
1214 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
1216 llvm::Constant *cst =
nullptr;
1217 const bool deferValueAttrToPass2 = op.getValueOrNull() &&
1218 !op.getInitializerBlock() &&
1219 !isa<StringAttr>(op.getValueOrNull());
1220 if (op.getValueOrNull() && !deferValueAttrToPass2) {
1223 if (
auto strAttr = dyn_cast_or_null<StringAttr>(op.getValueOrNull())) {
1224 cst = llvm::ConstantDataArray::getString(
1225 llvmModule->getContext(), strAttr.getValue(),
false);
1226 type = cst->getType();
1230 auto linkage = convertLinkageToLLVM(op.getLinkage());
1236 if (!deferValueAttrToPass2) {
1237 if (!dropInitializer && !cst)
1238 cst = llvm::UndefValue::get(type);
1239 else if (dropInitializer && cst)
1245 auto *var =
new llvm::GlobalVariable(
1246 *llvmModule, type, op.getConstant(), linkage, cst, op.getSymName(),
1247 nullptr, convertThreadLocalModeToLLVM(op.getTlsMode()),
1248 op.getAddrSpace(), op.getExternallyInitialized());
1250 if (std::optional<mlir::SymbolRefAttr> comdat = op.getComdat()) {
1251 auto selectorOp = cast<ComdatSelectorOp>(
1252 symbolTable().lookupNearestSymbolFrom(op, *comdat));
1253 var->setComdat(comdatMapping.lookup(selectorOp));
1256 if (op.getUnnamedAddr().has_value())
1257 var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
1259 if (op.getSection().has_value())
1260 var->setSection(*op.getSection());
1264 std::optional<uint64_t> alignment = op.getAlignment();
1265 if (alignment.has_value())
1266 var->setAlignment(llvm::MaybeAlign(alignment.value()));
1268 var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
1270 globalsMapping.try_emplace(op, var);
1271 globalsByNameMapping.try_emplace(op.getSymName(), var);
1274 if (op.getDbgExprs()) {
1275 for (
auto exprAttr :
1276 op.getDbgExprs()->getAsRange<DIGlobalVariableExpressionAttr>()) {
1277 llvm::DIGlobalVariableExpression *diGlobalExpr =
1278 debugTranslation->translateGlobalVariableExpression(exprAttr);
1279 llvm::DIGlobalVariable *diGlobalVar = diGlobalExpr->getVariable();
1280 var->addDebugInfo(diGlobalExpr);
1299 llvm::DIScope *scope = diGlobalVar->getScope();
1300 if (
auto *mod = dyn_cast_if_present<llvm::DIModule>(scope))
1301 scope = mod->getScope();
1302 else if (
auto *cb = dyn_cast_if_present<llvm::DICommonBlock>(scope)) {
1304 dyn_cast_if_present<llvm::DISubprogram>(cb->getScope()))
1305 scope = sp->getUnit();
1306 }
else if (
auto *lbb =
1307 dyn_cast_if_present<llvm::DILexicalBlockBase>(scope)) {
1308 scope = lbb->getSubprogram();
1313 if (llvm::DICompileUnit *compileUnit =
1314 dyn_cast_if_present<llvm::DICompileUnit>(scope)) {
1317 globalGVars[compileUnit].push_back(diGlobalExpr);
1318 }
else if (llvm::DISubprogram *sp =
1319 dyn_cast_if_present<llvm::DISubprogram>(scope)) {
1322 staticLocals[sp].push_back(diGlobalExpr);
1328 FailureOr<llvm::AttrBuilder> convertedTargetSpecificAttrs =
1330 op.getTargetSpecificAttrsAttr(),
1331 op.getTargetSpecificAttrsAttrName());
1332 if (
failed(convertedTargetSpecificAttrs))
1334 var->addAttributes(*convertedTargetSpecificAttrs);
1339 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
1340 if (!op.getValueOrNull() || op.getInitializerBlock() ||
1341 isa<StringAttr>(op.getValueOrNull()))
1345 llvm::Constant *cst =
1350 auto linkage = convertLinkageToLLVM(op.getLinkage());
1352 auto *var = cast<llvm::GlobalVariable>(
lookupGlobal(op));
1353 if (dropInitializer)
1354 var->setInitializer(
nullptr);
1356 var->setInitializer(cst);
1360 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
1362 llvm::Constant *cst =
nullptr;
1363 llvm::GlobalValue::LinkageTypes linkage =
1364 convertLinkageToLLVM(op.getLinkage());
1365 llvm::Module &llvmMod = *llvmModule;
1368 llvm::GlobalAlias *var = llvm::GlobalAlias::create(
1369 type, op.getAddrSpace(), linkage, op.getSymName(), cst,
1372 var->setThreadLocalMode(convertThreadLocalModeToLLVM(op.getTlsMode()));
1377 if (op.getUnnamedAddr().has_value())
1378 var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
1380 var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
1382 aliasesMapping.try_emplace(op, var);
1386 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
1387 if (
Block *initializer = op.getInitializerBlock()) {
1388 llvm::IRBuilder<llvm::TargetFolder> builder(
1389 llvmModule->getContext(),
1390 llvm::TargetFolder(llvmModule->getDataLayout()));
1392 [[maybe_unused]]
int numConstantsHit = 0;
1393 [[maybe_unused]]
int numConstantsErased = 0;
1396 for (
auto &op : initializer->without_terminator()) {
1410 if (
auto *agg = dyn_cast<llvm::ConstantAggregate>(cst)) {
1413 int numUsers = std::distance(
result.use_begin(),
result.use_end());
1415 constantAggregateUseMap.try_emplace(agg, numUsers);
1418 iterator->second += numUsers;
1424 auto *cst = dyn_cast<llvm::ConstantAggregate>(
lookupValue(v));
1427 auto iter = constantAggregateUseMap.find(cst);
1428 assert(iter != constantAggregateUseMap.end() &&
"constant not found");
1430 if (iter->second == 0) {
1433 if (cst->user_empty()) {
1434 cst->destroyConstant();
1435 numConstantsErased++;
1437 constantAggregateUseMap.erase(iter);
1442 ReturnOp ret = cast<ReturnOp>(initializer->getTerminator());
1443 llvm::Constant *cst =
1444 cast<llvm::Constant>(
lookupValue(ret.getOperand(0)));
1445 auto *global = cast<llvm::GlobalVariable>(
lookupGlobal(op));
1447 global->setInitializer(cst);
1451 for (
auto it : constantAggregateUseMap) {
1452 auto *cst = it.first;
1453 cst->removeDeadConstantUsers();
1454 if (cst->user_empty()) {
1455 cst->destroyConstant();
1456 numConstantsErased++;
1460 LLVM_DEBUG(llvm::dbgs()
1461 <<
"Convert initializer for " << op.
getName() <<
"\n";
1462 llvm::dbgs() << numConstantsHit <<
" new constants hit\n";
1464 << numConstantsErased <<
" dangling constants erased\n";);
1470 auto ctorOp = dyn_cast<GlobalCtorsOp>(op);
1471 auto dtorOp = dyn_cast<GlobalDtorsOp>(op);
1472 if (!ctorOp && !dtorOp)
1478 if ((ctorOp && ctorOp.getCtors().empty()) ||
1479 (dtorOp && dtorOp.getDtors().empty())) {
1480 llvm::IRBuilder<llvm::TargetFolder> builder(
1481 llvmModule->getContext(),
1482 llvm::TargetFolder(llvmModule->getDataLayout()));
1483 llvm::Type *eltTy = llvm::StructType::get(
1484 builder.getInt32Ty(), builder.getPtrTy(), builder.getPtrTy());
1485 llvm::ArrayType *at = llvm::ArrayType::get(eltTy, 0);
1486 llvm::Constant *zeroInit = llvm::Constant::getNullValue(at);
1487 (void)
new llvm::GlobalVariable(
1488 *llvmModule, zeroInit->getType(),
false,
1489 llvm::GlobalValue::AppendingLinkage, zeroInit,
1490 ctorOp ?
"llvm.global_ctors" :
"llvm.global_dtors");
1493 ? llvm::zip(ctorOp.getCtors(), ctorOp.getPriorities())
1494 : llvm::zip(dtorOp.getDtors(), dtorOp.getPriorities());
1495 auto appendGlobalFn =
1496 ctorOp ? llvm::appendToGlobalCtors : llvm::appendToGlobalDtors;
1497 for (
const auto &[sym, prio] : range) {
1500 appendGlobalFn(*llvmModule, f, cast<IntegerAttr>(prio).getInt(),
1506 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>())
1507 if (
failed(convertDialectAttributes(op, {})))
1512 for (
const auto &[compileUnit, globals] : globalGVars)
1513 compileUnit->replaceGlobalVariables(
1518 for (
const auto &[sp, globals] : staticLocals)
1519 sp->retainNodes(globals.begin(), globals.end());
1522 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
1523 Block &initializer = op.getInitializerBlock();
1524 llvm::IRBuilder<llvm::TargetFolder> builder(
1525 llvmModule->getContext(),
1526 llvm::TargetFolder(llvmModule->getDataLayout()));
1536 auto *cst = cast<llvm::Constant>(
lookupValue(ret.getOperand(0)));
1537 assert(aliasesMapping.count(op));
1538 auto *alias = cast<llvm::GlobalAlias>(aliasesMapping[op]);
1539 alias->setAliasee(cst);
1542 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::AliasOp>())
1543 if (
failed(convertDialectAttributes(op, {})))
1551 const llvm::APInt &value) {
1552 llvm::Constant *constant = llvm::ConstantInt::get(context, value);
1553 return llvm::ConstantAsMetadata::get(constant);
1558 const llvm::APInt &value) {
1566 llvm::Metadata *typeMD =
1567 llvm::ConstantAsMetadata::get(llvm::UndefValue::get(type));
1568 llvm::Metadata *isSignedMD =
1570 return llvm::MDNode::get(context, {typeMD, isSignedMD});
1578 values, std::back_inserter(mdValues), [&context](int32_t value) {
1581 return llvm::MDNode::get(context, mdValues);
1589 .Case([&](MDStringAttr a) -> FailureOr<llvm::Metadata *> {
1590 return llvm::MDString::get(llvmContext, a.getValue().getValue());
1592 .Case([&](MDConstantAttr a) -> FailureOr<llvm::Metadata *> {
1593 IntegerAttr intAttr = llvm::dyn_cast<IntegerAttr>(a.getValue());
1596 <<
"expected integer attribute in metadata constant";
1598 return llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1599 llvm::Type::getIntNTy(llvmContext,
1600 intAttr.getType().getIntOrFloatBitWidth()),
1601 intAttr.getValue()));
1603 .Case([&](MDGlobalValueAttr a) -> FailureOr<llvm::Metadata *> {
1604 return convertSymbolRefToMetadata(a.getName(),
emitError);
1606 .Case([&](MDNullAttr a) -> FailureOr<llvm::Metadata *> {
1607 return llvm::ConstantAsMetadata::get(llvm::ConstantPointerNull::get(
1608 llvm::PointerType::get(llvmContext, a.getAddressSpace())));
1610 .Case([&](MDAddrSpaceCastAttr a) -> FailureOr<llvm::Metadata *> {
1611 FailureOr<llvm::Metadata *> arg =
1617 auto *argAsMD = cast<llvm::ConstantAsMetadata>(*arg);
1618 return llvm::ConstantAsMetadata::get(
1619 llvm::ConstantExpr::getAddrSpaceCast(
1620 argAsMD->getValue(),
1621 llvm::PointerType::get(llvmContext, a.getAddressSpace())));
1623 .Case([&](MDNodeAttr a) -> FailureOr<llvm::Metadata *> {
1625 for (
Attribute operand : a.getOperands()) {
1626 FailureOr<llvm::Metadata *> md =
1630 operands.push_back(*md);
1632 return llvm::MDNode::get(llvmContext, operands);
1634 .Default([&](
Attribute attr) -> FailureOr<llvm::Metadata *> {
1635 return emitError() <<
"unsupported LLVM metadata attribute " << attr;
1639FailureOr<llvm::Metadata *> ModuleTranslation::convertSymbolRefToMetadata(
1642 return llvm::ValueAsMetadata::get(fn);
1644 return llvm::ValueAsMetadata::get(global);
1646 if (
auto alias = dyn_cast_if_present<LLVM::AliasOp>(symbol)) {
1647 if (llvm::GlobalValue *global =
lookupAlias(alias))
1648 return llvm::ValueAsMetadata::get(global);
1650 if (
auto ifunc = dyn_cast_if_present<LLVM::IFuncOp>(symbol)) {
1651 if (llvm::GlobalValue *global =
lookupIFunc(ifunc))
1652 return llvm::ValueAsMetadata::get(global);
1654 return emitError() <<
"could not resolve metadata reference '" << name <<
"'";
1657LogicalResult ModuleTranslation::convertFunctionMetadata() {
1658 for (
auto function :
getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
1659 ArrayAttr metadata = function.getFunctionMetadataAttr();
1664 for (
auto entry : metadata.getAsRange<LLVM::FunctionMetadataAttr>()) {
1665 StringRef metadataName = entry.getMetadataName().getValue();
1667 FailureOr<llvm::Metadata *> md =
1669 return function.emitError()
1670 <<
"failed to convert function_metadata entry '"
1671 << metadataName <<
"': ";
1675 llvm::MDNode *node = llvm::dyn_cast_if_present<llvm::MDNode>(*md);
1677 return function.emitError()
1678 <<
"failed to convert function_metadata entry '" << metadataName
1681 llvmFunc->addMetadata(metadataName, *node);
1687LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
1690 blockMapping.clear();
1691 valueMapping.clear();
1692 branchMapping.clear();
1694 llvm::LLVMContext &llvmContext = llvmFunc->getContext();
1697 for (
auto [mlirArg, llvmArg] :
1698 llvm::zip(func.getArguments(), llvmFunc->args()))
1702 if (func.getPersonality()) {
1703 llvm::Type *ty = llvm::PointerType::getUnqual(llvmFunc->getContext());
1704 if (llvm::Constant *pfunc =
getLLVMConstant(ty, func.getPersonalityAttr(),
1705 func.getLoc(), *
this))
1706 llvmFunc->setPersonalityFn(pfunc);
1709 if (std::optional<StringRef> section = func.getSection())
1710 llvmFunc->setSection(*section);
1712 if (func.getArmStreaming())
1713 llvmFunc->addFnAttr(
"aarch64_pstate_sm_enabled");
1714 else if (func.getArmLocallyStreaming())
1715 llvmFunc->addFnAttr(
"aarch64_pstate_sm_body");
1716 else if (func.getArmStreamingCompatible())
1717 llvmFunc->addFnAttr(
"aarch64_pstate_sm_compatible");
1719 if (func.getArmNewZa())
1720 llvmFunc->addFnAttr(
"aarch64_new_za");
1721 else if (func.getArmInZa())
1722 llvmFunc->addFnAttr(
"aarch64_in_za");
1723 else if (func.getArmOutZa())
1724 llvmFunc->addFnAttr(
"aarch64_out_za");
1725 else if (func.getArmInoutZa())
1726 llvmFunc->addFnAttr(
"aarch64_inout_za");
1727 else if (func.getArmPreservesZa())
1728 llvmFunc->addFnAttr(
"aarch64_preserves_za");
1730 if (
auto targetCpu = func.getTargetCpu())
1731 llvmFunc->addFnAttr(
"target-cpu", *targetCpu);
1733 if (
auto tuneCpu = func.getTuneCpu())
1734 llvmFunc->addFnAttr(
"tune-cpu", *tuneCpu);
1736 if (
auto reciprocalEstimates = func.getReciprocalEstimates())
1737 llvmFunc->addFnAttr(
"reciprocal-estimates", *reciprocalEstimates);
1739 if (
auto preferVectorWidth = func.getPreferVectorWidth())
1740 llvmFunc->addFnAttr(
"prefer-vector-width", *preferVectorWidth);
1742 if (func.getUseSampleProfile())
1743 llvmFunc->addFnAttr(
"use-sample-profile");
1745 if (
auto disableTailCalls = func.getDisableTailCalls())
1746 llvmFunc->addFnAttr(
"disable-tail-calls",
1747 llvm::toStringRef(*disableTailCalls));
1749 if (
auto sampleProfileSuffixElisionPolicy =
1750 func.getSampleProfileSuffixElisionPolicy())
1751 llvmFunc->addFnAttr(
"sample-profile-suffix-elision-policy",
1752 *sampleProfileSuffixElisionPolicy);
1754 if (
auto attr = func.getVscaleRange())
1755 llvmFunc->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
1757 attr->getMaxRange().getInt()));
1759 if (
auto noSignedZerosFpMath = func.getNoSignedZerosFpMath())
1760 llvmFunc->addFnAttr(
"no-signed-zeros-fp-math",
1761 llvm::toStringRef(*noSignedZerosFpMath));
1763 if (
auto fpContract = func.getFpContract())
1764 llvmFunc->addFnAttr(
"fp-contract", *fpContract);
1766 if (
auto instrumentFunctionEntry = func.getInstrumentFunctionEntry())
1767 llvmFunc->addFnAttr(
"instrument-function-entry", *instrumentFunctionEntry);
1769 if (
auto instrumentFunctionExit = func.getInstrumentFunctionExit())
1770 llvmFunc->addFnAttr(
"instrument-function-exit", *instrumentFunctionExit);
1773 for (
auto &bb : func) {
1774 auto *llvmBB = llvm::BasicBlock::Create(llvmContext);
1775 llvmBB->insertInto(llvmFunc);
1782 for (
Block *bb : blocks) {
1783 CapturingIRBuilder builder(llvmContext,
1784 llvm::TargetFolder(llvmModule->getDataLayout()));
1785 if (
failed(convertBlockImpl(*bb, bb->isEntryBlock(), builder,
1795 return convertDialectAttributes(func, {});
1798LogicalResult ModuleTranslation::convertDialectAttributes(
1799 Operation *op, ArrayRef<llvm::Instruction *> instructions) {
1801 if (
failed(iface.amendOperation(op, instructions, attribute, *
this)))
1809 llvm::Function *llvmFunc) {
1810 if (!
func.getMemoryEffects())
1813 MemoryEffectsAttr memEffects =
func.getMemoryEffectsAttr();
1816 llvm::MemoryEffects newMemEffects =
1817 llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
1818 convertModRefInfoToLLVM(memEffects.getArgMem()));
1819 newMemEffects |= llvm::MemoryEffects(
1820 llvm::MemoryEffects::Location::InaccessibleMem,
1821 convertModRefInfoToLLVM(memEffects.getInaccessibleMem()));
1823 llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
1824 convertModRefInfoToLLVM(memEffects.getOther()));
1826 llvm::MemoryEffects(llvm::MemoryEffects::Location::ErrnoMem,
1827 convertModRefInfoToLLVM(memEffects.getErrnoMem()));
1829 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem0,
1830 convertModRefInfoToLLVM(memEffects.getTargetMem0()));
1832 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem1,
1833 convertModRefInfoToLLVM(memEffects.getTargetMem1()));
1834 llvmFunc->setMemoryEffects(newMemEffects);
1839 if (!allocSizeAttr || allocSizeAttr.empty())
1840 return llvm::Attribute{};
1842 unsigned elemSize =
static_cast<unsigned>(allocSizeAttr[0]);
1843 std::optional<unsigned> numElems;
1844 if (allocSizeAttr.size() > 1)
1845 numElems =
static_cast<unsigned>(allocSizeAttr[1]);
1847 return llvm::Attribute::getWithAllocSizeArgs(
getLLVMContext(), elemSize,
1851 llvm::AttrBuilder &Attrs) {
1852 std::optional<DenormalFPEnvAttr> denormalFpEnv =
func.getDenormalFpenv();
1856 llvm::DenormalMode DefaultMode(
1857 convertDenormalModeKindToLLVM(denormalFpEnv->getDefaultOutputMode()),
1858 convertDenormalModeKindToLLVM(denormalFpEnv->getDefaultInputMode()));
1859 llvm::DenormalMode FloatMode(
1860 convertDenormalModeKindToLLVM(denormalFpEnv->getFloatOutputMode()),
1861 convertDenormalModeKindToLLVM(denormalFpEnv->getFloatInputMode()));
1863 llvm::DenormalFPEnv FPEnv(DefaultMode, FloatMode);
1864 Attrs.addDenormalFPEnvAttr(FPEnv);
1869 llvm::Function *llvmFunc) {
1871 llvm::AttrBuilder AttrBuilder(llvmFunc->getContext());
1873 if (
func.getNoInlineAttr())
1874 llvmFunc->addFnAttr(llvm::Attribute::NoInline);
1875 if (
func.getAlwaysInlineAttr())
1876 llvmFunc->addFnAttr(llvm::Attribute::AlwaysInline);
1877 if (
func.getInlineHintAttr())
1878 llvmFunc->addFnAttr(llvm::Attribute::InlineHint);
1879 if (
func.getOptimizeNoneAttr())
1880 llvmFunc->addFnAttr(llvm::Attribute::OptimizeNone);
1881 if (
func.getReturnsTwiceAttr())
1882 llvmFunc->addFnAttr(llvm::Attribute::ReturnsTwice);
1883 if (
func.getColdAttr())
1884 llvmFunc->addFnAttr(llvm::Attribute::Cold);
1885 if (
func.getHotAttr())
1886 llvmFunc->addFnAttr(llvm::Attribute::Hot);
1887 if (
func.getNoduplicateAttr())
1888 llvmFunc->addFnAttr(llvm::Attribute::NoDuplicate);
1889 if (
func.getConvergentAttr())
1890 llvmFunc->addFnAttr(llvm::Attribute::Convergent);
1891 if (
func.getNoUnwindAttr())
1892 llvmFunc->addFnAttr(llvm::Attribute::NoUnwind);
1893 if (
func.getWillReturnAttr())
1894 llvmFunc->addFnAttr(llvm::Attribute::WillReturn);
1895 if (
func.getNoreturnAttr())
1896 llvmFunc->addFnAttr(llvm::Attribute::NoReturn);
1897 if (
func.getOptsizeAttr())
1898 llvmFunc->addFnAttr(llvm::Attribute::OptimizeForSize);
1899 if (
func.getMinsizeAttr())
1900 llvmFunc->addFnAttr(llvm::Attribute::MinSize);
1901 if (
func.getSaveRegParamsAttr())
1902 llvmFunc->addFnAttr(
"save-reg-params");
1903 if (
func.getNoCallerSavedRegistersAttr())
1904 llvmFunc->addFnAttr(
"no_caller_saved_registers");
1905 if (
func.getNocallbackAttr())
1906 llvmFunc->addFnAttr(llvm::Attribute::NoCallback);
1907 if (StringAttr modFormat =
func.getModularFormatAttr())
1908 llvmFunc->addFnAttr(
"modular-format", modFormat.getValue());
1909 if (TargetFeaturesAttr targetFeatAttr =
func.getTargetFeaturesAttr())
1910 llvmFunc->addFnAttr(
"target-features", targetFeatAttr.getFeaturesString());
1911 if (FramePointerKindAttr fpAttr =
func.getFramePointerAttr())
1912 llvmFunc->addFnAttr(
"frame-pointer", stringifyFramePointerKind(
1913 fpAttr.getFramePointerKind()));
1914 if (UWTableKindAttr uwTableKindAttr =
func.getUwtableKindAttr())
1915 llvmFunc->setUWTableKind(
1916 convertUWTableKindToLLVM(uwTableKindAttr.getUwtableKind()));
1917 if (StringAttr zcsr =
func.getZeroCallUsedRegsAttr())
1918 llvmFunc->addFnAttr(
"zero-call-used-regs", zcsr.getValue());
1919 if (
func.getUniformWorkGroupSizeAttr())
1920 llvmFunc->addFnAttr(
"uniform-work-group-size");
1923 if (noBuiltins.empty())
1924 llvmFunc->addFnAttr(
"no-builtins");
1935 llvmFunc->addFnAttr(attr);
1940 llvmFunc->addFnAttrs(AttrBuilder);
1945 llvm::Function *llvmFunc,
1947 llvm::LLVMContext &llvmContext = llvmFunc->getContext();
1949 if (VecTypeHintAttr vecTypeHint =
func.getVecTypeHintAttr()) {
1950 Type type = vecTypeHint.getHint().getValue();
1951 llvm::Type *llvmType = translation.
convertType(type);
1952 bool isSigned = vecTypeHint.getIsSigned();
1953 llvmFunc->setMetadata(
1954 func.getVecTypeHintAttrName(),
1959 func.getWorkGroupSizeHint()) {
1960 llvmFunc->setMetadata(
1961 func.getWorkGroupSizeHintAttrName(),
1966 func.getReqdWorkGroupSize()) {
1967 llvmFunc->setMetadata(
1968 func.getReqdWorkGroupSizeAttrName(),
1972 if (std::optional<uint32_t> intelReqdSubGroupSize =
1973 func.getIntelReqdSubGroupSize()) {
1974 llvmFunc->setMetadata(
1975 func.getIntelReqdSubGroupSizeAttrName(),
1977 llvm::APInt(32, *intelReqdSubGroupSize)));
1982 llvm::Attribute::AttrKind llvmKind,
1987 .Case([&](TypeAttr typeAttr) {
1988 attrBuilder.addTypeAttr(
1989 llvmKind, moduleTranslation.
convertType(typeAttr.getValue()));
1992 .Case([&](IntegerAttr intAttr) {
1993 attrBuilder.addRawIntAttr(llvmKind, intAttr.getInt());
1996 .Case([&](UnitAttr) {
1997 attrBuilder.addAttribute(llvmKind);
2000 .Case([&](LLVM::ConstantRangeAttr rangeAttr) {
2001 attrBuilder.addConstantRangeAttr(
2003 llvm::ConstantRange(rangeAttr.getLower(), rangeAttr.getUpper()));
2006 .Default([loc](
auto) {
2007 return emitError(loc,
"unsupported parameter attribute type");
2011FailureOr<llvm::AttrBuilder>
2012ModuleTranslation::convertParameterAttrs(LLVMFuncOp func,
int argIdx,
2013 DictionaryAttr paramAttrs) {
2014 llvm::AttrBuilder attrBuilder(llvmModule->getContext());
2016 Location loc = func.getLoc();
2018 for (
auto namedAttr : paramAttrs) {
2019 auto it = attrNameToKindMapping.find(namedAttr.getName());
2020 if (it != attrNameToKindMapping.end()) {
2021 llvm::Attribute::AttrKind llvmKind = it->second;
2025 }
else if (namedAttr.getNameDialect()) {
2026 if (
failed(iface.convertParameterAttr(func, argIdx, namedAttr, *
this)))
2035 ArgAndResultAttrsOpInterface attrsOp, llvm::CallBase *call,
2038 if (ArrayAttr argAttrsArray = attrsOp.getArgAttrsAttr()) {
2039 unsigned argAttrIdx = 0;
2040 llvm::SmallDenseSet<unsigned> immArgPositionsSet(immArgPositions.begin(),
2041 immArgPositions.end());
2042 for (
unsigned argIdx : llvm::seq<unsigned>(call->arg_size())) {
2043 if (argAttrIdx >= argAttrsArray.size())
2046 if (immArgPositionsSet.contains(argIdx))
2049 auto argAttrs = cast<DictionaryAttr>(argAttrsArray[argAttrIdx++]);
2050 if (argAttrs.empty())
2053 FailureOr<llvm::AttrBuilder> attrBuilder =
2054 convertParameterAttrs(attrsOp->getLoc(), argAttrs);
2055 if (failed(attrBuilder))
2057 call->addParamAttrs(argIdx, *attrBuilder);
2062 if (ArrayAttr resAttrsArray = attrsOp.getResAttrsAttr()) {
2063 if (!resAttrsArray.empty()) {
2064 auto resAttrs = cast<DictionaryAttr>(resAttrsArray[0]);
2065 FailureOr<llvm::AttrBuilder> attrBuilder =
2066 convertParameterAttrs(attrsOp->getLoc(), resAttrs);
2067 if (failed(attrBuilder))
2069 call->addRetAttrs(*attrBuilder);
2076std::optional<llvm::Attribute>
2078 if (
auto str = dyn_cast<StringAttr>(a))
2079 return llvm::Attribute::get(ctx, (
"no-builtin-" + str.getValue()).str());
2080 return std::nullopt;
2083std::optional<llvm::Attribute>
2086 StringAttr name = namedAttr.
getName();
2089 if (
auto strVal = dyn_cast<StringAttr>(value))
2090 return llvm::Attribute::get(ctx, name.getValue(), strVal.getValue());
2091 if (mlir::isa<UnitAttr>(value))
2092 return llvm::Attribute::get(ctx, name.getValue());
2093 return std::nullopt;
2096FailureOr<llvm::AttrBuilder>
2097ModuleTranslation::convertParameterAttrs(
Location loc,
2098 DictionaryAttr paramAttrs) {
2099 llvm::AttrBuilder attrBuilder(llvmModule->getContext());
2102 for (
auto namedAttr : paramAttrs) {
2103 auto it = attrNameToKindMapping.find(namedAttr.getName());
2104 if (it != attrNameToKindMapping.end()) {
2105 llvm::Attribute::AttrKind llvmKind = it->second;
2115LogicalResult ModuleTranslation::convertFunctionSignatures() {
2119 for (
auto function :
getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
2120 llvm::FunctionCallee llvmFuncCst = llvmModule->getOrInsertFunction(
2122 cast<llvm::FunctionType>(
convertType(function.getFunctionType())));
2123 llvm::Function *llvmFunc = cast<llvm::Function>(llvmFuncCst.getCallee());
2127 for (
auto function :
getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
2129 llvmFunc->setLinkage(convertLinkageToLLVM(function.getLinkage()));
2130 llvmFunc->setCallingConv(convertCConvToLLVM(function.getCConv()));
2140 if (
auto entryCount = function.getFunctionEntryCountAttr()) {
2141 ArrayRef<uint64_t> imports = entryCount.getImports();
2142 llvm::DenseSet<llvm::GlobalValue::GUID> importGUIDs;
2143 if (!imports.empty())
2144 importGUIDs.insert(imports.begin(), imports.end());
2145 llvm::MDBuilder metadataBuilder(llvmFunc->getContext());
2146 llvmFunc->setMetadata(
2147 llvm::LLVMContext::MD_prof,
2148 metadataBuilder.createFunctionEntryCount(
2149 entryCount.getEntryCount(),
2150 entryCount.getCountType() == ProfileCountType::Synthetic,
2151 imports.empty() ?
nullptr : &importGUIDs));
2155 if (
ArrayAttr allResultAttrs = function.getAllResultAttrs()) {
2156 DictionaryAttr resultAttrs = cast<DictionaryAttr>(allResultAttrs[0]);
2157 FailureOr<llvm::AttrBuilder> attrBuilder =
2158 convertParameterAttrs(function, -1, resultAttrs);
2161 llvmFunc->addRetAttrs(*attrBuilder);
2165 for (
auto [argIdx, llvmArg] : llvm::enumerate(llvmFunc->args())) {
2166 if (DictionaryAttr argAttrs = function.getArgAttrDict(argIdx)) {
2167 FailureOr<llvm::AttrBuilder> attrBuilder =
2168 convertParameterAttrs(function, argIdx, argAttrs);
2171 llvmArg.addAttrs(*attrBuilder);
2176 FailureOr<llvm::AttrBuilder> convertedPassthroughAttrs =
2178 function.getPassthroughAttr(),
2179 function.getPassthroughAttrName());
2180 if (
failed(convertedPassthroughAttrs))
2182 llvmFunc->addFnAttrs(*convertedPassthroughAttrs);
2185 llvmFunc->setVisibility(convertVisibilityToLLVM(function.getVisibility_()));
2188 if (std::optional<mlir::SymbolRefAttr> comdat = function.getComdat()) {
2189 auto selectorOp = cast<ComdatSelectorOp>(
2190 symbolTable().lookupNearestSymbolFrom(function, *comdat));
2191 llvmFunc->setComdat(comdatMapping.lookup(selectorOp));
2194 if (
auto gc = function.getGarbageCollector())
2195 llvmFunc->setGC(gc->str());
2197 if (
auto unnamedAddr = function.getUnnamedAddr())
2198 llvmFunc->setUnnamedAddr(convertUnnamedAddrToLLVM(*unnamedAddr));
2200 if (
auto alignment = function.getAlignment())
2201 llvmFunc->setAlignment(llvm::MaybeAlign(*alignment));
2204 debugTranslation->translate(function, *llvmFunc);
2210LogicalResult ModuleTranslation::convertFunctions() {
2212 for (
auto function :
getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
2215 if (function.isExternal()) {
2216 if (
failed(convertDialectAttributes(function, {})))
2221 if (
failed(convertOneFunction(function)))
2228LogicalResult ModuleTranslation::convertIFuncs() {
2229 for (
auto op :
getModuleBody(mlirModule).getOps<IFuncOp>()) {
2230 llvm::Type *type =
convertType(op.getIFuncType());
2231 llvm::GlobalValue::LinkageTypes linkage =
2232 convertLinkageToLLVM(op.getLinkage());
2233 llvm::Constant *resolver;
2235 resolver = cast<llvm::Constant>(resolverFn);
2238 op.getResolverAttr());
2239 resolver = cast<llvm::Constant>(
lookupAlias(aliasOp));
2243 llvm::GlobalIFunc::create(type, op.getAddressSpace(), linkage,
2244 op.getSymName(), resolver, llvmModule.get());
2246 ifunc->setUnnamedAddr(convertUnnamedAddrToLLVM(op.getUnnamedAddr()));
2247 ifunc->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
2249 ifuncMapping.try_emplace(op, ifunc);
2257LogicalResult ModuleTranslation::convertGlobalMetadata() {
2258 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
2259 auto *var = cast<llvm::GlobalVariable>(
lookupGlobal(op));
2260 if (FlatSymbolRefAttr associated = op.getAssociatedAttr()) {
2261 FailureOr<llvm::Metadata *> md =
2262 convertSymbolRefToMetadata(associated, [&]() {
2263 return op.
emitError(
"failed to convert associated metadata");
2267 var->setMetadata(llvm::LLVMContext::MD_associated,
2268 llvm::MDNode::get(var->getContext(), *md));
2271 if (
ArrayAttr absSym = op.getAbsoluteSymbolAttr()) {
2272 SmallVector<llvm::Metadata *> mdOps;
2273 llvm::LLVMContext &ctx = var->getContext();
2274 mdOps.reserve(absSym.size());
2275 for (Attribute attr : absSym) {
2276 auto intAttr = cast<IntegerAttr>(attr);
2277 llvm::IntegerType *ty = llvm::IntegerType::get(
2278 ctx, intAttr.getType().getIntOrFloatBitWidth());
2279 mdOps.push_back(llvm::ConstantAsMetadata::get(
2280 llvm::ConstantInt::get(ty, intAttr.getValue())));
2282 var->setMetadata(llvm::LLVMContext::MD_absolute_symbol,
2283 llvm::MDNode::get(ctx, mdOps));
2290LogicalResult ModuleTranslation::convertComdats() {
2291 for (
auto comdatOp :
getModuleBody(mlirModule).getOps<ComdatOp>()) {
2292 for (
auto selectorOp : comdatOp.getOps<ComdatSelectorOp>()) {
2294 if (module->getComdatSymbolTable().contains(selectorOp.getSymName()))
2296 <<
"comdat selection symbols must be unique even in different "
2298 llvm::Comdat *comdat =
module->getOrInsertComdat(selectorOp.getSymName());
2299 comdat->setSelectionKind(convertComdatToLLVM(selectorOp.getComdat()));
2300 comdatMapping.try_emplace(selectorOp, comdat);
2306LogicalResult ModuleTranslation::convertUnresolvedBlockAddress() {
2307 for (
auto &[blockAddressOp, llvmCst] : unresolvedBlockAddressMapping) {
2308 BlockAddressAttr blockAddressAttr = blockAddressOp.getBlockAddr();
2310 assert(llvmBlock &&
"expected LLVM blocks to be already translated");
2313 auto *llvmBlockAddr = llvm::BlockAddress::get(
2314 lookupFunction(blockAddressAttr.getFunction().getValue()), llvmBlock);
2315 llvmCst->replaceAllUsesWith(llvmBlockAddr);
2316 assert(llvmCst->use_empty() &&
"expected all uses to be replaced");
2317 cast<llvm::GlobalVariable>(llvmCst)->eraseFromParent();
2319 unresolvedBlockAddressMapping.clear();
2324 llvm::Instruction *inst) {
2325 if (llvm::MDNode *node = loopAnnotationTranslation->getAccessGroups(op))
2326 inst->setMetadata(llvm::LLVMContext::MD_access_group, node);
2331 auto [scopeIt, scopeInserted] =
2332 aliasScopeMetadataMapping.try_emplace(aliasScopeAttr,
nullptr);
2334 return scopeIt->second;
2335 llvm::LLVMContext &ctx = llvmModule->getContext();
2336 auto dummy = llvm::MDNode::getTemporary(ctx, {});
2338 auto [domainIt, insertedDomain] = aliasDomainMetadataMapping.try_emplace(
2339 aliasScopeAttr.getDomain(),
nullptr);
2340 if (insertedDomain) {
2343 operands.push_back(dummy.get());
2345 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getFalse(ctx)));
2346 if (StringAttr description = aliasScopeAttr.getDomain().getDescription())
2347 operands.push_back(llvm::MDString::get(ctx, description));
2348 domainIt->second = llvm::MDNode::get(ctx, operands);
2351 if (
auto stringAttr =
2352 dyn_cast<StringAttr>(aliasScopeAttr.getDomain().getId()))
2353 replacement = llvm::MDString::get(ctx, stringAttr.getValue());
2356 domainIt->second->replaceOperandWith(0,
replacement);
2359 assert(domainIt->second &&
"Scope's domain should already be valid");
2362 operands.push_back(dummy.get());
2363 operands.push_back(domainIt->second);
2364 if (StringAttr description = aliasScopeAttr.getDescription())
2365 operands.push_back(llvm::MDString::get(ctx, description));
2366 scopeIt->second = llvm::MDNode::get(ctx, operands);
2369 if (
auto stringAttr = dyn_cast<StringAttr>(aliasScopeAttr.getId()))
2370 replacement = llvm::MDString::get(ctx, stringAttr.getValue());
2373 scopeIt->second->replaceOperandWith(0,
replacement);
2374 return scopeIt->second;
2380 nodes.reserve(aliasScopeAttrs.size());
2381 for (AliasScopeAttr aliasScopeAttr : aliasScopeAttrs)
2387 llvm::Instruction *inst) {
2388 auto populateScopeMetadata = [&](ArrayAttr aliasScopeAttrs,
unsigned kind) {
2389 if (!aliasScopeAttrs || aliasScopeAttrs.empty())
2392 llvm::to_vector(aliasScopeAttrs.getAsRange<AliasScopeAttr>()));
2393 inst->setMetadata(kind, node);
2396 populateScopeMetadata(op.getAliasScopesOrNull(),
2397 llvm::LLVMContext::MD_alias_scope);
2398 populateScopeMetadata(op.getNoAliasScopesOrNull(),
2399 llvm::LLVMContext::MD_noalias);
2402llvm::MDNode *ModuleTranslation::getTBAANode(TBAATagAttr tbaaAttr)
const {
2403 return tbaaMetadataMapping.lookup(tbaaAttr);
2407 llvm::Instruction *inst) {
2408 ArrayAttr tagRefs = op.getTBAATagsOrNull();
2409 if (!tagRefs || tagRefs.empty())
2416 if (tagRefs.size() > 1) {
2417 op.emitWarning() <<
"TBAA access tags were not translated, because LLVM "
2418 "IR only supports a single tag per instruction";
2422 llvm::MDNode *node = getTBAANode(cast<TBAATagAttr>(tagRefs[0]));
2423 inst->setMetadata(llvm::LLVMContext::MD_tbaa, node);
2427 DereferenceableOpInterface op, llvm::Instruction *inst) {
2428 DereferenceableAttr derefAttr = op.getDereferenceableOrNull();
2432 llvm::MDNode *derefSizeNode = llvm::MDNode::get(
2434 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2435 llvm::IntegerType::get(
getLLVMContext(), 64), derefAttr.getBytes())));
2436 unsigned kindId = derefAttr.getMayBeNull()
2437 ? llvm::LLVMContext::MD_dereferenceable_or_null
2438 : llvm::LLVMContext::MD_dereferenceable;
2439 inst->setMetadata(kindId, derefSizeNode);
2444 llvm::transform(op.getWeights(), std::back_inserter(weights),
2445 [](int32_t value) { return static_cast<uint32_t>(value); });
2446 if (weights.empty())
2450 assert(inst &&
"expected the operation to have a mapping to an instruction");
2452 llvm::LLVMContext::MD_prof,
2456LogicalResult ModuleTranslation::createTBAAMetadata() {
2457 llvm::LLVMContext &ctx = llvmModule->getContext();
2458 llvm::IntegerType *offsetTy = llvm::IntegerType::get(ctx, 64);
2469 walker.
addWalk([&](TBAARootAttr root) {
2471 if (StringAttr
id = root.getId()) {
2472 node = llvm::MDNode::get(ctx, llvm::MDString::get(ctx,
id));
2475 auto selfRef = llvm::MDNode::getTemporary(ctx, {});
2476 node = llvm::MDNode::get(ctx, {selfRef.get()});
2477 node->replaceOperandWith(0, node);
2479 tbaaMetadataMapping.insert({root, node});
2482 walker.
addWalk([&](TBAATypeDescriptorAttr descriptor) {
2483 SmallVector<llvm::Metadata *> operands;
2484 operands.push_back(llvm::MDString::get(ctx, descriptor.getId()));
2485 for (TBAAMemberAttr member : descriptor.getMembers()) {
2486 operands.push_back(tbaaMetadataMapping.lookup(member.getTypeDesc()));
2487 operands.push_back(llvm::ConstantAsMetadata::get(
2488 llvm::ConstantInt::get(offsetTy, member.getOffset())));
2491 tbaaMetadataMapping.insert({descriptor, llvm::MDNode::get(ctx, operands)});
2494 walker.
addWalk([&](TBAATagAttr tag) {
2495 SmallVector<llvm::Metadata *> operands;
2497 operands.push_back(tbaaMetadataMapping.lookup(tag.getBaseType()));
2498 operands.push_back(tbaaMetadataMapping.lookup(tag.getAccessType()));
2500 operands.push_back(llvm::ConstantAsMetadata::get(
2501 llvm::ConstantInt::get(offsetTy, tag.getOffset())));
2502 if (tag.getConstant())
2504 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(offsetTy, 1)));
2506 tbaaMetadataMapping.insert({tag, llvm::MDNode::get(ctx, operands)});
2509 mlirModule->walk([&](AliasAnalysisOpInterface analysisOpInterface) {
2510 if (
auto attr = analysisOpInterface.getTBAATagsOrNull())
2517LogicalResult ModuleTranslation::createIdentMetadata() {
2518 if (
auto attr = mlirModule->getDiscardableAttrOfType<StringAttr>(
2519 LLVMDialect::getIdentAttrName())) {
2520 StringRef ident = attr;
2521 llvm::LLVMContext &ctx = llvmModule->
getContext();
2522 llvm::NamedMDNode *namedMd =
2523 llvmModule->getOrInsertNamedMetadata(LLVMDialect::getIdentAttrName());
2524 llvm::MDNode *md = llvm::MDNode::get(ctx, llvm::MDString::get(ctx, ident));
2525 namedMd->addOperand(md);
2531LogicalResult ModuleTranslation::createCommandlineMetadata() {
2532 if (
auto attr = mlirModule->getDiscardableAttrOfType<StringAttr>(
2533 LLVMDialect::getCommandlineAttrName())) {
2534 StringRef cmdLine = attr;
2535 llvm::LLVMContext &ctx = llvmModule->
getContext();
2536 llvm::NamedMDNode *nmd = llvmModule->getOrInsertNamedMetadata(
2537 LLVMDialect::getCommandlineAttrName());
2539 llvm::MDNode::get(ctx, llvm::MDString::get(ctx, cmdLine));
2540 nmd->addOperand(md);
2546LogicalResult ModuleTranslation::createDependentLibrariesMetadata() {
2547 if (
auto dependentLibrariesAttr = mlirModule->getDiscardableAttr(
2548 LLVM::LLVMDialect::getDependentLibrariesAttrName())) {
2550 llvmModule->getOrInsertNamedMetadata(
"llvm.dependent-libraries");
2551 llvm::LLVMContext &ctx = llvmModule->getContext();
2553 cast<ArrayAttr>(dependentLibrariesAttr).getAsRange<StringAttr>()) {
2555 llvm::MDNode::get(ctx, llvm::MDString::get(ctx, libAttr.getValue()));
2556 nmd->addOperand(md);
2563 llvm::Instruction *inst) {
2564 LoopAnnotationAttr attr =
2566 .Case<LLVM::BrOp, LLVM::CondBrOp>(
2567 [](
auto branchOp) {
return branchOp.getLoopAnnotationAttr(); });
2570 llvm::MDNode *loopMD =
2571 loopAnnotationTranslation->translateLoopAnnotation(attr, op);
2572 inst->setMetadata(llvm::LLVMContext::MD_loop, loopMD);
2576 auto iface = cast<DisjointFlagInterface>(op);
2578 if (
auto *disjointInst = dyn_cast<llvm::PossiblyDisjointInst>(value))
2579 disjointInst->setIsDisjoint(iface.getIsDisjoint());
2583 return typeTranslator.translateType(type);
2589 remapped.reserve(values.size());
2590 for (
Value v : values)
2596 llvm::Value *newValue) {
2597 if (oldValue == newValue)
2600 for (
auto &entry : valueMapping)
2601 if (entry.second == oldValue)
2602 entry.second = newValue;
2607 ompBuilder = std::make_unique<llvm::OpenMPIRBuilder>(*llvmModule);
2612 llvm::OpenMPIRBuilderConfig config(
2619 unsigned int defaultAS =
2620 llvmModule->getDataLayout().getProgramAddressSpace();
2621 config.setDefaultTargetAS(defaultAS);
2622 config.setRuntimeCC(llvmModule->getTargetTriple().isSPIRV()
2623 ? llvm::CallingConv::SPIR_FUNC
2624 : llvm::CallingConv::C);
2625 ompBuilder->setConfig(std::move(config));
2626 ompBuilder->initialize();
2628 return ompBuilder.get();
2634 return *llvm::vfs::getRealFileSystem();
2638 llvm::DILocalScope *scope) {
2639 return debugTranslation->translateLoc(loc, scope);
2644 return debugTranslation->translateExpression(attr);
2647llvm::DIGlobalVariableExpression *
2649 LLVM::DIGlobalVariableExpressionAttr attr) {
2650 return debugTranslation->translateGlobalVariableExpression(attr);
2654 return debugTranslation->translate(attr);
2659 return convertRoundingModeToLLVM(rounding);
2663 LLVM::FPExceptionBehavior exceptionBehavior) {
2664 return convertFPExceptionBehaviorToLLVM(exceptionBehavior);
2669 return llvmModule->getOrInsertNamedMetadata(name);
2672static std::unique_ptr<llvm::Module>
2676 auto llvmModule = std::make_unique<llvm::Module>(name, llvmContext);
2677 if (
auto dataLayoutAttr =
2679 llvmModule->setDataLayout(cast<StringAttr>(dataLayoutAttr).getValue());
2681 FailureOr<llvm::DataLayout> llvmDataLayout(llvm::DataLayout(
""));
2682 if (
auto iface = dyn_cast<DataLayoutOpInterface>(m)) {
2683 if (DataLayoutSpecInterface spec = iface.getDataLayoutSpec()) {
2687 }
else if (
auto mod = dyn_cast<ModuleOp>(m)) {
2688 if (DataLayoutSpecInterface spec = mod.getDataLayoutSpec()) {
2693 if (failed(llvmDataLayout))
2695 llvmModule->setDataLayout(*llvmDataLayout);
2697 if (
auto targetTripleAttr =
2699 llvmModule->setTargetTriple(
2700 llvm::Triple(cast<StringAttr>(targetTripleAttr).getValue()));
2703 LLVM::LLVMDialect::getModuleLevelAsmAttrName())) {
2704 auto asmArrayAttr = dyn_cast<ArrayAttr>(asmAttr);
2705 if (!asmArrayAttr) {
2706 m->
emitError(
"expected an array attribute for a module level asm");
2711 auto asmStrAttr = dyn_cast<StringAttr>(elt);
2714 "expected a string attribute for each entry of a module level asm");
2717 llvmModule->appendModuleInlineAsm(asmStrAttr.getValue());
2724std::unique_ptr<llvm::Module>
2726 StringRef name,
bool disableVerification,
2727 llvm::vfs::FileSystem *fs) {
2729 module->emitOpError("can not be translated to an LLVMIR module");
2733 std::unique_ptr<llvm::Module> llvmModule =
2742 llvm::IRBuilder<llvm::TargetFolder> llvmBuilder(
2744 llvm::TargetFolder(translator.getLLVMModule()->getDataLayout()));
2750 if (
failed(translator.convertOperation(*module, llvmBuilder)))
2753 if (
failed(translator.convertComdats()))
2755 if (
failed(translator.convertFunctionSignatures()))
2757 if (
failed(translator.convertGlobalsAndAliases()))
2759 if (
failed(translator.convertIFuncs()))
2761 if (
failed(translator.convertGlobalMetadata()))
2763 if (
failed(translator.convertFunctionMetadata()))
2765 if (
failed(translator.createTBAAMetadata()))
2767 if (
failed(translator.createIdentMetadata()))
2769 if (
failed(translator.createCommandlineMetadata()))
2771 if (
failed(translator.createDependentLibrariesMetadata()))
2775 for (Operation &o :
getModuleBody(module).getOperations()) {
2776 if (!isa<LLVM::LLVMFuncOp, LLVM::AliasOp, LLVM::GlobalOp,
2777 LLVM::GlobalCtorsOp, LLVM::GlobalDtorsOp, LLVM::ComdatOp,
2778 LLVM::IFuncOp>(&o) &&
2779 !o.hasTrait<OpTrait::IsTerminator>() &&
2780 failed(translator.convertOperation(o, llvmBuilder))) {
2788 if (
failed(translator.convertFunctions()))
2793 if (
failed(translator.convertUnresolvedBlockAddress()))
2798 translator.debugTranslation->addModuleFlagsIfNotPresent();
2801 if (
auto *ompBuilder = translator.getOpenMPBuilder())
2802 ompBuilder->finalize();
2804 if (!disableVerification &&
2805 llvm::verifyModule(*translator.llvmModule, &llvm::errs()))
2808 return std::move(translator.llvmModule);