This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[trans-mem] handle hasNoAbort


Hi Richard.

After optimization we clear the atomic subcode hoping to accumulate it
as we do the final expand of __tm_atomic.  However, we currently don't
set the opcode ever again.

This patch sets GTMA_HAVE_ABORT when appropriate, so we can pass the
appropriate hint to the run-time.

Richard, I know you would've liked to get rid of the subcode in favor of
the state variable in the lowering phase, and the region structure in
the expand phase, but for now I'd like to keep it so I can see how
things are turning out in the IR as we flatten things out.

As a bonus, I have added code to dump the subcodes correctly and a
corresponding test.

Bootstrapped and tested for C on x86-64 Linux.

OK for branch?

	* gimple-pretty-print.c (dump_gimple_tm_atomic_subcode): New.
	(dump_gimple_tm_atomic): Dump subcodes.
	* trans-mem.c (is_tm_abort): New.
	(examine_call_tm): Use is_tm_abort.
	(expand_call_tm): Set GTMA_HAVE_ABORT.

Index: testsuite/gcc.dg/tm/props.c
===================================================================
--- testsuite/gcc.dg/tm/props.c	(revision 0)
+++ testsuite/gcc.dg/tm/props.c	(revision 0)
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-tmedge -fdump-tree-tmlower" } */
+
+int global;
+
+foo(int local)
+{
+  __tm_atomic {
+    local++;
+    if (++global == 10)
+      __tm_abort;
+  }
+}
+
+/* { dg-final { scan-tree-dump-times "instrumentedCode" 1 "tmedge" } } */
+/* { dg-final { scan-tree-dump-times "hasNoAbort" 0 "tmedge" } } */
+/* { dg-final { scan-tree-dump-times "GTMA_HAVE_ABORT" 1 "tmlower" } } */
+/* { dg-final { cleanup-tree-dump "tmedge" } } */
+/* { dg-final { cleanup-tree-dump "tmlower" } } */
Index: gimple-pretty-print.c
===================================================================
--- gimple-pretty-print.c	(revision 149720)
+++ gimple-pretty-print.c	(working copy)
@@ -1116,23 +1116,53 @@ dump_gimple_omp_return (pretty_printer *
     }
 }
 
+/* Dump the subcodes of a GIMPLE_ATOMIC tuple.  */
+
+static void
+dump_gimple_tm_atomic_subcode (pretty_printer *buffer, unsigned subcode)
+{
+  if (!subcode)
+    return;
+  pp_string (buffer, " [ ");
+  if (subcode & GTMA_HAVE_ABORT)
+    pp_string (buffer, "GTMA_HAVE_ABORT ");
+  if (subcode & GTMA_HAVE_LOAD)
+    pp_string (buffer, "GTMA_HAVE_LOAD ");
+  if (subcode & GTMA_HAVE_STORE)
+    pp_string (buffer, "GTMA_HAVE_STORE");
+  if (subcode & GTMA_HAVE_CALL_TM)
+    pp_string (buffer, "GTMA_HAVE_CALL_TM");
+  if (subcode & GTMA_HAVE_CALL_IRREVOKABLE)
+    pp_string (buffer, "GTMA_HAVE_CALL_IRREVOKABLE");
+  if (subcode & GTMA_MUST_CALL_IRREVOKABLE)
+    pp_string (buffer, "GTMA_MUST_CALL_IRREVOKABLE");
+  if (subcode & GTMA_HAVE_UNCOMMITTED_THROW)
+    pp_string (buffer, "GTMA_HAVE_UNCOMMITTED_THROW");
+  pp_string (buffer, " ]");
+}
+
 /* Dump a GIMPLE_TM_ATOMIC tuple on the pretty_printer BUFFER.  */
 
 static void
 dump_gimple_tm_atomic (pretty_printer *buffer, gimple gs, int spc, int flags)
 {
+  unsigned subcode = gimple_tm_atomic_subcode (gs);
+
   if (flags & TDF_RAW)
-    dump_gimple_fmt (buffer, spc, flags,
-		     "%G [SUBCODE=%x,LABEL=%T] <%+BODY <%S> >",
-		     gs, gimple_tm_atomic_subcode (gs),
-		     gimple_tm_atomic_label (gs), gimple_tm_atomic_body (gs));
+    {
+      dump_gimple_fmt (buffer, spc, flags,
+		       "%G [SUBCODE=%x,LABEL=%T] <%+BODY <%S> >",
+		       gs, subcode,
+		       gimple_tm_atomic_label (gs), gimple_tm_atomic_body (gs));
+      dump_gimple_tm_atomic_subcode (buffer, subcode);
+    }
   else
     {
-      pp_printf (buffer, "__tm_atomic [SUBCODE=%x,LABEL=",
-		 gimple_tm_atomic_subcode (gs));
+      pp_printf (buffer, "__tm_atomic [SUBCODE=%x,LABEL=", subcode);
       dump_generic_node (buffer, gimple_tm_atomic_label (gs),
 			 spc, flags, false);
       pp_string (buffer, "]");
+      dump_gimple_tm_atomic_subcode (buffer, subcode);
 
       if (!gimple_seq_empty_p (gimple_tm_atomic_body (gs)))
 	{
Index: trans-mem.c
===================================================================
--- trans-mem.c	(revision 149720)
+++ trans-mem.c	(working copy)
@@ -272,6 +272,17 @@ is_tm_ending_fndecl (tree fndecl)
   return false;
 }
 
+
+/* Return true if FNDECL is BUILT_IN_TM_ABORT.  */
+
+static bool
+is_tm_abort (tree fndecl)
+{
+  return (fndecl
+	  && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+	  && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_TM_ABORT);
+}
+
 /* Build a GENERIC tree for a user abort.  This is called by front ends
    while transforming the __tm_abort statement.  */
 
@@ -499,8 +510,7 @@ examine_call_tm (unsigned *state, gimple
 
   /* Check if this call is a transaction abort.  */
   fn = gimple_call_fndecl (stmt);
-  if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
-      && DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_ABORT)
+  if (is_tm_abort (fn))
     *state |= GTMA_HAVE_ABORT;
 
   /* Note that something may happen.  */
@@ -1077,7 +1087,7 @@ expand_assign_tm (struct tm_region *regi
    one of the builtins that end a transaction.  */
 
 static bool
-expand_call_tm (struct tm_region * ARG_UNUSED (region),
+expand_call_tm (struct tm_region *region,
 		gimple_stmt_iterator *gsi)
 {
   gimple stmt = gsi_stmt (*gsi);
@@ -1087,7 +1097,10 @@ expand_call_tm (struct tm_region * ARG_U
     return false;
 
   fn_decl = gimple_call_fndecl (stmt);
-  
+
+  if (is_tm_abort (fn_decl))
+    tm_atomic_subcode_ior (region, GTMA_HAVE_ABORT);
+
   /* For indirect calls, we already generated a call into the runtime.  */
   if (!fn_decl)
     return false;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]