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 <ja...@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 > > -- Richard Biener <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imend"orffer