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