From 46f46a3763c494054227b2b0f551fc34fa9af367 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Wed, 2 Mar 2022 17:58:38 +0100 Subject: [PATCH] [flang] Lower basic IO file statements This patches adds lowering for couple of basic io statements such as `flush`, `endfile`, `backspace` and `rewind` This patch is part of the upstreaming effort from fir-dev branch. Depends on D120821 Reviewed By: schweitz Differential Revision: https://reviews.llvm.org/D120822 Co-authored-by: Eric Schweitz Co-authored-by: Jean Perier --- flang/include/flang/Lower/IO.h | 22 +++++++++++++ flang/lib/Lower/Bridge.cpp | 15 ++++++--- flang/lib/Lower/IO.cpp | 51 +++++++++++++++++++++++++++++ flang/test/Lower/io-statement-1.f90 | 20 +++++++++++ 4 files changed, 103 insertions(+), 5 deletions(-) diff --git a/flang/include/flang/Lower/IO.h b/flang/include/flang/Lower/IO.h index f2acb7af3fb8..d7cb1a8b775e 100644 --- a/flang/include/flang/Lower/IO.h +++ b/flang/include/flang/Lower/IO.h @@ -19,10 +19,15 @@ class Value; 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 @@ namespace lower { 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 @@ mlir::Value genOpenStatement(AbstractConverter &, const parser::OpenStmt &); 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 index 7af503fa30be..33bbd5bf7590 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -811,7 +811,8 @@ private: //===--------------------------------------------------------------------===// 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 @@ private: } 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 @@ private: } 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 index c25f6d97feb6..d3f45a7480c3 100644 --- a/flang/lib/Lower/IO.cpp +++ b/flang/lib/Lower/IO.cpp @@ -1513,6 +1513,30 @@ static mlir::Value genBasicIOStmt(Fortran::lower::AbstractConverter &converter, 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 @@ Fortran::lower::genCloseStatement(Fortran::lower::AbstractConverter &converter, 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 index 3eeed9c8561a..edf6f77aeeee 100644 --- 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