This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [wide-int] Small wide_int_to_tree optimisation


On Thu, Nov 28, 2013 at 1:05 PM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> This patch convers some gcc_asserts to gcc_checking_asserts.
> I think the first two in particular should be checking-only,
> since we ignore the bits above the target precision anyway.
>
> Also we have:
>
>           /* This is a little hokie, but if the prec is smaller than
>              what is necessary to hold INTEGER_SHARE_LIMIT, then the
>              obvious test will not get the correct answer.  */
>           if (prec < HOST_BITS_PER_WIDE_INT)
>             {
>               if (cst.to_uhwi () < (unsigned HOST_WIDE_INT) INTEGER_SHARE_LIMIT)
>                 ix = cst.to_uhwi ();
>             }
>           else if (wi::ltu_p (cst, INTEGER_SHARE_LIMIT))
>             ix = cst.to_uhwi ();
>
> But this case only occurs for single-HWI integers.  We later check
> for that and extract the HWI value, so it seems simpler to postpone
> the index check until then.
>
> Tested on x86_64-linux-gnu.  OK to install?

Ok.

Thanks,
Richard.

> Thanks,
> Richard
>
>
> Index: gcc/tree.c
> ===================================================================
> *** gcc/tree.c  2013-11-28 11:27:32.043124135 +0000
> --- gcc/tree.c  2013-11-28 11:45:39.957427563 +0000
> *************** wide_int_to_tree (tree type, const wide_
> *** 1205,1295 ****
>     if (l > 1)
>       {
>         if (pcst.elt (l - 1) == 0)
> !       gcc_assert (pcst.elt (l - 2) < 0);
>         if (pcst.elt (l - 1) == (HOST_WIDE_INT) -1)
> !       gcc_assert (pcst.elt (l - 2) >= 0);
>       }
>
>     wide_int cst = wide_int::from (pcst, prec, sgn);
>     unsigned int ext_len = get_int_cst_ext_nunits (type, cst);
>
> !   switch (TREE_CODE (type))
>       {
> !     case NULLPTR_TYPE:
> !       gcc_assert (cst == 0);
> !       /* Fallthru.  */
> !
> !     case POINTER_TYPE:
> !     case REFERENCE_TYPE:
> !     case POINTER_BOUNDS_TYPE:
> !       /* Cache NULL pointer and zero bounds.  */
> !       if (cst == 0)
> !       {
> !         limit = 1;
> !         ix = 0;
> !       }
> !       break;
>
> !     case BOOLEAN_TYPE:
> !       /* Cache false or true.  */
> !       limit = 2;
> !       if (wi::leu_p (cst, 1))
> !       ix = cst.to_uhwi ();
> !       break;
> !
> !     case INTEGER_TYPE:
> !     case OFFSET_TYPE:
> !       if (TYPE_SIGN (type) == UNSIGNED)
>         {
> !         /* Cache 0..N */
> !         limit = INTEGER_SHARE_LIMIT;
> !
> !         /* This is a little hokie, but if the prec is smaller than
> !            what is necessary to hold INTEGER_SHARE_LIMIT, then the
> !            obvious test will not get the correct answer.  */
> !         if (prec < HOST_BITS_PER_WIDE_INT)
>             {
> !             if (cst.to_uhwi () < (unsigned HOST_WIDE_INT) INTEGER_SHARE_LIMIT)
> !               ix = cst.to_uhwi ();
>             }
> !         else if (wi::ltu_p (cst, INTEGER_SHARE_LIMIT))
> !           ix = cst.to_uhwi ();
> !       }
> !       else
> !       {
> !         /* Cache -1..N */
> !         limit = INTEGER_SHARE_LIMIT + 1;
>
> !         if (cst == -1)
> !           ix = 0;
> !         else if (!wi::neg_p (cst))
>             {
> !             if (prec < HOST_BITS_PER_WIDE_INT)
> !               {
> !                 if (cst.to_shwi () < INTEGER_SHARE_LIMIT)
> !                   ix = cst.to_shwi () + 1;
> !               }
> !             else if (wi::lts_p (cst, INTEGER_SHARE_LIMIT))
> !               ix = cst.to_shwi () + 1;
>             }
> !       }
> !       break;
>
> !     case ENUMERAL_TYPE:
> !       break;
>
> !     default:
> !       gcc_unreachable ();
> !     }
>
> -   if (ext_len == 1)
> -     {
> -       /* We just need to store a single HOST_WIDE_INT.  */
> -       HOST_WIDE_INT hwi;
> -       if (TYPE_UNSIGNED (type))
> -       hwi = cst.to_uhwi ();
> -       else
> -       hwi = cst.to_shwi ();
>         if (ix >= 0)
>         {
>           /* Look for it in the type's vector of small shared ints.  */
> --- 1205,1276 ----
>     if (l > 1)
>       {
>         if (pcst.elt (l - 1) == 0)
> !       gcc_checking_assert (pcst.elt (l - 2) < 0);
>         if (pcst.elt (l - 1) == (HOST_WIDE_INT) -1)
> !       gcc_checking_assert (pcst.elt (l - 2) >= 0);
>       }
>
>     wide_int cst = wide_int::from (pcst, prec, sgn);
>     unsigned int ext_len = get_int_cst_ext_nunits (type, cst);
>
> !   if (ext_len == 1)
>       {
> !       /* We just need to store a single HOST_WIDE_INT.  */
> !       HOST_WIDE_INT hwi;
> !       if (TYPE_UNSIGNED (type))
> !       hwi = cst.to_uhwi ();
> !       else
> !       hwi = cst.to_shwi ();
>
> !       switch (TREE_CODE (type))
>         {
> !       case NULLPTR_TYPE:
> !         gcc_assert (hwi == 0);
> !         /* Fallthru.  */
> !
> !       case POINTER_TYPE:
> !       case REFERENCE_TYPE:
> !       case POINTER_BOUNDS_TYPE:
> !         /* Cache NULL pointer and zero bounds.  */
> !         if (hwi == 0)
>             {
> !             limit = 1;
> !             ix = 0;
>             }
> !         break;
>
> !       case BOOLEAN_TYPE:
> !         /* Cache false or true.  */
> !         limit = 2;
> !         if (hwi < 2)
> !           ix = hwi;
> !         break;
> !
> !       case INTEGER_TYPE:
> !       case OFFSET_TYPE:
> !         if (TYPE_SIGN (type) == UNSIGNED)
>             {
> !             /* Cache [0, N).  */
> !             limit = INTEGER_SHARE_LIMIT;
> !             if (IN_RANGE (hwi, 0, INTEGER_SHARE_LIMIT - 1))
> !               ix = hwi;
>             }
> !         else
> !           {
> !             /* Cache [-1, N).  */
> !             limit = INTEGER_SHARE_LIMIT + 1;
> !             if (IN_RANGE (hwi, -1, INTEGER_SHARE_LIMIT - 1))
> !               ix = hwi + 1;
> !           }
> !         break;
>
> !       case ENUMERAL_TYPE:
> !         break;
>
> !       default:
> !         gcc_unreachable ();
> !       }
>
>         if (ix >= 0)
>         {
>           /* Look for it in the type's vector of small shared ints.  */
> *************** wide_int_to_tree (tree type, const wide_
> *** 1302,1311 ****
>           t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix);
>           if (t)
>             /* Make sure no one is clobbering the shared constant.  */
> !           gcc_assert (TREE_TYPE (t) == type
> !                       && TREE_INT_CST_NUNITS (t) == 1
> !                       && TREE_INT_CST_EXT_NUNITS (t) == 1
> !                       && TREE_INT_CST_ELT (t, 0) == hwi);
>           else
>             {
>               /* Create a new shared int.  */
> --- 1283,1292 ----
>           t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix);
>           if (t)
>             /* Make sure no one is clobbering the shared constant.  */
> !           gcc_checking_assert (TREE_TYPE (t) == type
> !                                && TREE_INT_CST_NUNITS (t) == 1
> !                                && TREE_INT_CST_EXT_NUNITS (t) == 1
> !                                && TREE_INT_CST_ELT (t, 0) == hwi);
>           else
>             {
>               /* Create a new shared int.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]