diff options
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index c2ab96e..e5877c83 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -10273,9 +10273,24 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0)); /* Fall through. */ + case OMP_CLAUSE_NUM_TEAMS: + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS + && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) + && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))) + { + if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))) + { + remove = true; + break; + } + OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) + = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c), + pre_p, NULL, true); + } + /* Fall through. */ + case OMP_CLAUSE_SCHEDULE: case OMP_CLAUSE_NUM_THREADS: - case OMP_CLAUSE_NUM_TEAMS: case OMP_CLAUSE_THREAD_LIMIT: case OMP_CLAUSE_DIST_SCHEDULE: case OMP_CLAUSE_DEVICE: @@ -13535,7 +13550,8 @@ optimize_target_teams (tree target, gimple_seq *pre_p) { tree body = OMP_BODY (target); tree teams = walk_tree (&body, find_omp_teams, NULL, NULL); - tree num_teams = integer_zero_node; + tree num_teams_lower = NULL_TREE; + tree num_teams_upper = integer_zero_node; tree thread_limit = integer_zero_node; location_t num_teams_loc = EXPR_LOCATION (target); location_t thread_limit_loc = EXPR_LOCATION (target); @@ -13543,14 +13559,42 @@ optimize_target_teams (tree target, gimple_seq *pre_p) struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp; if (teams == NULL_TREE) - num_teams = integer_one_node; + num_teams_upper = integer_one_node; else for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c)) { if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS) { - p = &num_teams; + p = &num_teams_upper; num_teams_loc = OMP_CLAUSE_LOCATION (c); + if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)) + { + expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c); + if (TREE_CODE (expr) == INTEGER_CST) + num_teams_lower = expr; + else if (walk_tree (&expr, computable_teams_clause, + NULL, NULL)) + num_teams_lower = integer_minus_one_node; + else + { + num_teams_lower = expr; + gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context; + if (gimplify_expr (&num_teams_lower, pre_p, NULL, + is_gimple_val, fb_rvalue, false) + == GS_ERROR) + { + gimplify_omp_ctxp = target_ctx; + num_teams_lower = integer_minus_one_node; + } + else + { + gimplify_omp_ctxp = target_ctx; + if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR) + OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) + = num_teams_lower; + } + } + } } else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT) { @@ -13588,7 +13632,8 @@ optimize_target_teams (tree target, gimple_seq *pre_p) OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target); OMP_TARGET_CLAUSES (target) = c; c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS); - OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams; + OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper; + OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower; OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target); OMP_TARGET_CLAUSES (target) = c; } |