Beispiel #1
0
static void
afdo_indirect_call (gimple_stmt_iterator *gsi, const icall_target_map &map,
                    bool transform)
{
  gimple gs = gsi_stmt (*gsi);
  tree callee;

  if (map.size () == 0)
    return;
  gcall *stmt = dyn_cast <gcall *> (gs);
  if ((!stmt) || gimple_call_fndecl (stmt) != NULL_TREE)
    return;

  callee = gimple_call_fn (stmt);

  histogram_value hist = gimple_alloc_histogram_value (
      cfun, HIST_TYPE_INDIR_CALL, stmt, callee);
  hist->n_counters = 3;
  hist->hvalue.counters = XNEWVEC (gcov_type, hist->n_counters);
  gimple_add_histogram_value (cfun, stmt, hist);

  gcov_type total = 0;
  icall_target_map::const_iterator max_iter = map.end ();

  for (icall_target_map::const_iterator iter = map.begin ();
       iter != map.end (); ++iter)
    {
      total += iter->second;
      if (max_iter == map.end () || max_iter->second < iter->second)
        max_iter = iter;
    }

  hist->hvalue.counters[0]
      = (unsigned long long)afdo_string_table->get_name (max_iter->first);
  hist->hvalue.counters[1] = max_iter->second;
  hist->hvalue.counters[2] = total;

  if (!transform)
    return;

  struct cgraph_edge *indirect_edge
      = cgraph_node::get (current_function_decl)->get_edge (stmt);
  struct cgraph_node *direct_call = cgraph_node::get_for_asmname (
      get_identifier ((const char *) hist->hvalue.counters[0]));

  if (direct_call == NULL || !check_ic_target (stmt, direct_call))
    return;
  if (DECL_STRUCT_FUNCTION (direct_call->decl) == NULL)
    return;
  struct cgraph_edge *new_edge
      = indirect_edge->make_speculative (direct_call, 0, 0);
  new_edge->redirect_call_stmt_to_callee ();
  gimple_remove_histogram_value (cfun, stmt, hist);
  inline_call (new_edge, true, NULL, NULL, false);
}
Beispiel #2
0
void inline_call_expression(CallExpression *the_call,
			    ProcedureSymbol *target_proc) {
  // first dismantle it
  list<CallExpression *> call_list;
  force_call_dest_not_expr(the_call, &call_list);
  for (list<CallExpression*>::iterator siter =
	 call_list.begin(); siter != call_list.end(); siter++) {
    CallExpression *cal_expr = *siter;
    CallStatement *st = dismantle_a_call_expression(cal_expr);
    inline_call(st, target_proc);
  }
}