diff mbox

support LTO of transactional memory

Message ID 4ECAA72B.90409@redhat.com
State New
Headers show

Commit Message

Aldy Hernandez Nov. 21, 2011, 7:31 p.m. UTC
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.

Comments

Richard Henderson Nov. 21, 2011, 7:38 p.m. UTC | #1
On 11/21/2011 11:31 AM, Aldy Hernandez wrote:
> 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.

All these tests support multi-file linkage (otherwise LTO is moot).
You could supply dummy implementations of the libitm functions,
with __attribute__((noinline,noclone)) and with a body containing
at least asm("").


r~
Richard Henderson Nov. 21, 2011, 7:45 p.m. UTC | #2
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.

> +      if (gimple_code (stmt) == GIMPLE_TRANSACTION)
> +    gimple_transaction_set_label (stmt, stream_read_tree (ib, data_in)); 

Similarly separate, although obviously no assert for BODY here.

Otherwise ok.


r~
diff mbox

Patch

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: