On 01/30/2017 02:18 AM, Thomas Schwinge wrote: > Hi Cesar! > > On Fri, 27 Jan 2017 07:45:52 -0800, Cesar Philippidis > <ce...@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
2017-02-01 Cesar Philippidis <ce...@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);