diff mbox

Fix PHI optimization issue with boolean types

Message ID 1842011.oP9bEcZBzd@polaris
State New
Headers show

Commit Message

Eric Botcazou Oct. 24, 2016, 11:39 a.m. UTC
> > But integer_truep is just integer_onep for BOOLEAN_TYPEs.
> 
> Yes, but it's more descriptive IMHO.

At the cost of consistency with fits_to_tree_p though.

> fits_to_tree_p avoids creating an INTEGER_CST in ggc memory and thus is the
> prefered way to test if you have a wide-int but not yet an INTEGER_CST.

OK, I was confused by int_fits_type_p, which calls it on an INTEGER_CST (which 
now breaks with the additional test in the function).

The attached fix seems to work and passes regression testing (all languages).


	* tree.h (wi::fits_to_tree_p): Accept only 0 and 1 for boolean types.
	* tree.c (int_fits_type_p): Likewise.  Pass the integer constant as a
	widest_int to above.

Comments

Richard Biener Oct. 24, 2016, 11:49 a.m. UTC | #1
On Mon, Oct 24, 2016 at 1:39 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> > But integer_truep is just integer_onep for BOOLEAN_TYPEs.
>>
>> Yes, but it's more descriptive IMHO.
>
> At the cost of consistency with fits_to_tree_p though.
>
>> fits_to_tree_p avoids creating an INTEGER_CST in ggc memory and thus is the
>> prefered way to test if you have a wide-int but not yet an INTEGER_CST.
>
> OK, I was confused by int_fits_type_p, which calls it on an INTEGER_CST (which
> now breaks with the additional test in the function).
>
> The attached fix seems to work and passes regression testing (all languages).

Is the change to pass wi::to_widest really necessary?  I think it has a
runtime penalty.

Otherwise ok.

Thanks,
Richard.

>
>         * tree.h (wi::fits_to_tree_p): Accept only 0 and 1 for boolean types.
>         * tree.c (int_fits_type_p): Likewise.  Pass the integer constant as a
>         widest_int to above.
>
> --
> Eric Botcazou
Eric Botcazou Oct. 25, 2016, 8:17 a.m. UTC | #2
> Is the change to pass wi::to_widest really necessary?  I think it has a
> runtime penalty.

Yes, because there is no == operator for a (tree, int) pair.  Is there a cheap 
way to convert a tree back into a wide_int?  wi::to_wide?  Or a combination 
with decompose?  Otherwise you can use eq_p, but this means that all other 
callers of fits_to_tree_p are affected:

template <typename T>
bool
wi::fits_to_tree_p (const T &x, const_tree type)
{
  /* Short-circuit boolean types since various transformations assume that
     they can only take values 0 and 1.  */
  if (TREE_CODE (type) == BOOLEAN_TYPE)
    return eq_p (x, 0) || eq_p (x, 1);

instead of just int_fits_type_p (but I don't really know if there is a penalty 
associated with eq_p here).
Richard Biener Oct. 25, 2016, 8:25 a.m. UTC | #3
On Tue, Oct 25, 2016 at 10:17 AM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> Is the change to pass wi::to_widest really necessary?  I think it has a
>> runtime penalty.
>
> Yes, because there is no == operator for a (tree, int) pair.

Ah, yes.  But operator== simply maps to wi::eq_p, so ...

>  Is there a cheap
> way to convert a tree back into a wide_int?  wi::to_wide?  Or a combination
> with decompose?  Otherwise you can use eq_p, but this means that all other
> callers of fits_to_tree_p are affected:
>
> template <typename T>
> bool
> wi::fits_to_tree_p (const T &x, const_tree type)
> {
>   /* Short-circuit boolean types since various transformations assume that
>      they can only take values 0 and 1.  */
>   if (TREE_CODE (type) == BOOLEAN_TYPE)
>     return eq_p (x, 0) || eq_p (x, 1);
>
> instead of just int_fits_type_p (but I don't really know if there is a penalty
> associated with eq_p here).

... this variant is fine it doesn't have any extra cost (the to_widest
in int_fits_type_p has).

I'm not sure what you mean with "all other callers of fits_to_tree_p
are affected" - that was desired.

Thanks,
Richard.


> --
> Eric Botcazou
Eric Botcazou Oct. 25, 2016, 10:22 a.m. UTC | #4
> I'm not sure what you mean with "all other callers of fits_to_tree_p
> are affected" - that was desired.

Affected by the from == to eq_p change:

+  if (TREE_CODE (type) == BOOLEAN_TYPE)
+    return x == 0 || x == 1;

vs

+  if (TREE_CODE (type) == BOOLEAN_TYPE)
+    return eq_p (x, 0) || eq_p (x, 1);

Is eq_p free for them too?  If no, then you distribute the overhead over all 
the callers instead of just int_fits_type_p (for which the call is unlikely).
Richard Biener Oct. 25, 2016, 10:31 a.m. UTC | #5
On Tue, Oct 25, 2016 at 12:22 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> I'm not sure what you mean with "all other callers of fits_to_tree_p
>> are affected" - that was desired.
>
> Affected by the from == to eq_p change:
>
> +  if (TREE_CODE (type) == BOOLEAN_TYPE)
> +    return x == 0 || x == 1;
>
> vs
>
> +  if (TREE_CODE (type) == BOOLEAN_TYPE)
> +    return eq_p (x, 0) || eq_p (x, 1);
>
> Is eq_p free for them too?  If no, then you distribute the overhead over all
> the callers instead of just int_fits_type_p (for which the call is unlikely).

Yes, eq_p is equivalent to == (apart from the overloading issue you ran into).

Richard.

> --
> Eric Botcazou
diff mbox

Patch

Index: tree.c
===================================================================
--- tree.c	(revision 241437)
+++ tree.c	(working copy)
@@ -9065,8 +9065,8 @@  get_narrower (tree op, int *unsignedp_pt
   return win;
 }
 
-/* Returns true if integer constant C has a value that is permissible
-   for type TYPE (an INTEGER_TYPE).  */
+/* Return true if integer constant C has a value that is permissible
+   for TYPE, an integral type.  */
 
 bool
 int_fits_type_p (const_tree c, const_tree type)
@@ -9075,6 +9075,11 @@  int_fits_type_p (const_tree c, const_tre
   bool ok_for_low_bound, ok_for_high_bound;
   signop sgn_c = TYPE_SIGN (TREE_TYPE (c));
 
+  /* Short-circuit boolean types since various transformations assume that
+     they can only take values 0 and 1.  */
+  if (TREE_CODE (type) == BOOLEAN_TYPE)
+    return integer_zerop (c) || integer_truep (c);
+
 retry:
   type_low_bound = TYPE_MIN_VALUE (type);
   type_high_bound = TYPE_MAX_VALUE (type);
@@ -9154,7 +9159,7 @@  retry:
     }
 
   /* Or to fits_to_tree_p, if nothing else.  */
-  return wi::fits_to_tree_p (c, type);
+  return wi::fits_to_tree_p (wi::to_widest (c), type);
 }
 
 /* Stores bounds of an integer TYPE in MIN and MAX.  If TYPE has non-constant
Index: tree.h
===================================================================
--- tree.h	(revision 241437)
+++ tree.h	(working copy)
@@ -5295,6 +5295,11 @@  template <typename T>
 bool
 wi::fits_to_tree_p (const T &x, const_tree type)
 {
+  /* Short-circuit boolean types since various transformations assume that
+     they can only take values 0 and 1.  */
+  if (TREE_CODE (type) == BOOLEAN_TYPE)
+    return x == 0 || x == 1;
+
   if (TYPE_SIGN (type) == UNSIGNED)
     return eq_p (x, zext (x, TYPE_PRECISION (type)));
   else