diff --git a/flang/include/flang/Lower/IO.h b/flang/include/flang/Lower/IO.h --- a/flang/include/flang/Lower/IO.h +++ b/flang/include/flang/Lower/IO.h @@ -19,10 +19,15 @@ namespace Fortran { namespace parser { +struct BackspaceStmt; struct CloseStmt; +struct EndfileStmt; +struct FlushStmt; struct OpenStmt; struct ReadStmt; +struct RewindStmt; struct PrintStmt; +struct WaitStmt; struct WriteStmt; } // namespace parser @@ -30,9 +35,20 @@ class AbstractConverter; +/// Generate IO call(s) for BACKSPACE; return the IOSTAT code +mlir::Value genBackspaceStatement(AbstractConverter &, + const parser::BackspaceStmt &); + /// Generate IO call(s) for CLOSE; return the IOSTAT code mlir::Value genCloseStatement(AbstractConverter &, const parser::CloseStmt &); +/// Generate IO call(s) for ENDFILE; return the IOSTAT code +mlir::Value genEndfileStatement(AbstractConverter &, + const parser::EndfileStmt &); + +/// Generate IO call(s) for FLUSH; return the IOSTAT code +mlir::Value genFlushStatement(AbstractConverter &, const parser::FlushStmt &); + /// Generate IO call(s) for READ; return the IOSTAT code mlir::Value genReadStatement(AbstractConverter &converter, const parser::ReadStmt &stmt); @@ -44,6 +60,12 @@ void genPrintStatement(AbstractConverter &converter, const parser::PrintStmt &stmt); +/// Generate IO call(s) for REWIND; return the IOSTAT code +mlir::Value genRewindStatement(AbstractConverter &, const parser::RewindStmt &); + +/// Generate IO call(s) for WAIT; return the IOSTAT code +mlir::Value genWaitStatement(AbstractConverter &, const parser::WaitStmt &); + /// Generate IO call(s) for WRITE; return the IOSTAT code mlir::Value genWriteStatement(AbstractConverter &converter, const parser::WriteStmt &stmt); diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -811,7 +811,8 @@ //===--------------------------------------------------------------------===// void genFIR(const Fortran::parser::BackspaceStmt &stmt) { - TODO(toLocation(), "BackspaceStmt lowering"); + mlir::Value iostat = genBackspaceStatement(*this, stmt); + genIoConditionBranches(getEval(), stmt.v, iostat); } void genFIR(const Fortran::parser::CloseStmt &stmt) { @@ -820,11 +821,13 @@ } void genFIR(const Fortran::parser::EndfileStmt &stmt) { - TODO(toLocation(), "EndfileStmt lowering"); + mlir::Value iostat = genEndfileStatement(*this, stmt); + genIoConditionBranches(getEval(), stmt.v, iostat); } void genFIR(const Fortran::parser::FlushStmt &stmt) { - TODO(toLocation(), "FlushStmt lowering"); + mlir::Value iostat = genFlushStatement(*this, stmt); + genIoConditionBranches(getEval(), stmt.v, iostat); } void genFIR(const Fortran::parser::InquireStmt &stmt) { @@ -846,11 +849,13 @@ } void genFIR(const Fortran::parser::RewindStmt &stmt) { - TODO(toLocation(), "RewindStmt lowering"); + mlir::Value iostat = genRewindStatement(*this, stmt); + genIoConditionBranches(getEval(), stmt.v, iostat); } void genFIR(const Fortran::parser::WaitStmt &stmt) { - TODO(toLocation(), "WaitStmt lowering"); + mlir::Value iostat = genWaitStatement(*this, stmt); + genIoConditionBranches(getEval(), stmt.v, iostat); } void genFIR(const Fortran::parser::WriteStmt &stmt) { diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp --- a/flang/lib/Lower/IO.cpp +++ b/flang/lib/Lower/IO.cpp @@ -1513,6 +1513,30 @@ stmtCtx); } +mlir::Value Fortran::lower::genBackspaceStatement( + Fortran::lower::AbstractConverter &converter, + const Fortran::parser::BackspaceStmt &stmt) { + return genBasicIOStmt(converter, stmt); +} + +mlir::Value Fortran::lower::genEndfileStatement( + Fortran::lower::AbstractConverter &converter, + const Fortran::parser::EndfileStmt &stmt) { + return genBasicIOStmt(converter, stmt); +} + +mlir::Value +Fortran::lower::genFlushStatement(Fortran::lower::AbstractConverter &converter, + const Fortran::parser::FlushStmt &stmt) { + return genBasicIOStmt(converter, stmt); +} + +mlir::Value +Fortran::lower::genRewindStatement(Fortran::lower::AbstractConverter &converter, + const Fortran::parser::RewindStmt &stmt) { + return genBasicIOStmt(converter, stmt); +} + mlir::Value Fortran::lower::genOpenStatement(Fortran::lower::AbstractConverter &converter, const Fortran::parser::OpenStmt &stmt) { @@ -1554,6 +1578,33 @@ return genBasicIOStmt(converter, stmt); } +mlir::Value +Fortran::lower::genWaitStatement(Fortran::lower::AbstractConverter &converter, + const Fortran::parser::WaitStmt &stmt) { + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + Fortran::lower::StatementContext stmtCtx; + mlir::Location loc = converter.getCurrentLocation(); + bool hasId = hasMem(stmt); + mlir::FuncOp beginFunc = + hasId ? getIORuntimeFunc(loc, builder) + : getIORuntimeFunc(loc, builder); + mlir::FunctionType beginFuncTy = beginFunc.getType(); + mlir::Value unit = fir::getBase(converter.genExprValue( + getExpr(stmt), stmtCtx, loc)); + mlir::Value un = builder.createConvert(loc, beginFuncTy.getInput(0), unit); + llvm::SmallVector args{un}; + if (hasId) { + mlir::Value id = fir::getBase(converter.genExprValue( + getExpr(stmt), stmtCtx, loc)); + args.push_back(builder.createConvert(loc, beginFuncTy.getInput(1), id)); + } + auto cookie = builder.create(loc, beginFunc, args).getResult(0); + ConditionSpecInfo csi; + genConditionHandlerCall(converter, loc, cookie, stmt.v, csi); + return genEndIO(converter, converter.getCurrentLocation(), cookie, csi, + stmtCtx); +} + //===----------------------------------------------------------------------===// // Data transfer statements. // diff --git a/flang/test/Lower/io-statement-1.f90 b/flang/test/Lower/io-statement-1.f90 --- a/flang/test/Lower/io-statement-1.f90 +++ b/flang/test/Lower/io-statement-1.f90 @@ -12,6 +12,26 @@ ! CHECK: call {{.*}}EndIoStatement open(8, file="foo", access="sequential") + ! CHECK: call {{.*}}BeginBackspace + ! CHECK: call {{.*}}EndIoStatement + backspace(8) + + ! CHECK: call {{.*}}BeginFlush + ! CHECK: call {{.*}}EndIoStatement + flush(8) + + ! CHECK: call {{.*}}BeginRewind + ! CHECK: call {{.*}}EndIoStatement + rewind(8) + + ! CHECK: call {{.*}}BeginEndfile + ! CHECK: call {{.*}}EndIoStatement + endfile(8) + + ! CHECK: call {{.*}}BeginWaitAll + ! CHECK: call {{.*}}EndIoStatement + wait(unit=8) + ! CHECK: call {{.*}}BeginExternalListInput ! CHECK: call {{.*}}InputInteger ! CHECK: call {{.*}}InputReal32