Re: Add post_expand_call_insn hook
On 24-04-14 17:13, Eric Botcazou wrote: The hook is called right after expansion of calls, and allows a target to do additional processing, such as f.i. adding clobbers to CALL_INSN_FUNCTION_USAGE. Instead of using the hook, we could add code to the preparation statements operand of the different call expands, but that requires those expands not to use the rtl template, and generate all the rtl through c code. Which requires a rewrite of the call expands in case of Aarch64. If Aarch64 is the only problematic back-end, then it should be changed to do what the other back-ends already do to use use_reg. IMO adding such a bogus hook should be the very last resort solution. Eric, I've written this concept patch, which tries to address the same problem, but in a different (and I hope more generic) way. It adds a post-emission C-code operand to define_expand. As an example of how this could be useful, for the define_expand of call and call_value in the arm target, I'm using the new operand to do the post-emit call processing done currently in arm_emit_call_insn. This allows us to eliminate the call_internal and call_value_internal define_expands, and simplifies the call and call_value define_expands. Any comments? Thanks, - Tom diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 74645ee..506791a 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -126,7 +126,7 @@ extern int arm_const_double_inline_cost (rtx); extern bool arm_const_double_by_parts (rtx); extern bool arm_const_double_by_immediates (rtx); extern const char *fp_immediate_constant (rtx); -extern void arm_emit_call_insn (rtx, rtx); +extern void arm_post_emit_call_insn (rtx, rtx); extern const char *output_call (rtx *); extern const char *output_call_mem (rtx *); void arm_emit_movpair (rtx, rtx); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 09b5c52..e36deac 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -17602,16 +17602,14 @@ vfp_emit_fstmd (int base_reg, int count) return count * 8; } -/* Emit a call instruction with pattern PAT. ADDR is the address of - the call target. */ +/* Process a call instruction with pattern PAT after emission. ADDR is the + address of the call target. */ void -arm_emit_call_insn (rtx pat, rtx addr) +arm_post_emit_call_insn (rtx pat, rtx addr) { rtx insn; - insn = emit_call_insn (pat); - /* The PIC register is live on entry to VxWorks PIC PLT entries. If the call might use such an entry, add a use of the PIC register to the instruction's CALL_INSN_FUNCTION_USAGE. */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 8a949b9..45019ae 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -9082,7 +9082,7 @@ TARGET_EITHER { -rtx callee, pat; +rtx callee; /* In an untyped call, we can get NULL for operand 2. */ if (operands[2] == NULL_RTX) @@ -9097,18 +9097,13 @@ : !REG_P (callee)) XEXP (operands[0], 0) = force_reg (Pmode, callee); -pat = gen_call_internal (operands[0], operands[1], operands[2]); -arm_emit_call_insn (pat, XEXP (operands[0], 0)); -DONE; + } + [] + { +arm_post_emit_call_insn (_val, XEXP (operands[0], 0)); } ) -(define_expand call_internal - [(parallel [(call (match_operand 0 memory_operand ) - (match_operand 1 general_operand )) - (use (match_operand 2 )) - (clobber (reg:SI LR_REGNUM))])]) - (define_insn *call_reg_armv5 [(call (mem:SI (match_operand:SI 0 s_register_operand r)) (match_operand 1 )) @@ -9191,7 +9186,7 @@ TARGET_EITHER { -rtx pat, callee; +rtx callee; /* In an untyped call, we can get NULL for operand 2. */ if (operands[3] == 0) @@ -9205,21 +9200,13 @@ ? arm_is_long_call_p (SYMBOL_REF_DECL (callee)) : !REG_P (callee)) XEXP (operands[1], 0) = force_reg (Pmode, callee); - -pat = gen_call_value_internal (operands[0], operands[1], - operands[2], operands[3]); -arm_emit_call_insn (pat, XEXP (operands[1], 0)); -DONE; + } + [] + { +arm_post_emit_call_insn (_val, XEXP (operands[1], 0)); } ) -(define_expand call_value_internal - [(parallel [(set (match_operand 0 ) - (call (match_operand 1 memory_operand ) - (match_operand 2 general_operand ))) - (use (match_operand 3 )) - (clobber (reg:SI LR_REGNUM))])]) - (define_insn *call_value_reg_armv5 [(set (match_operand 0 ) (call (mem:SI (match_operand:SI 1 s_register_operand r)) diff --git a/gcc/genemit.c b/gcc/genemit.c index faaa610..aff27f6 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -422,7 +422,8 @@ gen_expand (rtx expand) /* If we don't have any C code to write, only one insn is being written, and no MATCH_DUPs are present, we can just return the desired insn like we do for a DEFINE_INSN. This saves memory. */ - if ((XSTR
Re: Add post_expand_call_insn hook
On 04/29/2014 01:59 AM, Tom de Vries wrote: On 24-04-14 17:13, Eric Botcazou wrote: The hook is called right after expansion of calls, and allows a target to do additional processing, such as f.i. adding clobbers to CALL_INSN_FUNCTION_USAGE. Instead of using the hook, we could add code to the preparation statements operand of the different call expands, but that requires those expands not to use the rtl template, and generate all the rtl through c code. Which requires a rewrite of the call expands in case of Aarch64. If Aarch64 is the only problematic back-end, then it should be changed to do what the other back-ends already do to use use_reg. IMO adding such a bogus hook should be the very last resort solution. Eric, I've written this concept patch, which tries to address the same problem, but in a different (and I hope more generic) way. It adds a post-emission C-code operand to define_expand. As an example of how this could be useful, for the define_expand of call and call_value in the arm target, I'm using the new operand to do the post-emit call processing done currently in arm_emit_call_insn. This allows us to eliminate the call_internal and call_value_internal define_expands, and simplifies the call and call_value define_expands. Is this patch really any better? I can't see that it is myself. It seems to me that the existing mechanism to emit the call, then append to FUNCTION_USAGE is perfectly clear. This new argument to define_expand seems less clear. What are you trying to fix, anyway? r~
Re: Add post_expand_call_insn hook
On 29-04-14 20:56, Richard Henderson wrote: I've written this concept patch, which tries to address the same problem, but in a different (and I hope more generic) way. It adds a post-emission C-code operand to define_expand. As an example of how this could be useful, for the define_expand of call and call_value in the arm target, I'm using the new operand to do the post-emit call processing done currently in arm_emit_call_insn. This allows us to eliminate the call_internal and call_value_internal define_expands, and simplifies the call and call_value define_expands. Is this patch really any better? I can't see that it is myself. It seems to me that the existing mechanism to emit the call, then append to FUNCTION_USAGE is perfectly clear. This new argument to define_expand seems less clear. What are you trying to fix, anyway? Richard, In arm.md, the define_expand call rtl template is not used, because DONE is used in the preparation statements operand. The DONE is there, because we need a handle to the emitted insn to do post-emit processing. The post-emission C-code operand that this patch introduces provides a handle to the emitted insn, which means we no longer need to use an explicit emit and DONE to get that handle. And without that DONE, we can use the rtl template of define_expand call, and no longer need the call_internal. So we eliminate an define_expand (which is shorter, and removes duplicate code), and deal with expansion inside a single define_expand (which is clearer). To me, those are the benefits. I agree the existing mechanism is perfectly clear. Still I think that a 'finalization statements' operand is as clear as a 'preparation statements' operand. Thanks, - Tom
Re: Add post_expand_call_insn hook
The hook is called right after expansion of calls, and allows a target to do additional processing, such as f.i. adding clobbers to CALL_INSN_FUNCTION_USAGE. Instead of using the hook, we could add code to the preparation statements operand of the different call expands, but that requires those expands not to use the rtl template, and generate all the rtl through c code. Which requires a rewrite of the call expands in case of Aarch64. If Aarch64 is the only problematic back-end, then it should be changed to do what the other back-ends already do to use use_reg. IMO adding such a bogus hook should be the very last resort solution. -- Eric Botcazou
Add post_expand_call_insn hook
On 22-04-14 17:05, Tom de Vries wrote: I've updated the fuse-caller-save patch series to model non-callee call clobbers in CALL_INSN_FUNCTION_USAGE. Eric, this patch adds a post_expand_call_insn hook. The hook is called right after expansion of calls, and allows a target to do additional processing, such as f.i. adding clobbers to CALL_INSN_FUNCTION_USAGE. Instead of using the hook, we could add code to the preparation statements operand of the different call expands, but that requires those expands not to use the rtl template, and generate all the rtl through c code. Which requires a rewrite of the call expands in case of Aarch64. Bootstrapped and reg-tested on x86_64 as part of the fuse-caller-save patch series. OK for trunk? Thanks, - Tom 2014-04-18 Tom de Vries t...@codesourcery.com * target.def (post_expand_call_insn): New DEFHOOK. * calls.c (expand_call, emit_library_call_value_1): Call post_expand_call_insn hook. * tm.texi.in (@section Storage Layout): Add hook TARGET_POST_EXPAND_CALL_INSN. * hooks.c (hook_void_rtx): New function. * hooks.h (hook_void_rtx): Declare function. diff --git a/gcc/calls.c b/gcc/calls.c index e798c7a..0777a02 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -3507,6 +3507,8 @@ expand_call (tree exp, rtx target, int ignore) free (stack_usage_map_buf); + targetm.post_expand_call_insn (last_call_insn ()); + return target; } @@ -4344,6 +4346,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, free (stack_usage_map_buf); + targetm.post_expand_call_insn (last_call_insn ()); + return value; } diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 8af8efd..40b5bb1 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1408,6 +1408,11 @@ registers whenever the function being expanded has any SDmode usage. @end deftypefn +@deftypefn {Target Hook} void TARGET_POST_EXPAND_CALL_INSN (rtx) +This hook is called just after expansion of a call_expr into rtl, allowing +the target to perform additional processing. +@end deftypefn + @deftypefn {Target Hook} void TARGET_INSTANTIATE_DECLS (void) This hook allows the backend to perform additional instantiations on rtl that are not actually in any insns yet, but will be later. diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 8991c3c..812b0b8 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -1285,6 +1285,8 @@ The default definition of this macro returns false for all sizes. @hook TARGET_EXPAND_TO_RTL_HOOK +@hook TARGET_POST_EXPAND_CALL_INSN + @hook TARGET_INSTANTIATE_DECLS @hook TARGET_MANGLE_TYPE diff --git a/gcc/hooks.c b/gcc/hooks.c index 1c67bdf..53e8591 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -461,6 +461,13 @@ hook_void_rtx_int (rtx insn ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED) { } +/* Generic hook that takes a rtx and an int and returns void. */ + +void +hook_void_rtx (rtx insn ATTRIBUTE_UNUSED) +{ +} + /* Generic hook that takes a struct gcc_options * and returns void. */ void diff --git a/gcc/hooks.h b/gcc/hooks.h index 896b41d..4df5ae0 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -66,6 +66,7 @@ extern bool hook_bool_dint_dint_uint_bool_true (double_int, double_int, extern void hook_void_void (void); extern void hook_void_constcharptr (const char *); +extern void hook_void_rtx (rtx); extern void hook_void_rtx_int (rtx, int); extern void hook_void_FILEptr_constcharptr (FILE *, const char *); extern bool hook_bool_FILEptr_rtx_false (FILE *, rtx); diff --git a/gcc/target.def b/gcc/target.def index ae0bc9c..2f7178c 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4639,6 +4639,15 @@ usage., hook_void_void) /* This target hook allows the backend to perform additional + processing after expansion of a call insn. */ +DEFHOOK +(post_expand_call_insn, + This hook is called just after expansion of a call_expr into rtl, allowing\n\ +the target to perform additional processing., + void, (rtx), + hook_void_rtx) + +/* This target hook allows the backend to perform additional instantiations on rtx that are not actually in insns yet, but will be later. */ DEFHOOK