annotate flang/runtime/internal-unit.cpp @ 236:c4bab56944e8 llvm-original

LLVM 16
author kono
date Wed, 09 Nov 2022 17:45:10 +0900
parents 79ff65ed7e25
children 1f2b6ac9f198
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
1 //===-- runtime/internal-unit.cpp -----------------------------------------===//
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 //
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 //
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 #include "internal-unit.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 #include "io-error.h"
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
11 #include "flang/Runtime/descriptor.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 #include <algorithm>
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 #include <type_traits>
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 namespace Fortran::runtime::io {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 template <Direction DIR>
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 InternalDescriptorUnit<DIR>::InternalDescriptorUnit(
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
19 Scalar scalar, std::size_t length, int kind) {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
20 internalIoCharKind = kind;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 recordLength = length;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 endfileRecordNumber = 2;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 void *pointer{reinterpret_cast<void *>(const_cast<char *>(scalar))};
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
24 descriptor().Establish(TypeCode{TypeCategory::Character, kind}, length * kind,
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
25 pointer, 0, nullptr, CFI_attribute_pointer);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 template <Direction DIR>
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 InternalDescriptorUnit<DIR>::InternalDescriptorUnit(
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 const Descriptor &that, const Terminator &terminator) {
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
31 auto thatType{that.type().GetCategoryAndKind()};
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
32 RUNTIME_CHECK(terminator, thatType.has_value());
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
33 RUNTIME_CHECK(terminator, thatType->first == TypeCategory::Character);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 Descriptor &d{descriptor()};
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 RUNTIME_CHECK(
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 terminator, that.SizeInBytes() <= d.SizeInBytes(maxRank, true, 0));
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 new (&d) Descriptor{that};
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 d.Check();
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
39 internalIoCharKind = thatType->second;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 recordLength = d.ElementBytes();
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 endfileRecordNumber = d.Elements() + 1;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 template <Direction DIR> void InternalDescriptorUnit<DIR>::EndIoStatement() {
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
45 if constexpr (DIR == Direction::Output) {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
46 // Clear the remainder of the current record if anything was written
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
47 // to it, or if it is the only record.
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
48 auto end{endfileRecordNumber.value_or(0)};
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
49 if (currentRecordNumber < end &&
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
50 (end == 2 || furthestPositionInRecord > 0)) {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
51 BlankFillOutputRecord();
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
55
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 template <Direction DIR>
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 bool InternalDescriptorUnit<DIR>::Emit(
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 const char *data, std::size_t bytes, IoErrorHandler &handler) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 if constexpr (DIR == Direction::Input) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 handler.Crash("InternalDescriptorUnit<Direction::Input>::Emit() called");
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 return false && data[bytes] != 0; // bogus compare silences GCC warning
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 } else {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 if (bytes <= 0) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 return true;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 char *record{CurrentRecord()};
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 if (!record) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 handler.SignalError(IostatInternalWriteOverrun);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 return false;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 auto furthestAfter{std::max(furthestPositionInRecord,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 positionInRecord + static_cast<std::int64_t>(bytes))};
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 bool ok{true};
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 if (furthestAfter > static_cast<std::int64_t>(recordLength.value_or(0))) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 handler.SignalError(IostatRecordWriteOverrun);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 furthestAfter = recordLength.value_or(0);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 bytes = std::max(std::int64_t{0}, furthestAfter - positionInRecord);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 ok = false;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 } else if (positionInRecord > furthestPositionInRecord) {
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
80 BlankFill(record + furthestPositionInRecord,
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
81 positionInRecord - furthestPositionInRecord);
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 std::memcpy(record + positionInRecord, data, bytes);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 positionInRecord += bytes;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 furthestPositionInRecord = furthestAfter;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 return ok;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
89
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 template <Direction DIR>
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
91 std::size_t InternalDescriptorUnit<DIR>::GetNextInputBytes(
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
92 const char *&p, IoErrorHandler &handler) {
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 if constexpr (DIR == Direction::Output) {
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
94 handler.Crash("InternalDescriptorUnit<Direction::Output>::"
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
95 "GetNextInputBytes() called");
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
96 return 0;
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
97 } else {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
98 const char *record{CurrentRecord()};
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
99 if (!record) {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
100 handler.SignalEnd();
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
101 return 0;
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
102 } else if (positionInRecord >= recordLength.value_or(positionInRecord)) {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
103 return 0;
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
104 } else {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
105 p = &record[positionInRecord];
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
106 return *recordLength - positionInRecord;
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
107 }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
110
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 template <Direction DIR>
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 bool InternalDescriptorUnit<DIR>::AdvanceRecord(IoErrorHandler &handler) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 if (currentRecordNumber >= endfileRecordNumber.value_or(0)) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 handler.SignalEnd();
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 return false;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 }
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
117 if constexpr (DIR == Direction::Output) {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
118 BlankFillOutputRecord();
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 ++currentRecordNumber;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
121 BeginRecord();
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 return true;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
124
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 template <Direction DIR>
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
126 void InternalDescriptorUnit<DIR>::BlankFill(char *at, std::size_t bytes) {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
127 switch (internalIoCharKind) {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
128 case 2:
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
129 std::fill_n(reinterpret_cast<char16_t *>(at), bytes / 2,
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
130 static_cast<char16_t>(' '));
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
131 break;
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
132 case 4:
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
133 std::fill_n(reinterpret_cast<char32_t *>(at), bytes / 4,
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
134 static_cast<char32_t>(' '));
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
135 break;
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
136 default:
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
137 std::fill_n(at, bytes, ' ');
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
138 break;
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
139 }
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
140 }
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
141
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
142 template <Direction DIR>
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
143 void InternalDescriptorUnit<DIR>::BlankFillOutputRecord() {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
144 if constexpr (DIR == Direction::Output) {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
145 if (furthestPositionInRecord <
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
146 recordLength.value_or(furthestPositionInRecord)) {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
147 BlankFill(CurrentRecord() + furthestPositionInRecord,
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
148 *recordLength - furthestPositionInRecord);
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
149 }
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
150 }
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
151 }
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
152
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
153 template <Direction DIR>
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 void InternalDescriptorUnit<DIR>::BackspaceRecord(IoErrorHandler &handler) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 RUNTIME_CHECK(handler, currentRecordNumber > 1);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 --currentRecordNumber;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
157 BeginRecord();
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
159
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 template class InternalDescriptorUnit<Direction::Output>;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 template class InternalDescriptorUnit<Direction::Input>;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 } // namespace Fortran::runtime::io