2015-06-12 Cesar Philippidis <cesar@codesourcery.com>
gcc/c-family/
* c-omp.c (oacc_extract_device_id): Recognize GOMP_DEVICE_DEFAULT.
(struct identifier_hasher): New struct declaration.
(oacc_filter_device_types): Report errors on duplicate device_type
entries.
gcc/c/
* c-parser.c (c_parser_oacc_clause_device_type): Switch
OMP_CLAUSE_DEVICE_TYPE_DEVICES to tree instead of an int.
gcc/cp/
* parser.c (cp_parser_oacc_clause_device_type): Likewise.
gcc/fortran/
* openmp.c (gfc_match_omp_clauses): Report errors on duplicate
device_type entries.
gcc/testsuite/
* c-c++-common/goacc/dtype-4.c: New test.
* gfortran.dg/goacc/dtype-2.f95: Update error messages.
* gfortran.dg/goacc/dtype-3.f: New test.
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "omp-low.h"
#include "gomp-constants.h"
+#include "tree-hasher.h"
/* Complete a #pragma oacc wait construct. LOC is the location of
@@ -1097,9 +1098,20 @@ oacc_extract_device_id (const char *device)
{
if (!strcasecmp (device, "nvidia"))
return GOMP_DEVICE_NVIDIA_PTX;
+ else if (!strcmp (device, "*"))
+ return GOMP_DEVICE_DEFAULT;
return GOMP_DEVICE_NONE;
}
+struct identifier_hasher : ggc_cache_hasher<tree>
+{
+ static hashval_t hash (tree t) { return htab_hash_pointer (t); }
+ static bool equal (tree a, tree b)
+ {
+ return !strcmp(IDENTIFIER_POINTER (a), IDENTIFIER_POINTER (b));
+ }
+};
+
/* Filter out the list of unsupported OpenACC device_types. */
tree
@@ -1109,56 +1121,55 @@ oacc_filter_device_types (tree clauses)
tree dtype = NULL_TREE;
tree seen_nvidia = NULL_TREE;
tree seen_default = NULL_TREE;
- int device = 0;
+ hash_table<identifier_hasher> *dt_htab
+ = hash_table<identifier_hasher>::create_ggc (10);
/* First scan for all device_type clauses. */
for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
{
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
{
- int code = TREE_INT_CST_LOW (OMP_CLAUSE_DEVICE_TYPE_DEVICES (c));
+ tree t;
- if (code == GOMP_DEVICE_DEFAULT)
+ for (t = OMP_CLAUSE_DEVICE_TYPE_DEVICES (c); t; t = TREE_CHAIN (t))
{
- if (device & (1 << GOMP_DEVICE_DEFAULT))
+ if (dt_htab->find (t))
{
- seen_default = NULL_TREE;
error_at (OMP_CLAUSE_LOCATION (c),
- "duplicate device_type (*)");
- goto filter_error;
+ "duplicate device_type (%s)",
+ IDENTIFIER_POINTER (t));
+ goto filter_dtype;
}
- seen_default = OMP_CLAUSE_DEVICE_TYPE_CLAUSES (c);
- }
- else if (code & (1 << GOMP_DEVICE_NVIDIA_PTX))
- {
- if (device & code)
- {
- seen_nvidia = NULL_TREE;
- error_at (OMP_CLAUSE_LOCATION (c),
- "duplicate device_type (nvidia)");
- goto filter_error;
- }
+ int code = oacc_extract_device_id (IDENTIFIER_POINTER (t));
- seen_nvidia = OMP_CLAUSE_DEVICE_TYPE_CLAUSES (c);
- }
- else
- {
- if (device & (1 << code))
+ if (code == GOMP_DEVICE_DEFAULT)
+ seen_default = OMP_CLAUSE_DEVICE_TYPE_CLAUSES (c);
+ else if (code == GOMP_DEVICE_NVIDIA_PTX)
+ seen_nvidia = OMP_CLAUSE_DEVICE_TYPE_CLAUSES (c);
+ else
{
- error_at (OMP_CLAUSE_LOCATION (c),
- "duplicate device_type");
- goto filter_error;
+ /* The OpenACC technical committee advises compilers
+ to silently ignore unknown devices. */
}
+
+ tree *slot = dt_htab->find_slot (t, INSERT);
+ *slot = t;
}
- device |= (1 << code);
}
}
/* Don't do anything if there aren't any device_type clauses. */
- if (device == 0)
+ if (dt_htab->elements () == 0)
return clauses;
+ if (seen_nvidia)
+ dtype = seen_nvidia;
+ else if (seen_default)
+ dtype = seen_default;
+ else
+ goto filter_dtype;
+
dtype = seen_nvidia ? seen_nvidia : seen_default;
/* Now filter out clauses if necessary. */
@@ -1186,7 +1197,7 @@ oacc_filter_device_types (tree clauses)
prev = c;
}
- filter_error:
+ filter_dtype:
/* Remove all device_type clauses. Those clauses are located at the
beginning of the clause list. */
for (c = clauses; c && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE;
@@ -11246,7 +11246,7 @@ c_parser_oacc_clause_device_type (c_parser *parser, omp_clause_mask mask,
{
tree c, clauses;
location_t loc;
- int dev_id = GOMP_DEVICE_NONE;
+ tree dev_id = NULL_TREE;
loc = c_parser_peek_token (parser)->location;
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
@@ -11255,7 +11255,7 @@ c_parser_oacc_clause_device_type (c_parser *parser, omp_clause_mask mask,
if (c_parser_next_token_is (parser, CPP_MULT))
{
c_parser_consume_token (parser);
- dev_id = GOMP_DEVICE_DEFAULT;
+ dev_id = get_identifier ("*");
if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
return list;
}
@@ -11264,7 +11264,6 @@ c_parser_oacc_clause_device_type (c_parser *parser, omp_clause_mask mask,
do
{
tree keyword = error_mark_node;
- int dev = 0;
if (c_parser_next_token_is (parser, CPP_NAME))
{
@@ -11280,9 +11279,10 @@ c_parser_oacc_clause_device_type (c_parser *parser, omp_clause_mask mask,
return list;
}
- dev = oacc_extract_device_id (IDENTIFIER_POINTER (keyword));
- if (dev)
- dev_id |= 1 << dev;
+ if (dev_id)
+ dev_id = chainon (dev_id, keyword);
+ else
+ dev_id = keyword;
if (c_parser_next_token_is (parser, CPP_COMMA))
c_parser_consume_token (parser);
@@ -11297,8 +11297,7 @@ c_parser_oacc_clause_device_type (c_parser *parser, omp_clause_mask mask,
clauses = c_parser_oacc_all_clauses (parser, mask, "device_type", 0, false,
false);
OMP_CLAUSE_DEVICE_TYPE_CLAUSES (c) = clauses;
- OMP_CLAUSE_DEVICE_TYPE_DEVICES (c) = build_int_cst (integer_type_node,
- dev_id);
+ OMP_CLAUSE_DEVICE_TYPE_DEVICES (c) = dev_id;
OMP_CLAUSE_CHAIN (c) = list;
return c;
}
@@ -28356,7 +28356,7 @@ cp_parser_oacc_clause_device_type (cp_parser *parser, omp_clause_mask mask,
{
tree c, clauses;
location_t loc;
- int dev_id = GOMP_DEVICE_NONE;
+ tree dev_id = NULL_TREE;
loc = cp_lexer_peek_token (parser->lexer)->location;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
@@ -28365,7 +28365,7 @@ cp_parser_oacc_clause_device_type (cp_parser *parser, omp_clause_mask mask,
if (cp_lexer_next_token_is (parser->lexer, CPP_MULT))
{
cp_lexer_consume_token (parser->lexer);
- dev_id = GOMP_DEVICE_DEFAULT;
+ dev_id = get_identifier ("*");
if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
return list;
}
@@ -28374,7 +28374,6 @@ cp_parser_oacc_clause_device_type (cp_parser *parser, omp_clause_mask mask,
do
{
tree keyword = error_mark_node;
- int dev = 0;
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
@@ -28390,9 +28389,10 @@ cp_parser_oacc_clause_device_type (cp_parser *parser, omp_clause_mask mask,
return list;
}
- dev = oacc_extract_device_id (IDENTIFIER_POINTER (keyword));
- if (dev)
- dev_id |= 1 << dev;
+ if (dev_id)
+ dev_id = chainon (dev_id, keyword);
+ else
+ dev_id = keyword;
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
cp_lexer_consume_token (parser->lexer);
@@ -28407,8 +28407,7 @@ cp_parser_oacc_clause_device_type (cp_parser *parser, omp_clause_mask mask,
clauses = cp_parser_oacc_all_clauses (parser, mask, "device_type",
pragma_tok, 0, false, false);
OMP_CLAUSE_DEVICE_TYPE_CLAUSES (c) = clauses;
- OMP_CLAUSE_DEVICE_TYPE_DEVICES (c) = build_int_cst (integer_type_node,
- dev_id);
+ OMP_CLAUSE_DEVICE_TYPE_DEVICES (c) = dev_id;
OMP_CLAUSE_CHAIN (c) = list;
return c;
}
@@ -1171,17 +1171,23 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask,
{
char n[GFC_MAX_SYMBOL_LEN + 1];
- while (gfc_match (" %n ", n) == MATCH_YES)
- {
- if (!strcasecmp ("nvidia", n))
- device = GOMP_DEVICE_NVIDIA_PTX;
- else
- {
- /* The OpenACC technical committee advises compilers
- to silently ignore unknown devices. */
- }
- gfc_match (" , ");
- }
+ do {
+ if (gfc_match (" %n ", n) == MATCH_YES)
+ {
+ if (!strcasecmp ("nvidia", n))
+ device = GOMP_DEVICE_NVIDIA_PTX;
+ else
+ {
+ /* The OpenACC technical committee advises compilers
+ to silently ignore unknown devices. */
+ }
+ }
+ else
+ {
+ gfc_error ("missing device_type argument");
+ continue;
+ }
+ } while (gfc_match (" , ") == MATCH_YES);
}
/* Consume the trailing ')'. */
new file mode 100644
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+
+int
+main (int argc, char **argv)
+{
+ float a, b;
+
+ a = 2.0;
+ b = 0.0;
+
+ #pragma acc parallel copy (a, b) device_type (acc_device_host) num_gangs (1) device_type (acc_device_nvidia) num_gangs (2)
+ {
+ }
+
+ #pragma acc parallel copy (a, b) num_gangs (3) device_type (acc_device_host) num_gangs (1) device_type (acc_device_nvidia) num_gangs (2)
+ {
+ }
+
+#pragma acc parallel copy (a, b) device_type (acc_device_host) num_gangs (1) device_type (acc_device_nvidia) num_gangs (2) device_type (acc_device_host) num_gangs (60) /* { dg-error "duplicate device_type" } */
+ {
+ }
+
+#pragma acc parallel copy (a, b) num_gangs (3) device_type (nvidia) num_gangs (1) device_type (nvidia) num_gangs (2) /* { dg-error "duplicate device_type" } */
+ {
+ }
+
+ return 0;
+}
@@ -28,12 +28,12 @@ program dtype
end program dtype
-! { dg-error "Invalid character" "" { target *-*-* } 8 }
+! { dg-error "Unclassifiable OpenACC directive" "" { target *-*-* } 8 }
! { dg-error "Unexpected" "" { target *-*-* } 10 }
-! { dg-error "Invalid character" "" { target *-*-* } 14 }
+! { dg-error "Unclassifiable OpenACC directive" "" { target *-*-* } 14 }
! { dg-error "Unexpected" "" { target *-*-* } 15 }
-! { dg-error "Invalid character" "" { target *-*-* } 20 }
+! { dg-error "Unclassifiable OpenACC directive" "" { target *-*-* } 20 }
-! { dg-error "Invalid character" "" { target *-*-* } 27 }
+! { dg-error "Unclassifiable OpenACC directive" "" { target *-*-* } 27 }
new file mode 100644
@@ -0,0 +1,11 @@
+! { dg-do compile }
+
+ IMPLICIT NONE
+
+ INTEGER X
+
+!$ACC PARALLEL DTYPE (NVIDIA) NUM_GANGS(10) COPYOUT(X) ! { dg-error "Unclassifiable OpenACC directive" }
+ X = 0
+!$ACC END PARALLEL ! { dg-error "Unexpected" }
+
+ END