diff mbox

[gomp4] enable GOMP_MAP_FIRSTPRIVATE_INT in OpenACC

Message ID 14767369-91e5-71a1-2079-cad922783aef@codesourcery.com
State New
Headers show

Commit Message

Cesar Philippidis Feb. 1, 2017, 5:58 p.m. UTC
On 01/30/2017 02:18 AM, Thomas Schwinge wrote:
> Hi Cesar!
> 
> On Fri, 27 Jan 2017 07:45:52 -0800, Cesar Philippidis <cesar@codesourcery.com> wrote:
>> If you take a close look at lower_omp_target, you'll notice that I'm
>> gave reference types special treatment. Specifically, I disabled this
>> optimization on non-INTEGER_TYPE and floating point values, because the
>> nvptx target was having some problems dereferencing boolean-typed
>> pointers. That's something I have on my TODO list to track down later.
> 
> Please file an issue as appropriate.

I filed an issue for this internally.

>> As for the performance gains, this optimization resulted in a
>> non-trivial speedup in CloverLeaf running on a Nvidia Pascal board.
>> CloverLeaf is somewhat special in that it consists of a lot of OpenACC
>> offloaded regions which gets called multiple times throughout its
>> execution. Consequently, it is I/O limited. The other benchmarks I ran
>> didn't benefit nearly as much as CloverLeaf. I chose a small data set
>> for CloverLeaf that only ran in 1.3s without the patch, and hence make
>> it even more I/O limited. After the patch, it ran 0.35s faster.
> 
> \o/ Yay!
> 
>> This patch has been applied to gomp-4_0-branch.
> 
> (Not reviewed in detail.)
> 
>> --- a/gcc/omp-low.c
>> +++ b/gcc/omp-low.c
> 
>> +static tree
>> +convert_from_firstprivate_pointer (tree var, bool is_ref, gimple_seq *gs)
>> +{
>> +  tree type = TREE_TYPE (var);
>> +  tree new_type = NULL_TREE;
>> +  tree tmp = NULL_TREE;
>> +  tree inner_type = NULL_TREE;
> 
>     [...]/source-gcc/gcc/omp-low.c: In function 'tree_node* convert_from_firstprivate_pointer(tree, bool, gimple**)':
>     [...]/source-gcc/gcc/omp-low.c:16515:8: warning: unused variable 'inner_type' [-Wunused-variable]
> 
> 
>> --- /dev/null
>> +++ b/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90
> 
> I see:
> 
>     {+FAIL: libgomp.oacc-fortran/firstprivate-int.f90 -DACC_DEVICE_TYPE_nvidia=1 -DACC_MEM_SHARED=0 -foffload=nvptx-none  -O  (internal compiler error)+}
>     {+FAIL: libgomp.oacc-fortran/firstprivate-int.f90 -DACC_DEVICE_TYPE_nvidia=1 -DACC_MEM_SHARED=0 -foffload=nvptx-none  -O   4 blank line(s) in output+}
>     {+FAIL: libgomp.oacc-fortran/firstprivate-int.f90 -DACC_DEVICE_TYPE_nvidia=1 -DACC_MEM_SHARED=0 -foffload=nvptx-none  -O  (test for excess errors)+}
>     {+UNRESOLVED: libgomp.oacc-fortran/firstprivate-int.f90 -DACC_DEVICE_TYPE_nvidia=1 -DACC_MEM_SHARED=0 -foffload=nvptx-none  -O  compilation failed to produce executable+}
> 
> That's the nvptx offloading compiler configured with
> "--enable-checking=yes,df,fold,rtl":
> 
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90: In function 'MAIN__._omp_fn.1':
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:55:0: error: conversion of register to a different size
>     VIEW_CONVERT_EXPR<logical(kind=2)>(_17);
>     
>     _18 = VIEW_CONVERT_EXPR<logical(kind=2)>(_17);
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:55:0: error: conversion of register to a different size
>     VIEW_CONVERT_EXPR<logical(kind=4)>(_20);
>     
>     _21 = VIEW_CONVERT_EXPR<logical(kind=4)>(_20);
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:55:0: error: conversion of register to a different size
>     VIEW_CONVERT_EXPR<logical(kind=8)>(_23);
>     
>     _24 = VIEW_CONVERT_EXPR<logical(kind=8)>(_23);
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:55:0: error: conversion of register to a different size
>     VIEW_CONVERT_EXPR<logical(kind=16)>(_26);
>     
>     _27 = VIEW_CONVERT_EXPR<logical(kind=16)>(_26);
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:55:0: internal compiler error: verify_gimple failed
>     0xa67d75 verify_gimple_in_cfg(function*, bool)
>             [...]/source-gcc/gcc/tree-cfg.c:5125
>     0x94ebbc execute_function_todo
>             [...]/source-gcc/gcc/passes.c:1958
>     0x94f513 execute_todo
>             [...]/source-gcc/gcc/passes.c:2010
> 
> 
> And with "-m32" multilib testing, I see:
> 
>     {+FAIL: libgomp.oacc-fortran/firstprivate-int.f90 -DACC_DEVICE_TYPE_host=1 -DACC_MEM_SHARED=1 -foffload=disable  -O  (test for excess errors)+}
>     {+UNRESOLVED: libgomp.oacc-fortran/firstprivate-int.f90 -DACC_DEVICE_TYPE_host=1 -DACC_MEM_SHARED=1 -foffload=disable  -O  compilation failed to produce executable+}
> 
> That is:
> 
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:10:18: Error: Kind 16 not supported for type INTEGER at (1)
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:16:18: Error: Kind 16 not supported for type LOGICAL at (1)
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:115:18: Error: Kind 16 not supported for type INTEGER at (1)
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:121:18: Error: Kind 16 not supported for type LOGICAL at (1)
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:31:6: Error: Symbol 'i16i' at (1) has no IMPLICIT type
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:49:40: Error: Symbol 'i16o' at (1) has no IMPLICIT type
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:37:6: Error: Symbol 'l16i' at (1) has no IMPLICIT type
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:51:40: Error: Symbol 'l16o' at (1) has no IMPLICIT type
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:105:43: Error: Symbol 'i16i' at (1) has no IMPLICIT type
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:105:69: Error: Symbol 'i16o' at (1) has no IMPLICIT type
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:106:43: Error: Symbol 'l16i' at (1) has no IMPLICIT type
>     [...]/source-gcc/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-int.f90:106:69: Error: Symbol 'l16o' at (1) has no IMPLICIT type

I should have been comparing the type size, not precision against the
pointer size. This patch fixes that.

Cesar
diff mbox

Patch

2017-02-01  Cesar Philippidis  <cesar@codesourcery.com>

	gcc/
	* omp-low.c (convert_to_firstprivate_pointer): Use TYPE_SIZE instead
	of TYPE_PRECISION when determining if a firstprivate variable may be
	casted into a pointer.
	(convert_from_firstprivate_pointer): Likewise.
	(lower_omp_target): Likewise.


diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 142d928..450d76e 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -16480,7 +16480,7 @@  convert_to_firstprivate_pointer (tree var, gimple_seq *gs)
     return fold_convert (pointer_sized_int_node, var);
   }
 
-  switch (TYPE_PRECISION (type))
+  switch (tree_to_uhwi (TYPE_SIZE (type)))
     {
     case 1: case 2: case 4: case 8: new_type = unsigned_char_type_node; break;
     case 16: new_type = short_unsigned_type_node; break;
@@ -16520,7 +16520,7 @@  convert_from_firstprivate_pointer (tree var, bool is_ref, gimple_seq *gs)
   if (INTEGRAL_TYPE_P (var) || POINTER_TYPE_P (type))
     return fold_convert (type, var);
 
-  switch (TYPE_PRECISION (type))
+  switch (tree_to_uhwi (TYPE_SIZE (type)))
     {
     case 1: case 2: case 4: case 8: new_type = unsigned_char_type_node; break;
     case 16: new_type = short_unsigned_type_node; break;
@@ -16732,7 +16732,7 @@  lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 		&& (TREE_CODE (inner_type) == REAL_TYPE
 		    || (!is_reference (var) && INTEGRAL_TYPE_P (inner_type))
 		    || TREE_CODE (inner_type) == INTEGER_TYPE)
-		&& TYPE_PRECISION (inner_type) <= POINTER_SIZE
+		&& tree_to_uhwi (TYPE_SIZE (inner_type)) <= POINTER_SIZE
 		&& TYPE_PRECISION (inner_type) != 0
 		&& !maybe_lookup_field_in_outer_ctx (var, ctx))
 	      oacc_firstprivate_int = true;
@@ -17012,7 +17012,7 @@  lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 			 || (!is_reference (var)
 			     && INTEGRAL_TYPE_P (inner_type))
 			 || TREE_CODE (inner_type) == INTEGER_TYPE)
-			&& TYPE_PRECISION (inner_type) <= POINTER_SIZE
+			&& tree_to_uhwi (TYPE_SIZE (inner_type)) <= POINTER_SIZE
 			&& TYPE_PRECISION (inner_type) != 0
 			&& !maybe_lookup_field_in_outer_ctx (var, ctx))
 		      {
@@ -17200,7 +17200,7 @@  lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 	    if (is_reference (ovar))
 	      type = TREE_TYPE (type);
 	    if ((INTEGRAL_TYPE_P (type)
-		 && TYPE_PRECISION (type) <= POINTER_SIZE)
+		 && tree_to_uhwi (TYPE_SIZE (type)) <= POINTER_SIZE)
 		|| TREE_CODE (type) == POINTER_TYPE)
 	      {
 		tkind = GOMP_MAP_FIRSTPRIVATE_INT;
@@ -17355,7 +17355,7 @@  lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 		if (is_reference (var))
 		  type = TREE_TYPE (type);
 		if ((INTEGRAL_TYPE_P (type)
-		     && TYPE_PRECISION (type) <= POINTER_SIZE)
+		     && tree_to_uhwi (TYPE_SIZE (type)) <= POINTER_SIZE)
 		    || TREE_CODE (type) == POINTER_TYPE)
 		  {
 		    x = build_receiver_ref (var, false, ctx);