From patchwork Mon Nov 21 19:31:55 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: support LTO of transactional memory From: Aldy Hernandez X-Patchwork-Id: 126908 Message-Id: <4ECAA72B.90409@redhat.com> To: Richard Henderson Cc: gcc-patches , Andrew Pinski Date: Mon, 21 Nov 2011 13:31:55 -0600 No sense not supporting LTO in the first TM release, if we can avoid it. OK for trunk, or should I queue for 4.8? This only affects the TM code path. Tested on x86-64 Linux. The testcase only tests for assembly, since I see no way of testing linkage and depending on libitm as well. Plus, we only support a handful of targets anyhow. I also tested by setting "dg-lto-do link" and checking that the only error was a link error against the relevant _ITM_* symbols (no additional LTO related errors). p.s. See, Andrew? I didn't forget :). * opts.c (finish_options): Do not fail for -fgnu-tm. * gimple-streamer-out.c (output_gimple_stmt): Handle GIMPLE_TRANSACTION. * gimple-streamer-in.c (input_gimple_stmt): Same. (ipa_tm_create_version): Same. lto/ * lto-lang.c (lto_attribute_table): Handle transaction_pure. (handle_transaction_pure_attribute): New. Index: gimple-streamer-out.c =================================================================== --- gimple-streamer-out.c (revision 181588) +++ gimple-streamer-out.c (working copy) @@ -111,6 +111,7 @@ output_gimple_stmt (struct output_block case GIMPLE_COND: case GIMPLE_GOTO: case GIMPLE_DEBUG: + case GIMPLE_TRANSACTION: for (i = 0; i < gimple_num_ops (stmt); i++) { tree op = gimple_op (stmt, i); @@ -145,6 +146,8 @@ output_gimple_stmt (struct output_block else stream_write_tree (ob, gimple_call_fntype (stmt), true); } + if (gimple_code (stmt) == GIMPLE_TRANSACTION) + stream_write_tree (ob, gimple_transaction_label (stmt), true); break; case GIMPLE_NOP: Index: testsuite/gcc.dg/lto/trans-mem-1_0.c =================================================================== --- testsuite/gcc.dg/lto/trans-mem-1_0.c (revision 0) +++ testsuite/gcc.dg/lto/trans-mem-1_0.c (revision 0) @@ -0,0 +1,12 @@ +/* { dg-lto-do assemble } */ +/* { dg-lto-options {{-flto -fgnu-tm}} } */ + +int i; + +main() +{ + __transaction_atomic + { + i = 0; + } +} Index: opts.c =================================================================== --- opts.c (revision 181588) +++ opts.c (working copy) @@ -784,8 +784,6 @@ finish_options (struct gcc_options *opts #endif if (!opts->x_flag_fat_lto_objects && !HAVE_LTO_PLUGIN) error_at (loc, "-fno-fat-lto-objects are supported only with linker plugin."); - if (opts->x_flag_tm) - error_at (loc, "LTO is currently not supported with transactional memory"); } if ((opts->x_flag_lto_partition_balanced != 0) + (opts->x_flag_lto_partition_1to1 != 0) + (opts->x_flag_lto_partition_none != 0) >= 1) Index: lto/lto-lang.c =================================================================== --- lto/lto-lang.c (revision 181588) +++ lto/lto-lang.c (working copy) @@ -46,6 +46,7 @@ static tree handle_nonnull_attribute (tr static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *); static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *); static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *); +static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *); static tree handle_format_attribute (tree *, tree, tree, int, bool *); static tree handle_format_arg_attribute (tree *, tree, tree, int, bool *); @@ -75,6 +76,8 @@ const struct attribute_spec lto_attribut handle_sentinel_attribute, false }, { "type generic", 0, 0, false, true, true, handle_type_generic_attribute, false }, + { "transaction_pure", 0, 0, false, true, true, + handle_transaction_pure_attribute, false }, { NULL, 0, 0, false, false, false, NULL, false } }; @@ -401,6 +404,20 @@ handle_type_generic_attribute (tree *nod return NULL_TREE; } + +/* Handle a "transaction_pure" attribute. */ + +static tree +handle_transaction_pure_attribute (tree *node, tree ARG_UNUSED (name), + tree ARG_UNUSED (args), + int ARG_UNUSED (flags), + bool * ARG_UNUSED (no_add_attrs)) +{ + /* Ensure we have a function type. */ + gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE); + + return NULL_TREE; +} /* Handle a "format" attribute; arguments as in struct attribute_spec.handler. */ Index: gimple-streamer-in.c =================================================================== --- gimple-streamer-in.c (revision 181588) +++ gimple-streamer-in.c (working copy) @@ -141,6 +141,7 @@ input_gimple_stmt (struct lto_input_bloc case GIMPLE_COND: case GIMPLE_GOTO: case GIMPLE_DEBUG: + case GIMPLE_TRANSACTION: for (i = 0; i < num_ops; i++) { tree op = stream_read_tree (ib, data_in); @@ -232,6 +233,8 @@ input_gimple_stmt (struct lto_input_bloc && !gimple_check_call_matching_types (stmt, fndecl)) gimple_call_set_cannot_inline (stmt, true); } + if (gimple_code (stmt) == GIMPLE_TRANSACTION) + gimple_transaction_set_label (stmt, stream_read_tree (ib, data_in)); break; case GIMPLE_NOP: