[google gcc-4_8] fix size_estimation for builtin_expect

Rong Xu xur@google.com
Fri Sep 27 18:04:00 GMT 2013


On Fri, Sep 27, 2013 at 1:20 AM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Fri, Sep 27, 2013 at 12:23 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
>>> Hi,
>>>
>>> builtin_expect should be a NOP in size_estimation. Indeed, the call
>>> stmt itself is 0 weight in size and time. But it may introduce
>>> an extra relation expr which has non-zero size/time. The end result
>>> is: for w/ and w/o builtin_expect, we have different size/time estimation
>>> for early inlining.
>>>
>>> This patch fixes this problem.
>>>
>>> -Rong
>>
>>> 2013-09-26  Rong Xu  <xur@google.com>
>>>
>>>       * ipa-inline-analysis.c (estimate_function_body_sizes): fix
>>>         the size estimation for builtin_expect.
>>
>> This seems fine with an comment in the code what it is about.
>> I also think we want to support mutiple builtin_expects in a BB so perhaps
>> we want to have pointer set of statements to ignore?
>>
>> To avoid spagetti code, please just move the new logic into separate functions.
>
> Looks like this could use tree-ssa.c:walk_use_def_chains (please
> change its implementation as necessary, make it C++, etc. - you will
> be the first user again).
>

Thanks for the suggestion. But it seems walk_use_def_chains() was
removed by r201951.

-Rong

> Richard.
>
>> Honza
>>>
>>> Index: ipa-inline-analysis.c
>>> ===================================================================
>>> --- ipa-inline-analysis.c     (revision 202638)
>>> +++ ipa-inline-analysis.c     (working copy)
>>> @@ -2266,6 +2266,8 @@ estimate_function_body_sizes (struct cgraph_node *
>>>    /* Estimate static overhead for function prologue/epilogue and alignment. */
>>>    int overhead = PARAM_VALUE (PARAM_INLINE_FUNCTION_OVERHEAD_SIZE);
>>>    int size = overhead;
>>> +  gimple fix_expect_builtin;
>>> +
>>>    /* Benefits are scaled by probability of elimination that is in range
>>>       <0,2>.  */
>>>    basic_block bb;
>>> @@ -2359,14 +2361,73 @@ estimate_function_body_sizes (struct cgraph_node *
>>>           }
>>>       }
>>>
>>> +      fix_expect_builtin = NULL;
>>>        for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
>>>       {
>>>         gimple stmt = gsi_stmt (bsi);
>>> +       if (gimple_call_builtin_p (stmt, BUILT_IN_EXPECT))
>>> +            {
>>> +              tree var = gimple_call_lhs (stmt);
>>> +              tree arg = gimple_call_arg (stmt, 0);
>>> +              use_operand_p use_p;
>>> +              gimple use_stmt;
>>> +              bool match = false;
>>> +              bool done = false;
>>> +              gcc_assert (var && arg);
>>> +              gcc_assert (TREE_CODE (var) == SSA_NAME);
>>> +
>>> +              while (TREE_CODE (arg) == SSA_NAME)
>>> +                {
>>> +                  gimple stmt_tmp = SSA_NAME_DEF_STMT (arg);
>>> +                  switch (gimple_assign_rhs_code (stmt_tmp))
>>> +                    {
>>> +                      case LT_EXPR:
>>> +                      case LE_EXPR:
>>> +                      case GT_EXPR:
>>> +                      case GE_EXPR:
>>> +                      case EQ_EXPR:
>>> +                      case NE_EXPR:
>>> +                        match = true;
>>> +                        done = true;
>>> +                        break;
>>> +                      case NOP_EXPR:
>>> +                        break;
>>> +                      default:
>>> +                        done = true;
>>> +                        break;
>>> +                    }
>>> +                  if (done)
>>> +                    break;
>>> +                  arg = gimple_assign_rhs1 (stmt_tmp);
>>> +                }
>>> +
>>> +              if (match && single_imm_use (var, &use_p, &use_stmt))
>>> +                {
>>> +                  if (gimple_code (use_stmt) == GIMPLE_COND)
>>> +                    {
>>> +                      fix_expect_builtin = use_stmt;
>>> +                    }
>>> +                }
>>> +
>>> +              /* we should see one builtin_expert call in one bb.  */
>>> +              break;
>>> +            }
>>> +        }
>>> +
>>> +      for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
>>> +     {
>>> +       gimple stmt = gsi_stmt (bsi);
>>>         int this_size = estimate_num_insns (stmt, &eni_size_weights);
>>>         int this_time = estimate_num_insns (stmt, &eni_time_weights);
>>>         int prob;
>>>         struct predicate will_be_nonconstant;
>>>
>>> +       if (stmt == fix_expect_builtin)
>>> +            {
>>> +              this_size--;
>>> +              this_time--;
>>> +            }
>>> +
>>>         if (dump_file && (dump_flags & TDF_DETAILS))
>>>           {
>>>             fprintf (dump_file, "  ");
>>



More information about the Gcc-patches mailing list