Message ID | 20100722162552.GA18378@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On 07/22/2010 09:25 AM, Jakub Jelinek wrote: > Do you think that is a good idea? > > Bootstrapped/regtested on x86_64-linux and i686-linux. > > 2010-07-22 Jakub Jelinek <jakub@redhat.com> > > * gimplify.c (enum gimplify_omp_var_data): Add > GOVD_THREADPRIVATE_WARNED. > (gimplify_bind_expr): Add GOVD_LOCAL | GOVD_SEEN even for global vars. > (omp_notice_threadprivate_variable): Note used threadprivate vars > with current function's context in shared clauses. > (gimplify_adjust_omp_clauses_1): Allow globals with current function's > context in taskreg shared clause. > * omp-low.c (lower_rec_input_clauses): For function-local is_global_var > VAR_DECLs in shared clauses add a decl copy with DECL_VALUE_EXPR > pointing to the original. > > * trans-openmp.c (gfc_omp_private_debug_clause): Return false for > threadprivate decls. > > * gcc.dg/gomp/tls-3.c: New test. Yes, I think it's a good idea. Ok. r~
> x and y in the first testcase and thr and svar2 aren't visible in the > debugger when in *omp_fn* function. While in theory it should be possible > for the debugger to look at the containing function in the initial thread > (*omp_fn* is DW_AT_artificial) and find those vars there, that can take a > long time before it is implemented in gdb. > > The following patch adds the referenced fn local threadprivate and statics > to the *omp_fn* DW_TAG_subprogram too. IMHO it would be better to do it without such duplication. I think we can beat the support out of the gdb people well enough, if the "proper" indirect representations of all the info are there. With 4.4.4(RH)-10, I see: <subprogram name="main.omp_fn.0" prototyped=1 artificial=1 low_pc=0x4005e0 high_pc=0x4005fc frame_base={locexpr}> Shouldn't that have static_link to refer to main as a nested function would? If it did, wouldn't that make the debugger handle it as it should already handle nested functions? These following questions are tangential, but it's the first time I've really looked at -fopenmp DWARF output. The name "main.omp_fn.0" is not a source identifier. Should it really be there in name? IMHO it seems more proper for that to have only artificial=true, linkage_name="main.omp_fn.0", and no name. (Perhaps linkage_name is not useful or appropriate since it's not DW_AT_external.) Similarly: <formal_parameter name=".omp_data_i" type="#ref1" artificial=1 location={locexpr}/> Should that really have a name? As it stands, the debugger is going to present ".omp_data_i" as a resolvable identifier in this scope, as it would for any other artifical parameter (such as C++ "this"). Next: <structure_type ref="ref4" name=".omp_data_s.10" byte_size=0x8> This needs artificial=true too. Again, it seems quite questionable whether the non-source name should appear at all. AIUI, this sort of thing is exactly what DW_AT_description is for. Thanks, Roland
>>>>> "Roland" == Roland McGrath <roland@redhat.com> writes:
Roland> IMHO it would be better to do it without such duplication. I
Roland> think we can beat the support out of the gdb people well enough,
Roland> if the "proper" indirect representations of all the info are
Roland> there.
Please file a bug in gdb bugzilla with all the details.
Tom
--- gcc/fortran/trans-openmp.c.jj 2010-07-15 14:35:35.000000000 +0200 +++ gcc/fortran/trans-openmp.c 2010-07-22 12:02:26.000000000 +0200 @@ -352,6 +352,18 @@ gfc_omp_disregard_value_expr (tree decl, bool gfc_omp_private_debug_clause (tree decl, bool shared) { + if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) + { + if (DECL_THREAD_LOCAL_P (decl)) + return false; + if (DECL_HAS_VALUE_EXPR_P (decl)) + { + tree value = get_base_address (DECL_VALUE_EXPR (decl)); + if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value)) + return false; + } + } + if (GFC_DECL_CRAY_POINTEE (decl)) return true; --- gcc/gimplify.c.jj 2010-07-16 17:55:08.000000000 +0200 +++ gcc/gimplify.c 2010-07-22 14:45:08.000000000 +0200 @@ -64,6 +64,7 @@ enum gimplify_omp_var_data GOVD_LOCAL = 128, GOVD_DEBUG_PRIVATE = 256, GOVD_PRIVATE_OUTER_REF = 512, + GOVD_THREADPRIVATE_WARNED = 1024, GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LOCAL) }; @@ -1140,7 +1141,7 @@ gimplify_bind_expr (tree *expr_p, gimple struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; /* Mark variable as local. */ - if (ctx && !is_global_var (t) + if (ctx && (! DECL_SEEN_IN_BIND_EXPR_P (t) || splay_tree_lookup (ctx->variables, (splay_tree_key) t) == NULL)) @@ -5520,17 +5521,36 @@ omp_notice_threadprivate_variable (struc { splay_tree_node n; - if (ctx->region_type != ORT_UNTIED_TASK) + while (ctx && ctx->region_type == ORT_WORKSHARE) + { + n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); + if (n != NULL) + { + gcc_assert (n->value & GOVD_LOCAL); + return false; + } + ctx = ctx->outer_context; + } + if (ctx == NULL) return false; + n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); if (n == NULL) + n = splay_tree_insert (ctx->variables, (splay_tree_key)decl, + DECL_CONTEXT (decl) == current_function_decl + ? GOVD_SHARED | GOVD_SEEN : 0); + if (ctx->region_type == ORT_UNTIED_TASK + && (n->value & GOVD_THREADPRIVATE_WARNED) == 0) { - error ("threadprivate variable %qE used in untied task", DECL_NAME (decl)); + error ("threadprivate variable %qE used in untied task", + DECL_NAME (decl)); error_at (ctx->location, "enclosing task"); - splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0); + n->value |= GOVD_THREADPRIVATE_WARNED; } if (decl2) - splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0); + splay_tree_insert (ctx->variables, (splay_tree_key)decl2, + DECL_CONTEXT (decl2) == current_function_decl + ? GOVD_SHARED | GOVD_SEEN : 0); return false; } @@ -5958,7 +5978,9 @@ gimplify_adjust_omp_clauses_1 (splay_tre break; ctx = ctx->outer_context; } - if (ctx == NULL) + if (ctx == NULL + && (DECL_CONTEXT (decl) != current_function_decl + || gimplify_omp_ctxp->region_type == ORT_WORKSHARE)) return 0; } code = OMP_CLAUSE_SHARED; --- gcc/omp-low.c.jj 2010-07-16 17:55:08.000000000 +0200 +++ gcc/omp-low.c 2010-07-22 14:09:33.000000000 +0200 @@ -2248,6 +2248,17 @@ lower_rec_input_clauses (tree clauses, g continue; break; case OMP_CLAUSE_SHARED: + if (pass == 0 + && is_global_var (OMP_CLAUSE_DECL (c)) + && (DECL_CONTEXT (OMP_CLAUSE_DECL (c)) + == current_function_decl) + && is_taskreg_ctx (ctx) + && !DECL_IGNORED_P (OMP_CLAUSE_DECL (c))) + { + new_var = omp_copy_decl_1 (OMP_CLAUSE_DECL (c), ctx); + SET_DECL_VALUE_EXPR (new_var, OMP_CLAUSE_DECL (c)); + DECL_HAS_VALUE_EXPR_P (new_var) = 1; + } if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL) { gcc_assert (is_global_var (OMP_CLAUSE_DECL (c))); --- gcc/testsuite/gcc.dg/gomp/tls-3.c.jj 2010-07-22 15:48:41.000000000 +0200 +++ gcc/testsuite/gcc.dg/gomp/tls-3.c 2010-07-22 15:48:47.000000000 +0200 @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target tls_native } */ + +int thr; +#pragma omp threadprivate(thr) + +void +foo (void) +{ + #pragma omp task untied /* { dg-error "enclosing task" } */ + { + static int thr2; + #pragma omp threadprivate(thr2) + static int thr3; + #pragma omp threadprivate(thr3) + thr++; /* { dg-error "used in untied task" } */ + thr2++; /* { dg-error "used in untied task" } */ + thr++; + thr2++; + } +}