This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][match-and-simplify] Change inner if-parsing
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 20 Aug 2014 14:40:43 +0200 (CEST)
- Subject: [PATCH][match-and-simplify] Change inner if-parsing
- Authentication-results: sourceware.org; auth=none
This changes inner ifs to have a result operand and to allow
a simplify pattern to have multiple such ifs, thus:
(simplify
(match-expression...)
(if (cond1)
result1)
(if (cond2)
result2)
...
resultdefault)
I'm not sure a default makes sense when a previous if failed
(the first taken result always wins), but maybe it's useful
to catch special-cases that simplify differently.
What's not yet implemented is nesting those ifs to factor
out common checks (useful for the sofar single pattern in
match-comparison.pd). I'll get to that now.
Bootstrap/regtest in progress on x86_64-unknown-linux-gnu.
Richard.
2014-08-20 Richard Biener <rguenther@suse.de>
* genmatch.c (parse_simplify): Change inner if parsing, allow
multiple ifs.
(parse_pattern): Adjust.
* match.pd: Adjust inner ifs.
* match-builtin.pd: Likewise.
* match-comparison.pd: Likewise.
* match-constant-folding.pd: Likewise.
* match-plusminus.pd: Likewise.
* match-rotate.pd: Likewise.
Index: match-and-simplify/gcc/genmatch.c
===================================================================
*** match-and-simplify.orig/gcc/genmatch.c 2014-08-20 14:32:10.826845091 +0200
--- match-and-simplify/gcc/genmatch.c 2014-08-20 14:32:19.236844512 +0200
*************** parse_op (cpp_reader *r)
*** 2227,2234 ****
(simplify "<ident>"
<op> <op>) */
! static simplify *
! parse_simplify (cpp_reader *r, source_location match_location)
{
const cpp_token *token = peek (r);
const char *id;
--- 2227,2235 ----
(simplify "<ident>"
<op> <op>) */
! static void
! parse_simplify (cpp_reader *r, source_location match_location,
! vec<simplify *>& simplifiers)
{
const cpp_token *token = peek (r);
const char *id;
*************** parse_simplify (cpp_reader *r, source_lo
*** 2248,2278 ****
token = peek (r);
! if (token->type != CPP_OPEN_PAREN)
! return new simplify (id, match, match_location, parse_op (r), token->src_loc);
!
! eat_token (r, CPP_OPEN_PAREN);
!
! token = peek (r);
! source_location result_loc = token->src_loc;
!
! // ( expr )
! if (peek_ident (r, "if") == 0)
{
! operand *result = parse_expr (r);
eat_token (r, CPP_CLOSE_PAREN);
! return new simplify (id, match, match_location, result, result_loc);
}
! // (if c-expr)
! eat_ident (r, "if");
! operand *ifexpr = parse_c_expr (r, CPP_OPEN_PAREN);
! eat_token (r, CPP_CLOSE_PAREN);
! result_loc = peek (r)->src_loc;
! simplify *s = new simplify (id, match, match_location, parse_op (r), result_loc);
! s->ifexpr_vec.safe_push (ifexpr);
! return s;
}
void parse_pattern (cpp_reader *, vec<simplify *>&);
--- 2249,2290 ----
token = peek (r);
! operand *result = NULL;
! source_location result_loc;
! while (!result
! && token->type == CPP_OPEN_PAREN)
{
! eat_token (r, CPP_OPEN_PAREN);
! if (peek_ident (r, "if"))
! {
! vec<operand *> ifexprs = vNULL;
! eat_ident (r, "if");
! ifexprs.safe_push (parse_c_expr (r, CPP_OPEN_PAREN));
! /* ??? Support nested (if ...) here. */
! token = peek (r);
! simplifiers.safe_push
! (new simplify (id, match, match_location, parse_op (r),
! token->src_loc, ifexprs));
! }
! else
! {
! result_loc = token->src_loc;
! result = parse_expr (r);
! }
eat_token (r, CPP_CLOSE_PAREN);
! token = peek (r);
}
! if (!result
! && token->type != CPP_CLOSE_PAREN)
! {
! result_loc = token->src_loc;
! result = parse_op (r);
! }
! if (result)
! simplifiers.safe_push
! (new simplify (id, match, match_location, result, result_loc));
}
void parse_pattern (cpp_reader *, vec<simplify *>&);
*************** parse_pattern (cpp_reader *r, vec<simpli
*** 2373,2379 ****
const cpp_token *token = peek (r);
const char *id = get_ident (r);
if (strcmp (id, "simplify") == 0)
! simplifiers.safe_push (parse_simplify (r, token->src_loc));
else if (strcmp (id, "for") == 0)
parse_for (r, token->src_loc, simplifiers);
else if (strcmp (id, "if") == 0)
--- 2385,2391 ----
const cpp_token *token = peek (r);
const char *id = get_ident (r);
if (strcmp (id, "simplify") == 0)
! parse_simplify (r, token->src_loc, simplifiers);
else if (strcmp (id, "for") == 0)
parse_for (r, token->src_loc, simplifiers);
else if (strcmp (id, "if") == 0)
Index: match-and-simplify/gcc/match-builtin.pd
===================================================================
*** match-and-simplify.orig/gcc/match-builtin.pd 2014-08-20 14:32:10.826845091 +0200
--- match-and-simplify/gcc/match-builtin.pd 2014-08-20 14:32:19.236844512 +0200
*************** along with GCC; see the file COPYING3.
*** 39,44 ****
/* This needs to be conditionalized on flag_unsafe_math_optimizations,
but we keep it for now to exercise function re-optimization.
It makes gcc.dg/pr43419.c FAIL execution though. */
! (if (REAL_VALUES_EQUAL (TREE_REAL_CST (@1), dconsthalf)))
! (BUILT_IN_SQRT @0))
--- 39,44 ----
/* This needs to be conditionalized on flag_unsafe_math_optimizations,
but we keep it for now to exercise function re-optimization.
It makes gcc.dg/pr43419.c FAIL execution though. */
! (if (REAL_VALUES_EQUAL (TREE_REAL_CST (@1), dconsthalf))
! (BUILT_IN_SQRT @0)))
Index: match-and-simplify/gcc/match-comparison.pd
===================================================================
*** match-and-simplify.orig/gcc/match-comparison.pd 2014-08-20 14:32:10.826845091 +0200
--- match-and-simplify/gcc/match-comparison.pd 2014-08-20 14:33:18.195840452 +0200
***************
*** 8,20 ****
to use only two patterns by swapping the operands instead
of changing the comparison code. */
(if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
! && tree_int_cst_sgn (@1) > 0))
! (op @0 @2))
! (simplify
! (op (mult @0 INTEGER_CST@1) integer_zerop@2)
(if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
! && tree_int_cst_sgn (@1) < 0))
! (op @2 @0)))
#if 0
(for op in lt le eq ne ge gt
--- 8,18 ----
to use only two patterns by swapping the operands instead
of changing the comparison code. */
(if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
! && tree_int_cst_sgn (@1) > 0)
! (op @0 @2))
(if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
! && tree_int_cst_sgn (@1) < 0)
! (op @2 @0))))
#if 0
(for op in lt le eq ne ge gt
Index: match-and-simplify/gcc/match-constant-folding.pd
===================================================================
*** match-and-simplify.orig/gcc/match-constant-folding.pd 2014-08-20 14:32:10.826845091 +0200
--- match-and-simplify/gcc/match-constant-folding.pd 2014-08-20 14:32:19.236844512 +0200
*************** along with GCC; see the file COPYING3.
*** 24,31 ****
(simplify
(minus @0 @0)
! (if (!HONOR_NANS (TYPE_MODE (type))))
! { build_zero_cst (type); })
(simplify
(mult @0 integer_zerop@1)
--- 24,31 ----
(simplify
(minus @0 @0)
! (if (!HONOR_NANS (TYPE_MODE (type)))
! { build_zero_cst (type); }))
(simplify
(mult @0 integer_zerop@1)
*************** along with GCC; see the file COPYING3.
*** 45,52 ****
and simplifies 0 % x to 0. */
(simplify
(trunc_mod integer_zerop@0 @1)
! (if (!integer_zerop (@1)))
! @0)
(simplify
(bit_ior @0 integer_all_onesp@1)
--- 45,52 ----
and simplifies 0 % x to 0. */
(simplify
(trunc_mod integer_zerop@0 @1)
! (if (!integer_zerop (@1))
! @0))
(simplify
(bit_ior @0 integer_all_onesp@1)
Index: match-and-simplify/gcc/match-plusminus.pd
===================================================================
*** match-and-simplify.orig/gcc/match-plusminus.pd 2014-08-20 14:32:10.826845091 +0200
--- match-and-simplify/gcc/match-plusminus.pd 2014-08-20 14:32:19.236844512 +0200
*************** along with GCC; see the file COPYING3.
*** 23,34 ****
/* Contract negates. */
(simplify
(plus:c @0 (negate @1))
! (if (!TYPE_SATURATING (type)))
! (minus @0 @1))
(simplify
(minus @0 (negate @1))
! (if (!TYPE_SATURATING (type)))
! (plus @0 @1))
/* Match patterns that allow contracting a plus-minus pair
--- 23,34 ----
/* Contract negates. */
(simplify
(plus:c @0 (negate @1))
! (if (!TYPE_SATURATING (type))
! (minus @0 @1)))
(simplify
(minus @0 (negate @1))
! (if (!TYPE_SATURATING (type))
! (plus @0 @1)))
/* Match patterns that allow contracting a plus-minus pair
*************** along with GCC; see the file COPYING3.
*** 65,72 ****
/* If the constant operation overflows we cannot do the transform
as we would introduce undefined overflow, for example
with (a - 1) + INT_MIN. */
! (if (!TREE_OVERFLOW (@1 = int_const_binop (PLUS_EXPR, @1, @2))))
! (plus @0 @1))
(simplify
(plus (minus INTEGER_CST@0 @1) INTEGER_CST@2)
(minus (plus @0 @2) @1))
--- 65,72 ----
/* If the constant operation overflows we cannot do the transform
as we would introduce undefined overflow, for example
with (a - 1) + INT_MIN. */
! (if (!TREE_OVERFLOW (@1 = int_const_binop (PLUS_EXPR, @1, @2)))
! (plus @0 @1)))
(simplify
(plus (minus INTEGER_CST@0 @1) INTEGER_CST@2)
(minus (plus @0 @2) @1))
Index: match-and-simplify/gcc/match-rotate.pd
===================================================================
*** match-and-simplify.orig/gcc/match-rotate.pd 2014-08-20 14:32:10.826845091 +0200
--- match-and-simplify/gcc/match-rotate.pd 2014-08-20 14:32:19.237844511 +0200
*************** along with GCC; see the file COPYING3.
*** 25,29 ****
(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
&& TYPE_PRECISION (type) == GET_MODE_PRECISION (TYPE_MODE (type))
&& tree_fits_uhwi_p (@1) && tree_fits_uhwi_p (@2)
! && wi::eq_p (TYPE_PRECISION (type), wi::add (@1, @2))))
! (lrotate @0 @1)))
--- 25,29 ----
(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
&& TYPE_PRECISION (type) == GET_MODE_PRECISION (TYPE_MODE (type))
&& tree_fits_uhwi_p (@1) && tree_fits_uhwi_p (@2)
! && wi::eq_p (TYPE_PRECISION (type), wi::add (@1, @2)))
! (lrotate @0 @1))))
Index: match-and-simplify/gcc/match.pd
===================================================================
*** match-and-simplify.orig/gcc/match.pd 2014-08-20 14:32:10.826845091 +0200
--- match-and-simplify/gcc/match.pd 2014-08-20 14:32:19.237844511 +0200
*************** along with GCC; see the file COPYING3.
*** 41,47 ****
#if GIMPLE
(simplify
(pointer_plus (addr@2 @0) INTEGER_CST@1)
! (if (is_gimple_min_invariant (@2)))
{
HOST_WIDE_INT off;
tree base = get_addr_base_and_unit_offset (@0, &off);
--- 41,47 ----
#if GIMPLE
(simplify
(pointer_plus (addr@2 @0) INTEGER_CST@1)
! (if (is_gimple_min_invariant (@2))
{
HOST_WIDE_INT off;
tree base = get_addr_base_and_unit_offset (@0, &off);
*************** along with GCC; see the file COPYING3.
*** 52,58 ****
build2 (MEM_REF, TREE_TYPE (TREE_TYPE (@2)),
build_fold_addr_expr (base),
build_int_cst (ptr_type_node, off)));
! })
#endif
--- 52,58 ----
build2 (MEM_REF, TREE_TYPE (TREE_TYPE (@2)),
build_fold_addr_expr (base),
build_int_cst (ptr_type_node, off)));
! }))
#endif
*************** along with GCC; see the file COPYING3.
*** 66,73 ****
if the new mask might be further optimized. */
(simplify
(bit_and (rshift@0 @1 INTEGER_CST@2) integer_onep)
! (if (compare_tree_int (@2, TYPE_PRECISION (TREE_TYPE (@1)) - 1) == 0))
! @0)
/* COMPLEX_EXPR and REALPART/IMAGPART_EXPR cancellations. */
(simplify
--- 66,73 ----
if the new mask might be further optimized. */
(simplify
(bit_and (rshift@0 @1 INTEGER_CST@2) integer_onep)
! (if (compare_tree_int (@2, TYPE_PRECISION (TREE_TYPE (@1)) - 1) == 0)
! @0))
/* COMPLEX_EXPR and REALPART/IMAGPART_EXPR cancellations. */
(simplify