On 11/21/11 13:45, Richard Henderson wrote:
On 11/21/2011 11:31 AM, Aldy Hernandez wrote:
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);
No point merging GIMPLE_TRANSACTION with those cases. There are only two
operands, BODY and LABEL, and BODY should have been lowered already. Make this
a separate case with an assert BODY == NULL, and writing the label.
Done.
Otherwise ok.
I added a few things.
First, I added the dummy calls as you suggested, but I also had to add a
"used" attribute otherwise the hidden _ITM_* calls get swiped from under
us before link time.
Second, I added another test to make sure linking clones actually works.
Lastly, I noticed lto_cgraph.c inputs/outputs the cgraph bits. I added
code to handle the tm_clone bit. We do still need it, right?
Otherwise as before. Tested on x86-64 Linux.
OK?
* 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.
* lto-cgraph.c (input_overwrite_node): Read tm_clone bit.
(lto_output_node): Write tm_clone bit.
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)
@@ -151,6 +151,11 @@ output_gimple_stmt (struct output_block
case GIMPLE_PREDICT:
break;
+ case GIMPLE_TRANSACTION:
+ gcc_assert (gimple_transaction_body (stmt) == NULL);
+ stream_write_tree (ob, gimple_transaction_label (stmt), true);
+ break;
+
default:
gcc_unreachable ();
}
Index: testsuite/gcc.dg/lto/trans-mem-2_0.c
===================================================================
--- testsuite/gcc.dg/lto/trans-mem-2_0.c (revision 0)
+++ testsuite/gcc.dg/lto/trans-mem-2_0.c (revision 0)
@@ -0,0 +1,19 @@
+/* { dg-lto-options {{-flto -fgnu-tm}} } */
+
+extern void foobar() __attribute__((transaction_callable));
+
+#define dummy(func) \
+ __attribute__((noinline,noclone,used)) void func() { asm (""); }
+
+dummy(_ITM_beginTransaction)
+dummy(_ITM_commitTransaction)
+dummy(_ITM_WU4)
+dummy(_ITM_WU8)
+
+main()
+{
+ __transaction_relaxed
+ {
+ foobar();
+ }
+}
Index: testsuite/gcc.dg/lto/trans-mem-2_1.c
===================================================================
--- testsuite/gcc.dg/lto/trans-mem-2_1.c (revision 0)
+++ testsuite/gcc.dg/lto/trans-mem-2_1.c (revision 0)
@@ -0,0 +1,4 @@
+__attribute__((transaction_callable,noinline))
+void foobar()
+{
+}
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,11 @@
+/* { dg-lto-options {{-flto -fgnu-tm}} } */
+
+int i;
+
+main()
+{
+ __transaction_atomic
+ {
+ i = 0;
+ }
+}
Index: testsuite/gcc.dg/lto/trans-mem-1_1.c
===================================================================
--- testsuite/gcc.dg/lto/trans-mem-1_1.c (revision 0)
+++ testsuite/gcc.dg/lto/trans-mem-1_1.c (revision 0)
@@ -0,0 +1,7 @@
+#define dummy(func) \
+ __attribute__((noinline,noclone,used)) void func() { asm (""); }
+
+dummy(_ITM_beginTransaction)
+dummy(_ITM_commitTransaction)
+dummy(_ITM_WU4)
+dummy(_ITM_WU8)
Index: lto-cgraph.c
===================================================================
--- lto-cgraph.c (revision 181588)
+++ lto-cgraph.c (working copy)
@@ -522,6 +522,7 @@ lto_output_node (struct lto_simple_outpu
bp_pack_value (&bp, node->frequency, 2);
bp_pack_value (&bp, node->only_called_at_startup, 1);
bp_pack_value (&bp, node->only_called_at_exit, 1);
+ bp_pack_value (&bp, node->tm_clone, 1);
bp_pack_value (&bp, node->thunk.thunk_p && !boundary_p, 1);
bp_pack_enum (&bp, ld_plugin_symbol_resolution,
LDPR_NUM_KNOWN, node->resolution);
@@ -928,6 +929,7 @@ input_overwrite_node (struct lto_file_de
node->frequency = (enum node_frequency)bp_unpack_value (bp, 2);
node->only_called_at_startup = bp_unpack_value (bp, 1);
node->only_called_at_exit = bp_unpack_value (bp, 1);
+ node->tm_clone = bp_unpack_value (bp, 1);
node->thunk.thunk_p = bp_unpack_value (bp, 1);
node->resolution = bp_unpack_enum (bp, ld_plugin_symbol_resolution,
LDPR_NUM_KNOWN);
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)
@@ -238,6 +238,10 @@ input_gimple_stmt (struct lto_input_bloc
case GIMPLE_PREDICT:
break;
+ case GIMPLE_TRANSACTION:
+ gimple_transaction_set_label (stmt, stream_read_tree (ib, data_in));
+ break;
+
default:
internal_error ("bytecode stream: unknown GIMPLE statement tag %s",
lto_tag_name (tag));