diff mbox

SIMD clones LTO fixes part 1 (PR lto/59326)

Message ID 20131128225843.GR892@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Nov. 28, 2013, 10:58 p.m. UTC
Hi!

Here is the first part of LTO fixes for #pragma omp declare simd,
in partuclar support for streaming OMP_CLAUSEs.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2013-11-28  Jakub Jelinek  <jakub@redhat.com>

	PR lto/59326
	* tree-core.h (enum omp_clause_schedule_kind): Add
	OMP_CLAUSE_SCHEDULE_LAST.
	(enum omp_clause_default_kind): Add OMP_CLAUSE_DEFAULT_LAST.
	(enum omp_clause_depend_kind): Add OMP_CLAUSE_DEPEND_LAST.
	(enum omp_clause_map_kind): Add OMP_CLAUSE_MAP_LAST.
	(enum omp_clause_proc_bind_kind): Add OMP_CLAUSE_PROC_BIND_LAST.
	* lto-streamer-out.c (lto_is_streamable): Allow streaming
	OMP_CLAUSE.
	(DFS_write_tree_body): Handle OMP_CLAUSE.
	* tree-streamer-out.c (pack_ts_omp_clause_value_fields): New
	function.
	(streamer_pack_tree_bitfields): Call it for OMP_CLAUSE.
	(write_ts_omp_clause_tree_pointers): New function.
	(streamer_write_tree_body): Call it for OMP_CLAUSE.
	(streamer_write_tree_header): For OMP_CLAUSE stream OMP_CLAUSE_CODE.
	* tree-streamer-in.c (unpack_ts_omp_clause_value_fields): New
	function.
	(unpack_value_fields): Call it for OMP_CLAUSE.
	(streamer_alloc_tree): Handle OMP_CLAUSE.
	(lto_input_ts_omp_clause_tree_pointers): New function.
	(streamer_read_tree_body): Call it for OMP_CLAUSE.
lto/
	* lto.c (mentions_vars_p_omp_clause): New function.
	(mentions_vars_p): Call it for OMP_CLAUSE.  Remove break;
	after return stmts.


	Jakub

Comments

Richard Biener Nov. 29, 2013, 8:53 a.m. UTC | #1
On Thu, 28 Nov 2013, Jakub Jelinek wrote:

> Hi!
> 
> Here is the first part of LTO fixes for #pragma omp declare simd,
> in partuclar support for streaming OMP_CLAUSEs.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2013-11-28  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR lto/59326
> 	* tree-core.h (enum omp_clause_schedule_kind): Add
> 	OMP_CLAUSE_SCHEDULE_LAST.
> 	(enum omp_clause_default_kind): Add OMP_CLAUSE_DEFAULT_LAST.
> 	(enum omp_clause_depend_kind): Add OMP_CLAUSE_DEPEND_LAST.
> 	(enum omp_clause_map_kind): Add OMP_CLAUSE_MAP_LAST.
> 	(enum omp_clause_proc_bind_kind): Add OMP_CLAUSE_PROC_BIND_LAST.
> 	* lto-streamer-out.c (lto_is_streamable): Allow streaming
> 	OMP_CLAUSE.
> 	(DFS_write_tree_body): Handle OMP_CLAUSE.
> 	* tree-streamer-out.c (pack_ts_omp_clause_value_fields): New
> 	function.
> 	(streamer_pack_tree_bitfields): Call it for OMP_CLAUSE.
> 	(write_ts_omp_clause_tree_pointers): New function.
> 	(streamer_write_tree_body): Call it for OMP_CLAUSE.
> 	(streamer_write_tree_header): For OMP_CLAUSE stream OMP_CLAUSE_CODE.
> 	* tree-streamer-in.c (unpack_ts_omp_clause_value_fields): New
> 	function.
> 	(unpack_value_fields): Call it for OMP_CLAUSE.
> 	(streamer_alloc_tree): Handle OMP_CLAUSE.
> 	(lto_input_ts_omp_clause_tree_pointers): New function.
> 	(streamer_read_tree_body): Call it for OMP_CLAUSE.
> lto/
> 	* lto.c (mentions_vars_p_omp_clause): New function.
> 	(mentions_vars_p): Call it for OMP_CLAUSE.  Remove break;
> 	after return stmts.
> 
> --- gcc/tree-core.h.jj	2013-11-27 12:15:14.000000000 +0100
> +++ gcc/tree-core.h	2013-11-28 10:55:46.691490627 +0100
> @@ -350,7 +350,8 @@ enum omp_clause_schedule_kind {
>    OMP_CLAUSE_SCHEDULE_DYNAMIC,
>    OMP_CLAUSE_SCHEDULE_GUIDED,
>    OMP_CLAUSE_SCHEDULE_AUTO,
> -  OMP_CLAUSE_SCHEDULE_RUNTIME
> +  OMP_CLAUSE_SCHEDULE_RUNTIME,
> +  OMP_CLAUSE_SCHEDULE_LAST
>  };
>  
>  enum omp_clause_default_kind {
> @@ -358,7 +359,8 @@ enum omp_clause_default_kind {
>    OMP_CLAUSE_DEFAULT_SHARED,
>    OMP_CLAUSE_DEFAULT_NONE,
>    OMP_CLAUSE_DEFAULT_PRIVATE,
> -  OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
> +  OMP_CLAUSE_DEFAULT_FIRSTPRIVATE,
> +  OMP_CLAUSE_DEFAULT_LAST
>  };
>  
>  /* There is a TYPE_QUAL value for each type qualifier.  They can be
> @@ -1107,7 +1109,8 @@ enum omp_clause_depend_kind
>  {
>    OMP_CLAUSE_DEPEND_IN,
>    OMP_CLAUSE_DEPEND_OUT,
> -  OMP_CLAUSE_DEPEND_INOUT
> +  OMP_CLAUSE_DEPEND_INOUT,
> +  OMP_CLAUSE_DEPEND_LAST
>  };
>  
>  enum omp_clause_map_kind
> @@ -1119,7 +1122,8 @@ enum omp_clause_map_kind
>    /* The following kind is an internal only map kind, used for pointer based
>       array sections.  OMP_CLAUSE_SIZE for these is not the pointer size,
>       which is implicitly POINTER_SIZE / BITS_PER_UNIT, but the bias.  */
> -  OMP_CLAUSE_MAP_POINTER
> +  OMP_CLAUSE_MAP_POINTER,
> +  OMP_CLAUSE_MAP_LAST
>  };
>  
>  enum omp_clause_proc_bind_kind
> @@ -1129,7 +1133,8 @@ enum omp_clause_proc_bind_kind
>    OMP_CLAUSE_PROC_BIND_TRUE = 1,
>    OMP_CLAUSE_PROC_BIND_MASTER = 2,
>    OMP_CLAUSE_PROC_BIND_CLOSE = 3,
> -  OMP_CLAUSE_PROC_BIND_SPREAD = 4
> +  OMP_CLAUSE_PROC_BIND_SPREAD = 4,
> +  OMP_CLAUSE_PROC_BIND_LAST
>  };
>  
>  struct GTY(()) tree_exp {
> --- gcc/lto-streamer-out.c.jj	2013-11-27 18:02:46.000000000 +0100
> +++ gcc/lto-streamer-out.c	2013-11-28 11:51:03.085288356 +0100
> @@ -297,7 +297,6 @@ lto_is_streamable (tree expr)
>  	 && code != BIND_EXPR
>  	 && code != WITH_CLEANUP_EXPR
>  	 && code != STATEMENT_LIST
> -	 && code != OMP_CLAUSE
>  	 && (code == CASE_LABEL_EXPR
>  	     || code == DECL_EXPR
>  	     || TREE_CODE_CLASS (code) != tcc_statement);
> @@ -667,6 +666,14 @@ DFS_write_tree_body (struct output_block
>  	}
>      }
>  
> +  if (code == OMP_CLAUSE)
> +    {
> +      int i;
> +      for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
> +	DFS_follow_tree_edge (OMP_CLAUSE_OPERAND (expr, i));
> +      DFS_follow_tree_edge (OMP_CLAUSE_CHAIN (expr));
> +    }
> +
>  #undef DFS_follow_tree_edge
>  }
>  
> --- gcc/tree-streamer-out.c.jj	2013-11-22 21:03:16.000000000 +0100
> +++ gcc/tree-streamer-out.c	2013-11-28 11:49:49.327672855 +0100
> @@ -390,6 +390,46 @@ pack_ts_optimization (struct bitpack_d *
>  }
>  
>  
> +/* Pack all the non-pointer fields of the TS_OMP_CLAUSE structure
> +   of expression EXPR into bitpack BP.  */
> +
> +static void
> +pack_ts_omp_clause_value_fields (struct output_block *ob,
> +				 struct bitpack_d *bp, tree expr)
> +{
> +  stream_output_location (ob, bp, OMP_CLAUSE_LOCATION (expr));
> +  switch (OMP_CLAUSE_CODE (expr))
> +    {
> +    case OMP_CLAUSE_DEFAULT:
> +      bp_pack_enum (bp, omp_clause_default_kind, OMP_CLAUSE_DEFAULT_LAST,
> +		    OMP_CLAUSE_DEFAULT_KIND (expr));
> +      break;
> +    case OMP_CLAUSE_SCHEDULE:
> +      bp_pack_enum (bp, omp_clause_schedule_kind, OMP_CLAUSE_SCHEDULE_LAST,
> +		    OMP_CLAUSE_SCHEDULE_KIND (expr));
> +      break;
> +    case OMP_CLAUSE_DEPEND:
> +      bp_pack_enum (bp, omp_clause_depend_kind, OMP_CLAUSE_DEPEND_LAST,
> +		    OMP_CLAUSE_DEPEND_KIND (expr));
> +      break;
> +    case OMP_CLAUSE_MAP:
> +      bp_pack_enum (bp, omp_clause_map_kind, OMP_CLAUSE_MAP_LAST,
> +		    OMP_CLAUSE_MAP_KIND (expr));
> +      break;
> +    case OMP_CLAUSE_PROC_BIND:
> +      bp_pack_enum (bp, omp_clause_proc_bind_kind, OMP_CLAUSE_PROC_BIND_LAST,
> +		    OMP_CLAUSE_PROC_BIND_KIND (expr));
> +      break;
> +    case OMP_CLAUSE_REDUCTION:
> +      bp_pack_enum (bp, tree_code, MAX_TREE_CODES,
> +		    OMP_CLAUSE_REDUCTION_CODE (expr));
> +      break;
> +    default:
> +      break;
> +    }
> +}
> +
> +
>  /* Pack all the bitfields in EXPR into a bit pack.  */
>  
>  void
> @@ -451,6 +491,9 @@ streamer_pack_tree_bitfields (struct out
>  
>    if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
>      bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr));
> +
> +  if (code == OMP_CLAUSE)
> +    pack_ts_omp_clause_value_fields (ob, bp, expr);
>  }
>  
>  
> @@ -853,6 +896,29 @@ write_ts_constructor_tree_pointers (stru
>      }
>  }
>  
> +
> +/* Write all pointer fields in the TS_OMP_CLAUSE structure of EXPR
> +   to output block OB.  If REF_P is true, write a reference to EXPR's
> +   pointer fields.  */
> +
> +static void
> +write_ts_omp_clause_tree_pointers (struct output_block *ob, tree expr,
> +				   bool ref_p)
> +{
> +  int i;
> +  for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
> +    stream_write_tree (ob, OMP_CLAUSE_OPERAND (expr, i), ref_p);
> +  if (OMP_CLAUSE_CODE (expr) == OMP_CLAUSE_REDUCTION)
> +    {
> +      /* We don't stream these right now, handle it if streaming
> +	 of them is needed.  */
> +      gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (expr) == NULL);
> +      gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (expr) == NULL);
> +    }
> +  stream_write_tree (ob, OMP_CLAUSE_CHAIN (expr), ref_p);
> +}
> +
> +
>  /* Write all pointer fields in EXPR to output block OB.  If REF_P is true,
>     the leaves of EXPR are emitted as references.  */
>  
> @@ -915,6 +981,9 @@ streamer_write_tree_body (struct output_
>  
>    if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
>      write_ts_constructor_tree_pointers (ob, expr, ref_p);
> +
> +  if (code == OMP_CLAUSE)
> +    write_ts_omp_clause_tree_pointers (ob, expr, ref_p);
>  }
>  
>  
> @@ -963,6 +1032,8 @@ streamer_write_tree_header (struct outpu
>      streamer_write_uhwi (ob, BINFO_N_BASE_BINFOS (expr));
>    else if (TREE_CODE (expr) == CALL_EXPR)
>      streamer_write_uhwi (ob, call_expr_nargs (expr));
> +  else if (TREE_CODE (expr) == OMP_CLAUSE)
> +    streamer_write_uhwi (ob, OMP_CLAUSE_CODE (expr));
>  }
>  
>  
> --- gcc/tree-streamer-in.c.jj	2013-11-22 21:03:16.000000000 +0100
> +++ gcc/tree-streamer-in.c	2013-11-28 11:49:42.437709308 +0100
> @@ -425,6 +425,48 @@ unpack_ts_optimization (struct bitpack_d
>  }
>  
>  
> +/* Unpack all the non-pointer fields of the TS_OMP_CLAUSE
> +   structure of expression EXPR from bitpack BP.  */
> +
> +static void
> +unpack_ts_omp_clause_value_fields (struct data_in *data_in,
> +				   struct bitpack_d *bp, tree expr)
> +{
> +  OMP_CLAUSE_LOCATION (expr) = stream_input_location (bp, data_in);
> +  switch (OMP_CLAUSE_CODE (expr))
> +    {
> +    case OMP_CLAUSE_DEFAULT:
> +      OMP_CLAUSE_DEFAULT_KIND (expr)
> +	= bp_unpack_enum (bp, omp_clause_default_kind,
> +			  OMP_CLAUSE_DEFAULT_LAST);
> +      break;
> +    case OMP_CLAUSE_SCHEDULE:
> +      OMP_CLAUSE_SCHEDULE_KIND (expr)
> +	= bp_unpack_enum (bp, omp_clause_schedule_kind,
> +			  OMP_CLAUSE_SCHEDULE_LAST);
> +      break;
> +    case OMP_CLAUSE_DEPEND:
> +      OMP_CLAUSE_DEPEND_KIND (expr)
> +	= bp_unpack_enum (bp, omp_clause_depend_kind, OMP_CLAUSE_DEPEND_LAST);
> +      break;
> +    case OMP_CLAUSE_MAP:
> +      OMP_CLAUSE_MAP_KIND (expr)
> +	= bp_unpack_enum (bp, omp_clause_map_kind, OMP_CLAUSE_MAP_LAST);
> +      break;
> +    case OMP_CLAUSE_PROC_BIND:
> +      OMP_CLAUSE_PROC_BIND_KIND (expr)
> +	= bp_unpack_enum (bp, omp_clause_proc_bind_kind,
> +			  OMP_CLAUSE_PROC_BIND_LAST);
> +      break;
> +    case OMP_CLAUSE_REDUCTION:
> +      OMP_CLAUSE_REDUCTION_CODE (expr)
> +	= bp_unpack_enum (bp, tree_code, MAX_TREE_CODES);
> +      break;
> +    default:
> +      break;
> +    }
> +}
> +
>  /* Unpack all the non-pointer fields in EXPR into a bit pack.  */
>  
>  static void
> @@ -493,6 +535,9 @@ unpack_value_fields (struct data_in *dat
>        if (length > 0)
>  	vec_safe_grow (CONSTRUCTOR_ELTS (expr), length);
>      }
> +
> +  if (code == OMP_CLAUSE)
> +    unpack_ts_omp_clause_value_fields (data_in, bp, expr);
>  }
>  
>  
> @@ -578,6 +623,12 @@ streamer_alloc_tree (struct lto_input_bl
>        unsigned HOST_WIDE_INT nargs = streamer_read_uhwi (ib);
>        return build_vl_exp (CALL_EXPR, nargs + 3);
>      }
> +  else if (code == OMP_CLAUSE)
> +    {
> +      enum omp_clause_code subcode
> +	= (enum omp_clause_code) streamer_read_uhwi (ib);
> +      return build_omp_clause (UNKNOWN_LOCATION, subcode);
> +    }
>    else
>      {
>        /* For all other nodes, materialize the tree with a raw
> @@ -960,6 +1011,22 @@ lto_input_ts_constructor_tree_pointers (
>  }
>  
>  
> +/* Read all pointer fields in the TS_OMP_CLAUSE structure of EXPR from
> +   input block IB.  DATA_IN contains tables and descriptors for the
> +   file being read.  */
> +
> +static void
> +lto_input_ts_omp_clause_tree_pointers (struct lto_input_block *ib,
> +				       struct data_in *data_in, tree expr)
> +{
> +  int i;
> +
> +  for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
> +    OMP_CLAUSE_OPERAND (expr, i) = stream_read_tree (ib, data_in);
> +  OMP_CLAUSE_CHAIN (expr) = stream_read_tree (ib, data_in);
> +}
> +
> +
>  /* Read all pointer fields in EXPR from input block IB.  DATA_IN
>     contains tables and descriptors for the file being read.  */
>  
> @@ -1021,6 +1088,9 @@ streamer_read_tree_body (struct lto_inpu
>  
>    if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
>      lto_input_ts_constructor_tree_pointers (ib, data_in, expr);
> +
> +  if (code == OMP_CLAUSE)
> +    lto_input_ts_omp_clause_tree_pointers (ib, data_in, expr);
>  }
>  
>  
> --- gcc/lto/lto.c.jj	2013-11-22 21:03:14.000000000 +0100
> +++ gcc/lto/lto.c	2013-11-28 11:58:15.597048439 +0100
> @@ -904,6 +904,19 @@ mentions_vars_p_expr (tree t)
>    return false;
>  }
>  
> +/* Check presence of pointers to decls in fields of an OMP_CLAUSE T.  */
> +
> +static bool
> +mentions_vars_p_omp_clause (tree t)
> +{
> +  int i;
> +  if (mentions_vars_p_common (t))
> +    return true;
> +  for (i = omp_clause_num_ops[OMP_CLAUSE_CODE (t)] - 1; i >= 0; --i)
> +    CHECK_VAR (OMP_CLAUSE_OPERAND (t, i));
> +  return false;
> +}
> +
>  /* Check presence of pointers to decls that needs later fixup in T.  */
>  
>  static bool
> @@ -922,7 +935,6 @@ mentions_vars_p (tree t)
>  
>      case FIELD_DECL:
>        return mentions_vars_p_field_decl (t);
> -      break;
>  
>      case LABEL_DECL:
>      case CONST_DECL:
> @@ -931,27 +943,21 @@ mentions_vars_p (tree t)
>      case IMPORTED_DECL:
>      case NAMESPACE_DECL:
>        return mentions_vars_p_decl_common (t);
> -      break;
>  
>      case VAR_DECL:
>        return mentions_vars_p_decl_with_vis (t);
> -      break;
>  
>      case TYPE_DECL:
>        return mentions_vars_p_decl_non_common (t);
> -      break;
>  
>      case FUNCTION_DECL:
>        return mentions_vars_p_function (t);
> -      break;
>  
>      case TREE_BINFO:
>        return mentions_vars_p_binfo (t);
> -      break;
>  
>      case PLACEHOLDER_EXPR:
>        return mentions_vars_p_common (t);
> -      break;
>  
>      case BLOCK:
>      case TRANSLATION_UNIT_DECL:
> @@ -961,7 +967,9 @@ mentions_vars_p (tree t)
>  
>      case CONSTRUCTOR:
>        return mentions_vars_p_constructor (t);
> -      break;
> +
> +    case OMP_CLAUSE:
> +      return mentions_vars_p_omp_clause (t);
>  
>      default:
>        if (TYPE_P (t))
> 
> 	Jakub
> 
>
Jeff Law Dec. 3, 2013, 8:11 p.m. UTC | #2
On 11/28/13 15:58, Jakub Jelinek wrote:
  +  for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
> +    stream_write_tree (ob, OMP_CLAUSE_OPERAND (expr, i), ref_p);
> +  if (OMP_CLAUSE_CODE (expr) == OMP_CLAUSE_REDUCTION)
> +    {
> +      /* We don't stream these right now, handle it if streaming
> +	 of them is needed.  */
> +      gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (expr) == NULL);
> +      gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (expr) == NULL);
> +    }
ISTM we will need to stream these.  Is there some reason to think they 
won't be needed?  Otherwise it looks good.

If you've got a good reason to believe these won't be needed, then it's 
OK as-is.  If not I'd like to see this stuff handed too.



jeff
Jakub Jelinek Dec. 3, 2013, 8:14 p.m. UTC | #3
On Tue, Dec 03, 2013 at 01:11:08PM -0700, Jeff Law wrote:
> On 11/28/13 15:58, Jakub Jelinek wrote:
>  +  for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
> >+    stream_write_tree (ob, OMP_CLAUSE_OPERAND (expr, i), ref_p);
> >+  if (OMP_CLAUSE_CODE (expr) == OMP_CLAUSE_REDUCTION)
> >+    {
> >+      /* We don't stream these right now, handle it if streaming
> >+	 of them is needed.  */
> >+      gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (expr) == NULL);
> >+      gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (expr) == NULL);
> >+    }
> ISTM we will need to stream these.  Is there some reason to think
> they won't be needed?  Otherwise it looks good.
> 
> If you've got a good reason to believe these won't be needed, then
> it's OK as-is.  If not I'd like to see this stuff handed too.

Normally omp clauses disappear during omp expansion, right now the only
clauses that LTO streamers sees are those for #pragma omp declare simd,
those are never reductions.  I chose to implement streaming of all
omp clauses rather than just the subset of them that can appear in
"omp declare simd" attribute argument, just streaming of the above
gimple seqs would be too much work for something that isn't needed.

	Jakub
Jeff Law Dec. 3, 2013, 8:18 p.m. UTC | #4
On 12/03/13 13:14, Jakub Jelinek wrote:
> On Tue, Dec 03, 2013 at 01:11:08PM -0700, Jeff Law wrote:
>> On 11/28/13 15:58, Jakub Jelinek wrote:
>>   +  for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
>>> +    stream_write_tree (ob, OMP_CLAUSE_OPERAND (expr, i), ref_p);
>>> +  if (OMP_CLAUSE_CODE (expr) == OMP_CLAUSE_REDUCTION)
>>> +    {
>>> +      /* We don't stream these right now, handle it if streaming
>>> +	 of them is needed.  */
>>> +      gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (expr) == NULL);
>>> +      gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (expr) == NULL);
>>> +    }
>> ISTM we will need to stream these.  Is there some reason to think
>> they won't be needed?  Otherwise it looks good.
>>
>> If you've got a good reason to believe these won't be needed, then
>> it's OK as-is.  If not I'd like to see this stuff handed too.
>
> Normally omp clauses disappear during omp expansion, right now the only
> clauses that LTO streamers sees are those for #pragma omp declare simd,
> those are never reductions.  I chose to implement streaming of all
> omp clauses rather than just the subset of them that can appear in
> "omp declare simd" attribute argument, just streaming of the above
> gimple seqs would be too much work for something that isn't needed.
So the reductions are handled (expanded) prior to streaming out and we 
don't have to attach them back to something when we stream in?

Jeff
diff mbox

Patch

--- gcc/tree-core.h.jj	2013-11-27 12:15:14.000000000 +0100
+++ gcc/tree-core.h	2013-11-28 10:55:46.691490627 +0100
@@ -350,7 +350,8 @@  enum omp_clause_schedule_kind {
   OMP_CLAUSE_SCHEDULE_DYNAMIC,
   OMP_CLAUSE_SCHEDULE_GUIDED,
   OMP_CLAUSE_SCHEDULE_AUTO,
-  OMP_CLAUSE_SCHEDULE_RUNTIME
+  OMP_CLAUSE_SCHEDULE_RUNTIME,
+  OMP_CLAUSE_SCHEDULE_LAST
 };
 
 enum omp_clause_default_kind {
@@ -358,7 +359,8 @@  enum omp_clause_default_kind {
   OMP_CLAUSE_DEFAULT_SHARED,
   OMP_CLAUSE_DEFAULT_NONE,
   OMP_CLAUSE_DEFAULT_PRIVATE,
-  OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
+  OMP_CLAUSE_DEFAULT_FIRSTPRIVATE,
+  OMP_CLAUSE_DEFAULT_LAST
 };
 
 /* There is a TYPE_QUAL value for each type qualifier.  They can be
@@ -1107,7 +1109,8 @@  enum omp_clause_depend_kind
 {
   OMP_CLAUSE_DEPEND_IN,
   OMP_CLAUSE_DEPEND_OUT,
-  OMP_CLAUSE_DEPEND_INOUT
+  OMP_CLAUSE_DEPEND_INOUT,
+  OMP_CLAUSE_DEPEND_LAST
 };
 
 enum omp_clause_map_kind
@@ -1119,7 +1122,8 @@  enum omp_clause_map_kind
   /* The following kind is an internal only map kind, used for pointer based
      array sections.  OMP_CLAUSE_SIZE for these is not the pointer size,
      which is implicitly POINTER_SIZE / BITS_PER_UNIT, but the bias.  */
-  OMP_CLAUSE_MAP_POINTER
+  OMP_CLAUSE_MAP_POINTER,
+  OMP_CLAUSE_MAP_LAST
 };
 
 enum omp_clause_proc_bind_kind
@@ -1129,7 +1133,8 @@  enum omp_clause_proc_bind_kind
   OMP_CLAUSE_PROC_BIND_TRUE = 1,
   OMP_CLAUSE_PROC_BIND_MASTER = 2,
   OMP_CLAUSE_PROC_BIND_CLOSE = 3,
-  OMP_CLAUSE_PROC_BIND_SPREAD = 4
+  OMP_CLAUSE_PROC_BIND_SPREAD = 4,
+  OMP_CLAUSE_PROC_BIND_LAST
 };
 
 struct GTY(()) tree_exp {
--- gcc/lto-streamer-out.c.jj	2013-11-27 18:02:46.000000000 +0100
+++ gcc/lto-streamer-out.c	2013-11-28 11:51:03.085288356 +0100
@@ -297,7 +297,6 @@  lto_is_streamable (tree expr)
 	 && code != BIND_EXPR
 	 && code != WITH_CLEANUP_EXPR
 	 && code != STATEMENT_LIST
-	 && code != OMP_CLAUSE
 	 && (code == CASE_LABEL_EXPR
 	     || code == DECL_EXPR
 	     || TREE_CODE_CLASS (code) != tcc_statement);
@@ -667,6 +666,14 @@  DFS_write_tree_body (struct output_block
 	}
     }
 
+  if (code == OMP_CLAUSE)
+    {
+      int i;
+      for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
+	DFS_follow_tree_edge (OMP_CLAUSE_OPERAND (expr, i));
+      DFS_follow_tree_edge (OMP_CLAUSE_CHAIN (expr));
+    }
+
 #undef DFS_follow_tree_edge
 }
 
--- gcc/tree-streamer-out.c.jj	2013-11-22 21:03:16.000000000 +0100
+++ gcc/tree-streamer-out.c	2013-11-28 11:49:49.327672855 +0100
@@ -390,6 +390,46 @@  pack_ts_optimization (struct bitpack_d *
 }
 
 
+/* Pack all the non-pointer fields of the TS_OMP_CLAUSE structure
+   of expression EXPR into bitpack BP.  */
+
+static void
+pack_ts_omp_clause_value_fields (struct output_block *ob,
+				 struct bitpack_d *bp, tree expr)
+{
+  stream_output_location (ob, bp, OMP_CLAUSE_LOCATION (expr));
+  switch (OMP_CLAUSE_CODE (expr))
+    {
+    case OMP_CLAUSE_DEFAULT:
+      bp_pack_enum (bp, omp_clause_default_kind, OMP_CLAUSE_DEFAULT_LAST,
+		    OMP_CLAUSE_DEFAULT_KIND (expr));
+      break;
+    case OMP_CLAUSE_SCHEDULE:
+      bp_pack_enum (bp, omp_clause_schedule_kind, OMP_CLAUSE_SCHEDULE_LAST,
+		    OMP_CLAUSE_SCHEDULE_KIND (expr));
+      break;
+    case OMP_CLAUSE_DEPEND:
+      bp_pack_enum (bp, omp_clause_depend_kind, OMP_CLAUSE_DEPEND_LAST,
+		    OMP_CLAUSE_DEPEND_KIND (expr));
+      break;
+    case OMP_CLAUSE_MAP:
+      bp_pack_enum (bp, omp_clause_map_kind, OMP_CLAUSE_MAP_LAST,
+		    OMP_CLAUSE_MAP_KIND (expr));
+      break;
+    case OMP_CLAUSE_PROC_BIND:
+      bp_pack_enum (bp, omp_clause_proc_bind_kind, OMP_CLAUSE_PROC_BIND_LAST,
+		    OMP_CLAUSE_PROC_BIND_KIND (expr));
+      break;
+    case OMP_CLAUSE_REDUCTION:
+      bp_pack_enum (bp, tree_code, MAX_TREE_CODES,
+		    OMP_CLAUSE_REDUCTION_CODE (expr));
+      break;
+    default:
+      break;
+    }
+}
+
+
 /* Pack all the bitfields in EXPR into a bit pack.  */
 
 void
@@ -451,6 +491,9 @@  streamer_pack_tree_bitfields (struct out
 
   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
     bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr));
+
+  if (code == OMP_CLAUSE)
+    pack_ts_omp_clause_value_fields (ob, bp, expr);
 }
 
 
@@ -853,6 +896,29 @@  write_ts_constructor_tree_pointers (stru
     }
 }
 
+
+/* Write all pointer fields in the TS_OMP_CLAUSE structure of EXPR
+   to output block OB.  If REF_P is true, write a reference to EXPR's
+   pointer fields.  */
+
+static void
+write_ts_omp_clause_tree_pointers (struct output_block *ob, tree expr,
+				   bool ref_p)
+{
+  int i;
+  for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
+    stream_write_tree (ob, OMP_CLAUSE_OPERAND (expr, i), ref_p);
+  if (OMP_CLAUSE_CODE (expr) == OMP_CLAUSE_REDUCTION)
+    {
+      /* We don't stream these right now, handle it if streaming
+	 of them is needed.  */
+      gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (expr) == NULL);
+      gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (expr) == NULL);
+    }
+  stream_write_tree (ob, OMP_CLAUSE_CHAIN (expr), ref_p);
+}
+
+
 /* Write all pointer fields in EXPR to output block OB.  If REF_P is true,
    the leaves of EXPR are emitted as references.  */
 
@@ -915,6 +981,9 @@  streamer_write_tree_body (struct output_
 
   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
     write_ts_constructor_tree_pointers (ob, expr, ref_p);
+
+  if (code == OMP_CLAUSE)
+    write_ts_omp_clause_tree_pointers (ob, expr, ref_p);
 }
 
 
@@ -963,6 +1032,8 @@  streamer_write_tree_header (struct outpu
     streamer_write_uhwi (ob, BINFO_N_BASE_BINFOS (expr));
   else if (TREE_CODE (expr) == CALL_EXPR)
     streamer_write_uhwi (ob, call_expr_nargs (expr));
+  else if (TREE_CODE (expr) == OMP_CLAUSE)
+    streamer_write_uhwi (ob, OMP_CLAUSE_CODE (expr));
 }
 
 
--- gcc/tree-streamer-in.c.jj	2013-11-22 21:03:16.000000000 +0100
+++ gcc/tree-streamer-in.c	2013-11-28 11:49:42.437709308 +0100
@@ -425,6 +425,48 @@  unpack_ts_optimization (struct bitpack_d
 }
 
 
+/* Unpack all the non-pointer fields of the TS_OMP_CLAUSE
+   structure of expression EXPR from bitpack BP.  */
+
+static void
+unpack_ts_omp_clause_value_fields (struct data_in *data_in,
+				   struct bitpack_d *bp, tree expr)
+{
+  OMP_CLAUSE_LOCATION (expr) = stream_input_location (bp, data_in);
+  switch (OMP_CLAUSE_CODE (expr))
+    {
+    case OMP_CLAUSE_DEFAULT:
+      OMP_CLAUSE_DEFAULT_KIND (expr)
+	= bp_unpack_enum (bp, omp_clause_default_kind,
+			  OMP_CLAUSE_DEFAULT_LAST);
+      break;
+    case OMP_CLAUSE_SCHEDULE:
+      OMP_CLAUSE_SCHEDULE_KIND (expr)
+	= bp_unpack_enum (bp, omp_clause_schedule_kind,
+			  OMP_CLAUSE_SCHEDULE_LAST);
+      break;
+    case OMP_CLAUSE_DEPEND:
+      OMP_CLAUSE_DEPEND_KIND (expr)
+	= bp_unpack_enum (bp, omp_clause_depend_kind, OMP_CLAUSE_DEPEND_LAST);
+      break;
+    case OMP_CLAUSE_MAP:
+      OMP_CLAUSE_MAP_KIND (expr)
+	= bp_unpack_enum (bp, omp_clause_map_kind, OMP_CLAUSE_MAP_LAST);
+      break;
+    case OMP_CLAUSE_PROC_BIND:
+      OMP_CLAUSE_PROC_BIND_KIND (expr)
+	= bp_unpack_enum (bp, omp_clause_proc_bind_kind,
+			  OMP_CLAUSE_PROC_BIND_LAST);
+      break;
+    case OMP_CLAUSE_REDUCTION:
+      OMP_CLAUSE_REDUCTION_CODE (expr)
+	= bp_unpack_enum (bp, tree_code, MAX_TREE_CODES);
+      break;
+    default:
+      break;
+    }
+}
+
 /* Unpack all the non-pointer fields in EXPR into a bit pack.  */
 
 static void
@@ -493,6 +535,9 @@  unpack_value_fields (struct data_in *dat
       if (length > 0)
 	vec_safe_grow (CONSTRUCTOR_ELTS (expr), length);
     }
+
+  if (code == OMP_CLAUSE)
+    unpack_ts_omp_clause_value_fields (data_in, bp, expr);
 }
 
 
@@ -578,6 +623,12 @@  streamer_alloc_tree (struct lto_input_bl
       unsigned HOST_WIDE_INT nargs = streamer_read_uhwi (ib);
       return build_vl_exp (CALL_EXPR, nargs + 3);
     }
+  else if (code == OMP_CLAUSE)
+    {
+      enum omp_clause_code subcode
+	= (enum omp_clause_code) streamer_read_uhwi (ib);
+      return build_omp_clause (UNKNOWN_LOCATION, subcode);
+    }
   else
     {
       /* For all other nodes, materialize the tree with a raw
@@ -960,6 +1011,22 @@  lto_input_ts_constructor_tree_pointers (
 }
 
 
+/* Read all pointer fields in the TS_OMP_CLAUSE structure of EXPR from
+   input block IB.  DATA_IN contains tables and descriptors for the
+   file being read.  */
+
+static void
+lto_input_ts_omp_clause_tree_pointers (struct lto_input_block *ib,
+				       struct data_in *data_in, tree expr)
+{
+  int i;
+
+  for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
+    OMP_CLAUSE_OPERAND (expr, i) = stream_read_tree (ib, data_in);
+  OMP_CLAUSE_CHAIN (expr) = stream_read_tree (ib, data_in);
+}
+
+
 /* Read all pointer fields in EXPR from input block IB.  DATA_IN
    contains tables and descriptors for the file being read.  */
 
@@ -1021,6 +1088,9 @@  streamer_read_tree_body (struct lto_inpu
 
   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
     lto_input_ts_constructor_tree_pointers (ib, data_in, expr);
+
+  if (code == OMP_CLAUSE)
+    lto_input_ts_omp_clause_tree_pointers (ib, data_in, expr);
 }
 
 
--- gcc/lto/lto.c.jj	2013-11-22 21:03:14.000000000 +0100
+++ gcc/lto/lto.c	2013-11-28 11:58:15.597048439 +0100
@@ -904,6 +904,19 @@  mentions_vars_p_expr (tree t)
   return false;
 }
 
+/* Check presence of pointers to decls in fields of an OMP_CLAUSE T.  */
+
+static bool
+mentions_vars_p_omp_clause (tree t)
+{
+  int i;
+  if (mentions_vars_p_common (t))
+    return true;
+  for (i = omp_clause_num_ops[OMP_CLAUSE_CODE (t)] - 1; i >= 0; --i)
+    CHECK_VAR (OMP_CLAUSE_OPERAND (t, i));
+  return false;
+}
+
 /* Check presence of pointers to decls that needs later fixup in T.  */
 
 static bool
@@ -922,7 +935,6 @@  mentions_vars_p (tree t)
 
     case FIELD_DECL:
       return mentions_vars_p_field_decl (t);
-      break;
 
     case LABEL_DECL:
     case CONST_DECL:
@@ -931,27 +943,21 @@  mentions_vars_p (tree t)
     case IMPORTED_DECL:
     case NAMESPACE_DECL:
       return mentions_vars_p_decl_common (t);
-      break;
 
     case VAR_DECL:
       return mentions_vars_p_decl_with_vis (t);
-      break;
 
     case TYPE_DECL:
       return mentions_vars_p_decl_non_common (t);
-      break;
 
     case FUNCTION_DECL:
       return mentions_vars_p_function (t);
-      break;
 
     case TREE_BINFO:
       return mentions_vars_p_binfo (t);
-      break;
 
     case PLACEHOLDER_EXPR:
       return mentions_vars_p_common (t);
-      break;
 
     case BLOCK:
     case TRANSLATION_UNIT_DECL:
@@ -961,7 +967,9 @@  mentions_vars_p (tree t)
 
     case CONSTRUCTOR:
       return mentions_vars_p_constructor (t);
-      break;
+
+    case OMP_CLAUSE:
+      return mentions_vars_p_omp_clause (t);
 
     default:
       if (TYPE_P (t))