From d0fb20beb1b45c61b41bef61ab48c2e7b425560c Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 13 Mar 2008 10:26:25 +0100 Subject: [PATCH] re PR middle-end/35185 (ICE using openmp with g++-4.2) PR middle-end/35185 * omp-low.c (lower_regimplify, init_tmp_var, save_tmp_var): Removed. (lower_omp_2): New function. (lower_omp_1, lower_omp): Rewritten. * testsuite/libgomp.c++/pr35185.C: New test. From-SVN: r133162 --- gcc/ChangeLog | 12 +- gcc/omp-low.c | 217 ++++++++++++++++---------------- libgomp/ChangeLog | 5 + libgomp/testsuite/libgomp.c++/pr35185.C | 33 +++++ 4 files changed, 152 insertions(+), 115 deletions(-) create mode 100644 libgomp/testsuite/libgomp.c++/pr35185.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 98dc171913c..2fa006f4dcd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-03-13 Jakub Jelinek + + PR middle-end/35185 + * omp-low.c (lower_regimplify, init_tmp_var, save_tmp_var): Removed. + (lower_omp_2): New function. + (lower_omp_1, lower_omp): Rewritten. + 2008-03-13 Danny Smith PR 35054 @@ -22,7 +29,6 @@ 2008-03-12 Paul Brook - gcc/ * config/arm/arm.c (arm_size_rtx_costs): Use ARM costs for Thumb-2. 2008-03-12 Uros Bizjak @@ -55,7 +61,7 @@ Adjust stack pointer by poping call clobered registers. (arm_expand_prologue): Use offsets->saved_regs_mask. Adjust stack pointer by pushing extra registers. - * gcc/config/arm.h (arm_stack_offsets): Add saved_regs_mask. + * config/arm.h (arm_stack_offsets): Add saved_regs_mask. 2008-03-12 Paolo Bonzini @@ -3974,7 +3980,7 @@ 2008-01-02 Arthur Norman PR target/34013 - * gcc/config/i386/i386.c (ix86_expand_prologue): Save red-zone + * config/i386/i386.c (ix86_expand_prologue): Save red-zone while stack probing. 2008-01-01 Douglas Gregor diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 47114b6941f..340c621d350 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -4880,184 +4880,177 @@ lower_omp_parallel (tree *stmt_p, omp_context *ctx) pop_gimplify_context (NULL_TREE); } - -/* Pass *TP back through the gimplifier within the context determined by WI. - This handles replacement of DECL_VALUE_EXPR, as well as adjusting the - flags on ADDR_EXPR. */ - -static void -lower_regimplify (tree *tp, struct walk_stmt_info *wi) -{ - enum gimplify_status gs; - tree pre = NULL; - - if (wi->is_lhs) - gs = gimplify_expr (tp, &pre, NULL, is_gimple_lvalue, fb_lvalue); - else if (wi->val_only) - gs = gimplify_expr (tp, &pre, NULL, is_gimple_val, fb_rvalue); - else - gs = gimplify_expr (tp, &pre, NULL, is_gimple_formal_tmp_var, fb_rvalue); - gcc_assert (gs == GS_ALL_DONE); - - if (pre) - tsi_link_before (&wi->tsi, pre, TSI_SAME_STMT); -} - -/* Copy EXP into a temporary. Insert the initialization statement before TSI. */ +/* Callback for lower_omp_1. Return non-NULL if *tp needs to be + regimplified. */ static tree -init_tmp_var (tree exp, tree_stmt_iterator *tsi) +lower_omp_2 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) { - tree t, stmt; - - t = create_tmp_var (TREE_TYPE (exp), NULL); - DECL_GIMPLE_REG_P (t) = 1; - stmt = build_gimple_modify_stmt (t, exp); - SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi))); - tsi_link_before (tsi, stmt, TSI_SAME_STMT); - - return t; -} - -/* Similarly, but copy from the temporary and insert the statement - after the iterator. */ + tree t = *tp; -static tree -save_tmp_var (tree exp, tree_stmt_iterator *tsi) -{ - tree t, stmt; + /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */ + if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t)) + return t; - t = create_tmp_var (TREE_TYPE (exp), NULL); - DECL_GIMPLE_REG_P (t) = 1; - stmt = build_gimple_modify_stmt (exp, t); - SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi))); - tsi_link_after (tsi, stmt, TSI_SAME_STMT); + /* If a global variable has been privatized, TREE_CONSTANT on + ADDR_EXPR might be wrong. */ + if (TREE_CODE (t) == ADDR_EXPR) + recompute_tree_invariant_for_addr_expr (t); - return t; + *walk_subtrees = !TYPE_P (t) && !DECL_P (t); + return NULL_TREE; } -/* Callback for walk_stmts. Lower the OpenMP directive pointed by TP. */ - -static tree -lower_omp_1 (tree *tp, int *walk_subtrees, void *data) +static void +lower_omp_1 (tree *tp, omp_context *ctx, tree_stmt_iterator *tsi) { - struct walk_stmt_info *wi = data; - omp_context *ctx = wi->info; tree t = *tp; + if (!t) + return; + + if (EXPR_HAS_LOCATION (t)) + input_location = EXPR_LOCATION (t); + /* If we have issued syntax errors, avoid doing any heavy lifting. Just replace the OpenMP directives with a NOP to avoid confusing RTL expansion. */ - if (errorcount && OMP_DIRECTIVE_P (*tp)) + if (errorcount && OMP_DIRECTIVE_P (t)) { *tp = build_empty_stmt (); - return NULL_TREE; + return; } - *walk_subtrees = 0; - switch (TREE_CODE (*tp)) + switch (TREE_CODE (t)) { + case STATEMENT_LIST: + { + tree_stmt_iterator i; + for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i)) + lower_omp_1 (tsi_stmt_ptr (i), ctx, &i); + } + break; + + case COND_EXPR: + lower_omp_1 (&COND_EXPR_THEN (t), ctx, NULL); + lower_omp_1 (&COND_EXPR_ELSE (t), ctx, NULL); + if (ctx + && walk_tree (&COND_EXPR_COND (t), lower_omp_2, ctx, NULL)) + { + tree pre = NULL; + gimplify_expr (&COND_EXPR_COND (t), &pre, NULL, + is_gimple_condexpr, fb_rvalue); + if (pre) + { + if (tsi) + tsi_link_before (tsi, pre, TSI_SAME_STMT); + else + { + append_to_statement_list (t, &pre); + *tp = pre; + } + } + } + break; + case CATCH_EXPR: + lower_omp_1 (&CATCH_BODY (t), ctx, NULL); + break; + case EH_FILTER_EXPR: + lower_omp_1 (&EH_FILTER_FAILURE (t), ctx, NULL); + break; + case TRY_CATCH_EXPR: + case TRY_FINALLY_EXPR: + lower_omp_1 (&TREE_OPERAND (t, 0), ctx, NULL); + lower_omp_1 (&TREE_OPERAND (t, 1), ctx, NULL); + break; + case BIND_EXPR: + lower_omp_1 (&BIND_EXPR_BODY (t), ctx, NULL); + break; + case RETURN_EXPR: + lower_omp_1 (&TREE_OPERAND (t, 0), ctx, NULL); + break; + case OMP_PARALLEL: ctx = maybe_lookup_ctx (t); lower_omp_parallel (tp, ctx); break; - case OMP_FOR: ctx = maybe_lookup_ctx (t); gcc_assert (ctx); lower_omp_for (tp, ctx); break; - case OMP_SECTIONS: ctx = maybe_lookup_ctx (t); gcc_assert (ctx); lower_omp_sections (tp, ctx); break; - case OMP_SINGLE: ctx = maybe_lookup_ctx (t); gcc_assert (ctx); lower_omp_single (tp, ctx); break; - case OMP_MASTER: ctx = maybe_lookup_ctx (t); gcc_assert (ctx); lower_omp_master (tp, ctx); break; - case OMP_ORDERED: ctx = maybe_lookup_ctx (t); gcc_assert (ctx); lower_omp_ordered (tp, ctx); break; - case OMP_CRITICAL: ctx = maybe_lookup_ctx (t); gcc_assert (ctx); lower_omp_critical (tp, ctx); break; - case VAR_DECL: - if (ctx && DECL_HAS_VALUE_EXPR_P (t)) + default: + if (ctx && walk_tree (tp, lower_omp_2, ctx, NULL)) { - lower_regimplify (&t, wi); - if (wi->val_only) + /* The gimplifier doesn't gimplify CALL_EXPR_STATIC_CHAIN. + Handle that here. */ + tree call = get_call_expr_in (t); + if (call + && CALL_EXPR_STATIC_CHAIN (call) + && walk_tree (&CALL_EXPR_STATIC_CHAIN (call), lower_omp_2, + ctx, NULL)) { - if (wi->is_lhs) - t = save_tmp_var (t, &wi->tsi); - else - t = init_tmp_var (t, &wi->tsi); + tree pre = NULL; + gimplify_expr (&CALL_EXPR_STATIC_CHAIN (call), &pre, NULL, + is_gimple_val, fb_rvalue); + if (pre) + { + if (tsi) + tsi_link_before (tsi, pre, TSI_SAME_STMT); + else + { + append_to_statement_list (t, &pre); + lower_omp_1 (&pre, ctx, NULL); + *tp = pre; + return; + } + } } - *tp = t; - } - break; - - case ADDR_EXPR: - if (ctx) - lower_regimplify (tp, wi); - break; - - case ARRAY_REF: - case ARRAY_RANGE_REF: - case REALPART_EXPR: - case IMAGPART_EXPR: - case COMPONENT_REF: - case VIEW_CONVERT_EXPR: - if (ctx) - lower_regimplify (tp, wi); - break; - case INDIRECT_REF: - if (ctx) - { - wi->is_lhs = false; - wi->val_only = true; - lower_regimplify (&TREE_OPERAND (t, 0), wi); + if (tsi == NULL) + gimplify_stmt (tp); + else + { + tree pre = NULL; + gimplify_expr (tp, &pre, NULL, is_gimple_stmt, fb_none); + if (pre) + tsi_link_before (tsi, pre, TSI_SAME_STMT); + } } break; - - default: - if (!TYPE_P (t) && !DECL_P (t)) - *walk_subtrees = 1; - break; } - - return NULL_TREE; } static void lower_omp (tree *stmt_p, omp_context *ctx) { - struct walk_stmt_info wi; - - memset (&wi, 0, sizeof (wi)); - wi.callback = lower_omp_1; - wi.info = ctx; - wi.val_only = true; - wi.want_locations = true; - - walk_stmts (&wi, stmt_p); + lower_omp_1 (stmt_p, ctx, NULL); } /* Main entry point. */ diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 30782434487..17d714c1d45 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,8 @@ +2008-03-13 Jakub Jelinek + + PR middle-end/35185 + * testsuite/libgomp.c++/pr35185.C: New test. + 2008-03-12 Jakub Jelinek PR middle-end/35549 diff --git a/libgomp/testsuite/libgomp.c++/pr35185.C b/libgomp/testsuite/libgomp.c++/pr35185.C new file mode 100644 index 00000000000..f22c7720787 --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/pr35185.C @@ -0,0 +1,33 @@ +// PR middle-end/35185 +// { dg-do run } + +extern "C" void abort (); + +struct S +{ + S () : s (6) {} + ~S () {} + int s; +}; + +__attribute__((noinline)) +bool +bar (S s) +{ + return s.s != 6; +} + +int +main () +{ + S s; + int err = 0; +#pragma omp parallel shared (s) + { + if (bar (s)) + #pragma omp atomic + err++; + } + if (err) + abort (); +} -- 2.11.4.GIT