Skip to content

Commit 2fae4cc

Browse files
authored
[Flang][OpenMP] Add host_eval clause lowering support (#180)
This patch updates Flang lowering to use the `host_eval` clause in `omp.target` operations to pass host information into the applicable clauses inside of the target region, instead of the previous approach where these clauses were attached to the `omp.target` operation itself.
1 parent 5654efd commit 2fae4cc

File tree

10 files changed

+332
-466
lines changed

10 files changed

+332
-466
lines changed

flang/include/flang/Lower/OpenMP/Utils.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -174,15 +174,6 @@ void genObjectList(const ObjectList &objects,
174174
void lastprivateModifierNotSupported(const omp::clause::Lastprivate &lastp,
175175
mlir::Location loc);
176176

177-
// TODO: consider moving this to the `omp.loop_nest` op. Would be something like
178-
// this:
179-
//
180-
// ```
181-
// mlir::Value LoopNestOp::calculateTripCount(mlir::OpBuilder &builder,
182-
// mlir::OpBuilder::InsertPoint ip)
183-
// ```
184-
mlir::Value calculateTripCount(fir::FirOpBuilder &builder, mlir::Location loc,
185-
const mlir::omp::LoopRelatedClauseOps &ops);
186177
} // namespace omp
187178
} // namespace lower
188179
} // namespace Fortran

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 113 additions & 107 deletions
Large diffs are not rendered by default.

flang/lib/Lower/OpenMP/Utils.cpp

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)