From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11513 invoked by alias); 15 Jun 2011 00:21:15 -0000 Received: (qmail 11495 invoked by uid 22791); 15 Jun 2011 00:21:12 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,SPF_HELO_PASS,TW_TJ,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.44.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 15 Jun 2011 00:20:53 +0000 Received: from wpaz33.hot.corp.google.com (wpaz33.hot.corp.google.com [172.24.198.97]) by smtp-out.google.com with ESMTP id p5F0KpJo025104; Tue, 14 Jun 2011 17:20:51 -0700 Received: from jade.mtv.corp.google.com (jade.mtv.corp.google.com [172.18.110.116]) by wpaz33.hot.corp.google.com with ESMTP id p5F0Kh8N015561; Tue, 14 Jun 2011 17:20:43 -0700 Received: by jade.mtv.corp.google.com (Postfix, from userid 21482) id 5DD4C22265C; Tue, 14 Jun 2011 17:20:38 -0700 (PDT) To: reply@codereview.appspotmail.com, dnovillo@google.com, gcc-patches@gcc.gnu.org Subject: Stream struct function. (issue4620043) Message-Id: <20110615002038.5DD4C22265C@jade.mtv.corp.google.com> Date: Wed, 15 Jun 2011 00:47:00 -0000 From: crowl@google.com (Lawrence Crowl) X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-06/txt/msg01130.txt.bz2 Save the DECL_STRUCT_FUNCTION(...) field of FUNCTION_DECL. This change factors common functionality with the LTO streamer. Index: gcc/testsuite/ChangeLog.pph 2011-06-14 Lawrence Crowl * g++.dg/pph/x1tmplfunc.cc: Replace ICE xfail with an assembly diff xfail. Index: gcc/cp/ChangeLog.pph 2011-06-14 Lawrence Crowl * pph-streamer-out.c (pph_out_struct_function): New. (pph_out_used_types_slot): New for pph_out_struct_function. (struct pph_tree_info): New for pph_out_struct_function. (pph_write_tree): Save DECL_STRUCT_FUNCTION of FUNCTION_DECL with pph_out_struct_function. * pph-streamer-in.c (pph_in_struct_function): New. (pph_read_tree): Load DECL_STRUCT_FUNCTION of FUNCTION_DECL with pph_in_struct_function. Index: gcc/ChangeLog.pph 2011-06-14 Lawrence Crowl * lto-streamer.h (extern output_struct_function_base): New. (extern input_struct_function_base): New. * lto-streamer-out.c (lto_output_ts_function_decl_tree_pointers): Update comment. (output_struct_function_base): New. (output_function): Factor out code common with PPH into output_struct_function_base. * lto-streamer-in.c (input_struct_function_base): New. (input_function): Factor out common code with PPH into input_struct_function_base. Index: gcc/testsuite/g++.dg/pph/x1tmplfunc.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x1tmplfunc.cc (revision 175056) +++ gcc/testsuite/g++.dg/pph/x1tmplfunc.cc (working copy) @@ -1,6 +1,4 @@ -// { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } } -// { dg-bogus "x1tmplfunc.h:8:16: internal compiler error: Segmentation fault" "" { xfail *-*-* } 0 } -// { dg-prune-output "In file included from " } +// pph asm xdiff #include "x1tmplfunc.h" Index: gcc/cp/pph-streamer-in.c =================================================================== --- gcc/cp/pph-streamer-in.c (revision 175056) +++ gcc/cp/pph-streamer-in.c (working copy) @@ -608,6 +608,88 @@ pph_in_ld_fn (pph_stream *stream, struct } +/* Read applicable fields of struct function instance FN from STREAM. */ + +static struct function * +pph_in_struct_function (pph_stream *stream) +{ + size_t count, i; + unsigned ix; + enum pph_record_marker marker; + struct function *fn; + + gcc_assert (stream->data_in != NULL); + + marker = pph_start_record (stream, &ix); + if (marker == PPH_RECORD_END) + return NULL; + + /* Since struct function is embedded in every decl, fn cannot be shared. */ + gcc_assert (marker != PPH_RECORD_SHARED); + + fn = ggc_alloc_cleared_function (); + + input_struct_function_base (fn, stream->data_in, stream->ib); + + /* struct eh_status *eh; -- zero init */ + /* struct control_flow_graph *cfg; -- zero init */ + /* struct gimple_seq_d *gimple_body; -- zero init */ + /* struct gimple_df *gimple_df; -- zero init */ + /* struct loops *x_current_loops; -- zero init */ + /* struct stack_usage *su; -- zero init */ + /* htab_t value_histograms; -- zero init */ + /* tree decl; -- zero init */ + /* tree static_chain_decl; -- in base */ + /* tree nonlocal_goto_save_area; -- in base */ + /* tree local_decls; -- in base */ + /* struct machine_function * machine; -- zero init */ + + fn->language = pph_in_language_function (stream); + + count = pph_in_uint (stream); + if ( count > 0 ) + { + fn->used_types_hash = htab_create_ggc (37, htab_hash_pointer, + htab_eq_pointer, NULL); + for (i = 0; i < count; i++) + { + void **slot; + tree type = pph_in_tree (stream); + slot = htab_find_slot (fn->used_types_hash, type, INSERT); + if (*slot == NULL) + *slot = type; + } + } + /* else zero initialized */ + + /* int last_stmt_uid; -- zero init */ + /* int funcdef_no; -- zero init */ + /* location_t function_start_locus; -- in base */ + /* location_t function_end_locus; -- in base */ + /* unsigned int curr_properties; -- in base */ + /* unsigned int last_verified; -- zero init */ + /* const char *cannot_be_copied_reason; -- zero init */ + + /* unsigned int va_list_gpr_size : 8; -- in base */ + /* unsigned int va_list_fpr_size : 8; -- in base */ + /* unsigned int calls_setjmp : 1; -- in base */ + /* unsigned int calls_alloca : 1; -- in base */ + /* unsigned int has_nonlocal_label : 1; -- in base */ + /* unsigned int cannot_be_copied_set : 1; -- zero init */ + /* unsigned int stdarg : 1; -- in base */ + /* unsigned int after_inlining : 1; -- in base */ + /* unsigned int always_inline_functions_inlined : 1; -- in base */ + /* unsigned int can_throw_non_call_exceptions : 1; -- in base */ + /* unsigned int returns_struct : 1; -- in base */ + /* unsigned int returns_pcc_struct : 1; -- in base */ + /* unsigned int after_tree_profile : 1; -- in base */ + /* unsigned int has_local_explicit_reg_vars : 1; -- in base */ + /* unsigned int is_thunk : 1; -- in base */ + + return fn; +} + + /* Read all the fields of lang_decl_ns instance LDNS from STREAM. */ static void @@ -932,6 +1014,7 @@ pph_read_tree (struct lto_input_block *i DECL_INITIAL (expr) = pph_in_tree (stream); pph_in_lang_specific (stream, expr); DECL_SAVED_TREE (expr) = pph_in_tree (stream); + DECL_STRUCT_FUNCTION (expr) = pph_in_struct_function (stream); break; case TYPE_DECL: Index: gcc/cp/pph-streamer-out.c =================================================================== --- gcc/cp/pph-streamer-out.c (revision 175056) +++ gcc/cp/pph-streamer-out.c (working copy) @@ -599,6 +599,89 @@ pph_out_ld_fn (pph_stream *stream, struc } +/* A callback of htab_traverse. Just extracts a (type) tree from SLOT + and writes it out for PPH. */ + +struct pph_tree_info { + pph_stream *stream; + bool ref_p; +}; + +static int +pph_out_used_types_slot (void **slot, void *aux) +{ + struct pph_tree_info *pti = (struct pph_tree_info *)aux; + pph_out_tree_or_ref (pti->stream, (tree) *slot, pti->ref_p); + return 1; +} + + +/* Write applicable fields of struct function instance FN to STREAM. + If REF_P is true, all tree fields should be written as references. */ + +static void +pph_out_struct_function (pph_stream *stream, struct function *fn, bool ref_p) +{ + struct pph_tree_info pti; + + if (!pph_start_record (stream, fn)) + return; + + output_struct_function_base (stream->ob, fn); + + /* struct eh_status *eh; -- ignored */ + gcc_assert (fn->cfg == NULL); + gcc_assert (fn->gimple_body == NULL); + gcc_assert (fn->gimple_df == NULL); + gcc_assert (fn->x_current_loops == NULL); + gcc_assert (fn->su == NULL); + /* htab_t value_histograms; -- ignored */ + /* tree decl; -- ignored */ + /* tree static_chain_decl; -- in base */ + /* tree nonlocal_goto_save_area; -- in base */ + /* VEC(tree,gc) *local_decls; -- in base */ + /* struct machine_function *machine; -- ignored */ + pph_out_language_function (stream, fn->language, ref_p); + + /*FIXME pph: We would like to detect improper sharing here. */ + if (fn->used_types_hash) + { + /*FIXME pph: This write may be unstable. */ + pph_out_uint (stream, htab_elements (fn->used_types_hash)); + pti.stream = stream; + pti.ref_p = ref_p; + htab_traverse_noresize (fn->used_types_hash, + pph_out_used_types_slot, &pti); + } + else + pph_out_uint (stream, 0); + + gcc_assert (fn->last_stmt_uid == 0); + /* int funcdef_no; -- ignored */ + /* location_t function_start_locus; -- in base */ + /* location_t function_end_locus; -- in base */ + /* unsigned int curr_properties; -- in base */ + /* unsigned int last_verified; -- ignored */ + /* const char *cannot_be_copied_reason; -- ignored */ + + /* unsigned int va_list_gpr_size : 8; -- in base */ + /* unsigned int va_list_fpr_size : 8; -- in base */ + /* unsigned int calls_setjmp : 1; -- in base */ + /* unsigned int calls_alloca : 1; -- in base */ + /* unsigned int has_nonlocal_label : 1; -- in base */ + /* unsigned int cannot_be_copied_set : 1; -- ignored */ + /* unsigned int stdarg : 1; -- in base */ + /* unsigned int after_inlining : 1; -- in base */ + /* unsigned int always_inline_functions_inlined : 1; -- in base */ + /* unsigned int can_throw_non_call_exceptions : 1; -- in base */ + /* unsigned int returns_struct : 1; -- in base */ + /* unsigned int returns_pcc_struct : 1; -- in base */ + /* unsigned int after_tree_profile : 1; -- in base */ + /* unsigned int has_local_explicit_reg_vars : 1; -- in base */ + /* unsigned int is_thunk : 1; -- in base */ +} + + /* Write all the fields of lang_decl_ns instance LDNS to STREAM. If REF_P is true, all tree fields should be written as references. */ @@ -883,6 +966,7 @@ pph_write_tree (struct output_block *ob, pph_out_tree_or_ref_1 (stream, DECL_INITIAL (expr), ref_p, 3); pph_out_lang_specific (stream, expr, ref_p); pph_out_tree_or_ref_1 (stream, DECL_SAVED_TREE (expr), ref_p, 3); + pph_out_struct_function (stream, DECL_STRUCT_FUNCTION (expr), ref_p); break; case TYPE_DECL: Index: gcc/lto-streamer-out.c =================================================================== --- gcc/lto-streamer-out.c (revision 175056) +++ gcc/lto-streamer-out.c (working copy) @@ -967,8 +967,8 @@ static void lto_output_ts_function_decl_tree_pointers (struct output_block *ob, tree expr, bool ref_p) { - /* DECL_STRUCT_FUNCTION is handled by lto_output_function. FIXME lto, - maybe it should be handled here? */ + /* DECL_STRUCT_FUNCTION is handled by lto_streamer-out.c:output_function + or by pph-specific code. */ lto_output_tree_or_ref (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p); lto_output_tree_or_ref (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p); lto_output_tree_or_ref (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr), @@ -1974,36 +1974,48 @@ produce_asm (struct output_block *ob, tr } -/* Output the body of function NODE->DECL. */ +/* Output the base body of struct function FN using output block OB. */ -static void -output_function (struct cgraph_node *node) +void +output_struct_function_base (struct output_block *ob, struct function *fn) { struct bitpack_d bp; - tree function; - struct function *fn; - basic_block bb; - struct output_block *ob; unsigned i; tree t; - function = node->decl; - fn = DECL_STRUCT_FUNCTION (function); - ob = create_output_block (LTO_section_function_body); + /* struct eh_status *eh; -- maybe elsewhere */ + /* struct control_flow_graph *cfg; -- maybe elsewhere */ + /* struct gimple_seq_d *gimple_body; -- maybe elsewhere */ + /* struct gimple_df *gimple_df; -- maybe elsewhere */ + /* struct loops *x_current_loops; -- maybe elsewhere */ + /* struct stack_usage *su; -- maybe elsewhere */ + /* htab_t value_histograms; -- ignored */ + /* tree decl; -- ignored */ - clear_line_info (ob); - ob->cgraph_node = node; + /* Output the static chain and non-local goto save area. */ + lto_output_tree_ref (ob, fn->static_chain_decl); + lto_output_tree_ref (ob, fn->nonlocal_goto_save_area); - gcc_assert (current_function_decl == NULL_TREE && cfun == NULL); + /* Output all the local variables in the function. */ + output_sleb128 (ob, VEC_length (tree, fn->local_decls)); + FOR_EACH_VEC_ELT (tree, fn->local_decls, i, t) + lto_output_tree_ref (ob, t); - /* Set current_function_decl and cfun. */ - current_function_decl = function; - push_cfun (fn); + /* struct machine_function * machine; -- ignored */ + /* struct language_function * language; -- maybe elsewhere */ + /* htab_t used_types_hash; -- maybe elsewhere */ + /* int last_stmt_uid; -- maybe elsewhere */ + /* int funcdef_no; -- maybe elsewhere */ - /* Make string 0 be a NULL string. */ - lto_output_1_stream (ob->string_stream, 0); + /* Output the function start and end loci. */ + lto_output_location (ob, fn->function_start_locus); + lto_output_location (ob, fn->function_end_locus); - output_record_start (ob, LTO_function); + /* Output current IL state of the function. */ + output_uleb128 (ob, fn->curr_properties); + + /* unsigned int last_verified; -- ignored */ + /* const char *cannot_be_copied_reason; -- ignored */ /* Write all the attributes for FN. */ bp = bitpack_create (ob->main_stream); @@ -2016,28 +2028,45 @@ output_function (struct cgraph_node *nod bp_pack_value (&bp, fn->always_inline_functions_inlined, 1); bp_pack_value (&bp, fn->after_inlining, 1); bp_pack_value (&bp, fn->stdarg, 1); + /* unsigned int cannot_be_copied_set : 1; -- ignored */ bp_pack_value (&bp, fn->has_nonlocal_label, 1); bp_pack_value (&bp, fn->calls_alloca, 1); bp_pack_value (&bp, fn->calls_setjmp, 1); bp_pack_value (&bp, fn->va_list_fpr_size, 8); bp_pack_value (&bp, fn->va_list_gpr_size, 8); lto_output_bitpack (&bp); +} - /* Output the function start and end loci. */ - lto_output_location (ob, fn->function_start_locus); - lto_output_location (ob, fn->function_end_locus); - /* Output current IL state of the function. */ - output_uleb128 (ob, fn->curr_properties); +/* Output the body of function NODE->DECL. */ - /* Output the static chain and non-local goto save area. */ - lto_output_tree_ref (ob, fn->static_chain_decl); - lto_output_tree_ref (ob, fn->nonlocal_goto_save_area); +static void +output_function (struct cgraph_node *node) +{ + tree function; + struct function *fn; + basic_block bb; + struct output_block *ob; - /* Output all the local variables in the function. */ - output_sleb128 (ob, VEC_length (tree, fn->local_decls)); - FOR_EACH_VEC_ELT (tree, fn->local_decls, i, t) - lto_output_tree_ref (ob, t); + function = node->decl; + fn = DECL_STRUCT_FUNCTION (function); + ob = create_output_block (LTO_section_function_body); + + clear_line_info (ob); + ob->cgraph_node = node; + + gcc_assert (current_function_decl == NULL_TREE && cfun == NULL); + + /* Set current_function_decl and cfun. */ + current_function_decl = function; + push_cfun (fn); + + /* Make string 0 be a NULL string. */ + lto_output_1_stream (ob->string_stream, 0); + + output_record_start (ob, LTO_function); + + output_struct_function_base (ob, fn); /* Output the head of the arguments list. */ lto_output_tree_ref (ob, DECL_ARGUMENTS (function)); Index: gcc/lto-streamer-in.c =================================================================== --- gcc/lto-streamer-in.c (revision 175056) +++ gcc/lto-streamer-in.c (working copy) @@ -1242,27 +1242,55 @@ fixup_call_stmt_edges (struct cgraph_nod } } -/* Read the body of function FN_DECL from DATA_IN using input block IB. */ -static void -input_function (tree fn_decl, struct data_in *data_in, - struct lto_input_block *ib) +/* Input the base body of struct function FN from DATA_IN + using input block IB. */ + +void +input_struct_function_base (struct function *fn, struct data_in *data_in, + struct lto_input_block *ib) { - struct function *fn; - enum LTO_tags tag; - gimple *stmts; - basic_block bb; struct bitpack_d bp; - struct cgraph_node *node; - tree args, narg, oarg; int len; - fn = DECL_STRUCT_FUNCTION (fn_decl); - tag = input_record_start (ib); - clear_line_info (data_in); + /* struct eh_status *eh; -- maybe elsewhere */ + /* struct control_flow_graph *cfg; -- maybe elsewhere */ + /* struct gimple_seq_d *gimple_body; -- maybe elsewhere */ + /* struct gimple_df *gimple_df; -- maybe elsewhere */ + /* struct loops *x_current_loops; -- maybe elsewhere */ + /* struct stack_usage *su; -- maybe elsewhere */ + /* htab_t value_histograms; -- ignored */ + /* tree decl; -- ignored */ - gimple_register_cfg_hooks (); - lto_tag_check (tag, LTO_function); + /* Read the static chain and non-local goto save area. */ + fn->static_chain_decl = lto_input_tree (ib, data_in); + fn->nonlocal_goto_save_area = lto_input_tree (ib, data_in); + + /* Read all the local symbols. */ + len = lto_input_sleb128 (ib); + if (len > 0) + { + int i; + VEC_safe_grow (tree, gc, fn->local_decls, len); + for (i = 0; i < len; i++) + { + tree t = lto_input_tree (ib, data_in); + VEC_replace (tree, fn->local_decls, i, t); + } + } + + /* struct machine_function * machine; -- ignored */ + /* struct language_function * language; -- maybe elsewhere */ + /* htab_t used_types_hash; -- maybe elsewhere */ + /* int last_stmt_uid; -- maybe elsewhere */ + /* int funcdef_no; -- maybe elsewhere */ + + /* Input the function start and end loci. */ + fn->function_start_locus = lto_input_location (ib, data_in); + fn->function_end_locus = lto_input_location (ib, data_in); + + /* Input the current IL state of the function. */ + fn->curr_properties = lto_input_uleb128 (ib); /* Read all the attributes for FN. */ bp = lto_input_bitpack (ib); @@ -1280,30 +1308,30 @@ input_function (tree fn_decl, struct dat fn->calls_setjmp = bp_unpack_value (&bp, 1); fn->va_list_fpr_size = bp_unpack_value (&bp, 8); fn->va_list_gpr_size = bp_unpack_value (&bp, 8); +} - /* Input the function start and end loci. */ - fn->function_start_locus = lto_input_location (ib, data_in); - fn->function_end_locus = lto_input_location (ib, data_in); - /* Input the current IL state of the function. */ - fn->curr_properties = lto_input_uleb128 (ib); +/* Read the body of function FN_DECL from DATA_IN using input block IB. */ - /* Read the static chain and non-local goto save area. */ - fn->static_chain_decl = lto_input_tree (ib, data_in); - fn->nonlocal_goto_save_area = lto_input_tree (ib, data_in); +static void +input_function (tree fn_decl, struct data_in *data_in, + struct lto_input_block *ib) +{ + struct function *fn; + enum LTO_tags tag; + gimple *stmts; + basic_block bb; + struct cgraph_node *node; + tree args, narg, oarg; - /* Read all the local symbols. */ - len = lto_input_sleb128 (ib); - if (len > 0) - { - int i; - VEC_safe_grow (tree, gc, fn->local_decls, len); - for (i = 0; i < len; i++) - { - tree t = lto_input_tree (ib, data_in); - VEC_replace (tree, fn->local_decls, i, t); - } - } + fn = DECL_STRUCT_FUNCTION (fn_decl); + tag = input_record_start (ib); + clear_line_info (data_in); + + gimple_register_cfg_hooks (); + lto_tag_check (tag, LTO_function); + + input_struct_function_base (fn, data_in, ib); /* Read all function arguments. We need to re-map them here to the arguments of the merged function declaration. */ Index: gcc/lto-streamer.h =================================================================== --- gcc/lto-streamer.h (revision 175056) +++ gcc/lto-streamer.h (working copy) @@ -963,6 +963,9 @@ extern void lto_input_cgraph (struct lto extern void lto_reader_init (void); extern tree lto_input_tree (struct lto_input_block *, struct data_in *); extern tree lto_input_chain (struct lto_input_block *, struct data_in *); +extern void input_struct_function_base (struct function *fn, + struct data_in *data_in, + struct lto_input_block *ib); extern void lto_input_function_body (struct lto_file_decl_data *, tree, const char *); extern void lto_input_constructors_and_inits (struct lto_file_decl_data *, @@ -985,6 +988,8 @@ extern void destroy_output_block (struct extern void lto_output_tree (struct output_block *, tree, bool); extern void lto_output_tree_or_ref (struct output_block *, tree, bool); extern void lto_output_chain (struct output_block *, tree, bool); +extern void output_struct_function_base (struct output_block *ob, + struct function *fn); extern void produce_asm (struct output_block *ob, tree fn); void lto_output_decl_state_streams (struct output_block *, struct lto_out_decl_state *); -- This patch is available for review at http://codereview.appspot.com/4620043