public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC] Device-specific OpenMP target arguments
@ 2015-11-13 18:40 Martin Jambor
  2015-11-16  9:48 ` Jakub Jelinek
  0 siblings, 1 reply; 2+ messages in thread
From: Martin Jambor @ 2015-11-13 18:40 UTC (permalink / raw)
  To: GCC Patches; +Cc: Jakub Jelinek

Hello,

the patch below is is an untested trunk-only implementation of device
specific GOMP_target_ext arguments, which was proposed to me by Jakub
today on IRC.  I'm sending this patch to make sure I understood the
details well.  Nevertheless, I will be commiting a tested and working
version to the hsa branch shortly.

Trunkness-only means there is not much device-specific in the patch
itself, the idea is that the device specific stuff will be added to
the args vector at the place specified by the comment in omp-low.c.
Each such argument will take two array elements, the first one will be
an identifier and the second one the value itself.

As suggested by Jakub, the first two elements will be common NUM_TEAMS
and THREAD_LIMIT from the teams construct, if present.

Any comments welcome,

Thanks,

Martin


2015-11-13  Martin Jambor  <mjambor@suse.cz>

include/
	* gomp-constants.h (GOMP_TARGET_ARG_FIRST_DEVICE_SPECIFIC): New
	constant.
	(GOMP_TARGET_ARG_NUM_TEAMS): Likewise.
	(GOMP_TARGET_ARG_THREAD_LIMIT): Likewise.

gcc/
	* builtin-types.def
	(BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_INT_INT): Turned
	into BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_PTR.
	* omp-builtins.def (BUILT_IN_GOMP_TARGET): Updated type.
	* omp-low.c (get_target_arguments): New function.
	(expand_omp_target): Call it, do not calculate num_teams and
	thread_limit.

gcc/fortran
	* types.def:
	(BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_INT_INT): Turned
	into BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_PTR.

libgomp/
	* libgomp.h (gomp_device_descr): Update type of run_func.
	* libgomp_g.h (GOMP_target_ext): Update type.
	* oacc-host.c (host_run): Likewise.
	* target.c (GOMP_target_ext): Change type, pass arguments to plugins.

liboffloadmic/plugin/
	* libgomp-plugin-intelmic.cpp (GOMP_OFFLOAD_run): Update type.


diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index c68fb19..b0c7704 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -556,9 +556,9 @@ DEF_FUNCTION_TYPE_9 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR_INT,
 		     BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
 		     BT_BOOL, BT_UINT, BT_PTR, BT_INT)
 
-DEF_FUNCTION_TYPE_10 (BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_INT_INT,
-		      BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_SIZE, BT_PTR,
-		      BT_PTR, BT_PTR, BT_UINT, BT_PTR, BT_INT, BT_INT)
+DEF_FUNCTION_TYPE_9 (BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_PTR,
+		     BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_SIZE, BT_PTR,
+		     BT_PTR, BT_PTR, BT_UINT, BT_PTR, BT_PTR)
 
 DEF_FUNCTION_TYPE_11 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_UINT_LONG_INT_LONG_LONG_LONG,
 		      BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR,
diff --git a/gcc/fortran/types.def b/gcc/fortran/types.def
index a37e856..279d055 100644
--- a/gcc/fortran/types.def
+++ b/gcc/fortran/types.def
@@ -221,9 +221,9 @@ DEF_FUNCTION_TYPE_9 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR_INT,
 		     BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
 		     BT_BOOL, BT_UINT, BT_PTR, BT_INT)
 
-DEF_FUNCTION_TYPE_10 (BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_INT_INT,
-		      BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_SIZE, BT_PTR,
-		      BT_PTR, BT_PTR, BT_UINT, BT_PTR, BT_INT, BT_INT)
+DEF_FUNCTION_TYPE_9 (BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_PTR,
+		     BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_SIZE, BT_PTR,
+		     BT_PTR, BT_PTR, BT_UINT, BT_PTR, BT_PTR)
 
 DEF_FUNCTION_TYPE_11 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_UINT_LONG_INT_LONG_LONG_LONG,
 		      BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR,
diff --git a/gcc/omp-builtins.def b/gcc/omp-builtins.def
index 0b6bd58..17f0610 100644
--- a/gcc/omp-builtins.def
+++ b/gcc/omp-builtins.def
@@ -339,7 +339,7 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_COPY_START, "GOMP_single_copy_start",
 DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_COPY_END, "GOMP_single_copy_end",
 		  BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
 DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TARGET, "GOMP_target_ext",
-		  BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_INT_INT,
+		  BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_PTR,
 		  ATTR_NOTHROW_LIST)
 DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TARGET_DATA, "GOMP_target_data_ext",
 		  BT_FN_VOID_INT_SIZE_PTR_PTR_PTR, ATTR_NOTHROW_LIST)
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 51b471c..b9f3ac3 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -12426,6 +12426,54 @@ get_oacc_ifn_dim_arg (const gimple *stmt)
   return (int) axis;
 }
 
+/* Create an array of arguments that is then passed to GOMP_target.   */
+
+static tree
+get_target_arguments (gimple_stmt_iterator *gsi, gomp_target *tgt_stmt)
+{
+  auto_vec <tree, 2> args;
+  tree clauses = gimple_omp_target_clauses (tgt_stmt);
+  tree t, c = find_omp_clause (clauses, OMP_CLAUSE_NUM_TEAMS);
+  if (c)
+    {
+      t = fold_convert (ptr_type_node, OMP_CLAUSE_NUM_TEAMS_EXPR (c));
+      t = force_gimple_operand_gsi (gsi, t, true, NULL, true, GSI_SAME_STMT);
+    }
+  else
+    t = fold_convert (ptr_type_node, integer_minus_one_node);
+  args.quick_push (t);
+  c = find_omp_clause (clauses, OMP_CLAUSE_THREAD_LIMIT);
+  if (c)
+    {
+      t = fold_convert (ptr_type_node, OMP_CLAUSE_THREAD_LIMIT_EXPR (c));
+      t = force_gimple_operand_gsi (gsi, t, true, NULL, true, GSI_SAME_STMT);
+    }
+  else
+    t = fold_convert (ptr_type_node, integer_minus_one_node);
+  args.quick_push (t);
+
+  /* Produce more, perhaps device specific, arguments here.  */
+
+  tree argarray = create_tmp_var (build_array_type_nelts (ptr_type_node,
+							  args.length () + 1),
+				  ".omp_target_args");
+  for (unsigned i = 0; i < args.length (); i++)
+    {
+      tree ref = build4 (ARRAY_REF, ptr_type_node, argarray,
+			 build_int_cst (integer_type_node, i),
+			 NULL_TREE, NULL_TREE);
+      gsi_insert_before (gsi, gimple_build_assign (ref, args[i]),
+			 GSI_SAME_STMT);
+    }
+  tree ref = build4 (ARRAY_REF, ptr_type_node, argarray,
+		     build_int_cst (integer_type_node, args.length ()),
+		     NULL_TREE, NULL_TREE);
+  gsi_insert_before (gsi, gimple_build_assign (ref, null_pointer_node),
+		     GSI_SAME_STMT);
+  TREE_ADDRESSABLE (argarray) = 1;
+  return build_fold_addr_expr (argarray);
+}
+
 /* Expand the GIMPLE_OMP_TARGET starting at REGION.  */
 
 static void
@@ -12832,30 +12880,7 @@ expand_omp_target (struct omp_region *region)
 	depend = build_int_cst (ptr_type_node, 0);
       args.quick_push (depend);
       if (start_ix == BUILT_IN_GOMP_TARGET)
-	{
-	  c = find_omp_clause (clauses, OMP_CLAUSE_NUM_TEAMS);
-	  if (c)
-	    {
-	      t = fold_convert (integer_type_node,
-				OMP_CLAUSE_NUM_TEAMS_EXPR (c));
-	      t = force_gimple_operand_gsi (&gsi, t, true, NULL,
-					    true, GSI_SAME_STMT);
-	    }
-	  else
-	    t = integer_minus_one_node;
-	  args.quick_push (t);
-	  c = find_omp_clause (clauses, OMP_CLAUSE_THREAD_LIMIT);
-	  if (c)
-	    {
-	      t = fold_convert (integer_type_node,
-				OMP_CLAUSE_THREAD_LIMIT_EXPR (c));
-	      t = force_gimple_operand_gsi (&gsi, t, true, NULL,
-					    true, GSI_SAME_STMT);
-	    }
-	  else
-	    t = integer_minus_one_node;
-	  args.quick_push (t);
-	}
+	args.quick_push (get_target_arguments (&gsi, entry_stmt));
       break;
     case BUILT_IN_GOACC_PARALLEL:
       {
diff --git a/include/gomp-constants.h b/include/gomp-constants.h
index 7671dd7..5cb61d7 100644
--- a/include/gomp-constants.h
+++ b/include/gomp-constants.h
@@ -223,4 +223,11 @@ enum gomp_map_kind
 #define GOMP_LAUNCH_OP(X) (((X) >> GOMP_LAUNCH_OP_SHIFT) & 0xffff)
 #define GOMP_LAUNCH_OP_MAX 0xffff
 
+/* First device-specific identifier among target arguments. */
+#define GOMP_TARGET_ARG_FIRST_DEVICE_SPECIFIC	2
+/* Target argument index of NUM_TEAMS */
+#define GOMP_TARGET_ARG_NUM_TEAMS		0
+/* Target argument index of THREAD_LIMIT */
+#define GOMP_TARGET_ARG_THREAD_LIMIT		1
+
 #endif
diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h
index 23b516e..8759e4b 100644
--- a/libgomp/libgomp.h
+++ b/libgomp/libgomp.h
@@ -876,7 +876,7 @@ struct gomp_device_descr
   void *(*dev2host_func) (int, void *, const void *, size_t);
   void *(*host2dev_func) (int, void *, const void *, size_t);
   void *(*dev2dev_func) (int, void *, const void *, size_t);
-  void (*run_func) (int, void *, void *);
+  void (*run_func) (int, void *, void *, void **);
 
   /* Splay tree containing information about mapped memory regions.  */
   struct splay_tree_s mem_map;
diff --git a/libgomp/libgomp_g.h b/libgomp/libgomp_g.h
index c238e6a..9c90d59 100644
--- a/libgomp/libgomp_g.h
+++ b/libgomp/libgomp_g.h
@@ -278,8 +278,7 @@ extern void GOMP_single_copy_end (void *);
 extern void GOMP_target (int, void (*) (void *), const void *,
 			 size_t, void **, size_t *, unsigned char *);
 extern void GOMP_target_ext (int, void (*) (void *), size_t, void **, size_t *,
-			     unsigned short *, unsigned int, void **,
-			     int, int);
+			     unsigned short *, unsigned int, void **, void **);
 extern void GOMP_target_data (int, const void *,
 			      size_t, void **, size_t *, unsigned char *);
 extern void GOMP_target_data_ext (int, size_t, void **, size_t *,
diff --git a/libgomp/oacc-host.c b/libgomp/oacc-host.c
index 9874804..a769211 100644
--- a/libgomp/oacc-host.c
+++ b/libgomp/oacc-host.c
@@ -123,7 +123,8 @@ host_host2dev (int n __attribute__ ((unused)),
 }
 
 static void
-host_run (int n __attribute__ ((unused)), void *fn_ptr, void *vars)
+host_run (int n __attribute__ ((unused)), void *fn_ptr, void *vars,
+	  void **args __attribute__((unused)))
 {
   void (*fn)(void *) = (void (*)(void *)) fn_ptr;
 
diff --git a/libgomp/target.c b/libgomp/target.c
index 1bddc6f..dfb41c5 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -1373,7 +1373,8 @@ GOMP_target (int device, void (*fn) (void *), const void *unused,
       thr->place = old_thr.place;
       thr->ts.place_partition_len = gomp_places_list_len;
     }
-  devicep->run_func (devicep->target_id, fn_addr, (void *) tgt_vars->tgt_start);
+  devicep->run_func (devicep->target_id, fn_addr, (void *) tgt_vars->tgt_start,
+		     NULL);
   gomp_free_thread (thr);
   *thr = old_thr;
   gomp_unmap_vars (tgt_vars, true);
@@ -1383,6 +1384,11 @@ GOMP_target (int device, void (*fn) (void *), const void *unused,
    and several arguments have been added:
    FLAGS is a bitmask, see GOMP_TARGET_FLAG_* in gomp-constants.h.
    DEPEND is array of dependencies, see GOMP_task for details.
+   ARGS is a pointer to an array consisting of NUM_TEAMS, THREAD_LIMIT and a
+   variable number of device-specific arguments, which always take two elements
+   where the first specifies the type and the second the actual value.  The
+   last element of the array is a single NULL.
+
    NUM_TEAMS is positive if GOMP_teams will be called in the body with
    that value, or 1 if teams construct is not present, or 0, if
    teams construct does not have num_teams clause and so the choice is
@@ -1396,14 +1402,10 @@ GOMP_target (int device, void (*fn) (void *), const void *unused,
 void
 GOMP_target_ext (int device, void (*fn) (void *), size_t mapnum,
 		 void **hostaddrs, size_t *sizes, unsigned short *kinds,
-		 unsigned int flags, void **depend, int num_teams,
-		 int thread_limit)
+		 unsigned int flags, void **depend, void **args)
 {
   struct gomp_device_descr *devicep = resolve_device (device);
 
-  (void) num_teams;
-  (void) thread_limit;
-
   /* If there are depend clauses, but nowait is not present,
      block the parent task until the dependencies are resolved
      and then just continue with the rest of the function as if it
@@ -1435,7 +1437,8 @@ GOMP_target_ext (int device, void (*fn) (void *), size_t mapnum,
       thr->place = old_thr.place;
       thr->ts.place_partition_len = gomp_places_list_len;
     }
-  devicep->run_func (devicep->target_id, fn_addr, (void *) tgt_vars->tgt_start);
+  devicep->run_func (devicep->target_id, fn_addr, (void *) tgt_vars->tgt_start,
+		     args);
   gomp_free_thread (thr);
   *thr = old_thr;
   gomp_unmap_vars (tgt_vars, true);
diff --git a/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp b/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
index 26ac6fe..5314333 100644
--- a/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
+++ b/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
@@ -501,7 +501,8 @@ GOMP_OFFLOAD_dev2dev (int device, void *dst_ptr, const void *src_ptr,
 }
 
 extern "C" void
-GOMP_OFFLOAD_run (int device, void *tgt_fn, void *tgt_vars)
+GOMP_OFFLOAD_run (int device, void *tgt_fn, void *tgt_vars,
+		  void **args __attribute__((unused)))
 {
   TRACE ("(tgt_fn = %p, tgt_vars = %p)", tgt_fn, tgt_vars);
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [RFC] Device-specific OpenMP target arguments
  2015-11-13 18:40 [RFC] Device-specific OpenMP target arguments Martin Jambor
@ 2015-11-16  9:48 ` Jakub Jelinek
  0 siblings, 0 replies; 2+ messages in thread
From: Jakub Jelinek @ 2015-11-16  9:48 UTC (permalink / raw)
  To: GCC Patches

On Fri, Nov 13, 2015 at 07:40:27PM +0100, Martin Jambor wrote:
> the patch below is is an untested trunk-only implementation of device
> specific GOMP_target_ext arguments, which was proposed to me by Jakub
> today on IRC.  I'm sending this patch to make sure I understood the
> details well.  Nevertheless, I will be commiting a tested and working
> version to the hsa branch shortly.

Well, the details aren't really in the patch though.

> --- a/gcc/builtin-types.def
> +++ b/gcc/builtin-types.def
> @@ -556,9 +556,9 @@ DEF_FUNCTION_TYPE_9 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR_INT,
>  		     BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
>  		     BT_BOOL, BT_UINT, BT_PTR, BT_INT)
>  
> -DEF_FUNCTION_TYPE_10 (BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_INT_INT,
> -		      BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_SIZE, BT_PTR,
> -		      BT_PTR, BT_PTR, BT_UINT, BT_PTR, BT_INT, BT_INT)
> +DEF_FUNCTION_TYPE_9 (BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_PTR,
> +		     BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_SIZE, BT_PTR,
> +		     BT_PTR, BT_PTR, BT_UINT, BT_PTR, BT_PTR)

A _9 entry should be groupped together with other _9 entries, so no empty
line in between.

> diff --git a/gcc/fortran/types.def b/gcc/fortran/types.def
> index a37e856..279d055 100644
> --- a/gcc/fortran/types.def
> +++ b/gcc/fortran/types.def
> @@ -221,9 +221,9 @@ DEF_FUNCTION_TYPE_9 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_BOOL_UINT_PTR_INT,
>  		     BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
>  		     BT_BOOL, BT_UINT, BT_PTR, BT_INT)
>  
> -DEF_FUNCTION_TYPE_10 (BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_INT_INT,
> -		      BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_SIZE, BT_PTR,
> -		      BT_PTR, BT_PTR, BT_UINT, BT_PTR, BT_INT, BT_INT)
> +DEF_FUNCTION_TYPE_9 (BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_UINT_PTR_PTR,
> +		     BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_SIZE, BT_PTR,
> +		     BT_PTR, BT_PTR, BT_UINT, BT_PTR, BT_PTR)

Likewise.

> --- a/libgomp/libgomp.h
> +++ b/libgomp/libgomp.h
> @@ -876,7 +876,7 @@ struct gomp_device_descr
>    void *(*dev2host_func) (int, void *, const void *, size_t);
>    void *(*host2dev_func) (int, void *, const void *, size_t);
>    void *(*dev2dev_func) (int, void *, const void *, size_t);
> -  void (*run_func) (int, void *, void *);
> +  void (*run_func) (int, void *, void *, void **);

There is now async_run_func too, which needs similar treatment.

> --- a/libgomp/target.c
> +++ b/libgomp/target.c
> @@ -1373,7 +1373,8 @@ GOMP_target (int device, void (*fn) (void *), const void *unused,
>        thr->place = old_thr.place;
>        thr->ts.place_partition_len = gomp_places_list_len;
>      }
> -  devicep->run_func (devicep->target_id, fn_addr, (void *) tgt_vars->tgt_start);
> +  devicep->run_func (devicep->target_id, fn_addr, (void *) tgt_vars->tgt_start,
> +		     NULL);
>    gomp_free_thread (thr);
>    *thr = old_thr;
>    gomp_unmap_vars (tgt_vars, true);
> @@ -1383,6 +1384,11 @@ GOMP_target (int device, void (*fn) (void *), const void *unused,
>     and several arguments have been added:
>     FLAGS is a bitmask, see GOMP_TARGET_FLAG_* in gomp-constants.h.
>     DEPEND is array of dependencies, see GOMP_task for details.
> +   ARGS is a pointer to an array consisting of NUM_TEAMS, THREAD_LIMIT and a
> +   variable number of device-specific arguments, which always take two elements
> +   where the first specifies the type and the second the actual value.  The
> +   last element of the array is a single NULL.

I wouldn't document that it has to be always a pair, simply always a new
pointer in the array encodes:
a) a few bits describing what offloading target this is for
   (enum offload_target_type or some other constant, but needs to be defined
   in gomp-constants.h; offload_target_type has the advantage that it exists
   alrady, and disadvantage that it already now contains gaps, for now
   we really need some value describing that it applies to all offloading
   targets, then host fallback, XeonPhi, NVidia, HSA (but with enough room
   for future growth))
b) a few bits describing the opcode
c) the remaining bits could be used to hold shorter values; say if you
   have a bool value (or some set of bools), they could go inline, or
   say some integer with limited range (say 16 bits at most), or perhaps
   on 64-bit hosts even full integer (and on 32-bit hosts the argument
   would go in the next pointer instead)
And this pointer would be followed by optional arguments, as specific to the
opcode.
Though, if we want other plugins to be able to easily skip opcodes for
other offloading targets, perhaps there should be also bits describing
how many arguments the opcode has.

> --- a/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
> +++ b/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
> @@ -501,7 +501,8 @@ GOMP_OFFLOAD_dev2dev (int device, void *dst_ptr, const void *src_ptr,
>  }
>  
>  extern "C" void
> -GOMP_OFFLOAD_run (int device, void *tgt_fn, void *tgt_vars)
> +GOMP_OFFLOAD_run (int device, void *tgt_fn, void *tgt_vars,
> +		  void **args __attribute__((unused)))
>  {
>    TRACE ("(tgt_fn = %p, tgt_vars = %p)", tgt_fn, tgt_vars);

This plugin is written in C++, so you can just use void **/* args */ or
void ** instead.

	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-11-16  9:48 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-13 18:40 [RFC] Device-specific OpenMP target arguments Martin Jambor
2015-11-16  9:48 ` Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).