42 mlir::Value dstLen, B &builder, mlir::Location loc) {
47 if (!srcLen && !dstLen && srcTy.getFKind() == dstTy.getFKind() &&
48 srcTy.getLen() == dstTy.getLen()) {
50 auto load = fir::LoadOp::create(builder, loc, src);
51 fir::StoreOp::create(builder, loc, load, dst);
54 auto zero = mlir::arith::ConstantIndexOp::create(builder, loc, 0);
55 auto one = mlir::arith::ConstantIndexOp::create(builder, loc, 1);
56 auto toArrayTy = [&](fir::CharacterType ty) {
57 return fir::ReferenceType::get(fir::SequenceType::get(
58 fir::SequenceType::ShapeRef{fir::SequenceType::getUnknownExtent()},
59 fir::CharacterType::getSingleton(ty.getContext(), ty.getFKind())));
61 auto toEleTy = [&](fir::ReferenceType ty) {
62 auto seqTy = mlir::cast<fir::SequenceType>(ty.getEleTy());
63 return mlir::cast<fir::CharacterType>(seqTy.getEleTy());
65 auto toCoorTy = [&](fir::ReferenceType ty) {
66 return fir::ReferenceType::get(toEleTy(ty));
68 if (!srcLen && !dstLen && srcTy.getLen() >= dstTy.getLen()) {
70 mlir::arith::ConstantIndexOp::create(builder, loc, dstTy.getLen() - 1);
71 auto loop = fir::DoLoopOp::create(builder, loc, zero, upper, one);
72 auto insPt = builder.saveInsertionPoint();
73 builder.setInsertionPointToStart(loop.getBody());
74 auto csrcTy = toArrayTy(srcTy);
75 auto csrc = fir::ConvertOp::create(builder, loc, csrcTy, src);
76 auto in = fir::CoordinateOp::create(builder, loc, toCoorTy(csrcTy), csrc,
77 loop.getInductionVar());
78 auto load = fir::LoadOp::create(builder, loc, in);
79 auto cdstTy = toArrayTy(dstTy);
80 auto cdst = fir::ConvertOp::create(builder, loc, cdstTy, dst);
81 auto out = fir::CoordinateOp::create(builder, loc, toCoorTy(cdstTy), cdst,
82 loop.getInductionVar());
84 srcTy.getFKind() == dstTy.getFKind()
86 : fir::ConvertOp::create(builder, loc, toEleTy(cdstTy), load)
88 fir::StoreOp::create(builder, loc, cast, out);
89 builder.restoreInsertionPoint(insPt);
92 auto minusOne = [&](mlir::Value v) -> mlir::Value {
93 return mlir::arith::SubIOp::create(
94 builder, loc, fir::ConvertOp::create(builder, loc, one.getType(), v),
97 mlir::Value len = dstLen ? minusOne(dstLen)
98 : mlir::arith::ConstantIndexOp::create(
99 builder, loc, dstTy.getLen() - 1)
101 auto loop = fir::DoLoopOp::create(builder, loc, zero, len, one);
102 auto insPt = builder.saveInsertionPoint();
103 builder.setInsertionPointToStart(loop.getBody());
106 ? fir::ConvertOp::create(builder, loc, one.getType(), srcLen)
108 : mlir::arith::ConstantIndexOp::create(builder, loc, srcTy.getLen())
111 mlir::arith::CmpIOp::create(builder, loc, mlir::arith::CmpIPredicate::slt,
112 loop.getInductionVar(), slen);
113 auto ifOp = fir::IfOp::create(builder, loc, cond,
true);
114 builder.setInsertionPointToStart(&ifOp.getThenRegion().front());
115 auto csrcTy = toArrayTy(srcTy);
116 auto csrc = fir::ConvertOp::create(builder, loc, csrcTy, src);
117 auto in = fir::CoordinateOp::create(builder, loc, toCoorTy(csrcTy), csrc,
118 loop.getInductionVar());
119 auto load = fir::LoadOp::create(builder, loc, in);
120 auto cdstTy = toArrayTy(dstTy);
121 auto cdst = fir::ConvertOp::create(builder, loc, cdstTy, dst);
122 auto out = fir::CoordinateOp::create(builder, loc, toCoorTy(cdstTy), cdst,
123 loop.getInductionVar());
125 srcTy.getFKind() == dstTy.getFKind()
127 : fir::ConvertOp::create(builder, loc, toEleTy(cdstTy), load)
129 fir::StoreOp::create(builder, loc, cast, out);
130 builder.setInsertionPointToStart(&ifOp.getElseRegion().front());
131 auto space = fir::StringLitOp::create(builder, loc, toEleTy(cdstTy),
133 auto cdst2 = fir::ConvertOp::create(builder, loc, cdstTy, dst);
134 auto out2 = fir::CoordinateOp::create(builder, loc, toCoorTy(cdstTy), cdst2,
135 loop.getInductionVar());
136 fir::StoreOp::create(builder, loc, space, out2);
137 builder.restoreInsertionPoint(insPt);
182 mlir::Value shapeVal, mlir::ValueRange indices) {
185 if (origins.empty()) {
186 assert(!shapeVal || mlir::isa<fir::ShapeOp>(shapeVal.getDefiningOp()));
188 assert(ty && mlir::isa<fir::SequenceType>(ty));
189 auto seqTy = mlir::cast<fir::SequenceType>(ty);
190 auto one = mlir::arith::ConstantIndexOp::create(builder, loc, 1);
191 const auto dimension = seqTy.getDimension();
193 assert(dimension == mlir::cast<fir::ShapeOp>(shapeVal.getDefiningOp())
197 for (
auto i : llvm::enumerate(indices)) {
198 if (i.index() < dimension) {
201 mlir::arith::AddIOp::create(builder, loc, i.value(), one));
203 result.push_back(i.value());
208 const auto dimension = origins.size();
209 unsigned origOff = 0;
210 for (
auto i : llvm::enumerate(indices)) {
211 if (i.index() < dimension)
212 result.push_back(mlir::arith::AddIOp::create(builder, loc, i.value(),
213 origins[origOff++]));
215 result.push_back(i.value());