568 if (!attr || isa<UndefAttr>(attr))
569 return llvm::UndefValue::get(llvmType);
570 if (isa<ZeroAttr>(attr))
571 return llvm::Constant::getNullValue(llvmType);
572 if (
auto *structType = dyn_cast<::llvm::StructType>(llvmType)) {
573 auto arrayAttr = dyn_cast<ArrayAttr>(attr);
575 emitError(loc,
"expected an array attribute for a struct constant");
578 SmallVector<llvm::Constant *> structElements;
579 structElements.reserve(structType->getNumElements());
580 for (
auto [elemType, elemAttr] :
581 zip_equal(structType->elements(), arrayAttr)) {
582 llvm::Constant *element =
586 structElements.push_back(element);
588 return llvm::ConstantStruct::get(structType, structElements);
592 if (
auto intAttr = dyn_cast<IntegerAttr>(attr)) {
595 auto intTy = dyn_cast<IntegerType>(intAttr.getType());
597 if (intTy && (intTy.isUnsigned() || intTy.getWidth() == 1))
598 value = intAttr.getValue().zextOrTrunc(llvmType->getIntegerBitWidth());
600 value = intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth());
601 return llvm::ConstantInt::get(llvmType, value);
603 if (
auto floatAttr = dyn_cast<FloatAttr>(attr)) {
604 const llvm::fltSemantics &sem = floatAttr.getValue().getSemantics();
609 unsigned floatWidth = APFloat::getSizeInBits(sem);
610 if (llvmType->isIntegerTy(floatWidth))
611 return llvm::ConstantInt::get(llvmType,
612 floatAttr.getValue().bitcastToAPInt());
614 llvm::Type::getFloatingPointTy(llvmType->getContext(),
615 floatAttr.getValue().getSemantics())) {
616 emitError(loc,
"FloatAttr does not match expected type of the constant");
619 return llvm::ConstantFP::get(llvmType, floatAttr.getValue());
621 if (
auto symAttr = dyn_cast<FlatSymbolRefAttr>(attr)) {
622 StringRef name = symAttr.getValue();
623 if (llvm::Function *func = moduleTranslation.
lookupFunction(name))
624 return llvm::ConstantExpr::getBitCast(func, llvmType);
625 if (llvm::GlobalValue *global = moduleTranslation.
lookupGlobal(name))
626 return llvm::ConstantExpr::getBitCast(global, llvmType);
627 emitError(loc,
"unknown symbol reference '") << name <<
"' in constant";
630 if (
auto splatAttr = dyn_cast<SplatElementsAttr>(attr)) {
631 llvm::Type *elementType;
632 uint64_t numElements;
633 bool isScalable =
false;
634 if (
auto *arrayTy = dyn_cast<llvm::ArrayType>(llvmType)) {
635 elementType = arrayTy->getElementType();
636 numElements = arrayTy->getNumElements();
637 }
else if (
auto *fVectorTy = dyn_cast<llvm::FixedVectorType>(llvmType)) {
638 elementType = fVectorTy->getElementType();
639 numElements = fVectorTy->getNumElements();
640 }
else if (
auto *sVectorTy = dyn_cast<llvm::ScalableVectorType>(llvmType)) {
641 elementType = sVectorTy->getElementType();
642 numElements = sVectorTy->getMinNumElements();
645 llvm_unreachable(
"unrecognized constant vector type");
650 bool elementTypeSequential =
651 isa<llvm::ArrayType, llvm::VectorType>(elementType);
654 elementTypeSequential ? splatAttr
655 : splatAttr.getSplatValue<Attribute>(),
656 loc, moduleTranslation);
659 if (llvmType->isVectorTy())
660 return llvm::ConstantVector::getSplat(
661 llvm::ElementCount::get(numElements, isScalable), child);
662 if (llvmType->isArrayTy()) {
663 auto *arrayType = llvm::ArrayType::get(elementType, numElements);
664 if (child->isNullValue() && !elementType->isFPOrFPVectorTy()) {
665 return llvm::ConstantAggregateZero::get(arrayType);
667 if (llvm::ConstantDataSequential::isElementTypeCompatible(elementType)) {
668 if (isa<llvm::IntegerType>(elementType)) {
669 if (llvm::ConstantInt *ci = dyn_cast<llvm::ConstantInt>(child)) {
670 if (ci->getBitWidth() == 8) {
671 SmallVector<int8_t> constants(numElements, ci->getZExtValue());
672 return llvm::ConstantDataArray::get(elementType->getContext(),
675 if (ci->getBitWidth() == 16) {
676 SmallVector<int16_t> constants(numElements, ci->getZExtValue());
677 return llvm::ConstantDataArray::get(elementType->getContext(),
680 if (ci->getBitWidth() == 32) {
681 SmallVector<int32_t> constants(numElements, ci->getZExtValue());
682 return llvm::ConstantDataArray::get(elementType->getContext(),
685 if (ci->getBitWidth() == 64) {
686 SmallVector<int64_t> constants(numElements, ci->getZExtValue());
687 return llvm::ConstantDataArray::get(elementType->getContext(),
692 if (elementType->isFloatingPointTy()) {
693 if (llvm::ConstantFP *cfp = dyn_cast<llvm::ConstantFP>(child)) {
694 APInt bitPattern = cfp->getValueAPF().bitcastToAPInt();
695 uint64_t value = bitPattern.getZExtValue();
698 if (bitPattern.getBitWidth() == 16) {
699 SmallVector<uint16_t> constants(numElements, value);
700 return llvm::ConstantDataArray::getFP(elementType, constants);
702 if (bitPattern.getBitWidth() == 32) {
703 SmallVector<uint32_t> constants(numElements, value);
704 return llvm::ConstantDataArray::getFP(elementType, constants);
706 if (bitPattern.getBitWidth() == 64) {
707 SmallVector<uint64_t> constants(numElements, value);
708 return llvm::ConstantDataArray::getFP(elementType, constants);
715 std::vector<llvm::Constant *> constants(numElements, child);
716 return llvm::ConstantArray::get(arrayType, constants);
721 if (llvm::Constant *
result =
723 llvmType, moduleTranslation)) {
727 if (
auto denseResourceAttr = dyn_cast<DenseResourceElementsAttr>(attr)) {
733 if (
auto elementsAttr = dyn_cast<ElementsAttr>(attr)) {
734 assert(elementsAttr.getShapedType().hasStaticShape());
735 assert(!elementsAttr.getShapedType().getShape().empty() &&
736 "unexpected empty elements attribute shape");
738 SmallVector<llvm::Constant *, 8> constants;
739 constants.reserve(elementsAttr.getNumElements());
741 for (
auto n : elementsAttr.getValues<Attribute>()) {
744 if (!constants.back())
747 ArrayRef<llvm::Constant *> constantsRef = constants;
749 constantsRef, elementsAttr.getShapedType().getShape(), llvmType, loc);
750 assert(constantsRef.empty() &&
"did not consume all elemental constants");
754 if (
auto stringAttr = dyn_cast<StringAttr>(attr)) {
755 return llvm::ConstantDataArray::get(moduleTranslation.
getLLVMContext(),
756 ArrayRef<char>{stringAttr.getValue()});
761 if (
auto arrayAttr = dyn_cast<ArrayAttr>(attr)) {
762 if (
auto *arrayTy = dyn_cast<llvm::ArrayType>(llvmType)) {
763 llvm::Type *elementType = arrayTy->getElementType();
764 Attribute previousElementAttr;
765 llvm::Constant *elementCst =
nullptr;
766 SmallVector<llvm::Constant *> constants;
767 constants.reserve(arrayTy->getNumElements());
768 for (Attribute elementAttr : arrayAttr) {
772 if (!previousElementAttr || previousElementAttr != elementAttr) {
773 previousElementAttr = elementAttr;
779 constants.push_back(elementCst);
781 return llvm::ConstantArray::get(arrayTy, constants);
785 emitError(loc,
"unsupported constant value");
789ModuleTranslation::ModuleTranslation(Operation *module,
790 std::unique_ptr<llvm::Module> llvmModule,
791 llvm::vfs::FileSystem *fs)
792 : mlirModule(module), llvmModule(std::move(llvmModule)),
794 std::make_unique<DebugTranslation>(module, *this->llvmModule)),
795 loopAnnotationTranslation(std::make_unique<LoopAnnotationTranslation>(
796 *this, *this->llvmModule)),
797 fileSystem(fs), typeTranslator(this->llvmModule->
getContext()),
800 "mlirModule should honor LLVM's module semantics.");
803ModuleTranslation::~ModuleTranslation() {
804 if (ompBuilder && !ompBuilder->isFinalized())
805 ompBuilder->finalize();
810 toProcess.push_back(®ion);
811 while (!toProcess.empty()) {
812 Region *current = toProcess.pop_back_val();
813 for (
Block &block : *current) {
814 blockMapping.erase(&block);
815 for (
Value arg : block.getArguments())
816 valueMapping.erase(arg);
818 for (
Value value : op.getResults())
819 valueMapping.erase(value);
820 if (op.hasSuccessors())
821 branchMapping.erase(&op);
822 if (isa<LLVM::GlobalOp>(op))
823 globalsMapping.erase(&op);
824 if (isa<LLVM::AliasOp>(op))
825 aliasesMapping.erase(&op);
826 if (isa<LLVM::IFuncOp>(op))
827 ifuncMapping.erase(&op);
828 if (isa<LLVM::CallOp>(op))
829 callMapping.erase(&op);
832 llvm::map_range(op.getRegions(), [](
Region &r) { return &r; }));
841 unsigned numArguments,
unsigned index) {
843 if (isa<LLVM::BrOp>(terminator))
850 auto branch = cast<BranchOpInterface>(terminator);
853 (!seenSuccessors.contains(successor) || successorOperands.
empty()) &&
854 "successors with arguments in LLVM branches must be different blocks");
855 seenSuccessors.insert(successor);
861 if (
auto condBranchOp = dyn_cast<LLVM::CondBrOp>(terminator)) {
864 return condBranchOp.getSuccessor(0) == current
865 ? condBranchOp.getTrueDestOperands()[
index]
866 : condBranchOp.getFalseDestOperands()[
index];
869 if (
auto switchOp = dyn_cast<LLVM::SwitchOp>(terminator)) {
872 if (switchOp.getDefaultDestination() == current)
873 return switchOp.getDefaultOperands()[
index];
874 for (
const auto &i : llvm::enumerate(switchOp.getCaseDestinations()))
875 if (i.value() == current)
876 return switchOp.getCaseOperands(i.index())[
index];
879 if (
auto indBrOp = dyn_cast<LLVM::IndirectBrOp>(terminator)) {
881 for (
const auto &i : llvm::enumerate(indBrOp->getSuccessors())) {
882 if (indBrOp->getSuccessor(i.index()) == current)
883 return indBrOp.getSuccessorOperands(i.index())[
index];
887 if (
auto invokeOp = dyn_cast<LLVM::InvokeOp>(terminator)) {
888 return invokeOp.getNormalDest() == current
889 ? invokeOp.getNormalDestOperands()[
index]
890 : invokeOp.getUnwindDestOperands()[
index];
894 "only branch, switch or invoke operations can be terminators "
895 "of a block that has successors");
903 for (
Block &bb : llvm::drop_begin(region)) {
905 auto phis = llvmBB->phis();
906 auto numArguments = bb.getNumArguments();
907 assert(numArguments == std::distance(phis.begin(), phis.end()));
908 for (
auto [
index, phiNode] : llvm::enumerate(phis)) {
909 for (
auto *pred : bb.getPredecessors()) {
915 llvm::Instruction *terminator =
917 assert(terminator &&
"missing the mapping for a terminator");
919 &bb, pred, numArguments,
index)),
920 terminator->getParent());
927 llvm::IRBuilderBase &builder, llvm::Intrinsic::ID intrinsic,
929 return builder.CreateIntrinsicWithoutFolding(intrinsic, tys, args);
933 llvm::IRBuilderBase &builder, llvm::Intrinsic::ID intrinsic,
935 return builder.CreateIntrinsicWithoutFolding(retTy, intrinsic, args);
940 Operation *intrOp, llvm::Intrinsic::ID intrinsic,
unsigned numResults,
944 assert(immArgPositions.size() == immArgAttrNames.size() &&
945 "LLVM `immArgPositions` and MLIR `immArgAttrNames` should have equal "
949 size_t numOpBundleOperands = 0;
950 auto opBundleSizesAttr = cast_if_present<DenseI32ArrayAttr>(
951 intrOp->
getAttr(LLVMDialect::getOpBundleSizesAttrName()));
952 auto opBundleTagsAttr = cast_if_present<ArrayAttr>(
953 intrOp->
getAttr(LLVMDialect::getOpBundleTagsAttrName()));
955 if (opBundleSizesAttr && opBundleTagsAttr) {
956 ArrayRef<int> opBundleSizes = opBundleSizesAttr.asArrayRef();
957 assert(opBundleSizes.size() == opBundleTagsAttr.size() &&
958 "operand bundles and tags do not match");
960 numOpBundleOperands = llvm::sum_of(opBundleSizes);
961 assert(numOpBundleOperands <= intrOp->getNumOperands() &&
962 "operand bundle operands is more than the number of operands");
965 size_t nextOperandIdx = 0;
966 opBundles.reserve(opBundleSizesAttr.size());
968 for (
auto [opBundleTagAttr, bundleSize] :
969 llvm::zip(opBundleTagsAttr, opBundleSizes)) {
970 auto bundleTag = cast<StringAttr>(opBundleTagAttr).str();
972 operands.slice(nextOperandIdx, bundleSize));
973 opBundles.emplace_back(std::move(bundleTag), std::move(bundleOperands));
974 nextOperandIdx += bundleSize;
979 auto opOperands = intrOp->
getOperands().drop_back(numOpBundleOperands);
980 auto operands = moduleTranslation.
lookupValues(opOperands);
982 for (
auto [immArgPos, immArgName] :
983 llvm::zip(immArgPositions, immArgAttrNames)) {
985 if (
auto intrinsicIntegerAttr =
986 dyn_cast<LLVM::IntrinsicIntegerAttrInterface>(attr))
987 attr = intrinsicIntegerAttr.getIntegerAttr();
988 auto typedAttr = llvm::cast<TypedAttr>(attr);
989 assert(typedAttr.getType().isIntOrFloat() &&
990 "expected int or float immarg");
991 auto *type = moduleTranslation.
convertType(typedAttr.getType());
993 type, typedAttr, intrOp->
getLoc(), moduleTranslation);
996 for (
auto &arg : args) {
998 arg = operands[opArg++];
1003 for (
unsigned overloadedResultIdx : overloadedResults) {
1004 if (numResults > 1) {
1006 overloadedTypes.push_back(moduleTranslation.
convertType(
1008 .getBody()[overloadedResultIdx]));
1010 overloadedTypes.push_back(
1014 for (
unsigned overloadedOperandIdx : overloadedOperands)
1015 overloadedTypes.push_back(args[overloadedOperandIdx]->
getType());
1016 llvm::Module *module = builder.GetInsertBlock()->getModule();
1017 llvm::Function *llvmIntr = llvm::Intrinsic::getOrInsertDeclaration(
1018 module, intrinsic, overloadedTypes);
1020 return builder.CreateCall(llvmIntr, args, opBundles);
1025LogicalResult ModuleTranslation::convertOperationImpl(
1026 Operation &op, llvm::IRBuilderBase &builder,
bool recordInsertions) {
1027 const LLVMTranslationDialectInterface *opIface = iface.
getInterfaceFor(&op);
1029 return op.
emitError(
"cannot be converted to LLVM IR: missing "
1030 "`LLVMTranslationDialectInterface` registration for "
1034 InstructionCapturingInserter::CollectionScope scope(builder,
1036 if (failed(opIface->convertOperation(&op, builder, *
this)))
1037 return op.
emitError(
"LLVM Translation failed for operation: ")
1040 return convertDialectAttributes(&op, scope.getCapturedInstructions());
1050LogicalResult ModuleTranslation::convertBlockImpl(
Block &bb,
1051 bool ignoreArguments,
1052 llvm::IRBuilderBase &builder,
1053 bool recordInsertions) {
1055 auto *subprogram = builder.GetInsertBlock()->getParent()->getSubprogram();
1063 if (!ignoreArguments) {
1065 unsigned numPredecessors =
1066 std::distance(predecessors.begin(), predecessors.end());
1068 auto wrappedType = arg.getType();
1071 "block argument does not have an LLVM type");
1072 builder.SetCurrentDebugLocation(
1073 debugTranslation->translateLoc(arg.getLoc(), subprogram));
1075 llvm::PHINode *phi = builder.CreatePHI(type, numPredecessors);
1081 for (
auto &op : bb) {
1083 builder.SetCurrentDebugLocation(
1084 debugTranslation->translateLoc(op.
getLoc(), subprogram));
1086 if (
failed(convertOperationImpl(op, builder, recordInsertions)))
1090 if (
auto iface = dyn_cast<WeightedBranchOpInterface>(op))
1100 return module->getRegion(0).front();
1109 llvm::Constant *cst) {
1110 return (linkage == llvm::GlobalVariable::ExternalLinkage && !cst) ||
1111 linkage == llvm::GlobalVariable::ExternalWeakLinkage;
1117 llvm::GlobalValue *gv) {
1118 if (dsoLocalRequested)
1119 gv->setDSOLocal(
true);
1128static FailureOr<llvm::Attribute>
1130 StringRef value = StringRef()) {
1131 auto kind = llvm::Attribute::getAttrKindFromName(key);
1132 if (kind == llvm::Attribute::None)
1133 return llvm::Attribute::get(ctx, key, value);
1135 if (llvm::Attribute::isIntAttrKind(kind)) {
1137 return emitError(loc) <<
"LLVM attribute '" << key <<
"' expects a value";
1140 if (!value.getAsInteger(0,
result))
1141 return llvm::Attribute::get(ctx, kind,
result);
1142 return llvm::Attribute::get(ctx, key, value);
1146 return emitError(loc) <<
"LLVM attribute '" << key
1147 <<
"' does not expect a value, found '" << value
1150 return llvm::Attribute::get(ctx, kind);
1161static FailureOr<llvm::AttrBuilder>
1163 ArrayAttr arrayAttr, StringRef arrayAttrName) {
1164 llvm::AttrBuilder attrBuilder(ctx);
1169 if (
auto stringAttr = dyn_cast<StringAttr>(attr)) {
1170 FailureOr<llvm::Attribute> llvmAttr =
1172 if (failed(llvmAttr))
1174 attrBuilder.addAttribute(*llvmAttr);
1178 auto arrayAttr = dyn_cast<ArrayAttr>(attr);
1179 if (!arrayAttr || arrayAttr.size() != 2)
1180 return emitError(loc) <<
"expected '" << arrayAttrName
1181 <<
"' to contain string or array attributes";
1183 auto keyAttr = dyn_cast<StringAttr>(arrayAttr[0]);
1184 auto valueAttr = dyn_cast<StringAttr>(arrayAttr[1]);
1185 if (!keyAttr || !valueAttr)
1186 return emitError(loc) <<
"expected arrays within '" << arrayAttrName
1187 <<
"' to contain two strings";
1190 loc, ctx, keyAttr.getValue(), valueAttr.getValue());
1191 if (failed(llvmAttr))
1193 attrBuilder.addAttribute(*llvmAttr);
1199LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
1208 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
1210 llvm::Constant *cst =
nullptr;
1211 const bool deferValueAttrToPass2 = op.getValueOrNull() &&
1212 !op.getInitializerBlock() &&
1213 !isa<StringAttr>(op.getValueOrNull());
1214 if (op.getValueOrNull() && !deferValueAttrToPass2) {
1217 if (
auto strAttr = dyn_cast_or_null<StringAttr>(op.getValueOrNull())) {
1218 cst = llvm::ConstantDataArray::getString(
1219 llvmModule->getContext(), strAttr.getValue(),
false);
1220 type = cst->getType();
1224 auto linkage = convertLinkageToLLVM(op.getLinkage());
1230 if (!deferValueAttrToPass2) {
1231 if (!dropInitializer && !cst)
1232 cst = llvm::UndefValue::get(type);
1233 else if (dropInitializer && cst)
1239 auto *var =
new llvm::GlobalVariable(
1240 *llvmModule, type, op.getConstant(), linkage, cst, op.getSymName(),
1242 op.getThreadLocal_() ? llvm::GlobalValue::GeneralDynamicTLSModel
1243 : llvm::GlobalValue::NotThreadLocal,
1244 op.getAddrSpace(), op.getExternallyInitialized());
1246 if (std::optional<mlir::SymbolRefAttr> comdat = op.getComdat()) {
1247 auto selectorOp = cast<ComdatSelectorOp>(
1249 var->setComdat(comdatMapping.lookup(selectorOp));
1252 if (op.getUnnamedAddr().has_value())
1253 var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
1255 if (op.getSection().has_value())
1256 var->setSection(*op.getSection());
1260 std::optional<uint64_t> alignment = op.getAlignment();
1261 if (alignment.has_value())
1262 var->setAlignment(llvm::MaybeAlign(alignment.value()));
1264 var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
1266 globalsMapping.try_emplace(op, var);
1267 globalsByNameMapping.try_emplace(op.getSymName(), var);
1270 if (op.getDbgExprs()) {
1271 for (
auto exprAttr :
1272 op.getDbgExprs()->getAsRange<DIGlobalVariableExpressionAttr>()) {
1273 llvm::DIGlobalVariableExpression *diGlobalExpr =
1274 debugTranslation->translateGlobalVariableExpression(exprAttr);
1275 llvm::DIGlobalVariable *diGlobalVar = diGlobalExpr->getVariable();
1276 var->addDebugInfo(diGlobalExpr);
1295 llvm::DIScope *scope = diGlobalVar->getScope();
1296 if (
auto *mod = dyn_cast_if_present<llvm::DIModule>(scope))
1297 scope = mod->getScope();
1298 else if (
auto *cb = dyn_cast_if_present<llvm::DICommonBlock>(scope)) {
1300 dyn_cast_if_present<llvm::DISubprogram>(cb->getScope()))
1301 scope = sp->getUnit();
1302 }
else if (
auto *sp = dyn_cast_if_present<llvm::DISubprogram>(scope))
1303 scope = sp->getUnit();
1306 if (llvm::DICompileUnit *compileUnit =
1307 dyn_cast_if_present<llvm::DICompileUnit>(scope)) {
1310 allGVars[compileUnit].push_back(diGlobalExpr);
1316 FailureOr<llvm::AttrBuilder> convertedTargetSpecificAttrs =
1318 op.getTargetSpecificAttrsAttr(),
1319 op.getTargetSpecificAttrsAttrName());
1320 if (
failed(convertedTargetSpecificAttrs))
1322 var->addAttributes(*convertedTargetSpecificAttrs);
1327 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
1328 if (!op.getValueOrNull() || op.getInitializerBlock() ||
1329 isa<StringAttr>(op.getValueOrNull()))
1333 llvm::Constant *cst =
1338 auto linkage = convertLinkageToLLVM(op.getLinkage());
1340 auto *var = cast<llvm::GlobalVariable>(
lookupGlobal(op));
1341 if (dropInitializer)
1342 var->setInitializer(
nullptr);
1344 var->setInitializer(cst);
1348 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
1350 llvm::Constant *cst =
nullptr;
1351 llvm::GlobalValue::LinkageTypes linkage =
1352 convertLinkageToLLVM(op.getLinkage());
1353 llvm::Module &llvmMod = *llvmModule;
1356 llvm::GlobalAlias *var = llvm::GlobalAlias::create(
1357 type, op.getAddrSpace(), linkage, op.getSymName(), cst,
1360 var->setThreadLocalMode(op.getThreadLocal_()
1361 ? llvm::GlobalAlias::GeneralDynamicTLSModel
1362 : llvm::GlobalAlias::NotThreadLocal);
1367 if (op.getUnnamedAddr().has_value())
1368 var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
1370 var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
1372 aliasesMapping.try_emplace(op, var);
1376 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
1377 if (
Block *initializer = op.getInitializerBlock()) {
1378 llvm::IRBuilder<llvm::TargetFolder> builder(
1379 llvmModule->getContext(),
1380 llvm::TargetFolder(llvmModule->getDataLayout()));
1382 [[maybe_unused]]
int numConstantsHit = 0;
1383 [[maybe_unused]]
int numConstantsErased = 0;
1386 for (
auto &op : initializer->without_terminator()) {
1400 if (
auto *agg = dyn_cast<llvm::ConstantAggregate>(cst)) {
1403 int numUsers = std::distance(
result.use_begin(),
result.use_end());
1405 constantAggregateUseMap.try_emplace(agg, numUsers);
1408 iterator->second += numUsers;
1414 auto *cst = dyn_cast<llvm::ConstantAggregate>(
lookupValue(v));
1417 auto iter = constantAggregateUseMap.find(cst);
1418 assert(iter != constantAggregateUseMap.end() &&
"constant not found");
1420 if (iter->second == 0) {
1423 if (cst->user_empty()) {
1424 cst->destroyConstant();
1425 numConstantsErased++;
1427 constantAggregateUseMap.erase(iter);
1432 ReturnOp ret = cast<ReturnOp>(initializer->getTerminator());
1433 llvm::Constant *cst =
1434 cast<llvm::Constant>(
lookupValue(ret.getOperand(0)));
1435 auto *global = cast<llvm::GlobalVariable>(
lookupGlobal(op));
1437 global->setInitializer(cst);
1441 for (
auto it : constantAggregateUseMap) {
1442 auto *cst = it.first;
1443 cst->removeDeadConstantUsers();
1444 if (cst->user_empty()) {
1445 cst->destroyConstant();
1446 numConstantsErased++;
1450 LLVM_DEBUG(llvm::dbgs()
1451 <<
"Convert initializer for " << op.
getName() <<
"\n";
1452 llvm::dbgs() << numConstantsHit <<
" new constants hit\n";
1454 << numConstantsErased <<
" dangling constants erased\n";);
1460 auto ctorOp = dyn_cast<GlobalCtorsOp>(op);
1461 auto dtorOp = dyn_cast<GlobalDtorsOp>(op);
1462 if (!ctorOp && !dtorOp)
1468 if ((ctorOp && ctorOp.getCtors().empty()) ||
1469 (dtorOp && dtorOp.getDtors().empty())) {
1470 llvm::IRBuilder<llvm::TargetFolder> builder(
1471 llvmModule->getContext(),
1472 llvm::TargetFolder(llvmModule->getDataLayout()));
1473 llvm::Type *eltTy = llvm::StructType::get(
1474 builder.getInt32Ty(), builder.getPtrTy(), builder.getPtrTy());
1475 llvm::ArrayType *at = llvm::ArrayType::get(eltTy, 0);
1476 llvm::Constant *zeroInit = llvm::Constant::getNullValue(at);
1477 (void)
new llvm::GlobalVariable(
1478 *llvmModule, zeroInit->getType(),
false,
1479 llvm::GlobalValue::AppendingLinkage, zeroInit,
1480 ctorOp ?
"llvm.global_ctors" :
"llvm.global_dtors");
1483 ? llvm::zip(ctorOp.getCtors(), ctorOp.getPriorities())
1484 : llvm::zip(dtorOp.getDtors(), dtorOp.getPriorities());
1485 auto appendGlobalFn =
1486 ctorOp ? llvm::appendToGlobalCtors : llvm::appendToGlobalDtors;
1487 for (
const auto &[sym, prio] : range) {
1490 appendGlobalFn(*llvmModule, f, cast<IntegerAttr>(prio).getInt(),
1496 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::GlobalOp>())
1497 if (
failed(convertDialectAttributes(op, {})))
1502 for (
const auto &[compileUnit, globals] : allGVars) {
1503 compileUnit->replaceGlobalVariables(
1508 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
1509 Block &initializer = op.getInitializerBlock();
1510 llvm::IRBuilder<llvm::TargetFolder> builder(
1511 llvmModule->getContext(),
1512 llvm::TargetFolder(llvmModule->getDataLayout()));
1522 auto *cst = cast<llvm::Constant>(
lookupValue(ret.getOperand(0)));
1523 assert(aliasesMapping.count(op));
1524 auto *alias = cast<llvm::GlobalAlias>(aliasesMapping[op]);
1525 alias->setAliasee(cst);
1528 for (
auto op :
getModuleBody(mlirModule).getOps<LLVM::AliasOp>())
1529 if (
failed(convertDialectAttributes(op, {})))
1537 const llvm::APInt &value) {
1538 llvm::Constant *constant = llvm::ConstantInt::get(context, value);
1539 return llvm::ConstantAsMetadata::get(constant);
1544 const llvm::APInt &value) {
1552 llvm::Metadata *typeMD =
1553 llvm::ConstantAsMetadata::get(llvm::UndefValue::get(type));
1554 llvm::Metadata *isSignedMD =
1556 return llvm::MDNode::get(context, {typeMD, isSignedMD});
1564 values, std::back_inserter(mdValues), [&context](int32_t value) {
1567 return llvm::MDNode::get(context, mdValues);
1570LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
1573 blockMapping.clear();
1574 valueMapping.clear();
1575 branchMapping.clear();
1577 llvm::LLVMContext &llvmContext = llvmFunc->getContext();
1580 for (
auto [mlirArg, llvmArg] :
1581 llvm::zip(func.getArguments(), llvmFunc->args()))
1585 if (func.getPersonality()) {
1586 llvm::Type *ty = llvm::PointerType::getUnqual(llvmFunc->getContext());
1587 if (llvm::Constant *pfunc =
getLLVMConstant(ty, func.getPersonalityAttr(),
1588 func.getLoc(), *
this))
1589 llvmFunc->setPersonalityFn(pfunc);
1592 if (std::optional<StringRef> section = func.getSection())
1593 llvmFunc->setSection(*section);
1595 if (func.getArmStreaming())
1596 llvmFunc->addFnAttr(
"aarch64_pstate_sm_enabled");
1597 else if (func.getArmLocallyStreaming())
1598 llvmFunc->addFnAttr(
"aarch64_pstate_sm_body");
1599 else if (func.getArmStreamingCompatible())
1600 llvmFunc->addFnAttr(
"aarch64_pstate_sm_compatible");
1602 if (func.getArmNewZa())
1603 llvmFunc->addFnAttr(
"aarch64_new_za");
1604 else if (func.getArmInZa())
1605 llvmFunc->addFnAttr(
"aarch64_in_za");
1606 else if (func.getArmOutZa())
1607 llvmFunc->addFnAttr(
"aarch64_out_za");
1608 else if (func.getArmInoutZa())
1609 llvmFunc->addFnAttr(
"aarch64_inout_za");
1610 else if (func.getArmPreservesZa())
1611 llvmFunc->addFnAttr(
"aarch64_preserves_za");
1613 if (
auto targetCpu = func.getTargetCpu())
1614 llvmFunc->addFnAttr(
"target-cpu", *targetCpu);
1616 if (
auto tuneCpu = func.getTuneCpu())
1617 llvmFunc->addFnAttr(
"tune-cpu", *tuneCpu);
1619 if (
auto reciprocalEstimates = func.getReciprocalEstimates())
1620 llvmFunc->addFnAttr(
"reciprocal-estimates", *reciprocalEstimates);
1622 if (
auto preferVectorWidth = func.getPreferVectorWidth())
1623 llvmFunc->addFnAttr(
"prefer-vector-width", *preferVectorWidth);
1625 if (func.getUseSampleProfile())
1626 llvmFunc->addFnAttr(
"use-sample-profile");
1628 if (
auto attr = func.getVscaleRange())
1629 llvmFunc->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
1631 attr->getMaxRange().getInt()));
1633 if (
auto noSignedZerosFpMath = func.getNoSignedZerosFpMath())
1634 llvmFunc->addFnAttr(
"no-signed-zeros-fp-math",
1635 llvm::toStringRef(*noSignedZerosFpMath));
1637 if (
auto fpContract = func.getFpContract())
1638 llvmFunc->addFnAttr(
"fp-contract", *fpContract);
1640 if (
auto instrumentFunctionEntry = func.getInstrumentFunctionEntry())
1641 llvmFunc->addFnAttr(
"instrument-function-entry", *instrumentFunctionEntry);
1643 if (
auto instrumentFunctionExit = func.getInstrumentFunctionExit())
1644 llvmFunc->addFnAttr(
"instrument-function-exit", *instrumentFunctionExit);
1647 for (
auto &bb : func) {
1648 auto *llvmBB = llvm::BasicBlock::Create(llvmContext);
1649 llvmBB->insertInto(llvmFunc);
1656 for (
Block *bb : blocks) {
1657 CapturingIRBuilder builder(llvmContext,
1658 llvm::TargetFolder(llvmModule->getDataLayout()));
1659 if (
failed(convertBlockImpl(*bb, bb->isEntryBlock(), builder,
1669 return convertDialectAttributes(func, {});
1672LogicalResult ModuleTranslation::convertDialectAttributes(
1673 Operation *op, ArrayRef<llvm::Instruction *> instructions) {
1675 if (
failed(iface.amendOperation(op, instructions, attribute, *
this)))
1683 llvm::Function *llvmFunc) {
1684 if (!
func.getMemoryEffects())
1687 MemoryEffectsAttr memEffects =
func.getMemoryEffectsAttr();
1690 llvm::MemoryEffects newMemEffects =
1691 llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
1692 convertModRefInfoToLLVM(memEffects.getArgMem()));
1693 newMemEffects |= llvm::MemoryEffects(
1694 llvm::MemoryEffects::Location::InaccessibleMem,
1695 convertModRefInfoToLLVM(memEffects.getInaccessibleMem()));
1697 llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
1698 convertModRefInfoToLLVM(memEffects.getOther()));
1700 llvm::MemoryEffects(llvm::MemoryEffects::Location::ErrnoMem,
1701 convertModRefInfoToLLVM(memEffects.getErrnoMem()));
1703 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem0,
1704 convertModRefInfoToLLVM(memEffects.getTargetMem0()));
1706 llvm::MemoryEffects(llvm::MemoryEffects::Location::TargetMem1,
1707 convertModRefInfoToLLVM(memEffects.getTargetMem1()));
1708 llvmFunc->setMemoryEffects(newMemEffects);
1713 if (!allocSizeAttr || allocSizeAttr.empty())
1714 return llvm::Attribute{};
1716 unsigned elemSize =
static_cast<unsigned>(allocSizeAttr[0]);
1717 std::optional<unsigned> numElems;
1718 if (allocSizeAttr.size() > 1)
1719 numElems =
static_cast<unsigned>(allocSizeAttr[1]);
1721 return llvm::Attribute::getWithAllocSizeArgs(
getLLVMContext(), elemSize,
1725 llvm::AttrBuilder &Attrs) {
1726 std::optional<DenormalFPEnvAttr> denormalFpEnv =
func.getDenormalFpenv();
1730 llvm::DenormalMode DefaultMode(
1731 convertDenormalModeKindToLLVM(denormalFpEnv->getDefaultOutputMode()),
1732 convertDenormalModeKindToLLVM(denormalFpEnv->getDefaultInputMode()));
1733 llvm::DenormalMode FloatMode(
1734 convertDenormalModeKindToLLVM(denormalFpEnv->getFloatOutputMode()),
1735 convertDenormalModeKindToLLVM(denormalFpEnv->getFloatInputMode()));
1737 llvm::DenormalFPEnv FPEnv(DefaultMode, FloatMode);
1738 Attrs.addDenormalFPEnvAttr(FPEnv);
1743 llvm::Function *llvmFunc) {
1745 llvm::AttrBuilder AttrBuilder(llvmFunc->getContext());
1747 if (
func.getNoInlineAttr())
1748 llvmFunc->addFnAttr(llvm::Attribute::NoInline);
1749 if (
func.getAlwaysInlineAttr())
1750 llvmFunc->addFnAttr(llvm::Attribute::AlwaysInline);
1751 if (
func.getInlineHintAttr())
1752 llvmFunc->addFnAttr(llvm::Attribute::InlineHint);
1753 if (
func.getOptimizeNoneAttr())
1754 llvmFunc->addFnAttr(llvm::Attribute::OptimizeNone);
1755 if (
func.getReturnsTwiceAttr())
1756 llvmFunc->addFnAttr(llvm::Attribute::ReturnsTwice);
1757 if (
func.getColdAttr())
1758 llvmFunc->addFnAttr(llvm::Attribute::Cold);
1759 if (
func.getHotAttr())
1760 llvmFunc->addFnAttr(llvm::Attribute::Hot);
1761 if (
func.getNoduplicateAttr())
1762 llvmFunc->addFnAttr(llvm::Attribute::NoDuplicate);
1763 if (
func.getConvergentAttr())
1764 llvmFunc->addFnAttr(llvm::Attribute::Convergent);
1765 if (
func.getNoUnwindAttr())
1766 llvmFunc->addFnAttr(llvm::Attribute::NoUnwind);
1767 if (
func.getWillReturnAttr())
1768 llvmFunc->addFnAttr(llvm::Attribute::WillReturn);
1769 if (
func.getNoreturnAttr())
1770 llvmFunc->addFnAttr(llvm::Attribute::NoReturn);
1771 if (
func.getOptsizeAttr())
1772 llvmFunc->addFnAttr(llvm::Attribute::OptimizeForSize);
1773 if (
func.getMinsizeAttr())
1774 llvmFunc->addFnAttr(llvm::Attribute::MinSize);
1775 if (
func.getSaveRegParamsAttr())
1776 llvmFunc->addFnAttr(
"save-reg-params");
1777 if (
func.getNoCallerSavedRegistersAttr())
1778 llvmFunc->addFnAttr(
"no_caller_saved_registers");
1779 if (
func.getNocallbackAttr())
1780 llvmFunc->addFnAttr(llvm::Attribute::NoCallback);
1781 if (StringAttr modFormat =
func.getModularFormatAttr())
1782 llvmFunc->addFnAttr(
"modular-format", modFormat.getValue());
1783 if (TargetFeaturesAttr targetFeatAttr =
func.getTargetFeaturesAttr())
1784 llvmFunc->addFnAttr(
"target-features", targetFeatAttr.getFeaturesString());
1785 if (FramePointerKindAttr fpAttr =
func.getFramePointerAttr())
1786 llvmFunc->addFnAttr(
"frame-pointer", stringifyFramePointerKind(
1787 fpAttr.getFramePointerKind()));
1788 if (UWTableKindAttr uwTableKindAttr =
func.getUwtableKindAttr())
1789 llvmFunc->setUWTableKind(
1790 convertUWTableKindToLLVM(uwTableKindAttr.getUwtableKind()));
1791 if (StringAttr zcsr =
func.getZeroCallUsedRegsAttr())
1792 llvmFunc->addFnAttr(
"zero-call-used-regs", zcsr.getValue());
1795 if (noBuiltins.empty())
1796 llvmFunc->addFnAttr(
"no-builtins");
1807 llvmFunc->addFnAttr(attr);
1812 llvmFunc->addFnAttrs(AttrBuilder);
1817 llvm::Function *llvmFunc,
1819 llvm::LLVMContext &llvmContext = llvmFunc->getContext();
1821 if (VecTypeHintAttr vecTypeHint =
func.getVecTypeHintAttr()) {
1822 Type type = vecTypeHint.getHint().getValue();
1823 llvm::Type *llvmType = translation.
convertType(type);
1824 bool isSigned = vecTypeHint.getIsSigned();
1825 llvmFunc->setMetadata(
1826 func.getVecTypeHintAttrName(),
1831 func.getWorkGroupSizeHint()) {
1832 llvmFunc->setMetadata(
1833 func.getWorkGroupSizeHintAttrName(),
1838 func.getReqdWorkGroupSize()) {
1839 llvmFunc->setMetadata(
1840 func.getReqdWorkGroupSizeAttrName(),
1844 if (std::optional<uint32_t> intelReqdSubGroupSize =
1845 func.getIntelReqdSubGroupSize()) {
1846 llvmFunc->setMetadata(
1847 func.getIntelReqdSubGroupSizeAttrName(),
1849 llvm::APInt(32, *intelReqdSubGroupSize)));
1854 llvm::Attribute::AttrKind llvmKind,
1859 .Case([&](TypeAttr typeAttr) {
1860 attrBuilder.addTypeAttr(
1861 llvmKind, moduleTranslation.
convertType(typeAttr.getValue()));
1864 .Case([&](IntegerAttr intAttr) {
1865 attrBuilder.addRawIntAttr(llvmKind, intAttr.getInt());
1868 .Case([&](UnitAttr) {
1869 attrBuilder.addAttribute(llvmKind);
1872 .Case([&](LLVM::ConstantRangeAttr rangeAttr) {
1873 attrBuilder.addConstantRangeAttr(
1875 llvm::ConstantRange(rangeAttr.getLower(), rangeAttr.getUpper()));
1878 .Default([loc](
auto) {
1879 return emitError(loc,
"unsupported parameter attribute type");
1883FailureOr<llvm::AttrBuilder>
1884ModuleTranslation::convertParameterAttrs(LLVMFuncOp func,
int argIdx,
1885 DictionaryAttr paramAttrs) {
1886 llvm::AttrBuilder attrBuilder(llvmModule->getContext());
1888 Location loc = func.getLoc();
1890 for (
auto namedAttr : paramAttrs) {
1891 auto it = attrNameToKindMapping.find(namedAttr.getName());
1892 if (it != attrNameToKindMapping.end()) {
1893 llvm::Attribute::AttrKind llvmKind = it->second;
1897 }
else if (namedAttr.getNameDialect()) {
1898 if (
failed(iface.convertParameterAttr(func, argIdx, namedAttr, *
this)))
1907 ArgAndResultAttrsOpInterface attrsOp, llvm::CallBase *call,
1910 if (ArrayAttr argAttrsArray = attrsOp.getArgAttrsAttr()) {
1911 unsigned argAttrIdx = 0;
1912 llvm::SmallDenseSet<unsigned> immArgPositionsSet(immArgPositions.begin(),
1913 immArgPositions.end());
1914 for (
unsigned argIdx : llvm::seq<unsigned>(call->arg_size())) {
1915 if (argAttrIdx >= argAttrsArray.size())
1918 if (immArgPositionsSet.contains(argIdx))
1921 auto argAttrs = cast<DictionaryAttr>(argAttrsArray[argAttrIdx++]);
1922 if (argAttrs.empty())
1925 FailureOr<llvm::AttrBuilder> attrBuilder =
1926 convertParameterAttrs(attrsOp->getLoc(), argAttrs);
1927 if (failed(attrBuilder))
1929 call->addParamAttrs(argIdx, *attrBuilder);
1934 if (ArrayAttr resAttrsArray = attrsOp.getResAttrsAttr()) {
1935 if (!resAttrsArray.empty()) {
1936 auto resAttrs = cast<DictionaryAttr>(resAttrsArray[0]);
1937 FailureOr<llvm::AttrBuilder> attrBuilder =
1938 convertParameterAttrs(attrsOp->getLoc(), resAttrs);
1939 if (failed(attrBuilder))
1941 call->addRetAttrs(*attrBuilder);
1948std::optional<llvm::Attribute>
1950 if (
auto str = dyn_cast<StringAttr>(a))
1951 return llvm::Attribute::get(ctx, (
"no-builtin-" + str.getValue()).str());
1952 return std::nullopt;
1955std::optional<llvm::Attribute>
1958 StringAttr name = namedAttr.
getName();
1961 if (
auto strVal = dyn_cast<StringAttr>(value))
1962 return llvm::Attribute::get(ctx, name.getValue(), strVal.getValue());
1963 if (mlir::isa<UnitAttr>(value))
1964 return llvm::Attribute::get(ctx, name.getValue());
1965 return std::nullopt;
1968FailureOr<llvm::AttrBuilder>
1969ModuleTranslation::convertParameterAttrs(
Location loc,
1970 DictionaryAttr paramAttrs) {
1971 llvm::AttrBuilder attrBuilder(llvmModule->getContext());
1974 for (
auto namedAttr : paramAttrs) {
1975 auto it = attrNameToKindMapping.find(namedAttr.getName());
1976 if (it != attrNameToKindMapping.end()) {
1977 llvm::Attribute::AttrKind llvmKind = it->second;
1987LogicalResult ModuleTranslation::convertFunctionSignatures() {
1990 for (
auto function :
getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
1991 llvm::FunctionCallee llvmFuncCst = llvmModule->getOrInsertFunction(
1993 cast<llvm::FunctionType>(
convertType(function.getFunctionType())));
1994 llvm::Function *llvmFunc = cast<llvm::Function>(llvmFuncCst.getCallee());
1995 llvmFunc->setLinkage(convertLinkageToLLVM(function.getLinkage()));
1996 llvmFunc->setCallingConv(convertCConvToLLVM(function.getCConv()));
2007 if (std::optional<uint64_t> entryCount = function.getFunctionEntryCount())
2008 llvmFunc->setEntryCount(entryCount.value());
2011 if (
ArrayAttr allResultAttrs = function.getAllResultAttrs()) {
2012 DictionaryAttr resultAttrs = cast<DictionaryAttr>(allResultAttrs[0]);
2013 FailureOr<llvm::AttrBuilder> attrBuilder =
2014 convertParameterAttrs(function, -1, resultAttrs);
2017 llvmFunc->addRetAttrs(*attrBuilder);
2021 for (
auto [argIdx, llvmArg] : llvm::enumerate(llvmFunc->args())) {
2022 if (DictionaryAttr argAttrs = function.getArgAttrDict(argIdx)) {
2023 FailureOr<llvm::AttrBuilder> attrBuilder =
2024 convertParameterAttrs(function, argIdx, argAttrs);
2027 llvmArg.addAttrs(*attrBuilder);
2032 FailureOr<llvm::AttrBuilder> convertedPassthroughAttrs =
2034 function.getPassthroughAttr(),
2035 function.getPassthroughAttrName());
2036 if (
failed(convertedPassthroughAttrs))
2038 llvmFunc->addFnAttrs(*convertedPassthroughAttrs);
2041 llvmFunc->setVisibility(convertVisibilityToLLVM(function.getVisibility_()));
2044 if (std::optional<mlir::SymbolRefAttr> comdat = function.getComdat()) {
2045 auto selectorOp = cast<ComdatSelectorOp>(
2047 llvmFunc->setComdat(comdatMapping.lookup(selectorOp));
2050 if (
auto gc = function.getGarbageCollector())
2051 llvmFunc->setGC(gc->str());
2053 if (
auto unnamedAddr = function.getUnnamedAddr())
2054 llvmFunc->setUnnamedAddr(convertUnnamedAddrToLLVM(*unnamedAddr));
2056 if (
auto alignment = function.getAlignment())
2057 llvmFunc->setAlignment(llvm::MaybeAlign(*alignment));
2060 debugTranslation->translate(function, *llvmFunc);
2066LogicalResult ModuleTranslation::convertFunctions() {
2068 for (
auto function :
getModuleBody(mlirModule).getOps<LLVMFuncOp>()) {
2071 if (function.isExternal()) {
2072 if (
failed(convertDialectAttributes(function, {})))
2077 if (
failed(convertOneFunction(function)))
2084LogicalResult ModuleTranslation::convertIFuncs() {
2085 for (
auto op :
getModuleBody(mlirModule).getOps<IFuncOp>()) {
2086 llvm::Type *type =
convertType(op.getIFuncType());
2087 llvm::GlobalValue::LinkageTypes linkage =
2088 convertLinkageToLLVM(op.getLinkage());
2089 llvm::Constant *resolver;
2091 resolver = cast<llvm::Constant>(resolverFn);
2094 op.getResolverAttr());
2095 resolver = cast<llvm::Constant>(
lookupAlias(aliasOp));
2099 llvm::GlobalIFunc::create(type, op.getAddressSpace(), linkage,
2100 op.getSymName(), resolver, llvmModule.get());
2102 ifunc->setUnnamedAddr(convertUnnamedAddrToLLVM(op.getUnnamedAddr()));
2103 ifunc->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
2105 ifuncMapping.try_emplace(op, ifunc);
2111LogicalResult ModuleTranslation::convertComdats() {
2112 for (
auto comdatOp :
getModuleBody(mlirModule).getOps<ComdatOp>()) {
2113 for (
auto selectorOp : comdatOp.getOps<ComdatSelectorOp>()) {
2115 if (module->getComdatSymbolTable().contains(selectorOp.getSymName()))
2117 <<
"comdat selection symbols must be unique even in different "
2119 llvm::Comdat *comdat =
module->getOrInsertComdat(selectorOp.getSymName());
2120 comdat->setSelectionKind(convertComdatToLLVM(selectorOp.getComdat()));
2121 comdatMapping.try_emplace(selectorOp, comdat);
2127LogicalResult ModuleTranslation::convertUnresolvedBlockAddress() {
2128 for (
auto &[blockAddressOp, llvmCst] : unresolvedBlockAddressMapping) {
2129 BlockAddressAttr blockAddressAttr = blockAddressOp.getBlockAddr();
2131 assert(llvmBlock &&
"expected LLVM blocks to be already translated");
2134 auto *llvmBlockAddr = llvm::BlockAddress::get(
2135 lookupFunction(blockAddressAttr.getFunction().getValue()), llvmBlock);
2136 llvmCst->replaceAllUsesWith(llvmBlockAddr);
2137 assert(llvmCst->use_empty() &&
"expected all uses to be replaced");
2138 cast<llvm::GlobalVariable>(llvmCst)->eraseFromParent();
2140 unresolvedBlockAddressMapping.clear();
2145 llvm::Instruction *inst) {
2146 if (llvm::MDNode *node = loopAnnotationTranslation->getAccessGroups(op))
2147 inst->setMetadata(llvm::LLVMContext::MD_access_group, node);
2152 auto [scopeIt, scopeInserted] =
2153 aliasScopeMetadataMapping.try_emplace(aliasScopeAttr,
nullptr);
2155 return scopeIt->second;
2156 llvm::LLVMContext &ctx = llvmModule->getContext();
2157 auto dummy = llvm::MDNode::getTemporary(ctx, {});
2159 auto [domainIt, insertedDomain] = aliasDomainMetadataMapping.try_emplace(
2160 aliasScopeAttr.getDomain(),
nullptr);
2161 if (insertedDomain) {
2164 operands.push_back(dummy.get());
2165 if (StringAttr description = aliasScopeAttr.getDomain().getDescription())
2166 operands.push_back(llvm::MDString::get(ctx, description));
2167 domainIt->second = llvm::MDNode::get(ctx, operands);
2170 if (
auto stringAttr =
2171 dyn_cast<StringAttr>(aliasScopeAttr.getDomain().getId()))
2172 replacement = llvm::MDString::get(ctx, stringAttr.getValue());
2175 domainIt->second->replaceOperandWith(0,
replacement);
2178 assert(domainIt->second &&
"Scope's domain should already be valid");
2181 operands.push_back(dummy.get());
2182 operands.push_back(domainIt->second);
2183 if (StringAttr description = aliasScopeAttr.getDescription())
2184 operands.push_back(llvm::MDString::get(ctx, description));
2185 scopeIt->second = llvm::MDNode::get(ctx, operands);
2188 if (
auto stringAttr = dyn_cast<StringAttr>(aliasScopeAttr.getId()))
2189 replacement = llvm::MDString::get(ctx, stringAttr.getValue());
2192 scopeIt->second->replaceOperandWith(0,
replacement);
2193 return scopeIt->second;
2199 nodes.reserve(aliasScopeAttrs.size());
2200 for (AliasScopeAttr aliasScopeAttr : aliasScopeAttrs)
2206 llvm::Instruction *inst) {
2207 auto populateScopeMetadata = [&](ArrayAttr aliasScopeAttrs,
unsigned kind) {
2208 if (!aliasScopeAttrs || aliasScopeAttrs.empty())
2211 llvm::to_vector(aliasScopeAttrs.getAsRange<AliasScopeAttr>()));
2212 inst->setMetadata(kind, node);
2215 populateScopeMetadata(op.getAliasScopesOrNull(),
2216 llvm::LLVMContext::MD_alias_scope);
2217 populateScopeMetadata(op.getNoAliasScopesOrNull(),
2218 llvm::LLVMContext::MD_noalias);
2221llvm::MDNode *ModuleTranslation::getTBAANode(TBAATagAttr tbaaAttr)
const {
2222 return tbaaMetadataMapping.lookup(tbaaAttr);
2226 llvm::Instruction *inst) {
2227 ArrayAttr tagRefs = op.getTBAATagsOrNull();
2228 if (!tagRefs || tagRefs.empty())
2235 if (tagRefs.size() > 1) {
2236 op.emitWarning() <<
"TBAA access tags were not translated, because LLVM "
2237 "IR only supports a single tag per instruction";
2241 llvm::MDNode *node = getTBAANode(cast<TBAATagAttr>(tagRefs[0]));
2242 inst->setMetadata(llvm::LLVMContext::MD_tbaa, node);
2246 DereferenceableOpInterface op, llvm::Instruction *inst) {
2247 DereferenceableAttr derefAttr = op.getDereferenceableOrNull();
2251 llvm::MDNode *derefSizeNode = llvm::MDNode::get(
2253 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2254 llvm::IntegerType::get(
getLLVMContext(), 64), derefAttr.getBytes())));
2255 unsigned kindId = derefAttr.getMayBeNull()
2256 ? llvm::LLVMContext::MD_dereferenceable_or_null
2257 : llvm::LLVMContext::MD_dereferenceable;
2258 inst->setMetadata(kindId, derefSizeNode);
2263 llvm::transform(op.getWeights(), std::back_inserter(weights),
2264 [](int32_t value) { return static_cast<uint32_t>(value); });
2265 if (weights.empty())
2269 assert(inst &&
"expected the operation to have a mapping to an instruction");
2271 llvm::LLVMContext::MD_prof,
2275LogicalResult ModuleTranslation::createTBAAMetadata() {
2276 llvm::LLVMContext &ctx = llvmModule->getContext();
2277 llvm::IntegerType *offsetTy = llvm::IntegerType::get(ctx, 64);
2288 walker.
addWalk([&](TBAARootAttr root) {
2290 if (StringAttr
id = root.getId()) {
2291 node = llvm::MDNode::get(ctx, llvm::MDString::get(ctx,
id));
2294 auto selfRef = llvm::MDNode::getTemporary(ctx, {});
2295 node = llvm::MDNode::get(ctx, {selfRef.get()});
2296 node->replaceOperandWith(0, node);
2298 tbaaMetadataMapping.insert({root, node});
2301 walker.
addWalk([&](TBAATypeDescriptorAttr descriptor) {
2302 SmallVector<llvm::Metadata *> operands;
2303 operands.push_back(llvm::MDString::get(ctx, descriptor.getId()));
2304 for (TBAAMemberAttr member : descriptor.getMembers()) {
2305 operands.push_back(tbaaMetadataMapping.lookup(member.getTypeDesc()));
2306 operands.push_back(llvm::ConstantAsMetadata::get(
2307 llvm::ConstantInt::get(offsetTy, member.getOffset())));
2310 tbaaMetadataMapping.insert({descriptor, llvm::MDNode::get(ctx, operands)});
2313 walker.
addWalk([&](TBAATagAttr tag) {
2314 SmallVector<llvm::Metadata *> operands;
2316 operands.push_back(tbaaMetadataMapping.lookup(tag.getBaseType()));
2317 operands.push_back(tbaaMetadataMapping.lookup(tag.getAccessType()));
2319 operands.push_back(llvm::ConstantAsMetadata::get(
2320 llvm::ConstantInt::get(offsetTy, tag.getOffset())));
2321 if (tag.getConstant())
2323 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(offsetTy, 1)));
2325 tbaaMetadataMapping.insert({tag, llvm::MDNode::get(ctx, operands)});
2328 mlirModule->walk([&](AliasAnalysisOpInterface analysisOpInterface) {
2329 if (
auto attr = analysisOpInterface.getTBAATagsOrNull())
2336LogicalResult ModuleTranslation::createIdentMetadata() {
2337 if (
auto attr = mlirModule->getAttrOfType<StringAttr>(
2338 LLVMDialect::getIdentAttrName())) {
2339 StringRef ident = attr;
2340 llvm::LLVMContext &ctx = llvmModule->
getContext();
2341 llvm::NamedMDNode *namedMd =
2342 llvmModule->getOrInsertNamedMetadata(LLVMDialect::getIdentAttrName());
2343 llvm::MDNode *md = llvm::MDNode::get(ctx, llvm::MDString::get(ctx, ident));
2344 namedMd->addOperand(md);
2350LogicalResult ModuleTranslation::createCommandlineMetadata() {
2351 if (
auto attr = mlirModule->getAttrOfType<StringAttr>(
2352 LLVMDialect::getCommandlineAttrName())) {
2353 StringRef cmdLine = attr;
2354 llvm::LLVMContext &ctx = llvmModule->
getContext();
2355 llvm::NamedMDNode *nmd = llvmModule->getOrInsertNamedMetadata(
2356 LLVMDialect::getCommandlineAttrName());
2358 llvm::MDNode::get(ctx, llvm::MDString::get(ctx, cmdLine));
2359 nmd->addOperand(md);
2365LogicalResult ModuleTranslation::createDependentLibrariesMetadata() {
2366 if (
auto dependentLibrariesAttr = mlirModule->getDiscardableAttr(
2367 LLVM::LLVMDialect::getDependentLibrariesAttrName())) {
2369 llvmModule->getOrInsertNamedMetadata(
"llvm.dependent-libraries");
2370 llvm::LLVMContext &ctx = llvmModule->getContext();
2372 cast<ArrayAttr>(dependentLibrariesAttr).getAsRange<StringAttr>()) {
2374 llvm::MDNode::get(ctx, llvm::MDString::get(ctx, libAttr.getValue()));
2375 nmd->addOperand(md);
2382 llvm::Instruction *inst) {
2383 LoopAnnotationAttr attr =
2385 .Case<LLVM::BrOp, LLVM::CondBrOp>(
2386 [](
auto branchOp) {
return branchOp.getLoopAnnotationAttr(); });
2389 llvm::MDNode *loopMD =
2390 loopAnnotationTranslation->translateLoopAnnotation(attr, op);
2391 inst->setMetadata(llvm::LLVMContext::MD_loop, loopMD);
2395 auto iface = cast<DisjointFlagInterface>(op);
2397 if (
auto *disjointInst = dyn_cast<llvm::PossiblyDisjointInst>(value))
2398 disjointInst->setIsDisjoint(iface.getIsDisjoint());
2402 return typeTranslator.translateType(type);
2408 remapped.reserve(values.size());
2409 for (
Value v : values)
2416 ompBuilder = std::make_unique<llvm::OpenMPIRBuilder>(*llvmModule);
2421 llvm::OpenMPIRBuilderConfig config(
2428 unsigned int defaultAS =
2429 llvmModule->getDataLayout().getProgramAddressSpace();
2430 config.setDefaultTargetAS(defaultAS);
2431 config.setRuntimeCC(llvmModule->getTargetTriple().isSPIRV()
2432 ? llvm::CallingConv::SPIR_FUNC
2433 : llvm::CallingConv::C);
2434 ompBuilder->setConfig(std::move(config));
2435 ompBuilder->initialize();
2437 return ompBuilder.get();
2443 return *llvm::vfs::getRealFileSystem();
2447 llvm::DILocalScope *scope) {
2448 return debugTranslation->translateLoc(loc, scope);
2453 return debugTranslation->translateExpression(attr);
2456llvm::DIGlobalVariableExpression *
2458 LLVM::DIGlobalVariableExpressionAttr attr) {
2459 return debugTranslation->translateGlobalVariableExpression(attr);
2463 return debugTranslation->translate(attr);
2468 return convertRoundingModeToLLVM(rounding);
2472 LLVM::FPExceptionBehavior exceptionBehavior) {
2473 return convertFPExceptionBehaviorToLLVM(exceptionBehavior);
2478 return llvmModule->getOrInsertNamedMetadata(name);
2481static std::unique_ptr<llvm::Module>
2485 auto llvmModule = std::make_unique<llvm::Module>(name, llvmContext);
2486 if (
auto dataLayoutAttr =
2488 llvmModule->setDataLayout(cast<StringAttr>(dataLayoutAttr).getValue());
2490 FailureOr<llvm::DataLayout> llvmDataLayout(llvm::DataLayout(
""));
2491 if (
auto iface = dyn_cast<DataLayoutOpInterface>(m)) {
2492 if (DataLayoutSpecInterface spec = iface.getDataLayoutSpec()) {
2496 }
else if (
auto mod = dyn_cast<ModuleOp>(m)) {
2497 if (DataLayoutSpecInterface spec = mod.getDataLayoutSpec()) {
2502 if (failed(llvmDataLayout))
2504 llvmModule->setDataLayout(*llvmDataLayout);
2506 if (
auto targetTripleAttr =
2508 llvmModule->setTargetTriple(
2509 llvm::Triple(cast<StringAttr>(targetTripleAttr).getValue()));
2512 LLVM::LLVMDialect::getModuleLevelAsmAttrName())) {
2513 auto asmArrayAttr = dyn_cast<ArrayAttr>(asmAttr);
2514 if (!asmArrayAttr) {
2515 m->
emitError(
"expected an array attribute for a module level asm");
2520 auto asmStrAttr = dyn_cast<StringAttr>(elt);
2523 "expected a string attribute for each entry of a module level asm");
2526 llvmModule->appendModuleInlineAsm(asmStrAttr.getValue());
2533std::unique_ptr<llvm::Module>
2535 StringRef name,
bool disableVerification,
2536 llvm::vfs::FileSystem *fs) {
2538 module->emitOpError("can not be translated to an LLVMIR module");
2542 std::unique_ptr<llvm::Module> llvmModule =
2551 llvm::IRBuilder<llvm::TargetFolder> llvmBuilder(
2553 llvm::TargetFolder(translator.getLLVMModule()->getDataLayout()));
2559 if (
failed(translator.convertOperation(*module, llvmBuilder)))
2562 if (
failed(translator.convertComdats()))
2564 if (
failed(translator.convertFunctionSignatures()))
2566 if (
failed(translator.convertGlobalsAndAliases()))
2568 if (
failed(translator.convertIFuncs()))
2570 if (
failed(translator.createTBAAMetadata()))
2572 if (
failed(translator.createIdentMetadata()))
2574 if (
failed(translator.createCommandlineMetadata()))
2576 if (
failed(translator.createDependentLibrariesMetadata()))
2580 for (Operation &o :
getModuleBody(module).getOperations()) {
2581 if (!isa<LLVM::LLVMFuncOp, LLVM::AliasOp, LLVM::GlobalOp,
2582 LLVM::GlobalCtorsOp, LLVM::GlobalDtorsOp, LLVM::ComdatOp,
2583 LLVM::IFuncOp>(&o) &&
2584 !o.hasTrait<OpTrait::IsTerminator>() &&
2585 failed(translator.convertOperation(o, llvmBuilder))) {
2593 if (
failed(translator.convertFunctions()))
2598 if (
failed(translator.convertUnresolvedBlockAddress()))
2603 translator.debugTranslation->addModuleFlagsIfNotPresent();
2606 if (
auto *ompBuilder = translator.getOpenMPBuilder())
2607 ompBuilder->finalize();
2609 if (!disableVerification &&
2610 llvm::verifyModule(*translator.llvmModule, &llvm::errs()))
2613 return std::move(translator.llvmModule);