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]

PATCH: Devirtualization using profiling feedback


Hi, 

 i am sendig patch for devirtualization virtual calls using profile feedback. 

 Greetings 

 Tomas

ps. devirt-prof.C is c++ testcase and indir-call-prof.c is c testcase

---

PROBLEM DESC.: Devirtualization of virtual calls and directing indirect calls

  A) Lets have an indirect call p (...) where p is pointer to function (type of
  "sometype (*p) (args)"). In some programs there could be p nearly constant. 

  B) Lets have an virtual call p->somemethod (...) where p is instance of class
  with virtual method "somemethod". In some programs there could be p nearly
  constant class.

  Determine most common function call in A) and most common class in B). Use
  this information to improve code effectivity (espetialy info for inliner).

PROBLEM SOLUTION:

 Use actual gcc tree-profiling capability to measure most common func/class.

 1) Assign unique id to every finction/method:

  To structure cgraph_node was added attribute "pid" which is computed in
  function cgraph_finalize_function.

 2) STAGE generating profile:
 
  to every object file add two static variables:

  static void (*__gcov_indirect_call_callee) ();
  static gcov_type* __gcov_indirect_call_counters;

  before each virtual or indirect call add code:

  __gcov_indirect_call_counters = get_relevant_counter_ptr (); 
  __gcov_indirect_call_callee = (void *) indirect call argument;

  At the begining every called function or method (method uniquely determine
  class) add code:

  if (__gcov_indirect_call_callee == my_address)
     __gcov_one_value_profile (__gcov_indirect_call_counters, my pid);

 3) STAGE using profile:

  For every checked indirect/virtual call determine if most common pid of
  function/class method has probability more than 50%. If yes modify code of
  this call to:

  if (actual_callee_addres == addres_of_most_common_function/method)
    do direct call
  else
    old call

Attachment: devirt.patch
Description: Text document

/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-tree_profile" } */

struct A {
  A () {}

  virtual int AA (void)
  { return 0; }

};

struct B : public A {
  B () {}

  virtual int AA (void)
  { return 1; }
};

int
main (void)
{
  A a;
  B b;
  
  A* p;

  p = &a;
  p->AA ();

  p = &b;
  p->AA ();
  
  return 0;
}

/* { dg-final-use { scan-tree-dump "Devirtualizing.* AA transformation on insn" "tree_profile"} } */                                                  
/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */                                                                                
/* { dg-final-use { cleanup-tree-dump "optimized" } } */                                                                                              
/* { dg-final-use { cleanup-tree-dump "tree_profile" } } */                                                                                           

/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-tree_profile" } */

static int a1 (void)
{
    return 10;
}

static int a2 (void)
{
    return 0;
}

typedef int (*tp) (void);

static tp aa [] = {a2, a1, a1, a1, a1};

void setp (int (**pp) (void), int i)
{
  if (!i)
    *pp = aa [i];
  else
    *pp = aa [(i & 2) + 1];
}

int
main (void)
{
  int (*p) (void);
  int  i;

  for (i = 0; i < 10; i ++)
    {
	setp (&p, i);
	p ();
    }
  
  return 0;
}

/* { dg-final-use { scan-tree-dump "Devirtualizing.* a1 transformation on insn" "tree_profile"} } */
/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */                                                                                
/* { dg-final-use { cleanup-tree-dump "optimized" } } */                                                                                              
/* { dg-final-use { cleanup-tree-dump "tree_profile" } } */
                                                                                           

Attachment: Changelog.txt
Description: Text document


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