re PR middle-end/27337 (OpenMP ICE in expand_expr_real_1 at expr.c:6814)
PR middle-end/27337 * gimplify.c (gimplify_scan_omp_clauses): Handle INDIRECT_REF around RESULT_DECL for result passed by reference. (gimplify_expr): Call omp_notice_variable when RESULT_DECL is seen. * omp-low.c (use_pointer_for_field): Don't look at DECL_HAS_VALUE_EXPR_P for RESULT_DECLs. (scan_omp_1): Call remap_decl on RESULT_DECLs. (lower_rec_input_clauses): Don't allocate VLA memory for the second time or var for passing by reference for OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE clauses. Allow creation of TREE_ADDRESSABLE variables when passing by reference. * omp-low.c (dump_omp_region): Fix output formatting. cp/ * cp-gimplify.c (cxx_omp_privatize_by_reference): New function. * cp-tree.h (cxx_omp_privatize_by_reference): New prototype. * cp-objcp-common.h (LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE): Define. testsuite/ * g++.dg/gomp/pr27337-1.C: New test. * g++.dg/gomp/pr27337-2.C: New test. libgomp/ * testsuite/libgomp.c++/pr27337.C: New test. From-SVN: r113456
This commit is contained in:
parent
2aee3e57ae
commit
077b0dfbfe
@ -1,5 +1,19 @@
|
||||
2006-05-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/27337
|
||||
* gimplify.c (gimplify_scan_omp_clauses): Handle INDIRECT_REF
|
||||
around RESULT_DECL for result passed by reference.
|
||||
(gimplify_expr): Call omp_notice_variable when RESULT_DECL is seen.
|
||||
* omp-low.c (use_pointer_for_field): Don't look at
|
||||
DECL_HAS_VALUE_EXPR_P for RESULT_DECLs.
|
||||
(scan_omp_1): Call remap_decl on RESULT_DECLs.
|
||||
(lower_rec_input_clauses): Don't allocate VLA memory for the second
|
||||
time or var for passing by reference for
|
||||
OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE clauses. Allow creation of
|
||||
TREE_ADDRESSABLE variables when passing by reference.
|
||||
|
||||
* omp-low.c (dump_omp_region): Fix output formatting.
|
||||
|
||||
PR middle-end/27328
|
||||
* omp-low.c (remove_exit_barrier): Handle NULL exit_bb.
|
||||
(expand_omp_parallel): Likewise.
|
||||
|
@ -1,3 +1,10 @@
|
||||
2006-05-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/27337
|
||||
* cp-gimplify.c (cxx_omp_privatize_by_reference): New function.
|
||||
* cp-tree.h (cxx_omp_privatize_by_reference): New prototype.
|
||||
* cp-objcp-common.h (LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE): Define.
|
||||
|
||||
2006-04-30 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/27094
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
|
||||
|
||||
Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
Contributed by Jason Merrill <jason@redhat.com>
|
||||
|
||||
This file is part of GCC.
|
||||
@ -870,3 +870,12 @@ cxx_omp_clause_dtor (tree clause, tree decl)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* True if OpenMP should privatize what this DECL points to rather
|
||||
than the DECL itself. */
|
||||
|
||||
bool
|
||||
cxx_omp_privatize_by_reference (tree decl)
|
||||
{
|
||||
return TREE_CODE (decl) == RESULT_DECL && DECL_BY_REFERENCE (decl);
|
||||
}
|
||||
|
@ -161,5 +161,7 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
|
||||
#define LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP cxx_omp_clause_assign_op
|
||||
#undef LANG_HOOKS_OMP_CLAUSE_DTOR
|
||||
#define LANG_HOOKS_OMP_CLAUSE_DTOR cxx_omp_clause_dtor
|
||||
#undef LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE
|
||||
#define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE cxx_omp_privatize_by_reference
|
||||
|
||||
#endif /* GCC_CP_OBJCP_COMMON */
|
||||
|
@ -4267,6 +4267,7 @@ extern tree cxx_omp_clause_default_ctor (tree, tree);
|
||||
extern tree cxx_omp_clause_copy_ctor (tree, tree, tree);
|
||||
extern tree cxx_omp_clause_assign_op (tree, tree, tree);
|
||||
extern tree cxx_omp_clause_dtor (tree, tree);
|
||||
extern bool cxx_omp_privatize_by_reference (tree);
|
||||
|
||||
/* in tree.c */
|
||||
extern void lang_check_failed (const char *, int,
|
||||
|
@ -4504,6 +4504,11 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel)
|
||||
remove = true;
|
||||
break;
|
||||
}
|
||||
/* Handle NRV results passed by reference. */
|
||||
if (TREE_CODE (decl) == INDIRECT_REF
|
||||
&& TREE_CODE (TREE_OPERAND (decl, 0)) == RESULT_DECL
|
||||
&& DECL_BY_REFERENCE (TREE_OPERAND (decl, 0)))
|
||||
OMP_CLAUSE_DECL (c) = decl = TREE_OPERAND (decl, 0);
|
||||
omp_add_variable (ctx, decl, flags);
|
||||
if (TREE_CODE (c) == OMP_CLAUSE_REDUCTION
|
||||
&& OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
|
||||
@ -4531,6 +4536,11 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel)
|
||||
remove = true;
|
||||
break;
|
||||
}
|
||||
/* Handle NRV results passed by reference. */
|
||||
if (TREE_CODE (decl) == INDIRECT_REF
|
||||
&& TREE_CODE (TREE_OPERAND (decl, 0)) == RESULT_DECL
|
||||
&& DECL_BY_REFERENCE (TREE_OPERAND (decl, 0)))
|
||||
OMP_CLAUSE_DECL (c) = decl = TREE_OPERAND (decl, 0);
|
||||
do_notice:
|
||||
if (outer_ctx)
|
||||
omp_notice_variable (outer_ctx, decl, true);
|
||||
@ -5558,6 +5568,13 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
|
||||
ret = gimplify_var_or_parm_decl (expr_p);
|
||||
break;
|
||||
|
||||
case RESULT_DECL:
|
||||
/* When within an OpenMP context, notice uses of variables. */
|
||||
if (gimplify_omp_ctxp)
|
||||
omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
|
||||
ret = GS_ALL_DONE;
|
||||
break;
|
||||
|
||||
case SSA_NAME:
|
||||
/* Allow callbacks into the gimplifier during optimization. */
|
||||
ret = GS_ALL_DONE;
|
||||
|
@ -491,7 +491,7 @@ use_pointer_for_field (tree decl, bool shared_p)
|
||||
without analyzing the expression whether or not its location
|
||||
is accessible to anyone else. In the case of nested parallel
|
||||
regions it certainly may be. */
|
||||
if (DECL_HAS_VALUE_EXPR_P (decl))
|
||||
if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
|
||||
return true;
|
||||
|
||||
/* Do not use copy-in/copy-out for variables that have their
|
||||
@ -724,7 +724,7 @@ dump_omp_region (FILE *file, struct omp_region *region, int indent)
|
||||
}
|
||||
|
||||
if (region->exit)
|
||||
fprintf (file, "%*sbb: %d: OMP_RETURN\n", indent, "",
|
||||
fprintf (file, "%*sbb %d: OMP_RETURN\n", indent, "",
|
||||
region->exit->index);
|
||||
else
|
||||
fprintf (file, "%*s[no exit marker]\n", indent, "");
|
||||
@ -1286,6 +1286,7 @@ scan_omp_1 (tree *tp, int *walk_subtrees, void *data)
|
||||
case VAR_DECL:
|
||||
case PARM_DECL:
|
||||
case LABEL_DECL:
|
||||
case RESULT_DECL:
|
||||
if (ctx)
|
||||
*tp = remap_decl (t, &ctx->cb);
|
||||
break;
|
||||
@ -1518,10 +1519,14 @@ lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
|
||||
break;
|
||||
case OMP_CLAUSE_SHARED:
|
||||
case OMP_CLAUSE_FIRSTPRIVATE:
|
||||
case OMP_CLAUSE_LASTPRIVATE:
|
||||
case OMP_CLAUSE_COPYIN:
|
||||
case OMP_CLAUSE_REDUCTION:
|
||||
break;
|
||||
case OMP_CLAUSE_LASTPRIVATE:
|
||||
if (pass != 0
|
||||
&& OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@ -1564,7 +1569,8 @@ lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
|
||||
code that expects a pointer to something that expects
|
||||
a direct variable. Note that this doesn't apply to
|
||||
C++, since reference types are disallowed in data
|
||||
sharing clauses there. */
|
||||
sharing clauses there, except for NRV optimized
|
||||
return values. */
|
||||
if (pass == 0)
|
||||
continue;
|
||||
|
||||
@ -1575,7 +1581,9 @@ lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
|
||||
if (DECL_NAME (var))
|
||||
name = IDENTIFIER_POINTER (DECL_NAME (new_var));
|
||||
|
||||
x = create_tmp_var (TREE_TYPE (TREE_TYPE (new_var)), name);
|
||||
x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
|
||||
name);
|
||||
gimple_add_tmp_var (x);
|
||||
x = build_fold_addr_expr_with_type (x, TREE_TYPE (new_var));
|
||||
}
|
||||
else
|
||||
|
@ -1,5 +1,9 @@
|
||||
2006-05-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/27337
|
||||
* g++.dg/gomp/pr27337-1.C: New test.
|
||||
* g++.dg/gomp/pr27337-2.C: New test.
|
||||
|
||||
PR middle-end/27328
|
||||
* gcc.dg/gomp/pr27328.c: New test.
|
||||
|
||||
|
22
gcc/testsuite/g++.dg/gomp/pr27337-1.C
Normal file
22
gcc/testsuite/g++.dg/gomp/pr27337-1.C
Normal file
@ -0,0 +1,22 @@
|
||||
// PR middle-end/27337
|
||||
// { dg-do compile }
|
||||
|
||||
struct S
|
||||
{
|
||||
S ();
|
||||
~S ();
|
||||
double &operator* () const;
|
||||
};
|
||||
|
||||
S
|
||||
foo ()
|
||||
{
|
||||
int i;
|
||||
S ret;
|
||||
|
||||
#pragma omp parallel for
|
||||
for (i = 0; i < 2; i++)
|
||||
*ret += i;
|
||||
|
||||
return ret;
|
||||
}
|
22
gcc/testsuite/g++.dg/gomp/pr27337-2.C
Normal file
22
gcc/testsuite/g++.dg/gomp/pr27337-2.C
Normal file
@ -0,0 +1,22 @@
|
||||
// PR middle-end/27337
|
||||
// { dg-do compile }
|
||||
|
||||
struct S
|
||||
{
|
||||
S ();
|
||||
~S ();
|
||||
int i;
|
||||
};
|
||||
|
||||
S
|
||||
foo ()
|
||||
{
|
||||
int i;
|
||||
S ret;
|
||||
|
||||
#pragma omp parallel for firstprivate (ret) lastprivate (ret)
|
||||
for (i = 0; i < 2; i++)
|
||||
ret.i += i;
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,3 +1,8 @@
|
||||
2006-05-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/27337
|
||||
* testsuite/libgomp.c++/pr27337.C: New test.
|
||||
|
||||
2006-04-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c/26171
|
||||
|
91
libgomp/testsuite/libgomp.c++/pr27337.C
Normal file
91
libgomp/testsuite/libgomp.c++/pr27337.C
Normal file
@ -0,0 +1,91 @@
|
||||
// PR middle-end/27337
|
||||
// { dg-do run }
|
||||
|
||||
#include <omp.h>
|
||||
|
||||
extern "C" void abort (void);
|
||||
|
||||
struct S
|
||||
{
|
||||
S ();
|
||||
~S ();
|
||||
S (const S &);
|
||||
int i;
|
||||
};
|
||||
|
||||
int n[3];
|
||||
|
||||
S::S () : i(18)
|
||||
{
|
||||
if (omp_get_thread_num () != 0)
|
||||
#pragma omp atomic
|
||||
n[0]++;
|
||||
}
|
||||
|
||||
S::~S ()
|
||||
{
|
||||
if (omp_get_thread_num () != 0)
|
||||
#pragma omp atomic
|
||||
n[1]++;
|
||||
}
|
||||
|
||||
S::S (const S &x)
|
||||
{
|
||||
if (x.i != 18)
|
||||
abort ();
|
||||
i = 118;
|
||||
if (omp_get_thread_num () != 0)
|
||||
#pragma omp atomic
|
||||
n[2]++;
|
||||
}
|
||||
|
||||
S
|
||||
foo ()
|
||||
{
|
||||
int i;
|
||||
S ret;
|
||||
|
||||
#pragma omp parallel for firstprivate (ret) lastprivate (ret) \
|
||||
schedule (static, 1) num_threads (4)
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
ret.i += omp_get_thread_num ();
|
||||
// FIXME: The following barrier should be unnecessary.
|
||||
#pragma omp barrier
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
S
|
||||
bar ()
|
||||
{
|
||||
int i;
|
||||
S ret;
|
||||
|
||||
#pragma omp parallel for num_threads (4)
|
||||
for (i = 0; i < 4; i++)
|
||||
#pragma omp atomic
|
||||
ret.i += omp_get_thread_num () + 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
S x;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
omp_set_dynamic (false);
|
||||
x = foo ();
|
||||
if (n[0] != 0 || n[1] != 3 || n[2] != 3)
|
||||
abort ();
|
||||
if (x.i != 118 + 3)
|
||||
abort ();
|
||||
x = bar ();
|
||||
if (n[0] != 0 || n[1] != 3 || n[2] != 3)
|
||||
abort ();
|
||||
if (x.i != 18 + 0 + 1 + 2 + 3 + 4)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user