Skip to content

[flang] Remove dead code and update test (NFC) #73004

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 21, 2023

Conversation

kkwli
Copy link
Collaborator

@kkwli kkwli commented Nov 21, 2023

OutputUnformattedBlock and InputUnformattedBlock are not used.

OutputUnformattedBlock and InputUnformattedBlock are not used.
@kkwli kkwli requested a review from klausler November 21, 2023 16:14
@kkwli kkwli self-assigned this Nov 21, 2023
@llvmbot llvmbot added flang:runtime flang Flang issues not falling into any other category flang:fir-hlfir labels Nov 21, 2023
@llvmbot
Copy link
Member

llvmbot commented Nov 21, 2023

@llvm/pr-subscribers-flang-fir-hlfir

Author: None (kkwli)

Changes

OutputUnformattedBlock and InputUnformattedBlock are not used.


Full diff: https://github.com/llvm/llvm-project/pull/73004.diff

4 Files Affected:

  • (modified) flang/include/flang/Runtime/io-api.h (-5)
  • (modified) flang/lib/Lower/IO.cpp (+7-8)
  • (modified) flang/runtime/io-api.cpp (-33)
  • (modified) flang/unittests/Runtime/ExternalIOTest.cpp (+50-54)
diff --git a/flang/include/flang/Runtime/io-api.h b/flang/include/flang/Runtime/io-api.h
index e298ab4c53d4ae5..41574e3bb80ad3b 100644
--- a/flang/include/flang/Runtime/io-api.h
+++ b/flang/include/flang/Runtime/io-api.h
@@ -244,11 +244,6 @@ bool IONAME(SetSign)(Cookie, const char *, std::size_t);
 // and avoid the following items when they might crash.
 bool IONAME(OutputDescriptor)(Cookie, const Descriptor &);
 bool IONAME(InputDescriptor)(Cookie, const Descriptor &);
-// Contiguous transfers for unformatted I/O
-bool IONAME(OutputUnformattedBlock)(
-    Cookie, const char *, std::size_t, std::size_t elementBytes);
-bool IONAME(InputUnformattedBlock)(
-    Cookie, char *, std::size_t, std::size_t elementBytes);
 // Formatted (including list directed) I/O data items
 bool IONAME(OutputInteger8)(Cookie, std::int8_t);
 bool IONAME(OutputInteger16)(Cookie, std::int16_t);
diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp
index 94135bb570ffbc1..4186d6158fb1d04 100644
--- a/flang/lib/Lower/IO.cpp
+++ b/flang/lib/Lower/IO.cpp
@@ -101,20 +101,19 @@ static constexpr std::tuple<
     mkIOKey(InputAscii), mkIOKey(InputComplex32), mkIOKey(InputComplex64),
     mkIOKey(InputDerivedType), mkIOKey(InputDescriptor), mkIOKey(InputInteger),
     mkIOKey(InputLogical), mkIOKey(InputNamelist), mkIOKey(InputReal32),
-    mkIOKey(InputReal64), mkIOKey(InputUnformattedBlock),
-    mkIOKey(InquireCharacter), mkIOKey(InquireInteger64),
+    mkIOKey(InputReal64), mkIOKey(InquireCharacter), mkIOKey(InquireInteger64),
     mkIOKey(InquireLogical), mkIOKey(InquirePendingId), mkIOKey(OutputAscii),
     mkIOKey(OutputComplex32), mkIOKey(OutputComplex64),
     mkIOKey(OutputDerivedType), mkIOKey(OutputDescriptor),
     mkIOKey(OutputInteger8), mkIOKey(OutputInteger16), mkIOKey(OutputInteger32),
     mkIOKey(OutputInteger64), mkIOKey(OutputInteger128), mkIOKey(OutputLogical),
     mkIOKey(OutputNamelist), mkIOKey(OutputReal32), mkIOKey(OutputReal64),
-    mkIOKey(OutputUnformattedBlock), mkIOKey(SetAccess), mkIOKey(SetAction),
-    mkIOKey(SetAdvance), mkIOKey(SetAsynchronous), mkIOKey(SetBlank),
-    mkIOKey(SetCarriagecontrol), mkIOKey(SetConvert), mkIOKey(SetDecimal),
-    mkIOKey(SetDelim), mkIOKey(SetEncoding), mkIOKey(SetFile), mkIOKey(SetForm),
-    mkIOKey(SetPad), mkIOKey(SetPos), mkIOKey(SetPosition), mkIOKey(SetRec),
-    mkIOKey(SetRecl), mkIOKey(SetRound), mkIOKey(SetSign), mkIOKey(SetStatus)>
+    mkIOKey(SetAccess), mkIOKey(SetAction), mkIOKey(SetAdvance),
+    mkIOKey(SetAsynchronous), mkIOKey(SetBlank), mkIOKey(SetCarriagecontrol),
+    mkIOKey(SetConvert), mkIOKey(SetDecimal), mkIOKey(SetDelim),
+    mkIOKey(SetEncoding), mkIOKey(SetFile), mkIOKey(SetForm), mkIOKey(SetPad),
+    mkIOKey(SetPos), mkIOKey(SetPosition), mkIOKey(SetRec), mkIOKey(SetRecl),
+    mkIOKey(SetRound), mkIOKey(SetSign), mkIOKey(SetStatus)>
     newIOTable;
 } // namespace Fortran::lower
 
diff --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp
index 2fc530c7431a50d..9a69a262464123c 100644
--- a/flang/runtime/io-api.cpp
+++ b/flang/runtime/io-api.cpp
@@ -1135,39 +1135,6 @@ bool IONAME(InputDescriptor)(Cookie cookie, const Descriptor &descriptor) {
   return descr::DescriptorIO<Direction::Input>(*cookie, descriptor);
 }
 
-bool IONAME(OutputUnformattedBlock)(Cookie cookie, const char *x,
-    std::size_t length, std::size_t elementBytes) {
-  IoStatementState &io{*cookie};
-  if (auto *unf{io.get_if<
-          ExternalUnformattedIoStatementState<Direction::Output>>()}) {
-    return unf->Emit(x, length, elementBytes);
-  } else if (auto *inq{io.get_if<InquireIOLengthState>()}) {
-    return inq->Emit(x, length, elementBytes);
-  } else if (!io.get_if<ErroneousIoStatementState>()) {
-    io.GetIoErrorHandler().Crash("OutputUnformattedBlock() called for an I/O "
-                                 "statement that is not unformatted output");
-  }
-  return false;
-}
-
-bool IONAME(InputUnformattedBlock)(
-    Cookie cookie, char *x, std::size_t length, std::size_t elementBytes) {
-  IoStatementState &io{*cookie};
-  IoErrorHandler &handler{io.GetIoErrorHandler()};
-  io.BeginReadingRecord();
-  if (handler.InError()) {
-    return false;
-  }
-  if (auto *unf{
-          io.get_if<ExternalUnformattedIoStatementState<Direction::Input>>()}) {
-    return unf->Receive(x, length, elementBytes);
-  } else if (!io.get_if<ErroneousIoStatementState>()) {
-    handler.Crash("InputUnformattedBlock() called for an I/O statement that is "
-                  "not unformatted input");
-  }
-  return false;
-}
-
 bool IONAME(OutputInteger8)(Cookie cookie, std::int8_t n) {
   if (!cookie->CheckFormattedStmtType<Direction::Output>("OutputInteger8")) {
     return false;
diff --git a/flang/unittests/Runtime/ExternalIOTest.cpp b/flang/unittests/Runtime/ExternalIOTest.cpp
index 4f08505f05d0ad4..76fdb6cb68ae952 100644
--- a/flang/unittests/Runtime/ExternalIOTest.cpp
+++ b/flang/unittests/Runtime/ExternalIOTest.cpp
@@ -43,11 +43,15 @@ TEST(ExternalIOTests, TestDirectUnformatted) {
   ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
       << "EndIoStatement() for OpenNewUnit";
 
+  StaticDescriptor<0> staticDescriptor;
+  Descriptor &desc{staticDescriptor.descriptor()};
+  desc.Establish(TypeCode{CFI_type_int8_t}, recl, &buffer, 0);
+  desc.Check();
+
   // INQUIRE(IOLENGTH=) j
   io = IONAME(BeginInquireIoLength)(__FILE__, __LINE__);
-  ASSERT_TRUE(IONAME(OutputUnformattedBlock)(
-      io, reinterpret_cast<const char *>(&buffer), recl, 1))
-      << "OutputUnformattedBlock() for InquireIoLength";
+  ASSERT_TRUE(IONAME(OutputDescriptor)(io, desc))
+      << "OutputDescriptor() for InquireIoLength";
   ASSERT_EQ(IONAME(GetIoLength)(io), recl) << "GetIoLength";
   ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
       << "EndIoStatement() for InquireIoLength";
@@ -59,24 +63,23 @@ TEST(ExternalIOTests, TestDirectUnformatted) {
     ASSERT_TRUE(IONAME(SetRec)(io, j)) << "SetRec(" << j << ')';
 
     buffer = j;
-    ASSERT_TRUE(IONAME(OutputUnformattedBlock)(
-        io, reinterpret_cast<const char *>(&buffer), 1, recl))
-        << "OutputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(OutputDescriptor)(io, desc))
+        << "OutputDescriptor() for Write";
 
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for OutputUnformattedBlock";
+        << "EndIoStatement() for Write";
   }
 
   for (int j{records}; j >= 1; --j) {
+    buffer = -1;
     // READ(UNIT=unit,REC=j) n
     io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
     ASSERT_TRUE(IONAME(SetRec)(io, j)) << "SetRec(" << j << ')';
-    ASSERT_TRUE(IONAME(InputUnformattedBlock)(
-        io, reinterpret_cast<char *>(&buffer), 1, recl))
-        << "InputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(InputDescriptor)(io, desc))
+        << "InputDescriptor() for Read";
 
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for InputUnformattedBlock";
+        << "EndIoStatement() for Read";
 
     ASSERT_EQ(buffer, j) << "Read back " << buffer
                          << " from direct unformatted record " << j
@@ -108,17 +111,21 @@ TEST(ExternalIOTests, TestDirectUnformattedSwapped) {
   ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
       << "EndIoStatement() for OpenNewUnit";
 
+  StaticDescriptor<0> staticDescriptor;
+  Descriptor &desc{staticDescriptor.descriptor()};
+  desc.Establish(TypeCode{CFI_type_int64_t}, recl, &buffer, 0);
+  desc.Check();
+
   static constexpr int records{10};
   for (int j{1}; j <= records; ++j) {
     // WRITE(UNIT=unit,REC=j) j
     io = IONAME(BeginUnformattedOutput)(unit, __FILE__, __LINE__);
     ASSERT_TRUE(IONAME(SetRec)(io, j)) << "SetRec(" << j << ')';
     buffer = j;
-    ASSERT_TRUE(IONAME(OutputUnformattedBlock)(
-        io, reinterpret_cast<const char *>(&buffer), recl, recl))
-        << "OutputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(OutputDescriptor)(io, desc))
+        << "OutputDescriptor() for Write";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for OutputUnformattedBlock";
+        << "EndIoStatement() for Write";
   }
 
   // OPEN(UNIT=unit,STATUS='OLD',CONVERT='SWAP')
@@ -132,11 +139,10 @@ TEST(ExternalIOTests, TestDirectUnformattedSwapped) {
     // READ(UNIT=unit,REC=j) n
     io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
     ASSERT_TRUE(IONAME(SetRec)(io, j)) << "SetRec(" << j << ')';
-    ASSERT_TRUE(IONAME(InputUnformattedBlock)(
-        io, reinterpret_cast<char *>(&buffer), recl, recl))
-        << "InputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(InputDescriptor)(io, desc))
+        << "InputDescriptor() for Read";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for InputUnformattedBlock";
+        << "EndIoStatement() for Read";
     ASSERT_EQ(buffer >> 56, j)
         << "Read back " << (buffer >> 56) << " from direct unformatted record "
         << j << ", expected " << j << '\n';
@@ -169,17 +175,6 @@ TEST(ExternalIOTests, TestSequentialFixedUnformatted) {
   ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
       << "EndIoStatement() for OpenNewUnit";
 
-  // INQUIRE(IOLENGTH=) j, ...
-  io = IONAME(BeginInquireIoLength)(__FILE__, __LINE__);
-  for (int j{1}; j <= 3; ++j) {
-    ASSERT_TRUE(IONAME(OutputUnformattedBlock)(
-        io, reinterpret_cast<const char *>(&buffer), recl, 1))
-        << "OutputUnformattedBlock() for InquireIoLength";
-  }
-  ASSERT_EQ(IONAME(GetIoLength)(io), 3 * recl) << "GetIoLength";
-  ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-      << "EndIoStatement() for InquireIoLength";
-
   // INQUIRE(IOLENGTH=) j, ...
   StaticDescriptor<0> staticDescriptor;
   Descriptor &desc{staticDescriptor.descriptor()};
@@ -200,11 +195,10 @@ TEST(ExternalIOTests, TestSequentialFixedUnformatted) {
     // DO J=1,RECORDS; WRITE(UNIT=unit) j; END DO
     io = IONAME(BeginUnformattedOutput)(unit, __FILE__, __LINE__);
     buffer = j;
-    ASSERT_TRUE(IONAME(OutputUnformattedBlock)(
-        io, reinterpret_cast<const char *>(&buffer), recl, recl))
-        << "OutputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(OutputDescriptor)(io, desc))
+        << "OutputDescriptor() for Write";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for OutputUnformattedBlock";
+        << "EndIoStatement() for WRITE";
   }
 
   // REWIND(UNIT=unit)
@@ -215,11 +209,10 @@ TEST(ExternalIOTests, TestSequentialFixedUnformatted) {
   for (int j{1}; j <= records; ++j) {
     // DO J=1,RECORDS; READ(UNIT=unit) n; check n; END DO
     io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
-    ASSERT_TRUE(IONAME(InputUnformattedBlock)(
-        io, reinterpret_cast<char *>(&buffer), recl, recl))
-        << "InputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(InputDescriptor)(io, desc))
+        << "InputDescriptor() for Read";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for InputUnformattedBlock";
+        << "EndIoStatement() for Read";
     ASSERT_EQ(buffer, j) << "Read back " << buffer
                          << " from sequential fixed unformatted record " << j
                          << ", expected " << j << '\n';
@@ -232,11 +225,10 @@ TEST(ExternalIOTests, TestSequentialFixedUnformatted) {
         << "EndIoStatement() for Backspace (before read)";
     // READ(UNIT=unit) n
     io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
-    ASSERT_TRUE(IONAME(InputUnformattedBlock)(
-        io, reinterpret_cast<char *>(&buffer), recl, recl))
-        << "InputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(InputDescriptor)(io, desc))
+        << "InputDescriptor() for Read";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for InputUnformattedBlock";
+        << "EndIoStatement() for Read";
     ASSERT_EQ(buffer, j) << "Read back " << buffer
                          << " from sequential fixed unformatted record " << j
                          << " after backspacing, expected " << j << '\n';
@@ -275,15 +267,18 @@ TEST(ExternalIOTests, TestSequentialVariableUnformatted) {
     buffer[j] = j;
   }
 
+  StaticDescriptor<0> staticDescriptor;
+  Descriptor &desc{staticDescriptor.descriptor()};
+
   for (int j{1}; j <= records; ++j) {
     // DO J=1,RECORDS; WRITE(UNIT=unit) BUFFER(0:j); END DO
     io = IONAME(BeginUnformattedOutput)(unit, __FILE__, __LINE__);
-    ASSERT_TRUE(IONAME(OutputUnformattedBlock)(io,
-        reinterpret_cast<const char *>(&buffer), j * sizeof *buffer,
-        sizeof *buffer))
-        << "OutputUnformattedBlock()";
+    desc.Establish(TypeCode{sizeof *buffer}, j * sizeof *buffer, buffer, 0);
+    desc.Check();
+    ASSERT_TRUE(IONAME(OutputDescriptor)(io, desc))
+        << "OutputDescriptor() for Write";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for OutputUnformattedBlock";
+        << "EndIoStatement() for Write";
   }
 
   // REWIND(UNIT=unit)
@@ -293,11 +288,12 @@ TEST(ExternalIOTests, TestSequentialVariableUnformatted) {
   for (int j{1}; j <= records; ++j) {
     // DO J=1,RECORDS; READ(UNIT=unit) n; check n; END DO
     io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
-    ASSERT_TRUE(IONAME(InputUnformattedBlock)(io,
-        reinterpret_cast<char *>(&buffer), j * sizeof *buffer, sizeof *buffer))
-        << "InputUnformattedBlock()";
+    desc.Establish(TypeCode{sizeof *buffer}, j * sizeof *buffer, buffer, 0);
+    desc.Check();
+    ASSERT_TRUE(IONAME(InputDescriptor)(io, desc))
+        << "InputDescriptor() for Read";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for InputUnformattedBlock";
+        << "EndIoStatement() for Read";
     for (int k{0}; k < j; ++k) {
       ASSERT_EQ(buffer[k], k) << "Read back [" << k << "]=" << buffer[k]
                               << " from direct unformatted record " << j
@@ -312,9 +308,9 @@ TEST(ExternalIOTests, TestSequentialVariableUnformatted) {
         << "EndIoStatement() for Backspace (before read)";
     // READ(unit=unit) n; check
     io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
-    ASSERT_TRUE(IONAME(InputUnformattedBlock)(io,
-        reinterpret_cast<char *>(&buffer), j * sizeof *buffer, sizeof *buffer))
-        << "InputUnformattedBlock()";
+    desc.Establish(TypeCode{sizeof *buffer}, j * sizeof *buffer, buffer, 0);
+    desc.Check();
+    ASSERT_TRUE(IONAME(InputDescriptor)(io, desc)) << "InputDescriptor()";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
         << "EndIoStatement() for InputUnformattedBlock";
     for (int k{0}; k < j; ++k) {

@llvmbot
Copy link
Member

llvmbot commented Nov 21, 2023

@llvm/pr-subscribers-flang-runtime

Author: None (kkwli)

Changes

OutputUnformattedBlock and InputUnformattedBlock are not used.


Full diff: https://github.com/llvm/llvm-project/pull/73004.diff

4 Files Affected:

  • (modified) flang/include/flang/Runtime/io-api.h (-5)
  • (modified) flang/lib/Lower/IO.cpp (+7-8)
  • (modified) flang/runtime/io-api.cpp (-33)
  • (modified) flang/unittests/Runtime/ExternalIOTest.cpp (+50-54)
diff --git a/flang/include/flang/Runtime/io-api.h b/flang/include/flang/Runtime/io-api.h
index e298ab4c53d4ae5..41574e3bb80ad3b 100644
--- a/flang/include/flang/Runtime/io-api.h
+++ b/flang/include/flang/Runtime/io-api.h
@@ -244,11 +244,6 @@ bool IONAME(SetSign)(Cookie, const char *, std::size_t);
 // and avoid the following items when they might crash.
 bool IONAME(OutputDescriptor)(Cookie, const Descriptor &);
 bool IONAME(InputDescriptor)(Cookie, const Descriptor &);
-// Contiguous transfers for unformatted I/O
-bool IONAME(OutputUnformattedBlock)(
-    Cookie, const char *, std::size_t, std::size_t elementBytes);
-bool IONAME(InputUnformattedBlock)(
-    Cookie, char *, std::size_t, std::size_t elementBytes);
 // Formatted (including list directed) I/O data items
 bool IONAME(OutputInteger8)(Cookie, std::int8_t);
 bool IONAME(OutputInteger16)(Cookie, std::int16_t);
diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp
index 94135bb570ffbc1..4186d6158fb1d04 100644
--- a/flang/lib/Lower/IO.cpp
+++ b/flang/lib/Lower/IO.cpp
@@ -101,20 +101,19 @@ static constexpr std::tuple<
     mkIOKey(InputAscii), mkIOKey(InputComplex32), mkIOKey(InputComplex64),
     mkIOKey(InputDerivedType), mkIOKey(InputDescriptor), mkIOKey(InputInteger),
     mkIOKey(InputLogical), mkIOKey(InputNamelist), mkIOKey(InputReal32),
-    mkIOKey(InputReal64), mkIOKey(InputUnformattedBlock),
-    mkIOKey(InquireCharacter), mkIOKey(InquireInteger64),
+    mkIOKey(InputReal64), mkIOKey(InquireCharacter), mkIOKey(InquireInteger64),
     mkIOKey(InquireLogical), mkIOKey(InquirePendingId), mkIOKey(OutputAscii),
     mkIOKey(OutputComplex32), mkIOKey(OutputComplex64),
     mkIOKey(OutputDerivedType), mkIOKey(OutputDescriptor),
     mkIOKey(OutputInteger8), mkIOKey(OutputInteger16), mkIOKey(OutputInteger32),
     mkIOKey(OutputInteger64), mkIOKey(OutputInteger128), mkIOKey(OutputLogical),
     mkIOKey(OutputNamelist), mkIOKey(OutputReal32), mkIOKey(OutputReal64),
-    mkIOKey(OutputUnformattedBlock), mkIOKey(SetAccess), mkIOKey(SetAction),
-    mkIOKey(SetAdvance), mkIOKey(SetAsynchronous), mkIOKey(SetBlank),
-    mkIOKey(SetCarriagecontrol), mkIOKey(SetConvert), mkIOKey(SetDecimal),
-    mkIOKey(SetDelim), mkIOKey(SetEncoding), mkIOKey(SetFile), mkIOKey(SetForm),
-    mkIOKey(SetPad), mkIOKey(SetPos), mkIOKey(SetPosition), mkIOKey(SetRec),
-    mkIOKey(SetRecl), mkIOKey(SetRound), mkIOKey(SetSign), mkIOKey(SetStatus)>
+    mkIOKey(SetAccess), mkIOKey(SetAction), mkIOKey(SetAdvance),
+    mkIOKey(SetAsynchronous), mkIOKey(SetBlank), mkIOKey(SetCarriagecontrol),
+    mkIOKey(SetConvert), mkIOKey(SetDecimal), mkIOKey(SetDelim),
+    mkIOKey(SetEncoding), mkIOKey(SetFile), mkIOKey(SetForm), mkIOKey(SetPad),
+    mkIOKey(SetPos), mkIOKey(SetPosition), mkIOKey(SetRec), mkIOKey(SetRecl),
+    mkIOKey(SetRound), mkIOKey(SetSign), mkIOKey(SetStatus)>
     newIOTable;
 } // namespace Fortran::lower
 
diff --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp
index 2fc530c7431a50d..9a69a262464123c 100644
--- a/flang/runtime/io-api.cpp
+++ b/flang/runtime/io-api.cpp
@@ -1135,39 +1135,6 @@ bool IONAME(InputDescriptor)(Cookie cookie, const Descriptor &descriptor) {
   return descr::DescriptorIO<Direction::Input>(*cookie, descriptor);
 }
 
-bool IONAME(OutputUnformattedBlock)(Cookie cookie, const char *x,
-    std::size_t length, std::size_t elementBytes) {
-  IoStatementState &io{*cookie};
-  if (auto *unf{io.get_if<
-          ExternalUnformattedIoStatementState<Direction::Output>>()}) {
-    return unf->Emit(x, length, elementBytes);
-  } else if (auto *inq{io.get_if<InquireIOLengthState>()}) {
-    return inq->Emit(x, length, elementBytes);
-  } else if (!io.get_if<ErroneousIoStatementState>()) {
-    io.GetIoErrorHandler().Crash("OutputUnformattedBlock() called for an I/O "
-                                 "statement that is not unformatted output");
-  }
-  return false;
-}
-
-bool IONAME(InputUnformattedBlock)(
-    Cookie cookie, char *x, std::size_t length, std::size_t elementBytes) {
-  IoStatementState &io{*cookie};
-  IoErrorHandler &handler{io.GetIoErrorHandler()};
-  io.BeginReadingRecord();
-  if (handler.InError()) {
-    return false;
-  }
-  if (auto *unf{
-          io.get_if<ExternalUnformattedIoStatementState<Direction::Input>>()}) {
-    return unf->Receive(x, length, elementBytes);
-  } else if (!io.get_if<ErroneousIoStatementState>()) {
-    handler.Crash("InputUnformattedBlock() called for an I/O statement that is "
-                  "not unformatted input");
-  }
-  return false;
-}
-
 bool IONAME(OutputInteger8)(Cookie cookie, std::int8_t n) {
   if (!cookie->CheckFormattedStmtType<Direction::Output>("OutputInteger8")) {
     return false;
diff --git a/flang/unittests/Runtime/ExternalIOTest.cpp b/flang/unittests/Runtime/ExternalIOTest.cpp
index 4f08505f05d0ad4..76fdb6cb68ae952 100644
--- a/flang/unittests/Runtime/ExternalIOTest.cpp
+++ b/flang/unittests/Runtime/ExternalIOTest.cpp
@@ -43,11 +43,15 @@ TEST(ExternalIOTests, TestDirectUnformatted) {
   ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
       << "EndIoStatement() for OpenNewUnit";
 
+  StaticDescriptor<0> staticDescriptor;
+  Descriptor &desc{staticDescriptor.descriptor()};
+  desc.Establish(TypeCode{CFI_type_int8_t}, recl, &buffer, 0);
+  desc.Check();
+
   // INQUIRE(IOLENGTH=) j
   io = IONAME(BeginInquireIoLength)(__FILE__, __LINE__);
-  ASSERT_TRUE(IONAME(OutputUnformattedBlock)(
-      io, reinterpret_cast<const char *>(&buffer), recl, 1))
-      << "OutputUnformattedBlock() for InquireIoLength";
+  ASSERT_TRUE(IONAME(OutputDescriptor)(io, desc))
+      << "OutputDescriptor() for InquireIoLength";
   ASSERT_EQ(IONAME(GetIoLength)(io), recl) << "GetIoLength";
   ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
       << "EndIoStatement() for InquireIoLength";
@@ -59,24 +63,23 @@ TEST(ExternalIOTests, TestDirectUnformatted) {
     ASSERT_TRUE(IONAME(SetRec)(io, j)) << "SetRec(" << j << ')';
 
     buffer = j;
-    ASSERT_TRUE(IONAME(OutputUnformattedBlock)(
-        io, reinterpret_cast<const char *>(&buffer), 1, recl))
-        << "OutputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(OutputDescriptor)(io, desc))
+        << "OutputDescriptor() for Write";
 
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for OutputUnformattedBlock";
+        << "EndIoStatement() for Write";
   }
 
   for (int j{records}; j >= 1; --j) {
+    buffer = -1;
     // READ(UNIT=unit,REC=j) n
     io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
     ASSERT_TRUE(IONAME(SetRec)(io, j)) << "SetRec(" << j << ')';
-    ASSERT_TRUE(IONAME(InputUnformattedBlock)(
-        io, reinterpret_cast<char *>(&buffer), 1, recl))
-        << "InputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(InputDescriptor)(io, desc))
+        << "InputDescriptor() for Read";
 
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for InputUnformattedBlock";
+        << "EndIoStatement() for Read";
 
     ASSERT_EQ(buffer, j) << "Read back " << buffer
                          << " from direct unformatted record " << j
@@ -108,17 +111,21 @@ TEST(ExternalIOTests, TestDirectUnformattedSwapped) {
   ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
       << "EndIoStatement() for OpenNewUnit";
 
+  StaticDescriptor<0> staticDescriptor;
+  Descriptor &desc{staticDescriptor.descriptor()};
+  desc.Establish(TypeCode{CFI_type_int64_t}, recl, &buffer, 0);
+  desc.Check();
+
   static constexpr int records{10};
   for (int j{1}; j <= records; ++j) {
     // WRITE(UNIT=unit,REC=j) j
     io = IONAME(BeginUnformattedOutput)(unit, __FILE__, __LINE__);
     ASSERT_TRUE(IONAME(SetRec)(io, j)) << "SetRec(" << j << ')';
     buffer = j;
-    ASSERT_TRUE(IONAME(OutputUnformattedBlock)(
-        io, reinterpret_cast<const char *>(&buffer), recl, recl))
-        << "OutputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(OutputDescriptor)(io, desc))
+        << "OutputDescriptor() for Write";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for OutputUnformattedBlock";
+        << "EndIoStatement() for Write";
   }
 
   // OPEN(UNIT=unit,STATUS='OLD',CONVERT='SWAP')
@@ -132,11 +139,10 @@ TEST(ExternalIOTests, TestDirectUnformattedSwapped) {
     // READ(UNIT=unit,REC=j) n
     io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
     ASSERT_TRUE(IONAME(SetRec)(io, j)) << "SetRec(" << j << ')';
-    ASSERT_TRUE(IONAME(InputUnformattedBlock)(
-        io, reinterpret_cast<char *>(&buffer), recl, recl))
-        << "InputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(InputDescriptor)(io, desc))
+        << "InputDescriptor() for Read";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for InputUnformattedBlock";
+        << "EndIoStatement() for Read";
     ASSERT_EQ(buffer >> 56, j)
         << "Read back " << (buffer >> 56) << " from direct unformatted record "
         << j << ", expected " << j << '\n';
@@ -169,17 +175,6 @@ TEST(ExternalIOTests, TestSequentialFixedUnformatted) {
   ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
       << "EndIoStatement() for OpenNewUnit";
 
-  // INQUIRE(IOLENGTH=) j, ...
-  io = IONAME(BeginInquireIoLength)(__FILE__, __LINE__);
-  for (int j{1}; j <= 3; ++j) {
-    ASSERT_TRUE(IONAME(OutputUnformattedBlock)(
-        io, reinterpret_cast<const char *>(&buffer), recl, 1))
-        << "OutputUnformattedBlock() for InquireIoLength";
-  }
-  ASSERT_EQ(IONAME(GetIoLength)(io), 3 * recl) << "GetIoLength";
-  ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-      << "EndIoStatement() for InquireIoLength";
-
   // INQUIRE(IOLENGTH=) j, ...
   StaticDescriptor<0> staticDescriptor;
   Descriptor &desc{staticDescriptor.descriptor()};
@@ -200,11 +195,10 @@ TEST(ExternalIOTests, TestSequentialFixedUnformatted) {
     // DO J=1,RECORDS; WRITE(UNIT=unit) j; END DO
     io = IONAME(BeginUnformattedOutput)(unit, __FILE__, __LINE__);
     buffer = j;
-    ASSERT_TRUE(IONAME(OutputUnformattedBlock)(
-        io, reinterpret_cast<const char *>(&buffer), recl, recl))
-        << "OutputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(OutputDescriptor)(io, desc))
+        << "OutputDescriptor() for Write";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for OutputUnformattedBlock";
+        << "EndIoStatement() for WRITE";
   }
 
   // REWIND(UNIT=unit)
@@ -215,11 +209,10 @@ TEST(ExternalIOTests, TestSequentialFixedUnformatted) {
   for (int j{1}; j <= records; ++j) {
     // DO J=1,RECORDS; READ(UNIT=unit) n; check n; END DO
     io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
-    ASSERT_TRUE(IONAME(InputUnformattedBlock)(
-        io, reinterpret_cast<char *>(&buffer), recl, recl))
-        << "InputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(InputDescriptor)(io, desc))
+        << "InputDescriptor() for Read";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for InputUnformattedBlock";
+        << "EndIoStatement() for Read";
     ASSERT_EQ(buffer, j) << "Read back " << buffer
                          << " from sequential fixed unformatted record " << j
                          << ", expected " << j << '\n';
@@ -232,11 +225,10 @@ TEST(ExternalIOTests, TestSequentialFixedUnformatted) {
         << "EndIoStatement() for Backspace (before read)";
     // READ(UNIT=unit) n
     io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
-    ASSERT_TRUE(IONAME(InputUnformattedBlock)(
-        io, reinterpret_cast<char *>(&buffer), recl, recl))
-        << "InputUnformattedBlock()";
+    ASSERT_TRUE(IONAME(InputDescriptor)(io, desc))
+        << "InputDescriptor() for Read";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for InputUnformattedBlock";
+        << "EndIoStatement() for Read";
     ASSERT_EQ(buffer, j) << "Read back " << buffer
                          << " from sequential fixed unformatted record " << j
                          << " after backspacing, expected " << j << '\n';
@@ -275,15 +267,18 @@ TEST(ExternalIOTests, TestSequentialVariableUnformatted) {
     buffer[j] = j;
   }
 
+  StaticDescriptor<0> staticDescriptor;
+  Descriptor &desc{staticDescriptor.descriptor()};
+
   for (int j{1}; j <= records; ++j) {
     // DO J=1,RECORDS; WRITE(UNIT=unit) BUFFER(0:j); END DO
     io = IONAME(BeginUnformattedOutput)(unit, __FILE__, __LINE__);
-    ASSERT_TRUE(IONAME(OutputUnformattedBlock)(io,
-        reinterpret_cast<const char *>(&buffer), j * sizeof *buffer,
-        sizeof *buffer))
-        << "OutputUnformattedBlock()";
+    desc.Establish(TypeCode{sizeof *buffer}, j * sizeof *buffer, buffer, 0);
+    desc.Check();
+    ASSERT_TRUE(IONAME(OutputDescriptor)(io, desc))
+        << "OutputDescriptor() for Write";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for OutputUnformattedBlock";
+        << "EndIoStatement() for Write";
   }
 
   // REWIND(UNIT=unit)
@@ -293,11 +288,12 @@ TEST(ExternalIOTests, TestSequentialVariableUnformatted) {
   for (int j{1}; j <= records; ++j) {
     // DO J=1,RECORDS; READ(UNIT=unit) n; check n; END DO
     io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
-    ASSERT_TRUE(IONAME(InputUnformattedBlock)(io,
-        reinterpret_cast<char *>(&buffer), j * sizeof *buffer, sizeof *buffer))
-        << "InputUnformattedBlock()";
+    desc.Establish(TypeCode{sizeof *buffer}, j * sizeof *buffer, buffer, 0);
+    desc.Check();
+    ASSERT_TRUE(IONAME(InputDescriptor)(io, desc))
+        << "InputDescriptor() for Read";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-        << "EndIoStatement() for InputUnformattedBlock";
+        << "EndIoStatement() for Read";
     for (int k{0}; k < j; ++k) {
       ASSERT_EQ(buffer[k], k) << "Read back [" << k << "]=" << buffer[k]
                               << " from direct unformatted record " << j
@@ -312,9 +308,9 @@ TEST(ExternalIOTests, TestSequentialVariableUnformatted) {
         << "EndIoStatement() for Backspace (before read)";
     // READ(unit=unit) n; check
     io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
-    ASSERT_TRUE(IONAME(InputUnformattedBlock)(io,
-        reinterpret_cast<char *>(&buffer), j * sizeof *buffer, sizeof *buffer))
-        << "InputUnformattedBlock()";
+    desc.Establish(TypeCode{sizeof *buffer}, j * sizeof *buffer, buffer, 0);
+    desc.Check();
+    ASSERT_TRUE(IONAME(InputDescriptor)(io, desc)) << "InputDescriptor()";
     ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
         << "EndIoStatement() for InputUnformattedBlock";
     for (int k{0}; k < j; ++k) {

Copy link
Contributor

@vdonaldson vdonaldson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me; less is more. Peter can comment if we should really be attempting to use these calls.

@kkwli kkwli merged commit 8cf6e94 into llvm:main Nov 21, 2023
@kkwli kkwli deleted the remove-io-unformatted-block branch November 21, 2023 21:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang:runtime flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants