mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 23:11:36 +08:00
re PR fortran/91496 (!GCC$ directives error if mistyped or unknown)
2019-08-27 Harald Anlauf <anlauf@gmx.de> PR fortran/91496 * gfortran.h: Extend struct gfc_iterator for loop annotations. * array.c (gfc_copy_iterator): Copy loop annotations by IVDEP, VECTOR, and NOVECTOR pragmas. * decl.c (gfc_match_gcc_ivdep, gfc_match_gcc_vector) (gfc_match_gcc_novector): New matcher functions handling IVDEP, VECTOR, and NOVECTOR pragmas. * match.h: Declare prototypes of matcher functions handling IVDEP, VECTOR, and NOVECTOR pragmas. * parse.c (decode_gcc_attribute, parse_do_block) (parse_executable): Decode IVDEP, VECTOR, and NOVECTOR pragmas; emit warning for unrecognized pragmas instead of error. * trans-stmt.c (gfc_trans_simple_do, gfc_trans_do): Add code to emit annotations for IVDEP, VECTOR, and NOVECTOR pragmas. * gfortran.texi: Document IVDEP, VECTOR, and NOVECTOR pragmas. PR fortran/91496 * gfortran.dg/pr91496.f90: New testcase. From-SVN: r274966
This commit is contained in:
parent
340d34bf76
commit
2bd86b95f7
@ -1,3 +1,21 @@
|
||||
2019-08-27 Harald Anlauf <anlauf@gmx.de>
|
||||
|
||||
PR fortran/91496
|
||||
* gfortran.h: Extend struct gfc_iterator for loop annotations.
|
||||
* array.c (gfc_copy_iterator): Copy loop annotations by IVDEP,
|
||||
VECTOR, and NOVECTOR pragmas.
|
||||
* decl.c (gfc_match_gcc_ivdep, gfc_match_gcc_vector)
|
||||
(gfc_match_gcc_novector): New matcher functions handling IVDEP,
|
||||
VECTOR, and NOVECTOR pragmas.
|
||||
* match.h: Declare prototypes of matcher functions handling IVDEP,
|
||||
VECTOR, and NOVECTOR pragmas.
|
||||
* parse.c (decode_gcc_attribute, parse_do_block)
|
||||
(parse_executable): Decode IVDEP, VECTOR, and NOVECTOR pragmas;
|
||||
emit warning for unrecognized pragmas instead of error.
|
||||
* trans-stmt.c (gfc_trans_simple_do, gfc_trans_do): Add code to
|
||||
emit annotations for IVDEP, VECTOR, and NOVECTOR pragmas.
|
||||
* gfortran.texi: Document IVDEP, VECTOR, and NOVECTOR pragmas.
|
||||
|
||||
2019-08-27 Mark Eggleston <mark.eggleston@codethink.com>
|
||||
|
||||
* invoke.texi: Ensure that the option lists fit within the
|
||||
|
@ -2185,6 +2185,9 @@ gfc_copy_iterator (gfc_iterator *src)
|
||||
dest->end = gfc_copy_expr (src->end);
|
||||
dest->step = gfc_copy_expr (src->step);
|
||||
dest->unroll = src->unroll;
|
||||
dest->ivdep = src->ivdep;
|
||||
dest->vector = src->vector;
|
||||
dest->novector = src->novector;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
@ -99,6 +99,11 @@ bool gfc_matching_function;
|
||||
/* Set upon parsing a !GCC$ unroll n directive for use in the next loop. */
|
||||
int directive_unroll = -1;
|
||||
|
||||
/* Set upon parsing supported !GCC$ pragmas for use in the next loop. */
|
||||
bool directive_ivdep = false;
|
||||
bool directive_vector = false;
|
||||
bool directive_novector = false;
|
||||
|
||||
/* Map of middle-end built-ins that should be vectorized. */
|
||||
hash_map<nofree_string_hash, int> *gfc_vectorized_builtins;
|
||||
|
||||
@ -11528,3 +11533,53 @@ gfc_match_gcc_builtin (void)
|
||||
|
||||
return MATCH_YES;
|
||||
}
|
||||
|
||||
/* Match an !GCC$ IVDEP statement.
|
||||
When we come here, we have already matched the !GCC$ IVDEP string. */
|
||||
|
||||
match
|
||||
gfc_match_gcc_ivdep (void)
|
||||
{
|
||||
if (gfc_match_eos () == MATCH_YES)
|
||||
{
|
||||
directive_ivdep = true;
|
||||
return MATCH_YES;
|
||||
}
|
||||
|
||||
gfc_error ("Syntax error in !GCC$ IVDEP directive at %C");
|
||||
return MATCH_ERROR;
|
||||
}
|
||||
|
||||
/* Match an !GCC$ VECTOR statement.
|
||||
When we come here, we have already matched the !GCC$ VECTOR string. */
|
||||
|
||||
match
|
||||
gfc_match_gcc_vector (void)
|
||||
{
|
||||
if (gfc_match_eos () == MATCH_YES)
|
||||
{
|
||||
directive_vector = true;
|
||||
directive_novector = false;
|
||||
return MATCH_YES;
|
||||
}
|
||||
|
||||
gfc_error ("Syntax error in !GCC$ VECTOR directive at %C");
|
||||
return MATCH_ERROR;
|
||||
}
|
||||
|
||||
/* Match an !GCC$ NOVECTOR statement.
|
||||
When we come here, we have already matched the !GCC$ NOVECTOR string. */
|
||||
|
||||
match
|
||||
gfc_match_gcc_novector (void)
|
||||
{
|
||||
if (gfc_match_eos () == MATCH_YES)
|
||||
{
|
||||
directive_novector = true;
|
||||
directive_vector = false;
|
||||
return MATCH_YES;
|
||||
}
|
||||
|
||||
gfc_error ("Syntax error in !GCC$ NOVECTOR directive at %C");
|
||||
return MATCH_ERROR;
|
||||
}
|
||||
|
@ -2418,6 +2418,9 @@ typedef struct
|
||||
{
|
||||
gfc_expr *var, *start, *end, *step;
|
||||
unsigned short unroll;
|
||||
bool ivdep;
|
||||
bool vector;
|
||||
bool novector;
|
||||
}
|
||||
gfc_iterator;
|
||||
|
||||
@ -2794,6 +2797,9 @@ gfc_finalizer;
|
||||
bool gfc_in_match_data (void);
|
||||
match gfc_match_char_spec (gfc_typespec *);
|
||||
extern int directive_unroll;
|
||||
extern bool directive_ivdep;
|
||||
extern bool directive_vector;
|
||||
extern bool directive_novector;
|
||||
|
||||
/* SIMD clause enum. */
|
||||
enum gfc_simd_clause
|
||||
|
@ -3559,6 +3559,9 @@ as this requires the new array descriptor.
|
||||
* ATTRIBUTES directive::
|
||||
* UNROLL directive::
|
||||
* BUILTIN directive::
|
||||
* IVDEP directive::
|
||||
* VECTOR directive::
|
||||
* NOVECTOR directive::
|
||||
@end menu
|
||||
|
||||
@node ATTRIBUTES directive
|
||||
@ -3670,6 +3673,52 @@ for the built-in that should be vectorized. Example usage:
|
||||
The purpose of the directive is to provide an API among the GCC compiler and
|
||||
the GNU C Library which would define vector implementations of math routines.
|
||||
|
||||
|
||||
@node IVDEP directive
|
||||
@subsection IVDEP directive
|
||||
|
||||
The syntax of the directive is
|
||||
|
||||
@code{!GCC$ ivdep}
|
||||
|
||||
This directive tells the compiler to ignore vector dependencies in the
|
||||
following loop. It must be placed immediately before a @code{DO} loop
|
||||
and applies only to the loop that follows.
|
||||
|
||||
Sometimes the compiler may not have sufficient information to decide
|
||||
whether a particular loop is vectorizable due to potential
|
||||
dependencies between iterations. The purpose of the directive is to
|
||||
tell the compiler that vectorization is safe.
|
||||
|
||||
This directive is intended for annotation of existing code. For new
|
||||
code it is recommended to consider OpenMP SIMD directives as potential
|
||||
alternative.
|
||||
|
||||
|
||||
@node VECTOR directive
|
||||
@subsection VECTOR directive
|
||||
|
||||
The syntax of the directive is
|
||||
|
||||
@code{!GCC$ vector}
|
||||
|
||||
This directive tells the compiler to vectorize the following loop. It
|
||||
must be placed immediately before a @code{DO} loop and applies only to
|
||||
the loop that follows.
|
||||
|
||||
|
||||
@node NOVECTOR directive
|
||||
@subsection NOVECTOR directive
|
||||
|
||||
The syntax of the directive is
|
||||
|
||||
@code{!GCC$ novector}
|
||||
|
||||
This directive tells the compiler to not vectorize the following loop.
|
||||
It must be placed immediately before a @code{DO} loop and applies only
|
||||
to the loop that follows.
|
||||
|
||||
|
||||
@node Non-Fortran Main Program
|
||||
@section Non-Fortran Main Program
|
||||
|
||||
|
@ -246,8 +246,11 @@ match gfc_match_contiguous (void);
|
||||
match gfc_match_dimension (void);
|
||||
match gfc_match_external (void);
|
||||
match gfc_match_gcc_attributes (void);
|
||||
match gfc_match_gcc_unroll (void);
|
||||
match gfc_match_gcc_builtin (void);
|
||||
match gfc_match_gcc_ivdep (void);
|
||||
match gfc_match_gcc_novector (void);
|
||||
match gfc_match_gcc_unroll (void);
|
||||
match gfc_match_gcc_vector (void);
|
||||
match gfc_match_import (void);
|
||||
match gfc_match_intent (void);
|
||||
match gfc_match_intrinsic (void);
|
||||
|
@ -1079,12 +1079,20 @@ decode_gcc_attribute (void)
|
||||
match ("attributes", gfc_match_gcc_attributes, ST_ATTR_DECL);
|
||||
match ("unroll", gfc_match_gcc_unroll, ST_NONE);
|
||||
match ("builtin", gfc_match_gcc_builtin, ST_NONE);
|
||||
match ("ivdep", gfc_match_gcc_ivdep, ST_NONE);
|
||||
match ("vector", gfc_match_gcc_vector, ST_NONE);
|
||||
match ("novector", gfc_match_gcc_novector, ST_NONE);
|
||||
|
||||
/* All else has failed, so give up. See if any of the matchers has
|
||||
stored an error message of some sort. */
|
||||
|
||||
if (!gfc_error_check ())
|
||||
gfc_error_now ("Unclassifiable GCC directive at %C");
|
||||
{
|
||||
if (pedantic)
|
||||
gfc_error_now ("Unclassifiable GCC directive at %C");
|
||||
else
|
||||
gfc_warning_now (0, "Unclassifiable GCC directive at %C, ignored");
|
||||
}
|
||||
|
||||
reject_statement ();
|
||||
|
||||
@ -4672,6 +4680,21 @@ parse_do_block (void)
|
||||
new_st.ext.iterator->unroll = directive_unroll;
|
||||
directive_unroll = -1;
|
||||
}
|
||||
if (directive_ivdep)
|
||||
{
|
||||
new_st.ext.iterator->ivdep = directive_ivdep;
|
||||
directive_ivdep = false;
|
||||
}
|
||||
if (directive_vector)
|
||||
{
|
||||
new_st.ext.iterator->vector = directive_vector;
|
||||
directive_vector = false;
|
||||
}
|
||||
if (directive_novector)
|
||||
{
|
||||
new_st.ext.iterator->novector = directive_novector;
|
||||
directive_novector = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
stree = NULL;
|
||||
@ -5433,6 +5456,15 @@ parse_executable (gfc_statement st)
|
||||
if (directive_unroll != -1)
|
||||
gfc_error ("%<GCC unroll%> directive does not commence a loop at %C");
|
||||
|
||||
if (directive_ivdep)
|
||||
gfc_error ("%<GCC ivdep%> directive does not commence a loop at %C");
|
||||
|
||||
if (directive_vector)
|
||||
gfc_error ("%<GCC vector%> directive does not commence a loop at %C");
|
||||
|
||||
if (directive_novector)
|
||||
gfc_error ("%<GCC novector%> directive does not commence a loop at %C");
|
||||
|
||||
st = next_statement ();
|
||||
}
|
||||
}
|
||||
|
@ -2173,6 +2173,19 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
|
||||
build_int_cst (integer_type_node, annot_expr_unroll_kind),
|
||||
build_int_cst (integer_type_node, code->ext.iterator->unroll));
|
||||
|
||||
if (code->ext.iterator->ivdep && cond != error_mark_node)
|
||||
cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
|
||||
build_int_cst (integer_type_node, annot_expr_ivdep_kind),
|
||||
integer_zero_node);
|
||||
if (code->ext.iterator->vector && cond != error_mark_node)
|
||||
cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
|
||||
build_int_cst (integer_type_node, annot_expr_vector_kind),
|
||||
integer_zero_node);
|
||||
if (code->ext.iterator->novector && cond != error_mark_node)
|
||||
cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
|
||||
build_int_cst (integer_type_node, annot_expr_no_vector_kind),
|
||||
integer_zero_node);
|
||||
|
||||
/* The loop exit. */
|
||||
tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
|
||||
TREE_USED (exit_label) = 1;
|
||||
@ -2503,6 +2516,20 @@ gfc_trans_do (gfc_code * code, tree exit_cond)
|
||||
= build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
|
||||
build_int_cst (integer_type_node, annot_expr_unroll_kind),
|
||||
build_int_cst (integer_type_node, code->ext.iterator->unroll));
|
||||
|
||||
if (code->ext.iterator->ivdep && cond != error_mark_node)
|
||||
cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
|
||||
build_int_cst (integer_type_node, annot_expr_ivdep_kind),
|
||||
integer_zero_node);
|
||||
if (code->ext.iterator->vector && cond != error_mark_node)
|
||||
cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
|
||||
build_int_cst (integer_type_node, annot_expr_vector_kind),
|
||||
integer_zero_node);
|
||||
if (code->ext.iterator->novector && cond != error_mark_node)
|
||||
cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
|
||||
build_int_cst (integer_type_node, annot_expr_no_vector_kind),
|
||||
integer_zero_node);
|
||||
|
||||
tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
|
||||
tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
|
||||
cond, tmp, build_empty_stmt (loc));
|
||||
|
@ -1,3 +1,8 @@
|
||||
2019-08-27 Harald Anlauf <anlauf@gmx.de>
|
||||
|
||||
PR fortran/91496
|
||||
* gfortran.dg/pr91496.f90: New testcase.
|
||||
|
||||
2019-08-27 Uroš Bizjak <ubizjak@gmail.com>
|
||||
|
||||
* gcc.target/i386/sse4_1-round-roundeven-1.c (dg-options):
|
||||
|
38
gcc/testsuite/gfortran.dg/pr91496.f90
Normal file
38
gcc/testsuite/gfortran.dg/pr91496.f90
Normal file
@ -0,0 +1,38 @@
|
||||
! { dg-do compile }
|
||||
! { dg-options "-fdump-tree-original" }
|
||||
!
|
||||
subroutine foo (a, b, c, n)
|
||||
implicit none
|
||||
real a(*), b(*), c(*)
|
||||
integer :: i, n
|
||||
external bar
|
||||
!DIR$ unroll (4)
|
||||
!GCC$ unroll 4
|
||||
do i = 1, n
|
||||
a(i) = b(i) + c(i)
|
||||
end do
|
||||
!DIR$ ivdep
|
||||
!GCC$ ivdep
|
||||
do i = 1, n
|
||||
a(i) = b(i) + c(i)
|
||||
end do
|
||||
!DIR$ vector
|
||||
!GCC$ vector
|
||||
do i = 1, n
|
||||
a(i) = b(i) + c(i)
|
||||
end do
|
||||
!DIR$ novector
|
||||
!GCC$ novector
|
||||
do i = 1, n
|
||||
a(i) = b(i) + c(i)
|
||||
end do
|
||||
!GCC$ ivdep
|
||||
!GCC$ vector
|
||||
do i = 1, n
|
||||
a(i) = b(i) + c(i)
|
||||
end do
|
||||
!DIR$ noinline
|
||||
!GCC$ noinline ! { dg-warning "Unclassifiable GCC directive" }
|
||||
call bar (a)
|
||||
end subroutine foo
|
||||
! { dg-final { scan-tree-dump-times "ANNOTATE_EXPR" 6 "original" } }
|
Loading…
x
Reference in New Issue
Block a user