This was very painful, and it's still not over. We hadn't merged in almost 1.5 years, and we're paying for it now...

I managed to resolve all the conflicts, and bootstrap the compiler, which is rather amazing given the size of the changes. There are still over 16 compiler failures in gcc.dg/tm/, and 10 (out of 44) failures in libitm. I am in hit-man mode now, and will be tackling them one at a time over the next few days.

The branch is pretty useless. If you need it for actual TM work, I suggest you check out the branch as of yesterday.

Richard, do you mind taking a quick look at the attached patch, especially the TARGET_MEM_REF stuff? Those were the [very minor] changes to trans-mem.c. Most of the changes I had to do where conflicts elsewhere, but I want to make sure I don't botch up anything crucial in the TM engine.

Committing to branch and hoping for the best :).

Aldy

p.s. Note to self:
merge more often
merge more often
merge more often
merge more often
merge more often
merge more often
merge more often
Index: trans-mem.c
===================================================================
--- trans-mem.c (revision 178717)
+++ trans-mem.c (working copy)
@@ -38,6 +38,8 @@
 #include "params.h"
 #include "target.h"
 #include "langhooks.h"
+#include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
 
 
 #define PROB_VERY_UNLIKELY     (REG_BR_PROB_BASE / 2000 - 1)
@@ -450,7 +452,7 @@ record_tm_replacement (tree from, tree t
   if (tm_wrap_map == NULL)
     tm_wrap_map = htab_create_ggc (32, tree_map_hash, tree_map_eq, 0);
 
-  h = GGC_NEW (struct tree_map);
+  h = ggc_alloc_tree_map ();
   h->hash = htab_hash_pointer (from);
   h->base.from = from;
   h->to = to;
@@ -947,8 +949,7 @@ tm_log_delete (void)
 static bool
 transaction_invariant_address_p (const_tree mem, basic_block 
region_entry_block)
 {
-  if ((TREE_CODE (mem) == INDIRECT_REF
-       || TREE_CODE (mem) == MISALIGNED_INDIRECT_REF)
+  if (TREE_CODE (mem) == INDIRECT_REF
       && TREE_CODE (TREE_OPERAND (mem, 0)) == SSA_NAME)
     {
       basic_block def_bb;
@@ -1074,7 +1075,7 @@ tm_log_emit_stmt (tree addr, gimple stmt
   tree size = TYPE_SIZE_UNIT (type);
   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
   gimple log;
-  enum built_in_function code;
+  enum built_in_function code = BUILT_IN_TM_LOG;
 
   if (type == float_type_node)
     code = BUILT_IN_TM_LOG_FLOAT;
@@ -1432,7 +1433,7 @@ requires_barrier (basic_block entry_bloc
   switch (TREE_CODE (x))
     {
     case INDIRECT_REF:
-    case MISALIGNED_INDIRECT_REF:
+      /* case MISALIGNED_INDIRECT_REF: */
       {
        enum thread_memory_type ret;
 
@@ -1450,15 +1451,10 @@ requires_barrier (basic_block entry_bloc
        return false;
       }
 
-    case ALIGN_INDIRECT_REF:
-      /* ??? Insert an irrevocable when it comes to vectorized loops,
-        or handle these somehow.  */
-      gcc_unreachable ();
-
     case TARGET_MEM_REF:
-      x = TMR_SYMBOL (x);
-      if (x == NULL)
+      if (TREE_CODE (TMR_BASE (x)) != ADDR_EXPR)
        return true;
+      x = TREE_OPERAND (TMR_BASE (x), 0);
       if (TREE_CODE (x) == PARM_DECL)
        return false;
       gcc_assert (TREE_CODE (x) == VAR_DECL);
@@ -1490,7 +1486,7 @@ requires_barrier (basic_block entry_bloc
             lower_sequence_tm altogether.  */
          needs_to_live_in_memory (x)
          /* X escapes.  */
-         || is_call_clobbered (x))
+         || ptr_deref_may_alias_global_p (x))
        return true;
       else
        {
@@ -2228,7 +2224,7 @@ expand_call_tm (struct tm_region *region
       return false;
     }
 
-  node = cgraph_node (fn_decl);
+  node = cgraph_get_node (fn_decl);
   if (node->local.tm_may_enter_irr)
     transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
 
@@ -2474,7 +2470,7 @@ make_tm_edge (gimple stmt, basic_block b
   n = (struct tm_restart_node *) *slot;
   if (n == NULL)
     {
-      n = GGC_NEW (struct tm_restart_node);
+      n = ggc_alloc_tm_restart_node ();
       *n = dummy;
     }
   else
@@ -3630,7 +3626,7 @@ ipa_tm_scan_irr_block (basic_block bb)
              if (find_tm_replacement_function (fn))
                break;
 
-             d = get_cg_data (cgraph_node (fn));
+             d = get_cg_data (cgraph_get_node (fn));
              if (d->is_irrevocable)
                return true;
            }
@@ -3784,7 +3780,7 @@ ipa_tm_decrement_clone_counts (basic_blo
              if (find_tm_replacement_function (fndecl))
                continue;
 
-             d = get_cg_data (cgraph_node (fndecl));
+             d = get_cg_data (cgraph_get_node (fndecl));
              pcallers = (for_clone ? &d->tm_callers_clone
                          : &d->tm_callers_normal);
 
@@ -4105,6 +4101,47 @@ tm_mangle (tree old_asm_id)
   return new_asm_id;
 }
 
+/* Callback data for callback_mark_needed.  */
+struct mark_needed_info
+{
+  struct cgraph_node *old_node;
+  tree new_decl;
+};
+
+static bool
+callback_mark_needed (struct cgraph_node *node, void *data)
+{
+  struct mark_needed_info *info = (struct mark_needed_info *)data;
+  if (node->alias || node->thunk.thunk_p)
+    {
+      tree tm_name = tm_mangle (DECL_ASSEMBLER_NAME (node->decl));
+      tree tm_alias = build_decl (DECL_SOURCE_LOCATION (node->decl),
+                                 TREE_CODE (node->decl), tm_name,
+                                 TREE_TYPE (node->decl));
+
+      SET_DECL_ASSEMBLER_NAME (tm_alias, tm_name);
+      SET_DECL_RTL (tm_alias, NULL);
+
+      /* Based loosely on C++'s make_alias_for().  */
+      TREE_PUBLIC (tm_alias) = TREE_PUBLIC (node->decl);
+      DECL_CONTEXT (tm_alias) = NULL;
+      TREE_READONLY (tm_alias) = TREE_READONLY (node->decl);
+      DECL_EXTERNAL (tm_alias) = 0;
+      DECL_ARTIFICIAL (tm_alias) = 1;
+      TREE_ADDRESSABLE (tm_alias) = 1;
+      TREE_USED (tm_alias) = 1;
+      TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tm_alias)) = 1;
+
+      cgraph_same_body_alias (NULL, tm_alias, info->new_decl);
+
+      record_tm_clone_pair (node->decl, tm_alias);
+
+      if (info->old_node->needed)
+       cgraph_mark_needed_node (cgraph_get_node (tm_alias));
+    }
+  return false;
+}
+
 /* Create a copy of the function (possibly declaration only) of OLD_NODE,
    appropriate for the transactional clone.  */
 
@@ -4128,7 +4165,7 @@ ipa_tm_create_version (struct cgraph_nod
   if (DECL_COMDAT (new_decl))
     DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl));
 
-  new_node = cgraph_copy_node_for_versioning (old_node, new_decl, NULL);
+  new_node = cgraph_copy_node_for_versioning (old_node, new_decl, NULL, NULL);
   get_cg_data (old_node)->clone = new_node;
 
   if (cgraph_function_body_availability (old_node) >= AVAIL_OVERWRITABLE)
@@ -4141,7 +4178,8 @@ ipa_tm_create_version (struct cgraph_nod
          TREE_PUBLIC (new_decl) = 0;
        }
 
-      tree_function_versioning (old_decl, new_decl, NULL, false, NULL);
+      tree_function_versioning (old_decl, new_decl, NULL, false, NULL,
+                               NULL, NULL);
     }
 
   /* ?? We should be able to remove DECL_IS_TM_CLONE.  We have enough
@@ -4155,40 +4193,12 @@ ipa_tm_create_version (struct cgraph_nod
     cgraph_mark_needed_node (new_node);
 
   /* Do the same thing, but for any aliases of the original node.  */
-  if (old_node->same_body)
-    {
-      struct cgraph_node *alias;
-      tree tm_alias;
-
-      for (alias = old_node->same_body; alias; alias = alias->next)
-       {
-         tm_name = tm_mangle (DECL_ASSEMBLER_NAME (alias->decl));
-         tm_alias = build_decl (DECL_SOURCE_LOCATION (alias->decl),
-                                TREE_CODE (alias->decl), tm_name,
-                                TREE_TYPE (alias->decl));
-
-         SET_DECL_ASSEMBLER_NAME (tm_alias, tm_name);
-         SET_DECL_RTL (tm_alias, NULL);
-
-         /* Based loosely on C++'s make_alias_for().  */
-         TREE_PUBLIC (tm_alias) = TREE_PUBLIC (alias->decl);
-         /* ?? Do we need all of these too.  ??  */
-         DECL_CONTEXT (tm_alias) = NULL;
-         TREE_READONLY (tm_alias) = TREE_READONLY (alias->decl);
-         DECL_EXTERNAL (tm_alias) = 0;
-         DECL_ARTIFICIAL (tm_alias) = 1;
-         TREE_ADDRESSABLE (tm_alias) = 1;
-         TREE_USED (tm_alias) = 1;
-         TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tm_alias)) = 1;
-
-         cgraph_same_body_alias (tm_alias, new_decl);
-
-         record_tm_clone_pair (alias->decl, tm_alias);
-
-         if (old_node->needed)
-           cgraph_mark_needed_node (cgraph_node (tm_alias));
-       }
-    }
+  {
+    struct mark_needed_info data;
+    data.old_node = old_node;
+    data.new_decl = new_decl;
+    cgraph_for_node_and_aliases (old_node, callback_mark_needed, &data, true);
+  }
 }
 
 /* Construct a call to TM_IRREVOCABLE and insert it at the beginning of BB.  */
@@ -4210,11 +4220,10 @@ ipa_tm_insert_irr_call (struct cgraph_no
   gsi_insert_before (&gsi, g, GSI_SAME_STMT);
 
   cgraph_create_edge (node,
-                     cgraph_node (built_in_decls[BUILT_IN_TM_IRREVOCABLE]),
-                     g, 0,
-                     compute_call_stmt_bb_frequency (node->decl,
-                                                     gimple_bb (g)),
-                     bb->loop_depth);
+              cgraph_get_create_node (built_in_decls[BUILT_IN_TM_IRREVOCABLE]),
+              g, 0,
+              compute_call_stmt_bb_frequency (node->decl,
+                                              gimple_bb (g)));
 }
 
 /* Construct a call to TM_GETTMCLONE and insert it before GSI.  */
@@ -4239,9 +4248,9 @@ ipa_tm_insert_gettmclone_call (struct cg
          technically taking the address of the original function and
          its clone.  Explain this so inlining will know this function
          is needed.  */
-      cgraph_mark_address_taken_node (cgraph_node (fndecl));
+      cgraph_mark_address_taken_node (cgraph_get_node (fndecl));
       if (clone)
-       cgraph_mark_address_taken_node (cgraph_node (clone));
+       cgraph_mark_address_taken_node (cgraph_get_node (clone));
     }
 
   safe = is_tm_safe (TREE_TYPE (old_fn));
@@ -4263,9 +4272,9 @@ ipa_tm_insert_gettmclone_call (struct cg
 
   gsi_insert_before (gsi, g, GSI_SAME_STMT);
 
-  cgraph_create_edge (node, cgraph_node (gettm_fn), g, 0,
+  cgraph_create_edge (node, cgraph_get_create_node (gettm_fn), g, 0,
                      compute_call_stmt_bb_frequency (node->decl,
-                                                     gimple_bb(g)), 0);
+                                                     gimple_bb(g)));
 
   /* Cast return value from tm_gettmclone* into appropriate function
      pointer.  */
@@ -4281,7 +4290,7 @@ ipa_tm_insert_gettmclone_call (struct cg
      which we would have derived from the decl.  Failure to save
      this bit means we might have to split the basic block.  */
   if (gimple_call_nothrow_p (stmt))
-    gimple_call_set_nothrow_p (stmt);
+    gimple_call_set_nothrow (stmt, true);
 
   /* ??? This is a hack to prevent tree-eh.c inlineable_call_p from
      deciding that the indirect call we have after this transformation
@@ -4356,7 +4365,7 @@ ipa_tm_transform_calls_redirect (struct 
   fndecl = find_tm_replacement_function (fndecl);
   if (fndecl)
     {
-      new_node = cgraph_node (fndecl);
+      new_node = cgraph_get_create_node (fndecl);
 
       /* ??? Mark all transaction_wrap functions tm_may_enter_irr.
 

Reply via email to