@@ -538,84 +538,6 @@ void lastprivateModifierNotSupported(const omp::clause::Lastprivate &lastp,
538538 }
539539}
540540
541- mlir::Value calculateTripCount (fir::FirOpBuilder &builder, mlir::Location loc,
542- const mlir::omp::LoopRelatedClauseOps &ops) {
543- using namespace mlir ::arith;
544- assert (ops.loopLowerBounds .size () == ops.loopUpperBounds .size () &&
545- ops.loopLowerBounds .size () == ops.loopSteps .size () &&
546- !ops.loopLowerBounds .empty () && " Invalid bounds or step" );
547-
548- // Get the bit width of an integer-like type.
549- auto widthOf = [](mlir::Type ty) -> unsigned {
550- if (mlir::isa<mlir::IndexType>(ty)) {
551- return mlir::IndexType::kInternalStorageBitWidth ;
552- }
553- if (auto tyInt = mlir::dyn_cast<mlir::IntegerType>(ty)) {
554- return tyInt.getWidth ();
555- }
556- llvm_unreachable (" Unexpected type" );
557- };
558-
559- // For a type that is either IntegerType or IndexType, return the
560- // equivalent IntegerType. In the former case this is a no-op.
561- auto asIntTy = [&](mlir::Type ty) -> mlir::IntegerType {
562- if (ty.isIndex ()) {
563- return mlir::IntegerType::get (ty.getContext (), widthOf (ty));
564- }
565- assert (ty.isIntOrIndex () && " Unexpected type" );
566- return mlir::cast<mlir::IntegerType>(ty);
567- };
568-
569- // For two given values, establish a common signless IntegerType
570- // that can represent any value of type of x and of type of y,
571- // and return the pair of x, y converted to the new type.
572- auto unifyToSignless =
573- [&](fir::FirOpBuilder &b, mlir::Value x,
574- mlir::Value y) -> std::pair<mlir::Value, mlir::Value> {
575- auto tyX = asIntTy (x.getType ()), tyY = asIntTy (y.getType ());
576- unsigned width = std::max (widthOf (tyX), widthOf (tyY));
577- auto wideTy = mlir::IntegerType::get (b.getContext (), width,
578- mlir::IntegerType::Signless);
579- return std::make_pair (b.createConvert (loc, wideTy, x),
580- b.createConvert (loc, wideTy, y));
581- };
582-
583- // Start with signless i32 by default.
584- auto tripCount = builder.createIntegerConstant (loc, builder.getI32Type (), 1 );
585-
586- for (auto [origLb, origUb, origStep] :
587- llvm::zip (ops.loopLowerBounds , ops.loopUpperBounds , ops.loopSteps )) {
588- auto tmpS0 = builder.createIntegerConstant (loc, origStep.getType (), 0 );
589- auto [step, step0] = unifyToSignless (builder, origStep, tmpS0);
590- auto reverseCond =
591- builder.create <CmpIOp>(loc, CmpIPredicate::slt, step, step0);
592- auto negStep = builder.create <SubIOp>(loc, step0, step);
593- mlir::Value absStep =
594- builder.create <SelectOp>(loc, reverseCond, negStep, step);
595-
596- auto [lb, ub] = unifyToSignless (builder, origLb, origUb);
597- auto start = builder.create <SelectOp>(loc, reverseCond, ub, lb);
598- auto end = builder.create <SelectOp>(loc, reverseCond, lb, ub);
599-
600- mlir::Value range = builder.create <SubIOp>(loc, end, start);
601- auto rangeCond =
602- builder.create <CmpIOp>(loc, CmpIPredicate::slt, end, start);
603- std::tie (range, absStep) = unifyToSignless (builder, range, absStep);
604- // numSteps = (range /u absStep) + 1
605- auto numSteps = builder.create <AddIOp>(
606- loc, builder.create <DivUIOp>(loc, range, absStep),
607- builder.createIntegerConstant (loc, range.getType (), 1 ));
608-
609- auto trip0 = builder.createIntegerConstant (loc, numSteps.getType (), 0 );
610- auto loopTripCount =
611- builder.create <SelectOp>(loc, rangeCond, trip0, numSteps);
612- auto [totalTC, thisTC] = unifyToSignless (builder, tripCount, loopTripCount);
613- tripCount = builder.create <MulIOp>(loc, totalTC, thisTC);
614- }
615-
616- return tripCount;
617- }
618-
619541} // namespace omp
620542} // namespace lower
621543} // namespace Fortran
0 commit comments