invoke.texi (-fopenmp-simd): Document new option.
authorTobias Burnus <burnus@net-b.de>
Tue, 5 Nov 2013 07:29:47 +0000 (08:29 +0100)
committerTobias Burnus <burnus@gcc.gnu.org>
Tue, 5 Nov 2013 07:29:47 +0000 (08:29 +0100)
2013-11-05  Tobias Burnus  <burnus@net-b.de>

gcc/
        * doc/invoke.texi (-fopenmp-simd): Document new option.
        * gimplify.c (gimplify_body): Accept -fopenmp-simd.
        * omp-low.c (execute_expand_omp, execute_lower_omp): Ditto.
        * tree.c (attribute_value_equal): Ditto.

gcc/fortran/
        * lang.opt (fopenmp-simd): New option.
        * gfortran.h (gfc_option_t): Add gfc_flag_openmp_simd.
        * options.c (gfc_handle_option): Handle it.

gcc/c-family/
        * c.opt (fopenmp-simd): New option.
        * c-pragma.c (omp_pragmas): Move pragmas which can contain simd
        * to ...
        (omp_pragmas): ... this new struct.
        (c_pp_lookup_pragma): Also walk omp_pragmas.
        (init_pragma): Init pragmas for -fopenmp-simd.

gcc/c
        * c-parser.c (c_parser_omp_for, c_parser_omp_parallel,
        c_parser_omp_distribute, c_parser_omp_teams,
        c_parser_omp_target, c_parser_omp_declare): Handle
        -fopenmp-simd.

gcc/cp
        * parser.c (cp_parser_omp_for, cp_parser_omp_parallel,
        cp_parser_omp_distribute, cp_parser_omp_teams,
cp_parser_omp_target,
        cp_parser_omp_declare): Handle
        -fopenmp-simd.

gcc/testsuite/
        * g++.dg/gomp/openmp-simd-1.C: New.
        * g++.dg/gomp/openmp-simd-2.C: New.
        * gcc.dg/gomp/openmp-simd-1.c: New.
        * gcc.dg/gomp/openmp-simd-2.c: New.

From-SVN: r204382

21 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-pragma.c
gcc/c-family/c.opt
gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/doc/invoke.texi
gcc/fortran/ChangeLog
gcc/fortran/gfortran.h
gcc/fortran/lang.opt
gcc/fortran/options.c
gcc/gimplify.c
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/gomp/openmp-simd-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/openmp-simd-2.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/openmp-simd-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/openmp-simd-2.c [new file with mode: 0644]
gcc/tree.c

index 4d08af4..eecf65b 100644 (file)
@@ -1,3 +1,10 @@
+2013-11-05  Tobias Burnus  <burnus@net-b.de>
+
+       * doc/invoke.texi (-fopenmp-simd): Document new option.
+       * gimplify.c (gimplify_body): Accept -fopenmp-simd.
+       * omp-low.c (execute_expand_omp, execute_lower_omp): Ditto.
+       * tree.c (attribute_value_equal): Ditto.
+
 2013-11-04  Wei Mi  <wmi@google.com>
 
        * sched-rgn.c (add_branch_dependences): Keep insns in
index 067c134..9cd9e79 100644 (file)
@@ -1,3 +1,11 @@
+2013-11-05  Tobias Burnus  <burnus@net-b.de>
+
+       * c.opt (fopenmp-simd): New option.
+       * c-pragma.c (omp_pragmas): Move pragmas which can contain simd to ...
+       (omp_pragmas): ... this new struct.
+       (c_pp_lookup_pragma): Also walk omp_pragmas.
+       (init_pragma): Init pragmas for -fopenmp-simd.
+
 2013-11-04  Marek Polacek  <polacek@redhat.com>
 
        PR c++/58979
index 3ce77a2..c75b087 100644 (file)
@@ -1170,31 +1170,35 @@ static const struct omp_pragma_def omp_pragmas[] = {
   { "cancel", PRAGMA_OMP_CANCEL },
   { "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
   { "critical", PRAGMA_OMP_CRITICAL },
-  { "declare", PRAGMA_OMP_DECLARE_REDUCTION },
-  { "distribute", PRAGMA_OMP_DISTRIBUTE },
   { "end", PRAGMA_OMP_END_DECLARE_TARGET },
   { "flush", PRAGMA_OMP_FLUSH },
-  { "for", PRAGMA_OMP_FOR },
   { "master", PRAGMA_OMP_MASTER },
   { "ordered", PRAGMA_OMP_ORDERED },
-  { "parallel", PRAGMA_OMP_PARALLEL },
   { "section", PRAGMA_OMP_SECTION },
   { "sections", PRAGMA_OMP_SECTIONS },
-  { "simd", PRAGMA_OMP_SIMD },
   { "single", PRAGMA_OMP_SINGLE },
-  { "target", PRAGMA_OMP_TARGET },
-  { "task", PRAGMA_OMP_TASK },
   { "taskgroup", PRAGMA_OMP_TASKGROUP },
   { "taskwait", PRAGMA_OMP_TASKWAIT },
   { "taskyield", PRAGMA_OMP_TASKYIELD },
-  { "teams", PRAGMA_OMP_TEAMS },
   { "threadprivate", PRAGMA_OMP_THREADPRIVATE }
 };
+static const struct omp_pragma_def omp_pragmas_simd[] = {
+  { "declare", PRAGMA_OMP_DECLARE_REDUCTION },
+  { "distribute", PRAGMA_OMP_DISTRIBUTE },
+  { "for", PRAGMA_OMP_FOR },
+  { "parallel", PRAGMA_OMP_PARALLEL },
+  { "simd", PRAGMA_OMP_SIMD },
+  { "target", PRAGMA_OMP_TARGET },
+  { "task", PRAGMA_OMP_TASK },
+  { "teams", PRAGMA_OMP_TEAMS },
+};
 
 void
 c_pp_lookup_pragma (unsigned int id, const char **space, const char **name)
 {
   const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);
+  const int n_omp_pragmas_simd = sizeof (omp_pragmas_simd)
+                                / sizeof (*omp_pragmas);
   int i;
 
   for (i = 0; i < n_omp_pragmas; ++i)
@@ -1205,6 +1209,14 @@ c_pp_lookup_pragma (unsigned int id, const char **space, const char **name)
        return;
       }
 
+  for (i = 0; i < n_omp_pragmas_simd; ++i)
+    if (omp_pragmas_simd[i].id == id)
+      {
+       *space = "omp";
+       *name = omp_pragmas_simd[i].name;
+       return;
+      }
+
   if (id >= PRAGMA_FIRST_EXTERNAL
       && (id < PRAGMA_FIRST_EXTERNAL + registered_pp_pragmas.length ()))
     {
@@ -1357,6 +1369,16 @@ init_pragma (void)
        cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name,
                                      omp_pragmas[i].id, true, true);
     }
+  if (flag_openmp || flag_openmp_simd)
+    {
+      const int n_omp_pragmas_simd = sizeof (omp_pragmas_simd)
+                                    / sizeof (*omp_pragmas);
+      int i;
+
+      for (i = 0; i < n_omp_pragmas_simd; ++i)
+       cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas_simd[i].name,
+                                     omp_pragmas_simd[i].id, true, true);
+    }
 
   if (!flag_preprocess_only)
     cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
index b862eb9..22f8939 100644 (file)
@@ -1069,6 +1069,10 @@ fopenmp
 C ObjC C++ ObjC++ Var(flag_openmp)
 Enable OpenMP (implies -frecursive in Fortran)
 
+fopenmp-simd
+C ObjC C++ ObjC++ Var(flag_openmp_simd)
+Enable OpenMP's SIMD directives
+
 foperator-names
 C++ ObjC++
 Recognize C++ keywords like \"compl\" and \"xor\"
index efb4ba8..9a9eed3 100644 (file)
@@ -1,3 +1,10 @@
+2013-11-05  Tobias Burnus  <burnus@net-b.de>
+
+       * c-parser.c (c_parser_omp_for, c_parser_omp_parallel,
+       c_parser_omp_distribute, c_parser_omp_teams,
+       c_parser_omp_target, c_parser_omp_declare): Handle
+       -fopenmp-simd.
+
 2013-11-03  Marek Polacek  <polacek@redhat.com>
 
        * c-decl.c (grokdeclarator): Add VLA instrumentation.
index a8f4774..4ae30c3 100644 (file)
@@ -11616,6 +11616,8 @@ c_parser_omp_for (location_t loc, c_parser *parser,
            cclauses = cclauses_buf;
 
          c_parser_consume_token (parser);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return c_parser_omp_simd (loc, parser, p_name, mask, cclauses);
          block = c_begin_compound_stmt (true);
          ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses);
          block = c_end_compound_stmt (loc, block, true);
@@ -11630,6 +11632,11 @@ c_parser_omp_for (location_t loc, c_parser *parser,
          return ret;
        }
     }
+  if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      c_parser_skip_to_pragma_eol (parser);
+      return NULL_TREE;
+    }
 
   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   if (cclauses)
@@ -11825,6 +11832,8 @@ c_parser_omp_parallel (location_t loc, c_parser *parser,
        cclauses = cclauses_buf;
 
       c_parser_consume_token (parser);
+      if (!flag_openmp)  /* flag_openmp_simd  */
+       return c_parser_omp_for (loc, parser, p_name, mask, cclauses);
       block = c_begin_omp_parallel ();
       c_parser_omp_for (loc, parser, p_name, mask, cclauses);
       stmt
@@ -11839,6 +11848,11 @@ c_parser_omp_parallel (location_t loc, c_parser *parser,
       c_parser_skip_to_pragma_eol (parser);
       return NULL_TREE;
     }
+  else if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      c_parser_skip_to_pragma_eol (parser);
+      return NULL_TREE;
+    }
   else if (c_parser_next_token_is (parser, CPP_NAME))
     {
       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
@@ -12069,6 +12083,14 @@ c_parser_omp_distribute (location_t loc, c_parser *parser,
          if (cclauses == NULL)
            cclauses = cclauses_buf;
          c_parser_consume_token (parser);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           {
+             if (simd)
+               return c_parser_omp_simd (loc, parser, p_name, mask, cclauses);
+             else
+               return c_parser_omp_parallel (loc, parser, p_name, mask,
+                                             cclauses);
+           }
          block = c_begin_compound_stmt (true);
          if (simd)
            ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses);
@@ -12086,6 +12108,11 @@ c_parser_omp_distribute (location_t loc, c_parser *parser,
          return ret;
        }
     }
+  if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      c_parser_skip_to_pragma_eol (parser);
+      return NULL_TREE;
+    }
 
   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   if (cclauses)
@@ -12134,6 +12161,8 @@ c_parser_omp_teams (location_t loc, c_parser *parser,
            cclauses = cclauses_buf;
 
          c_parser_consume_token (parser);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return c_parser_omp_distribute (loc, parser, p_name, mask, cclauses);
          block = c_begin_compound_stmt (true);
          ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses);
          block = c_end_compound_stmt (loc, block, true);
@@ -12147,6 +12176,11 @@ c_parser_omp_teams (location_t loc, c_parser *parser,
          return add_stmt (ret);
        }
     }
+  if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      c_parser_skip_to_pragma_eol (parser);
+      return NULL_TREE;
+    }
 
   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   if (cclauses)
@@ -12258,24 +12292,16 @@ c_parser_omp_target (c_parser *parser, enum pragma_context context)
     {
       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
 
-      if (strcmp (p, "data") == 0)
-       {
-         c_parser_consume_token (parser);
-         c_parser_omp_target_data (loc, parser);
-         return true;
-       }
-      else if (strcmp (p, "update") == 0)
-       {
-         c_parser_consume_token (parser);
-         return c_parser_omp_target_update (loc, parser, context);
-       }
-      else if (strcmp (p, "teams") == 0)
+      if (strcmp (p, "teams") == 0)
        {
          tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
          char p_name[sizeof ("#pragma omp target teams distribute "
                              "parallel for simd")];
 
          c_parser_consume_token (parser);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return c_parser_omp_teams (loc, parser, p_name,
+                                      OMP_TARGET_CLAUSE_MASK, cclauses);
          strcpy (p_name, "#pragma omp target");
          keep_next_level ();
          tree block = c_begin_compound_stmt (true);
@@ -12291,6 +12317,22 @@ c_parser_omp_target (c_parser *parser, enum pragma_context context)
          add_stmt (stmt);
          return true;
        }
+      else if (!flag_openmp)  /* flag_openmp_simd  */
+       {
+         c_parser_skip_to_pragma_eol (parser);
+         return NULL_TREE;
+       }
+      else if (strcmp (p, "data") == 0)
+       {
+         c_parser_consume_token (parser);
+         c_parser_omp_target_data (loc, parser);
+         return true;
+       }
+      else if (strcmp (p, "update") == 0)
+       {
+         c_parser_consume_token (parser);
+         return c_parser_omp_target_update (loc, parser, context);
+       }
     }
 
   tree stmt = make_node (OMP_TARGET);
@@ -12918,6 +12960,11 @@ c_parser_omp_declare (c_parser *parser, enum pragma_context context)
          c_parser_omp_declare_reduction (parser, context);
          return;
        }
+      if (!flag_openmp)  /* flag_openmp_simd  */
+       {
+         c_parser_skip_to_pragma_eol (parser);
+         return;
+       }
       if (strcmp (p, "target") == 0)
        {
          c_parser_consume_token (parser);
index 8a3df56..e661390 100644 (file)
@@ -1,3 +1,9 @@
+2013-11-05  Tobias Burnus  <burnus@net-b.de>
+
+       * parser.c (cp_parser_omp_for, cp_parser_omp_parallel,
+       cp_parser_omp_distribute, cp_parser_omp_teams, cp_parser_omp_target,
+       cp_parser_omp_declare): Handle -fopenmp-simd.
+
 2013-11-04  Eric Botcazou  <ebotcazou@adacore.com>
 
        * decl2.c (cpp_check): Change type of first parameter and deal with
index 3df746a..1ff56fe 100644 (file)
@@ -29133,6 +29133,9 @@ cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok,
            cclauses = cclauses_buf;
 
          cp_lexer_consume_token (parser->lexer);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
+                                      cclauses);
          sb = begin_omp_structured_block ();
          save = cp_parser_begin_omp_structured_block (parser);
          ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
@@ -29150,6 +29153,11 @@ cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok,
          return ret;
        }
     }
+  if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      cp_parser_require_pragma_eol (parser, pragma_tok);
+      return NULL_TREE;
+    }
 
   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
                                       cclauses == NULL);
@@ -29333,6 +29341,8 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
        cclauses = cclauses_buf;
 
       cp_lexer_consume_token (parser->lexer);
+      if (!flag_openmp)  /* flag_openmp_simd  */
+       return cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses);
       block = begin_omp_parallel ();
       save = cp_parser_begin_omp_structured_block (parser);
       cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses);
@@ -29348,6 +29358,11 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
       return NULL_TREE;
     }
+  else if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      cp_parser_require_pragma_eol (parser, pragma_tok);
+      return NULL_TREE;
+    }
   else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     {
       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
@@ -29576,6 +29591,15 @@ cp_parser_omp_distribute (cp_parser *parser, cp_token *pragma_tok,
          if (cclauses == NULL)
            cclauses = cclauses_buf;
          cp_lexer_consume_token (parser->lexer);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           {
+             if (simd)
+               return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
+                                          cclauses);
+             else
+               return cp_parser_omp_parallel (parser, pragma_tok, p_name, mask,
+                                              cclauses);
+           }
          sb = begin_omp_structured_block ();
          save = cp_parser_begin_omp_structured_block (parser);
          if (simd)
@@ -29597,6 +29621,11 @@ cp_parser_omp_distribute (cp_parser *parser, cp_token *pragma_tok,
          return ret;
        }
     }
+  if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      cp_parser_require_pragma_eol (parser, pragma_tok);
+      return NULL_TREE;
+    }
 
   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
                                       cclauses == NULL);
@@ -29652,6 +29681,9 @@ cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
            cclauses = cclauses_buf;
 
          cp_lexer_consume_token (parser->lexer);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return cp_parser_omp_distribute (parser, pragma_tok, p_name, mask,
+                                            cclauses);
          sb = begin_omp_structured_block ();
          save = cp_parser_begin_omp_structured_block (parser);
          ret = cp_parser_omp_distribute (parser, pragma_tok, p_name, mask,
@@ -29668,6 +29700,11 @@ cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
          return add_stmt (ret);
        }
     }
+  if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      cp_parser_require_pragma_eol (parser, pragma_tok);
+      return NULL_TREE;
+    }
 
   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
                                       cclauses == NULL);
@@ -29777,18 +29814,7 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
       const char *p = IDENTIFIER_POINTER (id);
 
-      if (strcmp (p, "data") == 0)
-       {
-         cp_lexer_consume_token (parser->lexer);
-         cp_parser_omp_target_data (parser, pragma_tok);
-         return true;
-       }
-      else if (strcmp (p, "update") == 0)
-       {
-         cp_lexer_consume_token (parser->lexer);
-         return cp_parser_omp_target_update (parser, pragma_tok, context);
-       }
-      else if (strcmp (p, "teams") == 0)
+      if (strcmp (p, "teams") == 0)
        {
          tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
          char p_name[sizeof ("#pragma omp target teams distribute "
@@ -29797,6 +29823,9 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
          cp_lexer_consume_token (parser->lexer);
          strcpy (p_name, "#pragma omp target");
          keep_next_level (true);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return cp_parser_omp_teams (parser, pragma_tok, p_name,
+                                       OMP_TARGET_CLAUSE_MASK, cclauses);
          tree sb = begin_omp_structured_block ();
          unsigned save = cp_parser_begin_omp_structured_block (parser);
          tree ret = cp_parser_omp_teams (parser, pragma_tok, p_name,
@@ -29812,6 +29841,22 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
          add_stmt (stmt);
          return true;
        }
+      else if (!flag_openmp)  /* flag_openmp_simd  */
+       {
+         cp_parser_require_pragma_eol (parser, pragma_tok);
+         return NULL_TREE;
+       }
+      else if (strcmp (p, "data") == 0)
+       {
+         cp_lexer_consume_token (parser->lexer);
+         cp_parser_omp_target_data (parser, pragma_tok);
+         return true;
+       }
+      else if (strcmp (p, "update") == 0)
+       {
+         cp_lexer_consume_token (parser->lexer);
+         return cp_parser_omp_target_update (parser, pragma_tok, context);
+       }
     }
 
   tree stmt = make_node (OMP_TARGET);
@@ -30411,6 +30456,11 @@ cp_parser_omp_declare (cp_parser *parser, cp_token *pragma_tok,
                                           context);
          return;
        }
+      if (!flag_openmp)  /* flag_openmp_simd  */
+       {
+         cp_parser_require_pragma_eol (parser, pragma_tok);
+         return;
+       }
       if (strcmp (p, "target") == 0)
        {
          cp_lexer_consume_token (parser->lexer);
index e84bca3..35f41d9 100644 (file)
@@ -168,8 +168,8 @@ in the following sections.
 @gccoptlist{-ansi  -std=@var{standard}  -fgnu89-inline @gol
 -aux-info @var{filename} -fallow-parameterless-variadic-functions @gol
 -fno-asm  -fno-builtin  -fno-builtin-@var{function} @gol
--fhosted  -ffreestanding -fopenmp -fms-extensions -fplan9-extensions @gol
--trigraphs  -traditional  -traditional-cpp @gol
+-fhosted  -ffreestanding -fopenmp -fopenmp-simd -fms-extensions @gol
+-fplan9-extensions -trigraphs  -traditional  -traditional-cpp @gol
 -fallow-single-precision  -fcond-mismatch -flax-vector-conversions @gol
 -fsigned-bitfields  -fsigned-char @gol
 -funsigned-bitfields  -funsigned-char}
@@ -1839,7 +1839,16 @@ Enable handling of OpenMP directives @code{#pragma omp} in C/C++ and
 compiler generates parallel code according to the OpenMP Application
 Program Interface v4.0 @w{@uref{http://www.openmp.org/}}.  This option
 implies @option{-pthread}, and thus is only supported on targets that
-have support for @option{-pthread}.
+have support for @option{-pthread}. @option{-fopenmp} implies
+@option{-fopenmp-simd}.
+
+@item -fopenmp-simd
+@opindex fopenmp-simd
+@cindex OpenMP SIMD
+@cindex SIMD
+Enable handling of OpenMP's SIMD directives with @code{#pragma omp}
+in C/C++ and @code{!$omp} in Fortran. Other OpenMP directives
+are ignored.
 
 @item -fcilkplus
 @opindex fcilkplus
index 32b8c11..16703f6 100644 (file)
@@ -1,3 +1,9 @@
+2013-11-05  Tobias Burnus  <burnus@net-b.de>
+
+       * lang.opt (fopenmp-simd): New option.
+       * gfortran.h (gfc_option_t): Add gfc_flag_openmp_simd.
+       * options.c (gfc_handle_option): Handle it.
+
 2013-11-04  Ian Lance Taylor  <iant@google.com>
 
        * f95-lang.c (ATTR_LEAF_LIST): Define.
index b28edd8..af5e68c 100644 (file)
@@ -2286,6 +2286,7 @@ typedef struct
   int flag_cray_pointer;
   int flag_d_lines;
   int gfc_flag_openmp;
+  int gfc_flag_openmp_simd;
   int flag_sign_zero;
   int flag_stack_arrays;
   int flag_module_private;
index 4f79934..49d5f3a 100644 (file)
@@ -517,6 +517,10 @@ fopenmp
 Fortran
 ; Documented in C
 
+fopenmp-simd
+Fortran
+; Documented in C
+
 fpack-derived
 Fortran
 Try to lay out derived types as compactly as possible
index 6e4e7c1..e05528a 100644 (file)
@@ -836,6 +836,10 @@ gfc_handle_option (size_t scode, const char *arg, int value,
       gfc_option.gfc_flag_openmp = value;
       break;
 
+    case OPT_fopenmp_simd:
+      gfc_option.gfc_flag_openmp_simd = value;
+      break;
+
     case OPT_ffree_line_length_none:
       gfc_option.free_line_length = 0;
       break;
index 0723027..4df9ed4 100644 (file)
@@ -8871,7 +8871,7 @@ gimplify_body (tree fndecl, bool do_parms)
       nonlocal_vlas = NULL;
     }
 
-  if (flag_openmp && gimplify_omp_ctxp)
+  if ((flag_openmp || flag_openmp_simd) && gimplify_omp_ctxp)
     {
       delete_omp_context (gimplify_omp_ctxp);
       gimplify_omp_ctxp = NULL;
index a5b9210..7874ff1 100644 (file)
@@ -8232,7 +8232,7 @@ execute_expand_omp (void)
 static bool
 gate_expand_omp (void)
 {
-  return (flag_openmp != 0 && !seen_error ());
+  return ((flag_openmp != 0 || flag_openmp_simd != 0) && !seen_error ());
 }
 
 namespace {
@@ -10053,7 +10053,7 @@ execute_lower_omp (void)
 
   /* This pass always runs, to provide PROP_gimple_lomp.
      But there is nothing to do unless -fopenmp is given.  */
-  if (flag_openmp == 0)
+  if (flag_openmp == 0 && flag_openmp_simd == 0)
     return 0;
 
   all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
index fca772f..c1bfc3b 100644 (file)
@@ -1,3 +1,10 @@
+2013-11-05  Tobias Burnus  <burnus@net-b.de>
+
+       * g++.dg/gomp/openmp-simd-1.C: New.
+       * g++.dg/gomp/openmp-simd-2.C: New.
+       * gcc.dg/gomp/openmp-simd-1.c: New.
+       * gcc.dg/gomp/openmp-simd-2.c: New.
+
 2013-11-04  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
 
        * gcc.dg/superblock.c: Require scheduling support.
diff --git a/gcc/testsuite/g++.dg/gomp/openmp-simd-1.C b/gcc/testsuite/g++.dg/gomp/openmp-simd-1.C
new file mode 100644 (file)
index 0000000..fedb186
--- /dev/null
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp-simd -fdump-tree-original" } */
+
+#pragma omp declare simd
+float bar(float b) {
+  return b*b;
+}
+
+void foo(int n, float *a, float *b)
+{
+  int i; 
+#pragma omp simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp for simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp distribute simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp distribute parallel for simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp parallel for simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp teams distribute simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp target teams distribute simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp teams distribute parallel for simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp target teams distribute parallel for simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+}
+
+/* { dg-final { scan-tree-dump-times "pragma omp simd" 9 "original" } } */
+/* { dg-final { scan-tree-dump-not "omp for" "original" } } */
+/* { dg-final { scan-tree-dump-not "omp distribute" "original" } } */
+/* { dg-final { scan-tree-dump-not "omp teams" "original" } } */
+/* { dg-final { scan-tree-dump-not "omp target" "original" } } */
+/* { dg-final { scan-tree-dump-not "omp parallel" "original" } } */
diff --git a/gcc/testsuite/g++.dg/gomp/openmp-simd-2.C b/gcc/testsuite/g++.dg/gomp/openmp-simd-2.C
new file mode 100644 (file)
index 0000000..e31c1eb
--- /dev/null
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp-simd -fdump-tree-original" } */
+
+extern void abort ();
+int a[1024] __attribute__((aligned (32))) = { 1 };
+struct S { int s; };
+#pragma omp declare reduction (+:struct S:omp_out.s += omp_in.s)
+#pragma omp declare reduction (foo:struct S:omp_out.s += omp_in.s)
+#pragma omp declare reduction (foo:int:omp_out += omp_in)
+
+__attribute__((noinline, noclone)) int
+foo (void)
+{
+  int i, u = 0;
+  struct S s, t;
+  s.s = 0; t.s = 0;
+  #pragma omp simd aligned(a : 32) reduction(+:s) reduction(foo:t, u)
+  for (i = 0; i < 1024; i++)
+    {
+      int x = a[i];
+      s.s += x;
+      t.s += x;
+      u += x;
+    }
+  if (t.s != s.s || u != s.s)
+    abort ();
+  return s.s;
+}
+
+
+void bar(int n, float *a, float *b)
+{
+  int i; 
+#pragma omp parallel for simd num_threads(4) safelen(64)
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+}
+
+/* { dg-final { scan-tree-dump-times "Function void omp declare reduction operator\\+" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "Function void omp declare reduction foo" 2 "original" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp simd reduction\\(u\\) reduction\\(t\\) reduction\\(\\+:s\\) aligned\\(a:32\\)" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp simd safelen\\(64\\)" 1 "original" } } */
+/* { dg-final { scan-tree-dump-not "omp parallel" "original" } } */
+/* { dg-final { scan-tree-dump-not "omp for" "original" } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/openmp-simd-1.c b/gcc/testsuite/gcc.dg/gomp/openmp-simd-1.c
new file mode 100644 (file)
index 0000000..fedb186
--- /dev/null
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp-simd -fdump-tree-original" } */
+
+#pragma omp declare simd
+float bar(float b) {
+  return b*b;
+}
+
+void foo(int n, float *a, float *b)
+{
+  int i; 
+#pragma omp simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp for simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp distribute simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp distribute parallel for simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp parallel for simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp teams distribute simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp target teams distribute simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp teams distribute parallel for simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+#pragma omp target teams distribute parallel for simd
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+}
+
+/* { dg-final { scan-tree-dump-times "pragma omp simd" 9 "original" } } */
+/* { dg-final { scan-tree-dump-not "omp for" "original" } } */
+/* { dg-final { scan-tree-dump-not "omp distribute" "original" } } */
+/* { dg-final { scan-tree-dump-not "omp teams" "original" } } */
+/* { dg-final { scan-tree-dump-not "omp target" "original" } } */
+/* { dg-final { scan-tree-dump-not "omp parallel" "original" } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/openmp-simd-2.c b/gcc/testsuite/gcc.dg/gomp/openmp-simd-2.c
new file mode 100644 (file)
index 0000000..e668068
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp-simd -fdump-tree-original" } */
+
+extern void abort ();
+int a[1024] __attribute__((aligned (32))) = { 1 };
+struct S { int s; };
+#pragma omp declare reduction (+:struct S:omp_out.s += omp_in.s)
+#pragma omp declare reduction (foo:struct S:omp_out.s += omp_in.s)
+#pragma omp declare reduction (foo:int:omp_out += omp_in)
+
+__attribute__((noinline, noclone)) int
+foo (void)
+{
+  int i, u = 0;
+  struct S s, t;
+  s.s = 0; t.s = 0;
+  #pragma omp simd aligned(a : 32) reduction(+:s) reduction(foo:t, u)
+  for (i = 0; i < 1024; i++)
+    {
+      int x = a[i];
+      s.s += x;
+      t.s += x;
+      u += x;
+    }
+  if (t.s != s.s || u != s.s)
+    abort ();
+  return s.s;
+}
+
+
+void bar(int n, float *a, float *b)
+{
+  int i; 
+#pragma omp parallel for simd num_threads(4) safelen(64)
+  for (i = 0; i < n ; i++)
+    a[i] = b[i];
+}
+
+/* { dg-final { scan-tree-dump-times "pragma omp simd reduction\\(u\\) reduction\\(t\\) reduction\\(\\+:s\\) aligned\\(a:32\\)" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp simd safelen\\(64\\)" 1 "original" } } */
+/* { dg-final { scan-tree-dump-not "omp parallel" "original" } } */
+/* { dg-final { scan-tree-dump-not "omp for" "original" } } */
index 332751a..e0e9d8d 100644 (file)
@@ -4814,7 +4814,7 @@ attribute_value_equal (const_tree attr1, const_tree attr2)
     return (simple_cst_list_equal (TREE_VALUE (attr1),
                                   TREE_VALUE (attr2)) == 1);
 
-  if (flag_openmp
+  if ((flag_openmp || flag_openmp_simd)
       && TREE_VALUE (attr1) && TREE_VALUE (attr2)
       && TREE_CODE (TREE_VALUE (attr1)) == OMP_CLAUSE
       && TREE_CODE (TREE_VALUE (attr2)) == OMP_CLAUSE)