Commit 46998ae9 authored by Jonas Fietz's avatar Jonas Fietz
Browse files

Add optimizations for Proj after Cond using VRP

This uses the vrp information to evaluate int projs.
This optimizes cases like:
x |= 33;
y = x & 96;
to y = 1;

[r27100]
parent 285b86f3
......@@ -624,25 +624,30 @@ ir_graph_pass_t *set_vrp_pass(const char *name) {
}
pn_Cmp vrp_cmp(ir_node *left, ir_node *right) {
if (left->vrp.range_type == VRP_UNDEFINED ||
left->vrp.range_type == VRP_VARYING ||
if (!(left->vrp.range_type == VRP_UNDEFINED ||
left->vrp.range_type == VRP_VARYING) && !(
right->vrp.range_type == VRP_UNDEFINED ||
right->vrp.range_type == VRP_VARYING)
return pn_Cmp_False;
tarval *lefttop = left->vrp.range_top;
tarval *leftbottom = left->vrp.range_bottom;
tarval *righttop = right->vrp.range_top;
tarval *rightbottom = right->vrp.range_bottom;
if (left->vrp.range_type == VRP_RANGE && right->vrp.range_type ==
VRP_RANGE) {
if (tarval_cmp(lefttop, rightbottom) == pn_Cmp_Lt) {
return pn_Cmp_Lt;
}
if (tarval_cmp(leftbottom, righttop) == pn_Cmp_Gt) {
return pn_Cmp_Gt;
right->vrp.range_type == VRP_VARYING)) {
tarval *lefttop = left->vrp.range_top;
tarval *leftbottom = left->vrp.range_bottom;
tarval *righttop = right->vrp.range_top;
tarval *rightbottom = right->vrp.range_bottom;
if (left->vrp.range_type == VRP_RANGE && right->vrp.range_type ==
VRP_RANGE) {
if (tarval_cmp(lefttop, rightbottom) == pn_Cmp_Lt) {
return pn_Cmp_Lt;
}
if (tarval_cmp(leftbottom, righttop) == pn_Cmp_Gt) {
return pn_Cmp_Gt;
}
}
}
if (!tarval_is_null(tarval_and(left->vrp.bits_set, right->vrp.bits_not_set)) ||
!tarval_is_null(tarval_and(left->vrp.bits_not_set, right->vrp.bits_set))) {
return pn_Cmp_Lg;
}
// TODO: We can get way more information here
......
......@@ -472,86 +472,89 @@ static tarval *computed_value_Proj_Cmp(const ir_node *n) {
return new_tarval_from_long (proj_nr == pn_Cmp_Eq, mode_b) */
return new_tarval_from_long (proj_nr & pn_Cmp_Eq, mode_b);
}
else {
tarval *taa = value_of(aa);
tarval *tab = value_of(ab);
ir_mode *mode = get_irn_mode(aa);
tarval *taa = value_of(aa);
tarval *tab = value_of(ab);
ir_mode *mode = get_irn_mode(aa);
/*
* The predecessors of Cmp are target values. We can evaluate
* the Cmp.
*/
if ((taa != tarval_bad) && (tab != tarval_bad)) {
/* strange checks... */
pn_Cmp flags = tarval_cmp(taa, tab);
if (flags != pn_Cmp_False) {
return new_tarval_from_long (proj_nr & flags, mode_b);
}
}
/* for integer values, we can check against MIN/MAX */
else if (mode_is_int(mode)) {
/* MIN <=/> x. This results in true/false. */
if (taa == get_mode_min(mode)) {
/*
* The predecessors of Cmp are target values. We can evaluate
* the Cmp.
*/
if ((taa != tarval_bad) && (tab != tarval_bad)) {
/* strange checks... */
pn_Cmp flags = tarval_cmp(taa, tab);
if (flags != pn_Cmp_False) {
return new_tarval_from_long (proj_nr & flags, mode_b);
}
}
/* for integer values, we can check against MIN/MAX */
else if (mode_is_int(mode)) {
/* MIN <=/> x. This results in true/false. */
if (taa == get_mode_min(mode)) {
/* a compare with the MIN value */
if (proj_nr == pn_Cmp_Le)
return get_tarval_b_true();
else if (proj_nr == pn_Cmp_Gt)
return get_tarval_b_false();
}
/* x >=/< MIN. This results in true/false. */
else
if (tab == get_mode_min(mode)) {
/* a compare with the MIN value */
if (proj_nr == pn_Cmp_Ge)
return get_tarval_b_true();
else if (proj_nr == pn_Cmp_Lt)
return get_tarval_b_false();
}
/* MAX >=/< x. This results in true/false. */
else if (taa == get_mode_max(mode)) {
if (proj_nr == pn_Cmp_Ge)
return get_tarval_b_true();
else if (proj_nr == pn_Cmp_Lt)
return get_tarval_b_false();
}
/* x <=/> MAX. This results in true/false. */
else if (tab == get_mode_max(mode)) {
if (proj_nr == pn_Cmp_Le)
return get_tarval_b_true();
else if (proj_nr == pn_Cmp_Gt)
return get_tarval_b_false();
}
/* x >=/< MIN. This results in true/false. */
else
if (tab == get_mode_min(mode)) {
/* a compare with the MIN value */
if (proj_nr == pn_Cmp_Ge)
return get_tarval_b_true();
else if (proj_nr == pn_Cmp_Lt)
return get_tarval_b_false();
}
/* MAX >=/< x. This results in true/false. */
else if (taa == get_mode_max(mode)) {
if (proj_nr == pn_Cmp_Ge)
return get_tarval_b_true();
else if (proj_nr == pn_Cmp_Lt)
return get_tarval_b_false();
}
/* x <=/> MAX. This results in true/false. */
else if (tab == get_mode_max(mode)) {
if (proj_nr == pn_Cmp_Le)
return get_tarval_b_true();
else if (proj_nr == pn_Cmp_Gt)
return get_tarval_b_false();
}
pn_Cmp cmp_result = vrp_cmp(aa, ab);
if (cmp_result != pn_Cmp_False) {
return new_tarval_from_long(cmp_result & proj_nr, mode_b);
}
/*
* The predecessors are Allocs or (void*)(0) constants. Allocs never
* return NULL, they raise an exception. Therefore we can predict
* the Cmp result.
*/
else {
ir_node *aaa = skip_Proj(aa);
ir_node *aba = skip_Proj(ab);
if ( ( (/* aa is ProjP and aaa is Alloc */
is_Proj(aa)
&& mode_is_reference(get_irn_mode(aa))
&& is_Alloc(aaa))
&& ( (/* ab is NULL */
mode_is_reference(get_irn_mode(ab))
&& tarval_is_null(tab))
|| (/* ab is other Alloc */
is_Proj(ab)
&& mode_is_reference(get_irn_mode(ab))
&& is_Alloc(aba)
&& (aaa != aba))))
|| (/* aa is NULL and aba is Alloc */
mode_is_reference(get_irn_mode(aa))
&& tarval_is_null(taa)
&& is_Proj(ab)
&& mode_is_reference(get_irn_mode(ab))
&& is_Alloc(aba)))
/* 3.: */
}
/*
* The predecessors are Allocs or (void*)(0) constants. Allocs never
* return NULL, they raise an exception. Therefore we can predict
* the Cmp result.
*/
else {
ir_node *aaa = skip_Proj(aa);
ir_node *aba = skip_Proj(ab);
if ( ( (/* aa is ProjP and aaa is Alloc */
is_Proj(aa)
&& mode_is_reference(get_irn_mode(aa))
&& is_Alloc(aaa))
&& ( (/* ab is NULL */
mode_is_reference(get_irn_mode(ab))
&& tarval_is_null(tab))
|| (/* ab is other Alloc */
is_Proj(ab)
&& mode_is_reference(get_irn_mode(ab))
&& is_Alloc(aba)
&& (aaa != aba))))
|| (/* aa is NULL and aba is Alloc */
mode_is_reference(get_irn_mode(aa))
&& tarval_is_null(taa)
&& is_Proj(ab)
&& mode_is_reference(get_irn_mode(ab))
&& is_Alloc(aba)))
/* 3.: */
return new_tarval_from_long(proj_nr & pn_Cmp_Lg, mode_b);
}
}
return computed_value_Cmp_Confirm(a, aa, ab, proj_nr);
} /* computed_value_Proj_Cmp */
......
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