mirror of git://gcc.gnu.org/git/gcc.git
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>
|
2008-01-25 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
PR tree-optimization/34966
|
PR tree-optimization/34966
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Nested function decomposition for trees.
|
/* 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.
|
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));
|
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. */
|
/* Similarly for ROOT and all functions nested underneath, depth first. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1065,6 +1118,13 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OMP_FOR:
|
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_SECTIONS:
|
||||||
case OMP_SINGLE:
|
case OMP_SINGLE:
|
||||||
save_suppress = info->suppress_expansion;
|
save_suppress = info->suppress_expansion;
|
||||||
|
@ -1350,6 +1410,13 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OMP_FOR:
|
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_SECTIONS:
|
||||||
case OMP_SINGLE:
|
case OMP_SINGLE:
|
||||||
save_suppress = info->suppress_expansion;
|
save_suppress = info->suppress_expansion;
|
||||||
|
@ -1682,6 +1749,8 @@ convert_call_expr (tree *tp, int *walk_subtrees, void *data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OMP_FOR:
|
case OMP_FOR:
|
||||||
|
walk_body (convert_call_expr, info, &OMP_FOR_PRE_BODY (t));
|
||||||
|
/* FALLTHRU */
|
||||||
case OMP_SECTIONS:
|
case OMP_SECTIONS:
|
||||||
case OMP_SECTION:
|
case OMP_SECTION:
|
||||||
case OMP_SINGLE:
|
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>
|
2008-01-24 David Edelsohn <edelsohn@gnu.org>
|
||||||
|
|
||||||
* configure: Regenerate.
|
* configure: Regenerate.
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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