Patchwork support LTO of transactional memory

login
register
mail settings
Submitter Aldy Hernandez
Date Nov. 22, 2011, 5:55 p.m.
Message ID <4ECBE217.7080808@redhat.com>
Download mbox | patch
Permalink /patch/127143/
State New
Headers show

Comments

Aldy Hernandez - Nov. 22, 2011, 5:55 p.m.
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.
Richard Henderson - Nov. 22, 2011, 6:30 p.m.
On 11/22/2011 09:55 AM, Aldy Hernandez wrote:
> 	* 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.

Ok.


r~
Jack Howarth - Nov. 22, 2011, 8:57 p.m.
On Tue, Nov 22, 2011 at 10:30:44AM -0800, Richard Henderson wrote:
> On 11/22/2011 09:55 AM, Aldy Hernandez wrote:
> > 	* 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.
> 
> Ok.
> 
> 
> r~

  On x86_64-apple-darwin11, we see the link-time failures...

FAIL: gcc.dg/lto/trans-mem-1 c_lto_trans-mem-1_0.o-c_lto_trans-mem-1_1.o link, -flto -fgnu-tm
FAIL: gcc.dg/lto/trans-mem-2 c_lto_trans-mem-2_0.o-c_lto_trans-mem-2_1.o link, -flto -fgnu-tm

at -m32/-m64. These fail as...

Executing on host: /sw/src/fink.build/gcc47-4.7.0-1/darwin_objdir/gcc/xgcc -B/sw/src/fink.build/gcc47-4.7.0-1/darwin_objdir/gcc/ c_lto_trans-mem-1_0.o c_lto_trans-mem-1_1.o   -flto
 -fgnu-tm       -m32 -o gcc-dg-lto-trans-mem-1-01.exe    (timeout = 300)
Undefined symbols for architecture i386:^M
  "__ITM_registerTMCloneTable", referenced from:^M
      ___doTMRegistrations in crttms.o^M
      ___doTMRegistrations in crttms.o^M
  "__ITM_deregisterTMCloneTable", referenced from:^M
      ___doTMdeRegistrations in crttme.o^M
      ___doTMdeRegistrations in crttme.o^M
ld: symbol(s) not found for architecture i386^M
collect2: error: ld returned 1 exit status^M
compiler exited with status 1
output is:
Undefined symbols for architecture i386:^M
  "__ITM_registerTMCloneTable", referenced from:^M
      ___doTMRegistrations in crttms.o^M
      ___doTMRegistrations in crttms.o^M  "__ITM_deregisterTMCloneTable", referenced from:^M
      ___doTMdeRegistrations in crttme.o^M
      ___doTMdeRegistrations in crttme.o^M
ld: symbol(s) not found for architecture i386^M
collect2: error: ld returned 1 exit status^M

FAIL: gcc.dg/lto/trans-mem-1 c_lto_trans-mem-1_0.o-c_lto_trans-mem-1_1.o link, -flto -fgnu-tm

Perhaps these are related to the run-time execution failures seen on i386 linux...

http://gcc.gnu.org/ml/gcc-testresults/2011-11/msg02303.html

FAIL: gcc.dg/lto/trans-mem-1 c_lto_trans-mem-1_0.o-c_lto_trans-mem-1_1.o execute -flto -fgnu-tm
FAIL: gcc.dg/lto/trans-mem-2 c_lto_trans-mem-2_0.o-c_lto_trans-mem-2_1.o execute -flto -fgnu-tm
IainS - Nov. 22, 2011, 9:03 p.m.
On 22 Nov 2011, at 20:57, Jack Howarth wrote:

> On Tue, Nov 22, 2011 at 10:30:44AM -0800, Richard Henderson wrote:
>> On 11/22/2011 09:55 AM, Aldy Hernandez wrote:
>>> 	* 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.
>>
>> Ok.
>>
>>
>> r~
>
>  On x86_64-apple-darwin11, we see the link-time failures...
>
> FAIL: gcc.dg/lto/trans-mem-1 c_lto_trans-mem-1_0.o-c_lto_trans- 
> mem-1_1.o link, -flto -fgnu-tm
> FAIL: gcc.dg/lto/trans-mem-2 c_lto_trans-mem-2_0.o-c_lto_trans- 
> mem-2_1.o link, -flto -fgnu-tm
>
> at -m32/-m64. These fail as...
>
> Executing on host: /sw/src/fink.build/gcc47-4.7.0-1/darwin_objdir/ 
> gcc/xgcc -B/sw/src/fink.build/gcc47-4.7.0-1/darwin_objdir/gcc/  
> c_lto_trans-mem-1_0.o c_lto_trans-mem-1_1.o   -flto
> -fgnu-tm       -m32 -o gcc-dg-lto-trans-mem-1-01.exe    (timeout =  
> 300)
> Undefined symbols for architecture i386:^M
>  "__ITM_registerTMCloneTable", referenced from:^M
>      ___doTMRegistrations in crttms.o^M
>      ___doTMRegistrations in crttms.o^M
>  "__ITM_deregisterTMCloneTable", referenced from:^M
>      ___doTMdeRegistrations in crttme.o^M
>      ___doTMdeRegistrations in crttme.o^M
> ld: symbol(s) not found for architecture i386^M
> collect2: error: ld returned 1 exit status^M
> compiler exited with status 1
> output is:
> Undefined symbols for architecture i386:^M
>  "__ITM_registerTMCloneTable", referenced from:^M
>      ___doTMRegistrations in crttms.o^M
>      ___doTMRegistrations in crttms.o^M   
> "__ITM_deregisterTMCloneTable", referenced from:^M
>      ___doTMdeRegistrations in crttme.o^M
>      ___doTMdeRegistrations in crttme.o^M
> ld: symbol(s) not found for architecture i386^M
> collect2: error: ld returned 1 exit status^M
>
> FAIL: gcc.dg/lto/trans-mem-1 c_lto_trans-mem-1_0.o-c_lto_trans- 
> mem-1_1.o link, -flto -fgnu-tm

I think we will need to ensure that libitm.dylib is on the link line -
  - maybe we're not picking up the spec properly....

(or I will have to cook up a more complex build for the crts).

Iain

Patch

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));