@@ -214,6 +214,24 @@ static void threadPrivatizeVars(Fortran::lower::AbstractConverter &converter,
214
214
firOpBuilder.restoreInsertionPoint (insPt);
215
215
}
216
216
217
+ static mlir::Type getLoopVarType (Fortran::lower::AbstractConverter &converter,
218
+ std::size_t loopVarTypeSize) {
219
+ // OpenMP runtime requires 32-bit or 64-bit loop variables.
220
+ loopVarTypeSize = loopVarTypeSize * 8 ;
221
+ if (loopVarTypeSize < 32 ) {
222
+ loopVarTypeSize = 32 ;
223
+ } else if (loopVarTypeSize > 64 ) {
224
+ loopVarTypeSize = 64 ;
225
+ mlir::emitWarning (converter.getCurrentLocation (),
226
+ " OpenMP loop iteration variable cannot have more than 64 "
227
+ " bits size and will be narrowed into 64 bits." );
228
+ }
229
+ assert ((loopVarTypeSize == 32 || loopVarTypeSize == 64 ) &&
230
+ " OpenMP loop iteration variable size must be transformed into 32-bit "
231
+ " or 64-bit" );
232
+ return converter.getFirOpBuilder ().getIntegerType (loopVarTypeSize);
233
+ }
234
+
217
235
static mlir::Operation *
218
236
createAndSetPrivatizedLoopVar (Fortran::lower::AbstractConverter &converter,
219
237
mlir::Location loc, mlir::Value indexVal,
@@ -550,7 +568,6 @@ genParallelOp(Fortran::lower::AbstractConverter &converter,
550
568
mlir::omp::ClauseProcBindKindAttr procBindKindAttr;
551
569
llvm::SmallVector<mlir::Value> allocateOperands, allocatorOperands,
552
570
reductionVars;
553
- llvm::SmallVector<mlir::Type> reductionTypes;
554
571
llvm::SmallVector<mlir::Attribute> reductionDeclSymbols;
555
572
llvm::SmallVector<const Fortran::semantics::Symbol *> reductionSymbols;
556
573
@@ -561,8 +578,13 @@ genParallelOp(Fortran::lower::AbstractConverter &converter,
561
578
cp.processDefault ();
562
579
cp.processAllocate (allocatorOperands, allocateOperands);
563
580
if (!outerCombined)
564
- cp.processReduction (currentLocation, reductionVars, reductionTypes,
565
- reductionDeclSymbols, &reductionSymbols);
581
+ cp.processReduction (currentLocation, reductionVars, reductionDeclSymbols,
582
+ &reductionSymbols);
583
+
584
+ llvm::SmallVector<mlir::Type> reductionTypes;
585
+ reductionTypes.reserve (reductionVars.size ());
586
+ llvm::transform (reductionVars, std::back_inserter (reductionTypes),
587
+ [](mlir::Value v) { return v.getType (); });
566
588
567
589
auto reductionCallback = [&](mlir::Operation *op) {
568
590
llvm::SmallVector<mlir::Location> locs (reductionVars.size (),
@@ -1446,6 +1468,25 @@ genOMP(Fortran::lower::AbstractConverter &converter,
1446
1468
standaloneConstruct.u );
1447
1469
}
1448
1470
1471
+ static void convertLoopBounds (Fortran::lower::AbstractConverter &converter,
1472
+ mlir::Location loc,
1473
+ llvm::SmallVectorImpl<mlir::Value> &lowerBound,
1474
+ llvm::SmallVectorImpl<mlir::Value> &upperBound,
1475
+ llvm::SmallVectorImpl<mlir::Value> &step,
1476
+ std::size_t loopVarTypeSize) {
1477
+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
1478
+ // The types of lower bound, upper bound, and step are converted into the
1479
+ // type of the loop variable if necessary.
1480
+ mlir::Type loopVarType = getLoopVarType (converter, loopVarTypeSize);
1481
+ for (unsigned it = 0 ; it < (unsigned )lowerBound.size (); it++) {
1482
+ lowerBound[it] =
1483
+ firOpBuilder.createConvert (loc, loopVarType, lowerBound[it]);
1484
+ upperBound[it] =
1485
+ firOpBuilder.createConvert (loc, loopVarType, upperBound[it]);
1486
+ step[it] = firOpBuilder.createConvert (loc, loopVarType, step[it]);
1487
+ }
1488
+ }
1489
+
1449
1490
static llvm::SmallVector<const Fortran::semantics::Symbol *>
1450
1491
genLoopVars (mlir::Operation *op, Fortran::lower::AbstractConverter &converter,
1451
1492
mlir::Location &loc,
@@ -1541,15 +1582,16 @@ createSimdLoop(Fortran::lower::AbstractConverter &converter,
1541
1582
llvm::SmallVector<mlir::Value> lowerBound, upperBound, step, reductionVars;
1542
1583
llvm::SmallVector<mlir::Value> alignedVars, nontemporalVars;
1543
1584
llvm::SmallVector<const Fortran::semantics::Symbol *> iv;
1544
- llvm::SmallVector<mlir::Type> reductionTypes;
1545
1585
llvm::SmallVector<mlir::Attribute> reductionDeclSymbols;
1546
1586
mlir::omp::ClauseOrderKindAttr orderClauseOperand;
1547
1587
mlir::IntegerAttr simdlenClauseOperand, safelenClauseOperand;
1588
+ std::size_t loopVarTypeSize;
1548
1589
1549
1590
ClauseProcessor cp (converter, semaCtx, loopOpClauseList);
1550
- cp.processCollapse (loc, eval, lowerBound, upperBound, step, iv);
1591
+ cp.processCollapse (loc, eval, lowerBound, upperBound, step, iv,
1592
+ loopVarTypeSize);
1551
1593
cp.processScheduleChunk (stmtCtx, scheduleChunkClauseOperand);
1552
- cp.processReduction (loc, reductionVars, reductionTypes, reductionDeclSymbols);
1594
+ cp.processReduction (loc, reductionVars, reductionDeclSymbols);
1553
1595
cp.processIf (clause::If::DirectiveNameModifier::Simd, ifClauseOperand);
1554
1596
cp.processSimdlen (simdlenClauseOperand);
1555
1597
cp.processSafelen (safelenClauseOperand);
@@ -1559,6 +1601,9 @@ createSimdLoop(Fortran::lower::AbstractConverter &converter,
1559
1601
Fortran::parser::OmpClause::Nontemporal,
1560
1602
Fortran::parser::OmpClause::Order>(loc, ompDirective);
1561
1603
1604
+ convertLoopBounds (converter, loc, lowerBound, upperBound, step,
1605
+ loopVarTypeSize);
1606
+
1562
1607
mlir::TypeRange resultType;
1563
1608
auto simdLoopOp = firOpBuilder.create <mlir::omp::SimdLoopOp>(
1564
1609
loc, resultType, lowerBound, upperBound, step, alignedVars,
@@ -1596,23 +1641,27 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter,
1596
1641
llvm::SmallVector<mlir::Value> lowerBound, upperBound, step, reductionVars;
1597
1642
llvm::SmallVector<mlir::Value> linearVars, linearStepVars;
1598
1643
llvm::SmallVector<const Fortran::semantics::Symbol *> iv;
1599
- llvm::SmallVector<mlir::Type> reductionTypes;
1600
1644
llvm::SmallVector<mlir::Attribute> reductionDeclSymbols;
1601
1645
llvm::SmallVector<const Fortran::semantics::Symbol *> reductionSymbols;
1602
1646
mlir::omp::ClauseOrderKindAttr orderClauseOperand;
1603
1647
mlir::omp::ClauseScheduleKindAttr scheduleValClauseOperand;
1604
1648
mlir::UnitAttr nowaitClauseOperand, byrefOperand, scheduleSimdClauseOperand;
1605
1649
mlir::IntegerAttr orderedClauseOperand;
1606
1650
mlir::omp::ScheduleModifierAttr scheduleModClauseOperand;
1651
+ std::size_t loopVarTypeSize;
1607
1652
1608
1653
ClauseProcessor cp (converter, semaCtx, beginClauseList);
1609
- cp.processCollapse (loc, eval, lowerBound, upperBound, step, iv);
1654
+ cp.processCollapse (loc, eval, lowerBound, upperBound, step, iv,
1655
+ loopVarTypeSize);
1610
1656
cp.processScheduleChunk (stmtCtx, scheduleChunkClauseOperand);
1611
- cp.processReduction (loc, reductionVars, reductionTypes, reductionDeclSymbols,
1657
+ cp.processReduction (loc, reductionVars, reductionDeclSymbols,
1612
1658
&reductionSymbols);
1613
1659
cp.processTODO <Fortran::parser::OmpClause::Linear,
1614
1660
Fortran::parser::OmpClause::Order>(loc, ompDirective);
1615
1661
1662
+ convertLoopBounds (converter, loc, lowerBound, upperBound, step,
1663
+ loopVarTypeSize);
1664
+
1616
1665
if (ReductionProcessor::doReductionByRef (reductionVars))
1617
1666
byrefOperand = firOpBuilder.getUnitAttr ();
1618
1667
@@ -1653,6 +1702,11 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter,
1653
1702
auto *nestedEval = getCollapsedLoopEval (
1654
1703
eval, Fortran::lower::getCollapseValue (beginClauseList));
1655
1704
1705
+ llvm::SmallVector<mlir::Type> reductionTypes;
1706
+ reductionTypes.reserve (reductionVars.size ());
1707
+ llvm::transform (reductionVars, std::back_inserter (reductionTypes),
1708
+ [](mlir::Value v) { return v.getType (); });
1709
+
1656
1710
auto ivCallback = [&](mlir::Operation *op) {
1657
1711
return genLoopAndReductionVars (op, converter, loc, iv, reductionSymbols,
1658
1712
reductionTypes);
0 commit comments