This is the mail archive of the gcc@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]

Do we still need get_callee_fndecl?


Hi,

I am wondering if we still need get_callee_fndecl in the presence of
tree optimizers.  I think this function performs a form of constant
propagation at a rather strange place.

Currently, given an address expression of CALL_EXPR, get_callee_fndecl
tries to get to its DECL_INITIAL like so.

  STRIP_NOPS (addr);

  /* If this is a readonly function pointer, extract its initial value.  */
  if (DECL_P (addr) && TREE_CODE (addr) != FUNCTION_DECL
      && TREE_READONLY (addr) && ! TREE_THIS_VOLATILE (addr)
      && DECL_INITIAL (addr))
    addr = DECL_INITIAL (addr);

This is a constant propagation in that we are propagating the value of
DECL_INITIAL (addr) into a call site.

In fact, even if I remove the block of code above from
get_callee_fndecl, the tree optimizers can still turn an indirect call
into a direct one "bar ()" in the following test case.

extern int bar (void);
typedef int (*bar_type) (void);
const bar_type g = &bar;

int
foo_1 (void)
{
  /* Call through a function pointer stored in a const global
     variable.  */
  return (*g)();
}

A call through a function pointer stored in a local variable would be
fine, too.

int
foo_2 (void)
{
  /* Call through a function pointer stored in a local variable.  */
  bar_type h = &bar;
  return (*h)();
}

But a call through a function pointer stored in a constant global
array is not optimized.  Currently, we don't dig that deep.

const bar_type array[3] = { bar, bar, bar };

int
foo_3 (void)
{
  /* Call through a function pointer stored in a constant global
     array.  */
  bar_type h = array[2];
  return (*h)();
}

All of the above should illustrate my point.

If we improve our constant/copy propagator to dig into a constant
array and structures, we would get foo_3 optimized for free.  After
all, a function pointer is just a variable, and if we have an
assignment of a constant, we can propagate the constant into its uses.

The Java front end used to look into an array, but it doesn't
nowadays.  I wonder if there is any data structure that a front end
does not expose to the middle for the purpose of constant propagation.

After all, all we need in get_callee_fndecl seems to be

  addr = TREE_OPERAND (call_expr, 0);
  return ((TREE_CODE (addr) == ADDR_EXPR
	   && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
	  ? TREE_OPERAND (addr, 0) : NULL_TREE;

Thoughts?

Kazu Hirata


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