------- Comment #7 from hubicka at ucw dot cz  2010-05-15 09:35 -------
Subject: Re:  [4.6 Regression] emutls is broken under a
        range of circumstances.

Hi,
we can either go with DECL_PRESERVE that is kind of hack but makes situation no
worse.
Correct fix is to lower emultls earlier so both ipa-ref and LTO understands it.
This might be bit too early, but I think we can stick it into gimplifier as
follows

Index: expr.c
===================================================================
--- expr.c      (revision 159421)
+++ expr.c      (working copy)
@@ -6759,19 +6759,6 @@ highest_pow2_factor_for_target (const_tr
   return MAX (factor, talign);
 }

-/* Return &VAR expression for emulated thread local VAR.  */
-
-static tree
-emutls_var_address (tree var)
-{
-  tree emuvar = emutls_decl (var);
-  tree fn = built_in_decls [BUILT_IN_EMUTLS_GET_ADDRESS];
-  tree arg = build_fold_addr_expr_with_type (emuvar, ptr_type_node);
-  tree arglist = build_tree_list (NULL_TREE, arg);
-  tree call = build_function_call_expr (UNKNOWN_LOCATION, fn, arglist);
-  return fold_convert (build_pointer_type (TREE_TYPE (var)), call);
-}
-

 /* Subroutine of expand_expr.  Expand the two operands of a binary
    expression EXP0 and EXP1 placing the results in OP0 and OP1.
@@ -6866,15 +6853,6 @@ expand_expr_addr_expr_1 (tree exp, rtx t
       break;

     case VAR_DECL:
-      /* TLS emulation hook - replace __thread VAR's &VAR with
-        __emutls_get_address (&_emutls.VAR).  */
-      if (! targetm.have_tls
-         && TREE_CODE (exp) == VAR_DECL
-         && DECL_THREAD_LOCAL_P (exp))
-       {
-         exp = emutls_var_address (exp);
-         return expand_expr (exp, target, tmode, modifier);
-       }
       /* Fall through.  */

     default:
@@ -8406,16 +8384,6 @@ expand_expr_real_1 (tree exp, rtx target
          && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
        layout_decl (exp, 0);

-      /* TLS emulation hook - replace __thread vars with
-        *__emutls_get_address (&_emutls.var).  */
-      if (! targetm.have_tls
-         && TREE_CODE (exp) == VAR_DECL
-         && DECL_THREAD_LOCAL_P (exp))
-       {
-         exp = build_fold_indirect_ref_loc (loc, emutls_var_address (exp));
-         return expand_expr_real_1 (exp, target, tmode, modifier, NULL);
-       }
-
       /* ... fall through ...  */

     case FUNCTION_DECL:
Index: gimplify.c
===================================================================
--- gimplify.c  (revision 159421)
+++ gimplify.c  (working copy)
@@ -1309,6 +1309,18 @@ gimplify_vla_decl (tree decl, gimple_seq
   gimplify_ctxp->save_stack = true;
 }

+/* Return &VAR expression for emulated thread local VAR.  */
+
+static tree
+emutls_var_address (tree var)
+{
+  tree emuvar = emutls_decl (var);
+  tree fn = built_in_decls [BUILT_IN_EMUTLS_GET_ADDRESS];
+  tree arg = build_fold_addr_expr_with_type (emuvar, ptr_type_node);
+  tree arglist = build_tree_list (NULL_TREE, arg);
+  tree call = build_function_call_expr (UNKNOWN_LOCATION, fn, arglist);
+  return fold_convert (build_pointer_type (TREE_TYPE (var)), call);
+}

 /* Gimplifies a DECL_EXPR node *STMT_P by making any necessary allocation
    and initialization explicit.  */
@@ -1320,6 +1332,15 @@ gimplify_decl_expr (tree *stmt_p, gimple
   tree decl = DECL_EXPR_DECL (stmt);

   *stmt_p = NULL_TREE;
+  /* TLS emulation hook - replace __thread VAR's &VAR with
+     __emutls_get_address (&_emutls.VAR).  */
+  if (! targetm.have_tls
+      && TREE_CODE (decl) == VAR_DECL
+      && DECL_THREAD_LOCAL_P (decl))
+    {
+      *stmt_p = build_fold_indirect_ref (emutls_var_address (decl));
+      return GS_OK;
+    }

   if (TREE_TYPE (decl) == error_mark_node)
     return GS_ERROR;


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44132

Reply via email to