44 mlir::Value dstLen, B &builder, mlir::Location loc) {
49 if (!srcLen && !dstLen && srcTy.getFKind() == dstTy.getFKind() &&
50 srcTy.getLen() == dstTy.getLen()) {
52 auto load = fir::LoadOp::create(builder, loc, src);
53 fir::StoreOp::create(builder, loc, load, dst);
56 auto zero = mlir::arith::ConstantIndexOp::create(builder, loc, 0);
57 auto one = mlir::arith::ConstantIndexOp::create(builder, loc, 1);
58 auto toArrayTy = [&](fir::CharacterType ty) {
59 return fir::ReferenceType::get(fir::SequenceType::get(
60 fir::SequenceType::ShapeRef{fir::SequenceType::getUnknownExtent()},
61 fir::CharacterType::getSingleton(ty.getContext(), ty.getFKind())));
63 auto toEleTy = [&](fir::ReferenceType ty) {
64 auto seqTy = mlir::cast<fir::SequenceType>(ty.getEleTy());
65 return mlir::cast<fir::CharacterType>(seqTy.getEleTy());
67 auto toCoorTy = [&](fir::ReferenceType ty) {
68 return fir::ReferenceType::get(toEleTy(ty));
70 if (!srcLen && !dstLen && srcTy.getLen() >= dstTy.getLen()) {
72 mlir::arith::ConstantIndexOp::create(builder, loc, dstTy.getLen() - 1);
73 auto loop = fir::DoLoopOp::create(builder, loc, zero, upper, one);
74 auto insPt = builder.saveInsertionPoint();
75 builder.setInsertionPointToStart(loop.getBody());
76 auto csrcTy = toArrayTy(srcTy);
77 auto csrc = fir::ConvertOp::create(builder, loc, csrcTy, src);
78 auto in = fir::CoordinateOp::create(builder, loc, toCoorTy(csrcTy), csrc,
79 loop.getInductionVar());
80 auto load = fir::LoadOp::create(builder, loc, in);
81 auto cdstTy = toArrayTy(dstTy);
82 auto cdst = fir::ConvertOp::create(builder, loc, cdstTy, dst);
83 auto out = fir::CoordinateOp::create(builder, loc, toCoorTy(cdstTy), cdst,
84 loop.getInductionVar());
86 srcTy.getFKind() == dstTy.getFKind()
88 : fir::ConvertOp::create(builder, loc, toEleTy(cdstTy), load)
90 fir::StoreOp::create(builder, loc, cast, out);
91 builder.restoreInsertionPoint(insPt);
94 auto minusOne = [&](mlir::Value v) -> mlir::Value {
95 return mlir::arith::SubIOp::create(
96 builder, loc, fir::ConvertOp::create(builder, loc, one.getType(), v),
99 mlir::Value len = dstLen ? minusOne(dstLen)
100 : mlir::arith::ConstantIndexOp::create(
101 builder, loc, dstTy.getLen() - 1)
103 auto loop = fir::DoLoopOp::create(builder, loc, zero, len, one);
104 auto insPt = builder.saveInsertionPoint();
105 builder.setInsertionPointToStart(loop.getBody());
108 ? fir::ConvertOp::create(builder, loc, one.getType(), srcLen)
110 : mlir::arith::ConstantIndexOp::create(builder, loc, srcTy.getLen())
113 mlir::arith::CmpIOp::create(builder, loc, mlir::arith::CmpIPredicate::slt,
114 loop.getInductionVar(), slen);
115 auto ifOp = fir::IfOp::create(builder, loc, cond,
true);
116 builder.setInsertionPointToStart(&ifOp.getThenRegion().front());
117 auto csrcTy = toArrayTy(srcTy);
118 auto csrc = fir::ConvertOp::create(builder, loc, csrcTy, src);
119 auto in = fir::CoordinateOp::create(builder, loc, toCoorTy(csrcTy), csrc,
120 loop.getInductionVar());
121 auto load = fir::LoadOp::create(builder, loc, in);
122 auto cdstTy = toArrayTy(dstTy);
123 auto cdst = fir::ConvertOp::create(builder, loc, cdstTy, dst);
124 auto out = fir::CoordinateOp::create(builder, loc, toCoorTy(cdstTy), cdst,
125 loop.getInductionVar());
127 srcTy.getFKind() == dstTy.getFKind()
129 : fir::ConvertOp::create(builder, loc, toEleTy(cdstTy), load)
131 fir::StoreOp::create(builder, loc, cast, out);
132 builder.setInsertionPointToStart(&ifOp.getElseRegion().front());
133 auto space = fir::StringLitOp::create(builder, loc, toEleTy(cdstTy),
135 auto cdst2 = fir::ConvertOp::create(builder, loc, cdstTy, dst);
136 auto out2 = fir::CoordinateOp::create(builder, loc, toCoorTy(cdstTy), cdst2,
137 loop.getInductionVar());
138 fir::StoreOp::create(builder, loc, space, out2);
139 builder.restoreInsertionPoint(insPt);
184 mlir::Value shapeVal, mlir::ValueRange indices) {
187 if (origins.empty()) {
188 assert(!shapeVal || mlir::isa<fir::ShapeOp>(shapeVal.getDefiningOp()));
190 assert(ty && mlir::isa<fir::SequenceType>(ty));
191 auto seqTy = mlir::cast<fir::SequenceType>(ty);
192 auto one = mlir::arith::ConstantIndexOp::create(builder, loc, 1);
193 const auto dimension = seqTy.getDimension();
195 assert(dimension == mlir::cast<fir::ShapeOp>(shapeVal.getDefiningOp())
199 for (
auto i : llvm::enumerate(indices)) {
200 if (i.index() < dimension) {
203 mlir::arith::AddIOp::create(builder, loc, i.value(), one));
205 result.push_back(i.value());
210 const auto dimension = origins.size();
211 unsigned origOff = 0;
212 for (
auto i : llvm::enumerate(indices)) {
213 if (i.index() < dimension)
214 result.push_back(mlir::arith::AddIOp::create(builder, loc, i.value(),
215 origins[origOff++]));
217 result.push_back(i.value());