[patch, fortran] Handling of .and. and .or. expressions
Steve Kargl
sgk@troutmask.apl.washington.edu
Fri Jun 15 18:38:00 GMT 2018
On Fri, Jun 15, 2018 at 08:27:49PM +0300, Janne Blomqvist wrote:
> On Fri, Jun 15, 2018 at 8:06 PM, Thomas Koenig <tkoenig@netcologne.de>
> wrote:
>
> >
> > What about more complicated expressions like, say, "func() .and. flag .and
> >> func2() .and. flag2" etc.? Can it move all the function calls to the end?
> >>
> >
> > Not at the moment.
> >
> > Like many of the front-end optimizations, this aims for the easy 80%
> > which are relatively easy to achieve.
> >
>
> Come to think about it, is this optimization also done for impure
> functions? E.g. if func() changes the value of flag, then exchanging the
> order they are evaluated might change the result. Of course, this is all
> the fault of the programmer, but still..
It doesn't matter. The code is invalid. A compiler can do anything.
F2018: 10.1.4 Evaluation of operations
An intrinsic operation requires the values of its operands.
Execution of a function reference in the logical expression in
an IF statement (11.1.8.4), the mask expression in a WHERE
statement (10.2.3.1), or the concurrent-limits and concurrent-steps
in a FORALL statement (10.2.4) is permitted to define variables in
the subsidiary action-stmt, where-assignment-stmt, or
forall-assignment-stmt respectively. Except in those cases:
· the evaluation of a function reference shall neither affect
nor be affected by the evaluation of any other entity within
the statement;
· if a function reference causes definition or undefinition of
an actual argument of the function, that argument or any
associated entities shall not appear elsewhere in the same
statement.
>
> But at least for pure functions, this optimization looks Ok.
>
Why is everyone fixated on PURE vs IMPURE functions? The Fortran
standard allows short circuiting regardless of the pureness of
a function.
F2018: 10.1.5.4.2 Evaluation of logical intrinsic operations
Once the interpretation of a logical intrinsic operation is
established, the processor may evaluate any other expression
that is logically equivalent, provided that the integrity of
parentheses in any expression is not violated.
Two expressions of type logical are logically equivalent if
their values are equal for all possible values of their
primaries.
'.false. .and. func()' and 'func() .and. .false.' are logically
equivalent to '.false.'
F2018: 10.1.7 Evaluation of operands
It is not necessary for a processor to evaluate all of ther
operands of an expression, or to evaluate entirely each
operand, if the value of the expression can be determined
otherwise.
In fact, F2018 NOTE 10.28 describes this exact situation.
NOTE 10.28
This principle is most often applicable to logical expressions,
zero-sized arrays, and zero-length strings, but it applies to
all expressions.
For example, in evaluating the expression
X > Y .OR. L(Z)
where X, Y, and Z are real and L is a function of type logical,
the function reference L(Z) need not be evaluated if X is greater
than Y.
There is no statement about L(Z) being PURE or not.
Thomas' patch is simply trying to alert users to the fact that
their code may not do what they think. His check for pureness
versus impureness is an attempt to reduce warnings where the
the non-evaluation of pure function cannot change the outcome
of program.
Finally, I think that he can change the warning from
+ if (f->symtree == NULL || f->symtree->n.sym == NULL
+ || !gfc_implicit_pure (f->symtree->n.sym))
+ {
+ if (name)
+ gfc_warning (OPT_Wsurprising, "Impure function %qs at %L "
+ "might not be evaluated", name, &f->where);
+ else
+ gfc_warning (OPT_Wsurprising, "Impure function at %L "
+ "might not be evaluated", &f->where);
+ }
to
+ if (f->symtree == NULL || f->symtree->n.sym == NULL
+ || !gfc_implicit_pure (f->symtree->n.sym))
+ {
+ if (name)
+ gfc_warning (OPT_Wsurprising, "Function %qs at %L "
+ "might not be evaluated", name, &f->where);
+ else
+ gfc_warning (OPT_Wsurprising, "Function at %L "
+ "might not be evaluated", &f->where);
+ }
That is, remove the word 'Impure' as it can be misleading.
--
Steve
More information about the Gcc-patches
mailing list