Re: [PATCH 2/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-02-19 Thread Ilmir Usmanov

Hi Tobias!

On 10.02.2014 03:10, Tobias Burnus wrote:
Shouldn't you also reject polymorphic types (BT_CLASS and 
BT_ASSUMED)? [BT_CLASS = class(derived_type_name) or class(*); 
BT_ASSUMED = type(*)]



+  if (n-sym-attr.pointer)
+gfc_error (POINTER object '%s' in %s clause at %L,
+   n-sym-name, name, code-loc);


Actually, here and probably elsewhere: Do you need to take care of 
derived-type components? I mean something like

   clause(derived_type%comp)

Do you also need to reject AS_ASSUMED_RANK (new since Fortran 
Technical Specification ISO/IEC TS 29113:2012)? I mean code like:


   subroutine foo(x)
 integer, DIMENSION(..) :: x
 ... openacc_clause(x)

Side note: One should also check how OpenMP handles those.

I think we should reject assumed size, assumed shape and assumed rank 
variables, as OpenMP does.



+  case OMP_LIST_DEVICEPTR:
+if (n-sym-attr.pointer)
+  gfc_error (POINTER object '%s' in %s clause at %L,
+ n-sym-name, name, code-loc);


Talking about pointers, you probably also want to reject Cray pointers 
(attr.cray_pointee - and cray_pointee). [One should also check what 
OpenMP does; I think it does handle it correctly.]


I agree, currently my implementation does not handle Cray pointers 
correctly, will fix.


And another point: I think you have to check whether the argument is a 
named constant (PARAMETER, attr.flavor == FL_PARAMETER), I think those 
you cannot put them there either.


What happens if you try to use a literal such as deviceptr(5)?


Both parameter and literal are rejected.
By the way, PGI compiler accepts parameters with warning, CAPS silently 
accepts. I think, we also should support parameters with warning.





+  resolve_oacc_positive_int_expr (el-expr, TILE);
+  if (el-expr-expr_type != EXPR_CONSTANT)
+gfc_error (TILE requires constant expression at %L, 
code-loc);


Is the following permitted: tile(4+5)? If so, do you need to call 
gfc_simplify_expr() as some point? (Or is this already done at some 
point?)



Yes, the syntax is allowed, but ...
CAPSCompilers-3.4.1/bin/hmpp: [Error HP0112] tile.f95:30: Syntax error: 
expecting ')'

!$acc  parallel loop collapse(1+ 1)

CAPS compiler doesn't support this. But PGI does.

There is no need to simplify expression since it is constant anyway. The 
simplification is done during match stage (gfc_match_expr calls gfc_add).


--
Ilmir.


Re: [PATCH 2/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-02-10 Thread Thomas Schwinge
Hi!

On Mon, 10 Feb 2014 00:10:26 +0100, Tobias Burnus bur...@net-b.de wrote:
 Ilmir Usmanov wrote:
  OpenACC 1.0 fortran FE support -- matching and resolving.

  +static void
  +resolve_oacc_cache (gfc_code *)
  +{
  +   //TODO: resolve subarrays
  +}
 
 ;-)

Just to clarify: I'm fine with incomplete changes being committed to the
gomp-4_0-branch, which is a development branch, as long as such changes
don't largely break the existing (working) code, as determined by the
testsuite for example.  Occasional small breakage should be fine, if it
is understood, and will be fixed later, like in the case where a recent
merge that I did from trunk into gomp-4_0-branch caused a regression in
one C++ OpenMP test case, which I could pinpoint to one
gomp-4_0-branch-specific patch, which Ilya Tocar by now has fixed
(pending commit).

What I'd generally like to see added are markers à la:

/* TODO: resolve subarrays */
gcc_unreachable ();

This makes it obvious both to the reader/reviewer and user of GCC ;-)
that this code path has not yet been implemented.  This is of course not
acceptable for released versions of GCC, but I think it's fine for the
gomp-4_0-branch, in this early OpenACC development stage.


Grüße,
 Thomas


pgp1UsgK6EtuJ.pgp
Description: PGP signature


Re: [PATCH 2/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-02-09 Thread Tobias Burnus

Ilmir Usmanov wrote:

OpenACC 1.0 fortran FE support -- matching and resolving.



+  return MATCH_ERROR;
+}
+
+static match
+match_oacc_clause_gang (gfc_omp_clauses *cp)
+{


For consistency, can you  add another empty line before the function?


+#define OMP_CLAUSE_SEQ  (1ll  32)


I think you should use 1LL instead of 1ll - that should be more readable 
and matches gcc/{configure,fold-const.c,glimits.h,simplify-rtx.c}



+static void
+resolve_oacc_scalar_int_expr (gfc_expr *expr, const char *clause)
+{
+  if (!gfc_resolve_expr (expr)
+  || expr-ts.type != BT_INTEGER || expr-rank != 0)
+gfc_error (%s clause at %L requires a scalar INTEGER expression,
+ clause, expr-where);
+}


I'd use integer instead of INTEGER as it is not a 'reserved' word


+gfc_warning (INTEGER expression of %s clause at %L must be positive,
+ clause, expr-where);
+}


Ditto.


@@ -800,10 +1366,14 @@ resolve_omp_clauses (gfc_code *code)
static const char *clause_names[]
  = { PRIVATE, FIRSTPRIVATE, LASTPRIVATE, COPYPRIVATE, SHARED,
-   COPYIN, REDUCTION };
+   COPYIN, COPY, COPYIN, COPYOUT, CREATE, DELETE,
+PRESENT, PRESENT_OR_COPY, PRESENT_OR_COPYIN, 
PRESENT_OR_COPYOUT,
+PRESENT_OR_CREATE, DEVICEPTR, USE_DEVICE, DEVICE_RESIDENT,
+HOST, DEVICE, CACHE, REDUCTION};


Indention: Should be a tab not spaces.


@@ -933,8 +1503,43 @@ resolve_omp_clauses (gfc_code *code)
else
  gcc_unreachable ();
  
+  if (list = OMP_LIST_DATA_CLAUSE_FIRST

+   list = OMP_LIST_DATA_CLAUSE_LAST)
+{
+  if (n-sym-ts.type == BT_DERIVED
+   n-sym-attr.allocatable)
+gfc_error (ALLOCATABLE object '%s' of DERIVED type in %s clause at 
%L,
+   n-sym-name, name, code-loc);
+  if (n-sym-ts.type == BT_DERIVED
+   n-sym-attr.pointer)
+gfc_error (POINTER object '%s' of DERIVED type in %s clause at %L,
+   n-sym-name, name, code-loc);


I'd use derived type for the same reason as above.

Shouldn't you also reject polymorphic types (BT_CLASS and 
BT_ASSUMED)? [BT_CLASS = class(derived_type_name) or class(*); 
BT_ASSUMED = type(*)]



+  if (n-sym-attr.pointer)
+gfc_error (POINTER object '%s' in %s clause at %L,
+   n-sym-name, name, code-loc);


Actually, here and probably elsewhere: Do you need to take care of 
derived-type components? I mean something like

   clause(derived_type%comp)

If so, note that symtree-n.sym-attr.pointer only checks for 
derived_type - even if you are interested in comp's attributes. You 
probably should use  gfc_expr_attr() in this and similar cases.




+  if (n-sym-as  n-sym-as-type == AS_ASSUMED_SIZE)
+gfc_error (Assumed size array '%s' in %s clause at %L,
+   n-sym-name, name, code-loc);
+}


Do you also need to reject AS_ASSUMED_RANK (new since Fortran Technical 
Specification ISO/IEC TS 29113:2012)? I mean code like:


   subroutine foo(x)
 integer, DIMENSION(..) :: x
 ... openacc_clause(x)

Side note: One should also check how OpenMP handles those.


+ case OMP_LIST_DEVICEPTR:
+   if (n-sym-attr.pointer)
+ gfc_error (POINTER object '%s' in %s clause at %L,
+n-sym-name, name, code-loc);


Talking about pointers, you probably also want to reject Cray pointers 
(attr.cray_pointee - and cray_pointee). [One should also check what 
OpenMP does; I think it does handle it correctly.]


And another point: I think you have to check whether the argument is a 
named constant (PARAMETER, attr.flavor == FL_PARAMETER), I think those 
you cannot put them there either.


What happens if you try to use a literal such as deviceptr(5)?



+}
+
+static void
+resolve_oacc_params_in_parallel (gfc_code *code, const char *clause)
+{


Another empty line for consistency.


+  if (oacc_is_parallel (code))
+gfc_error (LOOP %s in PARALLEL section allows no argument or static at 
%L,
+   clause, code-loc);


I am not sure whether I understand the error - in particular what 
static means. (It might be obvious after looking at the spec - if not, 
the error message should be improved.) In any case, I think you want to 
use nor instead of or.



+  if (code-ext.omp_clauses-seq)
+{
+  if (code-ext.omp_clauses-independent)
+gfc_error (Both SEQ and INDEPENDENT are not allowed in %L, 
code-loc);


Somehow, I don't like the wording; it sounds to me a bit as if SEQ is 
not permitted and INDEPENDENT is not permitted while you mean that only 
using them simultaneously is wrong. I don't have a very good suggestion, 
but here are some: SEQ clause conflicts with INDEPENDENT at %L, SEQ 
shall not be used together with INDEPENDENT at %L or ...



+  resolve_oacc_positive_int_expr (el-expr, TILE);
+  if (el-expr-expr_type != EXPR_CONSTANT)
+gfc_error (TILE requires constant expression at %L, 

Re: [PATCH 2/6] [GOMP4] OpenACC 1.0+ support in fortran front-end

2014-01-31 Thread Ilmir Usmanov

OpenACC 1.0 fortran FE support -- matching and resolving.

* openmp.c (gfc_free_omp_clauses): Remove also OpenACC clauses.
(gfc_free_exprlist): New function to clear expression list.
(match_oacc_exprlist): New function to match expression list.
(match_oacc_clause_gang): New function to match OpenACC 2.0 gang 
clauses.

(OMP_CLAUSE_ASYNC, OMP_CLAUSE_NUM_GANGS,
OMP_CLAUSE_NUM_WORKERS, OMP_CLAUSE_VECTOR_LENGTH,
OMP_CLAUSE_COPY, OMP_CLAUSE_OACC_COPYIN,
OMP_CLAUSE_COPYOUT, OMP_CLAUSE_CREATE, OMP_CLAUSE_PRESENT,
OMP_CLAUSE_PRESENT_OR_COPY, OMP_CLAUSE_PRESENT_OR_COPYIN,
OMP_CLAUSE_PRESENT_OR_COPYOUT, OMP_CLAUSE_PRESENT_OR_CREATE,
OMP_CLAUSE_DEVICEPTR, OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER,
OMP_CLAUSE_VECTOR, OMP_CLAUSE_SEQ, OMP_CLAUSE_INDEPENDENT,
OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE_HOST, OMP_CLAUSE_DEVICE_RESIDENT,
OMP_CLAUSE_DEVICE, OMP_CLAUSE_DEFAULT, OMP_CLAUSE_WAIT,
OMP_CLAUSE_DELETE, OMP_CLAUSE_AUTO, OMP_CLAUSE_TILE): New clauses.
(OACC_PARALLEL_CLAUSES, OACC_KERNELS_CLAUSES, OACC_DATA_CLAUSES,
OACC_LOOP_CLAUSES, OACC_PARALLEL_LOOP_CLAUSES,
OACC_KERNELS_LOOP_CLAUSES, OACC_HOST_DATA_CLAUSES, 
OACC_DECLARE_CLAUSES,

OACC_UPDATE_CLAUSES, OACC_ENTER_DATA_CLAUSES,
OACC_EXIT_DATA_CLAUSES): New defines.
From 64b05eeeadf25fca4f92f083cc11aaad1a7a692a Mon Sep 17 00:00:00 2001
From: Ilmir Usmanov i.usma...@samsung.com
Date: Fri, 31 Jan 2014 13:26:13 +0400
Subject: [PATCH 2/6] OpenACC fortran front-end -- part 2

---
 gcc/fortran/openmp.c | 942 ++-
 1 file changed, 940 insertions(+), 2 deletions(-)

diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index dff3ab1..d4e3ebd 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -69,11 +69,36 @@ gfc_free_omp_clauses (gfc_omp_clauses *c)
   gfc_free_expr (c-final_expr);
   gfc_free_expr (c-num_threads);
   gfc_free_expr (c-chunk_size);
+  gfc_free_expr (c-async_expr);
+  gfc_free_expr (c-gang_expr);
+  gfc_free_expr (c-worker_expr);
+  gfc_free_expr (c-vector_expr);
+  gfc_free_expr (c-num_gangs_expr);
+  gfc_free_expr (c-num_workers_expr);
+  gfc_free_expr (c-vector_length_expr);
+  gfc_free_expr (c-non_clause_wait_expr);
+
   for (i = 0; i  OMP_LIST_NUM; i++)
 gfc_free_namelist (c-lists[i]);
+
+  gfc_free_exprlist (c-waitlist);
+
   free (c);
 }
 
+/* Free expression list. */
+void
+gfc_free_exprlist (gfc_exprlist *list)
+{
+  gfc_exprlist *n;
+
+  for (; list; list = n)
+{
+  n = list-next;
+  free (list);
+}
+}
+
 /* Match a variable/common block list and construct a namelist from it.  */
 
 static match
@@ -169,6 +194,87 @@ cleanup:
   return MATCH_ERROR;
 }
 
+static match
+match_oacc_exprlist (const char *str, gfc_exprlist **list, bool allow_asterisk)
+{
+  gfc_exprlist *head, *tail, *p;
+  locus old_loc;
+  gfc_expr *expr;
+  match m;
+
+  head = tail = NULL;
+
+  old_loc = gfc_current_locus;
+
+  m = gfc_match (str);
+  if (m != MATCH_YES)
+return m;
+
+  for (;;)
+{
+  m = gfc_match_expr (expr);
+  if (m == MATCH_YES || allow_asterisk)
+{
+  p = gfc_get_exprlist ();
+  if (head == NULL)
+head = tail = p;
+  else
+{
+  tail-next = p;
+  tail = tail-next;
+}
+  if (m == MATCH_YES)
+tail-expr = expr;
+  else if (gfc_match ( *) != MATCH_YES)
+goto syntax;
+  goto next_item;
+}
+  if (m == MATCH_ERROR)
+goto cleanup;
+  goto syntax;
+
+next_item:
+  if (gfc_match_char (')') == MATCH_YES)
+break;
+  if (gfc_match_char (',') != MATCH_YES)
+goto syntax;
+}
+
+  while (*list)
+list = (*list)-next;
+
+  *list = head;
+  return MATCH_YES;
+
+syntax:
+  gfc_error (Syntax error in OpenACC expression list at %C);
+
+cleanup:
+  gfc_free_exprlist (head);
+  gfc_current_locus = old_loc;
+  return MATCH_ERROR;
+}
+
+static match
+match_oacc_clause_gang (gfc_omp_clauses *cp)
+{
+  if (gfc_match_char ('(') != MATCH_YES)
+return MATCH_NO;
+  if (gfc_match ( num :) == MATCH_YES)
+{
+  cp-gang_static = false;
+  return gfc_match ( %e ), cp-gang_expr);
+}
+  if (gfc_match ( static :) == MATCH_YES)
+{
+  cp-gang_static = true;
+  if (gfc_match ( * )) != MATCH_YES)
+return gfc_match ( %e ), cp-gang_expr);
+  return MATCH_YES;
+}
+  return gfc_match ( %e ), cp-gang_expr);
+}
+
 #define OMP_CLAUSE_PRIVATE	(1  0)
 #define OMP_CLAUSE_FIRSTPRIVATE	(1  1)
 #define OMP_CLAUSE_LASTPRIVATE	(1  2)
@@ -186,11 +292,40 @@ cleanup:
 #define OMP_CLAUSE_FINAL	(1  14)
 #define OMP_CLAUSE_MERGEABLE	(1  15)
 
+/* OpenACC 2.0 clauses. */
+#define OMP_CLAUSE_ASYNC(1  16)
+#define OMP_CLAUSE_NUM_GANGS(1  17)
+#define OMP_CLAUSE_NUM_WORKERS  (1  18)
+#define OMP_CLAUSE_VECTOR_LENGTH(1  19)
+#define OMP_CLAUSE_COPY (1  20)
+#define