annotate libgfortran/generated/reshape_r10.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Implementation of the RESHAPE intrinsic
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2002-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by Paul Brook <paul@nowt.org>
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of the GNU Fortran runtime library (libgfortran).
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 Libgfortran is free software; you can redistribute it and/or
kono
parents:
diff changeset
8 modify it under the terms of the GNU General Public
kono
parents:
diff changeset
9 License as published by the Free Software Foundation; either
kono
parents:
diff changeset
10 version 3 of the License, or (at your option) any later version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 Libgfortran is distributed in the hope that it will be useful,
kono
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kono
parents:
diff changeset
15 GNU General Public License for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
18 permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
19 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
22 a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
24 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 #include "libgfortran.h"
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28
kono
parents:
diff changeset
29 #if defined (HAVE_GFC_REAL_10)
kono
parents:
diff changeset
30
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
31 typedef GFC_FULL_ARRAY_DESCRIPTOR(1, index_type) shape_type;
111
kono
parents:
diff changeset
32
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 extern void reshape_r10 (gfc_array_r10 * const restrict,
kono
parents:
diff changeset
35 gfc_array_r10 * const restrict,
kono
parents:
diff changeset
36 shape_type * const restrict,
kono
parents:
diff changeset
37 gfc_array_r10 * const restrict,
kono
parents:
diff changeset
38 shape_type * const restrict);
kono
parents:
diff changeset
39 export_proto(reshape_r10);
kono
parents:
diff changeset
40
kono
parents:
diff changeset
41 void
kono
parents:
diff changeset
42 reshape_r10 (gfc_array_r10 * const restrict ret,
kono
parents:
diff changeset
43 gfc_array_r10 * const restrict source,
kono
parents:
diff changeset
44 shape_type * const restrict shape,
kono
parents:
diff changeset
45 gfc_array_r10 * const restrict pad,
kono
parents:
diff changeset
46 shape_type * const restrict order)
kono
parents:
diff changeset
47 {
kono
parents:
diff changeset
48 /* r.* indicates the return array. */
kono
parents:
diff changeset
49 index_type rcount[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
50 index_type rextent[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
51 index_type rstride[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
52 index_type rstride0;
kono
parents:
diff changeset
53 index_type rdim;
kono
parents:
diff changeset
54 index_type rsize;
kono
parents:
diff changeset
55 index_type rs;
kono
parents:
diff changeset
56 index_type rex;
kono
parents:
diff changeset
57 GFC_REAL_10 *rptr;
kono
parents:
diff changeset
58 /* s.* indicates the source array. */
kono
parents:
diff changeset
59 index_type scount[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
60 index_type sextent[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
61 index_type sstride[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
62 index_type sstride0;
kono
parents:
diff changeset
63 index_type sdim;
kono
parents:
diff changeset
64 index_type ssize;
kono
parents:
diff changeset
65 const GFC_REAL_10 *sptr;
kono
parents:
diff changeset
66 /* p.* indicates the pad array. */
kono
parents:
diff changeset
67 index_type pcount[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
68 index_type pextent[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
69 index_type pstride[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
70 index_type pdim;
kono
parents:
diff changeset
71 index_type psize;
kono
parents:
diff changeset
72 const GFC_REAL_10 *pptr;
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 const GFC_REAL_10 *src;
kono
parents:
diff changeset
75 int sempty, pempty, shape_empty;
kono
parents:
diff changeset
76 index_type shape_data[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 rdim = GFC_DESCRIPTOR_EXTENT(shape,0);
kono
parents:
diff changeset
79 /* rdim is always > 0; this lets the compiler optimize more and
kono
parents:
diff changeset
80 avoids a potential warning. */
kono
parents:
diff changeset
81 GFC_ASSERT(rdim>0);
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 if (rdim != GFC_DESCRIPTOR_RANK(ret))
kono
parents:
diff changeset
84 runtime_error("rank of return array incorrect in RESHAPE intrinsic");
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 shape_empty = 0;
kono
parents:
diff changeset
87
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
88 for (index_type n = 0; n < rdim; n++)
111
kono
parents:
diff changeset
89 {
kono
parents:
diff changeset
90 shape_data[n] = shape->base_addr[n * GFC_DESCRIPTOR_STRIDE(shape,0)];
kono
parents:
diff changeset
91 if (shape_data[n] <= 0)
kono
parents:
diff changeset
92 {
kono
parents:
diff changeset
93 shape_data[n] = 0;
kono
parents:
diff changeset
94 shape_empty = 1;
kono
parents:
diff changeset
95 }
kono
parents:
diff changeset
96 }
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 if (ret->base_addr == NULL)
kono
parents:
diff changeset
99 {
kono
parents:
diff changeset
100 index_type alloc_size;
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 rs = 1;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
103 for (index_type n = 0; n < rdim; n++)
111
kono
parents:
diff changeset
104 {
kono
parents:
diff changeset
105 rex = shape_data[n];
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs);
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 rs *= rex;
kono
parents:
diff changeset
110 }
kono
parents:
diff changeset
111 ret->offset = 0;
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 if (unlikely (rs < 1))
kono
parents:
diff changeset
114 alloc_size = 0;
kono
parents:
diff changeset
115 else
kono
parents:
diff changeset
116 alloc_size = rs;
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 ret->base_addr = xmallocarray (alloc_size, sizeof (GFC_REAL_10));
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
119 ret->dtype.rank = rdim;
111
kono
parents:
diff changeset
120 }
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 if (shape_empty)
kono
parents:
diff changeset
123 return;
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 if (pad)
kono
parents:
diff changeset
126 {
kono
parents:
diff changeset
127 pdim = GFC_DESCRIPTOR_RANK (pad);
kono
parents:
diff changeset
128 psize = 1;
kono
parents:
diff changeset
129 pempty = 0;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
130 for (index_type n = 0; n < pdim; n++)
111
kono
parents:
diff changeset
131 {
kono
parents:
diff changeset
132 pcount[n] = 0;
kono
parents:
diff changeset
133 pstride[n] = GFC_DESCRIPTOR_STRIDE(pad,n);
kono
parents:
diff changeset
134 pextent[n] = GFC_DESCRIPTOR_EXTENT(pad,n);
kono
parents:
diff changeset
135 if (pextent[n] <= 0)
kono
parents:
diff changeset
136 {
kono
parents:
diff changeset
137 pempty = 1;
kono
parents:
diff changeset
138 pextent[n] = 0;
kono
parents:
diff changeset
139 }
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 if (psize == pstride[n])
kono
parents:
diff changeset
142 psize *= pextent[n];
kono
parents:
diff changeset
143 else
kono
parents:
diff changeset
144 psize = 0;
kono
parents:
diff changeset
145 }
kono
parents:
diff changeset
146 pptr = pad->base_addr;
kono
parents:
diff changeset
147 }
kono
parents:
diff changeset
148 else
kono
parents:
diff changeset
149 {
kono
parents:
diff changeset
150 pdim = 0;
kono
parents:
diff changeset
151 psize = 1;
kono
parents:
diff changeset
152 pempty = 1;
kono
parents:
diff changeset
153 pptr = NULL;
kono
parents:
diff changeset
154 }
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 if (unlikely (compile_options.bounds_check))
kono
parents:
diff changeset
157 {
kono
parents:
diff changeset
158 index_type ret_extent, source_extent;
kono
parents:
diff changeset
159
kono
parents:
diff changeset
160 rs = 1;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
161 for (index_type n = 0; n < rdim; n++)
111
kono
parents:
diff changeset
162 {
kono
parents:
diff changeset
163 rs *= shape_data[n];
kono
parents:
diff changeset
164 ret_extent = GFC_DESCRIPTOR_EXTENT(ret,n);
kono
parents:
diff changeset
165 if (ret_extent != shape_data[n])
kono
parents:
diff changeset
166 runtime_error("Incorrect extent in return value of RESHAPE"
kono
parents:
diff changeset
167 " intrinsic in dimension %ld: is %ld,"
kono
parents:
diff changeset
168 " should be %ld", (long int) n+1,
kono
parents:
diff changeset
169 (long int) ret_extent, (long int) shape_data[n]);
kono
parents:
diff changeset
170 }
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 source_extent = 1;
kono
parents:
diff changeset
173 sdim = GFC_DESCRIPTOR_RANK (source);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
174 for (index_type n = 0; n < sdim; n++)
111
kono
parents:
diff changeset
175 {
kono
parents:
diff changeset
176 index_type se;
kono
parents:
diff changeset
177 se = GFC_DESCRIPTOR_EXTENT(source,n);
kono
parents:
diff changeset
178 source_extent *= se > 0 ? se : 0;
kono
parents:
diff changeset
179 }
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 if (rs > source_extent && (!pad || pempty))
kono
parents:
diff changeset
182 runtime_error("Incorrect size in SOURCE argument to RESHAPE"
kono
parents:
diff changeset
183 " intrinsic: is %ld, should be %ld",
kono
parents:
diff changeset
184 (long int) source_extent, (long int) rs);
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186 if (order)
kono
parents:
diff changeset
187 {
kono
parents:
diff changeset
188 int seen[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
189 index_type v;
kono
parents:
diff changeset
190
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
191 for (index_type n = 0; n < rdim; n++)
111
kono
parents:
diff changeset
192 seen[n] = 0;
kono
parents:
diff changeset
193
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
194 for (index_type n = 0; n < rdim; n++)
111
kono
parents:
diff changeset
195 {
kono
parents:
diff changeset
196 v = order->base_addr[n * GFC_DESCRIPTOR_STRIDE(order,0)] - 1;
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 if (v < 0 || v >= rdim)
kono
parents:
diff changeset
199 runtime_error("Value %ld out of range in ORDER argument"
kono
parents:
diff changeset
200 " to RESHAPE intrinsic", (long int) v + 1);
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 if (seen[v] != 0)
kono
parents:
diff changeset
203 runtime_error("Duplicate value %ld in ORDER argument to"
kono
parents:
diff changeset
204 " RESHAPE intrinsic", (long int) v + 1);
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 seen[v] = 1;
kono
parents:
diff changeset
207 }
kono
parents:
diff changeset
208 }
kono
parents:
diff changeset
209 }
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 rsize = 1;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
212 for (index_type n = 0; n < rdim; n++)
111
kono
parents:
diff changeset
213 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
214 index_type dim;
111
kono
parents:
diff changeset
215 if (order)
kono
parents:
diff changeset
216 dim = order->base_addr[n * GFC_DESCRIPTOR_STRIDE(order,0)] - 1;
kono
parents:
diff changeset
217 else
kono
parents:
diff changeset
218 dim = n;
kono
parents:
diff changeset
219
kono
parents:
diff changeset
220 rcount[n] = 0;
kono
parents:
diff changeset
221 rstride[n] = GFC_DESCRIPTOR_STRIDE(ret,dim);
kono
parents:
diff changeset
222 rextent[n] = GFC_DESCRIPTOR_EXTENT(ret,dim);
kono
parents:
diff changeset
223 if (rextent[n] < 0)
kono
parents:
diff changeset
224 rextent[n] = 0;
kono
parents:
diff changeset
225
kono
parents:
diff changeset
226 if (rextent[n] != shape_data[dim])
kono
parents:
diff changeset
227 runtime_error ("shape and target do not conform");
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 if (rsize == rstride[n])
kono
parents:
diff changeset
230 rsize *= rextent[n];
kono
parents:
diff changeset
231 else
kono
parents:
diff changeset
232 rsize = 0;
kono
parents:
diff changeset
233 if (rextent[n] <= 0)
kono
parents:
diff changeset
234 return;
kono
parents:
diff changeset
235 }
kono
parents:
diff changeset
236
kono
parents:
diff changeset
237 sdim = GFC_DESCRIPTOR_RANK (source);
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 /* sdim is always > 0; this lets the compiler optimize more and
kono
parents:
diff changeset
240 avoids a warning. */
kono
parents:
diff changeset
241 GFC_ASSERT(sdim>0);
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 ssize = 1;
kono
parents:
diff changeset
244 sempty = 0;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
245 for (index_type n = 0; n < sdim; n++)
111
kono
parents:
diff changeset
246 {
kono
parents:
diff changeset
247 scount[n] = 0;
kono
parents:
diff changeset
248 sstride[n] = GFC_DESCRIPTOR_STRIDE(source,n);
kono
parents:
diff changeset
249 sextent[n] = GFC_DESCRIPTOR_EXTENT(source,n);
kono
parents:
diff changeset
250 if (sextent[n] <= 0)
kono
parents:
diff changeset
251 {
kono
parents:
diff changeset
252 sempty = 1;
kono
parents:
diff changeset
253 sextent[n] = 0;
kono
parents:
diff changeset
254 }
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 if (ssize == sstride[n])
kono
parents:
diff changeset
257 ssize *= sextent[n];
kono
parents:
diff changeset
258 else
kono
parents:
diff changeset
259 ssize = 0;
kono
parents:
diff changeset
260 }
kono
parents:
diff changeset
261
kono
parents:
diff changeset
262 if (rsize != 0 && ssize != 0 && psize != 0)
kono
parents:
diff changeset
263 {
kono
parents:
diff changeset
264 rsize *= sizeof (GFC_REAL_10);
kono
parents:
diff changeset
265 ssize *= sizeof (GFC_REAL_10);
kono
parents:
diff changeset
266 psize *= sizeof (GFC_REAL_10);
kono
parents:
diff changeset
267 reshape_packed ((char *)ret->base_addr, rsize, (char *)source->base_addr,
kono
parents:
diff changeset
268 ssize, pad ? (char *)pad->base_addr : NULL, psize);
kono
parents:
diff changeset
269 return;
kono
parents:
diff changeset
270 }
kono
parents:
diff changeset
271 rptr = ret->base_addr;
kono
parents:
diff changeset
272 src = sptr = source->base_addr;
kono
parents:
diff changeset
273 rstride0 = rstride[0];
kono
parents:
diff changeset
274 sstride0 = sstride[0];
kono
parents:
diff changeset
275
kono
parents:
diff changeset
276 if (sempty && pempty)
kono
parents:
diff changeset
277 abort ();
kono
parents:
diff changeset
278
kono
parents:
diff changeset
279 if (sempty)
kono
parents:
diff changeset
280 {
kono
parents:
diff changeset
281 /* Pretend we are using the pad array the first time around, too. */
kono
parents:
diff changeset
282 src = pptr;
kono
parents:
diff changeset
283 sptr = pptr;
kono
parents:
diff changeset
284 sdim = pdim;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
285 for (index_type dim = 0; dim < pdim; dim++)
111
kono
parents:
diff changeset
286 {
kono
parents:
diff changeset
287 scount[dim] = pcount[dim];
kono
parents:
diff changeset
288 sextent[dim] = pextent[dim];
kono
parents:
diff changeset
289 sstride[dim] = pstride[dim];
kono
parents:
diff changeset
290 sstride0 = pstride[0];
kono
parents:
diff changeset
291 }
kono
parents:
diff changeset
292 }
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 while (rptr)
kono
parents:
diff changeset
295 {
kono
parents:
diff changeset
296 /* Select between the source and pad arrays. */
kono
parents:
diff changeset
297 *rptr = *src;
kono
parents:
diff changeset
298 /* Advance to the next element. */
kono
parents:
diff changeset
299 rptr += rstride0;
kono
parents:
diff changeset
300 src += sstride0;
kono
parents:
diff changeset
301 rcount[0]++;
kono
parents:
diff changeset
302 scount[0]++;
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 /* Advance to the next destination element. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
305 index_type n = 0;
111
kono
parents:
diff changeset
306 while (rcount[n] == rextent[n])
kono
parents:
diff changeset
307 {
kono
parents:
diff changeset
308 /* When we get to the end of a dimension, reset it and increment
kono
parents:
diff changeset
309 the next dimension. */
kono
parents:
diff changeset
310 rcount[n] = 0;
kono
parents:
diff changeset
311 /* We could precalculate these products, but this is a less
kono
parents:
diff changeset
312 frequently used path so probably not worth it. */
kono
parents:
diff changeset
313 rptr -= rstride[n] * rextent[n];
kono
parents:
diff changeset
314 n++;
kono
parents:
diff changeset
315 if (n == rdim)
kono
parents:
diff changeset
316 {
kono
parents:
diff changeset
317 /* Break out of the loop. */
kono
parents:
diff changeset
318 rptr = NULL;
kono
parents:
diff changeset
319 break;
kono
parents:
diff changeset
320 }
kono
parents:
diff changeset
321 else
kono
parents:
diff changeset
322 {
kono
parents:
diff changeset
323 rcount[n]++;
kono
parents:
diff changeset
324 rptr += rstride[n];
kono
parents:
diff changeset
325 }
kono
parents:
diff changeset
326 }
kono
parents:
diff changeset
327 /* Advance to the next source element. */
kono
parents:
diff changeset
328 n = 0;
kono
parents:
diff changeset
329 while (scount[n] == sextent[n])
kono
parents:
diff changeset
330 {
kono
parents:
diff changeset
331 /* When we get to the end of a dimension, reset it and increment
kono
parents:
diff changeset
332 the next dimension. */
kono
parents:
diff changeset
333 scount[n] = 0;
kono
parents:
diff changeset
334 /* We could precalculate these products, but this is a less
kono
parents:
diff changeset
335 frequently used path so probably not worth it. */
kono
parents:
diff changeset
336 src -= sstride[n] * sextent[n];
kono
parents:
diff changeset
337 n++;
kono
parents:
diff changeset
338 if (n == sdim)
kono
parents:
diff changeset
339 {
kono
parents:
diff changeset
340 if (sptr && pad)
kono
parents:
diff changeset
341 {
kono
parents:
diff changeset
342 /* Switch to the pad array. */
kono
parents:
diff changeset
343 sptr = NULL;
kono
parents:
diff changeset
344 sdim = pdim;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
345 for (index_type dim = 0; dim < pdim; dim++)
111
kono
parents:
diff changeset
346 {
kono
parents:
diff changeset
347 scount[dim] = pcount[dim];
kono
parents:
diff changeset
348 sextent[dim] = pextent[dim];
kono
parents:
diff changeset
349 sstride[dim] = pstride[dim];
kono
parents:
diff changeset
350 sstride0 = sstride[0];
kono
parents:
diff changeset
351 }
kono
parents:
diff changeset
352 }
kono
parents:
diff changeset
353 /* We now start again from the beginning of the pad array. */
kono
parents:
diff changeset
354 src = pptr;
kono
parents:
diff changeset
355 break;
kono
parents:
diff changeset
356 }
kono
parents:
diff changeset
357 else
kono
parents:
diff changeset
358 {
kono
parents:
diff changeset
359 scount[n]++;
kono
parents:
diff changeset
360 src += sstride[n];
kono
parents:
diff changeset
361 }
kono
parents:
diff changeset
362 }
kono
parents:
diff changeset
363 }
kono
parents:
diff changeset
364 }
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 #endif