From patchwork Wed Feb 18 10:00:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 440862 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 7E1EA140168 for ; Wed, 18 Feb 2015 21:01:00 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=sI3olN/kWuvI8C+wb 42x89XZ+lzXTOqQeheAYTtg62yq2xTVsL7OP+++nelorP3QampHDssu6QbUho6Le jFTTWDQEdy5H1V+M4LB7rdexmzIzquJc+fZg0HIcEGAaCrvHVOuA5c4PbTxckjiz mL1SIV/KCsdtIFe5Js2hO3+Z0Q= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:references:mime-version :content-type:in-reply-to; s=default; bh=7MDZO9wElzKO+5UavNbJYPS CbAw=; b=gVkYxHA2oWlpkLJg3O8EkyC4vOvqdDGtCNa7+YlNjKhVl2Y531BAxOZ DrwcXc0QYRlHSYn800WHpsqhvdKINaYxDFC26rxtA3d9qlU8pg4ShpRvkelC8Vy0 1T1CJozvnZfYU3LHR+yZyIFjm9Iw3pBgpPW3bDTgysZqfZD5xfJM= Received: (qmail 8808 invoked by alias); 18 Feb 2015 10:00:51 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 7031 invoked by uid 89); 18 Feb 2015 10:00:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 18 Feb 2015 10:00:45 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t1IA0gpI019336 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 18 Feb 2015 05:00:42 -0500 Received: from tucnak.zalov.cz (ovpn-116-28.ams2.redhat.com [10.36.116.28]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t1IA0d3T006684 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Wed, 18 Feb 2015 05:00:40 -0500 Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.14.9/8.14.9) with ESMTP id t1IA0bJE030352; Wed, 18 Feb 2015 11:00:38 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.14.9/8.14.9/Submit) id t1IA0Zim030351; Wed, 18 Feb 2015 11:00:35 +0100 Date: Wed, 18 Feb 2015 11:00:35 +0100 From: Jakub Jelinek To: Richard Biener Cc: Jan Hubicka , Ilya Verbin , Bernd Schmidt , Thomas Schwinge , GCC Patches Subject: Re: nvptx offloading patches [3/n], RFD Message-ID: <20150218100035.GF1746@tucnak.redhat.com> Reply-To: Jakub Jelinek References: <5454CAB9.3040907@codesourcery.com> <20150204113817.GO1746@tucnak.redhat.com> <20150216210812.GO1746@tucnak.redhat.com> <5388429A-DE44-4C08-8A19-D42B6E00C0A6@gmail.com> <20150216214349.GR1746@tucnak.redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes On Tue, Feb 17, 2015 at 11:00:14AM +0100, Richard Biener wrote: > I'm just looking for a way to make this less of a hack (and the LTO IL > less target dependent). Not for GCC 5 for which something like your > patch is probably ok, but for the future. So, given Ilya's and Thomas' testing, is this acceptable for now, and perhaps we can try to do something better for GCC 6? Here is the patch with full ChangeLog: 2015-02-18 Jakub Jelinek * passes.c (ipa_write_summaries_1): Call lto_output_init_mode_table. (ipa_write_optimization_summaries): Likewise. * tree-streamer.h: Include data-streamer.h. (streamer_mode_table): Declare extern variable. (bp_pack_machine_mode, bp_unpack_machine_mode): New inline functions. * lto-streamer-out.c (lto_output_init_mode_table, lto_write_mode_table): New functions. (produce_asm_for_decls): Call lto_write_mode_table when streaming offloading LTO. * lto-section-in.c (lto_section_name): Add "mode_table" entry. (lto_create_simple_input_block): Add mode_table argument to the lto_input_block constructors. * ipa-prop.c (ipa_prop_read_section, read_replacements_section): Likewise. * data-streamer-in.c (string_for_index): Likewise. * ipa-inline-analysis.c (inline_read_section): Likewise. * ipa-icf.c (sem_item_optimizer::read_section): Likewise. * lto-cgraph.c (input_cgraph_opt_section): Likewise. * lto-streamer-in.c (lto_read_body_or_constructor, lto_input_toplevel_asms): Likewise. (lto_input_mode_table): New function. * tree-streamer-out.c (pack_ts_fixed_cst_value_fields, pack_ts_decl_common_value_fields, pack_ts_type_common_value_fields): Use bp_pack_machine_mode. * real.h (struct real_format): Add name field. * lto-streamer.h (enum lto_section_type): Add LTO_section_mode_table. (class lto_input_block): Add mode_table member. (lto_input_block::lto_input_block): Add mode_table_ argument, initialize mode_table. (struct lto_file_decl_data): Add mode_table field. (lto_input_mode_table, lto_output_init_mode_table): New prototypes. * tree-streamer-in.c (unpack_ts_fixed_cst_value_fields, unpack_ts_decl_common_value_fields, unpack_ts_type_common_value_fields): Call bp_unpack_machine_mode. * tree-streamer.c (streamer_mode_table): New variable. * real.c (ieee_single_format, mips_single_format, motorola_single_format, spu_single_format, ieee_double_format, mips_double_format, motorola_double_format, ieee_extended_motorola_format, ieee_extended_intel_96_format, ieee_extended_intel_128_format, ieee_extended_intel_96_round_53_format, ibm_extended_format, mips_extended_format, ieee_quad_format, mips_quad_format, vax_f_format, vax_d_format, vax_g_format, decimal_single_format, decimal_double_format, decimal_quad_format, ieee_half_format, arm_half_format, real_internal_format): Add name field. * config/pdp11/pdp11.c (pdp11_f_format, pdp11_d_format): Likewise. lto/ * lto.c (lto_mode_identity_table): New variable. (lto_read_decls): Add mode_table argument to the lto_input_block constructor. (lto_file_finalize): Initialize mode_table. (lto_init): Initialize lto_mode_identity_table. Jakub --- gcc/passes.c.jj 2015-02-16 22:18:33.219702315 +0100 +++ gcc/passes.c 2015-02-16 22:19:20.842917807 +0100 @@ -2460,6 +2460,7 @@ ipa_write_summaries_1 (lto_symtab_encode struct lto_out_decl_state *state = lto_new_out_decl_state (); state->symtab_node_encoder = encoder; + lto_output_init_mode_table (); lto_push_out_decl_state (state); gcc_assert (!flag_wpa); @@ -2581,6 +2582,7 @@ ipa_write_optimization_summaries (lto_sy lto_symtab_encoder_iterator lsei; state->symtab_node_encoder = encoder; + lto_output_init_mode_table (); lto_push_out_decl_state (state); for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei); lsei_next_function_in_partition (&lsei)) --- gcc/tree-streamer.h.jj 2015-02-16 22:18:33.222702266 +0100 +++ gcc/tree-streamer.h 2015-02-16 22:19:20.843917791 +0100 @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. #include "streamer-hooks.h" #include "lto-streamer.h" +#include "data-streamer.h" #include "hash-map.h" /* Cache of pickled nodes. Used to avoid writing the same node more @@ -91,6 +92,7 @@ void streamer_write_integer_cst (struct void streamer_write_builtin (struct output_block *, tree); /* In tree-streamer.c. */ +extern unsigned char streamer_mode_table[1 << 8]; void streamer_check_handled_ts_structures (void); bool streamer_tree_cache_insert (struct streamer_tree_cache_d *, tree, hashval_t, unsigned *); @@ -119,5 +121,19 @@ streamer_tree_cache_get_hash (struct str return cache->hashes[ix]; } +static inline void +bp_pack_machine_mode (struct bitpack_d *bp, machine_mode mode) +{ + streamer_mode_table[mode] = 1; + bp_pack_enum (bp, machine_mode, 1 << 8, mode); +} + +static inline machine_mode +bp_unpack_machine_mode (struct bitpack_d *bp) +{ + return (machine_mode) + ((struct lto_input_block *) + bp->stream)->mode_table[bp_unpack_enum (bp, machine_mode, 1 << 8)]; +} #endif /* GCC_TREE_STREAMER_H */ --- gcc/lto-streamer-out.c.jj 2015-02-16 22:18:33.204702562 +0100 +++ gcc/lto-streamer-out.c 2015-02-16 22:20:06.659163066 +0100 @@ -2642,6 +2642,96 @@ produce_symtab (struct output_block *ob) } +/* Init the streamer_mode_table for output, where we collect info on what + machine_mode values have been streamed. */ +void +lto_output_init_mode_table (void) +{ + memset (streamer_mode_table, '\0', MAX_MACHINE_MODE); +} + + +/* Write the mode table. */ +static void +lto_write_mode_table (void) +{ + struct output_block *ob; + ob = create_output_block (LTO_section_mode_table); + bitpack_d bp = bitpack_create (ob->main_stream); + + /* Ensure that for GET_MODE_INNER (m) != VOIDmode we have + also the inner mode marked. */ + for (int i = 0; i < (int) MAX_MACHINE_MODE; i++) + if (streamer_mode_table[i]) + { + machine_mode m = (machine_mode) i; + if (GET_MODE_INNER (m) != VOIDmode) + streamer_mode_table[(int) GET_MODE_INNER (m)] = 1; + } + /* First stream modes that have GET_MODE_INNER (m) == VOIDmode, + so that we can refer to them afterwards. */ + for (int pass = 0; pass < 2; pass++) + for (int i = 0; i < (int) MAX_MACHINE_MODE; i++) + if (streamer_mode_table[i] && i != (int) VOIDmode && i != (int) BLKmode) + { + machine_mode m = (machine_mode) i; + if ((GET_MODE_INNER (m) == VOIDmode) ^ (pass == 0)) + continue; + bp_pack_value (&bp, m, 8); + bp_pack_enum (&bp, mode_class, MAX_MODE_CLASS, GET_MODE_CLASS (m)); + bp_pack_value (&bp, GET_MODE_SIZE (m), 8); + bp_pack_value (&bp, GET_MODE_PRECISION (m), 16); + bp_pack_value (&bp, GET_MODE_INNER (m), 8); + bp_pack_value (&bp, GET_MODE_NUNITS (m), 8); + switch (GET_MODE_CLASS (m)) + { + case MODE_FRACT: + case MODE_UFRACT: + case MODE_ACCUM: + case MODE_UACCUM: + bp_pack_value (&bp, GET_MODE_IBIT (m), 8); + bp_pack_value (&bp, GET_MODE_FBIT (m), 8); + break; + case MODE_FLOAT: + case MODE_DECIMAL_FLOAT: + bp_pack_string (ob, &bp, REAL_MODE_FORMAT (m)->name, true); + break; + default: + break; + } + bp_pack_string (ob, &bp, GET_MODE_NAME (m), true); + } + bp_pack_value (&bp, VOIDmode, 8); + + streamer_write_bitpack (&bp); + + char *section_name + = lto_get_section_name (LTO_section_mode_table, NULL, NULL); + lto_begin_section (section_name, !flag_wpa); + free (section_name); + + /* The entire header stream is computed here. */ + struct lto_simple_header_with_strings header; + memset (&header, 0, sizeof (header)); + + /* Write the header. */ + header.major_version = LTO_major_version; + header.minor_version = LTO_minor_version; + + header.main_size = ob->main_stream->total_size; + header.string_size = ob->string_stream->total_size; + lto_write_data (&header, sizeof header); + + /* Put all of the gimple and the string table out the asm file as a + block of text. */ + lto_write_stream (ob->main_stream); + lto_write_stream (ob->string_stream); + + lto_end_section (); + destroy_output_block (ob); +} + + /* This pass is run after all of the functions are serialized and all of the IPA passes have written their serialized forms. This pass causes the vector of all of the global decls and types used from @@ -2749,4 +2839,6 @@ produce_asm_for_decls (void) lto_symtab_encoder_delete (ob->decl_state->symtab_node_encoder); lto_function_decl_states.release (); destroy_output_block (ob); + if (lto_stream_offload_p) + lto_write_mode_table (); } --- gcc/lto-section-in.c.jj 2015-02-16 22:18:33.202702595 +0100 +++ gcc/lto-section-in.c 2015-02-16 22:19:20.845917758 +0100 @@ -89,7 +89,8 @@ const char *lto_section_name[LTO_N_SECTI "inline", "ipcp_trans", "icf", - "offload_table" + "offload_table", + "mode_table" }; @@ -262,7 +263,8 @@ lto_create_simple_input_block (struct lt return NULL; *datar = data; - return new lto_input_block (data + main_offset, header->main_size); + return new lto_input_block (data + main_offset, header->main_size, + file_data->mode_table); } --- gcc/tree-streamer-out.c.jj 2015-02-16 22:18:33.222702266 +0100 +++ gcc/tree-streamer-out.c 2015-02-16 22:19:20.845917758 +0100 @@ -190,7 +190,7 @@ static void pack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr) { struct fixed_value fv = TREE_FIXED_CST (expr); - bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, fv.mode); + bp_pack_machine_mode (bp, fv.mode); bp_pack_var_len_int (bp, fv.data.low); bp_pack_var_len_int (bp, fv.data.high); } @@ -201,7 +201,7 @@ pack_ts_fixed_cst_value_fields (struct b static void pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) { - bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, DECL_MODE (expr)); + bp_pack_machine_mode (bp, DECL_MODE (expr)); bp_pack_value (bp, DECL_NONLOCAL (expr), 1); bp_pack_value (bp, DECL_VIRTUAL_P (expr), 1); bp_pack_value (bp, DECL_IGNORED_P (expr), 1); @@ -325,7 +325,7 @@ pack_ts_function_decl_value_fields (stru static void pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr) { - bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, TYPE_MODE (expr)); + bp_pack_machine_mode (bp, TYPE_MODE (expr)); bp_pack_value (bp, TYPE_STRING_FLAG (expr), 1); bp_pack_value (bp, TYPE_NO_FORCE_BLK (expr), 1); bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING (expr), 1); --- gcc/real.h.jj 2015-02-16 22:18:33.220702299 +0100 +++ gcc/real.h 2015-02-16 22:19:20.846917741 +0100 @@ -155,6 +155,7 @@ struct real_format bool has_signed_zero; bool qnan_msb_set; bool canonical_nan_lsbs_set; + const char *name; }; --- gcc/lto-streamer.h.jj 2015-02-16 22:18:33.211702447 +0100 +++ gcc/lto-streamer.h 2015-02-16 22:19:20.846917741 +0100 @@ -248,6 +248,7 @@ enum lto_section_type LTO_section_ipcp_transform, LTO_section_ipa_icf, LTO_section_offload_table, + LTO_section_mode_table, LTO_N_SECTION_TYPES /* Must be last. */ }; @@ -312,12 +313,15 @@ class lto_input_block public: /* Special constructor for the string table, it abuses this to do random access but use the uhwi decoder. */ - lto_input_block (const char *data_, unsigned int p_, unsigned int len_) - : data (data_), p (p_), len (len_) {} - lto_input_block (const char *data_, unsigned int len_) - : data (data_), p (0), len (len_) {} + lto_input_block (const char *data_, unsigned int p_, unsigned int len_, + const unsigned char *mode_table_) + : data (data_), mode_table (mode_table_), p (p_), len (len_) {} + lto_input_block (const char *data_, unsigned int len_, + const unsigned char *mode_table_) + : data (data_), mode_table (mode_table_), p (0), len (len_) {} const char *data; + const unsigned char *mode_table; unsigned int p; unsigned int len; }; @@ -527,6 +531,9 @@ struct GTY(()) lto_file_decl_data /* Map assigning declarations their resolutions. */ hash_map * GTY((skip)) resolution_map; + + /* Mode translation table. */ + const unsigned char *mode_table; }; typedef struct lto_file_decl_data *lto_file_decl_data_ptr; @@ -775,6 +782,7 @@ extern void lto_input_variable_construct extern void lto_input_constructors_and_inits (struct lto_file_decl_data *, const char *); extern void lto_input_toplevel_asms (struct lto_file_decl_data *, int); +extern void lto_input_mode_table (struct lto_file_decl_data *); extern struct data_in *lto_data_in_create (struct lto_file_decl_data *, const char *, unsigned, vec ); @@ -807,6 +815,7 @@ void lto_output_decl_state_refs (struct struct lto_output_stream *, struct lto_out_decl_state *); void lto_output_location (struct output_block *, struct bitpack_d *, location_t); +void lto_output_init_mode_table (void); /* In lto-cgraph.c */ --- gcc/ipa-prop.c.jj 2015-02-16 22:18:33.219702315 +0100 +++ gcc/ipa-prop.c 2015-02-16 22:19:20.848917709 +0100 @@ -4868,7 +4868,7 @@ ipa_prop_read_section (struct lto_file_d unsigned int count; lto_input_block ib_main ((const char *) data + main_offset, - header->main_size); + header->main_size, file_data->mode_table); data_in = lto_data_in_create (file_data, (const char *) data + string_offset, @@ -5089,7 +5089,7 @@ read_replacements_section (struct lto_fi unsigned int count; lto_input_block ib_main ((const char *) data + main_offset, - header->main_size); + header->main_size, file_data->mode_table); data_in = lto_data_in_create (file_data, (const char *) data + string_offset, header->string_size, vNULL); --- gcc/data-streamer-in.c.jj 2015-02-16 22:18:33.224702233 +0100 +++ gcc/data-streamer-in.c 2015-02-16 22:19:20.848917709 +0100 @@ -70,7 +70,7 @@ string_for_index (struct data_in *data_i } /* Get the string stored at location LOC in DATA_IN->STRINGS. */ - lto_input_block str_tab (data_in->strings, loc - 1, data_in->strings_len); + lto_input_block str_tab (data_in->strings, loc - 1, data_in->strings_len, NULL); len = streamer_read_uhwi (&str_tab); *rlen = len; --- gcc/tree-streamer-in.c.jj 2015-02-16 22:18:33.220702299 +0100 +++ gcc/tree-streamer-in.c 2015-02-16 22:19:20.849917692 +0100 @@ -224,7 +224,7 @@ static void unpack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr) { FIXED_VALUE_TYPE *fp = ggc_alloc (); - fp->mode = bp_unpack_enum (bp, machine_mode, MAX_MACHINE_MODE); + fp->mode = bp_unpack_machine_mode (bp); fp->data.low = bp_unpack_var_len_int (bp); fp->data.high = bp_unpack_var_len_int (bp); TREE_FIXED_CST_PTR (expr) = fp; @@ -236,7 +236,7 @@ unpack_ts_fixed_cst_value_fields (struct static void unpack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) { - DECL_MODE (expr) = bp_unpack_enum (bp, machine_mode, MAX_MACHINE_MODE); + DECL_MODE (expr) = bp_unpack_machine_mode (bp); DECL_NONLOCAL (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_VIRTUAL_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_IGNORED_P (expr) = (unsigned) bp_unpack_value (bp, 1); @@ -373,7 +373,7 @@ unpack_ts_type_common_value_fields (stru { machine_mode mode; - mode = bp_unpack_enum (bp, machine_mode, MAX_MACHINE_MODE); + mode = bp_unpack_machine_mode (bp); SET_TYPE_MODE (expr, mode); TYPE_STRING_FLAG (expr) = (unsigned) bp_unpack_value (bp, 1); TYPE_NO_FORCE_BLK (expr) = (unsigned) bp_unpack_value (bp, 1); --- gcc/ipa-inline-analysis.c.jj 2015-02-16 22:18:33.223702249 +0100 +++ gcc/ipa-inline-analysis.c 2015-02-16 22:19:20.850917676 +0100 @@ -4190,7 +4190,8 @@ inline_read_section (struct lto_file_dec unsigned int i, count2, j; unsigned int f_count; - lto_input_block ib ((const char *) data + main_offset, header->main_size); + lto_input_block ib ((const char *) data + main_offset, header->main_size, + file_data->mode_table); data_in = lto_data_in_create (file_data, (const char *) data + string_offset, --- gcc/ipa-icf.c.jj 2015-02-16 22:18:33.222702266 +0100 +++ gcc/ipa-icf.c 2015-02-16 22:19:20.851917659 +0100 @@ -1500,7 +1500,7 @@ sem_item_optimizer::read_section (lto_fi unsigned int count; lto_input_block ib_main ((const char *) data + main_offset, 0, - header->main_size); + header->main_size, file_data->mode_table); data_in = lto_data_in_create (file_data, (const char *) data + string_offset, --- gcc/tree-streamer.c.jj 2015-02-16 22:18:33.221702282 +0100 +++ gcc/tree-streamer.c 2015-02-16 22:19:20.853917626 +0100 @@ -53,6 +53,14 @@ along with GCC; see the file COPYING3. #include "cgraph.h" #include "tree-streamer.h" +/* Table indexed by machine_mode, used for 2 different purposes. + During streaming out we record there non-zero value for all modes + that were streamed out. + During streaming in, we translate the on the disk mode using this + table. For normal LTO it is set to identity, for ACCEL_COMPILER + depending on the mode_table content. */ +unsigned char streamer_mode_table[1 << 8]; + /* Check that all the TS_* structures handled by the streamer_write_* and streamer_read_* routines are exactly ALL the structures defined in treestruct.def. */ --- gcc/lto-cgraph.c.jj 2015-02-16 22:18:33.211702447 +0100 +++ gcc/lto-cgraph.c 2015-02-16 22:19:20.855917593 +0100 @@ -2113,7 +2113,7 @@ input_cgraph_opt_section (struct lto_fil unsigned int count; lto_input_block ib_main ((const char *) data + main_offset, - header->main_size); + header->main_size, file_data->mode_table); data_in = lto_data_in_create (file_data, (const char *) data + string_offset, --- gcc/lto-streamer-in.c.jj 2015-02-16 22:18:33.204702562 +0100 +++ gcc/lto-streamer-in.c 2015-02-16 22:26:53.355464202 +0100 @@ -1116,10 +1116,12 @@ lto_read_body_or_constructor (struct lto /* Set up the struct function. */ from = data_in->reader_cache->nodes.length (); - lto_input_block ib_main (data + main_offset, header->main_size); + lto_input_block ib_main (data + main_offset, header->main_size, + file_data->mode_table); if (TREE_CODE (node->decl) == FUNCTION_DECL) { - lto_input_block ib_cfg (data + cfg_offset, header->cfg_size); + lto_input_block ib_cfg (data + cfg_offset, header->cfg_size, + file_data->mode_table); input_function (fn_decl, data_in, &ib_main, &ib_cfg); } else @@ -1384,7 +1386,8 @@ lto_input_toplevel_asms (struct lto_file string_offset = sizeof (*header) + header->main_size; - lto_input_block ib (data + sizeof (*header), header->main_size); + lto_input_block ib (data + sizeof (*header), header->main_size, + file_data->mode_table); data_in = lto_data_in_create (file_data, data + string_offset, header->string_size, vNULL); @@ -1403,6 +1406,123 @@ lto_input_toplevel_asms (struct lto_file } +/* Input mode table. */ + +void +lto_input_mode_table (struct lto_file_decl_data *file_data) +{ + size_t len; + const char *data = lto_get_section_data (file_data, LTO_section_mode_table, + NULL, &len); + if (! data) + { + internal_error ("cannot read LTO mode table from %s", + file_data->file_name); + return; + } + + unsigned char *table = ggc_cleared_vec_alloc (1 << 8); + file_data->mode_table = table; + const struct lto_simple_header_with_strings *header + = (const struct lto_simple_header_with_strings *) data; + int string_offset; + struct data_in *data_in; + string_offset = sizeof (*header) + header->main_size; + + lto_input_block ib (data + sizeof (*header), header->main_size, NULL); + data_in = lto_data_in_create (file_data, data + string_offset, + header->string_size, vNULL); + bitpack_d bp = streamer_read_bitpack (&ib); + + table[VOIDmode] = VOIDmode; + table[BLKmode] = BLKmode; + unsigned int m; + while ((m = bp_unpack_value (&bp, 8)) != VOIDmode) + { + enum mode_class mclass + = bp_unpack_enum (&bp, mode_class, MAX_MODE_CLASS); + unsigned int size = bp_unpack_value (&bp, 8); + unsigned int prec = bp_unpack_value (&bp, 16); + machine_mode inner = (machine_mode) table[bp_unpack_value (&bp, 8)]; + unsigned int nunits = bp_unpack_value (&bp, 8); + unsigned int ibit = 0, fbit = 0; + unsigned int real_fmt_len = 0; + const char *real_fmt_name = NULL; + switch (mclass) + { + case MODE_FRACT: + case MODE_UFRACT: + case MODE_ACCUM: + case MODE_UACCUM: + ibit = bp_unpack_value (&bp, 8); + fbit = bp_unpack_value (&bp, 8); + break; + case MODE_FLOAT: + case MODE_DECIMAL_FLOAT: + real_fmt_name = bp_unpack_indexed_string (data_in, &bp, + &real_fmt_len); + break; + default: + break; + } + /* First search just the GET_CLASS_NARROWEST_MODE to wider modes, + if not found, fallback to all modes. */ + int pass; + for (pass = 0; pass < 2; pass++) + for (machine_mode mr = pass ? VOIDmode + : GET_CLASS_NARROWEST_MODE (mclass); + pass ? mr < MAX_MACHINE_MODE : mr != VOIDmode; + pass ? mr = (machine_mode) (m + 1) + : mr = GET_MODE_WIDER_MODE (mr)) + if (GET_MODE_CLASS (mr) != mclass + || GET_MODE_SIZE (mr) != size + || GET_MODE_PRECISION (mr) != prec + || GET_MODE_INNER (mr) != inner + || GET_MODE_IBIT (mr) != ibit + || GET_MODE_FBIT (mr) != fbit + || GET_MODE_NUNITS (mr) != nunits) + continue; + else if ((mclass == MODE_FLOAT || mclass == MODE_DECIMAL_FLOAT) + && strcmp (REAL_MODE_FORMAT (mr)->name, real_fmt_name) != 0) + continue; + else + { + table[m] = mr; + pass = 2; + break; + } + unsigned int mname_len; + const char *mname = bp_unpack_indexed_string (data_in, &bp, &mname_len); + if (pass == 2) + { + switch (mclass) + { + case MODE_VECTOR_INT: + case MODE_VECTOR_FLOAT: + case MODE_VECTOR_FRACT: + case MODE_VECTOR_UFRACT: + case MODE_VECTOR_ACCUM: + case MODE_VECTOR_UACCUM: + /* For unsupported vector modes just use BLKmode, + if the scalar mode is supported. */ + if (inner != VOIDmode) + { + table[m] = BLKmode; + break; + } + /* FALLTHRU */ + default: + error ("unsupported mode %s\n", mname); + break; + } + } + } + lto_data_in_delete (data_in); + + lto_free_section_data (file_data, LTO_section_mode_table, NULL, data, len); +} + + /* Initialization for the LTO reader. */ void --- gcc/real.c.jj 2015-02-16 22:18:33.220702299 +0100 +++ gcc/real.c 2015-02-16 22:19:20.853917626 +0100 @@ -3031,7 +3031,8 @@ const struct real_format ieee_single_for true, true, true, - false + false, + "ieee_single" }; const struct real_format mips_single_format = @@ -3052,7 +3053,8 @@ const struct real_format mips_single_for true, true, false, - true + true, + "mips_single" }; const struct real_format motorola_single_format = @@ -3073,7 +3075,8 @@ const struct real_format motorola_single true, true, true, - true + true, + "motorola_single" }; /* SPU Single Precision (Extended-Range Mode) format is the same as IEEE @@ -3105,7 +3108,8 @@ const struct real_format spu_single_form true, true, false, - false + false, + "spu_single" }; /* IEEE double-precision format. */ @@ -3314,7 +3318,8 @@ const struct real_format ieee_double_for true, true, true, - false + false, + "ieee_double" }; const struct real_format mips_double_format = @@ -3335,7 +3340,8 @@ const struct real_format mips_double_for true, true, false, - true + true, + "mips_double" }; const struct real_format motorola_double_format = @@ -3356,7 +3362,8 @@ const struct real_format motorola_double true, true, true, - true + true, + "motorola_double" }; /* IEEE extended real format. This comes in three flavors: Intel's as @@ -3700,7 +3707,8 @@ const struct real_format ieee_extended_m true, true, true, - true + true, + "ieee_extended_motorola" }; const struct real_format ieee_extended_intel_96_format = @@ -3721,7 +3729,8 @@ const struct real_format ieee_extended_i true, true, true, - false + false, + "ieee_extended_intel_96" }; const struct real_format ieee_extended_intel_128_format = @@ -3742,7 +3751,8 @@ const struct real_format ieee_extended_i true, true, true, - false + false, + "ieee_extended_intel_128" }; /* The following caters to i386 systems that set the rounding precision @@ -3765,7 +3775,8 @@ const struct real_format ieee_extended_i true, true, true, - false + false, + "ieee_extended_intel_96_round_53" }; /* IBM 128-bit extended precision format: a pair of IEEE double precision @@ -3853,7 +3864,8 @@ const struct real_format ibm_extended_fo true, true, true, - false + false, + "ibm_extended" }; const struct real_format mips_extended_format = @@ -3874,7 +3886,8 @@ const struct real_format mips_extended_f true, true, false, - true + true, + "mips_extended" }; @@ -4137,7 +4150,8 @@ const struct real_format ieee_quad_forma true, true, true, - false + false, + "ieee_quad" }; const struct real_format mips_quad_format = @@ -4158,7 +4172,8 @@ const struct real_format mips_quad_forma true, true, false, - true + true, + "mips_quad" }; /* Descriptions of VAX floating point formats can be found beginning at @@ -4458,7 +4473,8 @@ const struct real_format vax_f_format = false, false, false, - false + false, + "vax_f" }; const struct real_format vax_d_format = @@ -4479,7 +4495,8 @@ const struct real_format vax_d_format = false, false, false, - false + false, + "vax_d" }; const struct real_format vax_g_format = @@ -4500,7 +4517,8 @@ const struct real_format vax_g_format = false, false, false, - false + false, + "vax_g" }; /* Encode real R into a single precision DFP value in BUF. */ @@ -4576,7 +4594,8 @@ const struct real_format decimal_single_ true, true, true, - false + false, + "decimal_single" }; /* Double precision decimal floating point (IEEE 754). */ @@ -4598,7 +4617,8 @@ const struct real_format decimal_double_ true, true, true, - false + false, + "decimal_double" }; /* Quad precision decimal floating point (IEEE 754). */ @@ -4620,7 +4640,8 @@ const struct real_format decimal_quad_fo true, true, true, - false + false, + "decimal_quad" }; /* Encode half-precision floats. This routine is used both for the IEEE @@ -4757,7 +4778,8 @@ const struct real_format ieee_half_forma true, true, true, - false + false, + "ieee_half" }; /* ARM's alternative half-precision format, similar to IEEE but with @@ -4781,7 +4803,8 @@ const struct real_format arm_half_format true, true, false, - false + false, + "arm_half" }; /* A synthetic "format" for internal arithmetic. It's the size of the @@ -4826,7 +4849,8 @@ const struct real_format real_internal_f false, true, true, - false + false, + "real_internal" }; /* Calculate X raised to the integer exponent N in mode MODE and store --- gcc/config/pdp11/pdp11.c.jj 2015-02-16 22:18:33.209702480 +0100 +++ gcc/config/pdp11/pdp11.c 2015-02-16 22:19:20.845917758 +0100 @@ -107,7 +107,8 @@ const struct real_format pdp11_f_format false, false, false, - false + false, + "pdp11_f" }; const struct real_format pdp11_d_format = @@ -128,7 +129,8 @@ const struct real_format pdp11_d_format false, false, false, - false + false, + "pdp11_d" }; static void --- gcc/lto/lto.c.jj 2015-02-16 22:18:33.221702282 +0100 +++ gcc/lto/lto.c 2015-02-16 22:35:56.213523202 +0100 @@ -85,6 +85,8 @@ static int lto_parallelism; static GTY(()) tree first_personality_decl; +static GTY(()) const unsigned char *lto_mode_identity_table; + /* Returns a hash code for P. */ static hashval_t @@ -1877,7 +1879,7 @@ lto_read_decls (struct lto_file_decl_dat uint32_t num_decl_states; lto_input_block ib_main ((const char *) data + main_offset, - header->main_size); + header->main_size, decl_data->mode_table); data_in = lto_data_in_create (decl_data, (const char *) data + string_offset, header->string_size, resolutions); @@ -2219,6 +2221,11 @@ lto_file_finalize (struct lto_file_decl_ file_data->renaming_hash_table = lto_create_renaming_table (); file_data->file_name = file->filename; +#ifdef ACCEL_COMPILER + lto_input_mode_table (file_data); +#else + file_data->mode_table = lto_mode_identity_table; +#endif data = lto_get_section_data (file_data, LTO_section_decls, NULL, &len); if (data == NULL) { @@ -3394,6 +3401,13 @@ lto_init (void) memset (<o_stats, 0, sizeof (lto_stats)); bitmap_obstack_initialize (NULL); gimple_register_cfg_hooks (); +#ifndef ACCEL_COMPILER + unsigned char *table + = ggc_vec_alloc (MAX_MACHINE_MODE); + for (int m = 0; m < MAX_MACHINE_MODE; m++) + table[m] = m; + lto_mode_identity_table = table; +#endif }