[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 <eschweitz@nvidia.com>
Co-authored-by: Jean Perier <jperier@nvidia.com>
This commit is contained in:
Valentin Clement 2022-03-02 17:58:38 +01:00
parent db31da279f
commit 46f46a3763
No known key found for this signature in database
GPG Key ID: 086D54783C928776
4 changed files with 103 additions and 5 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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<mkIOKey(BeginBackspace)>(converter, stmt);
}
mlir::Value Fortran::lower::genEndfileStatement(
Fortran::lower::AbstractConverter &converter,
const Fortran::parser::EndfileStmt &stmt) {
return genBasicIOStmt<mkIOKey(BeginEndfile)>(converter, stmt);
}
mlir::Value
Fortran::lower::genFlushStatement(Fortran::lower::AbstractConverter &converter,
const Fortran::parser::FlushStmt &stmt) {
return genBasicIOStmt<mkIOKey(BeginFlush)>(converter, stmt);
}
mlir::Value
Fortran::lower::genRewindStatement(Fortran::lower::AbstractConverter &converter,
const Fortran::parser::RewindStmt &stmt) {
return genBasicIOStmt<mkIOKey(BeginRewind)>(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<mkIOKey(BeginClose)>(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<Fortran::parser::IdExpr>(stmt);
mlir::FuncOp beginFunc =
hasId ? getIORuntimeFunc<mkIOKey(BeginWait)>(loc, builder)
: getIORuntimeFunc<mkIOKey(BeginWaitAll)>(loc, builder);
mlir::FunctionType beginFuncTy = beginFunc.getType();
mlir::Value unit = fir::getBase(converter.genExprValue(
getExpr<Fortran::parser::FileUnitNumber>(stmt), stmtCtx, loc));
mlir::Value un = builder.createConvert(loc, beginFuncTy.getInput(0), unit);
llvm::SmallVector<mlir::Value> args{un};
if (hasId) {
mlir::Value id = fir::getBase(converter.genExprValue(
getExpr<Fortran::parser::IdExpr>(stmt), stmtCtx, loc));
args.push_back(builder.createConvert(loc, beginFuncTy.getInput(1), id));
}
auto cookie = builder.create<fir::CallOp>(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.
//

View File

@ -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