OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [fortran/] [trans-array.c] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* Array translation routines
2
   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3
   Contributed by Paul Brook <paul@nowt.org>
4
   and Steven Bosscher <s.bosscher@student.tudelft.nl>
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 2, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING.  If not, write to the Free
20
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21
02110-1301, USA.  */
22
 
23
/* trans-array.c-- Various array related code, including scalarization,
24
                   allocation, initialization and other support routines.  */
25
 
26
/* How the scalarizer works.
27
   In gfortran, array expressions use the same core routines as scalar
28
   expressions.
29
   First, a Scalarization State (SS) chain is built.  This is done by walking
30
   the expression tree, and building a linear list of the terms in the
31
   expression.  As the tree is walked, scalar subexpressions are translated.
32
 
33
   The scalarization parameters are stored in a gfc_loopinfo structure.
34
   First the start and stride of each term is calculated by
35
   gfc_conv_ss_startstride.  During this process the expressions for the array
36
   descriptors and data pointers are also translated.
37
 
38
   If the expression is an assignment, we must then resolve any dependencies.
39
   In fortran all the rhs values of an assignment must be evaluated before
40
   any assignments take place.  This can require a temporary array to store the
41
   values.  We also require a temporary when we are passing array expressions
42
   or vector subecripts as procedure parameters.
43
 
44
   Array sections are passed without copying to a temporary.  These use the
45
   scalarizer to determine the shape of the section.  The flag
46
   loop->array_parameter tells the scalarizer that the actual values and loop
47
   variables will not be required.
48
 
49
   The function gfc_conv_loop_setup generates the scalarization setup code.
50
   It determines the range of the scalarizing loop variables.  If a temporary
51
   is required, this is created and initialized.  Code for scalar expressions
52
   taken outside the loop is also generated at this time.  Next the offset and
53
   scaling required to translate from loop variables to array indices for each
54
   term is calculated.
55
 
56
   A call to gfc_start_scalarized_body marks the start of the scalarized
57
   expression.  This creates a scope and declares the loop variables.  Before
58
   calling this gfc_make_ss_chain_used must be used to indicate which terms
59
   will be used inside this loop.
60
 
61
   The scalar gfc_conv_* functions are then used to build the main body of the
62
   scalarization loop.  Scalarization loop variables and precalculated scalar
63
   values are automatically substituted.  Note that gfc_advance_se_ss_chain
64
   must be used, rather than changing the se->ss directly.
65
 
66
   For assignment expressions requiring a temporary two sub loops are
67
   generated.  The first stores the result of the expression in the temporary,
68
   the second copies it to the result.  A call to
69
   gfc_trans_scalarized_loop_boundary marks the end of the main loop code and
70
   the start of the copying loop.  The temporary may be less than full rank.
71
 
72
   Finally gfc_trans_scalarizing_loops is called to generate the implicit do
73
   loops.  The loops are added to the pre chain of the loopinfo.  The post
74
   chain may still contain cleanup code.
75
 
76
   After the loop code has been added into its parent scope gfc_cleanup_loop
77
   is called to free all the SS allocated by the scalarizer.  */
78
 
79
#include "config.h"
80
#include "system.h"
81
#include "coretypes.h"
82
#include "tree.h"
83
#include "tree-gimple.h"
84
#include "ggc.h"
85
#include "toplev.h"
86
#include "real.h"
87
#include "flags.h"
88
#include "gfortran.h"
89
#include "trans.h"
90
#include "trans-stmt.h"
91
#include "trans-types.h"
92
#include "trans-array.h"
93
#include "trans-const.h"
94
#include "dependency.h"
95
 
96
static gfc_ss *gfc_walk_subexpr (gfc_ss *, gfc_expr *);
97
static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor *);
98
 
99
/* The contents of this structure aren't actually used, just the address.  */
100
static gfc_ss gfc_ss_terminator_var;
101
gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
102
 
103
 
104
static tree
105
gfc_array_dataptr_type (tree desc)
106
{
107
  return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
108
}
109
 
110
 
111
/* Build expressions to access the members of an array descriptor.
112
   It's surprisingly easy to mess up here, so never access
113
   an array descriptor by "brute force", always use these
114
   functions.  This also avoids problems if we change the format
115
   of an array descriptor.
116
 
117
   To understand these magic numbers, look at the comments
118
   before gfc_build_array_type() in trans-types.c.
119
 
120
   The code within these defines should be the only code which knows the format
121
   of an array descriptor.
122
 
123
   Any code just needing to read obtain the bounds of an array should use
124
   gfc_conv_array_* rather than the following functions as these will return
125
   know constant values, and work with arrays which do not have descriptors.
126
 
127
   Don't forget to #undef these!  */
128
 
129
#define DATA_FIELD 0
130
#define OFFSET_FIELD 1
131
#define DTYPE_FIELD 2
132
#define DIMENSION_FIELD 3
133
 
134
#define STRIDE_SUBFIELD 0
135
#define LBOUND_SUBFIELD 1
136
#define UBOUND_SUBFIELD 2
137
 
138
/* This provides READ-ONLY access to the data field.  The field itself
139
   doesn't have the proper type.  */
140
 
141
tree
142
gfc_conv_descriptor_data_get (tree desc)
143
{
144
  tree field, type, t;
145
 
146
  type = TREE_TYPE (desc);
147
  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
148
 
149
  field = TYPE_FIELDS (type);
150
  gcc_assert (DATA_FIELD == 0);
151
 
152
  t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
153
  t = fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), t);
154
 
155
  return t;
156
}
157
 
158
/* This provides WRITE access to the data field.  */
159
 
160
void
161
gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
162
{
163
  tree field, type, t;
164
 
165
  type = TREE_TYPE (desc);
166
  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
167
 
168
  field = TYPE_FIELDS (type);
169
  gcc_assert (DATA_FIELD == 0);
170
 
171
  t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
172
  gfc_add_modify_expr (block, t, fold_convert (TREE_TYPE (field), value));
173
}
174
 
175
 
176
/* This provides address access to the data field.  This should only be
177
   used by array allocation, passing this on to the runtime.  */
178
 
179
tree
180
gfc_conv_descriptor_data_addr (tree desc)
181
{
182
  tree field, type, t;
183
 
184
  type = TREE_TYPE (desc);
185
  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
186
 
187
  field = TYPE_FIELDS (type);
188
  gcc_assert (DATA_FIELD == 0);
189
 
190
  t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
191
  return gfc_build_addr_expr (NULL, t);
192
}
193
 
194
tree
195
gfc_conv_descriptor_offset (tree desc)
196
{
197
  tree type;
198
  tree field;
199
 
200
  type = TREE_TYPE (desc);
201
  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
202
 
203
  field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
204
  gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
205
 
206
  return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
207
}
208
 
209
tree
210
gfc_conv_descriptor_dtype (tree desc)
211
{
212
  tree field;
213
  tree type;
214
 
215
  type = TREE_TYPE (desc);
216
  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
217
 
218
  field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
219
  gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
220
 
221
  return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
222
}
223
 
224
static tree
225
gfc_conv_descriptor_dimension (tree desc, tree dim)
226
{
227
  tree field;
228
  tree type;
229
  tree tmp;
230
 
231
  type = TREE_TYPE (desc);
232
  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
233
 
234
  field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
235
  gcc_assert (field != NULL_TREE
236
          && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
237
          && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
238
 
239
  tmp = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
240
  tmp = gfc_build_array_ref (tmp, dim);
241
  return tmp;
242
}
243
 
244
tree
245
gfc_conv_descriptor_stride (tree desc, tree dim)
246
{
247
  tree tmp;
248
  tree field;
249
 
250
  tmp = gfc_conv_descriptor_dimension (desc, dim);
251
  field = TYPE_FIELDS (TREE_TYPE (tmp));
252
  field = gfc_advance_chain (field, STRIDE_SUBFIELD);
253
  gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
254
 
255
  tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
256
  return tmp;
257
}
258
 
259
tree
260
gfc_conv_descriptor_lbound (tree desc, tree dim)
261
{
262
  tree tmp;
263
  tree field;
264
 
265
  tmp = gfc_conv_descriptor_dimension (desc, dim);
266
  field = TYPE_FIELDS (TREE_TYPE (tmp));
267
  field = gfc_advance_chain (field, LBOUND_SUBFIELD);
268
  gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
269
 
270
  tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
271
  return tmp;
272
}
273
 
274
tree
275
gfc_conv_descriptor_ubound (tree desc, tree dim)
276
{
277
  tree tmp;
278
  tree field;
279
 
280
  tmp = gfc_conv_descriptor_dimension (desc, dim);
281
  field = TYPE_FIELDS (TREE_TYPE (tmp));
282
  field = gfc_advance_chain (field, UBOUND_SUBFIELD);
283
  gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
284
 
285
  tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
286
  return tmp;
287
}
288
 
289
 
290
/* Build a null array descriptor constructor.  */
291
 
292
tree
293
gfc_build_null_descriptor (tree type)
294
{
295
  tree field;
296
  tree tmp;
297
 
298
  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
299
  gcc_assert (DATA_FIELD == 0);
300
  field = TYPE_FIELDS (type);
301
 
302
  /* Set a NULL data pointer.  */
303
  tmp = build_constructor_single (type, field, null_pointer_node);
304
  TREE_CONSTANT (tmp) = 1;
305
  TREE_INVARIANT (tmp) = 1;
306
  /* All other fields are ignored.  */
307
 
308
  return tmp;
309
}
310
 
311
 
312
/* Cleanup those #defines.  */
313
 
314
#undef DATA_FIELD
315
#undef OFFSET_FIELD
316
#undef DTYPE_FIELD
317
#undef DIMENSION_FIELD
318
#undef STRIDE_SUBFIELD
319
#undef LBOUND_SUBFIELD
320
#undef UBOUND_SUBFIELD
321
 
322
 
323
/* Mark a SS chain as used.  Flags specifies in which loops the SS is used.
324
   flags & 1 = Main loop body.
325
   flags & 2 = temp copy loop.  */
326
 
327
void
328
gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
329
{
330
  for (; ss != gfc_ss_terminator; ss = ss->next)
331
    ss->useflags = flags;
332
}
333
 
334
static void gfc_free_ss (gfc_ss *);
335
 
336
 
337
/* Free a gfc_ss chain.  */
338
 
339
static void
340
gfc_free_ss_chain (gfc_ss * ss)
341
{
342
  gfc_ss *next;
343
 
344
  while (ss != gfc_ss_terminator)
345
    {
346
      gcc_assert (ss != NULL);
347
      next = ss->next;
348
      gfc_free_ss (ss);
349
      ss = next;
350
    }
351
}
352
 
353
 
354
/* Free a SS.  */
355
 
356
static void
357
gfc_free_ss (gfc_ss * ss)
358
{
359
  int n;
360
 
361
  switch (ss->type)
362
    {
363
    case GFC_SS_SECTION:
364
      for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
365
        {
366
          if (ss->data.info.subscript[n])
367
            gfc_free_ss_chain (ss->data.info.subscript[n]);
368
        }
369
      break;
370
 
371
    default:
372
      break;
373
    }
374
 
375
  gfc_free (ss);
376
}
377
 
378
 
379
/* Free all the SS associated with a loop.  */
380
 
381
void
382
gfc_cleanup_loop (gfc_loopinfo * loop)
383
{
384
  gfc_ss *ss;
385
  gfc_ss *next;
386
 
387
  ss = loop->ss;
388
  while (ss != gfc_ss_terminator)
389
    {
390
      gcc_assert (ss != NULL);
391
      next = ss->loop_chain;
392
      gfc_free_ss (ss);
393
      ss = next;
394
    }
395
}
396
 
397
 
398
/* Associate a SS chain with a loop.  */
399
 
400
void
401
gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
402
{
403
  gfc_ss *ss;
404
 
405
  if (head == gfc_ss_terminator)
406
    return;
407
 
408
  ss = head;
409
  for (; ss && ss != gfc_ss_terminator; ss = ss->next)
410
    {
411
      if (ss->next == gfc_ss_terminator)
412
        ss->loop_chain = loop->ss;
413
      else
414
        ss->loop_chain = ss->next;
415
    }
416
  gcc_assert (ss == gfc_ss_terminator);
417
  loop->ss = head;
418
}
419
 
420
 
421
/* Generate an initializer for a static pointer or allocatable array.  */
422
 
423
void
424
gfc_trans_static_array_pointer (gfc_symbol * sym)
425
{
426
  tree type;
427
 
428
  gcc_assert (TREE_STATIC (sym->backend_decl));
429
  /* Just zero the data member.  */
430
  type = TREE_TYPE (sym->backend_decl);
431
  DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
432
}
433
 
434
 
435
/* If the bounds of SE's loop have not yet been set, see if they can be
436
   determined from array spec AS, which is the array spec of a called
437
   function.  MAPPING maps the callee's dummy arguments to the values
438
   that the caller is passing.  Add any initialization and finalization
439
   code to SE.  */
440
 
441
void
442
gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
443
                                     gfc_se * se, gfc_array_spec * as)
444
{
445
  int n, dim;
446
  gfc_se tmpse;
447
  tree lower;
448
  tree upper;
449
  tree tmp;
450
 
451
  if (as && as->type == AS_EXPLICIT)
452
    for (dim = 0; dim < se->loop->dimen; dim++)
453
      {
454
        n = se->loop->order[dim];
455
        if (se->loop->to[n] == NULL_TREE)
456
          {
457
            /* Evaluate the lower bound.  */
458
            gfc_init_se (&tmpse, NULL);
459
            gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
460
            gfc_add_block_to_block (&se->pre, &tmpse.pre);
461
            gfc_add_block_to_block (&se->post, &tmpse.post);
462
            lower = tmpse.expr;
463
 
464
            /* ...and the upper bound.  */
465
            gfc_init_se (&tmpse, NULL);
466
            gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
467
            gfc_add_block_to_block (&se->pre, &tmpse.pre);
468
            gfc_add_block_to_block (&se->post, &tmpse.post);
469
            upper = tmpse.expr;
470
 
471
            /* Set the upper bound of the loop to UPPER - LOWER.  */
472
            tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, upper, lower);
473
            tmp = gfc_evaluate_now (tmp, &se->pre);
474
            se->loop->to[n] = tmp;
475
          }
476
      }
477
}
478
 
479
 
480
/* Generate code to allocate an array temporary, or create a variable to
481
   hold the data.  If size is NULL, zero the descriptor so that the
482
   callee will allocate the array.  If DEALLOC is true, also generate code to
483
   free the array afterwards.
484
 
485
   Initialization code is added to PRE and finalization code to POST.
486
   DYNAMIC is true if the caller may want to extend the array later
487
   using realloc.  This prevents us from putting the array on the stack.  */
488
 
489
static void
490
gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
491
                                  gfc_ss_info * info, tree size, tree nelem,
492
                                  bool dynamic, bool dealloc)
493
{
494
  tree tmp;
495
  tree args;
496
  tree desc;
497
  bool onstack;
498
 
499
  desc = info->descriptor;
500
  info->offset = gfc_index_zero_node;
501
  if (size == NULL_TREE || integer_zerop (size))
502
    {
503
      /* A callee allocated array.  */
504
      gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
505
      onstack = FALSE;
506
    }
507
  else
508
    {
509
      /* Allocate the temporary.  */
510
      onstack = !dynamic && gfc_can_put_var_on_stack (size);
511
 
512
      if (onstack)
513
        {
514
          /* Make a temporary variable to hold the data.  */
515
          tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (nelem), nelem,
516
                             integer_one_node);
517
          tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
518
                                  tmp);
519
          tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
520
                                  tmp);
521
          tmp = gfc_create_var (tmp, "A");
522
          tmp = gfc_build_addr_expr (NULL, tmp);
523
          gfc_conv_descriptor_data_set (pre, desc, tmp);
524
        }
525
      else
526
        {
527
          /* Allocate memory to hold the data.  */
528
          args = gfc_chainon_list (NULL_TREE, size);
529
 
530
          if (gfc_index_integer_kind == 4)
531
            tmp = gfor_fndecl_internal_malloc;
532
          else if (gfc_index_integer_kind == 8)
533
            tmp = gfor_fndecl_internal_malloc64;
534
          else
535
            gcc_unreachable ();
536
          tmp = gfc_build_function_call (tmp, args);
537
          tmp = gfc_evaluate_now (tmp, pre);
538
          gfc_conv_descriptor_data_set (pre, desc, tmp);
539
        }
540
    }
541
  info->data = gfc_conv_descriptor_data_get (desc);
542
 
543
  /* The offset is zero because we create temporaries with a zero
544
     lower bound.  */
545
  tmp = gfc_conv_descriptor_offset (desc);
546
  gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
547
 
548
  if (dealloc && !onstack)
549
    {
550
      /* Free the temporary.  */
551
      tmp = gfc_conv_descriptor_data_get (desc);
552
      tmp = fold_convert (pvoid_type_node, tmp);
553
      tmp = gfc_chainon_list (NULL_TREE, tmp);
554
      tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
555
      gfc_add_expr_to_block (post, tmp);
556
    }
557
}
558
 
559
 
560
/* Generate code to allocate and initialize the descriptor for a temporary
561
   array.  This is used for both temporaries needed by the scalarizer, and
562
   functions returning arrays.  Adjusts the loop variables to be zero-based,
563
   and calculates the loop bounds for callee allocated arrays.
564
   Also fills in the descriptor, data and offset fields of info if known.
565
   Returns the size of the array, or NULL for a callee allocated array.
566
 
567
   PRE, POST, DYNAMIC and DEALLOC are as for gfc_trans_allocate_array_storage.
568
 */
569
 
570
tree
571
gfc_trans_allocate_temp_array (stmtblock_t * pre, stmtblock_t * post,
572
                               gfc_loopinfo * loop, gfc_ss_info * info,
573
                               tree eltype, bool dynamic, bool dealloc)
574
{
575
  tree type;
576
  tree desc;
577
  tree tmp;
578
  tree size;
579
  tree nelem;
580
  int n;
581
  int dim;
582
 
583
  gcc_assert (info->dimen > 0);
584
  /* Set the lower bound to zero.  */
585
  for (dim = 0; dim < info->dimen; dim++)
586
    {
587
      n = loop->order[dim];
588
      if (n < loop->temp_dim)
589
        gcc_assert (integer_zerop (loop->from[n]));
590
      else
591
        {
592
          /* Callee allocated arrays may not have a known bound yet.  */
593
          if (loop->to[n])
594
              loop->to[n] = fold_build2 (MINUS_EXPR, gfc_array_index_type,
595
                                         loop->to[n], loop->from[n]);
596
          loop->from[n] = gfc_index_zero_node;
597
        }
598
 
599
      info->delta[dim] = gfc_index_zero_node;
600
      info->start[dim] = gfc_index_zero_node;
601
      info->stride[dim] = gfc_index_one_node;
602
      info->dim[dim] = dim;
603
    }
604
 
605
  /* Initialize the descriptor.  */
606
  type =
607
    gfc_get_array_type_bounds (eltype, info->dimen, loop->from, loop->to, 1);
608
  desc = gfc_create_var (type, "atmp");
609
  GFC_DECL_PACKED_ARRAY (desc) = 1;
610
 
611
  info->descriptor = desc;
612
  size = gfc_index_one_node;
613
 
614
  /* Fill in the array dtype.  */
615
  tmp = gfc_conv_descriptor_dtype (desc);
616
  gfc_add_modify_expr (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
617
 
618
  /*
619
     Fill in the bounds and stride.  This is a packed array, so:
620
 
621
     size = 1;
622
     for (n = 0; n < rank; n++)
623
       {
624
         stride[n] = size
625
         delta = ubound[n] + 1 - lbound[n];
626
         size = size * delta;
627
       }
628
     size = size * sizeof(element);
629
  */
630
 
631
  for (n = 0; n < info->dimen; n++)
632
    {
633
      if (loop->to[n] == NULL_TREE)
634
        {
635
          /* For a callee allocated array express the loop bounds in terms
636
             of the descriptor fields.  */
637
          tmp = build2 (MINUS_EXPR, gfc_array_index_type,
638
                        gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]),
639
                        gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]));
640
          loop->to[n] = tmp;
641
          size = NULL_TREE;
642
          continue;
643
        }
644
 
645
      /* Store the stride and bound components in the descriptor.  */
646
      tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[n]);
647
      gfc_add_modify_expr (pre, tmp, size);
648
 
649
      tmp = gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]);
650
      gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
651
 
652
      tmp = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]);
653
      gfc_add_modify_expr (pre, tmp, loop->to[n]);
654
 
655
      tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
656
                         loop->to[n], gfc_index_one_node);
657
 
658
      size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
659
      size = gfc_evaluate_now (size, pre);
660
    }
661
 
662
  /* Get the size of the array.  */
663
  nelem = size;
664
  if (size)
665
    size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
666
                        TYPE_SIZE_UNIT (gfc_get_element_type (type)));
667
 
668
  gfc_trans_allocate_array_storage (pre, post, info, size, nelem, dynamic,
669
                                    dealloc);
670
 
671
  if (info->dimen > loop->temp_dim)
672
    loop->temp_dim = info->dimen;
673
 
674
  return size;
675
}
676
 
677
 
678
/* Return the number of iterations in a loop that starts at START,
679
   ends at END, and has step STEP.  */
680
 
681
static tree
682
gfc_get_iteration_count (tree start, tree end, tree step)
683
{
684
  tree tmp;
685
  tree type;
686
 
687
  type = TREE_TYPE (step);
688
  tmp = fold_build2 (MINUS_EXPR, type, end, start);
689
  tmp = fold_build2 (FLOOR_DIV_EXPR, type, tmp, step);
690
  tmp = fold_build2 (PLUS_EXPR, type, tmp, build_int_cst (type, 1));
691
  tmp = fold_build2 (MAX_EXPR, type, tmp, build_int_cst (type, 0));
692
  return fold_convert (gfc_array_index_type, tmp);
693
}
694
 
695
 
696
/* Extend the data in array DESC by EXTRA elements.  */
697
 
698
static void
699
gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
700
{
701
  tree args;
702
  tree tmp;
703
  tree size;
704
  tree ubound;
705
 
706
  if (integer_zerop (extra))
707
    return;
708
 
709
  ubound = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
710
 
711
  /* Add EXTRA to the upper bound.  */
712
  tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, extra);
713
  gfc_add_modify_expr (pblock, ubound, tmp);
714
 
715
  /* Get the value of the current data pointer.  */
716
  tmp = gfc_conv_descriptor_data_get (desc);
717
  args = gfc_chainon_list (NULL_TREE, tmp);
718
 
719
  /* Calculate the new array size.  */
720
  size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
721
  tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, gfc_index_one_node);
722
  tmp = build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
723
  args = gfc_chainon_list (args, tmp);
724
 
725
  /* Pick the appropriate realloc function.  */
726
  if (gfc_index_integer_kind == 4)
727
    tmp = gfor_fndecl_internal_realloc;
728
  else if (gfc_index_integer_kind == 8)
729
    tmp = gfor_fndecl_internal_realloc64;
730
  else
731
    gcc_unreachable ();
732
 
733
  /* Set the new data pointer.  */
734
  tmp = gfc_build_function_call (tmp, args);
735
  gfc_conv_descriptor_data_set (pblock, desc, tmp);
736
}
737
 
738
 
739
/* Return true if the bounds of iterator I can only be determined
740
   at run time.  */
741
 
742
static inline bool
743
gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
744
{
745
  return (i->start->expr_type != EXPR_CONSTANT
746
          || i->end->expr_type != EXPR_CONSTANT
747
          || i->step->expr_type != EXPR_CONSTANT);
748
}
749
 
750
 
751
/* Split the size of constructor element EXPR into the sum of two terms,
752
   one of which can be determined at compile time and one of which must
753
   be calculated at run time.  Set *SIZE to the former and return true
754
   if the latter might be nonzero.  */
755
 
756
static bool
757
gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
758
{
759
  if (expr->expr_type == EXPR_ARRAY)
760
    return gfc_get_array_constructor_size (size, expr->value.constructor);
761
  else if (expr->rank > 0)
762
    {
763
      /* Calculate everything at run time.  */
764
      mpz_set_ui (*size, 0);
765
      return true;
766
    }
767
  else
768
    {
769
      /* A single element.  */
770
      mpz_set_ui (*size, 1);
771
      return false;
772
    }
773
}
774
 
775
 
776
/* Like gfc_get_array_constructor_element_size, but applied to the whole
777
   of array constructor C.  */
778
 
779
static bool
780
gfc_get_array_constructor_size (mpz_t * size, gfc_constructor * c)
781
{
782
  gfc_iterator *i;
783
  mpz_t val;
784
  mpz_t len;
785
  bool dynamic;
786
 
787
  mpz_set_ui (*size, 0);
788
  mpz_init (len);
789
  mpz_init (val);
790
 
791
  dynamic = false;
792
  for (; c; c = c->next)
793
    {
794
      i = c->iterator;
795
      if (i && gfc_iterator_has_dynamic_bounds (i))
796
        dynamic = true;
797
      else
798
        {
799
          dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
800
          if (i)
801
            {
802
              /* Multiply the static part of the element size by the
803
                 number of iterations.  */
804
              mpz_sub (val, i->end->value.integer, i->start->value.integer);
805
              mpz_fdiv_q (val, val, i->step->value.integer);
806
              mpz_add_ui (val, val, 1);
807
              if (mpz_sgn (val) > 0)
808
                mpz_mul (len, len, val);
809
              else
810
                mpz_set_ui (len, 0);
811
            }
812
          mpz_add (*size, *size, len);
813
        }
814
    }
815
  mpz_clear (len);
816
  mpz_clear (val);
817
  return dynamic;
818
}
819
 
820
 
821
/* Make sure offset is a variable.  */
822
 
823
static void
824
gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
825
                         tree * offsetvar)
826
{
827
  /* We should have already created the offset variable.  We cannot
828
     create it here because we may be in an inner scope.  */
829
  gcc_assert (*offsetvar != NULL_TREE);
830
  gfc_add_modify_expr (pblock, *offsetvar, *poffset);
831
  *poffset = *offsetvar;
832
  TREE_USED (*offsetvar) = 1;
833
}
834
 
835
 
836
/* Assign an element of an array constructor.  */
837
 
838
static void
839
gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
840
                              tree offset, gfc_se * se, gfc_expr * expr)
841
{
842
  tree tmp;
843
  tree args;
844
 
845
  gfc_conv_expr (se, expr);
846
 
847
  /* Store the value.  */
848
  tmp = gfc_build_indirect_ref (gfc_conv_descriptor_data_get (desc));
849
  tmp = gfc_build_array_ref (tmp, offset);
850
  if (expr->ts.type == BT_CHARACTER)
851
    {
852
      gfc_conv_string_parameter (se);
853
      if (POINTER_TYPE_P (TREE_TYPE (tmp)))
854
        {
855
          /* The temporary is an array of pointers.  */
856
          se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
857
          gfc_add_modify_expr (&se->pre, tmp, se->expr);
858
        }
859
      else
860
        {
861
          /* The temporary is an array of string values.  */
862
          tmp = gfc_build_addr_expr (pchar_type_node, tmp);
863
          /* We know the temporary and the value will be the same length,
864
             so can use memcpy.  */
865
          args = gfc_chainon_list (NULL_TREE, tmp);
866
          args = gfc_chainon_list (args, se->expr);
867
          args = gfc_chainon_list (args, se->string_length);
868
          tmp = built_in_decls[BUILT_IN_MEMCPY];
869
          tmp = gfc_build_function_call (tmp, args);
870
          gfc_add_expr_to_block (&se->pre, tmp);
871
        }
872
    }
873
  else
874
    {
875
      /* TODO: Should the frontend already have done this conversion?  */
876
      se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
877
      gfc_add_modify_expr (&se->pre, tmp, se->expr);
878
    }
879
 
880
  gfc_add_block_to_block (pblock, &se->pre);
881
  gfc_add_block_to_block (pblock, &se->post);
882
}
883
 
884
 
885
/* Add the contents of an array to the constructor.  DYNAMIC is as for
886
   gfc_trans_array_constructor_value.  */
887
 
888
static void
889
gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
890
                                      tree type ATTRIBUTE_UNUSED,
891
                                      tree desc, gfc_expr * expr,
892
                                      tree * poffset, tree * offsetvar,
893
                                      bool dynamic)
894
{
895
  gfc_se se;
896
  gfc_ss *ss;
897
  gfc_loopinfo loop;
898
  stmtblock_t body;
899
  tree tmp;
900
  tree size;
901
  int n;
902
 
903
  /* We need this to be a variable so we can increment it.  */
904
  gfc_put_offset_into_var (pblock, poffset, offsetvar);
905
 
906
  gfc_init_se (&se, NULL);
907
 
908
  /* Walk the array expression.  */
909
  ss = gfc_walk_expr (expr);
910
  gcc_assert (ss != gfc_ss_terminator);
911
 
912
  /* Initialize the scalarizer.  */
913
  gfc_init_loopinfo (&loop);
914
  gfc_add_ss_to_loop (&loop, ss);
915
 
916
  /* Initialize the loop.  */
917
  gfc_conv_ss_startstride (&loop);
918
  gfc_conv_loop_setup (&loop);
919
 
920
  /* Make sure the constructed array has room for the new data.  */
921
  if (dynamic)
922
    {
923
      /* Set SIZE to the total number of elements in the subarray.  */
924
      size = gfc_index_one_node;
925
      for (n = 0; n < loop.dimen; n++)
926
        {
927
          tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
928
                                         gfc_index_one_node);
929
          size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
930
        }
931
 
932
      /* Grow the constructed array by SIZE elements.  */
933
      gfc_grow_array (&loop.pre, desc, size);
934
    }
935
 
936
  /* Make the loop body.  */
937
  gfc_mark_ss_chain_used (ss, 1);
938
  gfc_start_scalarized_body (&loop, &body);
939
  gfc_copy_loopinfo_to_se (&se, &loop);
940
  se.ss = ss;
941
 
942
  if (expr->ts.type == BT_CHARACTER)
943
    gfc_todo_error ("character arrays in constructors");
944
 
945
  gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
946
  gcc_assert (se.ss == gfc_ss_terminator);
947
 
948
  /* Increment the offset.  */
949
  tmp = build2 (PLUS_EXPR, gfc_array_index_type, *poffset, gfc_index_one_node);
950
  gfc_add_modify_expr (&body, *poffset, tmp);
951
 
952
  /* Finish the loop.  */
953
  gfc_trans_scalarizing_loops (&loop, &body);
954
  gfc_add_block_to_block (&loop.pre, &loop.post);
955
  tmp = gfc_finish_block (&loop.pre);
956
  gfc_add_expr_to_block (pblock, tmp);
957
 
958
  gfc_cleanup_loop (&loop);
959
}
960
 
961
 
962
/* Assign the values to the elements of an array constructor.  DYNAMIC
963
   is true if descriptor DESC only contains enough data for the static
964
   size calculated by gfc_get_array_constructor_size.  When true, memory
965
   for the dynamic parts must be allocated using realloc.  */
966
 
967
static void
968
gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
969
                                   tree desc, gfc_constructor * c,
970
                                   tree * poffset, tree * offsetvar,
971
                                   bool dynamic)
972
{
973
  tree tmp;
974
  stmtblock_t body;
975
  gfc_se se;
976
  mpz_t size;
977
 
978
  mpz_init (size);
979
  for (; c; c = c->next)
980
    {
981
      /* If this is an iterator or an array, the offset must be a variable.  */
982
      if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
983
        gfc_put_offset_into_var (pblock, poffset, offsetvar);
984
 
985
      gfc_start_block (&body);
986
 
987
      if (c->expr->expr_type == EXPR_ARRAY)
988
        {
989
          /* Array constructors can be nested.  */
990
          gfc_trans_array_constructor_value (&body, type, desc,
991
                                             c->expr->value.constructor,
992
                                             poffset, offsetvar, dynamic);
993
        }
994
      else if (c->expr->rank > 0)
995
        {
996
          gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
997
                                                poffset, offsetvar, dynamic);
998
        }
999
      else
1000
        {
1001
          /* This code really upsets the gimplifier so don't bother for now.  */
1002
          gfc_constructor *p;
1003
          HOST_WIDE_INT n;
1004
          HOST_WIDE_INT size;
1005
 
1006
          p = c;
1007
          n = 0;
1008
          while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
1009
            {
1010
              p = p->next;
1011
              n++;
1012
            }
1013
          if (n < 4)
1014
            {
1015
              /* Scalar values.  */
1016
              gfc_init_se (&se, NULL);
1017
              gfc_trans_array_ctor_element (&body, desc, *poffset,
1018
                                            &se, c->expr);
1019
 
1020
              *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1021
                                      *poffset, gfc_index_one_node);
1022
            }
1023
          else
1024
            {
1025
              /* Collect multiple scalar constants into a constructor.  */
1026
              tree list;
1027
              tree init;
1028
              tree bound;
1029
              tree tmptype;
1030
 
1031
              p = c;
1032
              list = NULL_TREE;
1033
              /* Count the number of consecutive scalar constants.  */
1034
              while (p && !(p->iterator
1035
                            || p->expr->expr_type != EXPR_CONSTANT))
1036
                {
1037
                  gfc_init_se (&se, NULL);
1038
                  gfc_conv_constant (&se, p->expr);
1039
                  if (p->expr->ts.type == BT_CHARACTER
1040
                      && POINTER_TYPE_P (type))
1041
                    {
1042
                      /* For constant character array constructors we build
1043
                         an array of pointers.  */
1044
                      se.expr = gfc_build_addr_expr (pchar_type_node,
1045
                                                     se.expr);
1046
                    }
1047
 
1048
                  list = tree_cons (NULL_TREE, se.expr, list);
1049
                  c = p;
1050
                  p = p->next;
1051
                }
1052
 
1053
              bound = build_int_cst (NULL_TREE, n - 1);
1054
              /* Create an array type to hold them.  */
1055
              tmptype = build_range_type (gfc_array_index_type,
1056
                                          gfc_index_zero_node, bound);
1057
              tmptype = build_array_type (type, tmptype);
1058
 
1059
              init = build_constructor_from_list (tmptype, nreverse (list));
1060
              TREE_CONSTANT (init) = 1;
1061
              TREE_INVARIANT (init) = 1;
1062
              TREE_STATIC (init) = 1;
1063
              /* Create a static variable to hold the data.  */
1064
              tmp = gfc_create_var (tmptype, "data");
1065
              TREE_STATIC (tmp) = 1;
1066
              TREE_CONSTANT (tmp) = 1;
1067
              TREE_INVARIANT (tmp) = 1;
1068
              DECL_INITIAL (tmp) = init;
1069
              init = tmp;
1070
 
1071
              /* Use BUILTIN_MEMCPY to assign the values.  */
1072
              tmp = gfc_conv_descriptor_data_get (desc);
1073
              tmp = gfc_build_indirect_ref (tmp);
1074
              tmp = gfc_build_array_ref (tmp, *poffset);
1075
              tmp = gfc_build_addr_expr (NULL, tmp);
1076
              init = gfc_build_addr_expr (NULL, init);
1077
 
1078
              size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
1079
              bound = build_int_cst (NULL_TREE, n * size);
1080
              tmp = gfc_chainon_list (NULL_TREE, tmp);
1081
              tmp = gfc_chainon_list (tmp, init);
1082
              tmp = gfc_chainon_list (tmp, bound);
1083
              tmp = gfc_build_function_call (built_in_decls[BUILT_IN_MEMCPY],
1084
                                             tmp);
1085
              gfc_add_expr_to_block (&body, tmp);
1086
 
1087
              *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1088
                                      *poffset, build_int_cst (NULL_TREE, n));
1089
            }
1090
          if (!INTEGER_CST_P (*poffset))
1091
            {
1092
              gfc_add_modify_expr (&body, *offsetvar, *poffset);
1093
              *poffset = *offsetvar;
1094
            }
1095
        }
1096
 
1097
      /* The frontend should already have done any expansions possible
1098
         at compile-time.  */
1099
      if (!c->iterator)
1100
        {
1101
          /* Pass the code as is.  */
1102
          tmp = gfc_finish_block (&body);
1103
          gfc_add_expr_to_block (pblock, tmp);
1104
        }
1105
      else
1106
        {
1107
          /* Build the implied do-loop.  */
1108
          tree cond;
1109
          tree end;
1110
          tree step;
1111
          tree loopvar;
1112
          tree exit_label;
1113
          tree loopbody;
1114
          tree tmp2;
1115
 
1116
          loopbody = gfc_finish_block (&body);
1117
 
1118
          gfc_init_se (&se, NULL);
1119
          gfc_conv_expr (&se, c->iterator->var);
1120
          gfc_add_block_to_block (pblock, &se.pre);
1121
          loopvar = se.expr;
1122
 
1123
          /* Initialize the loop.  */
1124
          gfc_init_se (&se, NULL);
1125
          gfc_conv_expr_val (&se, c->iterator->start);
1126
          gfc_add_block_to_block (pblock, &se.pre);
1127
          gfc_add_modify_expr (pblock, loopvar, se.expr);
1128
 
1129
          gfc_init_se (&se, NULL);
1130
          gfc_conv_expr_val (&se, c->iterator->end);
1131
          gfc_add_block_to_block (pblock, &se.pre);
1132
          end = gfc_evaluate_now (se.expr, pblock);
1133
 
1134
          gfc_init_se (&se, NULL);
1135
          gfc_conv_expr_val (&se, c->iterator->step);
1136
          gfc_add_block_to_block (pblock, &se.pre);
1137
          step = gfc_evaluate_now (se.expr, pblock);
1138
 
1139
          /* If this array expands dynamically, and the number of iterations
1140
             is not constant, we won't have allocated space for the static
1141
             part of C->EXPR's size.  Do that now.  */
1142
          if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
1143
            {
1144
              /* Get the number of iterations.  */
1145
              tmp = gfc_get_iteration_count (loopvar, end, step);
1146
 
1147
              /* Get the static part of C->EXPR's size.  */
1148
              gfc_get_array_constructor_element_size (&size, c->expr);
1149
              tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1150
 
1151
              /* Grow the array by TMP * TMP2 elements.  */
1152
              tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, tmp2);
1153
              gfc_grow_array (pblock, desc, tmp);
1154
            }
1155
 
1156
          /* Generate the loop body.  */
1157
          exit_label = gfc_build_label_decl (NULL_TREE);
1158
          gfc_start_block (&body);
1159
 
1160
          /* Generate the exit condition.  Depending on the sign of
1161
             the step variable we have to generate the correct
1162
             comparison.  */
1163
          tmp = fold_build2 (GT_EXPR, boolean_type_node, step,
1164
                             build_int_cst (TREE_TYPE (step), 0));
1165
          cond = fold_build3 (COND_EXPR, boolean_type_node, tmp,
1166
                              build2 (GT_EXPR, boolean_type_node,
1167
                                      loopvar, end),
1168
                              build2 (LT_EXPR, boolean_type_node,
1169
                                      loopvar, end));
1170
          tmp = build1_v (GOTO_EXPR, exit_label);
1171
          TREE_USED (exit_label) = 1;
1172
          tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1173
          gfc_add_expr_to_block (&body, tmp);
1174
 
1175
          /* The main loop body.  */
1176
          gfc_add_expr_to_block (&body, loopbody);
1177
 
1178
          /* Increase loop variable by step.  */
1179
          tmp = build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
1180
          gfc_add_modify_expr (&body, loopvar, tmp);
1181
 
1182
          /* Finish the loop.  */
1183
          tmp = gfc_finish_block (&body);
1184
          tmp = build1_v (LOOP_EXPR, tmp);
1185
          gfc_add_expr_to_block (pblock, tmp);
1186
 
1187
          /* Add the exit label.  */
1188
          tmp = build1_v (LABEL_EXPR, exit_label);
1189
          gfc_add_expr_to_block (pblock, tmp);
1190
        }
1191
    }
1192
  mpz_clear (size);
1193
}
1194
 
1195
 
1196
/* Figure out the string length of a variable reference expression.
1197
   Used by get_array_ctor_strlen.  */
1198
 
1199
static void
1200
get_array_ctor_var_strlen (gfc_expr * expr, tree * len)
1201
{
1202
  gfc_ref *ref;
1203
  gfc_typespec *ts;
1204
 
1205
  /* Don't bother if we already know the length is a constant.  */
1206
  if (*len && INTEGER_CST_P (*len))
1207
    return;
1208
 
1209
  ts = &expr->symtree->n.sym->ts;
1210
  for (ref = expr->ref; ref; ref = ref->next)
1211
    {
1212
      switch (ref->type)
1213
        {
1214
        case REF_ARRAY:
1215
          /* Array references don't change the string length.  */
1216
          break;
1217
 
1218
        case REF_COMPONENT:
1219
          /* Use the length of the component.  */
1220
          ts = &ref->u.c.component->ts;
1221
          break;
1222
 
1223
        default:
1224
          /* TODO: Substrings are tricky because we can't evaluate the
1225
             expression more than once.  For now we just give up, and hope
1226
             we can figure it out elsewhere.  */
1227
          return;
1228
        }
1229
    }
1230
 
1231
  *len = ts->cl->backend_decl;
1232
}
1233
 
1234
 
1235
/* Figure out the string length of a character array constructor.
1236
   Returns TRUE if all elements are character constants.  */
1237
 
1238
bool
1239
get_array_ctor_strlen (gfc_constructor * c, tree * len)
1240
{
1241
  bool is_const;
1242
 
1243
  is_const = TRUE;
1244
  for (; c; c = c->next)
1245
    {
1246
      switch (c->expr->expr_type)
1247
        {
1248
        case EXPR_CONSTANT:
1249
          if (!(*len && INTEGER_CST_P (*len)))
1250
            *len = build_int_cstu (gfc_charlen_type_node,
1251
                                   c->expr->value.character.length);
1252
          break;
1253
 
1254
        case EXPR_ARRAY:
1255
          if (!get_array_ctor_strlen (c->expr->value.constructor, len))
1256
            is_const = FALSE;
1257
          break;
1258
 
1259
        case EXPR_VARIABLE:
1260
          is_const = false;
1261
          get_array_ctor_var_strlen (c->expr, len);
1262
          break;
1263
 
1264
        default:
1265
          is_const = FALSE;
1266
          /* TODO: For now we just ignore anything we don't know how to
1267
             handle, and hope we can figure it out a different way.  */
1268
          break;
1269
        }
1270
    }
1271
 
1272
  return is_const;
1273
}
1274
 
1275
 
1276
/* Array constructors are handled by constructing a temporary, then using that
1277
   within the scalarization loop.  This is not optimal, but seems by far the
1278
   simplest method.  */
1279
 
1280
static void
1281
gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
1282
{
1283
  gfc_constructor *c;
1284
  tree offset;
1285
  tree offsetvar;
1286
  tree desc;
1287
  tree type;
1288
  bool const_string;
1289
  bool dynamic;
1290
 
1291
  ss->data.info.dimen = loop->dimen;
1292
 
1293
  c = ss->expr->value.constructor;
1294
  if (ss->expr->ts.type == BT_CHARACTER)
1295
    {
1296
      const_string = get_array_ctor_strlen (c, &ss->string_length);
1297
      if (!ss->string_length)
1298
        gfc_todo_error ("complex character array constructors");
1299
 
1300
      type = gfc_get_character_type_len (ss->expr->ts.kind, ss->string_length);
1301
      if (const_string)
1302
        type = build_pointer_type (type);
1303
    }
1304
  else
1305
    {
1306
      const_string = TRUE;
1307
      type = gfc_typenode_for_spec (&ss->expr->ts);
1308
    }
1309
 
1310
  /* See if the constructor determines the loop bounds.  */
1311
  dynamic = false;
1312
  if (loop->to[0] == NULL_TREE)
1313
    {
1314
      mpz_t size;
1315
 
1316
      /* We should have a 1-dimensional, zero-based loop.  */
1317
      gcc_assert (loop->dimen == 1);
1318
      gcc_assert (integer_zerop (loop->from[0]));
1319
 
1320
      /* Split the constructor size into a static part and a dynamic part.
1321
         Allocate the static size up-front and record whether the dynamic
1322
         size might be nonzero.  */
1323
      mpz_init (size);
1324
      dynamic = gfc_get_array_constructor_size (&size, c);
1325
      mpz_sub_ui (size, size, 1);
1326
      loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1327
      mpz_clear (size);
1328
    }
1329
 
1330
  gfc_trans_allocate_temp_array (&loop->pre, &loop->post, loop,
1331
                                 &ss->data.info, type, dynamic, true);
1332
 
1333
  desc = ss->data.info.descriptor;
1334
  offset = gfc_index_zero_node;
1335
  offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
1336
  TREE_USED (offsetvar) = 0;
1337
  gfc_trans_array_constructor_value (&loop->pre, type, desc, c,
1338
                                     &offset, &offsetvar, dynamic);
1339
 
1340
  /* If the array grows dynamically, the upper bound of the loop variable
1341
     is determined by the array's final upper bound.  */
1342
  if (dynamic)
1343
    loop->to[0] = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
1344
 
1345
  if (TREE_USED (offsetvar))
1346
    pushdecl (offsetvar);
1347
  else
1348
    gcc_assert (INTEGER_CST_P (offset));
1349
#if 0
1350
  /* Disable bound checking for now because it's probably broken.  */
1351
  if (flag_bounds_check)
1352
    {
1353
      gcc_unreachable ();
1354
    }
1355
#endif
1356
}
1357
 
1358
 
1359
/* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
1360
   called after evaluating all of INFO's vector dimensions.  Go through
1361
   each such vector dimension and see if we can now fill in any missing
1362
   loop bounds.  */
1363
 
1364
static void
1365
gfc_set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss_info * info)
1366
{
1367
  gfc_se se;
1368
  tree tmp;
1369
  tree desc;
1370
  tree zero;
1371
  int n;
1372
  int dim;
1373
 
1374
  for (n = 0; n < loop->dimen; n++)
1375
    {
1376
      dim = info->dim[n];
1377
      if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR
1378
          && loop->to[n] == NULL)
1379
        {
1380
          /* Loop variable N indexes vector dimension DIM, and we don't
1381
             yet know the upper bound of loop variable N.  Set it to the
1382
             difference between the vector's upper and lower bounds.  */
1383
          gcc_assert (loop->from[n] == gfc_index_zero_node);
1384
          gcc_assert (info->subscript[dim]
1385
                      && info->subscript[dim]->type == GFC_SS_VECTOR);
1386
 
1387
          gfc_init_se (&se, NULL);
1388
          desc = info->subscript[dim]->data.info.descriptor;
1389
          zero = gfc_rank_cst[0];
1390
          tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1391
                             gfc_conv_descriptor_ubound (desc, zero),
1392
                             gfc_conv_descriptor_lbound (desc, zero));
1393
          tmp = gfc_evaluate_now (tmp, &loop->pre);
1394
          loop->to[n] = tmp;
1395
        }
1396
    }
1397
}
1398
 
1399
 
1400
/* Add the pre and post chains for all the scalar expressions in a SS chain
1401
   to loop.  This is called after the loop parameters have been calculated,
1402
   but before the actual scalarizing loops.  */
1403
 
1404
static void
1405
gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
1406
{
1407
  gfc_se se;
1408
  int n;
1409
 
1410
  /* TODO: This can generate bad code if there are ordering dependencies.
1411
     eg. a callee allocated function and an unknown size constructor.  */
1412
  gcc_assert (ss != NULL);
1413
 
1414
  for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
1415
    {
1416
      gcc_assert (ss);
1417
 
1418
      switch (ss->type)
1419
        {
1420
        case GFC_SS_SCALAR:
1421
          /* Scalar expression.  Evaluate this now.  This includes elemental
1422
             dimension indices, but not array section bounds.  */
1423
          gfc_init_se (&se, NULL);
1424
          gfc_conv_expr (&se, ss->expr);
1425
          gfc_add_block_to_block (&loop->pre, &se.pre);
1426
 
1427
          if (ss->expr->ts.type != BT_CHARACTER)
1428
            {
1429
              /* Move the evaluation of scalar expressions outside the
1430
                 scalarization loop.  */
1431
              if (subscript)
1432
                se.expr = convert(gfc_array_index_type, se.expr);
1433
              se.expr = gfc_evaluate_now (se.expr, &loop->pre);
1434
              gfc_add_block_to_block (&loop->pre, &se.post);
1435
            }
1436
          else
1437
            gfc_add_block_to_block (&loop->post, &se.post);
1438
 
1439
          ss->data.scalar.expr = se.expr;
1440
          ss->string_length = se.string_length;
1441
          break;
1442
 
1443
        case GFC_SS_REFERENCE:
1444
          /* Scalar reference.  Evaluate this now.  */
1445
          gfc_init_se (&se, NULL);
1446
          gfc_conv_expr_reference (&se, ss->expr);
1447
          gfc_add_block_to_block (&loop->pre, &se.pre);
1448
          gfc_add_block_to_block (&loop->post, &se.post);
1449
 
1450
          ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
1451
          ss->string_length = se.string_length;
1452
          break;
1453
 
1454
        case GFC_SS_SECTION:
1455
          /* Add the expressions for scalar and vector subscripts.  */
1456
          for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1457
            if (ss->data.info.subscript[n])
1458
              gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true);
1459
 
1460
          gfc_set_vector_loop_bounds (loop, &ss->data.info);
1461
          break;
1462
 
1463
        case GFC_SS_VECTOR:
1464
          /* Get the vector's descriptor and store it in SS.  */
1465
          gfc_init_se (&se, NULL);
1466
          gfc_conv_expr_descriptor (&se, ss->expr, gfc_walk_expr (ss->expr));
1467
          gfc_add_block_to_block (&loop->pre, &se.pre);
1468
          gfc_add_block_to_block (&loop->post, &se.post);
1469
          ss->data.info.descriptor = se.expr;
1470
          break;
1471
 
1472
        case GFC_SS_INTRINSIC:
1473
          gfc_add_intrinsic_ss_code (loop, ss);
1474
          break;
1475
 
1476
        case GFC_SS_FUNCTION:
1477
          /* Array function return value.  We call the function and save its
1478
             result in a temporary for use inside the loop.  */
1479
          gfc_init_se (&se, NULL);
1480
          se.loop = loop;
1481
          se.ss = ss;
1482
          gfc_conv_expr (&se, ss->expr);
1483
          gfc_add_block_to_block (&loop->pre, &se.pre);
1484
          gfc_add_block_to_block (&loop->post, &se.post);
1485
          ss->string_length = se.string_length;
1486
          break;
1487
 
1488
        case GFC_SS_CONSTRUCTOR:
1489
          gfc_trans_array_constructor (loop, ss);
1490
          break;
1491
 
1492
        case GFC_SS_TEMP:
1493
        case GFC_SS_COMPONENT:
1494
          /* Do nothing.  These are handled elsewhere.  */
1495
          break;
1496
 
1497
        default:
1498
          gcc_unreachable ();
1499
        }
1500
    }
1501
}
1502
 
1503
 
1504
/* Translate expressions for the descriptor and data pointer of a SS.  */
1505
/*GCC ARRAYS*/
1506
 
1507
static void
1508
gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
1509
{
1510
  gfc_se se;
1511
  tree tmp;
1512
 
1513
  /* Get the descriptor for the array to be scalarized.  */
1514
  gcc_assert (ss->expr->expr_type == EXPR_VARIABLE);
1515
  gfc_init_se (&se, NULL);
1516
  se.descriptor_only = 1;
1517
  gfc_conv_expr_lhs (&se, ss->expr);
1518
  gfc_add_block_to_block (block, &se.pre);
1519
  ss->data.info.descriptor = se.expr;
1520
  ss->string_length = se.string_length;
1521
 
1522
  if (base)
1523
    {
1524
      /* Also the data pointer.  */
1525
      tmp = gfc_conv_array_data (se.expr);
1526
      /* If this is a variable or address of a variable we use it directly.
1527
         Otherwise we must evaluate it now to avoid breaking dependency
1528
         analysis by pulling the expressions for elemental array indices
1529
         inside the loop.  */
1530
      if (!(DECL_P (tmp)
1531
            || (TREE_CODE (tmp) == ADDR_EXPR
1532
                && DECL_P (TREE_OPERAND (tmp, 0)))))
1533
        tmp = gfc_evaluate_now (tmp, block);
1534
      ss->data.info.data = tmp;
1535
 
1536
      tmp = gfc_conv_array_offset (se.expr);
1537
      ss->data.info.offset = gfc_evaluate_now (tmp, block);
1538
    }
1539
}
1540
 
1541
 
1542
/* Initialize a gfc_loopinfo structure.  */
1543
 
1544
void
1545
gfc_init_loopinfo (gfc_loopinfo * loop)
1546
{
1547
  int n;
1548
 
1549
  memset (loop, 0, sizeof (gfc_loopinfo));
1550
  gfc_init_block (&loop->pre);
1551
  gfc_init_block (&loop->post);
1552
 
1553
  /* Initially scalarize in order.  */
1554
  for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1555
    loop->order[n] = n;
1556
 
1557
  loop->ss = gfc_ss_terminator;
1558
}
1559
 
1560
 
1561
/* Copies the loop variable info to a gfc_se structure. Does not copy the SS
1562
   chain.  */
1563
 
1564
void
1565
gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
1566
{
1567
  se->loop = loop;
1568
}
1569
 
1570
 
1571
/* Return an expression for the data pointer of an array.  */
1572
 
1573
tree
1574
gfc_conv_array_data (tree descriptor)
1575
{
1576
  tree type;
1577
 
1578
  type = TREE_TYPE (descriptor);
1579
  if (GFC_ARRAY_TYPE_P (type))
1580
    {
1581
      if (TREE_CODE (type) == POINTER_TYPE)
1582
        return descriptor;
1583
      else
1584
        {
1585
          /* Descriptorless arrays.  */
1586
          return gfc_build_addr_expr (NULL, descriptor);
1587
        }
1588
    }
1589
  else
1590
    return gfc_conv_descriptor_data_get (descriptor);
1591
}
1592
 
1593
 
1594
/* Return an expression for the base offset of an array.  */
1595
 
1596
tree
1597
gfc_conv_array_offset (tree descriptor)
1598
{
1599
  tree type;
1600
 
1601
  type = TREE_TYPE (descriptor);
1602
  if (GFC_ARRAY_TYPE_P (type))
1603
    return GFC_TYPE_ARRAY_OFFSET (type);
1604
  else
1605
    return gfc_conv_descriptor_offset (descriptor);
1606
}
1607
 
1608
 
1609
/* Get an expression for the array stride.  */
1610
 
1611
tree
1612
gfc_conv_array_stride (tree descriptor, int dim)
1613
{
1614
  tree tmp;
1615
  tree type;
1616
 
1617
  type = TREE_TYPE (descriptor);
1618
 
1619
  /* For descriptorless arrays use the array size.  */
1620
  tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
1621
  if (tmp != NULL_TREE)
1622
    return tmp;
1623
 
1624
  tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[dim]);
1625
  return tmp;
1626
}
1627
 
1628
 
1629
/* Like gfc_conv_array_stride, but for the lower bound.  */
1630
 
1631
tree
1632
gfc_conv_array_lbound (tree descriptor, int dim)
1633
{
1634
  tree tmp;
1635
  tree type;
1636
 
1637
  type = TREE_TYPE (descriptor);
1638
 
1639
  tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
1640
  if (tmp != NULL_TREE)
1641
    return tmp;
1642
 
1643
  tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[dim]);
1644
  return tmp;
1645
}
1646
 
1647
 
1648
/* Like gfc_conv_array_stride, but for the upper bound.  */
1649
 
1650
tree
1651
gfc_conv_array_ubound (tree descriptor, int dim)
1652
{
1653
  tree tmp;
1654
  tree type;
1655
 
1656
  type = TREE_TYPE (descriptor);
1657
 
1658
  tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
1659
  if (tmp != NULL_TREE)
1660
    return tmp;
1661
 
1662
  /* This should only ever happen when passing an assumed shape array
1663
     as an actual parameter.  The value will never be used.  */
1664
  if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
1665
    return gfc_index_zero_node;
1666
 
1667
  tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[dim]);
1668
  return tmp;
1669
}
1670
 
1671
 
1672
/* Generate code to perform an array index bound check.  */
1673
 
1674
static tree
1675
gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n)
1676
{
1677
  tree cond;
1678
  tree fault;
1679
  tree tmp;
1680
 
1681
  if (!flag_bounds_check)
1682
    return index;
1683
 
1684
  index = gfc_evaluate_now (index, &se->pre);
1685
  /* Check lower bound.  */
1686
  tmp = gfc_conv_array_lbound (descriptor, n);
1687
  fault = fold_build2 (LT_EXPR, boolean_type_node, index, tmp);
1688
  /* Check upper bound.  */
1689
  tmp = gfc_conv_array_ubound (descriptor, n);
1690
  cond = fold_build2 (GT_EXPR, boolean_type_node, index, tmp);
1691
  fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1692
 
1693
  gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
1694
 
1695
  return index;
1696
}
1697
 
1698
 
1699
/* Return the offset for an index.  Performs bound checking for elemental
1700
   dimensions.  Single element references are processed separately.  */
1701
 
1702
static tree
1703
gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
1704
                             gfc_array_ref * ar, tree stride)
1705
{
1706
  tree index;
1707
  tree desc;
1708
  tree data;
1709
 
1710
  /* Get the index into the array for this dimension.  */
1711
  if (ar)
1712
    {
1713
      gcc_assert (ar->type != AR_ELEMENT);
1714
      switch (ar->dimen_type[dim])
1715
        {
1716
        case DIMEN_ELEMENT:
1717
          gcc_assert (i == -1);
1718
          /* Elemental dimension.  */
1719
          gcc_assert (info->subscript[dim]
1720
                      && info->subscript[dim]->type == GFC_SS_SCALAR);
1721
          /* We've already translated this value outside the loop.  */
1722
          index = info->subscript[dim]->data.scalar.expr;
1723
 
1724
          index =
1725
            gfc_trans_array_bound_check (se, info->descriptor, index, dim);
1726
          break;
1727
 
1728
        case DIMEN_VECTOR:
1729
          gcc_assert (info && se->loop);
1730
          gcc_assert (info->subscript[dim]
1731
                      && info->subscript[dim]->type == GFC_SS_VECTOR);
1732
          desc = info->subscript[dim]->data.info.descriptor;
1733
 
1734
          /* Get a zero-based index into the vector.  */
1735
          index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1736
                               se->loop->loopvar[i], se->loop->from[i]);
1737
 
1738
          /* Multiply the index by the stride.  */
1739
          index = fold_build2 (MULT_EXPR, gfc_array_index_type,
1740
                               index, gfc_conv_array_stride (desc, 0));
1741
 
1742
          /* Read the vector to get an index into info->descriptor.  */
1743
          data = gfc_build_indirect_ref (gfc_conv_array_data (desc));
1744
          index = gfc_build_array_ref (data, index);
1745
          index = gfc_evaluate_now (index, &se->pre);
1746
 
1747
          /* Do any bounds checking on the final info->descriptor index.  */
1748
          index = gfc_trans_array_bound_check (se, info->descriptor,
1749
                                               index, dim);
1750
          break;
1751
 
1752
        case DIMEN_RANGE:
1753
          /* Scalarized dimension.  */
1754
          gcc_assert (info && se->loop);
1755
 
1756
          /* Multiply the loop variable by the stride and delta.  */
1757
          index = se->loop->loopvar[i];
1758
          index = fold_build2 (MULT_EXPR, gfc_array_index_type, index,
1759
                               info->stride[i]);
1760
          index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index,
1761
                               info->delta[i]);
1762
          break;
1763
 
1764
        default:
1765
          gcc_unreachable ();
1766
        }
1767
    }
1768
  else
1769
    {
1770
      /* Temporary array or derived type component.  */
1771
      gcc_assert (se->loop);
1772
      index = se->loop->loopvar[se->loop->order[i]];
1773
      if (!integer_zerop (info->delta[i]))
1774
        index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1775
                             index, info->delta[i]);
1776
    }
1777
 
1778
  /* Multiply by the stride.  */
1779
  index = fold_build2 (MULT_EXPR, gfc_array_index_type, index, stride);
1780
 
1781
  return index;
1782
}
1783
 
1784
 
1785
/* Build a scalarized reference to an array.  */
1786
 
1787
static void
1788
gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
1789
{
1790
  gfc_ss_info *info;
1791
  tree index;
1792
  tree tmp;
1793
  int n;
1794
 
1795
  info = &se->ss->data.info;
1796
  if (ar)
1797
    n = se->loop->order[0];
1798
  else
1799
    n = 0;
1800
 
1801
  index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
1802
                                       info->stride0);
1803
  /* Add the offset for this dimension to the stored offset for all other
1804
     dimensions.  */
1805
  index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, info->offset);
1806
 
1807
  tmp = gfc_build_indirect_ref (info->data);
1808
  se->expr = gfc_build_array_ref (tmp, index);
1809
}
1810
 
1811
 
1812
/* Translate access of temporary array.  */
1813
 
1814
void
1815
gfc_conv_tmp_array_ref (gfc_se * se)
1816
{
1817
  se->string_length = se->ss->string_length;
1818
  gfc_conv_scalarized_array_ref (se, NULL);
1819
}
1820
 
1821
 
1822
/* Build an array reference.  se->expr already holds the array descriptor.
1823
   This should be either a variable, indirect variable reference or component
1824
   reference.  For arrays which do not have a descriptor, se->expr will be
1825
   the data pointer.
1826
   a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
1827
 
1828
void
1829
gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar)
1830
{
1831
  int n;
1832
  tree index;
1833
  tree tmp;
1834
  tree stride;
1835
  tree fault;
1836
  gfc_se indexse;
1837
 
1838
  /* Handle scalarized references separately.  */
1839
  if (ar->type != AR_ELEMENT)
1840
    {
1841
      gfc_conv_scalarized_array_ref (se, ar);
1842
      gfc_advance_se_ss_chain (se);
1843
      return;
1844
    }
1845
 
1846
  index = gfc_index_zero_node;
1847
 
1848
  fault = gfc_index_zero_node;
1849
 
1850
  /* Calculate the offsets from all the dimensions.  */
1851
  for (n = 0; n < ar->dimen; n++)
1852
    {
1853
      /* Calculate the index for this dimension.  */
1854
      gfc_init_se (&indexse, se);
1855
      gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
1856
      gfc_add_block_to_block (&se->pre, &indexse.pre);
1857
 
1858
      if (flag_bounds_check)
1859
        {
1860
          /* Check array bounds.  */
1861
          tree cond;
1862
 
1863
          indexse.expr = gfc_evaluate_now (indexse.expr, &se->pre);
1864
 
1865
          tmp = gfc_conv_array_lbound (se->expr, n);
1866
          cond = fold_build2 (LT_EXPR, boolean_type_node,
1867
                              indexse.expr, tmp);
1868
          fault =
1869
            fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1870
 
1871
          tmp = gfc_conv_array_ubound (se->expr, n);
1872
          cond = fold_build2 (GT_EXPR, boolean_type_node,
1873
                              indexse.expr, tmp);
1874
          fault =
1875
            fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1876
        }
1877
 
1878
      /* Multiply the index by the stride.  */
1879
      stride = gfc_conv_array_stride (se->expr, n);
1880
      tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indexse.expr,
1881
                         stride);
1882
 
1883
      /* And add it to the total.  */
1884
      index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1885
    }
1886
 
1887
  if (flag_bounds_check)
1888
    gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
1889
 
1890
  tmp = gfc_conv_array_offset (se->expr);
1891
  if (!integer_zerop (tmp))
1892
    index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1893
 
1894
  /* Access the calculated element.  */
1895
  tmp = gfc_conv_array_data (se->expr);
1896
  tmp = gfc_build_indirect_ref (tmp);
1897
  se->expr = gfc_build_array_ref (tmp, index);
1898
}
1899
 
1900
 
1901
/* Generate the code to be executed immediately before entering a
1902
   scalarization loop.  */
1903
 
1904
static void
1905
gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
1906
                         stmtblock_t * pblock)
1907
{
1908
  tree index;
1909
  tree stride;
1910
  gfc_ss_info *info;
1911
  gfc_ss *ss;
1912
  gfc_se se;
1913
  int i;
1914
 
1915
  /* This code will be executed before entering the scalarization loop
1916
     for this dimension.  */
1917
  for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
1918
    {
1919
      if ((ss->useflags & flag) == 0)
1920
        continue;
1921
 
1922
      if (ss->type != GFC_SS_SECTION
1923
          && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
1924
          && ss->type != GFC_SS_COMPONENT)
1925
        continue;
1926
 
1927
      info = &ss->data.info;
1928
 
1929
      if (dim >= info->dimen)
1930
        continue;
1931
 
1932
      if (dim == info->dimen - 1)
1933
        {
1934
          /* For the outermost loop calculate the offset due to any
1935
             elemental dimensions.  It will have been initialized with the
1936
             base offset of the array.  */
1937
          if (info->ref)
1938
            {
1939
              for (i = 0; i < info->ref->u.ar.dimen; i++)
1940
                {
1941
                  if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
1942
                    continue;
1943
 
1944
                  gfc_init_se (&se, NULL);
1945
                  se.loop = loop;
1946
                  se.expr = info->descriptor;
1947
                  stride = gfc_conv_array_stride (info->descriptor, i);
1948
                  index = gfc_conv_array_index_offset (&se, info, i, -1,
1949
                                                       &info->ref->u.ar,
1950
                                                       stride);
1951
                  gfc_add_block_to_block (pblock, &se.pre);
1952
 
1953
                  info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1954
                                              info->offset, index);
1955
                  info->offset = gfc_evaluate_now (info->offset, pblock);
1956
                }
1957
 
1958
              i = loop->order[0];
1959
              stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
1960
            }
1961
          else
1962
            stride = gfc_conv_array_stride (info->descriptor, 0);
1963
 
1964
          /* Calculate the stride of the innermost loop.  Hopefully this will
1965
             allow the backend optimizers to do their stuff more effectively.
1966
           */
1967
          info->stride0 = gfc_evaluate_now (stride, pblock);
1968
        }
1969
      else
1970
        {
1971
          /* Add the offset for the previous loop dimension.  */
1972
          gfc_array_ref *ar;
1973
 
1974
          if (info->ref)
1975
            {
1976
              ar = &info->ref->u.ar;
1977
              i = loop->order[dim + 1];
1978
            }
1979
          else
1980
            {
1981
              ar = NULL;
1982
              i = dim + 1;
1983
            }
1984
 
1985
          gfc_init_se (&se, NULL);
1986
          se.loop = loop;
1987
          se.expr = info->descriptor;
1988
          stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
1989
          index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
1990
                                               ar, stride);
1991
          gfc_add_block_to_block (pblock, &se.pre);
1992
          info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1993
                                      info->offset, index);
1994
          info->offset = gfc_evaluate_now (info->offset, pblock);
1995
        }
1996
 
1997
      /* Remember this offset for the second loop.  */
1998
      if (dim == loop->temp_dim - 1)
1999
        info->saved_offset = info->offset;
2000
    }
2001
}
2002
 
2003
 
2004
/* Start a scalarized expression.  Creates a scope and declares loop
2005
   variables.  */
2006
 
2007
void
2008
gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
2009
{
2010
  int dim;
2011
  int n;
2012
  int flags;
2013
 
2014
  gcc_assert (!loop->array_parameter);
2015
 
2016
  for (dim = loop->dimen - 1; dim >= 0; dim--)
2017
    {
2018
      n = loop->order[dim];
2019
 
2020
      gfc_start_block (&loop->code[n]);
2021
 
2022
      /* Create the loop variable.  */
2023
      loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
2024
 
2025
      if (dim < loop->temp_dim)
2026
        flags = 3;
2027
      else
2028
        flags = 1;
2029
      /* Calculate values that will be constant within this loop.  */
2030
      gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
2031
    }
2032
  gfc_start_block (pbody);
2033
}
2034
 
2035
 
2036
/* Generates the actual loop code for a scalarization loop.  */
2037
 
2038
static void
2039
gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
2040
                               stmtblock_t * pbody)
2041
{
2042
  stmtblock_t block;
2043
  tree cond;
2044
  tree tmp;
2045
  tree loopbody;
2046
  tree exit_label;
2047
 
2048
  loopbody = gfc_finish_block (pbody);
2049
 
2050
  /* Initialize the loopvar.  */
2051
  gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);
2052
 
2053
  exit_label = gfc_build_label_decl (NULL_TREE);
2054
 
2055
  /* Generate the loop body.  */
2056
  gfc_init_block (&block);
2057
 
2058
  /* The exit condition.  */
2059
  cond = build2 (GT_EXPR, boolean_type_node, loop->loopvar[n], loop->to[n]);
2060
  tmp = build1_v (GOTO_EXPR, exit_label);
2061
  TREE_USED (exit_label) = 1;
2062
  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2063
  gfc_add_expr_to_block (&block, tmp);
2064
 
2065
  /* The main body.  */
2066
  gfc_add_expr_to_block (&block, loopbody);
2067
 
2068
  /* Increment the loopvar.  */
2069
  tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2070
                loop->loopvar[n], gfc_index_one_node);
2071
  gfc_add_modify_expr (&block, loop->loopvar[n], tmp);
2072
 
2073
  /* Build the loop.  */
2074
  tmp = gfc_finish_block (&block);
2075
  tmp = build1_v (LOOP_EXPR, tmp);
2076
  gfc_add_expr_to_block (&loop->code[n], tmp);
2077
 
2078
  /* Add the exit label.  */
2079
  tmp = build1_v (LABEL_EXPR, exit_label);
2080
  gfc_add_expr_to_block (&loop->code[n], tmp);
2081
}
2082
 
2083
 
2084
/* Finishes and generates the loops for a scalarized expression.  */
2085
 
2086
void
2087
gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
2088
{
2089
  int dim;
2090
  int n;
2091
  gfc_ss *ss;
2092
  stmtblock_t *pblock;
2093
  tree tmp;
2094
 
2095
  pblock = body;
2096
  /* Generate the loops.  */
2097
  for (dim = 0; dim < loop->dimen; dim++)
2098
    {
2099
      n = loop->order[dim];
2100
      gfc_trans_scalarized_loop_end (loop, n, pblock);
2101
      loop->loopvar[n] = NULL_TREE;
2102
      pblock = &loop->code[n];
2103
    }
2104
 
2105
  tmp = gfc_finish_block (pblock);
2106
  gfc_add_expr_to_block (&loop->pre, tmp);
2107
 
2108
  /* Clear all the used flags.  */
2109
  for (ss = loop->ss; ss; ss = ss->loop_chain)
2110
    ss->useflags = 0;
2111
}
2112
 
2113
 
2114
/* Finish the main body of a scalarized expression, and start the secondary
2115
   copying body.  */
2116
 
2117
void
2118
gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
2119
{
2120
  int dim;
2121
  int n;
2122
  stmtblock_t *pblock;
2123
  gfc_ss *ss;
2124
 
2125
  pblock = body;
2126
  /* We finish as many loops as are used by the temporary.  */
2127
  for (dim = 0; dim < loop->temp_dim - 1; dim++)
2128
    {
2129
      n = loop->order[dim];
2130
      gfc_trans_scalarized_loop_end (loop, n, pblock);
2131
      loop->loopvar[n] = NULL_TREE;
2132
      pblock = &loop->code[n];
2133
    }
2134
 
2135
  /* We don't want to finish the outermost loop entirely.  */
2136
  n = loop->order[loop->temp_dim - 1];
2137
  gfc_trans_scalarized_loop_end (loop, n, pblock);
2138
 
2139
  /* Restore the initial offsets.  */
2140
  for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2141
    {
2142
      if ((ss->useflags & 2) == 0)
2143
        continue;
2144
 
2145
      if (ss->type != GFC_SS_SECTION
2146
          && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2147
          && ss->type != GFC_SS_COMPONENT)
2148
        continue;
2149
 
2150
      ss->data.info.offset = ss->data.info.saved_offset;
2151
    }
2152
 
2153
  /* Restart all the inner loops we just finished.  */
2154
  for (dim = loop->temp_dim - 2; dim >= 0; dim--)
2155
    {
2156
      n = loop->order[dim];
2157
 
2158
      gfc_start_block (&loop->code[n]);
2159
 
2160
      loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
2161
 
2162
      gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
2163
    }
2164
 
2165
  /* Start a block for the secondary copying code.  */
2166
  gfc_start_block (body);
2167
}
2168
 
2169
 
2170
/* Calculate the upper bound of an array section.  */
2171
 
2172
static tree
2173
gfc_conv_section_upper_bound (gfc_ss * ss, int n, stmtblock_t * pblock)
2174
{
2175
  int dim;
2176
  gfc_expr *end;
2177
  tree desc;
2178
  tree bound;
2179
  gfc_se se;
2180
  gfc_ss_info *info;
2181
 
2182
  gcc_assert (ss->type == GFC_SS_SECTION);
2183
 
2184
  info = &ss->data.info;
2185
  dim = info->dim[n];
2186
 
2187
  if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2188
    /* We'll calculate the upper bound once we have access to the
2189
       vector's descriptor.  */
2190
    return NULL;
2191
 
2192
  gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2193
  desc = info->descriptor;
2194
  end = info->ref->u.ar.end[dim];
2195
 
2196
  if (end)
2197
    {
2198
      /* The upper bound was specified.  */
2199
      gfc_init_se (&se, NULL);
2200
      gfc_conv_expr_type (&se, end, gfc_array_index_type);
2201
      gfc_add_block_to_block (pblock, &se.pre);
2202
      bound = se.expr;
2203
    }
2204
  else
2205
    {
2206
      /* No upper bound was specified, so use the bound of the array.  */
2207
      bound = gfc_conv_array_ubound (desc, dim);
2208
    }
2209
 
2210
  return bound;
2211
}
2212
 
2213
 
2214
/* Calculate the lower bound of an array section.  */
2215
 
2216
static void
2217
gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
2218
{
2219
  gfc_expr *start;
2220
  gfc_expr *stride;
2221
  tree desc;
2222
  gfc_se se;
2223
  gfc_ss_info *info;
2224
  int dim;
2225
 
2226
  gcc_assert (ss->type == GFC_SS_SECTION);
2227
 
2228
  info = &ss->data.info;
2229
  dim = info->dim[n];
2230
 
2231
  if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2232
    {
2233
      /* We use a zero-based index to access the vector.  */
2234
      info->start[n] = gfc_index_zero_node;
2235
      info->stride[n] = gfc_index_one_node;
2236
      return;
2237
    }
2238
 
2239
  gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2240
  desc = info->descriptor;
2241
  start = info->ref->u.ar.start[dim];
2242
  stride = info->ref->u.ar.stride[dim];
2243
 
2244
  /* Calculate the start of the range.  For vector subscripts this will
2245
     be the range of the vector.  */
2246
  if (start)
2247
    {
2248
      /* Specified section start.  */
2249
      gfc_init_se (&se, NULL);
2250
      gfc_conv_expr_type (&se, start, gfc_array_index_type);
2251
      gfc_add_block_to_block (&loop->pre, &se.pre);
2252
      info->start[n] = se.expr;
2253
    }
2254
  else
2255
    {
2256
      /* No lower bound specified so use the bound of the array.  */
2257
      info->start[n] = gfc_conv_array_lbound (desc, dim);
2258
    }
2259
  info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre);
2260
 
2261
  /* Calculate the stride.  */
2262
  if (stride == NULL)
2263
    info->stride[n] = gfc_index_one_node;
2264
  else
2265
    {
2266
      gfc_init_se (&se, NULL);
2267
      gfc_conv_expr_type (&se, stride, gfc_array_index_type);
2268
      gfc_add_block_to_block (&loop->pre, &se.pre);
2269
      info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre);
2270
    }
2271
}
2272
 
2273
 
2274
/* Calculates the range start and stride for a SS chain.  Also gets the
2275
   descriptor and data pointer.  The range of vector subscripts is the size
2276
   of the vector.  Array bounds are also checked.  */
2277
 
2278
void
2279
gfc_conv_ss_startstride (gfc_loopinfo * loop)
2280
{
2281
  int n;
2282
  tree tmp;
2283
  gfc_ss *ss;
2284
  tree desc;
2285
 
2286
  loop->dimen = 0;
2287
  /* Determine the rank of the loop.  */
2288
  for (ss = loop->ss;
2289
       ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
2290
    {
2291
      switch (ss->type)
2292
        {
2293
        case GFC_SS_SECTION:
2294
        case GFC_SS_CONSTRUCTOR:
2295
        case GFC_SS_FUNCTION:
2296
        case GFC_SS_COMPONENT:
2297
          loop->dimen = ss->data.info.dimen;
2298
          break;
2299
 
2300
        /* As usual, lbound and ubound are exceptions!.  */
2301
        case GFC_SS_INTRINSIC:
2302
          switch (ss->expr->value.function.isym->generic_id)
2303
            {
2304
            case GFC_ISYM_LBOUND:
2305
            case GFC_ISYM_UBOUND:
2306
              loop->dimen = ss->data.info.dimen;
2307
 
2308
            default:
2309
              break;
2310
            }
2311
 
2312
        default:
2313
          break;
2314
        }
2315
    }
2316
 
2317
  if (loop->dimen == 0)
2318
    gfc_todo_error ("Unable to determine rank of expression");
2319
 
2320
 
2321
  /* Loop over all the SS in the chain.  */
2322
  for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2323
    {
2324
      if (ss->expr && ss->expr->shape && !ss->shape)
2325
        ss->shape = ss->expr->shape;
2326
 
2327
      switch (ss->type)
2328
        {
2329
        case GFC_SS_SECTION:
2330
          /* Get the descriptor for the array.  */
2331
          gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
2332
 
2333
          for (n = 0; n < ss->data.info.dimen; n++)
2334
            gfc_conv_section_startstride (loop, ss, n);
2335
          break;
2336
 
2337
        case GFC_SS_INTRINSIC:
2338
          switch (ss->expr->value.function.isym->generic_id)
2339
            {
2340
            /* Fall through to supply start and stride.  */
2341
            case GFC_ISYM_LBOUND:
2342
            case GFC_ISYM_UBOUND:
2343
              break;
2344
            default:
2345
              continue;
2346
            }
2347
 
2348
        case GFC_SS_CONSTRUCTOR:
2349
        case GFC_SS_FUNCTION:
2350
          for (n = 0; n < ss->data.info.dimen; n++)
2351
            {
2352
              ss->data.info.start[n] = gfc_index_zero_node;
2353
              ss->data.info.stride[n] = gfc_index_one_node;
2354
            }
2355
          break;
2356
 
2357
        default:
2358
          break;
2359
        }
2360
    }
2361
 
2362
  /* The rest is just runtime bound checking.  */
2363
  if (flag_bounds_check)
2364
    {
2365
      stmtblock_t block;
2366
      tree fault;
2367
      tree bound;
2368
      tree end;
2369
      tree size[GFC_MAX_DIMENSIONS];
2370
      gfc_ss_info *info;
2371
      int dim;
2372
 
2373
      gfc_start_block (&block);
2374
 
2375
      fault = integer_zero_node;
2376
      for (n = 0; n < loop->dimen; n++)
2377
        size[n] = NULL_TREE;
2378
 
2379
      for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2380
        {
2381
          if (ss->type != GFC_SS_SECTION)
2382
            continue;
2383
 
2384
          /* TODO: range checking for mapped dimensions.  */
2385
          info = &ss->data.info;
2386
 
2387
          /* This code only checks ranges.  Elemental and vector
2388
             dimensions are checked later.  */
2389
          for (n = 0; n < loop->dimen; n++)
2390
            {
2391
              dim = info->dim[n];
2392
              if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
2393
                continue;
2394
 
2395
              desc = ss->data.info.descriptor;
2396
 
2397
              /* Check lower bound.  */
2398
              bound = gfc_conv_array_lbound (desc, dim);
2399
              tmp = info->start[n];
2400
              tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp, bound);
2401
              fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault,
2402
                                   tmp);
2403
 
2404
              /* Check the upper bound.  */
2405
              bound = gfc_conv_array_ubound (desc, dim);
2406
              end = gfc_conv_section_upper_bound (ss, n, &block);
2407
              tmp = fold_build2 (GT_EXPR, boolean_type_node, end, bound);
2408
              fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault,
2409
                                   tmp);
2410
 
2411
              /* Check the section sizes match.  */
2412
              tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2413
                                 info->start[n]);
2414
              tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
2415
                                 info->stride[n]);
2416
              /* We remember the size of the first section, and check all the
2417
                 others against this.  */
2418
              if (size[n])
2419
                {
2420
                  tmp =
2421
                    fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]);
2422
                  fault =
2423
                    build2 (TRUTH_OR_EXPR, boolean_type_node, fault, tmp);
2424
                }
2425
              else
2426
                size[n] = gfc_evaluate_now (tmp, &block);
2427
            }
2428
        }
2429
      gfc_trans_runtime_check (fault, gfc_strconst_bounds, &block);
2430
 
2431
      tmp = gfc_finish_block (&block);
2432
      gfc_add_expr_to_block (&loop->pre, tmp);
2433
    }
2434
}
2435
 
2436
 
2437
/* Return true if the two SS could be aliased, i.e. both point to the same data
2438
   object.  */
2439
/* TODO: resolve aliases based on frontend expressions.  */
2440
 
2441
static int
2442
gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
2443
{
2444
  gfc_ref *lref;
2445
  gfc_ref *rref;
2446
  gfc_symbol *lsym;
2447
  gfc_symbol *rsym;
2448
 
2449
  lsym = lss->expr->symtree->n.sym;
2450
  rsym = rss->expr->symtree->n.sym;
2451
  if (gfc_symbols_could_alias (lsym, rsym))
2452
    return 1;
2453
 
2454
  if (rsym->ts.type != BT_DERIVED
2455
      && lsym->ts.type != BT_DERIVED)
2456
    return 0;
2457
 
2458
  /* For derived types we must check all the component types.  We can ignore
2459
     array references as these will have the same base type as the previous
2460
     component ref.  */
2461
  for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
2462
    {
2463
      if (lref->type != REF_COMPONENT)
2464
        continue;
2465
 
2466
      if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
2467
        return 1;
2468
 
2469
      for (rref = rss->expr->ref; rref != rss->data.info.ref;
2470
           rref = rref->next)
2471
        {
2472
          if (rref->type != REF_COMPONENT)
2473
            continue;
2474
 
2475
          if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
2476
            return 1;
2477
        }
2478
    }
2479
 
2480
  for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
2481
    {
2482
      if (rref->type != REF_COMPONENT)
2483
        break;
2484
 
2485
      if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
2486
        return 1;
2487
    }
2488
 
2489
  return 0;
2490
}
2491
 
2492
 
2493
/* Resolve array data dependencies.  Creates a temporary if required.  */
2494
/* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
2495
   dependency.c.  */
2496
 
2497
void
2498
gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
2499
                               gfc_ss * rss)
2500
{
2501
  gfc_ss *ss;
2502
  gfc_ref *lref;
2503
  gfc_ref *rref;
2504
  gfc_ref *aref;
2505
  int nDepend = 0;
2506
  int temp_dim = 0;
2507
 
2508
  loop->temp_ss = NULL;
2509
  aref = dest->data.info.ref;
2510
  temp_dim = 0;
2511
 
2512
  for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
2513
    {
2514
      if (ss->type != GFC_SS_SECTION)
2515
        continue;
2516
 
2517
      if (gfc_could_be_alias (dest, ss)
2518
            || gfc_are_equivalenced_arrays (dest->expr, ss->expr))
2519
        {
2520
          nDepend = 1;
2521
          break;
2522
        }
2523
 
2524
      if (dest->expr->symtree->n.sym == ss->expr->symtree->n.sym)
2525
        {
2526
          lref = dest->expr->ref;
2527
          rref = ss->expr->ref;
2528
 
2529
          nDepend = gfc_dep_resolver (lref, rref);
2530
#if 0
2531
          /* TODO : loop shifting.  */
2532
          if (nDepend == 1)
2533
            {
2534
              /* Mark the dimensions for LOOP SHIFTING */
2535
              for (n = 0; n < loop->dimen; n++)
2536
                {
2537
                  int dim = dest->data.info.dim[n];
2538
 
2539
                  if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2540
                    depends[n] = 2;
2541
                  else if (! gfc_is_same_range (&lref->u.ar,
2542
                                                &rref->u.ar, dim, 0))
2543
                    depends[n] = 1;
2544
                 }
2545
 
2546
              /* Put all the dimensions with dependencies in the
2547
                 innermost loops.  */
2548
              dim = 0;
2549
              for (n = 0; n < loop->dimen; n++)
2550
                {
2551
                  gcc_assert (loop->order[n] == n);
2552
                  if (depends[n])
2553
                  loop->order[dim++] = n;
2554
                }
2555
              temp_dim = dim;
2556
              for (n = 0; n < loop->dimen; n++)
2557
                {
2558
                  if (! depends[n])
2559
                  loop->order[dim++] = n;
2560
                }
2561
 
2562
              gcc_assert (dim == loop->dimen);
2563
              break;
2564
            }
2565
#endif
2566
        }
2567
    }
2568
 
2569
  if (nDepend == 1)
2570
    {
2571
      tree base_type = gfc_typenode_for_spec (&dest->expr->ts);
2572
      if (GFC_ARRAY_TYPE_P (base_type)
2573
          || GFC_DESCRIPTOR_TYPE_P (base_type))
2574
        base_type = gfc_get_element_type (base_type);
2575
      loop->temp_ss = gfc_get_ss ();
2576
      loop->temp_ss->type = GFC_SS_TEMP;
2577
      loop->temp_ss->data.temp.type = base_type;
2578
      loop->temp_ss->string_length = dest->string_length;
2579
      loop->temp_ss->data.temp.dimen = loop->dimen;
2580
      loop->temp_ss->next = gfc_ss_terminator;
2581
      gfc_add_ss_to_loop (loop, loop->temp_ss);
2582
    }
2583
  else
2584
    loop->temp_ss = NULL;
2585
}
2586
 
2587
 
2588
/* Initialize the scalarization loop.  Creates the loop variables.  Determines
2589
   the range of the loop variables.  Creates a temporary if required.
2590
   Calculates how to transform from loop variables to array indices for each
2591
   expression.  Also generates code for scalar expressions which have been
2592
   moved outside the loop.  */
2593
 
2594
void
2595
gfc_conv_loop_setup (gfc_loopinfo * loop)
2596
{
2597
  int n;
2598
  int dim;
2599
  gfc_ss_info *info;
2600
  gfc_ss_info *specinfo;
2601
  gfc_ss *ss;
2602
  tree tmp;
2603
  tree len;
2604
  gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
2605
  bool dynamic[GFC_MAX_DIMENSIONS];
2606
  gfc_constructor *c;
2607
  mpz_t *cshape;
2608
  mpz_t i;
2609
 
2610
  mpz_init (i);
2611
  for (n = 0; n < loop->dimen; n++)
2612
    {
2613
      loopspec[n] = NULL;
2614
      dynamic[n] = false;
2615
      /* We use one SS term, and use that to determine the bounds of the
2616
         loop for this dimension.  We try to pick the simplest term.  */
2617
      for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2618
        {
2619
          if (ss->shape)
2620
            {
2621
              /* The frontend has worked out the size for us.  */
2622
              loopspec[n] = ss;
2623
              continue;
2624
            }
2625
 
2626
          if (ss->type == GFC_SS_CONSTRUCTOR)
2627
            {
2628
              /* An unknown size constructor will always be rank one.
2629
                 Higher rank constructors will either have known shape,
2630
                 or still be wrapped in a call to reshape.  */
2631
              gcc_assert (loop->dimen == 1);
2632
 
2633
              /* Always prefer to use the constructor bounds if the size
2634
                 can be determined at compile time.  Prefer not to otherwise,
2635
                 since the general case involves realloc, and it's better to
2636
                 avoid that overhead if possible.  */
2637
              c = ss->expr->value.constructor;
2638
              dynamic[n] = gfc_get_array_constructor_size (&i, c);
2639
              if (!dynamic[n] || !loopspec[n])
2640
                loopspec[n] = ss;
2641
              continue;
2642
            }
2643
 
2644
          /* TODO: Pick the best bound if we have a choice between a
2645
             function and something else.  */
2646
          if (ss->type == GFC_SS_FUNCTION)
2647
            {
2648
              loopspec[n] = ss;
2649
              continue;
2650
            }
2651
 
2652
          if (ss->type != GFC_SS_SECTION)
2653
            continue;
2654
 
2655
          if (loopspec[n])
2656
            specinfo = &loopspec[n]->data.info;
2657
          else
2658
            specinfo = NULL;
2659
          info = &ss->data.info;
2660
 
2661
          if (!specinfo)
2662
            loopspec[n] = ss;
2663
          /* Criteria for choosing a loop specifier (most important first):
2664
             doesn't need realloc
2665
             stride of one
2666
             known stride
2667
             known lower bound
2668
             known upper bound
2669
           */
2670
          else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n])
2671
            loopspec[n] = ss;
2672
          else if (integer_onep (info->stride[n])
2673
                   && !integer_onep (specinfo->stride[n]))
2674
            loopspec[n] = ss;
2675
          else if (INTEGER_CST_P (info->stride[n])
2676
                   && !INTEGER_CST_P (specinfo->stride[n]))
2677
            loopspec[n] = ss;
2678
          else if (INTEGER_CST_P (info->start[n])
2679
                   && !INTEGER_CST_P (specinfo->start[n]))
2680
            loopspec[n] = ss;
2681
          /* We don't work out the upper bound.
2682
             else if (INTEGER_CST_P (info->finish[n])
2683
             && ! INTEGER_CST_P (specinfo->finish[n]))
2684
             loopspec[n] = ss; */
2685
        }
2686
 
2687
      if (!loopspec[n])
2688
        gfc_todo_error ("Unable to find scalarization loop specifier");
2689
 
2690
      info = &loopspec[n]->data.info;
2691
 
2692
      /* Set the extents of this range.  */
2693
      cshape = loopspec[n]->shape;
2694
      if (cshape && INTEGER_CST_P (info->start[n])
2695
          && INTEGER_CST_P (info->stride[n]))
2696
        {
2697
          loop->from[n] = info->start[n];
2698
          mpz_set (i, cshape[n]);
2699
          mpz_sub_ui (i, i, 1);
2700
          /* To = from + (size - 1) * stride.  */
2701
          tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
2702
          if (!integer_onep (info->stride[n]))
2703
            tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2704
                               tmp, info->stride[n]);
2705
          loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2706
                                     loop->from[n], tmp);
2707
        }
2708
      else
2709
        {
2710
          loop->from[n] = info->start[n];
2711
          switch (loopspec[n]->type)
2712
            {
2713
            case GFC_SS_CONSTRUCTOR:
2714
              /* The upper bound is calculated when we expand the
2715
                 constructor.  */
2716
              gcc_assert (loop->to[n] == NULL_TREE);
2717
              break;
2718
 
2719
            case GFC_SS_SECTION:
2720
              loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n,
2721
                                                          &loop->pre);
2722
              break;
2723
 
2724
            case GFC_SS_FUNCTION:
2725
              /* The loop bound will be set when we generate the call.  */
2726
              gcc_assert (loop->to[n] == NULL_TREE);
2727
              break;
2728
 
2729
            default:
2730
              gcc_unreachable ();
2731
            }
2732
        }
2733
 
2734
      /* Transform everything so we have a simple incrementing variable.  */
2735
      if (integer_onep (info->stride[n]))
2736
        info->delta[n] = gfc_index_zero_node;
2737
      else
2738
        {
2739
          /* Set the delta for this section.  */
2740
          info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre);
2741
          /* Number of iterations is (end - start + step) / step.
2742
             with start = 0, this simplifies to
2743
             last = end / step;
2744
             for (i = 0; i<=last; i++){...};  */
2745
          tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2746
                             loop->to[n], loop->from[n]);
2747
          tmp = fold_build2 (TRUNC_DIV_EXPR, gfc_array_index_type,
2748
                             tmp, info->stride[n]);
2749
          loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
2750
          /* Make the loop variable start at 0.  */
2751
          loop->from[n] = gfc_index_zero_node;
2752
        }
2753
    }
2754
 
2755
  /* Add all the scalar code that can be taken out of the loops.
2756
     This may include calculating the loop bounds, so do it before
2757
     allocating the temporary.  */
2758
  gfc_add_loop_ss_code (loop, loop->ss, false);
2759
 
2760
  /* If we want a temporary then create it.  */
2761
  if (loop->temp_ss != NULL)
2762
    {
2763
      gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
2764
      tmp = loop->temp_ss->data.temp.type;
2765
      len = loop->temp_ss->string_length;
2766
      n = loop->temp_ss->data.temp.dimen;
2767
      memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
2768
      loop->temp_ss->type = GFC_SS_SECTION;
2769
      loop->temp_ss->data.info.dimen = n;
2770
      gfc_trans_allocate_temp_array (&loop->pre, &loop->post, loop,
2771
                                     &loop->temp_ss->data.info, tmp, false,
2772
                                     true);
2773
    }
2774
 
2775
  for (n = 0; n < loop->temp_dim; n++)
2776
    loopspec[loop->order[n]] = NULL;
2777
 
2778
  mpz_clear (i);
2779
 
2780
  /* For array parameters we don't have loop variables, so don't calculate the
2781
     translations.  */
2782
  if (loop->array_parameter)
2783
    return;
2784
 
2785
  /* Calculate the translation from loop variables to array indices.  */
2786
  for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2787
    {
2788
      if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT)
2789
        continue;
2790
 
2791
      info = &ss->data.info;
2792
 
2793
      for (n = 0; n < info->dimen; n++)
2794
        {
2795
          dim = info->dim[n];
2796
 
2797
          /* If we are specifying the range the delta is already set.  */
2798
          if (loopspec[n] != ss)
2799
            {
2800
              /* Calculate the offset relative to the loop variable.
2801
                 First multiply by the stride.  */
2802
              tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2803
                                 loop->from[n], info->stride[n]);
2804
 
2805
              /* Then subtract this from our starting value.  */
2806
              tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2807
                                 info->start[n], tmp);
2808
 
2809
              info->delta[n] = gfc_evaluate_now (tmp, &loop->pre);
2810
            }
2811
        }
2812
    }
2813
}
2814
 
2815
 
2816
/* Fills in an array descriptor, and returns the size of the array.  The size
2817
   will be a simple_val, ie a variable or a constant.  Also calculates the
2818
   offset of the base.  Returns the size of the array.
2819
   {
2820
    stride = 1;
2821
    offset = 0;
2822
    for (n = 0; n < rank; n++)
2823
      {
2824
        a.lbound[n] = specified_lower_bound;
2825
        offset = offset + a.lbond[n] * stride;
2826
        size = 1 - lbound;
2827
        a.ubound[n] = specified_upper_bound;
2828
        a.stride[n] = stride;
2829
        size = ubound + size; //size = ubound + 1 - lbound
2830
        stride = stride * size;
2831
      }
2832
    return (stride);
2833
   }  */
2834
/*GCC ARRAYS*/
2835
 
2836
static tree
2837
gfc_array_init_size (tree descriptor, int rank, tree * poffset,
2838
                     gfc_expr ** lower, gfc_expr ** upper,
2839
                     stmtblock_t * pblock)
2840
{
2841
  tree type;
2842
  tree tmp;
2843
  tree size;
2844
  tree offset;
2845
  tree stride;
2846
  tree cond;
2847
  tree or_expr;
2848
  tree thencase;
2849
  tree elsecase;
2850
  tree var;
2851
  stmtblock_t thenblock;
2852
  stmtblock_t elseblock;
2853
  gfc_expr *ubound;
2854
  gfc_se se;
2855
  int n;
2856
 
2857
  type = TREE_TYPE (descriptor);
2858
 
2859
  stride = gfc_index_one_node;
2860
  offset = gfc_index_zero_node;
2861
 
2862
  /* Set the dtype.  */
2863
  tmp = gfc_conv_descriptor_dtype (descriptor);
2864
  gfc_add_modify_expr (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
2865
 
2866
  or_expr = NULL_TREE;
2867
 
2868
  for (n = 0; n < rank; n++)
2869
    {
2870
      /* We have 3 possibilities for determining the size of the array:
2871
         lower == NULL    => lbound = 1, ubound = upper[n]
2872
         upper[n] = NULL  => lbound = 1, ubound = lower[n]
2873
         upper[n] != NULL => lbound = lower[n], ubound = upper[n]  */
2874
      ubound = upper[n];
2875
 
2876
      /* Set lower bound.  */
2877
      gfc_init_se (&se, NULL);
2878
      if (lower == NULL)
2879
        se.expr = gfc_index_one_node;
2880
      else
2881
        {
2882
          gcc_assert (lower[n]);
2883
          if (ubound)
2884
            {
2885
              gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
2886
              gfc_add_block_to_block (pblock, &se.pre);
2887
            }
2888
          else
2889
            {
2890
              se.expr = gfc_index_one_node;
2891
              ubound = lower[n];
2892
            }
2893
        }
2894
      tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
2895
      gfc_add_modify_expr (pblock, tmp, se.expr);
2896
 
2897
      /* Work out the offset for this component.  */
2898
      tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
2899
      offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
2900
 
2901
      /* Start the calculation for the size of this dimension.  */
2902
      size = build2 (MINUS_EXPR, gfc_array_index_type,
2903
                     gfc_index_one_node, se.expr);
2904
 
2905
      /* Set upper bound.  */
2906
      gfc_init_se (&se, NULL);
2907
      gcc_assert (ubound);
2908
      gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
2909
      gfc_add_block_to_block (pblock, &se.pre);
2910
 
2911
      tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
2912
      gfc_add_modify_expr (pblock, tmp, se.expr);
2913
 
2914
      /* Store the stride.  */
2915
      tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
2916
      gfc_add_modify_expr (pblock, tmp, stride);
2917
 
2918
      /* Calculate the size of this dimension.  */
2919
      size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
2920
 
2921
      /* Check wether the size for this dimension is negative.  */
2922
      cond = fold_build2 (LE_EXPR, boolean_type_node, size,
2923
                          gfc_index_zero_node);
2924
      if (n == 0)
2925
        or_expr = cond;
2926
      else
2927
        or_expr = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, or_expr, cond);
2928
 
2929
      /* Multiply the stride by the number of elements in this dimension.  */
2930
      stride = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, size);
2931
      stride = gfc_evaluate_now (stride, pblock);
2932
    }
2933
 
2934
  /* The stride is the number of elements in the array, so multiply by the
2935
     size of an element to get the total size.  */
2936
  tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
2937
  size = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, tmp);
2938
 
2939
  if (poffset != NULL)
2940
    {
2941
      offset = gfc_evaluate_now (offset, pblock);
2942
      *poffset = offset;
2943
    }
2944
 
2945
  var = gfc_create_var (TREE_TYPE (size), "size");
2946
  gfc_start_block (&thenblock);
2947
  gfc_add_modify_expr (&thenblock, var, gfc_index_zero_node);
2948
  thencase = gfc_finish_block (&thenblock);
2949
 
2950
  gfc_start_block (&elseblock);
2951
  gfc_add_modify_expr (&elseblock, var, size);
2952
  elsecase = gfc_finish_block (&elseblock);
2953
 
2954
  tmp = gfc_evaluate_now (or_expr, pblock);
2955
  tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
2956
  gfc_add_expr_to_block (pblock, tmp);
2957
 
2958
  return var;
2959
}
2960
 
2961
 
2962
/* Initializes the descriptor and generates a call to _gfor_allocate.  Does
2963
   the work for an ALLOCATE statement.  */
2964
/*GCC ARRAYS*/
2965
 
2966
bool
2967
gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat)
2968
{
2969
  tree tmp;
2970
  tree pointer;
2971
  tree allocate;
2972
  tree offset;
2973
  tree size;
2974
  gfc_expr **lower;
2975
  gfc_expr **upper;
2976
  gfc_ref *ref;
2977
  int allocatable_array;
2978
 
2979
  ref = expr->ref;
2980
 
2981
  /* Find the last reference in the chain.  */
2982
  while (ref && ref->next != NULL)
2983
    {
2984
      gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
2985
      ref = ref->next;
2986
    }
2987
 
2988
  if (ref == NULL || ref->type != REF_ARRAY)
2989
    return false;
2990
 
2991
  /* Figure out the size of the array.  */
2992
  switch (ref->u.ar.type)
2993
    {
2994
    case AR_ELEMENT:
2995
      lower = NULL;
2996
      upper = ref->u.ar.start;
2997
      break;
2998
 
2999
    case AR_FULL:
3000
      gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
3001
 
3002
      lower = ref->u.ar.as->lower;
3003
      upper = ref->u.ar.as->upper;
3004
      break;
3005
 
3006
    case AR_SECTION:
3007
      lower = ref->u.ar.start;
3008
      upper = ref->u.ar.end;
3009
      break;
3010
 
3011
    default:
3012
      gcc_unreachable ();
3013
      break;
3014
    }
3015
 
3016
  size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset,
3017
                              lower, upper, &se->pre);
3018
 
3019
  /* Allocate memory to store the data.  */
3020
  tmp = gfc_conv_descriptor_data_addr (se->expr);
3021
  pointer = gfc_evaluate_now (tmp, &se->pre);
3022
 
3023
  allocatable_array = expr->symtree->n.sym->attr.allocatable;
3024
 
3025
  if (TYPE_PRECISION (gfc_array_index_type) == 32)
3026
    {
3027
      if (allocatable_array)
3028
        allocate = gfor_fndecl_allocate_array;
3029
      else
3030
        allocate = gfor_fndecl_allocate;
3031
    }
3032
  else if (TYPE_PRECISION (gfc_array_index_type) == 64)
3033
    {
3034
      if (allocatable_array)
3035
        allocate = gfor_fndecl_allocate64_array;
3036
      else
3037
        allocate = gfor_fndecl_allocate64;
3038
    }
3039
  else
3040
    gcc_unreachable ();
3041
 
3042
  tmp = gfc_chainon_list (NULL_TREE, pointer);
3043
  tmp = gfc_chainon_list (tmp, size);
3044
  tmp = gfc_chainon_list (tmp, pstat);
3045
  tmp = gfc_build_function_call (allocate, tmp);
3046
  gfc_add_expr_to_block (&se->pre, tmp);
3047
 
3048
  tmp = gfc_conv_descriptor_offset (se->expr);
3049
  gfc_add_modify_expr (&se->pre, tmp, offset);
3050
 
3051
  return true;
3052
}
3053
 
3054
 
3055
/* Deallocate an array variable.  Also used when an allocated variable goes
3056
   out of scope.  */
3057
/*GCC ARRAYS*/
3058
 
3059
tree
3060
gfc_array_deallocate (tree descriptor, tree pstat)
3061
{
3062
  tree var;
3063
  tree tmp;
3064
  stmtblock_t block;
3065
 
3066
  gfc_start_block (&block);
3067
  /* Get a pointer to the data.  */
3068
  tmp = gfc_conv_descriptor_data_addr (descriptor);
3069
  var = gfc_evaluate_now (tmp, &block);
3070
 
3071
  /* Parameter is the address of the data component.  */
3072
  tmp = gfc_chainon_list (NULL_TREE, var);
3073
  tmp = gfc_chainon_list (tmp, pstat);
3074
  tmp = gfc_build_function_call (gfor_fndecl_deallocate, tmp);
3075
  gfc_add_expr_to_block (&block, tmp);
3076
 
3077
  return gfc_finish_block (&block);
3078
}
3079
 
3080
 
3081
/* Create an array constructor from an initialization expression.
3082
   We assume the frontend already did any expansions and conversions.  */
3083
 
3084
tree
3085
gfc_conv_array_initializer (tree type, gfc_expr * expr)
3086
{
3087
  gfc_constructor *c;
3088
  tree tmp;
3089
  mpz_t maxval;
3090
  gfc_se se;
3091
  HOST_WIDE_INT hi;
3092
  unsigned HOST_WIDE_INT lo;
3093
  tree index, range;
3094
  VEC(constructor_elt,gc) *v = NULL;
3095
 
3096
  switch (expr->expr_type)
3097
    {
3098
    case EXPR_CONSTANT:
3099
    case EXPR_STRUCTURE:
3100
      /* A single scalar or derived type value.  Create an array with all
3101
         elements equal to that value.  */
3102
      gfc_init_se (&se, NULL);
3103
 
3104
      if (expr->expr_type == EXPR_CONSTANT)
3105
        gfc_conv_constant (&se, expr);
3106
      else
3107
        gfc_conv_structure (&se, expr, 1);
3108
 
3109
      tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3110
      gcc_assert (tmp && INTEGER_CST_P (tmp));
3111
      hi = TREE_INT_CST_HIGH (tmp);
3112
      lo = TREE_INT_CST_LOW (tmp);
3113
      lo++;
3114
      if (lo == 0)
3115
        hi++;
3116
      /* This will probably eat buckets of memory for large arrays.  */
3117
      while (hi != 0 || lo != 0)
3118
        {
3119
          CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
3120
          if (lo == 0)
3121
            hi--;
3122
          lo--;
3123
        }
3124
      break;
3125
 
3126
    case EXPR_ARRAY:
3127
      /* Create a vector of all the elements.  */
3128
      for (c = expr->value.constructor; c; c = c->next)
3129
        {
3130
          if (c->iterator)
3131
            {
3132
              /* Problems occur when we get something like
3133
                 integer :: a(lots) = (/(i, i=1,lots)/)  */
3134
              /* TODO: Unexpanded array initializers.  */
3135
              internal_error
3136
                ("Possible frontend bug: array constructor not expanded");
3137
            }
3138
          if (mpz_cmp_si (c->n.offset, 0) != 0)
3139
            index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3140
          else
3141
            index = NULL_TREE;
3142
          mpz_init (maxval);
3143
          if (mpz_cmp_si (c->repeat, 0) != 0)
3144
            {
3145
              tree tmp1, tmp2;
3146
 
3147
              mpz_set (maxval, c->repeat);
3148
              mpz_add (maxval, c->n.offset, maxval);
3149
              mpz_sub_ui (maxval, maxval, 1);
3150
              tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3151
              if (mpz_cmp_si (c->n.offset, 0) != 0)
3152
                {
3153
                  mpz_add_ui (maxval, c->n.offset, 1);
3154
                  tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3155
                }
3156
              else
3157
                tmp1 = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3158
 
3159
              range = build2 (RANGE_EXPR, integer_type_node, tmp1, tmp2);
3160
            }
3161
          else
3162
            range = NULL;
3163
          mpz_clear (maxval);
3164
 
3165
          gfc_init_se (&se, NULL);
3166
          switch (c->expr->expr_type)
3167
            {
3168
            case EXPR_CONSTANT:
3169
              gfc_conv_constant (&se, c->expr);
3170
              if (range == NULL_TREE)
3171
                CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3172
              else
3173
                {
3174
                  if (index != NULL_TREE)
3175
                    CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3176
                  CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
3177
                }
3178
              break;
3179
 
3180
            case EXPR_STRUCTURE:
3181
              gfc_conv_structure (&se, c->expr, 1);
3182
              CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3183
              break;
3184
 
3185
            default:
3186
              gcc_unreachable ();
3187
            }
3188
        }
3189
      break;
3190
 
3191
    default:
3192
      gcc_unreachable ();
3193
    }
3194
 
3195
  /* Create a constructor from the list of elements.  */
3196
  tmp = build_constructor (type, v);
3197
  TREE_CONSTANT (tmp) = 1;
3198
  TREE_INVARIANT (tmp) = 1;
3199
  return tmp;
3200
}
3201
 
3202
 
3203
/* Generate code to evaluate non-constant array bounds.  Sets *poffset and
3204
   returns the size (in elements) of the array.  */
3205
 
3206
static tree
3207
gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
3208
                        stmtblock_t * pblock)
3209
{
3210
  gfc_array_spec *as;
3211
  tree size;
3212
  tree stride;
3213
  tree offset;
3214
  tree ubound;
3215
  tree lbound;
3216
  tree tmp;
3217
  gfc_se se;
3218
 
3219
  int dim;
3220
 
3221
  as = sym->as;
3222
 
3223
  size = gfc_index_one_node;
3224
  offset = gfc_index_zero_node;
3225
  for (dim = 0; dim < as->rank; dim++)
3226
    {
3227
      /* Evaluate non-constant array bound expressions.  */
3228
      lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
3229
      if (as->lower[dim] && !INTEGER_CST_P (lbound))
3230
        {
3231
          gfc_init_se (&se, NULL);
3232
          gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
3233
          gfc_add_block_to_block (pblock, &se.pre);
3234
          gfc_add_modify_expr (pblock, lbound, se.expr);
3235
        }
3236
      ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
3237
      if (as->upper[dim] && !INTEGER_CST_P (ubound))
3238
        {
3239
          gfc_init_se (&se, NULL);
3240
          gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
3241
          gfc_add_block_to_block (pblock, &se.pre);
3242
          gfc_add_modify_expr (pblock, ubound, se.expr);
3243
        }
3244
      /* The offset of this dimension.  offset = offset - lbound * stride.  */
3245
      tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, size);
3246
      offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3247
 
3248
      /* The size of this dimension, and the stride of the next.  */
3249
      if (dim + 1 < as->rank)
3250
        stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
3251
      else
3252
        stride = NULL_TREE;
3253
 
3254
      if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
3255
        {
3256
          /* Calculate stride = size * (ubound + 1 - lbound).  */
3257
          tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3258
                             gfc_index_one_node, lbound);
3259
          tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, tmp);
3260
          tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3261
          if (stride)
3262
            gfc_add_modify_expr (pblock, stride, tmp);
3263
          else
3264
            stride = gfc_evaluate_now (tmp, pblock);
3265
        }
3266
 
3267
      size = stride;
3268
    }
3269
 
3270
  *poffset = offset;
3271
  return size;
3272
}
3273
 
3274
 
3275
/* Generate code to initialize/allocate an array variable.  */
3276
 
3277
tree
3278
gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
3279
{
3280
  stmtblock_t block;
3281
  tree type;
3282
  tree tmp;
3283
  tree fndecl;
3284
  tree size;
3285
  tree offset;
3286
  bool onstack;
3287
 
3288
  gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
3289
 
3290
  /* Do nothing for USEd variables.  */
3291
  if (sym->attr.use_assoc)
3292
    return fnbody;
3293
 
3294
  type = TREE_TYPE (decl);
3295
  gcc_assert (GFC_ARRAY_TYPE_P (type));
3296
  onstack = TREE_CODE (type) != POINTER_TYPE;
3297
 
3298
  gfc_start_block (&block);
3299
 
3300
  /* Evaluate character string length.  */
3301
  if (sym->ts.type == BT_CHARACTER
3302
      && onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3303
    {
3304
      gfc_trans_init_string_length (sym->ts.cl, &block);
3305
 
3306
      /* Emit a DECL_EXPR for this variable, which will cause the
3307
         gimplifier to allocate storage, and all that good stuff.  */
3308
      tmp = build1 (DECL_EXPR, TREE_TYPE (decl), decl);
3309
      gfc_add_expr_to_block (&block, tmp);
3310
    }
3311
 
3312
  if (onstack)
3313
    {
3314
      gfc_add_expr_to_block (&block, fnbody);
3315
      return gfc_finish_block (&block);
3316
    }
3317
 
3318
  type = TREE_TYPE (type);
3319
 
3320
  gcc_assert (!sym->attr.use_assoc);
3321
  gcc_assert (!TREE_STATIC (decl));
3322
  gcc_assert (!sym->module);
3323
 
3324
  if (sym->ts.type == BT_CHARACTER
3325
      && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3326
    gfc_trans_init_string_length (sym->ts.cl, &block);
3327
 
3328
  size = gfc_trans_array_bounds (type, sym, &offset, &block);
3329
 
3330
  /* Don't actually allocate space for Cray Pointees.  */
3331
  if (sym->attr.cray_pointee)
3332
    {
3333
      if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3334
        gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3335
      gfc_add_expr_to_block (&block, fnbody);
3336
      return gfc_finish_block (&block);
3337
    }
3338
 
3339
  /* The size is the number of elements in the array, so multiply by the
3340
     size of an element to get the total size.  */
3341
  tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3342
  size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3343
 
3344
  /* Allocate memory to hold the data.  */
3345
  tmp = gfc_chainon_list (NULL_TREE, size);
3346
 
3347
  if (gfc_index_integer_kind == 4)
3348
    fndecl = gfor_fndecl_internal_malloc;
3349
  else if (gfc_index_integer_kind == 8)
3350
    fndecl = gfor_fndecl_internal_malloc64;
3351
  else
3352
    gcc_unreachable ();
3353
  tmp = gfc_build_function_call (fndecl, tmp);
3354
  tmp = fold (convert (TREE_TYPE (decl), tmp));
3355
  gfc_add_modify_expr (&block, decl, tmp);
3356
 
3357
  /* Set offset of the array.  */
3358
  if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3359
    gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3360
 
3361
 
3362
  /* Automatic arrays should not have initializers.  */
3363
  gcc_assert (!sym->value);
3364
 
3365
  gfc_add_expr_to_block (&block, fnbody);
3366
 
3367
  /* Free the temporary.  */
3368
  tmp = convert (pvoid_type_node, decl);
3369
  tmp = gfc_chainon_list (NULL_TREE, tmp);
3370
  tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
3371
  gfc_add_expr_to_block (&block, tmp);
3372
 
3373
  return gfc_finish_block (&block);
3374
}
3375
 
3376
 
3377
/* Generate entry and exit code for g77 calling convention arrays.  */
3378
 
3379
tree
3380
gfc_trans_g77_array (gfc_symbol * sym, tree body)
3381
{
3382
  tree parm;
3383
  tree type;
3384
  locus loc;
3385
  tree offset;
3386
  tree tmp;
3387
  stmtblock_t block;
3388
 
3389
  gfc_get_backend_locus (&loc);
3390
  gfc_set_backend_locus (&sym->declared_at);
3391
 
3392
  /* Descriptor type.  */
3393
  parm = sym->backend_decl;
3394
  type = TREE_TYPE (parm);
3395
  gcc_assert (GFC_ARRAY_TYPE_P (type));
3396
 
3397
  gfc_start_block (&block);
3398
 
3399
  if (sym->ts.type == BT_CHARACTER
3400
      && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3401
    gfc_trans_init_string_length (sym->ts.cl, &block);
3402
 
3403
  /* Evaluate the bounds of the array.  */
3404
  gfc_trans_array_bounds (type, sym, &offset, &block);
3405
 
3406
  /* Set the offset.  */
3407
  if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3408
    gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3409
 
3410
  /* Set the pointer itself if we aren't using the parameter directly.  */
3411
  if (TREE_CODE (parm) != PARM_DECL)
3412
    {
3413
      tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
3414
      gfc_add_modify_expr (&block, parm, tmp);
3415
    }
3416
  tmp = gfc_finish_block (&block);
3417
 
3418
  gfc_set_backend_locus (&loc);
3419
 
3420
  gfc_start_block (&block);
3421
  /* Add the initialization code to the start of the function.  */
3422
  gfc_add_expr_to_block (&block, tmp);
3423
  gfc_add_expr_to_block (&block, body);
3424
 
3425
  return gfc_finish_block (&block);
3426
}
3427
 
3428
 
3429
/* Modify the descriptor of an array parameter so that it has the
3430
   correct lower bound.  Also move the upper bound accordingly.
3431
   If the array is not packed, it will be copied into a temporary.
3432
   For each dimension we set the new lower and upper bounds.  Then we copy the
3433
   stride and calculate the offset for this dimension.  We also work out
3434
   what the stride of a packed array would be, and see it the two match.
3435
   If the array need repacking, we set the stride to the values we just
3436
   calculated, recalculate the offset and copy the array data.
3437
   Code is also added to copy the data back at the end of the function.
3438
   */
3439
 
3440
tree
3441
gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
3442
{
3443
  tree size;
3444
  tree type;
3445
  tree offset;
3446
  locus loc;
3447
  stmtblock_t block;
3448
  stmtblock_t cleanup;
3449
  tree lbound;
3450
  tree ubound;
3451
  tree dubound;
3452
  tree dlbound;
3453
  tree dumdesc;
3454
  tree tmp;
3455
  tree stmt;
3456
  tree stride;
3457
  tree stmt_packed;
3458
  tree stmt_unpacked;
3459
  tree partial;
3460
  gfc_se se;
3461
  int n;
3462
  int checkparm;
3463
  int no_repack;
3464
  bool optional_arg;
3465
 
3466
  /* Do nothing for pointer and allocatable arrays.  */
3467
  if (sym->attr.pointer || sym->attr.allocatable)
3468
    return body;
3469
 
3470
  if (sym->attr.dummy && gfc_is_nodesc_array (sym))
3471
    return gfc_trans_g77_array (sym, body);
3472
 
3473
  gfc_get_backend_locus (&loc);
3474
  gfc_set_backend_locus (&sym->declared_at);
3475
 
3476
  /* Descriptor type.  */
3477
  type = TREE_TYPE (tmpdesc);
3478
  gcc_assert (GFC_ARRAY_TYPE_P (type));
3479
  dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3480
  dumdesc = gfc_build_indirect_ref (dumdesc);
3481
  gfc_start_block (&block);
3482
 
3483
  if (sym->ts.type == BT_CHARACTER
3484
      && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3485
    gfc_trans_init_string_length (sym->ts.cl, &block);
3486
 
3487
  checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
3488
 
3489
  no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
3490
                || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
3491
 
3492
  if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
3493
    {
3494
      /* For non-constant shape arrays we only check if the first dimension
3495
         is contiguous.  Repacking higher dimensions wouldn't gain us
3496
         anything as we still don't know the array stride.  */
3497
      partial = gfc_create_var (boolean_type_node, "partial");
3498
      TREE_USED (partial) = 1;
3499
      tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3500
      tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, integer_one_node);
3501
      gfc_add_modify_expr (&block, partial, tmp);
3502
    }
3503
  else
3504
    {
3505
      partial = NULL_TREE;
3506
    }
3507
 
3508
  /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
3509
     here, however I think it does the right thing.  */
3510
  if (no_repack)
3511
    {
3512
      /* Set the first stride.  */
3513
      stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3514
      stride = gfc_evaluate_now (stride, &block);
3515
 
3516
      tmp = build2 (EQ_EXPR, boolean_type_node, stride, integer_zero_node);
3517
      tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
3518
                    gfc_index_one_node, stride);
3519
      stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
3520
      gfc_add_modify_expr (&block, stride, tmp);
3521
 
3522
      /* Allow the user to disable array repacking.  */
3523
      stmt_unpacked = NULL_TREE;
3524
    }
3525
  else
3526
    {
3527
      gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
3528
      /* A library call to repack the array if necessary.  */
3529
      tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3530
      tmp = gfc_chainon_list (NULL_TREE, tmp);
3531
      stmt_unpacked = gfc_build_function_call (gfor_fndecl_in_pack, tmp);
3532
 
3533
      stride = gfc_index_one_node;
3534
    }
3535
 
3536
  /* This is for the case where the array data is used directly without
3537
     calling the repack function.  */
3538
  if (no_repack || partial != NULL_TREE)
3539
    stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
3540
  else
3541
    stmt_packed = NULL_TREE;
3542
 
3543
  /* Assign the data pointer.  */
3544
  if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3545
    {
3546
      /* Don't repack unknown shape arrays when the first stride is 1.  */
3547
      tmp = build3 (COND_EXPR, TREE_TYPE (stmt_packed), partial,
3548
                    stmt_packed, stmt_unpacked);
3549
    }
3550
  else
3551
    tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
3552
  gfc_add_modify_expr (&block, tmpdesc, fold_convert (type, tmp));
3553
 
3554
  offset = gfc_index_zero_node;
3555
  size = gfc_index_one_node;
3556
 
3557
  /* Evaluate the bounds of the array.  */
3558
  for (n = 0; n < sym->as->rank; n++)
3559
    {
3560
      if (checkparm || !sym->as->upper[n])
3561
        {
3562
          /* Get the bounds of the actual parameter.  */
3563
          dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
3564
          dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
3565
        }
3566
      else
3567
        {
3568
          dubound = NULL_TREE;
3569
          dlbound = NULL_TREE;
3570
        }
3571
 
3572
      lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
3573
      if (!INTEGER_CST_P (lbound))
3574
        {
3575
          gfc_init_se (&se, NULL);
3576
          gfc_conv_expr_type (&se, sym->as->lower[n],
3577
                              gfc_array_index_type);
3578
          gfc_add_block_to_block (&block, &se.pre);
3579
          gfc_add_modify_expr (&block, lbound, se.expr);
3580
        }
3581
 
3582
      ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
3583
      /* Set the desired upper bound.  */
3584
      if (sym->as->upper[n])
3585
        {
3586
          /* We know what we want the upper bound to be.  */
3587
          if (!INTEGER_CST_P (ubound))
3588
            {
3589
              gfc_init_se (&se, NULL);
3590
              gfc_conv_expr_type (&se, sym->as->upper[n],
3591
                                  gfc_array_index_type);
3592
              gfc_add_block_to_block (&block, &se.pre);
3593
              gfc_add_modify_expr (&block, ubound, se.expr);
3594
            }
3595
 
3596
          /* Check the sizes match.  */
3597
          if (checkparm)
3598
            {
3599
              /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)).  */
3600
 
3601
              tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3602
                                 ubound, lbound);
3603
              stride = build2 (MINUS_EXPR, gfc_array_index_type,
3604
                               dubound, dlbound);
3605
              tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride);
3606
              gfc_trans_runtime_check (tmp, gfc_strconst_bounds, &block);
3607
            }
3608
        }
3609
      else
3610
        {
3611
          /* For assumed shape arrays move the upper bound by the same amount
3612
             as the lower bound.  */
3613
          tmp = build2 (MINUS_EXPR, gfc_array_index_type, dubound, dlbound);
3614
          tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp, lbound);
3615
          gfc_add_modify_expr (&block, ubound, tmp);
3616
        }
3617
      /* The offset of this dimension.  offset = offset - lbound * stride.  */
3618
      tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, stride);
3619
      offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3620
 
3621
      /* The size of this dimension, and the stride of the next.  */
3622
      if (n + 1 < sym->as->rank)
3623
        {
3624
          stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
3625
 
3626
          if (no_repack || partial != NULL_TREE)
3627
            {
3628
              stmt_unpacked =
3629
                gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
3630
            }
3631
 
3632
          /* Figure out the stride if not a known constant.  */
3633
          if (!INTEGER_CST_P (stride))
3634
            {
3635
              if (no_repack)
3636
                stmt_packed = NULL_TREE;
3637
              else
3638
                {
3639
                  /* Calculate stride = size * (ubound + 1 - lbound).  */
3640
                  tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3641
                                     gfc_index_one_node, lbound);
3642
                  tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3643
                                     ubound, tmp);
3644
                  size = fold_build2 (MULT_EXPR, gfc_array_index_type,
3645
                                      size, tmp);
3646
                  stmt_packed = size;
3647
                }
3648
 
3649
              /* Assign the stride.  */
3650
              if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3651
                tmp = build3 (COND_EXPR, gfc_array_index_type, partial,
3652
                              stmt_unpacked, stmt_packed);
3653
              else
3654
                tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
3655
              gfc_add_modify_expr (&block, stride, tmp);
3656
            }
3657
        }
3658
    }
3659
 
3660
  /* Set the offset.  */
3661
  if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3662
    gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3663
 
3664
  stmt = gfc_finish_block (&block);
3665
 
3666
  gfc_start_block (&block);
3667
 
3668
  /* Only do the entry/initialization code if the arg is present.  */
3669
  dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3670
  optional_arg = (sym->attr.optional
3671
                  || (sym->ns->proc_name->attr.entry_master
3672
                      && sym->attr.dummy));
3673
  if (optional_arg)
3674
    {
3675
      tmp = gfc_conv_expr_present (sym);
3676
      stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3677
    }
3678
  gfc_add_expr_to_block (&block, stmt);
3679
 
3680
  /* Add the main function body.  */
3681
  gfc_add_expr_to_block (&block, body);
3682
 
3683
  /* Cleanup code.  */
3684
  if (!no_repack)
3685
    {
3686
      gfc_start_block (&cleanup);
3687
 
3688
      if (sym->attr.intent != INTENT_IN)
3689
        {
3690
          /* Copy the data back.  */
3691
          tmp = gfc_chainon_list (NULL_TREE, dumdesc);
3692
          tmp = gfc_chainon_list (tmp, tmpdesc);
3693
          tmp = gfc_build_function_call (gfor_fndecl_in_unpack, tmp);
3694
          gfc_add_expr_to_block (&cleanup, tmp);
3695
        }
3696
 
3697
      /* Free the temporary.  */
3698
      tmp = gfc_chainon_list (NULL_TREE, tmpdesc);
3699
      tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
3700
      gfc_add_expr_to_block (&cleanup, tmp);
3701
 
3702
      stmt = gfc_finish_block (&cleanup);
3703
 
3704
      /* Only do the cleanup if the array was repacked.  */
3705
      tmp = gfc_build_indirect_ref (dumdesc);
3706
      tmp = gfc_conv_descriptor_data_get (tmp);
3707
      tmp = build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
3708
      stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3709
 
3710
      if (optional_arg)
3711
        {
3712
          tmp = gfc_conv_expr_present (sym);
3713
          stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3714
        }
3715
      gfc_add_expr_to_block (&block, stmt);
3716
    }
3717
  /* We don't need to free any memory allocated by internal_pack as it will
3718
     be freed at the end of the function by pop_context.  */
3719
  return gfc_finish_block (&block);
3720
}
3721
 
3722
 
3723
/* Convert an array for passing as an actual argument.  Expressions and
3724
   vector subscripts are evaluated and stored in a temporary, which is then
3725
   passed.  For whole arrays the descriptor is passed.  For array sections
3726
   a modified copy of the descriptor is passed, but using the original data.
3727
 
3728
   This function is also used for array pointer assignments, and there
3729
   are three cases:
3730
 
3731
     - want_pointer && !se->direct_byref
3732
         EXPR is an actual argument.  On exit, se->expr contains a
3733
         pointer to the array descriptor.
3734
 
3735
     - !want_pointer && !se->direct_byref
3736
         EXPR is an actual argument to an intrinsic function or the
3737
         left-hand side of a pointer assignment.  On exit, se->expr
3738
         contains the descriptor for EXPR.
3739
 
3740
     - !want_pointer && se->direct_byref
3741
         EXPR is the right-hand side of a pointer assignment and
3742
         se->expr is the descriptor for the previously-evaluated
3743
         left-hand side.  The function creates an assignment from
3744
         EXPR to se->expr.  */
3745
 
3746
void
3747
gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
3748
{
3749
  gfc_loopinfo loop;
3750
  gfc_ss *secss;
3751
  gfc_ss_info *info;
3752
  int need_tmp;
3753
  int n;
3754
  tree tmp;
3755
  tree desc;
3756
  stmtblock_t block;
3757
  tree start;
3758
  tree offset;
3759
  int full;
3760
  gfc_ref *ref;
3761
 
3762
  gcc_assert (ss != gfc_ss_terminator);
3763
 
3764
  /* TODO: Pass constant array constructors without a temporary.  */
3765
  /* Special case things we know we can pass easily.  */
3766
  switch (expr->expr_type)
3767
    {
3768
    case EXPR_VARIABLE:
3769
      /* If we have a linear array section, we can pass it directly.
3770
         Otherwise we need to copy it into a temporary.  */
3771
 
3772
      /* Find the SS for the array section.  */
3773
      secss = ss;
3774
      while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
3775
        secss = secss->next;
3776
 
3777
      gcc_assert (secss != gfc_ss_terminator);
3778
      info = &secss->data.info;
3779
 
3780
      /* Get the descriptor for the array.  */
3781
      gfc_conv_ss_descriptor (&se->pre, secss, 0);
3782
      desc = info->descriptor;
3783
 
3784
      need_tmp = gfc_ref_needs_temporary_p (expr->ref);
3785
      if (need_tmp)
3786
        full = 0;
3787
      else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
3788
        {
3789
          /* Create a new descriptor if the array doesn't have one.  */
3790
          full = 0;
3791
        }
3792
      else if (info->ref->u.ar.type == AR_FULL)
3793
        full = 1;
3794
      else if (se->direct_byref)
3795
        full = 0;
3796
      else
3797
        {
3798
          ref = info->ref;
3799
          gcc_assert (ref->u.ar.type == AR_SECTION);
3800
 
3801
          full = 1;
3802
          for (n = 0; n < ref->u.ar.dimen; n++)
3803
            {
3804
              /* Detect passing the full array as a section.  This could do
3805
                 even more checking, but it doesn't seem worth it.  */
3806
              if (ref->u.ar.start[n]
3807
                  || ref->u.ar.end[n]
3808
                  || (ref->u.ar.stride[n]
3809
                      && !gfc_expr_is_one (ref->u.ar.stride[n], 0)))
3810
                {
3811
                  full = 0;
3812
                  break;
3813
                }
3814
            }
3815
        }
3816
 
3817
      if (full)
3818
        {
3819
          if (se->direct_byref)
3820
            {
3821
              /* Copy the descriptor for pointer assignments.  */
3822
              gfc_add_modify_expr (&se->pre, se->expr, desc);
3823
            }
3824
          else if (se->want_pointer)
3825
            {
3826
              /* We pass full arrays directly.  This means that pointers and
3827
                 allocatable arrays should also work.  */
3828
              se->expr = gfc_build_addr_expr (NULL_TREE, desc);
3829
            }
3830
          else
3831
            {
3832
              se->expr = desc;
3833
            }
3834
 
3835
          if (expr->ts.type == BT_CHARACTER)
3836
            se->string_length = gfc_get_expr_charlen (expr);
3837
 
3838
          return;
3839
        }
3840
      break;
3841
 
3842
    case EXPR_FUNCTION:
3843
      /* A transformational function return value will be a temporary
3844
         array descriptor.  We still need to go through the scalarizer
3845
         to create the descriptor.  Elemental functions ar handled as
3846
         arbitrary expressions, i.e. copy to a temporary.  */
3847
      secss = ss;
3848
      /* Look for the SS for this function.  */
3849
      while (secss != gfc_ss_terminator
3850
             && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
3851
        secss = secss->next;
3852
 
3853
      if (se->direct_byref)
3854
        {
3855
          gcc_assert (secss != gfc_ss_terminator);
3856
 
3857
          /* For pointer assignments pass the descriptor directly.  */
3858
          se->ss = secss;
3859
          se->expr = gfc_build_addr_expr (NULL, se->expr);
3860
          gfc_conv_expr (se, expr);
3861
          return;
3862
        }
3863
 
3864
      if (secss == gfc_ss_terminator)
3865
        {
3866
          /* Elemental function.  */
3867
          need_tmp = 1;
3868
          info = NULL;
3869
        }
3870
      else
3871
        {
3872
          /* Transformational function.  */
3873
          info = &secss->data.info;
3874
          need_tmp = 0;
3875
        }
3876
      break;
3877
 
3878
    default:
3879
      /* Something complicated.  Copy it into a temporary.  */
3880
      need_tmp = 1;
3881
      secss = NULL;
3882
      info = NULL;
3883
      break;
3884
    }
3885
 
3886
 
3887
  gfc_init_loopinfo (&loop);
3888
 
3889
  /* Associate the SS with the loop.  */
3890
  gfc_add_ss_to_loop (&loop, ss);
3891
 
3892
  /* Tell the scalarizer not to bother creating loop variables, etc.  */
3893
  if (!need_tmp)
3894
    loop.array_parameter = 1;
3895
  else
3896
    /* The right-hand side of a pointer assignment mustn't use a temporary.  */
3897
    gcc_assert (!se->direct_byref);
3898
 
3899
  /* Setup the scalarizing loops and bounds.  */
3900
  gfc_conv_ss_startstride (&loop);
3901
 
3902
  if (need_tmp)
3903
    {
3904
      /* Tell the scalarizer to make a temporary.  */
3905
      loop.temp_ss = gfc_get_ss ();
3906
      loop.temp_ss->type = GFC_SS_TEMP;
3907
      loop.temp_ss->next = gfc_ss_terminator;
3908
      if (expr->ts.type == BT_CHARACTER)
3909
        {
3910
          if (expr->ts.cl
3911
              && expr->ts.cl->length
3912
              && expr->ts.cl->length->expr_type == EXPR_CONSTANT)
3913
            {
3914
              expr->ts.cl->backend_decl
3915
                = gfc_conv_mpz_to_tree (expr->ts.cl->length->value.integer,
3916
                                        expr->ts.cl->length->ts.kind);
3917
              loop.temp_ss->data.temp.type
3918
                = gfc_typenode_for_spec (&expr->ts);
3919
              loop.temp_ss->string_length
3920
                = TYPE_SIZE_UNIT (loop.temp_ss->data.temp.type);
3921
            }
3922
          else
3923
            {
3924
              loop.temp_ss->data.temp.type
3925
                = gfc_typenode_for_spec (&expr->ts);
3926
              loop.temp_ss->string_length = expr->ts.cl->backend_decl;
3927
            }
3928
          se->string_length = loop.temp_ss->string_length;
3929
        }
3930
      else
3931
        {
3932
          loop.temp_ss->data.temp.type
3933
            = gfc_typenode_for_spec (&expr->ts);
3934
          loop.temp_ss->string_length = NULL;
3935
        }
3936
      loop.temp_ss->data.temp.dimen = loop.dimen;
3937
      gfc_add_ss_to_loop (&loop, loop.temp_ss);
3938
    }
3939
 
3940
  gfc_conv_loop_setup (&loop);
3941
 
3942
  if (need_tmp)
3943
    {
3944
      /* Copy into a temporary and pass that.  We don't need to copy the data
3945
         back because expressions and vector subscripts must be INTENT_IN.  */
3946
      /* TODO: Optimize passing function return values.  */
3947
      gfc_se lse;
3948
      gfc_se rse;
3949
 
3950
      /* Start the copying loops.  */
3951
      gfc_mark_ss_chain_used (loop.temp_ss, 1);
3952
      gfc_mark_ss_chain_used (ss, 1);
3953
      gfc_start_scalarized_body (&loop, &block);
3954
 
3955
      /* Copy each data element.  */
3956
      gfc_init_se (&lse, NULL);
3957
      gfc_copy_loopinfo_to_se (&lse, &loop);
3958
      gfc_init_se (&rse, NULL);
3959
      gfc_copy_loopinfo_to_se (&rse, &loop);
3960
 
3961
      lse.ss = loop.temp_ss;
3962
      rse.ss = ss;
3963
 
3964
      gfc_conv_scalarized_array_ref (&lse, NULL);
3965
      if (expr->ts.type == BT_CHARACTER)
3966
        {
3967
          gfc_conv_expr (&rse, expr);
3968
          if (POINTER_TYPE_P (TREE_TYPE (rse.expr)))
3969
            rse.expr = gfc_build_indirect_ref (rse.expr);
3970
        }
3971
      else
3972
        gfc_conv_expr_val (&rse, expr);
3973
 
3974
      gfc_add_block_to_block (&block, &rse.pre);
3975
      gfc_add_block_to_block (&block, &lse.pre);
3976
 
3977
      gfc_add_modify_expr (&block, lse.expr, rse.expr);
3978
 
3979
      /* Finish the copying loops.  */
3980
      gfc_trans_scalarizing_loops (&loop, &block);
3981
 
3982
      /* Set the first stride component to zero to indicate a temporary.  */
3983
      desc = loop.temp_ss->data.info.descriptor;
3984
      tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[0]);
3985
      gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
3986
 
3987
      gcc_assert (is_gimple_lvalue (desc));
3988
    }
3989
  else if (expr->expr_type == EXPR_FUNCTION)
3990
    {
3991
      desc = info->descriptor;
3992
      se->string_length = ss->string_length;
3993
    }
3994
  else
3995
    {
3996
      /* We pass sections without copying to a temporary.  Make a new
3997
         descriptor and point it at the section we want.  The loop variable
3998
         limits will be the limits of the section.
3999
         A function may decide to repack the array to speed up access, but
4000
         we're not bothered about that here.  */
4001
      int dim;
4002
      tree parm;
4003
      tree parmtype;
4004
      tree stride;
4005
      tree from;
4006
      tree to;
4007
      tree base;
4008
 
4009
      /* Set the string_length for a character array.  */
4010
      if (expr->ts.type == BT_CHARACTER)
4011
        se->string_length =  gfc_get_expr_charlen (expr);
4012
 
4013
      desc = info->descriptor;
4014
      gcc_assert (secss && secss != gfc_ss_terminator);
4015
      if (se->direct_byref)
4016
        {
4017
          /* For pointer assignments we fill in the destination.  */
4018
          parm = se->expr;
4019
          parmtype = TREE_TYPE (parm);
4020
        }
4021
      else
4022
        {
4023
          /* Otherwise make a new one.  */
4024
          parmtype = gfc_get_element_type (TREE_TYPE (desc));
4025
          parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
4026
                                                loop.from, loop.to, 0);
4027
          parm = gfc_create_var (parmtype, "parm");
4028
        }
4029
 
4030
      offset = gfc_index_zero_node;
4031
      dim = 0;
4032
 
4033
      /* The following can be somewhat confusing.  We have two
4034
         descriptors, a new one and the original array.
4035
         {parm, parmtype, dim} refer to the new one.
4036
         {desc, type, n, secss, loop} refer to the original, which maybe
4037
         a descriptorless array.
4038
         The bounds of the scalarization are the bounds of the section.
4039
         We don't have to worry about numeric overflows when calculating
4040
         the offsets because all elements are within the array data.  */
4041
 
4042
      /* Set the dtype.  */
4043
      tmp = gfc_conv_descriptor_dtype (parm);
4044
      gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
4045
 
4046
      if (se->direct_byref)
4047
        base = gfc_index_zero_node;
4048
      else
4049
        base = NULL_TREE;
4050
 
4051
      for (n = 0; n < info->ref->u.ar.dimen; n++)
4052
        {
4053
          stride = gfc_conv_array_stride (desc, n);
4054
 
4055
          /* Work out the offset.  */
4056
          if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4057
            {
4058
              gcc_assert (info->subscript[n]
4059
                      && info->subscript[n]->type == GFC_SS_SCALAR);
4060
              start = info->subscript[n]->data.scalar.expr;
4061
            }
4062
          else
4063
            {
4064
              /* Check we haven't somehow got out of sync.  */
4065
              gcc_assert (info->dim[dim] == n);
4066
 
4067
              /* Evaluate and remember the start of the section.  */
4068
              start = info->start[dim];
4069
              stride = gfc_evaluate_now (stride, &loop.pre);
4070
            }
4071
 
4072
          tmp = gfc_conv_array_lbound (desc, n);
4073
          tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), start, tmp);
4074
 
4075
          tmp = fold_build2 (MULT_EXPR, TREE_TYPE (tmp), tmp, stride);
4076
          offset = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp);
4077
 
4078
          if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4079
            {
4080
              /* For elemental dimensions, we only need the offset.  */
4081
              continue;
4082
            }
4083
 
4084
          /* Vector subscripts need copying and are handled elsewhere.  */
4085
          gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
4086
 
4087
          /* Set the new lower bound.  */
4088
          from = loop.from[dim];
4089
          to = loop.to[dim];
4090
 
4091
          /* If we have an array section or are assigning to a pointer,
4092
             make sure that the lower bound is 1.  References to the full
4093
             array should otherwise keep the original bounds.  */
4094
          if ((info->ref->u.ar.type != AR_FULL || se->direct_byref)
4095
              && !integer_onep (from))
4096
            {
4097
              tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4098
                                 gfc_index_one_node, from);
4099
              to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
4100
              from = gfc_index_one_node;
4101
            }
4102
          tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
4103
          gfc_add_modify_expr (&loop.pre, tmp, from);
4104
 
4105
          /* Set the new upper bound.  */
4106
          tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
4107
          gfc_add_modify_expr (&loop.pre, tmp, to);
4108
 
4109
          /* Multiply the stride by the section stride to get the
4110
             total stride.  */
4111
          stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
4112
                                stride, info->stride[dim]);
4113
 
4114
          if (se->direct_byref)
4115
            base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4116
                                base, stride);
4117
 
4118
          /* Store the new stride.  */
4119
          tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
4120
          gfc_add_modify_expr (&loop.pre, tmp, stride);
4121
 
4122
          dim++;
4123
        }
4124
 
4125
      if (se->data_not_needed)
4126
        gfc_conv_descriptor_data_set (&loop.pre, parm, gfc_index_zero_node);
4127
      else
4128
        {
4129
          /* Point the data pointer at the first element in the section.  */
4130
          tmp = gfc_conv_array_data (desc);
4131
          tmp = build_fold_indirect_ref (tmp);
4132
          tmp = gfc_build_array_ref (tmp, offset);
4133
          offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
4134
          gfc_conv_descriptor_data_set (&loop.pre, parm, offset);
4135
        }
4136
 
4137
      if (se->direct_byref && !se->data_not_needed)
4138
        {
4139
        /* Set the offset.  */
4140
          tmp = gfc_conv_descriptor_offset (parm);
4141
          gfc_add_modify_expr (&loop.pre, tmp, base);
4142
        }
4143
      else
4144
        {
4145
          /* Only the callee knows what the correct offset it, so just set
4146
             it to zero here.  */
4147
          tmp = gfc_conv_descriptor_offset (parm);
4148
          gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
4149
        }
4150
      desc = parm;
4151
    }
4152
 
4153
  if (!se->direct_byref)
4154
    {
4155
      /* Get a pointer to the new descriptor.  */
4156
      if (se->want_pointer)
4157
        se->expr = gfc_build_addr_expr (NULL, desc);
4158
      else
4159
        se->expr = desc;
4160
    }
4161
 
4162
  gfc_add_block_to_block (&se->pre, &loop.pre);
4163
  gfc_add_block_to_block (&se->post, &loop.post);
4164
 
4165
  /* Cleanup the scalarizer.  */
4166
  gfc_cleanup_loop (&loop);
4167
}
4168
 
4169
 
4170
/* Convert an array for passing as an actual parameter.  */
4171
/* TODO: Optimize passing g77 arrays.  */
4172
 
4173
void
4174
gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
4175
{
4176
  tree ptr;
4177
  tree desc;
4178
  tree tmp;
4179
  tree stmt;
4180
  gfc_symbol *sym;
4181
  stmtblock_t block;
4182
 
4183
  /* Passing address of the array if it is not pointer or assumed-shape.  */
4184
  if (expr->expr_type == EXPR_VARIABLE
4185
       && expr->ref->u.ar.type == AR_FULL && g77)
4186
    {
4187
      sym = expr->symtree->n.sym;
4188
      tmp = gfc_get_symbol_decl (sym);
4189
 
4190
      if (sym->ts.type == BT_CHARACTER)
4191
        se->string_length = sym->ts.cl->backend_decl;
4192
      if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE
4193
          && !sym->attr.allocatable)
4194
        {
4195
          /* Some variables are declared directly, others are declared as
4196
             pointers and allocated on the heap.  */
4197
          if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
4198
            se->expr = tmp;
4199
          else
4200
            se->expr = gfc_build_addr_expr (NULL, tmp);
4201
          return;
4202
        }
4203
      if (sym->attr.allocatable)
4204
        {
4205
          se->expr = gfc_conv_array_data (tmp);
4206
          return;
4207
        }
4208
    }
4209
 
4210
  se->want_pointer = 1;
4211
  gfc_conv_expr_descriptor (se, expr, ss);
4212
 
4213
  if (g77)
4214
    {
4215
      desc = se->expr;
4216
      /* Repack the array.  */
4217
      tmp = gfc_chainon_list (NULL_TREE, desc);
4218
      ptr = gfc_build_function_call (gfor_fndecl_in_pack, tmp);
4219
      ptr = gfc_evaluate_now (ptr, &se->pre);
4220
      se->expr = ptr;
4221
 
4222
      gfc_start_block (&block);
4223
 
4224
      /* Copy the data back.  */
4225
      tmp = gfc_chainon_list (NULL_TREE, desc);
4226
      tmp = gfc_chainon_list (tmp, ptr);
4227
      tmp = gfc_build_function_call (gfor_fndecl_in_unpack, tmp);
4228
      gfc_add_expr_to_block (&block, tmp);
4229
 
4230
      /* Free the temporary.  */
4231
      tmp = convert (pvoid_type_node, ptr);
4232
      tmp = gfc_chainon_list (NULL_TREE, tmp);
4233
      tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
4234
      gfc_add_expr_to_block (&block, tmp);
4235
 
4236
      stmt = gfc_finish_block (&block);
4237
 
4238
      gfc_init_block (&block);
4239
      /* Only if it was repacked.  This code needs to be executed before the
4240
         loop cleanup code.  */
4241
      tmp = gfc_build_indirect_ref (desc);
4242
      tmp = gfc_conv_array_data (tmp);
4243
      tmp = build2 (NE_EXPR, boolean_type_node, ptr, tmp);
4244
      tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4245
 
4246
      gfc_add_expr_to_block (&block, tmp);
4247
      gfc_add_block_to_block (&block, &se->post);
4248
 
4249
      gfc_init_block (&se->post);
4250
      gfc_add_block_to_block (&se->post, &block);
4251
    }
4252
}
4253
 
4254
 
4255
/* NULLIFY an allocatable/pointer array on function entry, free it on exit.  */
4256
 
4257
tree
4258
gfc_trans_deferred_array (gfc_symbol * sym, tree body)
4259
{
4260
  tree type;
4261
  tree tmp;
4262
  tree descriptor;
4263
  tree deallocate;
4264
  stmtblock_t block;
4265
  stmtblock_t fnblock;
4266
  locus loc;
4267
 
4268
  /* Make sure the frontend gets these right.  */
4269
  if (!(sym->attr.pointer || sym->attr.allocatable))
4270
    fatal_error
4271
      ("Possible frontend bug: Deferred array size without pointer or allocatable attribute.");
4272
 
4273
  gfc_init_block (&fnblock);
4274
 
4275
  gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL
4276
                || TREE_CODE (sym->backend_decl) == PARM_DECL);
4277
 
4278
  if (sym->ts.type == BT_CHARACTER
4279
      && !INTEGER_CST_P (sym->ts.cl->backend_decl))
4280
    gfc_trans_init_string_length (sym->ts.cl, &fnblock);
4281
 
4282
  /* Dummy and use associated variables don't need anything special.  */
4283
  if (sym->attr.dummy || sym->attr.use_assoc)
4284
    {
4285
      gfc_add_expr_to_block (&fnblock, body);
4286
 
4287
      return gfc_finish_block (&fnblock);
4288
    }
4289
 
4290
  gfc_get_backend_locus (&loc);
4291
  gfc_set_backend_locus (&sym->declared_at);
4292
  descriptor = sym->backend_decl;
4293
 
4294
  if (TREE_STATIC (descriptor))
4295
    {
4296
      /* SAVEd variables are not freed on exit.  */
4297
      gfc_trans_static_array_pointer (sym);
4298
      return body;
4299
    }
4300
 
4301
  /* Get the descriptor type.  */
4302
  type = TREE_TYPE (sym->backend_decl);
4303
  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
4304
 
4305
  /* NULLIFY the data pointer.  */
4306
  gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node);
4307
 
4308
  gfc_add_expr_to_block (&fnblock, body);
4309
 
4310
  gfc_set_backend_locus (&loc);
4311
  /* Allocatable arrays need to be freed when they go out of scope.  */
4312
  if (sym->attr.allocatable)
4313
    {
4314
      gfc_start_block (&block);
4315
 
4316
      /* Deallocate if still allocated at the end of the procedure.  */
4317
      deallocate = gfc_array_deallocate (descriptor, null_pointer_node);
4318
 
4319
      tmp = gfc_conv_descriptor_data_get (descriptor);
4320
      tmp = build2 (NE_EXPR, boolean_type_node, tmp,
4321
                    build_int_cst (TREE_TYPE (tmp), 0));
4322
      tmp = build3_v (COND_EXPR, tmp, deallocate, build_empty_stmt ());
4323
      gfc_add_expr_to_block (&block, tmp);
4324
 
4325
      tmp = gfc_finish_block (&block);
4326
      gfc_add_expr_to_block (&fnblock, tmp);
4327
    }
4328
 
4329
  return gfc_finish_block (&fnblock);
4330
}
4331
 
4332
/************ Expression Walking Functions ******************/
4333
 
4334
/* Walk a variable reference.
4335
 
4336
   Possible extension - multiple component subscripts.
4337
    x(:,:) = foo%a(:)%b(:)
4338
   Transforms to
4339
    forall (i=..., j=...)
4340
      x(i,j) = foo%a(j)%b(i)
4341
    end forall
4342
   This adds a fair amout of complexity because you need to deal with more
4343
   than one ref.  Maybe handle in a similar manner to vector subscripts.
4344
   Maybe not worth the effort.  */
4345
 
4346
 
4347
static gfc_ss *
4348
gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
4349
{
4350
  gfc_ref *ref;
4351
  gfc_array_ref *ar;
4352
  gfc_ss *newss;
4353
  gfc_ss *head;
4354
  int n;
4355
 
4356
  for (ref = expr->ref; ref; ref = ref->next)
4357
    if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
4358
      break;
4359
 
4360
  for (; ref; ref = ref->next)
4361
    {
4362
      if (ref->type == REF_SUBSTRING)
4363
        {
4364
          newss = gfc_get_ss ();
4365
          newss->type = GFC_SS_SCALAR;
4366
          newss->expr = ref->u.ss.start;
4367
          newss->next = ss;
4368
          ss = newss;
4369
 
4370
          newss = gfc_get_ss ();
4371
          newss->type = GFC_SS_SCALAR;
4372
          newss->expr = ref->u.ss.end;
4373
          newss->next = ss;
4374
          ss = newss;
4375
        }
4376
 
4377
      /* We're only interested in array sections from now on.  */
4378
      if (ref->type != REF_ARRAY)
4379
        continue;
4380
 
4381
      ar = &ref->u.ar;
4382
      switch (ar->type)
4383
        {
4384
        case AR_ELEMENT:
4385
          for (n = 0; n < ar->dimen; n++)
4386
            {
4387
              newss = gfc_get_ss ();
4388
              newss->type = GFC_SS_SCALAR;
4389
              newss->expr = ar->start[n];
4390
              newss->next = ss;
4391
              ss = newss;
4392
            }
4393
          break;
4394
 
4395
        case AR_FULL:
4396
          newss = gfc_get_ss ();
4397
          newss->type = GFC_SS_SECTION;
4398
          newss->expr = expr;
4399
          newss->next = ss;
4400
          newss->data.info.dimen = ar->as->rank;
4401
          newss->data.info.ref = ref;
4402
 
4403
          /* Make sure array is the same as array(:,:), this way
4404
             we don't need to special case all the time.  */
4405
          ar->dimen = ar->as->rank;
4406
          for (n = 0; n < ar->dimen; n++)
4407
            {
4408
              newss->data.info.dim[n] = n;
4409
              ar->dimen_type[n] = DIMEN_RANGE;
4410
 
4411
              gcc_assert (ar->start[n] == NULL);
4412
              gcc_assert (ar->end[n] == NULL);
4413
              gcc_assert (ar->stride[n] == NULL);
4414
            }
4415
          ss = newss;
4416
          break;
4417
 
4418
        case AR_SECTION:
4419
          newss = gfc_get_ss ();
4420
          newss->type = GFC_SS_SECTION;
4421
          newss->expr = expr;
4422
          newss->next = ss;
4423
          newss->data.info.dimen = 0;
4424
          newss->data.info.ref = ref;
4425
 
4426
          head = newss;
4427
 
4428
          /* We add SS chains for all the subscripts in the section.  */
4429
          for (n = 0; n < ar->dimen; n++)
4430
            {
4431
              gfc_ss *indexss;
4432
 
4433
              switch (ar->dimen_type[n])
4434
                {
4435
                case DIMEN_ELEMENT:
4436
                  /* Add SS for elemental (scalar) subscripts.  */
4437
                  gcc_assert (ar->start[n]);
4438
                  indexss = gfc_get_ss ();
4439
                  indexss->type = GFC_SS_SCALAR;
4440
                  indexss->expr = ar->start[n];
4441
                  indexss->next = gfc_ss_terminator;
4442
                  indexss->loop_chain = gfc_ss_terminator;
4443
                  newss->data.info.subscript[n] = indexss;
4444
                  break;
4445
 
4446
                case DIMEN_RANGE:
4447
                  /* We don't add anything for sections, just remember this
4448
                     dimension for later.  */
4449
                  newss->data.info.dim[newss->data.info.dimen] = n;
4450
                  newss->data.info.dimen++;
4451
                  break;
4452
 
4453
                case DIMEN_VECTOR:
4454
                  /* Create a GFC_SS_VECTOR index in which we can store
4455
                     the vector's descriptor.  */
4456
                  indexss = gfc_get_ss ();
4457
                  indexss->type = GFC_SS_VECTOR;
4458
                  indexss->expr = ar->start[n];
4459
                  indexss->next = gfc_ss_terminator;
4460
                  indexss->loop_chain = gfc_ss_terminator;
4461
                  newss->data.info.subscript[n] = indexss;
4462
                  newss->data.info.dim[newss->data.info.dimen] = n;
4463
                  newss->data.info.dimen++;
4464
                  break;
4465
 
4466
                default:
4467
                  /* We should know what sort of section it is by now.  */
4468
                  gcc_unreachable ();
4469
                }
4470
            }
4471
          /* We should have at least one non-elemental dimension.  */
4472
          gcc_assert (newss->data.info.dimen > 0);
4473
          ss = newss;
4474
          break;
4475
 
4476
        default:
4477
          /* We should know what sort of section it is by now.  */
4478
          gcc_unreachable ();
4479
        }
4480
 
4481
    }
4482
  return ss;
4483
}
4484
 
4485
 
4486
/* Walk an expression operator. If only one operand of a binary expression is
4487
   scalar, we must also add the scalar term to the SS chain.  */
4488
 
4489
static gfc_ss *
4490
gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
4491
{
4492
  gfc_ss *head;
4493
  gfc_ss *head2;
4494
  gfc_ss *newss;
4495
 
4496
  head = gfc_walk_subexpr (ss, expr->value.op.op1);
4497
  if (expr->value.op.op2 == NULL)
4498
    head2 = head;
4499
  else
4500
    head2 = gfc_walk_subexpr (head, expr->value.op.op2);
4501
 
4502
  /* All operands are scalar.  Pass back and let the caller deal with it.  */
4503
  if (head2 == ss)
4504
    return head2;
4505
 
4506
  /* All operands require scalarization.  */
4507
  if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
4508
    return head2;
4509
 
4510
  /* One of the operands needs scalarization, the other is scalar.
4511
     Create a gfc_ss for the scalar expression.  */
4512
  newss = gfc_get_ss ();
4513
  newss->type = GFC_SS_SCALAR;
4514
  if (head == ss)
4515
    {
4516
      /* First operand is scalar.  We build the chain in reverse order, so
4517
         add the scarar SS after the second operand.  */
4518
      head = head2;
4519
      while (head && head->next != ss)
4520
        head = head->next;
4521
      /* Check we haven't somehow broken the chain.  */
4522
      gcc_assert (head);
4523
      newss->next = ss;
4524
      head->next = newss;
4525
      newss->expr = expr->value.op.op1;
4526
    }
4527
  else                          /* head2 == head */
4528
    {
4529
      gcc_assert (head2 == head);
4530
      /* Second operand is scalar.  */
4531
      newss->next = head2;
4532
      head2 = newss;
4533
      newss->expr = expr->value.op.op2;
4534
    }
4535
 
4536
  return head2;
4537
}
4538
 
4539
 
4540
/* Reverse a SS chain.  */
4541
 
4542
gfc_ss *
4543
gfc_reverse_ss (gfc_ss * ss)
4544
{
4545
  gfc_ss *next;
4546
  gfc_ss *head;
4547
 
4548
  gcc_assert (ss != NULL);
4549
 
4550
  head = gfc_ss_terminator;
4551
  while (ss != gfc_ss_terminator)
4552
    {
4553
      next = ss->next;
4554
      /* Check we didn't somehow break the chain.  */
4555
      gcc_assert (next != NULL);
4556
      ss->next = head;
4557
      head = ss;
4558
      ss = next;
4559
    }
4560
 
4561
  return (head);
4562
}
4563
 
4564
 
4565
/* Walk the arguments of an elemental function.  */
4566
 
4567
gfc_ss *
4568
gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
4569
                                  gfc_ss_type type)
4570
{
4571
  int scalar;
4572
  gfc_ss *head;
4573
  gfc_ss *tail;
4574
  gfc_ss *newss;
4575
 
4576
  head = gfc_ss_terminator;
4577
  tail = NULL;
4578
  scalar = 1;
4579
  for (; arg; arg = arg->next)
4580
    {
4581
      if (!arg->expr)
4582
        continue;
4583
 
4584
      newss = gfc_walk_subexpr (head, arg->expr);
4585
      if (newss == head)
4586
        {
4587
          /* Scalar argument.  */
4588
          newss = gfc_get_ss ();
4589
          newss->type = type;
4590
          newss->expr = arg->expr;
4591
          newss->next = head;
4592
        }
4593
      else
4594
        scalar = 0;
4595
 
4596
      head = newss;
4597
      if (!tail)
4598
        {
4599
          tail = head;
4600
          while (tail->next != gfc_ss_terminator)
4601
            tail = tail->next;
4602
        }
4603
    }
4604
 
4605
  if (scalar)
4606
    {
4607
      /* If all the arguments are scalar we don't need the argument SS.  */
4608
      gfc_free_ss_chain (head);
4609
      /* Pass it back.  */
4610
      return ss;
4611
    }
4612
 
4613
  /* Add it onto the existing chain.  */
4614
  tail->next = ss;
4615
  return head;
4616
}
4617
 
4618
 
4619
/* Walk a function call.  Scalar functions are passed back, and taken out of
4620
   scalarization loops.  For elemental functions we walk their arguments.
4621
   The result of functions returning arrays is stored in a temporary outside
4622
   the loop, so that the function is only called once.  Hence we do not need
4623
   to walk their arguments.  */
4624
 
4625
static gfc_ss *
4626
gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
4627
{
4628
  gfc_ss *newss;
4629
  gfc_intrinsic_sym *isym;
4630
  gfc_symbol *sym;
4631
 
4632
  isym = expr->value.function.isym;
4633
 
4634
  /* Handle intrinsic functions separately.  */
4635
  if (isym)
4636
    return gfc_walk_intrinsic_function (ss, expr, isym);
4637
 
4638
  sym = expr->value.function.esym;
4639
  if (!sym)
4640
      sym = expr->symtree->n.sym;
4641
 
4642
  /* A function that returns arrays.  */
4643
  if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
4644
    {
4645
      newss = gfc_get_ss ();
4646
      newss->type = GFC_SS_FUNCTION;
4647
      newss->expr = expr;
4648
      newss->next = ss;
4649
      newss->data.info.dimen = expr->rank;
4650
      return newss;
4651
    }
4652
 
4653
  /* Walk the parameters of an elemental function.  For now we always pass
4654
     by reference.  */
4655
  if (sym->attr.elemental)
4656
    return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
4657
                                             GFC_SS_REFERENCE);
4658
 
4659
  /* Scalar functions are OK as these are evaluated outside the scalarization
4660
     loop.  Pass back and let the caller deal with it.  */
4661
  return ss;
4662
}
4663
 
4664
 
4665
/* An array temporary is constructed for array constructors.  */
4666
 
4667
static gfc_ss *
4668
gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
4669
{
4670
  gfc_ss *newss;
4671
  int n;
4672
 
4673
  newss = gfc_get_ss ();
4674
  newss->type = GFC_SS_CONSTRUCTOR;
4675
  newss->expr = expr;
4676
  newss->next = ss;
4677
  newss->data.info.dimen = expr->rank;
4678
  for (n = 0; n < expr->rank; n++)
4679
    newss->data.info.dim[n] = n;
4680
 
4681
  return newss;
4682
}
4683
 
4684
 
4685
/* Walk an expression.  Add walked expressions to the head of the SS chain.
4686
   A wholly scalar expression will not be added.  */
4687
 
4688
static gfc_ss *
4689
gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
4690
{
4691
  gfc_ss *head;
4692
 
4693
  switch (expr->expr_type)
4694
    {
4695
    case EXPR_VARIABLE:
4696
      head = gfc_walk_variable_expr (ss, expr);
4697
      return head;
4698
 
4699
    case EXPR_OP:
4700
      head = gfc_walk_op_expr (ss, expr);
4701
      return head;
4702
 
4703
    case EXPR_FUNCTION:
4704
      head = gfc_walk_function_expr (ss, expr);
4705
      return head;
4706
 
4707
    case EXPR_CONSTANT:
4708
    case EXPR_NULL:
4709
    case EXPR_STRUCTURE:
4710
      /* Pass back and let the caller deal with it.  */
4711
      break;
4712
 
4713
    case EXPR_ARRAY:
4714
      head = gfc_walk_array_constructor (ss, expr);
4715
      return head;
4716
 
4717
    case EXPR_SUBSTRING:
4718
      /* Pass back and let the caller deal with it.  */
4719
      break;
4720
 
4721
    default:
4722
      internal_error ("bad expression type during walk (%d)",
4723
                      expr->expr_type);
4724
    }
4725
  return ss;
4726
}
4727
 
4728
 
4729
/* Entry point for expression walking.
4730
   A return value equal to the passed chain means this is
4731
   a scalar expression.  It is up to the caller to take whatever action is
4732
   necessary to translate these.  */
4733
 
4734
gfc_ss *
4735
gfc_walk_expr (gfc_expr * expr)
4736
{
4737
  gfc_ss *res;
4738
 
4739
  res = gfc_walk_subexpr (gfc_ss_terminator, expr);
4740
  return gfc_reverse_ss (res);
4741
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.