Exemple #1
0
void
autofdo_source_profile::mark_annotated (location_t loc)
{
  inline_stack stack;
  get_inline_stack (loc, &stack);
  if (stack.length () == 0)
    return;
  function_instance *s = get_function_instance_by_inline_stack (stack);
  if (s == NULL)
    return;
  s->mark_annotated (stack[0].second);
}
Exemple #2
0
bool
autofdo_source_profile::get_count_info (gimple *stmt, count_info *info) const
{
  if (LOCATION_LOCUS (gimple_location (stmt)) == cfun->function_end_locus)
    return false;

  inline_stack stack;
  get_inline_stack (gimple_location (stmt), &stack);
  if (stack.length () == 0)
    return false;
  function_instance *s = get_function_instance_by_inline_stack (stack);
  if (s == NULL)
    return false;
  return s->get_count_info (stack[0].second, info);
}
Exemple #3
0
gcov_type
autofdo_source_profile::get_callsite_total_count (
    struct cgraph_edge *edge) const
{
  inline_stack stack;
  stack.safe_push (std::make_pair (edge->callee->decl, 0));
  get_inline_stack (gimple_location (edge->call_stmt), &stack);

  function_instance *s = get_function_instance_by_inline_stack (stack);
  if (s == NULL
      || afdo_string_table->get_index (IDENTIFIER_POINTER (
             DECL_ASSEMBLER_NAME (edge->callee->decl))) != s->name ())
    return 0;

  return s->total_count ();
}
Exemple #4
0
bool
autofdo_source_profile::update_inlined_ind_target (gcall *stmt,
                                                   count_info *info)
{
  if (LOCATION_LOCUS (gimple_location (stmt)) == cfun->function_end_locus)
    return false;

  count_info old_info;
  get_count_info (stmt, &old_info);
  gcov_type total = 0;
  for (icall_target_map::const_iterator iter = old_info.targets.begin ();
       iter != old_info.targets.end (); ++iter)
    total += iter->second;

  /* Program behavior changed, original promoted (and inlined) target is not
     hot any more. Will avoid promote the original target.

     To check if original promoted target is still hot, we check the total
     count of the unpromoted targets (stored in old_info). If it is no less
     than half of the callsite count (stored in INFO), the original promoted
     target is considered not hot any more.  */
  if (total >= info->count / 2)
    return false;

  inline_stack stack;
  get_inline_stack (gimple_location (stmt), &stack);
  if (stack.length () == 0)
    return false;
  function_instance *s = get_function_instance_by_inline_stack (stack);
  if (s == NULL)
    return false;
  icall_target_map map;
  if (s->find_icall_target_map (stmt, &map) == 0)
    return false;
  for (icall_target_map::const_iterator iter = map.begin ();
       iter != map.end (); ++iter)
    info->targets[iter->first] = iter->second;
  return true;
}
Exemple #5
0
bool
autofdo_source_profile::update_inlined_ind_target (gcall *stmt,
                                                   count_info *info)
{
  if (dump_file)
    {
      fprintf (dump_file, "Checking indirect call -> direct call ");
      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    }

  if (LOCATION_LOCUS (gimple_location (stmt)) == cfun->function_end_locus)
    {
      if (dump_file)
	fprintf (dump_file, " good locus\n");
      return false;
    }

  count_info old_info;
  get_count_info (stmt, &old_info);
  gcov_type total = 0;
  for (icall_target_map::const_iterator iter = old_info.targets.begin ();
       iter != old_info.targets.end (); ++iter)
    total += iter->second;

  /* Program behavior changed, original promoted (and inlined) target is not
     hot any more. Will avoid promote the original target.

     To check if original promoted target is still hot, we check the total
     count of the unpromoted targets (stored in TOTAL). If a callsite count
     (stored in INFO) is smaller than half of the total count, the original
     promoted target is considered not hot any more.  */
  if (info->count < total / 2)
    {
      if (dump_file)
	fprintf (dump_file, " not hot anymore %ld < %ld",
		 (long)info->count,
		 (long)total /2);
      return false;
    }

  inline_stack stack;
  get_inline_stack (gimple_location (stmt), &stack);
  if (stack.length () == 0)
    {
      if (dump_file)
	fprintf (dump_file, " no inline stack\n");
      return false;
    }
  function_instance *s = get_function_instance_by_inline_stack (stack);
  if (s == NULL)
    {
      if (dump_file)
	fprintf (dump_file, " function not found in inline stack\n");
      return false;
    }
  icall_target_map map;
  if (s->find_icall_target_map (stmt, &map) == 0)
    {
      if (dump_file)
	fprintf (dump_file, " no target map\n");
      return false;
    }
  for (icall_target_map::const_iterator iter = map.begin ();
       iter != map.end (); ++iter)
    info->targets[iter->first] = iter->second;
  if (dump_file)
    fprintf (dump_file, " looks good\n");
  return true;
}