mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-27 22:03:57 +08:00
re PR middle-end/33880 (ICE: in extract_omp_for_data, at omp-low.c:162)
PR middle-end/33880 * tree-nested.c (walk_omp_for): New function. (convert_nonlocal_reference, convert_local_reference): Call walk_omp_for on OMP_FOR. (convert_call_expr): Call walk_body on OMP_FOR's OMP_FOR_PRE_INIT_BODY. * testsuite/libgomp.c/pr33880.c: New test. * testsuite/libgomp.fortran/pr33880.f90: New test. From-SVN: r131825
This commit is contained in:
parent
59805c3b29
commit
c256730cef
@ -1,3 +1,12 @@
|
||||
2008-01-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/33880
|
||||
* tree-nested.c (walk_omp_for): New function.
|
||||
(convert_nonlocal_reference, convert_local_reference): Call
|
||||
walk_omp_for on OMP_FOR.
|
||||
(convert_call_expr): Call walk_body on OMP_FOR's
|
||||
OMP_FOR_PRE_INIT_BODY.
|
||||
|
||||
2008-01-25 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/34966
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Nested function decomposition for trees.
|
||||
Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -665,6 +665,59 @@ walk_function (walk_tree_fn callback, struct nesting_info *info)
|
||||
walk_body (callback, info, &DECL_SAVED_TREE (info->context));
|
||||
}
|
||||
|
||||
/* Invoke CALLBACK on OMP_FOR init, cond, incr and pre-body. */
|
||||
|
||||
static void
|
||||
walk_omp_for (walk_tree_fn callback, struct nesting_info *info, tree for_stmt)
|
||||
{
|
||||
struct walk_stmt_info wi;
|
||||
tree t, list = NULL, empty;
|
||||
|
||||
walk_body (callback, info, &OMP_FOR_PRE_BODY (for_stmt));
|
||||
|
||||
empty = build_empty_stmt ();
|
||||
append_to_statement_list_force (empty, &list);
|
||||
memset (&wi, 0, sizeof (wi));
|
||||
wi.callback = callback;
|
||||
wi.info = info;
|
||||
wi.tsi = tsi_last (list);
|
||||
|
||||
t = OMP_FOR_INIT (for_stmt);
|
||||
gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
|
||||
SET_EXPR_LOCUS (empty, EXPR_LOCUS (t));
|
||||
wi.val_only = false;
|
||||
walk_tree (&GIMPLE_STMT_OPERAND (t, 0), callback, &wi, NULL);
|
||||
wi.val_only = true;
|
||||
wi.is_lhs = false;
|
||||
walk_tree (&GIMPLE_STMT_OPERAND (t, 1), callback, &wi, NULL);
|
||||
|
||||
t = OMP_FOR_COND (for_stmt);
|
||||
gcc_assert (COMPARISON_CLASS_P (t));
|
||||
SET_EXPR_LOCUS (empty, EXPR_LOCUS (t));
|
||||
wi.val_only = false;
|
||||
walk_tree (&TREE_OPERAND (t, 0), callback, &wi, NULL);
|
||||
wi.val_only = true;
|
||||
wi.is_lhs = false;
|
||||
walk_tree (&TREE_OPERAND (t, 1), callback, &wi, NULL);
|
||||
|
||||
t = OMP_FOR_INCR (for_stmt);
|
||||
gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
|
||||
SET_EXPR_LOCUS (empty, EXPR_LOCUS (t));
|
||||
wi.val_only = false;
|
||||
walk_tree (&GIMPLE_STMT_OPERAND (t, 0), callback, &wi, NULL);
|
||||
t = GIMPLE_STMT_OPERAND (t, 1);
|
||||
gcc_assert (BINARY_CLASS_P (t));
|
||||
wi.val_only = false;
|
||||
walk_tree (&TREE_OPERAND (t, 0), callback, &wi, NULL);
|
||||
wi.val_only = true;
|
||||
wi.is_lhs = false;
|
||||
walk_tree (&TREE_OPERAND (t, 1), callback, &wi, NULL);
|
||||
|
||||
/* Remove empty statement added above from the end of statement list. */
|
||||
tsi_delink (&wi.tsi);
|
||||
append_to_statement_list (list, &OMP_FOR_PRE_BODY (for_stmt));
|
||||
}
|
||||
|
||||
/* Similarly for ROOT and all functions nested underneath, depth first. */
|
||||
|
||||
static void
|
||||
@ -1065,6 +1118,13 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
|
||||
break;
|
||||
|
||||
case OMP_FOR:
|
||||
save_suppress = info->suppress_expansion;
|
||||
convert_nonlocal_omp_clauses (&OMP_FOR_CLAUSES (t), wi);
|
||||
walk_omp_for (convert_nonlocal_reference, info, t);
|
||||
walk_body (convert_nonlocal_reference, info, &OMP_FOR_BODY (t));
|
||||
info->suppress_expansion = save_suppress;
|
||||
break;
|
||||
|
||||
case OMP_SECTIONS:
|
||||
case OMP_SINGLE:
|
||||
save_suppress = info->suppress_expansion;
|
||||
@ -1350,6 +1410,13 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
|
||||
break;
|
||||
|
||||
case OMP_FOR:
|
||||
save_suppress = info->suppress_expansion;
|
||||
convert_local_omp_clauses (&OMP_FOR_CLAUSES (t), wi);
|
||||
walk_omp_for (convert_local_reference, info, t);
|
||||
walk_body (convert_local_reference, info, &OMP_FOR_BODY (t));
|
||||
info->suppress_expansion = save_suppress;
|
||||
break;
|
||||
|
||||
case OMP_SECTIONS:
|
||||
case OMP_SINGLE:
|
||||
save_suppress = info->suppress_expansion;
|
||||
@ -1682,6 +1749,8 @@ convert_call_expr (tree *tp, int *walk_subtrees, void *data)
|
||||
break;
|
||||
|
||||
case OMP_FOR:
|
||||
walk_body (convert_call_expr, info, &OMP_FOR_PRE_BODY (t));
|
||||
/* FALLTHRU */
|
||||
case OMP_SECTIONS:
|
||||
case OMP_SECTION:
|
||||
case OMP_SINGLE:
|
||||
|
@ -1,3 +1,9 @@
|
||||
2008-01-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/33880
|
||||
* testsuite/libgomp.c/pr33880.c: New test.
|
||||
* testsuite/libgomp.fortran/pr33880.f90: New test.
|
||||
|
||||
2008-01-24 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* configure: Regenerate.
|
||||
|
123
libgomp/testsuite/libgomp.c/pr33880.c
Normal file
123
libgomp/testsuite/libgomp.c/pr33880.c
Normal file
@ -0,0 +1,123 @@
|
||||
/* PR middle-end/33880 */
|
||||
/* { dg-do run } */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
void
|
||||
test1 (void)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
void bar (void)
|
||||
{
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
bar ();
|
||||
#pragma omp parallel for num_threads(4)
|
||||
for (i = 0; i < 100; i++)
|
||||
#pragma omp atomic
|
||||
j += 1;
|
||||
if (j != 101)
|
||||
abort ();
|
||||
#pragma omp parallel for lastprivate(i) num_threads(2)
|
||||
for (i = 0; i < 100; i++)
|
||||
#pragma omp atomic
|
||||
j += 1;
|
||||
if (i != 100)
|
||||
abort ();
|
||||
i = 3;
|
||||
bar ();
|
||||
if (j != 202)
|
||||
abort ();
|
||||
if (i != 4)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void
|
||||
test2 (void)
|
||||
{
|
||||
int i = -1, j = 99, k, l = 9, m = 0;
|
||||
void bar (void)
|
||||
{
|
||||
i++;
|
||||
j++;
|
||||
l++;
|
||||
m++;
|
||||
}
|
||||
bar ();
|
||||
#pragma omp parallel for num_threads(4)
|
||||
for (k = i; k < j; k += l)
|
||||
#pragma omp atomic
|
||||
m += 1;
|
||||
bar ();
|
||||
if (i != 1 || j != 101 || l != 11 || m != 12)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void
|
||||
test3 (void)
|
||||
{
|
||||
int i, j, k, l, m;
|
||||
void bar (void)
|
||||
{
|
||||
#pragma omp parallel for num_threads(4)
|
||||
for (i = j; i < k; i += l)
|
||||
#pragma omp atomic
|
||||
m += 1;
|
||||
}
|
||||
void baz (void)
|
||||
{
|
||||
#pragma omp parallel for num_threads(2) lastprivate(i)
|
||||
for (i = j; i < k * 2; i += l / 2)
|
||||
#pragma omp atomic
|
||||
m += 1;
|
||||
}
|
||||
i = 7;
|
||||
j = 0;
|
||||
k = 100;
|
||||
l = 2;
|
||||
m = 0;
|
||||
bar ();
|
||||
if (j != 0 || k != 100 || l != 2 || m != 50)
|
||||
abort ();
|
||||
baz ();
|
||||
if (i != 200 || j != 0 || k != 100 || l != 2 || m != 250)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void
|
||||
test4 (void)
|
||||
{
|
||||
int i, j, k, l, m = 0;
|
||||
int foo (void)
|
||||
{
|
||||
return j;
|
||||
}
|
||||
int bar (void)
|
||||
{
|
||||
return k;
|
||||
}
|
||||
int baz (void)
|
||||
{
|
||||
return l;
|
||||
}
|
||||
j = 0;
|
||||
k = 1000;
|
||||
l = 2;
|
||||
#pragma omp parallel for num_threads(8) lastprivate(i)
|
||||
for (i = foo (); i < bar (); i += baz ())
|
||||
#pragma omp atomic
|
||||
m += 1;
|
||||
if (i != 1000 || m != 500 || j != 0 || k != 1000 || l != 2)
|
||||
abort ();
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
test1 ();
|
||||
test2 ();
|
||||
test3 ();
|
||||
test4 ();
|
||||
return 0;
|
||||
}
|
18
libgomp/testsuite/libgomp.fortran/pr33880.f90
Normal file
18
libgomp/testsuite/libgomp.fortran/pr33880.f90
Normal file
@ -0,0 +1,18 @@
|
||||
! PR middle-end/33880
|
||||
! { dg-do run }
|
||||
|
||||
program pr33880
|
||||
integer :: i, j
|
||||
call something ()
|
||||
!$omp parallel do
|
||||
do i = 1, 1000
|
||||
!$omp atomic
|
||||
j = j + 1
|
||||
end do
|
||||
if (j .ne. 1000) call abort
|
||||
contains
|
||||
subroutine something()
|
||||
i = 0
|
||||
j = 0
|
||||
end subroutine something
|
||||
end program pr33880
|
Loading…
Reference in New Issue
Block a user