aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fold-const.cc7
-rw-r--r--gcc/gimplify.cc19
-rw-r--r--gcc/omp-low.cc2
-rw-r--r--gcc/poly-int.h19
4 files changed, 36 insertions, 11 deletions
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 3e20538..1275ef7 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -1284,6 +1284,13 @@ poly_int_binop (poly_wide_int &res, enum tree_code code,
return false;
break;
+ case BIT_AND_EXPR:
+ if (TREE_CODE (arg2) != INTEGER_CST
+ || !can_and_p (wi::to_poly_wide (arg1), wi::to_wide (arg2),
+ &res))
+ return false;
+ break;
+
case BIT_IOR_EXPR:
if (TREE_CODE (arg2) != INTEGER_CST
|| !can_ior_p (wi::to_poly_wide (arg1), wi::to_wide (arg2),
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index e90220c..55cab7a 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -9301,7 +9301,8 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
&& (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
&& DECL_SIZE (decl))
{
- if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+ tree size;
+ if (!poly_int_tree_p (DECL_SIZE (decl)))
{
splay_tree_node n2;
tree t = DECL_VALUE_EXPR (decl);
@@ -9312,16 +9313,14 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
n2->value |= GOVD_SEEN;
}
else if (omp_privatize_by_reference (decl)
- && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
- && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
- != INTEGER_CST))
+ && (size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
+ && !poly_int_tree_p (size))
{
splay_tree_node n2;
- tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
- gcc_assert (DECL_P (t));
- n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
+ gcc_assert (DECL_P (size));
+ n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) size);
if (n2)
- omp_notice_variable (ctx, t, true);
+ omp_notice_variable (ctx, size, true);
}
}
@@ -14581,7 +14580,7 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
if (DECL_SIZE (decl)
- && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+ && !poly_int_tree_p (DECL_SIZE (decl)))
{
tree decl2 = DECL_VALUE_EXPR (decl);
gcc_assert (INDIRECT_REF_P (decl2));
@@ -15322,7 +15321,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
if (!DECL_P (decl))
break;
if (DECL_SIZE (decl)
- && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+ && !poly_int_tree_p (DECL_SIZE (decl)))
{
tree decl2 = DECL_VALUE_EXPR (decl);
gcc_assert (INDIRECT_REF_P (decl2));
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index e369df6..e1036ad 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -1461,7 +1461,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
else
install_var_field (decl, false, 11, ctx);
if (DECL_SIZE (decl)
- && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+ && !poly_int_tree_p (DECL_SIZE (decl)))
{
tree decl2 = DECL_VALUE_EXPR (decl);
gcc_assert (INDIRECT_REF_P (decl2));
diff --git a/gcc/poly-int.h b/gcc/poly-int.h
index 7c8901a..77f7875 100644
--- a/gcc/poly-int.h
+++ b/gcc/poly-int.h
@@ -1906,6 +1906,25 @@ known_alignment (const poly_int<N, Ca> &a)
return r & -r;
}
+/* Return true if we can compute A & B at compile time, storing the
+ result in RES if so. */
+
+template<unsigned int N, typename Ca, typename Cb, typename Cr>
+inline typename if_nonpoly<Cb, bool>::type
+can_and_p (const poly_int<N, Ca> &a, Cb b, Cr *result)
+{
+ /* Coefficients 1 and above must be a multiple of something greater
+ than ~B. */
+ typedef POLY_INT_TYPE (Ca) int_type;
+ if (N >= 2)
+ for (unsigned int i = 1; i < N; i++)
+ if ((-(a.coeffs[i] & -a.coeffs[i]) & ~b) != int_type (0))
+ return false;
+ *result = a;
+ result->coeffs[0] &= b;
+ return true;
+}
+
/* Return true if we can compute A | B at compile time, storing the
result in RES if so. */