[flang-commits] [flang] [llvm] [flang][MIF] Adding lowering for EVENT POST/WAIT statements (PR #210283)
via flang-commits
flang-commits at lists.llvm.org
Sat Oct 10 23:34:48 PDT 2026
================
@@ -1407,6 +1552,118 @@ struct MIFImageIndexOpConversion
}
};
+/// Convert mif.event_wait operation to runtime call of 'prif_event_wait*'
+struct MIFEventWaitOpConversion
+ : public mlir::OpRewritePattern<mif::EventWaitOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::EventWaitOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Type ptrTy = getBuiltinCptrType(builder, loc);
+ mlir::Type i64Ty = builder.getI64Type();
+ mlir::Type errmsgTy = getPRIFErrmsgType(builder);
+ mlir::FunctionType ftype = mlir::FunctionType::get(
+ builder.getContext(),
+ /*inputs*/
+ {builder.getRefType(ptrTy), builder.getRefType(i64Ty),
+ getPRIFStatType(builder), errmsgTy, errmsgTy},
+ /*results*/ {});
+ mlir::func::FuncOp funcOp =
+ builder.createFunction(loc, getPRIFProcName("event_wait"), ftype);
+
+ mlir::Value untilCount;
+ if (!op.getUntilCount())
+ untilCount =
+ fir::AbsentOp::create(builder, loc, builder.getRefType(i64Ty));
+ else {
+ untilCount = builder.createTemporary(loc, i64Ty);
+ mlir::Value u = builder.createConvert(loc, i64Ty, op.getUntilCount());
+ fir::StoreOp::create(builder, loc, u, untilCount);
+ }
+
+ mlir::Value stat = op.getStat();
+ if (!stat)
+ stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
+ auto [errmsgArg, errmsgAllocArg] =
+ genErrmsgPRIF(builder, loc, op.getErrmsg());
+
+ mlir::Value cptrEvent =
+ convertRefTypeToCPtrType(builder, loc, op.getEvent());
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, cptrEvent, untilCount, stat, errmsgArg,
+ errmsgAllocArg);
+ fir::CallOp callOp = fir::CallOp::create(builder, loc, funcOp, args);
+ rewriter.replaceOp(op, callOp);
+ return mlir::success();
+ }
+};
+
+/// Convert mif.event_post operation to runtime call of 'prif_event_post'
+struct MIFEventPostOpConversion
+ : public mlir::OpRewritePattern<mif::EventPostOp> {
+ using OpRewritePattern::OpRewritePattern;
+
+ mlir::LogicalResult
+ matchAndRewrite(mif::EventPostOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ auto mod = op->template getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, mod);
+ mlir::Location loc = op.getLoc();
+
+ mlir::Type ptrTy = builder.getRefType(builder.getNoneType());
+ mlir::Type i32Ty = builder.getI32Type();
+ mlir::Type i64Ty = builder.getI64Type();
+ mlir::Type errmsgTy = getPRIFErrmsgType(builder);
+ mlir::Type statTy = getPRIFStatType(builder);
+ mlir::Type eventType = fir::unwrapRefType(op.getEvent().getType());
+ mlir::FunctionType ftype;
+ mlir::func::FuncOp funcOp;
+ llvm::SmallVector<mlir::Value> args;
+
+ mlir::Value stat = op.getStat();
+ if (!stat)
+ stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder));
+ auto [errmsgArg, errmsgAllocArg] =
+ genErrmsgPRIF(builder, loc, op.getErrmsg());
+
+ bool isCoarray = false;
+ if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(eventType))
+ isCoarray = boxTy.isCoarray();
+
+ if (isCoarray) {
+ ftype = mlir::FunctionType::get(builder.getContext(),
+ /*inputs*/
+ {builder.getRefType(i32Ty), ptrTy,
+ builder.getRefType(i64Ty), statTy,
+ errmsgTy, errmsgTy},
+ /*results*/ {});
+ funcOp =
+ builder.createFunction(loc, getPRIFProcName("event_post"), ftype);
+
+ mlir::Value offset = builder.createTemporary(loc, i64Ty);
+ mlir::Value offset_val =
+ computeOffsetInBytes(builder, loc, op.getEvent());
+ fir::StoreOp::create(builder, loc, offset_val, offset);
+ mlir::Value coarrayHandle = getCoarrayHandle(builder, loc, op.getEvent());
----------------
MattPD wrote:
EVENT POST on an associate name crashes in codegen. You can reproduce this by saving the following to `assoc.f90` and running `flang -fcoarray -c assoc.f90`:
```fortran
program p
use iso_fortran_env, only: event_type
type(event_type) :: e[*]
associate (a => e)
event post(a[1])
end associate
end program
```
Compilation fails with `'llvm.mlir.addressof' op must reference a global defined by 'llvm.mlir.global', ...` and `Lowering to LLVM IR failed`. A build with assertions then aborts in `LLVMToLLVMIRTranslation.cpp`. Before this PR, the statement stopped at the EVENT POST TODO.
`getCoarrayHandle` builds the handle name from the associate name's `uniq_name`, and no handle global has that name.
SELECT TYPE behaves the same way when the associate name's `uniq_name` differs from the coarray's, as with `select type (a => c)` or with `select type (c)` on a module coarray. Since EVENT POST can reach an event in a `class(*)` coarray only through SELECT TYPE, could these cases get a TODO for now?
https://github.com/llvm/llvm-project/pull/210283
More information about the flang-commits
mailing list