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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [fortran/] [dependency.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
/* Dependency analysis
2
   Copyright (C) 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
3
   Contributed by Paul Brook <paul@nowt.org>
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 2, or (at your option) any later
10
version.
11
 
12
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING.  If not, write to the Free
19
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301, USA.  */
21
 
22
/* dependency.c -- Expression dependency analysis code.  */
23
/* There's probably quite a bit of duplication in this file.  We currently
24
   have different dependency checking functions for different types
25
   if dependencies.  Ideally these would probably be merged.  */
26
 
27
 
28
#include "config.h"
29
#include "gfortran.h"
30
#include "dependency.h"
31
 
32
/* static declarations */
33
/* Enums  */
34
enum range {LHS, RHS, MID};
35
 
36
/* Dependency types.  These must be in reverse order of priority.  */
37
typedef enum
38
{
39
  GFC_DEP_ERROR,
40
  GFC_DEP_EQUAL,        /* Identical Ranges.  */
41
  GFC_DEP_FORWARD,      /* eg. a(1:3), a(2:4).  */
42
  GFC_DEP_OVERLAP,      /* May overlap in some other way.  */
43
  GFC_DEP_NODEP         /* Distinct ranges.  */
44
}
45
gfc_dependency;
46
 
47
/* Macros */
48
#define IS_ARRAY_EXPLICIT(as) ((as->type == AS_EXPLICIT ? 1 : 0))
49
 
50
 
51
/* Returns 1 if the expr is an integer constant value 1, 0 if it is not or
52
   def if the value could not be determined.  */
53
 
54
int
55
gfc_expr_is_one (gfc_expr * expr, int def)
56
{
57
  gcc_assert (expr != NULL);
58
 
59
  if (expr->expr_type != EXPR_CONSTANT)
60
    return def;
61
 
62
  if (expr->ts.type != BT_INTEGER)
63
    return def;
64
 
65
  return mpz_cmp_si (expr->value.integer, 1) == 0;
66
}
67
 
68
 
69
/* Compare two values.  Returns 0 if e1 == e2, -1 if e1 < e2, +1 if e1 > e2,
70
   and -2 if the relationship could not be determined.  */
71
 
72
int
73
gfc_dep_compare_expr (gfc_expr * e1, gfc_expr * e2)
74
{
75
  int i;
76
 
77
  if (e1->expr_type != e2->expr_type)
78
    return -2;
79
 
80
  switch (e1->expr_type)
81
    {
82
    case EXPR_CONSTANT:
83
      if (e1->ts.type != BT_INTEGER || e2->ts.type != BT_INTEGER)
84
        return -2;
85
 
86
      i = mpz_cmp (e1->value.integer, e2->value.integer);
87
      if (i == 0)
88
        return 0;
89
      else if (i < 0)
90
        return -1;
91
      return 1;
92
 
93
    case EXPR_VARIABLE:
94
      if (e1->ref || e2->ref)
95
        return -2;
96
      if (e1->symtree->n.sym == e2->symtree->n.sym)
97
        return 0;
98
      return -2;
99
 
100
    default:
101
      return -2;
102
    }
103
}
104
 
105
 
106
/* Returns 1 if the two ranges are the same, 0 if they are not, and def
107
   if the results are indeterminate.  N is the dimension to compare.  */
108
 
109
int
110
gfc_is_same_range (gfc_array_ref * ar1, gfc_array_ref * ar2, int n, int def)
111
{
112
  gfc_expr *e1;
113
  gfc_expr *e2;
114
  int i;
115
 
116
  /* TODO: More sophisticated range comparison.  */
117
  gcc_assert (ar1 && ar2);
118
 
119
  gcc_assert (ar1->dimen_type[n] == ar2->dimen_type[n]);
120
 
121
  e1 = ar1->stride[n];
122
  e2 = ar2->stride[n];
123
  /* Check for mismatching strides.  A NULL stride means a stride of 1.  */
124
  if (e1 && !e2)
125
    {
126
      i = gfc_expr_is_one (e1, -1);
127
      if (i == -1)
128
        return def;
129
      else if (i == 0)
130
        return 0;
131
    }
132
  else if (e2 && !e1)
133
    {
134
      i = gfc_expr_is_one (e2, -1);
135
      if (i == -1)
136
        return def;
137
      else if (i == 0)
138
        return 0;
139
    }
140
  else if (e1 && e2)
141
    {
142
      i = gfc_dep_compare_expr (e1, e2);
143
      if (i == -2)
144
        return def;
145
      else if (i != 0)
146
        return 0;
147
    }
148
  /* The strides match.  */
149
 
150
  /* Check the range start.  */
151
  e1 = ar1->start[n];
152
  e2 = ar2->start[n];
153
 
154
  if (!(e1 || e2))
155
    return 1;
156
 
157
  /* Use the bound of the array if no bound is specified.  */
158
  if (ar1->as && !e1)
159
    e1 = ar1->as->lower[n];
160
 
161
  if (ar2->as && !e2)
162
    e2 = ar2->as->lower[n];
163
 
164
  /* Check we have values for both.  */
165
  if (!(e1 && e2))
166
    return def;
167
 
168
  i = gfc_dep_compare_expr (e1, e2);
169
 
170
  if (i == -2)
171
    return def;
172
  else if (i == 0)
173
    return 1;
174
  return 0;
175
}
176
 
177
 
178
/* Return true if the result of reference REF can only be constructed
179
   using a temporary array.  */
180
 
181
bool
182
gfc_ref_needs_temporary_p (gfc_ref *ref)
183
{
184
  int n;
185
  bool subarray_p;
186
 
187
  subarray_p = false;
188
  for (; ref; ref = ref->next)
189
    switch (ref->type)
190
      {
191
      case REF_ARRAY:
192
        /* Vector dimensions are generally not monotonic and must be
193
           handled using a temporary.  */
194
        if (ref->u.ar.type == AR_SECTION)
195
          for (n = 0; n < ref->u.ar.dimen; n++)
196
            if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR)
197
              return true;
198
 
199
        subarray_p = true;
200
        break;
201
 
202
      case REF_SUBSTRING:
203
        /* Within an array reference, character substrings generally
204
           need a temporary.  Character array strides are expressed as
205
           multiples of the element size (consistent with other array
206
           types), not in characters.  */
207
        return subarray_p;
208
 
209
      case REF_COMPONENT:
210
        break;
211
      }
212
 
213
  return false;
214
}
215
 
216
 
217
/* Dependency checking for direct function return by reference.
218
   Returns true if the arguments of the function depend on the
219
   destination.  This is considerably less conservative than other
220
   dependencies because many function arguments will already be
221
   copied into a temporary.  */
222
 
223
int
224
gfc_check_fncall_dependency (gfc_expr * dest, gfc_expr * fncall)
225
{
226
  gfc_actual_arglist *actual;
227
  gfc_expr *expr;
228
 
229
  gcc_assert (dest->expr_type == EXPR_VARIABLE
230
          && fncall->expr_type == EXPR_FUNCTION);
231
  gcc_assert (fncall->rank > 0);
232
 
233
  for (actual = fncall->value.function.actual; actual; actual = actual->next)
234
    {
235
      expr = actual->expr;
236
 
237
      /* Skip args which are not present.  */
238
      if (!expr)
239
        continue;
240
 
241
      /* Non-variable expressions will be allocated temporaries anyway.  */
242
      switch (expr->expr_type)
243
        {
244
        case EXPR_VARIABLE:
245
          if (!gfc_ref_needs_temporary_p (expr->ref)
246
              && gfc_check_dependency (dest, expr, NULL, 0))
247
            return 1;
248
          break;
249
 
250
        case EXPR_ARRAY:
251
          if (gfc_check_dependency (dest, expr, NULL, 0))
252
            return 1;
253
          break;
254
 
255
        default:
256
          break;
257
        }
258
    }
259
 
260
  return 0;
261
}
262
 
263
 
264
/* Return 1 if e1 and e2 are equivalenced arrays, either
265
   directly or indirectly; ie. equivalence (a,b) for a and b
266
   or equivalence (a,c),(b,c).  This function uses the equiv_
267
   lists, generated in trans-common(add_equivalences), that are
268
   guaranteed to pick up indirect equivalences.  A rudimentary
269
   use is made of the offset to ensure that cases where the
270
   source elements are moved down to the destination are not
271
   identified as dependencies.  */
272
 
273
int
274
gfc_are_equivalenced_arrays (gfc_expr *e1, gfc_expr *e2)
275
{
276
  gfc_equiv_list *l;
277
  gfc_equiv_info *s, *fl1, *fl2;
278
 
279
  gcc_assert (e1->expr_type == EXPR_VARIABLE
280
                && e2->expr_type == EXPR_VARIABLE);
281
 
282
  if (!e1->symtree->n.sym->attr.in_equivalence
283
        || !e2->symtree->n.sym->attr.in_equivalence
284
        || !e1->rank
285
        || !e2->rank)
286
    return 0;
287
 
288
  /* Go through the equiv_lists and return 1 if the variables
289
     e1 and e2 are members of the same group and satisfy the
290
     requirement on their relative offsets.  */
291
  for (l = gfc_current_ns->equiv_lists; l; l = l->next)
292
    {
293
      fl1 = NULL;
294
      fl2 = NULL;
295
      for (s = l->equiv; s; s = s->next)
296
        {
297
          if (s->sym == e1->symtree->n.sym)
298
            fl1 = s;
299
          if (s->sym == e2->symtree->n.sym)
300
            fl2 = s;
301
          if (fl1 && fl2 && (fl1->offset > fl2->offset))
302
            return 1;
303
        }
304
    }
305
return 0;
306
}
307
 
308
 
309
/* Return true if the statement body redefines the condition.  Returns
310
   true if expr2 depends on expr1.  expr1 should be a single term
311
   suitable for the lhs of an assignment.  The symbols listed in VARS
312
   must be considered to have all possible values. All other scalar
313
   variables may be considered constant.  Used for forall and where
314
   statements.  Also used with functions returning arrays without a
315
   temporary.  */
316
 
317
int
318
gfc_check_dependency (gfc_expr * expr1, gfc_expr * expr2, gfc_expr ** vars,
319
                      int nvars)
320
{
321
  gfc_ref *ref;
322
  int n;
323
  gfc_actual_arglist *actual;
324
 
325
  gcc_assert (expr1->expr_type == EXPR_VARIABLE);
326
 
327
  /* TODO: -fassume-no-pointer-aliasing */
328
  if (expr1->symtree->n.sym->attr.pointer)
329
    return 1;
330
  for (ref = expr1->ref; ref; ref = ref->next)
331
    {
332
      if (ref->type == REF_COMPONENT && ref->u.c.component->pointer)
333
        return 1;
334
    }
335
 
336
  switch (expr2->expr_type)
337
    {
338
    case EXPR_OP:
339
      n = gfc_check_dependency (expr1, expr2->value.op.op1, vars, nvars);
340
      if (n)
341
        return n;
342
      if (expr2->value.op.op2)
343
        return gfc_check_dependency (expr1, expr2->value.op.op2, vars, nvars);
344
      return 0;
345
 
346
    case EXPR_VARIABLE:
347
      if (expr2->symtree->n.sym->attr.pointer)
348
        return 1;
349
 
350
      for (ref = expr2->ref; ref; ref = ref->next)
351
        {
352
          if (ref->type == REF_COMPONENT && ref->u.c.component->pointer)
353
            return 1;
354
        }
355
 
356
      /* Return 1 if expr1 and expr2 are equivalenced arrays.  */
357
      if (gfc_are_equivalenced_arrays (expr1, expr2))
358
        return 1;
359
 
360
      if (expr1->symtree->n.sym != expr2->symtree->n.sym)
361
        return 0;
362
 
363
      for (ref = expr2->ref; ref; ref = ref->next)
364
        {
365
          /* Identical ranges return 0, overlapping ranges return 1.  */
366
          if (ref->type == REF_ARRAY)
367
            return 1;
368
        }
369
      return 1;
370
 
371
    case EXPR_FUNCTION:
372
      /* Remember possible differences between elemental and
373
         transformational functions.  All functions inside a FORALL
374
         will be pure.  */
375
      for (actual = expr2->value.function.actual;
376
           actual; actual = actual->next)
377
        {
378
          if (!actual->expr)
379
            continue;
380
          n = gfc_check_dependency (expr1, actual->expr, vars, nvars);
381
          if (n)
382
            return n;
383
        }
384
      return 0;
385
 
386
    case EXPR_CONSTANT:
387
      return 0;
388
 
389
    case EXPR_ARRAY:
390
      /* Probably ok in the majority of (constant) cases.  */
391
      return 1;
392
 
393
    default:
394
      return 1;
395
    }
396
}
397
 
398
 
399
/* Calculates size of the array reference using lower bound, upper bound
400
   and stride.  */
401
 
402
static void
403
get_no_of_elements(mpz_t ele, gfc_expr * u1, gfc_expr * l1, gfc_expr * s1)
404
{
405
  /* nNoOfEle = (u1-l1)/s1  */
406
 
407
  mpz_sub (ele, u1->value.integer, l1->value.integer);
408
 
409
  if (s1 != NULL)
410
    mpz_tdiv_q (ele, ele, s1->value.integer);
411
}
412
 
413
 
414
/* Returns if the ranges ((0..Y), (X1..X2))  overlap.  */
415
 
416
static gfc_dependency
417
get_deps (mpz_t x1, mpz_t x2, mpz_t y)
418
{
419
  int start;
420
  int end;
421
 
422
  start = mpz_cmp_ui (x1, 0);
423
  end = mpz_cmp (x2, y);
424
 
425
  /* Both ranges the same.  */
426
  if (start == 0 && end == 0)
427
    return GFC_DEP_EQUAL;
428
 
429
  /* Distinct ranges.  */
430
  if ((start < 0 && mpz_cmp_ui (x2, 0) < 0)
431
      || (mpz_cmp (x1, y) > 0 && end > 0))
432
    return GFC_DEP_NODEP;
433
 
434
  /* Overlapping, but with corresponding elements of the second range
435
     greater than the first.  */
436
  if (start > 0 && end > 0)
437
    return GFC_DEP_FORWARD;
438
 
439
  /* Overlapping in some other way.  */
440
  return GFC_DEP_OVERLAP;
441
}
442
 
443
 
444
/* Perform the same linear transformation on sections l and r such that
445
   (l_start:l_end:l_stride) -> (0:no_of_elements)
446
   (r_start:r_end:r_stride) -> (X1:X2)
447
   Where r_end is implicit as both sections must have the same number of
448
   elements.
449
   Returns 0 on success, 1 of the transformation failed.  */
450
/* TODO: Should this be (0:no_of_elements-1) */
451
 
452
static int
453
transform_sections (mpz_t X1, mpz_t X2, mpz_t no_of_elements,
454
                    gfc_expr * l_start, gfc_expr * l_end, gfc_expr * l_stride,
455
                    gfc_expr * r_start, gfc_expr * r_stride)
456
{
457
  if (NULL == l_start || NULL == l_end || NULL == r_start)
458
    return 1;
459
 
460
  /* TODO : Currently we check the dependency only when start, end and stride
461
    are constant.  We could also check for equal (variable) values, and
462
    common subexpressions, eg. x vs. x+1.  */
463
 
464
  if (l_end->expr_type != EXPR_CONSTANT
465
      || l_start->expr_type != EXPR_CONSTANT
466
      || r_start->expr_type != EXPR_CONSTANT
467
      || ((NULL != l_stride) && (l_stride->expr_type != EXPR_CONSTANT))
468
      || ((NULL != r_stride) && (r_stride->expr_type != EXPR_CONSTANT)))
469
    {
470
       return 1;
471
    }
472
 
473
 
474
  get_no_of_elements (no_of_elements, l_end, l_start, l_stride);
475
 
476
  mpz_sub (X1, r_start->value.integer, l_start->value.integer);
477
  if (l_stride != NULL)
478
    mpz_cdiv_q (X1, X1, l_stride->value.integer);
479
 
480
  if (r_stride == NULL)
481
    mpz_set (X2, no_of_elements);
482
  else
483
    mpz_mul (X2, no_of_elements, r_stride->value.integer);
484
 
485
  if (l_stride != NULL)
486
    mpz_cdiv_q (X2, X2, l_stride->value.integer);
487
  mpz_add (X2, X2, X1);
488
 
489
  return 0;
490
}
491
 
492
 
493
/* Determines overlapping for two array sections.  */
494
 
495
static gfc_dependency
496
gfc_check_section_vs_section (gfc_ref * lref, gfc_ref * rref, int n)
497
{
498
  gfc_expr *l_start;
499
  gfc_expr *l_end;
500
  gfc_expr *l_stride;
501
 
502
  gfc_expr *r_start;
503
  gfc_expr *r_stride;
504
 
505
  gfc_array_ref l_ar;
506
  gfc_array_ref r_ar;
507
 
508
  mpz_t no_of_elements;
509
  mpz_t X1, X2;
510
  gfc_dependency dep;
511
 
512
  l_ar = lref->u.ar;
513
  r_ar = rref->u.ar;
514
 
515
  /* If they are the same range, return without more ado.  */
516
  if (gfc_is_same_range (&l_ar, &r_ar, n, 0))
517
    return GFC_DEP_EQUAL;
518
 
519
  l_start = l_ar.start[n];
520
  l_end = l_ar.end[n];
521
  l_stride = l_ar.stride[n];
522
  r_start = r_ar.start[n];
523
  r_stride = r_ar.stride[n];
524
 
525
  /* if l_start is NULL take it from array specifier  */
526
  if (NULL == l_start && IS_ARRAY_EXPLICIT(l_ar.as))
527
    l_start = l_ar.as->lower[n];
528
 
529
  /* if l_end is NULL take it from array specifier  */
530
  if (NULL == l_end && IS_ARRAY_EXPLICIT(l_ar.as))
531
    l_end = l_ar.as->upper[n];
532
 
533
  /* if r_start is NULL take it from array specifier  */
534
  if (NULL == r_start && IS_ARRAY_EXPLICIT(r_ar.as))
535
    r_start = r_ar.as->lower[n];
536
 
537
  mpz_init (X1);
538
  mpz_init (X2);
539
  mpz_init (no_of_elements);
540
 
541
  if (transform_sections (X1, X2, no_of_elements,
542
                          l_start, l_end, l_stride,
543
                          r_start, r_stride))
544
    dep = GFC_DEP_OVERLAP;
545
  else
546
    dep =  get_deps (X1, X2, no_of_elements);
547
 
548
  mpz_clear (no_of_elements);
549
  mpz_clear (X1);
550
  mpz_clear (X2);
551
  return dep;
552
}
553
 
554
 
555
/* Checks if the expr chk is inside the range left-right.
556
   Returns  GFC_DEP_NODEP if chk is outside the range,
557
   GFC_DEP_OVERLAP otherwise.
558
   Assumes left<=right.  */
559
 
560
static gfc_dependency
561
gfc_is_inside_range (gfc_expr * chk, gfc_expr * left, gfc_expr * right)
562
{
563
  int l;
564
  int r;
565
  int s;
566
 
567
  s = gfc_dep_compare_expr (left, right);
568
  if (s == -2)
569
    return GFC_DEP_OVERLAP;
570
 
571
  l = gfc_dep_compare_expr (chk, left);
572
  r = gfc_dep_compare_expr (chk, right);
573
 
574
  /* Check for indeterminate relationships.  */
575
  if (l == -2 || r == -2 || s == -2)
576
    return GFC_DEP_OVERLAP;
577
 
578
  if (s == 1)
579
    {
580
      /* When left>right we want to check for right <= chk <= left.  */
581
      if (l <= 0 || r >= 0)
582
        return GFC_DEP_OVERLAP;
583
    }
584
  else
585
    {
586
      /* Otherwise check for left <= chk <= right.  */
587
      if (l >= 0 || r <= 0)
588
        return GFC_DEP_OVERLAP;
589
    }
590
 
591
  return GFC_DEP_NODEP;
592
}
593
 
594
 
595
/* Determines overlapping for a single element and a section.  */
596
 
597
static gfc_dependency
598
gfc_check_element_vs_section( gfc_ref * lref, gfc_ref * rref, int n)
599
{
600
  gfc_array_ref l_ar;
601
  gfc_array_ref r_ar;
602
  gfc_expr *l_start;
603
  gfc_expr *r_start;
604
  gfc_expr *r_end;
605
 
606
  l_ar = lref->u.ar;
607
  r_ar = rref->u.ar;
608
  l_start = l_ar.start[n] ;
609
  r_start = r_ar.start[n] ;
610
  r_end = r_ar.end[n] ;
611
  if (NULL == r_start && IS_ARRAY_EXPLICIT (r_ar.as))
612
    r_start = r_ar.as->lower[n];
613
  if (NULL == r_end && IS_ARRAY_EXPLICIT (r_ar.as))
614
    r_end = r_ar.as->upper[n];
615
  if (NULL == r_start || NULL == r_end || l_start == NULL)
616
    return GFC_DEP_OVERLAP;
617
 
618
  return gfc_is_inside_range (l_start, r_end, r_start);
619
}
620
 
621
 
622
/* Determines overlapping for two single element array references.  */
623
 
624
static gfc_dependency
625
gfc_check_element_vs_element (gfc_ref * lref, gfc_ref * rref, int n)
626
{
627
  gfc_array_ref l_ar;
628
  gfc_array_ref r_ar;
629
  gfc_expr *l_start;
630
  gfc_expr *r_start;
631
  gfc_dependency nIsDep;
632
 
633
  if (lref->type == REF_ARRAY && rref->type == REF_ARRAY)
634
    {
635
      l_ar = lref->u.ar;
636
      r_ar = rref->u.ar;
637
      l_start = l_ar.start[n] ;
638
      r_start = r_ar.start[n] ;
639
      if (gfc_dep_compare_expr (r_start, l_start) == 0)
640
        nIsDep = GFC_DEP_EQUAL;
641
      else
642
        nIsDep = GFC_DEP_NODEP;
643
  }
644
  else
645
    nIsDep = GFC_DEP_NODEP;
646
 
647
  return nIsDep;
648
}
649
 
650
 
651
/* Finds if two array references are overlapping or not.
652
   Return value
653
        1 : array references are overlapping.
654
 
655
 
656
int
657
gfc_dep_resolver (gfc_ref * lref, gfc_ref * rref)
658
{
659
  int n;
660
  gfc_dependency fin_dep;
661
  gfc_dependency this_dep;
662
 
663
 
664
  fin_dep = GFC_DEP_ERROR;
665
  /* Dependencies due to pointers should already have been identified.
666
     We only need to check for overlapping array references.  */
667
 
668
  while (lref && rref)
669
    {
670
      /* We're resolving from the same base symbol, so both refs should be
671
         the same type.  We traverse the reference chain intil we find ranges
672
         that are not equal.  */
673
      gcc_assert (lref->type == rref->type);
674
      switch (lref->type)
675
        {
676
        case REF_COMPONENT:
677
          /* The two ranges can't overlap if they are from different
678
             components.  */
679
          if (lref->u.c.component != rref->u.c.component)
680
            return 0;
681
          break;
682
 
683
        case REF_SUBSTRING:
684
          /* Substring overlaps are handled by the string assignment code.  */
685
          return 0;
686
 
687
        case REF_ARRAY:
688
 
689
          for (n=0; n < lref->u.ar.dimen; n++)
690
            {
691
              /* Assume dependency when either of array reference is vector
692
                 subscript.  */
693
              if (lref->u.ar.dimen_type[n] == DIMEN_VECTOR
694
                  || rref->u.ar.dimen_type[n] == DIMEN_VECTOR)
695
                return 1;
696
              if (lref->u.ar.dimen_type[n] == DIMEN_RANGE
697
                  && rref->u.ar.dimen_type[n] == DIMEN_RANGE)
698
                this_dep = gfc_check_section_vs_section (lref, rref, n);
699
              else if (lref->u.ar.dimen_type[n] == DIMEN_ELEMENT
700
                       && rref->u.ar.dimen_type[n] == DIMEN_RANGE)
701
                this_dep = gfc_check_element_vs_section (lref, rref, n);
702
              else if (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT
703
                       && lref->u.ar.dimen_type[n] == DIMEN_RANGE)
704
                this_dep = gfc_check_element_vs_section (rref, lref, n);
705
              else
706
                {
707
                  gcc_assert (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT
708
                          && lref->u.ar.dimen_type[n] == DIMEN_ELEMENT);
709
                  this_dep = gfc_check_element_vs_element (rref, lref, n);
710
                }
711
 
712
              /* If any dimension doesn't overlap, we have no dependency.  */
713
              if (this_dep == GFC_DEP_NODEP)
714
                return 0;
715
 
716
              /* Overlap codes are in order of priority.  We only need to
717
                 know the worst one.*/
718
              if (this_dep > fin_dep)
719
                fin_dep = this_dep;
720
            }
721
          /* Exactly matching and forward overlapping ranges don't cause a
722
             dependency.  */
723
          if (fin_dep < GFC_DEP_OVERLAP)
724
            return 0;
725
 
726
          /* Keep checking.  We only have a dependency if
727
             subsequent references also overlap.  */
728
          break;
729
 
730
        default:
731
          gcc_unreachable ();
732
        }
733
      lref = lref->next;
734
      rref = rref->next;
735
    }
736
 
737
  /* If we haven't seen any array refs then something went wrong.  */
738
  gcc_assert (fin_dep != GFC_DEP_ERROR);
739
 
740
  if (fin_dep < GFC_DEP_OVERLAP)
741
    return 0;
742
  else
743
    return 1;
744
}
745
 

powered by: WebSVN 2.1.0

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