Commit Graph

404 Commits

Author SHA1 Message Date
Peter Steinfeld ebe24a2a31 [flang] Change "unsupported" messages in the runtime to "not yet implemented"
If a programmer is able to compile and link a program that contains types that
are not yet supported by the runtime, it must be because they're not yet
implemented.

This change will make it easier to find unimplemented code in tests.

Differential Revision: https://reviews.llvm.org/D125046
2022-05-05 15:20:01 -07:00
Jean Perier b910cf986a [flang] use 1-based dim in transformational runtime error msg
Flang transformational runtime was previously reporting conformity
issues in a zero based fashion to describe which dimension is non
conformant. This may confuse Fortran user, especially when the message
is about a dimension other than the first one.

Differential Revision: https://reviews.llvm.org/D124941
2022-05-05 10:33:14 +02:00
Peter Klausler 53f775bbc0 [flang][runtime] Support B/O/Z editing of CHARACTER
This is a common extension, though semantics differ across
compilers.  I've chosen to interpret the CHARACTER data
as if it were an arbitrary-precision integer value and
format or read it as such.  This matches Intel's compilers
and nvfortran.  (GNU Fortran can't handle lengths > 1 and XLF
seems to get the enddianness wrong.)

This patch generalizes the previous implementations of
B/O/Z input and output so that they'll work for arbitrary data
in memory, and then uses them for all B/O/Z input/output,
including (now) CHARACTER.

Differential Revision: https://reviews.llvm.org/D124547
2022-04-28 12:44:31 -07:00
Peter Klausler 36771bbad1 [flang][runtime] Correct emission & reading of unterminated final records
When the last operation on a foramtted sequential or stream file (prior
to an implied or explicit ENDFILE) is a non-advancing WRITE, ensure
that any partial record data is emitted to the file without a line
terminator.  Further, when that last record is read with a non-advancing
READ, ensure that it won't raise an end-of-record condition after its
data, but instead will signal an end-of-file.

Differential Revision: https://reviews.llvm.org/D124546
2022-04-28 09:22:07 -07:00
Peter Steinfeld 9df99d8ac2 [flang] Fix MAXLOC/MINLOC when MASK is scalar .FALSE.
When passing a scalar .FALSE. as the MASK argument to MAXLOC, we were getting
bad memory references.  We were falling into the code intended when the MASK
argument was missing.

I fixed this by checking for a scalar MASK with a .FALSE. value and
setting the result to all zeroes in that case.  I also added tests for
MAXLOC and MINLOC with scalar values of .TRUE. and .FALSE. for the MASK
argument.

I also special cased situations where the MASK argument is a scalar with
a .TRUE. value and passed along a nullptr in such cases.

Along the way, I eliminated the unused "chars" argument from the constructor
for ExtremumLocAccumulator.

Differential Revision: https://reviews.llvm.org/D124484
2022-04-27 14:50:00 -07:00
Peter Klausler 2c272a4e8f [flang][runtime] Fix total MAXLOC/MINLOC for non-integer data
A template argument was hard-coded as the Integer type category
rather than properly forwarding the type category of the data for
type-specific instantiations of total (no DIM=) MAXLOC and MINLOC.
This broke total MAXLOC and MINLOC reductions for real and character
data.

Differential Revision: https://reviews.llvm.org/D124303
2022-04-25 12:42:20 -07:00
Peter Klausler 6bcdde2334 [flang][runtime] Fix KIND=16 real/complex component I/O
Don't treat KIND=16 as 80-bit extended floating-point any more on x86.

Differential Revision: https://reviews.llvm.org/D124400
2022-04-25 11:18:21 -07:00
Andrzej Warzynski 97a32d3e43 [flang][driver] Add support for generating executables
This patch adds 2 missing items required for `flang-new` to be able to
generate executables:

1. The Fortran_main runtime library, which implements the main entry
   point into Fortran's `PROGRAM` in Flang,

2. Extra linker flags to include Fortran runtime libraries (e.g.
   Fortran_main).

Fortran_main is the bridge between object files generated by Flang and
the C runtime that takes care of program set-up at system-level. For
every Fortran `PROGRAM`, Flang generates the `_QQmain` function.
Fortran_main implements the C `main` function that simply calls
`_QQmain`.

Additionally, "<driver-path>/../lib" directory is added to the list of
search directories for libraries. This is where the required runtime
libraries are currently located. Note that this the case for the build
directory. We haven't considered installation directories/targets yet.

With this change, you can generate an executable that will print `hello,
world!` as follows:

```bash
$ cat hello.f95
PROGRAM HELLO
  write(*, *) "hello, world!"
END PROGRAM HELLO
$ flang-new -flang-experimental-exec hello.f95
./a.out
hello, world!
```

NOTE 1: Fortran_main has to be a static library at all times. It invokes
`_QQmain`, which is the main entry point generated by Flang for the
given input file (you can check this with `flang-new -S hello.f95 -o - |
grep "Qmain"`). This means that Fortran_main has an unresolved
dependency at build time. The linker will allow this for a static
library. However, if Fortran_main was a shared object, then the linker
will produce an error: `undefined symbol: `_QQmain`.

NOTE 2: When Fortran runtime libraries are generated as shared libraries
(excluding Fortran_main, which is always static), you will need to
tell the dynamic linker (by e.g. tweaking LD_LIBRARY_PATH) where to look
for them when invoking the executables. For example:
```bash
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:<flang-build-dir>/lib/ ./a.out
```

NOTE 3: This feature is considered experimental and currently guarded
with a flag: `-flang-experimental-exec`.

Differential Revision: https://reviews.llvm.org/D122008

[1] https://github.com/flang-compiler/f18-llvm-project

CREDITS: Fortran_main was originally written by Eric Schweitz, Jean
Perier, Peter Klausler and Steve Scalpone in the fir-dev` branch in [1].

Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
Co-authored-by: Peter Klausler <pklausler@nvidia.com>
Co-authored-by: Jean Perier <jperier@nvidia.com>
Co-authored-by: Steve Scalpone <sscalpone@nvidia.com
2022-04-25 12:00:23 +00:00
Peter Klausler aac6e25f7d [flang][runtime] Signal record read overrun when PAD='NO'
When PAD='NO' and ADVANCE='YES', we currently signal an input
error when a formatted read tries to go past the end of a record
only when a fixed RECL= is in effect.  Other compilers will signal
an error without RECL= too, and that seems like a precedent we
should follow.

Differential Revision: https://reviews.llvm.org/D124301
2022-04-22 16:52:05 -07:00
Peter Klausler c02abb68cd [flang][runtime] Enforce some limits on kP scale factors
Ew.d and Dw.d output edit descriptors should respect limitations from
the standard on the value of a kP scale factor with respect to the
digit count (d), at least for values of k other than zero.

Differential Revision: https://reviews.llvm.org/D124300
2022-04-22 16:51:36 -07:00
Peter Klausler f1dbf8e4ad [flang][runtime] Fix edge-case FP input bugs
Blanks are allowed in more places than I allowed for, and
"NAN(foobar)" is allowed to have any parenthesis-balanced
characters in parentheses.

Update: Fix up old sanity test, then avoid usage of "limit" when null.

Differential Revision: https://reviews.llvm.org/D124294
2022-04-22 16:12:04 -07:00
Peter Klausler 839f0abdaa [flang][runtime] Accept "." as REAL input
".", possibly followed by an exponent, is a valid REAL input value (meaning zero).

Differential Revision: https://reviews.llvm.org/D124279
2022-04-22 12:38:07 -07:00
Peter Klausler cbbc662900 [flang][runtime] Ignore leading spaces even in BZ mode
When editing numeric input, always skip leading spaces, even if
BZ mode (or BLANK='ZERO') is in effect; otherwise, a sign character
preceded by blanks will not be recognized.

Differential Revision: https://reviews.llvm.org/D124278
2022-04-22 12:27:19 -07:00
Peter Klausler cd03e96f00 [flang] Add & use a better visit() (take 2)
Adds flang/include/flang/Common/log2-visit.h, which defines
a Fortran::common::visit() template function that is a drop-in
replacement for std::visit().  Modifies most use sites in
the front-end and runtime to use common::visit().

The C++ standard mandates that std::visit() have O(1) execution
time, which forces implementations to build dispatch tables.
This new common::visit() is O(log2 N) in the number of alternatives
in a variant<>, but that N tends to be small and so this change
produces a fairly significant improvement in compiler build
memory requirements, a 5-10% improvement in compiler build time,
and a small improvement in compiler execution time.

Building with -DFLANG_USE_STD_VISIT causes common::visit()
to be an alias for std::visit().

Calls to common::visit() with multiple variant arguments
are referred to std::visit(), pending further work.

This change is enabled only for GCC builds with GCC >= 9;
an earlier attempt (D122441) ran into bugs in some versions of
clang and was reverted rather than simply disabled; and it is
not well tested with MSVC. In non-GCC and older GCC builds,
common::visit() is simply an alias for std::visit().
2022-04-16 16:00:48 -07:00
Peter Klausler 1fe7a187ae [flang][runtime] Don't emit empty lines for bad writes
When an error occurs in a formatted sequential output statement
and no output was ever emitted, don't emit a blank record.
This matches the error case behavior of other Fortran compilers.

Differential Revision: https://reviews.llvm.org/D123734
2022-04-15 20:32:32 -07:00
Peter Klausler 64aff3632f [flang][runtime] Fix ENDFILE for formatted stream output
A predicate expression made ENDFILE statements significant
only for sequential files, but it's applicable to formatted
stream output as well.

Differential Revision: https://reviews.llvm.org/D123730
2022-04-15 18:57:29 -07:00
Peter Klausler e6873bfbcd [flang][runtime] Don't skip input spaces when they are significant
When formatted input (not list-directed or NAMELIST) is in "BZ" mode,
either because a BZ control edit descriptor appeared in a FORMAT or
BLANK="ZERO" appeared in OPEN or READ, input editing must not skip
over blanks before or within the input field.

Differential Revision: https://reviews.llvm.org/D123725
2022-04-14 21:30:43 -07:00
Peter Klausler a68612a964 [flang][runtime] Preserve effect of positioning in record in non-advancing output
When formatted non-advancing output ends in a control edit descriptor
like nX or Tn or TRn that effectively extends the record, fill any
gap with explicit blanks at the completion of the WRITE.

Differential Revision: https://reviews.llvm.org/D123716
2022-04-14 15:33:15 -07:00
Peter Klausler 724709e09d [flang] Make F0.1 output editing of zero edge case consistent
The statement
  PRINT '(2F0.1)', 0.0, 0.5
should emit consistent ".0 .5" output, not "0.0 .5".

Differential Revision: https://reviews.llvm.org/D123715
2022-04-14 15:31:47 -07:00
Peter Klausler de026aeb8e [flang] Raise FP exceptions from runtime conversion to binary
Formatted READs of REAL should convert the exception flags from
the decimal-to-binary conversion library into real runtime FP
exceptions so that they at least show up in the termination message
of a STOP statement.

Differential Revision: https://reviews.llvm.org/D123714
2022-04-14 14:49:36 -07:00
V Donaldson 96e45a8958 [flang] Use full result range for clock_gettime implementation of SYSTEM_CLOCK
Update the primary clock_gettime implementation of SYSTEM_CLOCK to use
the full range of values, dependent on the type kind of the requested
result.  Counts/sec and count max for supported kinds become:

 kind          counts/sec             count max

    1                  10                   127
    2                1000                 32767
    4                1000            2147483647
    8          1000000000   9223372036854775807
   16          1000000000   9223372036854775807

The secondary "fallback" implementation is not changed.

Real valued COUNT_RATE arguments are not changed.

The test program below has calls for kinds 1, 2, 4, 8, 16.  Support for
these types varies by compiler.  The code as given can be restricted to
accommodate these variations, with results shown below.

subroutine c
  integer(1) c1, r1, m1
  integer(2) c2, r2, m2
  integer(4) c4, r4, m4
  integer(8) c8, r8, m8
  integer(16) c16, r16, m16

  print*
  print '(a5,3a22)', 'kind', 'counts/sec', 'count max', 'count'
  print*

  call system_clock(c1, r1, m1)
  print '(i5,3i22)', 1, r1, m1, c1

  call system_clock(c2, r2, m2)
  print '(i5,3i22)', 2, r2, m2, c2

  call system_clock(c4, r4, m4)
  print '(i5,3i22)', 4, r4, m4, c4

  call system_clock(c8, r8, m8)
  print '(i5,3i22)', 8, r8, m8, c8

  call system_clock(c16, r16, m16)
  print '(i5,3i22)', 16, r16, m16, c16
end

subroutine k(j)
  j = 0
  do i=1,1000000000
    j = j + i
  enddo
end

program p
  do i=1,1 ! increase loop count to check for (kind=1) wraparound
    call k(j)
    call c
  enddo
end

=== flang output without change (last column counts vary per run) ===

 kind          counts/sec             count max                 count

    1                 -24                   127                    83
    2                1000                   290                   211
    4                1000                   290                   211
    8          1000000000             290448383             211631452
   16          1000000000             290448383             211633853

=== flang output with change (last column counts vary per run) ===

    1                  10                   127                    21
    2                1000                 32767                  2100
    4                1000            2147483647                  2100
    8          1000000000   9223372036854775807            2100183374
   16          1000000000   9223372036854775807            2100185353

Other compilers; kind support varies (last column counts vary per run).
Test and ouput modified to avoid crashes and normalize results.
Some negative values indicate unsupported kinds; others are bugs.

 kind          counts/sec             count max                 count

    1                   0                     0                  -127
    2                   0                     0                -32767
    4                1000            2147483647              69271692
    8          1000000000   9223372036854775807        69271692353290
   16          1000000000   9223372036854775807        69271692354794

=======

    1                  10                   127                     0
    2                1000                 32767                     0
    4             1000000            2147483647                     0
    8            10000000   9223372036854775807                     9

=======

    1                   0                     0                  -127
    2                1000                 32767                  3263
    4               10000            2147483647            1788192630
    8             1000000   9223372036854775807      1649443459263095

=======

    1                 -24                    -1                    36
    2                1000                    -1                -10716
    4                1000            2147483647             176018980
    8                1000   9223372036854775807         1649443460644

=======

    2                 100                 28799                 23080
    4                 100               8639999               4285480
    8                 100               8639999               4285480
   16                 100               8639999               4285480

=======

    1                 -24                    -1                     4
    2                1000                 23551                -26108
    4                1000              86399999              67541508
    8             1000000   9223372036854775807      1649443541508087
2022-04-14 13:01:32 -07:00
Peter Klausler 664c111c95 [flang] Always encode multi-byte output in UTF-8
A recent change to implement UTF-8 encoding should have
made the encoding conditional only for CHARACTER(KIND=1)
to enable UTF-8 output vs. Latin-1 or whatever.  UTF-8 output
of wider CHARACTER kinds should not be conditional (until we choose
to support UCS-16, maybe).  So wider CHARACTER kinds are being
emitted with extra zero bytes; this patch fixes them.

Differential Revision: https://reviews.llvm.org/D123711
2022-04-14 11:13:51 -07:00
Peter Klausler d2b339f176 [flang] Respect left tab limit with Tn editing after ADVANCE='NO'
Correct the implementation of non-advancing I/O after some testing
to ensure that T tab edit descriptors are not allowed to back up
into positions of a record prior to where it stood at the beginning
of the I/O statement.

Differential Revision: https://reviews.llvm.org/D123709
2022-04-13 21:45:53 -07:00
Mats Petersson 3d0e0e1027 [flang][runtime] Prefer process time over thread time in CPU_TIME
Most Fortran compilers appear to return the process time
for calls to CPU_TIME, where the flang implementation
prior to this change was returning the time used by the
current thread. This would cause incorrect time being
reported when for example OpenMP is used to share work
across multiple CPUs.

This patch changes the order so the selection of "what
time to return" so that if there is a process time to
report, that is the reported value, and only if that is
not available, the thread time is considerd instead.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D123416
2022-04-11 10:44:33 +01:00
Jean Perier 9cfa899b87 [flang] add a static assert in CheckUnitNumberInRangeImpl
Add a check that CheckUnitNumberInRangeImpl is not needlessly instantiated.

Differential Revision: https://reviews.llvm.org/D123285
2022-04-11 09:32:52 +02:00
Jean Perier c58c64d05c [flang] Add runtime API to catch unit number out of range
Unit numbers must fit on a default integer. It is however possible that
the user provides the unit number in UNIT with a wider integer type.
In such case, lowering was previously silently narrowing
the value and passing the result to the BeginXXX runtime entry points.
Cases where the conversion caused overflow were not reported/caught.
Most existing compilers catch these errors and raise an IO error.
Add a CheckUnitNumberInRange runtime API to do the same in f18.

This runtime API has its own error management interface (i.e., does not
use GetIoMsg, EndIo, and EnableHandlers) because the usual error
management requires BeginXXX to be called to set up the error
management. But in this case, the BeginXXX cannot be called since
the bad unit number that would be provided to it overflew (and in the worst
case scenario, the narrowed value could point to a different valid unit
already in use). Hence I decided to make an API that must be called
before the BeginXXX and should trigger the whole BeginXXX/.../EndIoStatement
to be skipped in case the unit number is too big and the user enabled
error recovery.

Note that CheckUnitNumberInRange accepts negative numbers (as long as
they can fit on a default integer), because unit numbers may be negative
if they were created by NEWUNIT.

Differential Revision: https://reviews.llvm.org/D123157
2022-04-06 15:38:13 +02:00
Jean Perier 88d4b85f59 [flang] Allow user to recover from bad edit descriptor with INTEGER
Runtime was crashing when an INTEGER passed in formatted output with
a bad edit descriptor even when the user did provide IOSTAT. Flang
is already signaling an error when facing similar error with other
types. Do the same with INTEGERs.

The input case is already signaling an error in the related input error
case.

Differential Revision: https://reviews.llvm.org/D122749
2022-03-31 10:57:13 +02:00
serge-sans-paille c531171d99 Fix invalid overflow check in flang
Statically checking for overflow with

    if constexpr (sizeof(std::size_t) <= sizeof(std::int64_t)) {
         return static_cast<std::int64_t>(length);
    }

Doesn't work if `sizeof(std::size_t) == sizeof(std::int64_t)` because std::size_t
is unsigned.

if `length == std::numeric_limits<size_t>` casting it to `int64_t` is going to overflow.

This code would be much simpler if returning a `uint64_t` instead of a signed
value...

Differential Revision: https://reviews.llvm.org/D122705
2022-03-30 16:47:33 +02:00
Andrzej Warzynski 4ca111d4cb Revert "[flang] Add & use a better visit()"
This reverts commit 2ab9990c9e. It has
caused multiple build failures:
*  https://lab.llvm.org/buildbot/#/builders/177/builds/4346
*  https://lab.llvm.org/buildbot/#/builders/180/builds/3803
*  https://lab.llvm.org/buildbot/#/builders/175/builds/10419
*  https://lab.llvm.org/buildbot/#/builders/191/builds/4318
*  https://lab.llvm.org/buildbot/#/builders/173/builds/4274
*  https://lab.llvm.org/buildbot/#/builders/181/builds/4297

All these bots failed with a time-out:
```
command timed out: 1200 seconds without output running [b'ninja', b'-j', b'32'], attempting to kill
```
I'm guessing that that's due to template instantiations failing at some
point (https://reviews.llvm.org/D122441 introduced a custom
implementation of std::visit). Everything seems fine when either:
* building on X86 with GCC or Clang (tested with GCC 9.3 and Clang 12)
* building on AArch64 with GCC (tested with GCC 11)
2022-03-28 10:46:47 +00:00
Jean Perier 479eed1850 [flang][runtime] Ensure PointerDeallocate actually deallocate pointers
PointerDeallocate was silently doing nothing because it relied on
Destroy that doe not do anything for Pointers. Add an option to Destroy
in order to destroy pointers.

Add a unit test for PointerDeallocate.

Differential Revision: https://reviews.llvm.org/D122492
2022-03-28 10:22:08 +02:00
Peter Klausler 435641bc3d [flang] Catch bad OPEN(STATUS=) cases
STATUS='NEW' and 'REPLACE' require FILE= to be present.
STATUS='SCRATCH' may not appear with FILE=.

These errors are caught at compilation time when constant character
strings are used in an OPEN statement, but the runtime needs
to enforce them as well to catch errors in OPEN statements
with character variables and expressions.

Differential Revision: https://reviews.llvm.org/D122509
2022-03-25 18:24:50 -07:00
Peter Klausler 2ab9990c9e [flang] Add & use a better visit()
Adds flang/include/flang/Common/visit.h, which defines
a Fortran::common::visit() template function that is a drop-in
replacement for std::visit().  Modifies most use sites in
the front-end and runtime to use common::visit().

The C++ standard mandates that std::visit() have O(1) execution
time, which forces implementations to build dispatch tables.
This new common::visit() is O(log2 N) in the number of alternatives
in a variant<>, but that N tends to be small and so this change
produces a fairly significant improvement in compiler build
memory requirements, a 5-10% improvement in compiler build time,
and a small improvement in compiler execution time.

Building with -DFLANG_USE_STD_VISIT causes common::visit()
to be an alias for std::visit().

Calls to common::visit() with multiple variant arguments
are referred to std::visit(), pending further work.

Differential Revision: https://reviews.llvm.org/D122441
2022-03-25 13:15:20 -07:00
Peter Steinfeld df209b8038 [flang] Make not yet implemented messages more consistent
To make it easier to find things that are not yet implemented, I'm changing the
messages that appear in the compiler's output to all have the string "not yet
implemented:".

These changes apply to files in the front end.  I have another set of changes
to files in the lowering code.

Differential Revision: https://reviews.llvm.org/D122355
2022-03-24 15:19:40 -07:00
Peter Klausler bafbae238a [flang] Initial UTF-8 support in runtime I/O
Implements UTF-8 encoding and decoding for external units
with OPEN(ENCODING='UTF-8').  This encoding applies to default
CHARACTER values that are not 7-bit ASCII as well as to
the wide CHARACTER kinds 2 and 4.  Basic testing is in place
via direct calls to the runtime I/O APIs, but serious checkout
awaits lowering support of the wide CHARACTER kinds.

Differential Revision: https://reviews.llvm.org/D122038
2022-03-22 11:48:14 -07:00
Peter Klausler 461b6fe470 [flang] Expose error recovery cases in external I/O
Some I/O error situations are current handled with fatal
runtime asserts, but should be exposed for user program
error recovery.

Differential Revision: https://reviews.llvm.org/D122049
2022-03-21 12:46:16 -07:00
Peter Klausler 8db4dc8686 [flang] Error recovery improvement in runtime (IOMSG=)
Some refactoring and related fixes for more accurate
user program error recovery in the I/O runtime, especially
for error recovery with IOMSG= character values.

1) Move any work in an EndIoStatement() implementation
that may raise an error into a new CompleteOperation()
member function.  This allows error handling APIs like
GetIoMsg() to complete a pending I/O statement and harvest
any errors that may result.

2) Move the pending error code from ErroneousIoStatementState
to a new pendingError_ data member in IoErrorHandler.
This allows IoErrorHandler::InError() to return a correct
result when there is a pending error that will be recovered
from so that I/O list data transfers don't crash in the meantime.

3) Don't create and leak a unit for a failed OPEN(NEWUNIT=n)
with error recovery, and don't modify 'n'.  (Depends on
changes to API call ordering in lowering, in a separate patch;
code was added to ensure that OPEN statement control list
specifiers, e.g. SetFile(), must be passed before GetNewUnit().)

4) Fix the code that calls a form of strerror to fill an
IOMSG= variable so that it actually works for Fortran's
character type: blank fill with no null or newline termination.

Differential Revision: https://reviews.llvm.org/D122036
2022-03-18 17:24:32 -07:00
Peter Klausler 251d062e4e [flang] Convert RUNTIME_CHECK to better error for user errors in transformational.cpp
In flang/runtime/transformational.cpp, there are many RUNTIME_CHECK assertions
for errors that should have been caught in semantics, but there are alno others
that signify program errors that in principle cannot be detected until
execution.  Convert this second group into readable fatal error messages.
Also clean up some missing braces and incorrect printf formats found
along the way.

Differential Revision: https://reviews.llvm.org/D122037
2022-03-18 16:52:43 -07:00
Jean Perier a69cb78242 [flang] Hanlde COMPLEX 2/3/10 in runtime TypeCode(cat, kind)
Type codes for COMPLEX kinds 2, 3, and 10 were added in https://reviews.llvm.org/D117336
but handling for these kinds in TypeCode(cat, kind) has not been added
yet.

Differential Revision: https://reviews.llvm.org/D121587
2022-03-15 09:26:14 +01:00
Peter Klausler 3b61587c9e [flang] LBOUND() edge case: empty dimension
LBOUND must return 1 for an empty dimension, no matter what
explicit expression might appear in a declaration or arrive in
a descriptor.

Differential Revision: https://reviews.llvm.org/D121488
2022-03-14 11:16:09 -07:00
Diana Picus 873f081e5a [flang] Add runtime support for GET_COMMAND
Implement the GET_COMMAND intrinsic.
Add 2 new parameters (sourceFile and line) so we can create a terminator
for RUNTIME_CHECKs.

Differential Revision: https://reviews.llvm.org/D118777
2022-03-14 09:35:45 +00:00
Peter Steinfeld e3550f1903 [flang] Improve runtime crash messages
Where possible, I added additional information to the messages to help
programmers figure out what went wrong.  I also removed all uses of the word
"bad" from the messages since (to me) that implies a moral judgement rather
than a programming error.  I replaced it with either "invalid" or "unsupported"
where appropriate.

Differential Revision: https://reviews.llvm.org/D121493
2022-03-12 15:15:56 -08:00
Peter Klausler 041080fc9b [flang] Fix extent computation in finalization
The code that computed the extent of a dimension of a
non-allocatable/non-automatic component array during
finalization had a reversed subtraction; fix, and
use variables to make the code a little more readable.

Differential Revision: https://reviews.llvm.org/D121163
2022-03-09 09:01:02 -08:00
Peter Klausler 764363368c [flang] Runtime validation of SPREAD(DIM=dim) argument
Crash when DIM= is not a valid dimension in the result.

Differential Revision: https://reviews.llvm.org/D121145
2022-03-07 13:49:39 -08:00
Peter Klausler ef7f6f7cd7 [flang] Use faster path for default formatted character input
Rather than reading default character variables in formatted
input one byte at a time via NextInField(), skip and read
them via blocks of available buffer data.  This eliminates
a bottleneck that affected reads of large character values.
(It also exposed a problem with sequential reads with RECL=
set on the OPEN statement, so that's fixed too.)

Differential Revision: https://reviews.llvm.org/D121144
2022-03-07 13:01:08 -08:00
Jean Perier 392cba8603 [flang] Handle optional TARGET associate in ASSOCIATED runtime
The TARGET argument of ASSOCIATED may be dynamically optional, in which
case ASSOCIATED(POINTER, TARGET) is equal to ASSOCIATED(TARGET).

Make the runtime argument a pointer so that it can detect and handle
arguments that are dynamically optional.

Also fix the runtime to check if TARGET base address is not null and if
its element size is not null to match the requirement of ASSOCIATED
regarding TARGET:
- if TARGET is an object: true iff [..] TARGET is not a zerosized storage sequence
- if TARGET is a POINTER: true iff [..] POINTER and TARGET are associated

Not that ASSOCIATED will also returns false if TARGET is an unallocated allocatable.
This is not described in the standard, but is a unanimous behaviour of
existing compilers.

Differential Revision: https://reviews.llvm.org/D120835
2022-03-03 10:11:35 +01:00
Peter Klausler 507f7317a0 [flang] Catch READ/WRITE on direct-access file without REC=
A data transfer statement must have REC= in its control list
if (and only if) the unit was opened with ACCESS='DIRECT'.
The runtime wasn't catching this error, but was just silently
advancing to the next record as if the access were sequential.

Differential Revision: https://reviews.llvm.org/D120838
2022-03-02 12:38:11 -08:00
Peter Klausler 3a96446d51 [flang] Honor RECL= in list-directed/namelist output
Advancement to new output lines was taking fixed-sized direct-access
and internal character array element lengths into account, but not
RECL= settings from OPEN statements.

Differential Revision: https://reviews.llvm.org/D120837
2022-03-02 12:07:18 -08:00
Peter Klausler 44ff4df6de [flang] Extension: don't require commas between most edit descriptors in formats
The standard explicitly allows a comma to be omitted between a 'P'
edit descriptor and a following numeric edit descriptor (e.g., 1PE10.1),
and before and after a '/' edit descriptor, but otherwise requires them
between edit descriptors.  Most implementations, however, only require
commas where they prevent ambiguity, and accept things like 1XI10.
This extension is already assumed by the static FORMAT checker in
semantics.  Patch the runtime to behave accordingly.

Differential Revision: https://reviews.llvm.org/D120747
2022-03-01 15:15:59 -08:00
Peter Klausler df38f35acb [flang] Allow data transfer stmt control list errors to be caught
The runtime crashes on several fundamental I/O data transfer statement
control list errors, like list I/O on a direct-access unit, or
input from a write-only unit, &c.  These errors should not be fatal
when ERR= or IOSTAT= are present.

This patch creates a new ErroneousIoStatementState class and
uses it for the state of an I/O statement that is doomed to fail
from these errors.  If there is no ERR= label or IOSTAT= variable,
the error will be raised at the end of the statement.  Data transfer
operations along the way will be no-op failures.

Differential Revision: https://reviews.llvm.org/D120745
2022-03-01 14:39:30 -08:00
Peter Klausler 73b193aec2 [flang] Allow more concurrently open NEWUNIT= values, with recycling
Add a header-only implementation of Briggs & Torczon's fast small
integer set data structure to flang/include/flang/Common, and use
it in the runtime to manage a pool of Fortran unit numbers with
recycling.  This replaces the bit set previously used for that
purpose.  The set is initialized on demand with the negations of
all the NEWUNIT= unit numbers that can be returned to any kind
of integer variable.

For programs that require more concurrently open NEWUNIT= unit
numbers than the pool can hold, they are now allocated with a
non-recycling counter.  This allows as many open units as the
operating system provides.

Many of the top-line comments in flang/unittests/Runtime had the
wrong path name.  I noticed this while adding a unit test for the
fast integer set data structure, and cleaned them up.

Differential Revision: https://reviews.llvm.org/D120685
2022-02-28 16:13:22 -08:00
V Donaldson 338b478e70 [flang] Do not print format tabs
As an extension, tabs are accepted in a format, but should be skipped,
not printed.
2022-02-23 20:03:10 -08:00
Peter Klausler 07b9a44515 [flang] Allow for deferred-length character in EstablishDescriptor
When the runtime is initializing an instance of a derived type,
don't crash if an allocatable character component has deferred length.

Differential Revision: https://reviews.llvm.org/D119731
2022-02-14 10:05:07 -08:00
Peter Steinfeld bdf5736521 [flang] Change internal errors in RESHAPE runtime routine to user errors
There are several checks in the runtime routine for the RESHAPE
intrinsic.  Some checks verify things that should have been checked at
compile time while others represent user errors.

This update changes the checks for user errors into calls to "Crash"
which include information about the failing check.  This identifies them
as user errors rather than compiler errors.

I also verified that the checks that remain as internal errors are also
checked by the front end.  I added a test to the front end's RESHAPE
test to complete the checks.

Differential Revision: https://reviews.llvm.org/D119596
2022-02-11 15:51:21 -08:00
Peter Steinfeld 6cd417bfd8 [flang] Upstream runtime changes for inquiry intrinsics
This change adds runtime routines and tests for LBOUND when passed a DIM argument, SIZE, and UBOUND when not passed a DIM argument.

Associated changes for lowering have already been merged into fir-dev.

Differential Revision: https://reviews.llvm.org/D119360
2022-02-09 12:42:36 -08:00
Peter Klausler 991696c2eb [flang] Debugging of ACCESS='STREAM' I/O (take 2)
Corrects the runtime implementation of I/O on files with
the access mode ACCESS='STREAM'.  This is a collection
of edge-case tweaks to ensure that the distinctions between
stream and direct/sequential files, unformatted or formatted,
are respected where appropriate.

Moves NextInField() from io-stmt.h to io-stmt.cpp --
it was getting too big to keep in a header.

This patch exposed a problem with the I/O runtime
on Windows and it was reverted.  This version also
fixes that problem; files are now opened on Windows
in binary mode to prevent inadvertent insertions of
carriage returns before line feeds, and those line
endings (CR+LF) are now explicitly generated.

Differential Revision: https://reviews.llvm.org/D119015
2022-02-04 18:02:34 -08:00
Andrzej Warzynski 4e53e28374 Revert "[flang] Debugging of ACCESS='STREAM' I/O"
This reverts commit be9946b877.

This change has caused Flang's Windows buildbot to start failing:
* https://lab.llvm.org/buildbot/#/builders/172/builds/7664
2022-02-03 15:19:42 +00:00
Peter Klausler 2b0b9b2e83 [flang] Modify right modes for READ/WRITE vs OPEN
When a mode flag is modified (e.g., BLANK='ZERO') in an I/O data transfer
statement, ensure that the right set of mode flags is modified.
There's one set of mode flags that are captured by an OPEN
statement and maintained in the connection, and another that
is maintained in an I/O statement state record for local mutability.
Some I/O API routines were unconditionally modifying the persistent
set of flags.

Differential Revision: https://reviews.llvm.org/D118835
2022-02-02 13:47:46 -08:00
Peter Klausler be9946b877 [flang] Debugging of ACCESS='STREAM' I/O
Corrects the runtime implementation of I/O on files with
the access mode ACCESS='STREAM'.  This is a collection
of edge-case tweaks to ensure that the distinctions between
stream and direct/sequential files, unformatted or formatted,
are respected where appropriate.
Moves NextInField() from io-stmt.h to io-stmt.cpp --
it was getting too big to keep in a header.

Differential Revision: https://reviews.llvm.org/D118834
2022-02-02 13:09:38 -08:00
Peter Klausler 9772dbba74 [flang] Set right "inNamelist" flag
NAMELIST I/O was inconsistent in its choice of which set of I/O modes
to set the "inNamelist" flag.  The wrong choice was in the set of modes
that are part of the persistent state of an I/O connection; the right
place is the set of modes that are reinitialized at the beginning of
each I/O statement so that they can be modified by READ/WRITE control
list specifiers and FORMAT control edit descriptors.  Fix.

Differential Revision: https://reviews.llvm.org/D118745
2022-02-02 09:33:19 -08:00
Peter Klausler 0f5c60f151 [flang] Fix edge-case I/O regressions
A blank field in an input record that exists must be interpreted
as a zero value for numeric input editing, but advancing to a
next record that doesn't exist should leave an input variable
unmodified (and signal END=).  On internal output, blank fill
the "current record" array element even if nothing has been
written to it if it is the only record.

Differential Revision: https://reviews.llvm.org/D118720
2022-02-01 16:27:47 -08:00
Peter Steinfeld 93ee588232 [flang] Rename the runtime routine that reports a fatal user error
As per Steve Scalpone's suggestion, I've renamed the runtime routine to
better evoke its purpose.

I implemented a routine called "Crash" and added a test.

Differential Revision: https://reviews.llvm.org/D118703
2022-02-01 09:01:50 -08:00
Peter Klausler c7f4c333af [flang] Make NEWUNIT= use a range suitable for INTEGER(KIND=1) and recycle unit numbers
Use a bit-set to manage runtime-generated I/O unit numbers, recycle
them after they're closed, and use a range of values that fits in
a minimal-sized integer.

Differential Revision: https://reviews.llvm.org/D118651
2022-01-31 15:20:21 -08:00
Peter Klausler 702c0cfa07 [flang] runtime perf: larger I/O buffer growth increments
When reallocating an I/O buffer to accommodate a large record,
ensure that the amount of growth is at least as large as the
minimum initial record size (64KiB).  The previous policy was
causing input buffer reallocation for each byte after the minimum
buffer size when scanning input data for record termination
newlines.

Differential Revision: https://reviews.llvm.org/D118649
2022-01-31 14:53:15 -08:00
Peter Klausler f651bbea06 [flang] Correct interpretation of RECL=
When RECL= is set on OPEN(), ensure that it:
  1) enforces a max output record payload size
     (not including header+footer or newline), and
  2) causes padding of short output records only
     for ACCESS='DIRECT'

The previous code was causing some false overrun errors
and applying padding to sequential/stream output files.

Differential Revision: https://reviews.llvm.org/D118630
2022-01-31 12:48:17 -08:00
Peter Steinfeld eb933225f4 [flang] Implement a runtime routine to report fatal errors with source position
The title says it all.

I implemented a routine called "Crash" and added a test.

Differential Revision: https://reviews.llvm.org/D118509
2022-01-28 15:46:00 -08:00
Peter Klausler 896a543e72 [flang] Support DECIMAL='COMMA' mode in namelist I/O
DECIMAL='COMMA' mode affects item separators, real editing, and
complex editing.

Differential Revision: https://reviews.llvm.org/D117906
2022-01-22 09:01:36 -08:00
Peter Klausler e9d0f8baf2 [flang] Don't drop format string for external child I/O
In user-defined derived type I/O to an external unit, don't
omit the format string from the constructor of ChildFormattedIoStatement.
And include any user IOMSG text in the crash message of the
parent, if it doesn't catch errors.

Differential Revision: https://reviews.llvm.org/D117903
2022-01-22 09:01:02 -08:00
Peter Klausler b1856009fb [flang] Allow INQUIRE() on a child unit in user-defined I/O procedure
A procedure that implements a user-defined derived type I/O operation
is allowed to perform an INQUIRE statement on its unit.

Differential Revision: https://reviews.llvm.org/D117905https://reviews.llvm.org/D117905
2022-01-21 18:23:56 -08:00
Peter Klausler 04eb93b1d5 [flang] Fix repeated "DT" editing
User-defined derived type editing in formatted I/O wasn't
working with repeat counts; e.g., "2DT(10)".  The solution required
some code to be moved from GetNextDataEdit() to CueUpNextDataEdit() so
that a stack entry for a nonparenthesized repeated data edit
descriptor would work correctly -- all other data edit descriptors
are capable of dealing with repetition in their callees, so the bug
hadn't been exposed before.

Debugging this problem led to some improvements in error messages
for bad format strings, and those changes have been retained; also,
a dead member function was discovered and expunged.

Differential Revision: https://reviews.llvm.org/D117904
2022-01-21 17:22:51 -08:00
Peter Klausler d1123e3692 [flang] Extension: skip over NAMELIST groups
Implements a near-universal extension in which NAMELIST
input will skip over unrelated namelist groups in the
input stream until the group with the requested name appears.

Differential Revision: https://reviews.llvm.org/D117843
2022-01-20 17:01:29 -08:00
Peter Klausler 922c29ccf1 [flang] Allow explicit '+' in NAMELIST input subscripts
Array subscripts and substring limits in NAMELIST input are
allowed to bear an explicit plus sign.

Differential Revision: https://reviews.llvm.org/D117818
2022-01-20 17:01:02 -08:00
Peter Klausler 9ddd07922f [flang] Handle FLUSH(unknown unit)
The unit number passed to a FLUSH statement is not required to
be a valid open unit; nothing happens (esp. not the creation of
an empty fort.n file) in this case.

Differential Revision: https://reviews.llvm.org/D117819
2022-01-20 15:35:34 -08:00
Peter Klausler 5501c16edf [flang] Fix OPEN/WRITE(SIGN='SUPPRESS')
The keyword value was misspelled in the runtime.

Differential Revision: https://reviews.llvm.org/D117816
2022-01-20 15:34:35 -08:00
Peter Klausler 047884e71e [flang] runtime: catch OPEN(ACCESS='DIRECT',POSITION=)
A POSITION= specifier may not be used on a direct access file.

Differential Revision: https://reviews.llvm.org/D117596
2022-01-18 14:54:53 -08:00
Peter Klausler e847b30369 [flang] runtime error on inappropriate OPEN(UNIT=extant,RECL=n)
Don't let a program set a fixed RECL= on a connected unit unless
it already had one with the same value.

Differential Revision: https://reviews.llvm.org/D117595
2022-01-18 14:54:27 -08:00
Peter Klausler 0ab170803f [flang] Support substring references in NAMELIST input
Implements substring references into potentially partial CHARACTER
scalars and array elements in NAMELIST input.

Differential Revision: https://reviews.llvm.org/D117576
2022-01-18 11:24:17 -08:00
Peter Klausler b77fd01a8f [flang] Don't blank-fill remaining lines in internal output
Internal writes to character arrays should not blank-fill
records (elements) past the last one that was written to.

Differential Revision: https://reviews.llvm.org/D117342
2022-01-14 15:14:48 -08:00
Peter Klausler ac4202fe9d [flang] Signal runtime error on WRITE after ENDFILE
After an ENDFILE statement, a WRITE is an error without
a prior BACKSPACE.  Also fix the return value for the case
of formatted integer input with no input digits to be false
(exposed by new test).

Differential Revision: https://reviews.llvm.org/D117346
2022-01-14 14:46:00 -08:00
V Donaldson e43b2e4f48 [flang] "CFI" types for Fortran REAL and COMPLEX kinds 2, 3, 10, 16
Add additional "CFI" types for Fortran REAL and COMPLEX kinds 2, 3, 10, 16 to allow their use in Fortran descriptors.
2022-01-14 11:06:18 -08:00
Valentin Clement ad3bb7c7da
[flang] Simplify RaggedArrayHeader and make it plain C struct
- Join indirection and rank into a single value `flags`
- Make the struct a plain C struct.

Reviewed By: schweitz

Differential Revision: https://reviews.llvm.org/D115464
2021-12-09 22:28:06 +01:00
Peter Klausler 627a8ac790 [flang] Add CALL FLUSH(n) legacy extension
Prior to the introduction of the FLUSH statement in Fortran 2003,
implementations provided a FLUSH subroutine.

We can't yet put Fortran code into the runtime, so this subroutine
is in C++ with a Fortran-mangled entry point name.

Differential Revision: https://reviews.llvm.org/D115289
2021-12-08 08:56:54 -08:00
Valentin Clement 6116ff297f
[flang][runtime] Add ragged array runtime functions
This patch adds the runtime function to allocate and
deallocate ragged arrays.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D114534

Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
2021-12-07 21:22:34 +01:00
Peter Klausler 5034e1730f [flang] Remove runtime check from OpenFile::Close()
In error cases it is possible to CLOSE a unit that has not
been successfully connected, so don't crash when the file descriptor
is negative.

Differential Revision: https://reviews.llvm.org/D115165
2021-12-07 09:43:24 -08:00
Peter Klausler c84616c3b3 [flang] Avoid potential deadlock in CloseAll()
When closing all open units, don't hold the unit map lock
over the actual close operations; if one of those aborts,
CloseAll() may be called and then deadlock.

Differential Review: https://reviews.llvm.org/D115184
2021-12-07 09:42:48 -08:00
Peter Klausler 398dffd4ff [flang] Fix INQUIRE(FILE=,NAME=)
The file name output was not being copied back to the program
from the runtime.

Differential Revision: https://reviews.llvm.org/D115190
2021-12-07 08:17:08 -08:00
Peter Klausler 06ca9f24e7 [flang] OPEN(RECL=) handling for sequential formatted I/O
RECL= is required for direct access I/O, but is permitted
as well for sequential I/O, where it is defined by the
standard to specify a maximum record (line) length.
The standard does not say what should happen when an
sequential formatted input record appears whose length is
unequal to RECL= when it is specified.

Precedents from other compilers are unclear: one raises an error,
some honor RECL= as an effective truncation, and a few ignore the
situation.  On output, all other compilers tested raised an
error when an attempt is made to emit a record longer than RECL=.

This patch treats RECL= as effective truncation on input and
as a hard limit with error on output, and also ensures that
RECL= can be set *longer* than the actual input record lengths.

Differential Revision: https://reviews.llvm.org/D115102
2021-12-04 16:02:48 -08:00
Jean Perier 1c16b0db9d [flang] Return arrays in Transfer runtime with SIZE argument
In TRANSFER runtime the result was an array only if the MOLD was an array.
This is not in line with TRANSFER definition in 16.9.193 that rules that it
must also be an array if MOLD is scalar and SIZE if provided.

Differential Revision: https://reviews.llvm.org/D114943
2021-12-03 08:23:30 +01:00
Peter Klausler 3f6dbf1a75 [flang] Don't close stderr in runtime (fixes STOP output)
STOP statement output was sometimes failing to appear because
the runtime flushes and shuts down open Fortran units beforehand.
But when file descriptor 2 was closed, the STOP statement output
was suppressed.  The fix is to not actually close file descriptors
0-2 if they are connected to Fortran units being closed.  This was
already the policy when an OPEN statement was (re-)opening such a
unit, so that logic has been pulled out into a member function and
shared with CLOSE processing.

Differential Revision: https://reviews.llvm.org/D114897
2021-12-01 13:25:18 -08:00
Peter Klausler 77ff6f7df8 [flang] Define & implement a lowering support API IsContiguous() in runtime
Create a new flang/runtime/support.cpp module to hold miscellaneous
runtime APIs to support lowering, and define an API IsContiguous() to
wrap the member function predicate Descriptor::IsContiguous().
And do a little clean-up of other API headers that don't need to expose
Runtime/descriptor.h.

Differential Revision: https://reviews.llvm.org/D114752
2021-11-30 14:15:56 -08:00
Peter Klausler 80cdf0db67 [flang] Correct INQUIRE(POSITION= & PAD=)
INQUIRE(POSITION=)'s results need to reflect the POSITION=
specifier used for the OPEN statement until the unit has been
repositioned.  Preserve the POSITION= from OPEN and used it
for INQUIRE(POSITION=) until is becomes obsolete.

INQUIRE(PAD=) is implemented here in the case of an unconnected unit
with Fortran 2018 semantics; i.e., "UNDEFINED", rather than Fortran 90's
"YES"/"NO" (see 4.3.6 para 2).  Apparent failures with F'90-only tests
will persist with INQUIRE(PAD=); these discrepancies don't seem to warrant
an option or environment variable.

To make the implementation of INQUIRE more closely match the language
in the standard, rename IsOpen() to IsConnected(), and use it explicitly
for the various INQUIRE specifiers.

Differential Revision: https://reviews.llvm.org/D114755
2021-11-30 13:51:48 -08:00
Peter Klausler 45a8caf1cd [flang] Fix reversed comparison in RESHAPE() runtime
RESHAPE() fails inappropriately at runtime if the source array
is larger than the result -- which is perfectly valid -- because
of an obviously reversed comparison of their numbers of elements
is activating the runtime asserts meant for the opposite case
(source smaller than result).

Differential Revision: https://reviews.llvm.org/D114474
2021-11-26 12:34:00 -08:00
Peter Klausler d02b318af6 [flang] Remove typo that affected complex namelist input
A recent patch to real/complex formatted input included what must
have been an editing hiccup: "++ ++p" instead of "++p".  This
compiles, and it broke the consumption of the trailing ')' of a
complex value in namelist input by skipping over the character.

Extend existing test to cover this case.

Differential Revision: https://reviews.llvm.org/D114297
2021-11-22 15:06:46 -08:00
Peter Klausler a62b60167d [flang] Predefine unit 0 connected to stderr
This is a near-universal language extension; external unit 0
is preconnected to the standard error output.

Differential Revision: https://reviews.llvm.org/D114298
2021-11-22 09:02:39 -08:00
Jean Perier 7796d81ae8 [flang] Skip `Fortran STOP:` before message when NO_STOP_MESSAGE is set
In 'STOP bye bye', do not print 'Fortran STOP:` before 'bye bye' when
NO_STOP_MESSAGE environment variable is set at runtime.

Also only exit with code 1 in StopStatementText if this is an ERROR STOP.
This matches other compiler behaviors.

Move STOP related unit tests in their own test file and add new tests to
cover this change.

Differential Revision: https://reviews.llvm.org/D114152
2021-11-18 18:08:06 +01:00
Peter Klausler d6b7576f21 [flang] Fix INQUIRE(PAD=) and (POSITION=) for predefined units
The predefined units were not being initialized with FORM='FORMATTED',
so INQUIRE(PAD=) was failing if no I/O had already been done.

INQUIRE(POSITION=) was returning 'REWIND' on stdin/stdout (which
is somewhat defensible from the definition, and is what Intel Fortran
does), but most implementations return 'ASIS'.  Change the runtime
to return 'REWIND' only for positionable external files, but 'ASIS'
for terminals, sockets, &c.

Differential Revision: https://reviews.llvm.org/D114028
2021-11-17 16:27:35 -08:00
V Donaldson ea8cdf322f [flang] Fix a bug in INQUIRE(IOLENGTH=) output
The inquire by output list form of the INQUIRE statement calculates the
number of file storage units that would be required to store the data
of an output list in an unformatted file.  Currently, the result is
incorrectly multiplied by the number of bytes for a data type.  A query
for "INTEGER(KIND=4) A(10)" should be 40, not 160.

Update formatting.
2021-11-16 11:33:15 -08:00
Jean Perier 2e65c8e8db [flang] Allow write after non advancing read in IO runtime
1. To avoid overwriting the part of the record read in the non advancing read,
the furtherPositionInRecord field must be set to the max of the
furtherPositionInRecord and the positionInRecord at the beginning of the
IO write.

2. To allow any further read to succeed after the write, the unit
beganReadingRecord_ must be set to false when resetting the recordLength
during the write, otherwise, recordLength will not be computed in further
read and an assert is hit (at unit.cpp(398)).

The added unit test exercises both of these scenarios.

Differential Revision: https://reviews.llvm.org/D113740
2021-11-16 14:53:39 +01:00
Peter Klausler da25f968a9 [flang] Runtime performance improvements to real formatted input
Profiling a basic internal real input read benchmark shows some
hot spots in the code used to prepare input for decimal-to-binary
conversion, which is of course where the time should be spent.
The library that implements decimal to/from binary conversions has
been optimized, but not the code in the Fortran runtime that calls it,
and there are some obvious light changes worth making here.

Move some member functions from *.cpp files into the class definitions
of Descriptor and IoStatementState to enable inlining and specialization.

Make GetNextInputBytes() the new basic input API within the
runtime, replacing GetCurrentChar() -- which is rewritten in terms of
GetNextInputBytes -- so that input routines can have the
ability to acquire more than one input character at a time
and amortize overhead.

These changes speed up the time to read 1M random reals
using internal I/O from a character array from 1.29s to 0.54s
on my machine, which on par with Intel Fortran and much faster than
GNU Fortran.

Differential Revision: https://reviews.llvm.org/D113697
2021-11-12 11:40:02 -08:00
Peter Klausler d1b09adeeb [flang] Fix rounding edge case in F output editing
When an Fw.d output edit descriptor has a "d" value exactly
equal to the number of zeroes after the decimal point for a value
(e.g., 0.07 with F5.1), the Fw.d output editing code needs to
do the rounding itself to either 0.0 or 0.1 after performing
a conversion without rounding (to avoid 0.04999 rounding up twice).

Differential Revision: https://reviews.llvm.org/D113698
2021-11-12 11:16:25 -08:00
Peter Klausler 4a0af824ee [flang] Respect NO_STOP_MESSAGE=1 in runtime
When an environment variable NO_STOP_MESSAGE=1 is set,
assume that STOP statements with a successful code
have QUIET=.TRUE.

Differential Revision: https://reviews.llvm.org/D113701
2021-11-12 10:50:36 -08:00