Commit 0227ffa9 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 1c9676e2
2019-11-15 Jakub Jelinek <jakub@redhat.com>
* 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 <luoxhu@linux.ibm.com>
* ipa-comdats.c: Fix comments typo.
......@@ -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)
......
......@@ -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 <widest_int> (scores[b + n], 1, false);
......@@ -1407,6 +1423,8 @@ omp_resolve_declare_variant (tree base)
{
tree variant1 = NULL_TREE, variant2 = NULL_TREE;
auto_vec <tree, 16> variants;
auto_vec <bool, 16> 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]));
......
2019-11-15 Jakub Jelinek <jakub@redhat.com>
* c-c++-common/gomp/declare-variant-13.c: New test.
2019-11-15 Jan Hubicka <hubicka@ucw.cz>
PR testsuite/92520
......
/* { 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" } } */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment