Lines Matching full:mlir
25 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
26 #include "mlir/Dialect/OpenACC/OpenACC.h"
27 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
42 mlir::func::FuncOp
43 fir::FirOpBuilder::createFunction(mlir::Location loc, mlir::ModuleOp module,
44 llvm::StringRef name, mlir::FunctionType ty,
45 mlir::SymbolTable *symbolTable) {
49 mlir::func::FuncOp
50 fir::FirOpBuilder::getNamedFunction(mlir::ModuleOp modOp,
51 const mlir::SymbolTable *symbolTable,
54 if (auto func = symbolTable->lookup<mlir::func::FuncOp>(name)) {
56 assert(func == modOp.lookupSymbol<mlir::func::FuncOp>(name) &&
61 return modOp.lookupSymbol<mlir::func::FuncOp>(name);
64 mlir::func::FuncOp
65 fir::FirOpBuilder::getNamedFunction(mlir::ModuleOp modOp,
66 const mlir::SymbolTable *symbolTable,
67 mlir::SymbolRefAttr symbol) {
69 if (auto func = symbolTable->lookup<mlir::func::FuncOp>(
72 assert(func == modOp.lookupSymbol<mlir::func::FuncOp>(symbol) &&
77 return modOp.lookupSymbol<mlir::func::FuncOp>(symbol);
81 fir::FirOpBuilder::getNamedGlobal(mlir::ModuleOp modOp,
82 const mlir::SymbolTable *symbolTable,
95 mlir::Type fir::FirOpBuilder::getRefType(mlir::Type eleTy) {
96 assert(!mlir::isa<fir::ReferenceType>(eleTy) && "cannot be a reference type");
100 mlir::Type fir::FirOpBuilder::getVarLenSeqTy(mlir::Type eleTy, unsigned rank) {
105 mlir::Type fir::FirOpBuilder::getRealType(int kind) {
108 return mlir::Float16Type::get(getContext());
110 return mlir::BFloat16Type::get(getContext());
112 return mlir::Float32Type::get(getContext());
114 return mlir::Float64Type::get(getContext());
116 return mlir::Float80Type::get(getContext());
118 return mlir::Float128Type::get(getContext());
120 fir::emitFatalError(mlir::UnknownLoc::get(getContext()),
125 mlir::Value fir::FirOpBuilder::createNullConstant(mlir::Location loc,
126 mlir::Type ptrType) {
131 mlir::Value fir::FirOpBuilder::createIntegerConstant(mlir::Location loc,
132 mlir::Type ty,
134 assert((cst >= 0 || mlir::isa<mlir::IndexType>(ty) ||
135 mlir::cast<mlir::IntegerType>(ty).getWidth() <= 64) &&
137 return create<mlir::arith::ConstantOp>(loc, ty, getIntegerAttr(ty, cst));
140 mlir::Value fir::FirOpBuilder::createAllOnesInteger(mlir::Location loc,
141 mlir::Type ty) {
142 if (mlir::isa<mlir::IndexType>(ty))
145 llvm::APInt::getAllOnes(mlir::cast<mlir::IntegerType>(ty).getWidth());
146 return create<mlir::arith::ConstantOp>(loc, ty, getIntegerAttr(ty, allOnes));
149 mlir::Value
150 fir::FirOpBuilder::createRealConstant(mlir::Location loc, mlir::Type fltTy,
165 llvm_unreachable("unhandled MLIR floating-point type");
170 mlir::Value fir::FirOpBuilder::createRealConstant(mlir::Location loc,
171 mlir::Type fltTy,
173 if (mlir::isa<mlir::FloatType>(fltTy)) {
175 return create<mlir::arith::ConstantOp>(loc, fltTy, attr);
180 llvm::SmallVector<mlir::Value>
181 fir::factory::elideExtentsAlreadyInType(mlir::Type type,
182 mlir::ValueRange shape) {
183 auto arrTy = mlir::dyn_cast<fir::SequenceType>(type);
188 llvm::SmallVector<mlir::Value> dynamicShape;
196 llvm::SmallVector<mlir::Value>
197 fir::factory::elideLengthsAlreadyInType(mlir::Type type,
198 mlir::ValueRange lenParams) {
201 if (auto arrTy = mlir::dyn_cast<fir::SequenceType>(type))
210 mlir::Value fir::FirOpBuilder::allocateLocal(
211 mlir::Location loc, mlir::Type ty, llvm::StringRef uniqName,
212 llvm::StringRef name, bool pinned, llvm::ArrayRef<mlir::Value> shape,
213 llvm::ArrayRef<mlir::Value> lenParams, bool asTarget) {
215 llvm::SmallVector<mlir::Value> indices;
216 llvm::SmallVector<mlir::Value> elidedShape =
218 llvm::SmallVector<mlir::Value> elidedLenParams =
221 for (mlir::Value sh : elidedShape)
224 llvm::SmallVector<mlir::NamedAttribute> attrs;
227 mlir::StringAttr::get(getContext(), fir::getTargetAttrName()),
241 mlir::Value fir::FirOpBuilder::allocateLocal(
242 mlir::Location loc, mlir::Type ty, llvm::StringRef uniqName,
243 llvm::StringRef name, llvm::ArrayRef<mlir::Value> shape,
244 llvm::ArrayRef<mlir::Value> lenParams, bool asTarget) {
250 mlir::Block *fir::FirOpBuilder::getAllocaBlock() {
252 getRegion().getParentOfType<mlir::acc::ComputeRegionOpInterface>()) {
258 .getParentOfType<mlir::omp::OutlineableOpenMPOpInterface>()) {
263 getRegion().getParentOfType<mlir::accomp::RecipeInterface>()) {
270 static mlir::ArrayAttr makeI64ArrayAttr(llvm::ArrayRef<int64_t> values,
271 mlir::MLIRContext *context) {
272 llvm::SmallVector<mlir::Attribute, 4> attrs;
275 attrs.push_back(mlir::IntegerAttr::get(mlir::IntegerType::get(context, 64),
276 mlir::APInt(64, v)));
277 return mlir::ArrayAttr::get(context, attrs);
280 mlir::ArrayAttr fir::FirOpBuilder::create2DI64ArrayAttr(
282 llvm::SmallVector<mlir::Attribute> arrayAttr;
284 mlir::MLIRContext *context = getContext();
287 return mlir::ArrayAttr::get(context, arrayAttr);
290 mlir::Value fir::FirOpBuilder::createTemporaryAlloc(
291 mlir::Location loc, mlir::Type type, llvm::StringRef name,
292 mlir::ValueRange lenParams, mlir::ValueRange shape,
293 llvm::ArrayRef<mlir::NamedAttribute> attrs,
295 assert(!mlir::isa<fir::ReferenceType>(type) && "cannot be a reference");
299 getRegion().getParentOfType<mlir::omp::OutlineableOpenMPOpInterface>();
312 mlir::Value fir::FirOpBuilder::createTemporary(
313 mlir::Location loc, mlir::Type type, llvm::StringRef name,
314 mlir::ValueRange shape, mlir::ValueRange lenParams,
315 llvm::ArrayRef<mlir::NamedAttribute> attrs,
317 llvm::SmallVector<mlir::Value> dynamicShape =
319 llvm::SmallVector<mlir::Value> dynamicLength =
328 mlir::Value ae = createTemporaryAlloc(loc, type, name, dynamicLength,
336 mlir::Value fir::FirOpBuilder::createHeapTemporary(
337 mlir::Location loc, mlir::Type type, llvm::StringRef name,
338 mlir::ValueRange shape, mlir::ValueRange lenParams,
339 llvm::ArrayRef<mlir::NamedAttribute> attrs) {
340 llvm::SmallVector<mlir::Value> dynamicShape =
342 llvm::SmallVector<mlir::Value> dynamicLength =
345 assert(!mlir::isa<fir::ReferenceType>(type) && "cannot be a reference");
350 mlir::Value fir::FirOpBuilder::genStackSave(mlir::Location loc) {
351 mlir::Type voidPtr = mlir::LLVM::LLVMPointerType::get(
353 return create<mlir::LLVM::StackSaveOp>(loc, voidPtr);
356 void fir::FirOpBuilder::genStackRestore(mlir::Location loc,
357 mlir::Value stackPointer) {
358 create<mlir::LLVM::StackRestoreOp>(loc, stackPointer);
364 mlir::Location loc, mlir::Type type, llvm::StringRef name,
365 mlir::StringAttr linkage, mlir::Attribute value, bool isConst,
372 llvm::SmallVector<mlir::NamedAttribute> attrs;
374 auto globalOpName = mlir::OperationName(fir::GlobalOp::getOperationName(),
376 attrs.push_back(mlir::NamedAttribute(
388 mlir::Location loc, mlir::Type type, llvm::StringRef name, bool isConst,
390 mlir::StringAttr linkage, cuf::DataAttributeAttr dataAttr) {
397 mlir::Attribute{}, linkage);
399 region.push_back(new mlir::Block);
409 std::pair<fir::TypeInfoOp, mlir::OpBuilder::InsertPoint>
410 fir::FirOpBuilder::createTypeInfoOp(mlir::Location loc,
413 mlir::ModuleOp module = getModule();
425 mlir::Value fir::FirOpBuilder::convertWithSemantics(
426 mlir::Location loc, mlir::Type toTy, mlir::Value val,
448 if (mlir::isa<fir::BoxCharType>(fromTy)) {
451 std::pair<mlir::Value, mlir::Value> unboxchar =
455 if (auto boxType = mlir::dyn_cast<fir::BoxCharType>(toTy)) {
461 mlir::Value charBase = createConvert(loc, refType, val);
464 mlir::Value unknownLen = createIntegerConstant(loc, getIndexType(), 0);
477 if (fir::isa_ref_type(fromTy) && mlir::isa<fir::BoxProcType>(toTy)) {
480 mlir::Type procTy = mlir::cast<fir::BoxProcType>(toTy).getEleTy();
481 mlir::Value proc = createConvert(loc, procTy, val);
490 (fir::isPolymorphicType(fromTy) && mlir::isa<fir::BoxType>(toTy))) &&
492 return create<fir::ReboxOp>(loc, toTy, val, mlir::Value{},
493 /*slice=*/mlir::Value{});
498 mlir::Value fir::factory::createConvert(mlir::OpBuilder &builder,
499 mlir::Location loc, mlir::Type toTy,
500 mlir::Value val) {
503 mlir::cast<fir::RecordType>(val.getType()).getTypeList() ==
504 mlir::cast<fir::RecordType>(toTy).getTypeList()) &&
511 mlir::Value fir::FirOpBuilder::createConvert(mlir::Location loc,
512 mlir::Type toTy, mlir::Value val) {
516 void fir::FirOpBuilder::createStoreWithConvert(mlir::Location loc,
517 mlir::Value val,
518 mlir::Value addr) {
519 mlir::Value cast =
524 mlir::Value fir::FirOpBuilder::loadIfRef(mlir::Location loc, mlir::Value val) {
530 fir::StringLitOp fir::FirOpBuilder::createStringLitOp(mlir::Location loc,
533 auto strAttr = mlir::StringAttr::get(getContext(), data);
534 auto valTag = mlir::StringAttr::get(getContext(), fir::StringLitOp::value());
535 mlir::NamedAttribute dataAttr(valTag, strAttr);
536 auto sizeTag = mlir::StringAttr::get(getContext(), fir::StringLitOp::size());
537 mlir::NamedAttribute sizeAttr(sizeTag, getI64IntegerAttr(data.size()));
538 llvm::SmallVector<mlir::NamedAttribute> attrs{dataAttr, sizeAttr};
539 return create<fir::StringLitOp>(loc, llvm::ArrayRef<mlir::Type>{type},
543 mlir::Value fir::FirOpBuilder::genShape(mlir::Location loc,
544 llvm::ArrayRef<mlir::Value> exts) {
548 mlir::Value fir::FirOpBuilder::genShape(mlir::Location loc,
549 llvm::ArrayRef<mlir::Value> shift,
550 llvm::ArrayRef<mlir::Value> exts) {
552 llvm::SmallVector<mlir::Value> shapeArgs;
562 mlir::Value fir::FirOpBuilder::genShape(mlir::Location loc,
569 mlir::Value fir::FirOpBuilder::genShift(mlir::Location loc,
570 llvm::ArrayRef<mlir::Value> shift) {
575 mlir::Value fir::FirOpBuilder::createShape(mlir::Location loc,
580 [&](const fir::BoxValue &box) -> mlir::Value {
588 [&](const fir::MutableBoxValue &) -> mlir::Value {
593 [&](auto) -> mlir::Value { fir::emitFatalError(loc, "not an array"); });
596 mlir::Value fir::FirOpBuilder::createSlice(mlir::Location loc,
598 mlir::ValueRange triples,
599 mlir::ValueRange path) {
602 auto fullShape = [&](const llvm::ArrayRef<mlir::Value> lbounds,
603 llvm::ArrayRef<mlir::Value> extents) -> mlir::Value {
604 llvm::SmallVector<mlir::Value> trips;
618 auto shift = create<mlir::arith::SubIOp>(loc, lb, one);
619 auto ub = create<mlir::arith::AddIOp>(loc, ext, shift);
637 [&](const fir::MutableBoxValue &) -> mlir::Value {
642 [&](auto) -> mlir::Value { fir::emitFatalError(loc, "not an array"); });
647 mlir::Value fir::FirOpBuilder::createBox(mlir::Location loc,
651 mlir::Value itemAddr = fir::getBase(exv);
652 if (mlir::isa<fir::BaseBoxType>(itemAddr.getType()))
656 mlir::emitError(loc, "internal: expected a memory reference type ")
660 mlir::Type boxTy;
661 mlir::Value tdesc;
663 if (mlir::isa<fir::BaseBoxType>(elementType)) {
677 [&](const fir::ArrayBoxValue &box) -> mlir::Value {
678 mlir::Value empty;
679 mlir::ValueRange emptyRange;
680 mlir::Value s = createShape(loc, exv);
685 [&](const fir::CharArrayBoxValue &box) -> mlir::Value {
686 mlir::Value s = createShape(loc, exv);
690 mlir::Value emptySlice;
691 llvm::SmallVector<mlir::Value> lenParams{box.getLen()};
695 [&](const fir::CharBoxValue &box) -> mlir::Value {
698 mlir::Value emptyShape, emptySlice;
699 llvm::SmallVector<mlir::Value> lenParams{box.getLen()};
703 [&](const fir::MutableBoxValue &x) -> mlir::Value {
707 [&](const fir::PolymorphicValue &p) -> mlir::Value {
708 mlir::Value empty;
709 mlir::ValueRange emptyRange;
714 [&](const auto &) -> mlir::Value {
715 mlir::Value empty;
716 mlir::ValueRange emptyRange;
722 mlir::Value fir::FirOpBuilder::createBox(mlir::Location loc, mlir::Type boxType,
723 mlir::Value addr, mlir::Value shape,
724 mlir::Value slice,
725 llvm::ArrayRef<mlir::Value> lengths,
726 mlir::Value tdesc) {
727 mlir::Type valueOrSequenceType = fir::unwrapPassByRefType(boxType);
736 static mlir::Value
737 genNullPointerComparison(fir::FirOpBuilder &builder, mlir::Location loc,
738 mlir::Value addr,
739 mlir::arith::CmpIPredicate condition) {
743 return builder.create<mlir::arith::CmpIOp>(loc, condition, ptrToInt, c0);
746 mlir::Value fir::FirOpBuilder::genIsNotNullAddr(mlir::Location loc,
747 mlir::Value addr) {
749 mlir::arith::CmpIPredicate::ne);
752 mlir::Value fir::FirOpBuilder::genIsNullAddr(mlir::Location loc,
753 mlir::Value addr) {
755 mlir::arith::CmpIPredicate::eq);
758 mlir::Value fir::FirOpBuilder::genExtentFromTriplet(mlir::Location loc,
759 mlir::Value lb,
760 mlir::Value ub,
761 mlir::Value step,
762 mlir::Type type) {
767 auto diff = create<mlir::arith::SubIOp>(loc, ub, lb);
768 auto add = create<mlir::arith::AddIOp>(loc, diff, step);
769 auto div = create<mlir::arith::DivSIOp>(loc, add, step);
770 auto cmp = create<mlir::arith::CmpIOp>(loc, mlir::arith::CmpIPredicate::sgt,
772 return create<mlir::arith::SelectOp>(loc, cmp, div, zero);
775 mlir::Value fir::FirOpBuilder::genAbsentOp(mlir::Location loc,
776 mlir::Type argTy) {
781 create<fir::AbsentOp>(loc, mlir::cast<mlir::TupleType>(argTy).getType(0));
782 mlir::Value charLen = create<fir::UndefOp>(loc, getCharacterLengthType());
787 void fir::FirOpBuilder::setCommonAttributes(mlir::Operation *op) const {
788 auto fmi = mlir::dyn_cast<mlir::arith::ArithFastMathInterface>(*op);
793 if (fastMathFlags != mlir::arith::FastMathFlags::none)
794 op->setAttr(arithFMFAttrName, mlir::arith::FastMathFlagsAttr::get(
798 mlir::dyn_cast<mlir::arith::ArithIntegerOverflowFlagsInterface>(*op);
801 if (integerOverflowFlags != mlir::arith::IntegerOverflowFlags::none)
803 mlir::arith::IntegerOverflowFlagsAttr::get(
810 mlir::arith::FastMathFlags arithFMF{};
812 arithFMF = arithFMF | mlir::arith::FastMathFlags::contract;
815 arithFMF = arithFMF | mlir::arith::FastMathFlags::ninf;
818 arithFMF = arithFMF | mlir::arith::FastMathFlags::nnan;
821 arithFMF = arithFMF | mlir::arith::FastMathFlags::afn;
824 arithFMF = arithFMF | mlir::arith::FastMathFlags::nsz;
827 arithFMF = arithFMF | mlir::arith::FastMathFlags::reassoc;
830 arithFMF = arithFMF | mlir::arith::FastMathFlags::arcp;
835 // Construction of an mlir::DataLayout is expensive so only do it on demand and
837 mlir::DataLayout &fir::FirOpBuilder::getDataLayout() {
840 dataLayout = std::make_unique<mlir::DataLayout>(getModule());
848 mlir::Value fir::factory::readCharLen(fir::FirOpBuilder &builder,
849 mlir::Location loc,
852 [&](const fir::CharBoxValue &x) -> mlir::Value { return x.getLen(); },
853 [&](const fir::CharArrayBoxValue &x) -> mlir::Value {
856 [&](const fir::BoxValue &x) -> mlir::Value {
863 [&](const fir::MutableBoxValue &x) -> mlir::Value {
867 [&](const auto &) -> mlir::Value {
873 mlir::Value fir::factory::readExtent(fir::FirOpBuilder &builder,
874 mlir::Location loc,
879 [&](const fir::ArrayBoxValue &x) -> mlir::Value {
882 [&](const fir::CharArrayBoxValue &x) -> mlir::Value {
885 [&](const fir::BoxValue &x) -> mlir::Value {
895 [&](const fir::MutableBoxValue &x) -> mlir::Value {
900 [&](const auto &) -> mlir::Value {
905 mlir::Value fir::factory::readLowerBound(fir::FirOpBuilder &builder,
906 mlir::Location loc,
909 mlir::Value defaultValue) {
912 [&](const fir::ArrayBoxValue &x) -> mlir::Value {
913 return x.getLBounds().empty() ? mlir::Value{} : x.getLBounds()[dim];
915 [&](const fir::CharArrayBoxValue &x) -> mlir::Value {
916 return x.getLBounds().empty() ? mlir::Value{} : x.getLBounds()[dim];
918 [&](const fir::BoxValue &x) -> mlir::Value {
919 return x.getLBounds().empty() ? mlir::Value{} : x.getLBounds()[dim];
921 [&](const fir::MutableBoxValue &x) -> mlir::Value {
926 [&](const auto &) -> mlir::Value {
934 llvm::SmallVector<mlir::Value>
935 fir::factory::readExtents(fir::FirOpBuilder &builder, mlir::Location loc,
937 llvm::SmallVector<mlir::Value> result;
954 llvm::SmallVector<mlir::Value>
955 fir::factory::getExtents(mlir::Location loc, fir::FirOpBuilder &builder,
958 [&](const fir::ArrayBoxValue &x) -> llvm::SmallVector<mlir::Value> {
961 [&](const fir::CharArrayBoxValue &x) -> llvm::SmallVector<mlir::Value> {
964 [&](const fir::BoxValue &x) -> llvm::SmallVector<mlir::Value> {
967 [&](const fir::MutableBoxValue &x) -> llvm::SmallVector<mlir::Value> {
971 [&](const auto &) -> llvm::SmallVector<mlir::Value> { return {}; });
975 mlir::Location loc,
991 mlir::Value sourceBox;
1002 llvm::SmallVector<mlir::Value>
1004 mlir::Location loc,
1007 [&](const fir::ArrayBoxValue &array) -> llvm::SmallVector<mlir::Value> {
1011 -> llvm::SmallVector<mlir::Value> {
1014 [&](const fir::BoxValue &box) -> llvm::SmallVector<mlir::Value> {
1017 [&](const fir::MutableBoxValue &box) -> llvm::SmallVector<mlir::Value> {
1021 [&](const auto &) -> llvm::SmallVector<mlir::Value> { return {}; });
1024 llvm::SmallVector<mlir::Value>
1028 -> llvm::SmallVector<mlir::Value> { return {character.getLen()}; },
1030 -> llvm::SmallVector<mlir::Value> { return {character.getLen()}; },
1031 [&](const fir::MutableBoxValue &box) -> llvm::SmallVector<mlir::Value> {
1035 [&](const fir::BoxValue &box) -> llvm::SmallVector<mlir::Value> {
1039 [&](const auto &) -> llvm::SmallVector<mlir::Value> { return {}; });
1044 static llvm::SmallVector<mlir::Value> getFromBox(mlir::Location loc,
1046 mlir::Type valTy,
1047 mlir::Value boxVal) {
1048 if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(valTy)) {
1050 if (auto recTy = mlir::dyn_cast<fir::RecordType>(eleTy)) {
1055 } else if (auto charTy = mlir::dyn_cast<fir::CharacterType>(eleTy)) {
1061 mlir::Value charSz =
1063 mlir::Value len =
1064 builder.create<mlir::arith::DivSIOp>(loc, eleSz, charSz);
1076 llvm::SmallVector<mlir::Value>
1077 fir::factory::getTypeParams(mlir::Location loc, fir::FirOpBuilder &builder,
1079 auto handleBoxed = [&](const auto &box) -> llvm::SmallVector<mlir::Value> {
1098 llvm::SmallVector<mlir::Value>
1099 fir::factory::getTypeParams(mlir::Location loc, fir::FirOpBuilder &builder,
1101 mlir::Type memTy = load.getMemref().getType();
1102 if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(memTy))
1127 mlir::Value fir::factory::locationToFilename(fir::FirOpBuilder &builder,
1128 mlir::Location loc) {
1129 if (auto flc = mlir::dyn_cast<mlir::FileLineColLoc>(loc)) {
1137 mlir::Value fir::factory::locationToLineNo(fir::FirOpBuilder &builder,
1138 mlir::Location loc,
1139 mlir::Type type) {
1140 if (auto flc = mlir::dyn_cast<mlir::FileLineColLoc>(loc))
1146 mlir::Location loc,
1166 llvm::SmallVector<mlir::Value>
1167 fir::factory::createExtents(fir::FirOpBuilder &builder, mlir::Location loc,
1169 llvm::SmallVector<mlir::Value> extents;
1194 fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value component) {
1198 if (mlir::isa<fir::BaseBoxType>(fieldTy)) {
1199 llvm::SmallVector<mlir::Value> nonDeferredTypeParams;
1201 if (auto charTy = mlir::dyn_cast<fir::CharacterType>(eleTy)) {
1210 if (auto recTy = mlir::dyn_cast<fir::RecordType>(eleTy))
1218 llvm::SmallVector<mlir::Value> extents;
1219 if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(fieldTy)) {
1228 if (auto charTy = mlir::dyn_cast<fir::CharacterType>(fieldTy)) {
1238 if (auto recordTy = mlir::dyn_cast<fir::RecordType>(fieldTy))
1248 fir::FirOpBuilder &builder, mlir::Location loc,
1249 const fir::ExtendedValue &array, mlir::Value element) {
1278 fir::FirOpBuilder &builder, mlir::Location loc,
1279 const fir::ExtendedValue &array, mlir::Value element, mlir::Value slice) {
1282 auto sliceOp = mlir::dyn_cast_or_null<fir::SliceOp>(slice.getDefiningOp());
1293 mlir::Location loc,
1301 if (mlir::isa<fir::CharacterType>(type)) {
1308 } else if (mlir::isa<fir::RecordType>(type)) {
1316 mlir::Value lhsAddr = fir::getBase(lhs);
1324 mlir::Location loc,
1329 auto lhsType = mlir::dyn_cast<fir::RecordType>(lbaseType);
1332 auto rhsType = mlir::dyn_cast<fir::RecordType>(rbaseType);
1340 mlir::Value rField = builder.create<fir::FieldIndexOp>(
1343 mlir::Value fromCoor = builder.create<fir::CoordinateOp>(
1345 mlir::Value field = builder.create<fir::FieldIndexOp>(
1348 mlir::Value toCoor = builder.create<fir::CoordinateOp>(
1351 if (auto sequenceType = mlir::dyn_cast<fir::SequenceType>(lFieldTy)) {
1356 mlir::Type idxTy = builder.getIndexType();
1357 llvm::SmallVector<mlir::Value> indices;
1358 mlir::Value zero = builder.createIntegerConstant(loc, idxTy, 0);
1359 mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
1362 mlir::Value ub = builder.createIntegerConstant(loc, idxTy, extent - 1);
1378 mlir::isa<fir::BaseBoxType>(fieldEleTy)) {
1379 assert(mlir::isa<fir::PointerType>(
1380 mlir::cast<fir::BaseBoxType>(fieldEleTy).getEleTy()) &&
1413 if (mlir::isa<fir::RecordType>(fir::unwrapSequenceType(fieldType)) &&
1417 if (auto boxType = mlir::dyn_cast<fir::BaseBoxType>(fieldType))
1418 if (mlir::isa<fir::HeapType>(boxType.getEleTy()))
1436 mlir::Location loc,
1448 mlir::isa<fir::BaseBoxType>(fir::getBase(lhs).getType()) ||
1449 mlir::isa<fir::BaseBoxType>(fir::getBase(rhs).getType());
1450 auto recTy = mlir::dyn_cast<fir::RecordType>(baseTy);
1481 mlir::TupleType
1483 mlir::IntegerType i64Ty = builder.getIntegerType(64);
1488 return mlir::TupleType::get(builder.getContext(), {i64Ty, buffTy, shTy});
1491 mlir::Value fir::factory::genLenOfCharacter(
1492 fir::FirOpBuilder &builder, mlir::Location loc, fir::ArrayLoadOp arrLoad,
1493 llvm::ArrayRef<mlir::Value> path, llvm::ArrayRef<mlir::Value> substring) {
1494 llvm::SmallVector<mlir::Value> typeParams(arrLoad.getTypeparams());
1496 mlir::cast<fir::SequenceType>(arrLoad.getType()),
1500 mlir::Value fir::factory::genLenOfCharacter(
1501 fir::FirOpBuilder &builder, mlir::Location loc, fir::SequenceType seqTy,
1502 mlir::Value memref, llvm::ArrayRef<mlir::Value> typeParams,
1503 llvm::ArrayRef<mlir::Value> path, llvm::ArrayRef<mlir::Value> substring) {
1506 auto saturatedDiff = [&](mlir::Value lower, mlir::Value upper) {
1507 auto diff = builder.create<mlir::arith::SubIOp>(loc, upper, lower);
1509 auto size = builder.create<mlir::arith::AddIOp>(loc, diff, one);
1510 auto cmp = builder.create<mlir::arith::CmpIOp>(
1511 loc, mlir::arith::CmpIPredicate::sgt, size, zero);
1512 return builder.create<mlir::arith::SelectOp>(loc, cmp, size, zero);
1524 if (auto charTy = mlir::dyn_cast<fir::CharacterType>(eleTy)) {
1533 if (mlir::isa<fir::BoxCharType>(memref.getType()))
1535 if (mlir::isa<fir::BoxType>(memref.getType()))
1549 mlir::Value fir::factory::createZeroValue(fir::FirOpBuilder &builder,
1550 mlir::Location loc, mlir::Type type) {
1551 mlir::Type i1 = builder.getIntegerType(1);
1552 if (mlir::isa<fir::LogicalType>(type) || type == i1)
1560 mlir::Type partType = complexHelper.getComplexPartType(type);
1561 mlir::Value zeroPart = builder.createRealZeroConstant(loc, partType);
1569 fir::factory::getExtentFromTriplet(mlir::Value lb, mlir::Value ub,
1570 mlir::Value stride) {
1571 std::function<std::optional<std::int64_t>(mlir::Value)> getConstantValue =
1572 [&](mlir::Value value) -> std::optional<std::int64_t> {
1576 if (mlir::isa_and_nonnull<fir::ConvertOp>(definingOp)) {
1577 auto valOp = mlir::dyn_cast<fir::ConvertOp>(definingOp);
1596 mlir::Value fir::factory::genMaxWithZero(fir::FirOpBuilder &builder,
1597 mlir::Location loc,
1598 mlir::Value value) {
1599 mlir::Value zero = builder.createIntegerConstant(loc, value.getType(), 0);
1600 if (mlir::Operation *definingOp = value.getDefiningOp())
1601 if (auto cst = mlir::dyn_cast<mlir::arith::ConstantOp>(definingOp))
1602 if (auto intAttr = mlir::dyn_cast<mlir::IntegerAttr>(cst.getValue()))
1604 mlir::Value valueIsGreater = builder.create<mlir::arith::CmpIOp>(
1605 loc, mlir::arith::CmpIPredicate::sgt, value, zero);
1606 return builder.create<mlir::arith::SelectOp>(loc, valueIsGreater, value,
1610 static std::pair<mlir::Value, mlir::Type>
1611 genCPtrOrCFunptrFieldIndex(fir::FirOpBuilder &builder, mlir::Location loc,
1612 mlir::Type cptrTy) {
1613 auto recTy = mlir::cast<fir::RecordType>(cptrTy);
1616 mlir::Type addrFieldTy = recTy.getTypeList()[0].second;
1618 mlir::Value addrFieldIndex = builder.create<fir::FieldIndexOp>(
1620 /*typeParams=*/mlir::ValueRange{});
1624 mlir::Value fir::factory::genCPtrOrCFunptrAddr(fir::FirOpBuilder &builder,
1625 mlir::Location loc,
1626 mlir::Value cPtr,
1627 mlir::Type ty) {
1634 mlir::Value fir::factory::genCDevPtrAddr(fir::FirOpBuilder &builder,
1635 mlir::Location loc,
1636 mlir::Value cDevPtr, mlir::Type ty) {
1637 auto recTy = mlir::cast<fir::RecordType>(ty);
1640 mlir::Type cptrFieldTy = recTy.getTypeList()[0].second;
1642 mlir::Value cptrFieldIndex = builder.create<fir::FieldIndexOp>(
1644 /*typeParams=*/mlir::ValueRange{});
1653 mlir::Value fir::factory::genCPtrOrCFunptrValue(fir::FirOpBuilder &builder,
1654 mlir::Location loc,
1655 mlir::Value cPtr) {
1656 mlir::Type cPtrTy = fir::unwrapRefType(cPtr.getType());
1661 mlir::Value cPtrCoor;
1675 mlir::Value cPtrAddr =
1687 mlir::Location loc,
1691 mlir::Value box = builder.createBox(loc, exv);
1692 llvm::SmallVector<mlir::Value> lbounds;
1693 llvm::SmallVector<mlir::Value> explicitTypeParams;
1724 mlir::Value fir::factory::createNullBoxProc(fir::FirOpBuilder &builder,
1725 mlir::Location loc,
1726 mlir::Type boxType) {
1727 auto boxTy{mlir::dyn_cast<fir::BoxProcType>(boxType)};
1731 mlir::Value initVal{builder.create<fir::ZeroOp>(loc, boxEleTy)};
1735 void fir::factory::setInternalLinkage(mlir::func::FuncOp func) {
1736 auto internalLinkage = mlir::LLVM::linkage::Linkage::Internal;
1738 mlir::LLVM::LinkageAttr::get(func->getContext(), internalLinkage);
1742 uint64_t fir::factory::getAllocaAddressSpace(mlir::DataLayout *dataLayout) {
1744 if (mlir::Attribute addrSpace = dataLayout->getAllocaMemorySpace())
1745 return mlir::cast<mlir::IntegerAttr>(addrSpace).getUInt();
1749 llvm::SmallVector<mlir::Value>
1750 fir::factory::deduceOptimalExtents(mlir::ValueRange extents1,
1751 mlir::ValueRange extents2) {
1752 llvm::SmallVector<mlir::Value> extents;
1763 llvm::SmallVector<mlir::Value> fir::factory::updateRuntimeExtentsForEmptyArrays(
1764 fir::FirOpBuilder &builder, mlir::Location loc, mlir::ValueRange extents) {
1768 mlir::Type i1Type = builder.getI1Type();
1769 mlir::Value isEmpty = createZeroValue(builder, loc, i1Type);
1771 llvm::SmallVector<mlir::Value, Fortran::common::maxRank> zeroes;
1772 for (mlir::Value extent : extents) {
1773 mlir::Type type = extent.getType();
1774 mlir::Value zero = createZeroValue(builder, loc, type);
1776 mlir::Value isZero = builder.create<mlir::arith::CmpIOp>(
1777 loc, mlir::arith::CmpIPredicate::eq, extent, zero);
1778 isEmpty = builder.create<mlir::arith::OrIOp>(loc, isEmpty, isZero);
1781 llvm::SmallVector<mlir::Value, Fortran::common::maxRank> newExtents;
1784 builder.create<mlir::arith::SelectOp>(loc, isEmpty, zero, extent));