Hi All,
I took a few moments away from what I really must be doing to try out
an earlier version of the patch. There are quite a few CRs in the
patch and the third chunk in gcc.c was rejected, although I cannot see
why. I made a change to scanner.c to prevent the segfault that results
from not having the pre-include file in the right directory - see
attached.
Everything works fine with the testcases and a slightly evolved
version shows reasonable speed-ups:
program test_overloaded_intrinsic
real(4) :: x4(3200), y4(3200, 10000)
real(8) :: x8(3200), y8(3200)
do i = 1,10000
y4(:,i) = cos(x4)
y4(:,i) = x4*y4(:,i)
y4(:,i) = sqrt(y4(:,i))
end do
print *, y4(1,1)
end
Disappointingly, though, one of the worst cases in
https://www.fortran.uk/fortran-compiler-comparisons/ of a big
difference between gfortran and ifort with vectorization,
mp_prop_design.f90, doesn't seem to pick up any of the vectorization
opportunities, even though it is peppered with trig functions. Should
I be expecting this? Yes, I did add the other trig functions to the
pre-include file :-)
Best regards and thanks for taking care of this
Paul
On Fri, 16 Nov 2018 at 15:13, Martin Liška <[email protected]> wrote:
>
> On 11/16/18 2:49 PM, Jakub Jelinek wrote:
> > On Fri, Nov 16, 2018 at 02:24:42PM +0100, Martin Liška wrote:
> >> + if (gfc_match (" (%n) attributes simd", builtin) != MATCH_YES)
> >> + return MATCH_ERROR;
> >> +
> >> + int builtin_kind = 0;
> >> + if (gfc_match (" (notinbranch)") == MATCH_YES)
> >
> > I think you need " ( notinbranch )" here.
> >
> >> + builtin_kind = -1;
> >> + else if (gfc_match (" (inbranch)") == MATCH_YES)
> >> + builtin_kind = 1;
> >
> > And similarly here (+ testsuite coverage for whether you can in free form
> > insert spaces in all the spots that should be allowed).
> > !gcc$ builtin ( sinf ) attributes simd ( notinbranch ) ! comment
> > e.g. should be valid in free form (and fixed form too).
> >
> >> --- a/gcc/fortran/gfortran.h
> >> +++ b/gcc/fortran/gfortran.h
> >> @@ -2764,6 +2764,18 @@ bool gfc_in_match_data (void);
> >> match gfc_match_char_spec (gfc_typespec *);
> >> extern int directive_unroll;
> >>
> >> +/* Tuple for parsing of vectorized built-ins. */
> >> +struct vect_builtin_tuple
> >> +{
> >> + vect_builtin_tuple (const char *n, int t): name (n), simd_type (t)
> >
> > gfc_vect_builtin_tuple ?
> > + document what the simd_type is (or make it enum or whatever).
> > One option would be enum omp_clause_code and use OMP_CLAUSE_ERROR for
> > the case where the argument isn't specified, but I think generally
> > gfortran.h doesn't depend on tree* stuff and wants to have its own
> > enums etc.
> >
> >> +extern vec<vect_builtin_tuple> vectorized_builtins;
> >
> > gfc_vectorized_builtins ?
> >
> >> --- a/gcc/fortran/trans-intrinsic.c
> >> +++ b/gcc/fortran/trans-intrinsic.c
> >> @@ -597,7 +597,61 @@ 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. */
> >> +#include "print-tree.h"
> >
> > If you need to include a header, include it at the start of the file.
> >
> >> +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, name) == 0)
> >
> > How many add_simd_flag_for_built_in calls are we expecting and how many
> > vectorized_builtins.length ()? If it is too much, perhaps e.g. sort
> > the vector by name and do a binary search. At least if it turns out to be
> > non-trivial compile time.
> >> +
> >> + vectorized_builtins.truncate (0);
> >
> > That is a memory leak, right? The names are malloced.
> > And why truncate rather than release?
> >> + const char *path = find_a_file (&include_prefixes, argv[1], R_OK, true);
> >> + if (path != NULL)
> >> + return concat (argv[0], path, NULL);
> >
> > Formatting.
> >> --- /dev/null
> >> +++ b/gcc/testsuite/gfortran.dg/simd-builtins-1.h
> >> @@ -0,0 +1,4 @@
> >> +!GCC$ builtin (sinf) attributes simd
> >> +!GCC$ builtin (sinf) attributes simd (inbranch)
> >> +!GCC$ builtin (sinf) attributes simd (notinbranch)
> >> +!GCC$ builtin (cosf) attributes simd (notinbranch)
> >
> > Are you sure it is a good idea to have the 3 first lines for the same
> > builtin, rather than different?
> >
> > It should be testsuite covered what we do in that case, but with the above
> > you don't cover what happens e.g. with notinbranch alone, or no argument.
> >
> > Plus, as I said, I think you should have one *.f and one *.f90 test where
> > you just use many of those !gcc$ builtin lines with spaces in various spots
> > to verify it is parsed properly.
> >
> > Jakub
> >
>
> Hi.
>
> I'm sending version, I changed the container to hash_map that should provide
> faster look up.
>
> I've been testing the patch right now.
>
> Martin
--
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein
Index: gcc/config/gnu-user.h
===================================================================
*** gcc/config/gnu-user.h (revision 266027)
--- gcc/config/gnu-user.h (working copy)
*************** see the files COPYING3 and COPYING.RUNTI
*** 170,172 ****
--- 170,176 ----
LD_STATIC_OPTION " --whole-archive -llsan --no-whole-archive " \
LD_DYNAMIC_OPTION "}}%{!static-liblsan:-llsan}"
#endif
+
+ #undef TARGET_F951_OPTIONS
+ #define TARGET_F951_OPTIONS "%{!nostdinc:\
+ %:fortran-preinclude-file(-fpre-include= math-vector-fortran.h)}"
Index: gcc/fortran/decl.c
===================================================================
*** gcc/fortran/decl.c (revision 266027)
--- gcc/fortran/decl.c (working copy)
*************** bool gfc_matching_function;
*** 98,103 ****
--- 98,106 ----
/* 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<vect_builtin_tuple> 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;
*************** gfc_match_gcc_unroll (void)
*** 11243,11245 ****
--- 11246,11278 ----
gfc_error ("Syntax error in !GCC$ UNROLL directive at %C");
return MATCH_ERROR;
}
+
+ /* Match a !GCC$ builtin (b) attributes simd flags form:
+
+ The parameter b is name of a middle-end built-in.
+ Flags are one of:
+ - (empty)
+ - inbranch
+ - 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 (" (%n) attributes simd", builtin) != MATCH_YES)
+ return MATCH_ERROR;
+
+ int builtin_kind = 0;
+ if (gfc_match (" (notinbranch)") == MATCH_YES)
+ builtin_kind = -1;
+ else if (gfc_match (" (inbranch)") == MATCH_YES)
+ builtin_kind = 1;
+
+ char *r = XNEWVEC (char, strlen (builtin) + 32);
+ sprintf (r, "__builtin_%s", builtin);
+ vectorized_builtins.safe_push (vect_builtin_tuple (r, builtin_kind));
+
+ return MATCH_YES;
+ }
Index: gcc/fortran/gfortran.h
===================================================================
*** gcc/fortran/gfortran.h (revision 266027)
--- gcc/fortran/gfortran.h (working copy)
*************** bool gfc_in_match_data (void);
*** 2764,2769 ****
--- 2764,2781 ----
match gfc_match_char_spec (gfc_typespec *);
extern int directive_unroll;
+ /* Tuple for parsing of vectorized built-ins. */
+ struct vect_builtin_tuple
+ {
+ vect_builtin_tuple (const char *n, int t): name (n), simd_type (t)
+ {}
+
+ const char *name;
+ int simd_type;
+ };
+
+ extern vec<vect_builtin_tuple> vectorized_builtins;
+
/* Handling Parameterized Derived Types */
bool gfc_insert_kind_parameter_exprs (gfc_expr *);
bool gfc_insert_parameter_exprs (gfc_expr *, gfc_actual_arglist *);
*************** bool gfc_is_reallocatable_lhs (gfc_expr
*** 3501,3505 ****
--- 3513,3518 ----
/* trans-decl.c */
void finish_oacc_declare (gfc_namespace *, gfc_symbol *, bool);
+ void gfc_adjust_builtins (void);
#endif /* GCC_GFORTRAN_H */
Index: gcc/fortran/lang-specs.h
===================================================================
*** gcc/fortran/lang-specs.h (revision 266027)
--- gcc/fortran/lang-specs.h (working copy)
***************
*** 32,40 ****
#define F951_CPP_OPTIONS "%{!nocpp: -cpp=%g.f90 %{E} %(cpp_unique_options) \
%{E|M|MM:%(cpp_debug_options) " CPP_ONLY_OPTIONS \
" -fsyntax-only};: " CPP_FORWARD_OPTIONS "}"
#define F951_OPTIONS "%(cc1_options) %{J*} \
! %{!nostdinc:-fintrinsic-modules-path finclude%s}\
! %{!fsyntax-only:%(invoke_as)}"
#define F951_SOURCE_FORM "%{!ffree-form:-ffixed-form}"
--- 32,46 ----
#define F951_CPP_OPTIONS "%{!nocpp: -cpp=%g.f90 %{E} %(cpp_unique_options) \
%{E|M|MM:%(cpp_debug_options) " CPP_ONLY_OPTIONS \
" -fsyntax-only};: " CPP_FORWARD_OPTIONS "}"
+
+ #ifndef TARGET_F951_OPTIONS
+ #define TARGET_F951_OPTIONS
+ #endif
+
#define F951_OPTIONS "%(cc1_options) %{J*} \
! %{!nostdinc:-fintrinsic-modules-path finclude%s}" \
! TARGET_F951_OPTIONS \
! "%{!fsyntax-only:%(invoke_as)}"
#define F951_SOURCE_FORM "%{!ffree-form:-ffixed-form}"
Index: gcc/fortran/lang.opt
===================================================================
*** gcc/fortran/lang.opt (revision 266027)
--- gcc/fortran/lang.opt (working copy)
*************** fprotect-parens
*** 662,667 ****
--- 662,671 ----
Fortran Var(flag_protect_parens) Init(-1)
Protect parentheses in expressions.
+ fpre-include=
+ Fortran RejectNegative Joined Var(flag_pre_include) Undocumented
+ Path to header file that should be pre-included before each compilation unit.
+
frange-check
Fortran Var(flag_range_check) Init(1)
Enable range checking during compilation.
Index: gcc/fortran/match.h
===================================================================
*** gcc/fortran/match.h (revision 266027)
--- gcc/fortran/match.h (working copy)
*************** match gfc_match_dimension (void);
*** 247,252 ****
--- 247,253 ----
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);
Index: gcc/fortran/parse.c
===================================================================
*** gcc/fortran/parse.c (revision 266027)
--- gcc/fortran/parse.c (working copy)
*************** decode_gcc_attribute (void)
*** 1072,1077 ****
--- 1072,1078 ----
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. */
*************** parse_progunit (gfc_statement st)
*** 5663,5668 ****
--- 5664,5671 ----
gfc_state_data *p;
int n;
+ gfc_adjust_builtins ();
+
if (gfc_new_block
&& gfc_new_block->abr_modproc_decl
&& gfc_new_block->attr.function)
Index: gcc/fortran/scanner.c
===================================================================
*** gcc/fortran/scanner.c (revision 266027)
--- gcc/fortran/scanner.c (working copy)
*************** static locus gcc_attribute_locus;
*** 65,71 ****
gfc_source_form gfc_current_form;
static gfc_linebuf *line_head, *line_tail;
!
locus gfc_current_locus;
const char *gfc_source_file;
static FILE *gfc_src_file;
--- 65,71 ----
gfc_source_form gfc_current_form;
static gfc_linebuf *line_head, *line_tail;
!
locus gfc_current_locus;
const char *gfc_source_file;
static FILE *gfc_src_file;
*************** gfc_scanner_done_1 (void)
*** 282,300 ****
gfc_linebuf *lb;
gfc_file *f;
! while(line_head != NULL)
{
lb = line_head->next;
free (line_head);
line_head = lb;
}
!
! while(file_head != NULL)
{
f = file_head->next;
free (file_head->filename);
free (file_head);
! file_head = f;
}
}
--- 282,300 ----
gfc_linebuf *lb;
gfc_file *f;
! while(line_head != NULL)
{
lb = line_head->next;
free (line_head);
line_head = lb;
}
!
! while(file_head != NULL)
{
f = file_head->next;
free (file_head->filename);
free (file_head);
! file_head = f;
}
}
*************** add_path_to_list (gfc_directorylist **li
*** 311,317 ****
struct stat st;
size_t len;
int i;
!
p = path;
while (*p == ' ' || *p == '\t') /* someone might do "-I include" */
if (*p++ == '\0')
--- 311,317 ----
struct stat st;
size_t len;
int i;
!
p = path;
while (*p == ' ' || *p == '\t') /* someone might do "-I include" */
if (*p++ == '\0')
*************** gfc_advance_line (void)
*** 581,591 ****
if (gfc_at_end ())
return;
! if (gfc_current_locus.lb == NULL)
{
end_flag = 1;
return;
! }
if (gfc_current_locus.lb->next
&& !gfc_current_locus.lb->next->dbg_emitted)
--- 581,591 ----
if (gfc_at_end ())
return;
! if (gfc_current_locus.lb == NULL)
{
end_flag = 1;
return;
! }
if (gfc_current_locus.lb->next
&& !gfc_current_locus.lb->next->dbg_emitted)
*************** gfc_advance_line (void)
*** 596,608 ****
gfc_current_locus.lb = gfc_current_locus.lb->next;
! if (gfc_current_locus.lb != NULL)
gfc_current_locus.nextc = gfc_current_locus.lb->line;
! else
{
gfc_current_locus.nextc = NULL;
end_flag = 1;
! }
}
--- 596,608 ----
gfc_current_locus.lb = gfc_current_locus.lb->next;
! if (gfc_current_locus.lb != NULL)
gfc_current_locus.nextc = gfc_current_locus.lb->line;
! else
{
gfc_current_locus.nextc = NULL;
end_flag = 1;
! }
}
*************** static gfc_char_t
*** 619,625 ****
next_char (void)
{
gfc_char_t c;
!
if (gfc_current_locus.nextc == NULL)
return '\n';
--- 619,625 ----
next_char (void)
{
gfc_char_t c;
!
if (gfc_current_locus.nextc == NULL)
return '\n';
*************** skip_free_oacc_sentinel (locus start, lo
*** 736,742 ****
openacc_locus = old_loc;
gfc_current_locus = start;
}
! else
r = false;
}
else
--- 736,742 ----
openacc_locus = old_loc;
gfc_current_locus = start;
}
! else
r = false;
}
else
*************** skip_free_omp_sentinel (locus start, loc
*** 776,782 ****
openmp_locus = old_loc;
gfc_current_locus = start;
}
! else
r = false;
}
else
--- 776,782 ----
openmp_locus = old_loc;
gfc_current_locus = start;
}
! else
r = false;
}
else
*************** skip_fixed_comments (void)
*** 1051,1057 ****
}
/* If -fopenmp/-fopenacc, we need to handle here 2 things:
! 1) don't treat !$omp/!$acc|c$omp/c$acc|*$omp / *$acc as comments,
but directives
2) handle OpenMP/OpenACC conditional compilation, where
!$|c$|*$ should be treated as 2 spaces if the characters
--- 1051,1057 ----
}
/* If -fopenmp/-fopenacc, we need to handle here 2 things:
! 1) don't treat !$omp/!$acc|c$omp/c$acc|*$omp / *$acc as comments,
but directives
2) handle OpenMP/OpenACC conditional compilation, where
!$|c$|*$ should be treated as 2 spaces if the characters
*************** restart:
*** 1318,1324 ****
skip_comment_line ();
else
gfc_advance_line ();
!
if (gfc_at_eof ())
goto not_continuation;
--- 1318,1324 ----
skip_comment_line ();
else
gfc_advance_line ();
!
if (gfc_at_eof ())
goto not_continuation;
*************** restart:
*** 1421,1427 ****
{
gfc_current_locus.nextc--;
if (warn_ampersand && in_string == INSTRING_WARN)
! gfc_warning (OPT_Wampersand,
"Missing %<&%> in continued character "
"constant at %C");
}
--- 1421,1427 ----
{
gfc_current_locus.nextc--;
if (warn_ampersand && in_string == INSTRING_WARN)
! gfc_warning (OPT_Wampersand,
"Missing %<&%> in continued character "
"constant at %C");
}
*************** gfc_gobble_whitespace (void)
*** 1732,1738 ****
load_line returns whether the line was truncated.
NOTE: The error machinery isn't available at this point, so we can't
! easily report line and column numbers consistent with other
parts of gfortran. */
static int
--- 1732,1738 ----
load_line returns whether the line was truncated.
NOTE: The error machinery isn't available at this point, so we can't
! easily report line and column numbers consistent with other
parts of gfortran. */
static int
*************** load_line (FILE *input, gfc_char_t **pbu
*** 1788,1794 ****
if (c == '\n')
{
/* Check for illegal use of ampersand. See F95 Standard 3.3.1.3. */
! if (gfc_current_form == FORM_FREE
&& !seen_printable && seen_ampersand)
{
if (pedantic)
--- 1788,1794 ----
if (c == '\n')
{
/* Check for illegal use of ampersand. See F95 Standard 3.3.1.3. */
! if (gfc_current_form == FORM_FREE
&& !seen_printable && seen_ampersand)
{
if (pedantic)
*************** include_line (gfc_char_t *line)
*** 2174,2180 ****
c++;
/* Find filename between quotes. */
!
quote = *c++;
if (quote != '"' && quote != '\'')
return false;
--- 2174,2180 ----
c++;
/* Find filename between quotes. */
!
quote = *c++;
if (quote != '"' && quote != '\'')
return false;
*************** include_line (gfc_char_t *line)
*** 2188,2194 ****
return false;
stop = c++;
!
while (*c == ' ' || *c == '\t')
c++;
--- 2188,2194 ----
return false;
stop = c++;
!
while (*c == ' ' || *c == '\t')
c++;
*************** load_file (const char *realfilename, con
*** 2261,2268 ****
input = gfc_open_included_file (realfilename, false, false);
if (input == NULL)
{
! fprintf (stderr, "%s:%d: Error: Can't open included file '%s'\n",
! current_file->filename, current_file->line, filename);
return false;
}
stat_result = stat (realfilename, &st);
--- 2261,2272 ----
input = gfc_open_included_file (realfilename, false, false);
if (input == NULL)
{
! if (current_file)
! fprintf (stderr, "%s:%d: Error: Can't open included file '%s'\n",
! current_file->filename, current_file->line, filename);
! else
! fprintf (stderr, "Error: Can't open pre-included file '%s'\n",
! filename);
return false;
}
stat_result = stat (realfilename, &st);
*************** gfc_new_file (void)
*** 2428,2433 ****
--- 2432,2441 ----
{
bool result;
+ if (flag_pre_include != NULL
+ && !load_file (flag_pre_include, NULL, false))
+ exit (FATAL_EXIT_CODE);
+
if (gfc_cpp_enabled ())
{
result = gfc_cpp_preprocess (gfc_source_file);
Index: gcc/fortran/trans-intrinsic.c
===================================================================
*** gcc/fortran/trans-intrinsic.c (revision 266027)
--- gcc/fortran/trans-intrinsic.c (working copy)
*************** define_quad_builtin (const char *name, t
*** 597,603 ****
--- 597,657 ----
return fndecl;
}
+ /* Add SIMD attribute for FNDECL built-in if the built-in
+ name is in VECTORIZED_BUILTINS. */
+ #include "print-tree.h"
+ 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, name) == 0)
+ {
+ int simd_type = vectorized_builtins[i].simd_type;
+ tree omp_clause = NULL_TREE;
+ if (simd_type == 0)
+ ; /* No SIMD clause. */
+ else
+ {
+ omp_clause_code code
+ = (simd_type == 1 ? OMP_CLAUSE_INBRANCH : OMP_CLAUSE_NOTINBRANCH);
+ omp_clause = build_omp_clause (UNKNOWN_LOCATION, code);
+ omp_clause = build_tree_list (NULL_TREE, omp_clause);
+ }
+
+ DECL_ATTRIBUTES (fndecl)
+ = tree_cons (get_identifier ("omp declare simd"), omp_clause,
+ DECL_ATTRIBUTES (fndecl));
+ }
+ }
+
+ /* Set SIMD attribute to all built-in functions that are mentioned
+ in vectorized_builtins vector. */
+
+ 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. */
Index: gcc/gcc.c
===================================================================
*** gcc/gcc.c (revision 266027)
--- gcc/gcc.c (working copy)
*************** static const char *pass_through_libs_spe
*** 408,413 ****
--- 408,414 ----
static const char *replace_extension_spec_func (int, const char **);
static const char *greater_than_spec_func (int, const char **);
static const char *debug_level_greater_than_spec_func (int, const char **);
+ static const char *find_fortran_preinclude_file (int, const char **);
static char *convert_white_space (char *);
/* The Specs Language
*************** static const struct spec_function static
*** 1647,1652 ****
--- 1648,1654 ----
{ "replace-extension", replace_extension_spec_func },
{ "gt", greater_than_spec_func },
{ "debug-level-gt", debug_level_greater_than_spec_func },
+ { "fortran-preinclude-file", find_fortran_preinclude_file},
#ifdef EXTRA_SPEC_FUNCTIONS
EXTRA_SPEC_FUNCTIONS
#endif
*************** do_spec_1 (const char *spec, int inswitc
*** 5948,5954 ****
"%{foo=*:bar%*}%{foo=*:one%*two}"
matches -foo=hello then it will produce:
!
barhello onehellotwo
*/
if (*p == 0 || *p == '}')
--- 5950,5956 ----
"%{foo=*:bar%*}%{foo=*:one%*two}"
matches -foo=hello then it will produce:
!
barhello onehellotwo
*/
if (*p == 0 || *p == '}')
*************** static unsigned HOST_WIDE_INT
*** 9585,9593 ****
get_random_number (void)
{
unsigned HOST_WIDE_INT ret = 0;
! int fd;
! fd = open ("/dev/urandom", O_RDONLY);
if (fd >= 0)
{
read (fd, &ret, sizeof (HOST_WIDE_INT));
--- 9587,9595 ----
get_random_number (void)
{
unsigned HOST_WIDE_INT ret = 0;
! int fd;
! fd = open ("/dev/urandom", O_RDONLY);
if (fd >= 0)
{
read (fd, &ret, sizeof (HOST_WIDE_INT));
*************** greater_than_spec_func (int argc, const
*** 9868,9873 ****
--- 9870,9892 ----
return NULL;
}
+ /* The function takes 2 arguments: OPTION name and file name.
+ When the FILE is found by find_file, return OPTION=path_to_file. */
+
+ static const char *
+ find_fortran_preinclude_file (int argc, const char **argv)
+ {
+ if (argc != 2)
+ return NULL;
+
+ const char *path = find_a_file (&include_prefixes, argv[1], R_OK, true);
+ if (path != NULL)
+ return concat (argv[0], path, NULL);
+
+ return NULL;
+ }
+
+
/* Returns "" if debug_info_level is greater than ARGV[ARGC-1].
Otherwise, return NULL. */
*************** debug_level_greater_than_spec_func (int
*** 9889,9904 ****
return NULL;
}
! /* Insert backslash before spaces in ORIG (usually a file path), to
avoid being broken by spec parser.
This function is needed as do_spec_1 treats white space (' ' and '\t')
as the end of an argument. But in case of -plugin /usr/gcc install/xxx.so,
the file name should be treated as a single argument rather than being
! broken into multiple. Solution is to insert '\\' before the space in a
file name.
!
! This function converts and only converts all occurrence of ' '
to '\\' + ' ' and '\t' to '\\' + '\t'. For example:
"a b" -> "a\\ b"
"a b" -> "a\\ \\ b"
--- 9908,9923 ----
return NULL;
}
! /* Insert backslash before spaces in ORIG (usually a file path), to
avoid being broken by spec parser.
This function is needed as do_spec_1 treats white space (' ' and '\t')
as the end of an argument. But in case of -plugin /usr/gcc install/xxx.so,
the file name should be treated as a single argument rather than being
! broken into multiple. Solution is to insert '\\' before the space in a
file name.
!
! This function converts and only converts all occurrence of ' '
to '\\' + ' ' and '\t' to '\\' + '\t'. For example:
"a b" -> "a\\ b"
"a b" -> "a\\ \\ b"
Index: gcc/testsuite/gfortran.dg/simd-builtins-1.f90
===================================================================
*** gcc/testsuite/gfortran.dg/simd-builtins-1.f90 (nonexistent)
--- gcc/testsuite/gfortran.dg/simd-builtins-1.f90 (working copy)
***************
*** 0 ****
--- 1,19 ----
+ ! { dg-do compile { target x86_64-*-linux* } }
+ ! { dg-additional-options "-nostdinc -Ofast -fpre-include=simd-builtins-1.h -fdump-tree-optimized" }
+
+ program test_overloaded_intrinsic
+ real(4) :: x4(3200), y4(3200)
+ real(8) :: x8(3200), y8(3200)
+
+ ! this should be using simd clone
+ y4 = sin(x4)
+ print *, y4
+
+ ! this should not be using simd clone
+ y4 = sin(x8)
+ print *, y8
+ end
+
+ ! { dg-final { scan-tree-dump "sinf.simdclone" "optimized" } } */
+ ! { dg-final { scan-tree-dump "__builtin_sin" "optimized" } } */
+ ! { dg-final { scan-assembler "call.*_ZGVbN4v_sinf" } }
Index: gcc/testsuite/gfortran.dg/simd-builtins-1.h
===================================================================
*** gcc/testsuite/gfortran.dg/simd-builtins-1.h (nonexistent)
--- gcc/testsuite/gfortran.dg/simd-builtins-1.h (working copy)
***************
*** 0 ****
--- 1,4 ----
+ !GCC$ builtin (sinf) attributes simd
+ !GCC$ builtin (sinf) attributes simd (inbranch)
+ !GCC$ builtin (sinf) attributes simd (notinbranch)
+ !GCC$ builtin (cosf) attributes simd (notinbranch)
Index: gcc/testsuite/gfortran.dg/simd-builtins-2.f90
===================================================================
*** gcc/testsuite/gfortran.dg/simd-builtins-2.f90 (nonexistent)
--- gcc/testsuite/gfortran.dg/simd-builtins-2.f90 (working copy)
***************
*** 0 ****
--- 1,20 ----
+ ! { dg-do compile { target x86_64-*-linux* } }
+ ! { dg-additional-options "-nostdinc -Ofast -fdump-tree-optimized" }
+
+ program test_overloaded_intrinsic
+ real(4) :: x4(3200), y4(3200)
+ real(8) :: x8(3200), y8(3200)
+
+ ! this should be using simd clone
+ y4 = sin(x4)
+ print *, y4
+
+ ! this should not be using simd clone
+ y4 = sin(x8)
+ print *, y8
+ end
+
+ ! { dg-final { scan-tree-dump "__builtin_sinf" "optimized" } } */
+ ! { dg-final { scan-tree-dump "__builtin_sin" "optimized" } } */
+ ! { dg-final { scan-tree-dump-not "simdclone" "optimized" } } */
+ ! { dg-final { scan-assembler-not "call.*_ZGVbN4v_sinf" } }