Hi. After I added 2 new options, I would like to include a new master option. It's minimal version which only disables optimizations that we are aware of and can potentially cause problems for live-patching. Martin
>From dd52cd0249fc30cf6d7bf01a8826323277817b78 Mon Sep 17 00:00:00 2001 From: marxin <mliska@xxxxxxx> Date: Wed, 7 Nov 2018 12:41:19 +0100 Subject: [PATCH] Come up with -fvectorized-functions. --- gcc/fortran/decl.c | 33 +++++++++++++++++++++++++++ gcc/fortran/gfortran.h | 2 ++ gcc/fortran/match.h | 1 + gcc/fortran/parse.c | 3 +++ gcc/fortran/trans-intrinsic.c | 43 +++++++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+) diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 2b77d950abb..938c35c508f 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -98,6 +98,9 @@ bool gfc_matching_function; /* Set upon parsing a !GCC$ unroll n directive for use in the next loop. */ int directive_unroll = -1; +/* List middle-end built-ins that should be vectorized. */ +vec<const char *> vectorized_builtins; + /* If a kind expression of a component of a parameterized derived type is parameterized, temporarily store the expression here. */ static gfc_expr *saved_kind_expr = NULL; @@ -11243,3 +11246,33 @@ gfc_match_gcc_unroll (void) gfc_error ("Syntax error in !GCC$ UNROLL directive at %C"); return MATCH_ERROR; } + +/* Match a !GCC$ builtin b attributes flags form: + + The parameter b is name of a middle-end built-in. + Flags are one of: + - omp-simd-notinbranch. + + When we come here, we have already matched the !GCC$ builtin string. */ +match +gfc_match_gcc_builtin (void) +{ + char builtin[GFC_MAX_SYMBOL_LEN + 1]; + + if (gfc_match_name (builtin) != MATCH_YES) + return MATCH_ERROR; + + gfc_gobble_whitespace (); + if (gfc_match ("attributes") != MATCH_YES) + return MATCH_ERROR; + + gfc_gobble_whitespace (); + if (gfc_match ("omp_simd_notinbranch") != MATCH_YES) + return MATCH_ERROR; + + char *r = XNEWVEC (char, strlen (builtin) + 32); + sprintf (r, "__builtin_%s", builtin); + vectorized_builtins.safe_push (r); + + return MATCH_YES; +} diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index d8ef35d9d6c..bb7f4dd0c4b 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2763,6 +2763,7 @@ gfc_finalizer; bool gfc_in_match_data (void); match gfc_match_char_spec (gfc_typespec *); extern int directive_unroll; +extern vec<const char *> vectorized_builtins; /* Handling Parameterized Derived Types */ bool gfc_insert_kind_parameter_exprs (gfc_expr *); @@ -3501,5 +3502,6 @@ bool gfc_is_reallocatable_lhs (gfc_expr *); /* trans-decl.c */ void finish_oacc_declare (gfc_namespace *, gfc_symbol *, bool); +void gfc_adjust_builtins (void); #endif /* GCC_GFORTRAN_H */ diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h index 418542bd5a6..f25ed860c06 100644 --- a/gcc/fortran/match.h +++ b/gcc/fortran/match.h @@ -247,6 +247,7 @@ 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_import (void); match gfc_match_intent (void); match gfc_match_intrinsic (void); diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index 13cc6f5fccd..56d0d050bc3 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -1072,6 +1072,7 @@ 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); /* All else has failed, so give up. See if any of the matchers has stored an error message of some sort. */ @@ -5663,6 +5664,8 @@ parse_progunit (gfc_statement st) gfc_state_data *p; int n; + gfc_adjust_builtins (); + if (gfc_new_block && gfc_new_block->abr_modproc_decl && gfc_new_block->attr.function) diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 4ae2b3252b5..0417e039a39 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -597,7 +597,50 @@ define_quad_builtin (const char *name, tree type, bool is_const) return fndecl; } +/* Add SIMD attribute for FNDECL built-in if the built-in + name is in VECTORIZED_BUILTINS. */ +static void +add_simd_flag_for_built_in (tree fndecl) +{ + if (fndecl == NULL_TREE) + return; + + const char *name = IDENTIFIER_POINTER (DECL_NAME (fndecl)); + for (unsigned i = 0; i < vectorized_builtins.length (); i++) + if (strcmp (vectorized_builtins[i], name) == 0) + { + DECL_ATTRIBUTES (fndecl) + = tree_cons (get_identifier ("omp declare simd"), + build_tree_list (NULL_TREE, + build_omp_clause (UNKNOWN_LOCATION, + OMP_CLAUSE_NOTINBRANCH)), + DECL_ATTRIBUTES (fndecl)); + return; + } +} + +void +gfc_adjust_builtins (void) +{ + gfc_intrinsic_map_t *m; + for (m = gfc_intrinsic_map; + m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++) + { + add_simd_flag_for_built_in (m->real4_decl); + add_simd_flag_for_built_in (m->complex4_decl); + add_simd_flag_for_built_in (m->real8_decl); + add_simd_flag_for_built_in (m->complex8_decl); + add_simd_flag_for_built_in (m->real10_decl); + add_simd_flag_for_built_in (m->complex10_decl); + add_simd_flag_for_built_in (m->real16_decl); + add_simd_flag_for_built_in (m->complex16_decl); + add_simd_flag_for_built_in (m->real16_decl); + add_simd_flag_for_built_in (m->complex16_decl); + } + + vectorized_builtins.truncate (0); +} /* Initialize function decls for library functions. The external functions are created as required. Builtin functions are added here. */ -- 2.19.1