On Mon, Jun 2, 2025 at 4:07 PM Richard Sandiford <richard.sandif...@arm.com> wrote: > > "H.J. Lu" <hjl.to...@gmail.com> writes: > > Since not all CALL instructions in RTL passes have a REG_CALL_DECL note, > > update get_call_fndecl to also check function symbol for function > > declaration so that it can be used on CALL instructions like > > > > (call_insn 39 38 61 7 (set (reg:SI 0 ax) > > (call (mem:QI (symbol_ref:DI ("foo") [flags 0x3] > > <function_decl 0x7fffe96da900 foo>) [0 foo S1 A8]) > > (const_int 0 [0]))) "pr92080-15.c":24:9 1480 {*call_value} > > (expr_list:REG_DEAD (reg:SI 5 di) > > (expr_list:REG_DEAD (reg:SI 4 si) > > (expr_list:REG_EH_REGION (const_int 0 [0]) > > (nil)))) > > (expr_list:SI (use (reg:SI 5 di)) > > (expr_list:SI (use (reg:SI 4 si)) > > (nil)))) > > > > PR other/120494 > > * rtlanal.cc (get_call_fndecl): Also check function symbol to > > get function declaration. > > What's your use case for this? I think we should instead move to making > the notes more generally available, since looking at the call rtx won't > work for targets that need indirect calls (e.g. for -mlong-calls).
I am working on a pass which needs to check if CALL insn is a recursive call. Currently I have * Get the declaration of the function called by INSN. If INDIRECT_P is true, also get indirect declaration. */ static tree get_call_fndecl_from_rtx (const rtx_insn *insn, bool indirect_p = false) { rtx note = find_reg_note (insn, REG_CALL_DECL, NULL_RTX); if (note) { rtx datum = XEXP (note, 0); if (datum) return SYMBOL_REF_DECL (datum); } rtx call = get_call_rtx_from (insn); rtx fnaddr = XEXP (call, 0); rtx addr = XEXP (fnaddr, 0); if (GET_CODE (addr) == SYMBOL_REF) { tree fndecl = SYMBOL_REF_DECL (addr); if (fndecl && TREE_CODE (fndecl) == FUNCTION_DECL) return fndecl; } return indirect_p ? MEM_EXPR (fnaddr) : nullptr; } if (CALL_P (insn)) { tree fndecl = get_call_fndecl_from_rtx (insn); if (fndecl == current_function_decl && decl_binds_to_current_def_p (fndecl)) { recursive_call_p = true; break; } } If get_call_fndecl works without a REG_CALL_DECL note, I can use it instead of writing my own. > Thanks, > Richard > > > > > -- > > H.J. > > > > From 6e20aad0c0b02c688f93ebc20b160f31c23adc82 Mon Sep 17 00:00:00 2001 > > From: "H.J. Lu" <hjl.to...@gmail.com> > > Date: Sat, 31 May 2025 08:42:21 +0800 > > Subject: [PATCH] Also check function symbol for function declaration > > > > Since not all CALL instructions in RTL passes have a REG_CALL_DECL note, > > update get_call_fndecl to also check function symbol for function > > declaration so that it can be used on CALL instructions like > > > > (call_insn 39 38 61 7 (set (reg:SI 0 ax) > > (call (mem:QI (symbol_ref:DI ("foo") [flags 0x3] <function_decl > > 0x7fffe96da900 foo>) [0 foo S1 A8]) > > (const_int 0 [0]))) "pr92080-15.c":24:9 1480 {*call_value} > > (expr_list:REG_DEAD (reg:SI 5 di) > > (expr_list:REG_DEAD (reg:SI 4 si) > > (expr_list:REG_EH_REGION (const_int 0 [0]) > > (nil)))) > > (expr_list:SI (use (reg:SI 5 di)) > > (expr_list:SI (use (reg:SI 4 si)) > > (nil)))) > > > > PR other/120494 > > * rtlanal.cc (get_call_fndecl): Also check function symbol to > > get function declaration. > > > > Signed-off-by: H.J. Lu <hjl.to...@gmail.com> > > --- > > gcc/rtlanal.cc | 31 +++++++++++++++++++++---------- > > 1 file changed, 21 insertions(+), 10 deletions(-) > > > > diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc > > index 900f53e252a..b0983f8ebfc 100644 > > --- a/gcc/rtlanal.cc > > +++ b/gcc/rtlanal.cc > > @@ -833,17 +833,28 @@ get_call_rtx_from (const rtx_insn *insn) > > tree > > get_call_fndecl (const rtx_insn *insn) > > { > > - rtx note, datum; > > - > > + rtx note; > > note = find_reg_note (insn, REG_CALL_DECL, NULL_RTX); > > - if (note == NULL_RTX) > > - return NULL_TREE; > > - > > - datum = XEXP (note, 0); > > - if (datum != NULL_RTX) > > - return SYMBOL_REF_DECL (datum); > > - > > - return NULL_TREE; > > + if (note) > > + { > > + rtx datum = XEXP (note, 0); > > + if (datum) > > + return SYMBOL_REF_DECL (datum); > > + } > > + rtx call = get_call_rtx_from (insn); > > + rtx addr = XEXP (call, 0); > > + tree fndecl = nullptr; > > + if (MEM_P (addr)) > > + { > > + addr = XEXP (addr, 0); > > + if (GET_CODE (addr) == SYMBOL_REF) > > + { > > + tree decl = SYMBOL_REF_DECL (addr); > > + if (decl && TREE_CODE (decl) == FUNCTION_DECL) > > + fndecl = decl; > > + } > > + } > > + return fndecl; > > } > > > > /* Return the value of the integer term in X, if one is apparent; -- H.J.