@@ -122,25 +122,49 @@ static void createCleanupRegion(Fortran::lower::AbstractConverter &converter,
122122 typeError ();
123123}
124124
125- fir::ShapeShiftOp Fortran::lower::omp::getShapeShift (fir::FirOpBuilder &builder,
126- mlir::Location loc,
127- mlir::Value box) {
125+ fir::ShapeShiftOp
126+ Fortran::lower::omp::getShapeShift (fir::FirOpBuilder &builder,
127+ mlir::Location loc, mlir::Value box,
128+ bool useDefaultLowerBounds) {
128129 fir::SequenceType sequenceType = mlir::cast<fir::SequenceType>(
129130 hlfir::getFortranElementOrSequenceType (box.getType ()));
130131 const unsigned rank = sequenceType.getDimension ();
131132 llvm::SmallVector<mlir::Value> lbAndExtents;
132133 lbAndExtents.reserve (rank * 2 );
133134
134135 mlir::Type idxTy = builder.getIndexType ();
135- for (unsigned i = 0 ; i < rank; ++i) {
136- // TODO: ideally we want to hoist box reads out of the critical section.
137- // We could do this by having box dimensions in block arguments like
138- // OpenACC does
139- mlir::Value dim = builder.createIntegerConstant (loc, idxTy, i);
140- auto dimInfo =
141- builder.create <fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, box, dim);
142- lbAndExtents.push_back (dimInfo.getLowerBound ());
143- lbAndExtents.push_back (dimInfo.getExtent ());
136+
137+ mlir::Value oneVal;
138+ auto one = [&] {
139+ if (!oneVal)
140+ oneVal = builder.createIntegerConstant (loc, idxTy, 1 );
141+ return oneVal;
142+ };
143+
144+ if ((useDefaultLowerBounds) && !sequenceType.hasDynamicExtents ()) {
145+ // We don't need fir::BoxDimsOp if all of the extents are statically known
146+ // and we can assume default lower bounds. This helps avoids reads from the
147+ // mold arg.
148+ // We may also want to use default lower bounds to iterate through array
149+ // elements without having to adjust each index.
150+ for (int64_t extent : sequenceType.getShape ()) {
151+ assert (extent != sequenceType.getUnknownExtent ());
152+ lbAndExtents.push_back (one ());
153+ mlir::Value extentVal = builder.createIntegerConstant (loc, idxTy, extent);
154+ lbAndExtents.push_back (extentVal);
155+ }
156+ } else {
157+ for (unsigned i = 0 ; i < rank; ++i) {
158+ // TODO: ideally we want to hoist box reads out of the critical section.
159+ // We could do this by having box dimensions in block arguments like
160+ // OpenACC does
161+ mlir::Value dim = builder.createIntegerConstant (loc, idxTy, i);
162+ auto dimInfo =
163+ builder.create <fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, box, dim);
164+ lbAndExtents.push_back (useDefaultLowerBounds ? one ()
165+ : dimInfo.getLowerBound ());
166+ lbAndExtents.push_back (dimInfo.getExtent ());
167+ }
144168 }
145169
146170 auto shapeShiftTy = fir::ShapeShiftType::get (builder.getContext (), rank);
0 commit comments