[Bug target/44132] [4.6 Regression] emutls is broken under a range of circumstances.
hubicka at ucw dot cz
gcc-bugzilla@gcc.gnu.org
Sat May 15 09:35:00 GMT 2010
------- 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
More information about the Gcc-bugs
mailing list