[gomp] Handle array reductions plus various fortran reduction handling fixes

Jakub Jelinek jakub@redhat.com
Fri Oct 14 21:11:00 GMT 2005


On Fri, Oct 14, 2005 at 01:16:22PM -0700, Richard Henderson wrote:
> On Fri, Oct 14, 2005 at 11:57:27AM -0400, Jakub Jelinek wrote:
> >      case MIN_EXPR:
> >        if (SCALAR_FLOAT_TYPE_P (type))
> > +	{
> > +	  REAL_VALUE_TYPE inf;
> > +	  real_inf (&inf);
> > +	  return build_real (type, inf);
> 
> Hmm.  I'd have thought FLT_MAX and not +inf.

I actually coded there real_max (...) first.  But Inf is bigger than
FLT_MAX, so it wouldn't actually print the right result if
all threads set the inner x to Inf.

> And am I mistaken, or should the following properly test this case:
> 
> -----
>        real*4 x
> !$omp sections reduction(min:x)
>        x = huge(x) * 2.0
> !$omp end sections
>        write (*,*) x
>        end
> -----

The outer x is not initialized, so I'd say that's undefined behaviour.

> > +static void
> > +array_reduction_init (tree var, tree x, tree *stmt_list)
> 
> Are you sure you can even generate this in generic?  What if this
> is a multi-dimensional array with slices?  I'm not even sure that
> such arrays are even array types at the generic level.

I believe all arrays Fortran FE creates are one-dimensional.
Say:
integer, dimension (7:12, 8:13, 5:6, 1:1, 1:2) :: a
is:
 <var_decl 0x2aaaadb0f420 a
    type <array_type 0x2aaaadb0f0b0
        type <integer_type 0x2aaaada5f4d0 int4 public SI
            size <integer_cst 0x2aaaada54a50 constant invariant 32>
            unit size <integer_cst 0x2aaaada54570 constant invariant 4>
            align 32 symtab 0 alias set -1 precision 32 min <integer_cst 0x2aaaada549c0 -2147483648> max <integer_cst 0x2aaaada549f0 2147483647>
            pointer_to_this <pointer_type 0x2aaaada6d630>>
        type_2 BLK
        size <integer_cst 0x2aaaadb0d690 constant invariant 4608>
        unit size <integer_cst 0x2aaaadb0d780 constant invariant 576>
        align 32 symtab 0 alias set -1
        domain <integer_type 0x2aaaadb0f370 type <integer_type 0x2aaaada5f630 int8>
            DI
            size <integer_cst 0x2aaaada54c00 constant invariant 64>
            unit size <integer_cst 0x2aaaada54c30 constant invariant 8>
            align 64 symtab 0 alias set -1 precision 64 min <integer_cst 0x2aaaada6acc0 0> max <integer_cst 0x2aaaadb0d6f0 143>> pointer_to_this <pointer_type 0x2aaaadb0f4d0>>
    addressable used decl_0 BLK file tt.f90 line 1 size <integer_cst 0x2aaaadb0d690 4608> unit size <integer_cst 0x2aaaadb0d780 576>
    align 32 context <function_decl 0x2aaaadb0be00 MAIN__>>

As you can only put variable names into the reduction list, not
say a(5:7), I can't think of a way how you could get something that
wouldn't be a one-dimensional array, not starting at 0 or where you wouldn't
need to do the op on every array element from 0 till size / sizeof(element) - 1.
> 
> > +  tree ptr_type = build_pointer_type (TREE_TYPE (TREE_TYPE (var)));
> > +  tree array = build_fold_addr_expr_with_type (var, ptr_type);
> 
> This is illegal.  At minimum you wanted &a[<min-index>].  However,
> this will also not function properly for multi-dimensional arrays,
> since TREE_TYPE (TREE_TYPE (var)) is in that case still an array.

See above, I can surely add there the min-index to make it more generic
(though I hope C/C++ FEs reject arrays in reduction clause and are there
any other OpenMP languages in sight?)

> > +  stmt = build2 (MODIFY_EXPR, void_type_node, ptr, array);
> > +  gimplify_and_add (stmt, stmt_list);
> > +  append_to_statement_list (build_and_jump (&test_label), stmt_list);
> > +  loop_label = create_artificial_label ();
> > +  stmt = build1 (LABEL_EXPR, void_type_node, loop_label);
> > +  append_to_statement_list (stmt, stmt_list);
> > +  stmt = build2 (MODIFY_EXPR, void_type_node,
> 
> And please use blank lines to separate statements.

Ok.

	Jakub



More information about the Fortran mailing list