From: Jakub Jelinek Date: Fri, 15 Nov 2019 08:32:36 +0000 (+0100) Subject: gimplify.c (gimplify_call_expr): Don't call omp_resolve_declare_variant after gimplif... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0227ffa98e122d5716d508c435cb8323cd93bfef;p=gcc.git gimplify.c (gimplify_call_expr): Don't call omp_resolve_declare_variant after gimplification. * gimplify.c (gimplify_call_expr): Don't call omp_resolve_declare_variant after gimplification. * omp-general.c (omp_context_selector_matches): For isa that might match in some other function, defer if in declare simd function. (omp_context_compute_score): Don't look for " score" in construct trait set. Set *score to -1 if it can't ever match. (omp_resolve_declare_variant): If any variants need to be deferred, don't punt immediately, but compute scores of all variants and if ther eis a score winner that doesn't need to be deferred, return that. * c-c++-common/gomp/declare-variant-13.c: New test. From-SVN: r278280 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e5d9e38196c..6810dfb194b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2019-11-15 Jakub Jelinek + + * gimplify.c (gimplify_call_expr): Don't call + omp_resolve_declare_variant after gimplification. + * omp-general.c (omp_context_selector_matches): For isa that might + match in some other function, defer if in declare simd function. + (omp_context_compute_score): Don't look for " score" in construct + trait set. Set *score to -1 if it can't ever match. + (omp_resolve_declare_variant): If any variants need to be deferred, + don't punt immediately, but compute scores of all variants and if + ther eis a score winner that doesn't need to be deferred, return that. + 2019-11-15 Luo Xiong Hu * ipa-comdats.c: Fix comments typo. diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 87a64054514..0bbd475b3dd 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -3391,7 +3391,10 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value) /* Remember the original function pointer type. */ fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p)); - if (flag_openmp && fndecl) + if (flag_openmp + && fndecl + && cfun + && (cfun->curr_properties & PROP_gimple_any) == 0) { tree variant = omp_resolve_declare_variant (fndecl); if (variant != fndecl) diff --git a/gcc/omp-general.c b/gcc/omp-general.c index a8efc106779..c9c4f3aba97 100644 --- a/gcc/omp-general.c +++ b/gcc/omp-general.c @@ -939,6 +939,21 @@ omp_context_selector_matches (tree ctx) isa); if (r == 0 || (r == -1 && symtab->state != PARSING)) { + /* If isa is valid on the target, but not in the + current function and current function has + #pragma omp declare simd on it, some simd clones + might have the isa added later on. */ + if (r == -1 + && targetm.simd_clone.compute_vecsize_and_simdlen) + { + tree attrs + = DECL_ATTRIBUTES (current_function_decl); + if (lookup_attribute ("omp declare simd", attrs)) + { + ret = -1; + continue; + } + } /* If we are or might be in a target region or declare target function, need to take into account also offloading values. */ @@ -1355,12 +1370,13 @@ omp_context_compute_score (tree ctx, widest_int *score, bool declare_simd) bool ret = false; *score = 1; for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)) - for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2)) - if (tree t3 = TREE_VALUE (t2)) - if (TREE_PURPOSE (t3) - && strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t3)), " score") == 0 - && TREE_CODE (TREE_VALUE (t3)) == INTEGER_CST) - *score += wi::to_widest (TREE_VALUE (t3)); + if (TREE_VALUE (t1) != construct) + for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2)) + if (tree t3 = TREE_VALUE (t2)) + if (TREE_PURPOSE (t3) + && strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t3)), " score") == 0 + && TREE_CODE (TREE_VALUE (t3)) == INTEGER_CST) + *score += wi::to_widest (TREE_VALUE (t3)); if (construct || has_kind || has_arch || has_isa) { int scores[12]; @@ -1378,7 +1394,7 @@ omp_context_compute_score (tree ctx, widest_int *score, bool declare_simd) { if (scores[b + n] < 0) { - *score = 0; + *score = -1; return ret; } *score += wi::shifted_mask (scores[b + n], 1, false); @@ -1407,6 +1423,8 @@ omp_resolve_declare_variant (tree base) { tree variant1 = NULL_TREE, variant2 = NULL_TREE; auto_vec variants; + auto_vec defer; + bool any_deferred = false; for (tree attr = DECL_ATTRIBUTES (base); attr; attr = TREE_CHAIN (attr)) { attr = lookup_attribute ("omp declare variant base", attr); @@ -1421,13 +1439,95 @@ omp_resolve_declare_variant (tree base) break; case -1: /* Needs to be deferred. */ - return base; + any_deferred = true; + variants.safe_push (attr); + defer.safe_push (true); + break; default: variants.safe_push (attr); + defer.safe_push (false); + break; } } if (variants.length () == 0) return base; + + if (any_deferred) + { + widest_int max_score1 = 0; + widest_int max_score2 = 0; + bool first = true; + unsigned int i; + tree attr1, attr2; + FOR_EACH_VEC_ELT (variants, i, attr1) + { + widest_int score1; + widest_int score2; + bool need_two; + tree ctx = TREE_VALUE (TREE_VALUE (attr1)); + need_two = omp_context_compute_score (ctx, &score1, false); + if (need_two) + omp_context_compute_score (ctx, &score2, true); + else + score2 = score1; + if (first) + { + first = false; + max_score1 = score1; + max_score2 = score2; + if (!defer[i]) + { + variant1 = attr1; + variant2 = attr1; + } + } + else + { + if (max_score1 == score1) + variant1 = NULL_TREE; + else if (score1 > max_score1) + { + max_score1 = score1; + variant1 = defer[i] ? NULL_TREE : attr1; + } + if (max_score2 == score2) + variant2 = NULL_TREE; + else if (score2 > max_score2) + { + max_score2 = score2; + variant2 = defer[i] ? NULL_TREE : attr1; + } + } + } + + /* If there is a clear winner variant with the score which is not + deferred, verify it is not a strict subset of any other context + selector and if it is not, it is the best alternative no matter + whether the others do or don't match. */ + if (variant1 && variant1 == variant2) + { + tree ctx1 = TREE_VALUE (TREE_VALUE (variant1)); + FOR_EACH_VEC_ELT (variants, i, attr2) + { + if (attr2 == variant1) + continue; + tree ctx2 = TREE_VALUE (TREE_VALUE (attr2)); + int r = omp_context_selector_compare (ctx1, ctx2); + if (r == -1) + { + /* The winner is a strict subset of ctx2, can't + decide now. */ + variant1 = NULL_TREE; + break; + } + } + if (variant1) + return TREE_PURPOSE (TREE_VALUE (variant1)); + } + + return base; + } + if (variants.length () == 1) return TREE_PURPOSE (TREE_VALUE (variants[0])); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0d96f0a3b27..6d7a132f08f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-11-15 Jakub Jelinek + + * c-c++-common/gomp/declare-variant-13.c: New test. + 2019-11-15 Jan Hubicka PR testsuite/92520 diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-13.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-13.c new file mode 100644 index 00000000000..68e6a897950 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-13.c @@ -0,0 +1,24 @@ +/* { dg-do compile { target vect_simd_clones } } */ +/* { dg-additional-options "-fdump-tree-gimple" } */ +/* { dg-additional-options "-mno-sse3" { target { i?86-*-* x86_64-*-* } } } */ + +int f01 (int); +int f02 (int); +int f03 (int); +int f04 (int); +#pragma omp declare variant (f01) match (device={isa("avx512f")}) /* 4 or 8 */ +#pragma omp declare variant (f02) match (implementation={vendor(score(3):gnu)},device={kind(cpu)}) /* (1 or 2) + 3 */ +#pragma omp declare variant (f03) match (user={condition(score(9):1)}) +#pragma omp declare variant (f04) match (implementation={vendor(score(6):gnu)},device={kind(host)}) /* (1 or 2) + 6 */ +int f05 (int); + +#pragma omp declare simd +int +test1 (int x) +{ + /* 0 or 1 (the latter if in a declare simd clone) constructs in OpenMP context, + isa has score 2^2 or 2^3. We can't decide on whether avx512f will match or + not, that also depends on whether it is a declare simd clone or not and which + one, but the f03 variant has a higher score anyway. */ + return f05 (x); /* { dg-final { scan-tree-dump-times "f03 \\\(x" 1 "gimple" } } */ +}