match.pd: Implement pattern from simplify_conversion_from_bitmask.
2014-11-10 Richard Biener <rguenther@suse.de> * match.pd: Implement pattern from simplify_conversion_from_bitmask. * tree-ssa-forwprop.c (simplify_conversion_from_bitmask): Remove. (pass_forwprop::execute): Do not call simplify_conversion_from_bitmask. From-SVN: r217284
This commit is contained in:
parent
bb60d646c1
commit
ea2042ba81
3 changed files with 18 additions and 90 deletions
|
@ -1,3 +1,9 @@
|
|||
2014-11-10 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* match.pd: Implement pattern from simplify_conversion_from_bitmask.
|
||||
* tree-ssa-forwprop.c (simplify_conversion_from_bitmask): Remove.
|
||||
(pass_forwprop::execute): Do not call simplify_conversion_from_bitmask.
|
||||
|
||||
2014-11-10 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* match.pd: Move rest of the conversion combining patterns
|
||||
|
|
12
gcc/match.pd
12
gcc/match.pd
|
@ -431,3 +431,15 @@ along with GCC; see the file COPYING3. If not see
|
|||
(unsigned) significand_size (TYPE_MODE (inter_type))
|
||||
>= inside_prec - !inside_unsignedp)
|
||||
(convert @0))))))
|
||||
|
||||
/* If we have a narrowing conversion to an integral type that is fed by a
|
||||
BIT_AND_EXPR, we might be able to remove the BIT_AND_EXPR if it merely
|
||||
masks off bits outside the final type (and nothing else). */
|
||||
(simplify
|
||||
(convert (bit_and @0 INTEGER_CST@1))
|
||||
(if (INTEGRAL_TYPE_P (type)
|
||||
&& INTEGRAL_TYPE_P (TREE_TYPE (@0))
|
||||
&& TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (@0))
|
||||
&& operand_equal_p (@1, build_low_bits_mask (TREE_TYPE (@1),
|
||||
TYPE_PRECISION (type)), 0))
|
||||
(convert @0)))
|
||||
|
|
|
@ -1214,78 +1214,6 @@ bailout:
|
|||
}
|
||||
|
||||
|
||||
/* GSI_P points to a statement which performs a narrowing integral
|
||||
conversion.
|
||||
|
||||
Look for cases like:
|
||||
|
||||
t = x & c;
|
||||
y = (T) t;
|
||||
|
||||
Turn them into:
|
||||
|
||||
t = x & c;
|
||||
y = (T) x;
|
||||
|
||||
If T is narrower than X's type and C merely masks off bits outside
|
||||
of (T) and nothing else.
|
||||
|
||||
Normally we'd let DCE remove the dead statement. But no DCE runs
|
||||
after the last forwprop/combine pass, so we remove the obviously
|
||||
dead code ourselves.
|
||||
|
||||
Return TRUE if a change was made, FALSE otherwise. */
|
||||
|
||||
static bool
|
||||
simplify_conversion_from_bitmask (gimple_stmt_iterator *gsi_p)
|
||||
{
|
||||
gimple stmt = gsi_stmt (*gsi_p);
|
||||
gimple rhs_def_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
|
||||
|
||||
/* See if the input for the conversion was set via a BIT_AND_EXPR and
|
||||
the only use of the BIT_AND_EXPR result is the conversion. */
|
||||
if (is_gimple_assign (rhs_def_stmt)
|
||||
&& gimple_assign_rhs_code (rhs_def_stmt) == BIT_AND_EXPR
|
||||
&& has_single_use (gimple_assign_lhs (rhs_def_stmt)))
|
||||
{
|
||||
tree rhs_def_operand1 = gimple_assign_rhs1 (rhs_def_stmt);
|
||||
tree rhs_def_operand2 = gimple_assign_rhs2 (rhs_def_stmt);
|
||||
tree lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
|
||||
|
||||
/* Now verify suitability of the BIT_AND_EXPR's operands.
|
||||
The first must be an SSA_NAME that we can propagate and the
|
||||
second must be an integer constant that masks out all the
|
||||
bits outside the final result's type, but nothing else. */
|
||||
if (TREE_CODE (rhs_def_operand1) == SSA_NAME
|
||||
&& ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs_def_operand1)
|
||||
&& TREE_CODE (rhs_def_operand2) == INTEGER_CST
|
||||
&& operand_equal_p (rhs_def_operand2,
|
||||
build_low_bits_mask (TREE_TYPE (rhs_def_operand2),
|
||||
TYPE_PRECISION (lhs_type)),
|
||||
0))
|
||||
{
|
||||
/* This is an optimizable case. Replace the source operand
|
||||
in the conversion with the first source operand of the
|
||||
BIT_AND_EXPR. */
|
||||
gimple_assign_set_rhs1 (stmt, rhs_def_operand1);
|
||||
stmt = gsi_stmt (*gsi_p);
|
||||
update_stmt (stmt);
|
||||
|
||||
/* There is no DCE after the last forwprop pass. It's
|
||||
easy to clean up the first order effects here. */
|
||||
gimple_stmt_iterator si;
|
||||
si = gsi_for_stmt (rhs_def_stmt);
|
||||
gsi_remove (&si, true);
|
||||
fwprop_invalidate_lattice (gimple_get_lhs (rhs_def_stmt));
|
||||
release_defs (rhs_def_stmt);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Helper function for simplify_gimple_switch. Remove case labels that
|
||||
have values outside the range of the new type. */
|
||||
|
||||
|
@ -2940,24 +2868,6 @@ pass_forwprop::execute (function *fun)
|
|||
&& maybe_clean_or_replace_eh_stmt (stmt, stmt))
|
||||
bitmap_set_bit (to_purge, bb->index);
|
||||
}
|
||||
else if (CONVERT_EXPR_CODE_P (code)
|
||||
|| code == FLOAT_EXPR
|
||||
|| code == FIX_TRUNC_EXPR)
|
||||
{
|
||||
/* If we have a narrowing conversion to an integral
|
||||
type that is fed by a BIT_AND_EXPR, we might be
|
||||
able to remove the BIT_AND_EXPR if it merely
|
||||
masks off bits outside the final type (and nothing
|
||||
else. */
|
||||
tree outer_type = TREE_TYPE (gimple_assign_lhs (stmt));
|
||||
tree inner_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
|
||||
if (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
|
||||
&& INTEGRAL_TYPE_P (outer_type)
|
||||
&& INTEGRAL_TYPE_P (inner_type)
|
||||
&& (TYPE_PRECISION (outer_type)
|
||||
<= TYPE_PRECISION (inner_type)))
|
||||
changed = simplify_conversion_from_bitmask (&gsi);
|
||||
}
|
||||
else if (code == VEC_PERM_EXPR)
|
||||
{
|
||||
int did_something = simplify_permutation (&gsi);
|
||||
|
|
Loading…
Add table
Reference in a new issue