Steve Ellcey <[email protected]> writes:
> On Wed, 2019-01-09 at 10:00 +0000, Richard Sandiford wrote:
>
> Thanks for the quick turnaround on the comments Richard. Here is a new
> version where I tried to address all the issues you raised. One thing
> I noticed is that I think your calls_have_same_clobbers_p function only
> works if, when return_call_with_max_clobbers is called with two calls
> that clobber the same set of registers, it always returns the first
> call.
>
> I don't think my original function had that guarantee but I changed it
> so that it would and documented that requirement in target.def. I
> couldn't see a better way to implement the calls_have_same_clobbers_p
> function other than doing that.
Yeah, I think that's a good guarantee to have.
> diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
> index 1c300af..d88be6c 100644
> --- a/gcc/config/aarch64/aarch64.c
> +++ b/gcc/config/aarch64/aarch64.c
> @@ -1655,14 +1655,56 @@ aarch64_reg_save_mode (tree fndecl, unsigned regno)
> /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. The callee only saves
> the lower 64 bits of a 128-bit register. Tell the compiler the callee
> clobbers the top 64 bits when restoring the bottom 64 bits. */
>
> static bool
> -aarch64_hard_regno_call_part_clobbered (unsigned int regno, machine_mode
> mode)
> +aarch64_hard_regno_call_part_clobbered (rtx_insn *insn, unsigned int regno,
> + machine_mode mode)
> {
> - return FP_REGNUM_P (regno) && maybe_gt (GET_MODE_SIZE (mode), 8);
> + bool simd_p = insn && CALL_P (insn) && aarch64_simd_call_p (insn);
> + return FP_REGNUM_P (regno)
> + && maybe_gt (GET_MODE_SIZE (mode), simd_p ? 16 : 8);
> +}
> +
> +/* Implement TARGET_RETURN_CALL_WITH_MAX_CLOBBERS. */
> +
> +rtx_insn *
> +aarch64_return_call_with_max_clobbers (rtx_insn *call_1, rtx_insn *call_2)
> +{
> + gcc_assert (CALL_P (call_1) && CALL_P (call_2));
> +
> + if (aarch64_simd_call_p (call_1) == aarch64_simd_call_p (call_2))
> + return call_1;
> +
> + if (aarch64_simd_call_p (call_2))
> + return call_1;
> + else
> + return call_2;
Think this is simpler as:
gcc_assert (CALL_P (call_1) && CALL_P (call_2));
if (!aarch64_simd_call_p (call_1) || aarch64_simd_call_p (call_2))
return call_1;
else
return call_2;
> diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c
> index a00ec38..61149e1 100644
> --- a/gcc/lra-lives.c
> +++ b/gcc/lra-lives.c
> @@ -579,22 +579,32 @@ lra_setup_reload_pseudo_preferenced_hard_reg (int regno,
> PSEUDOS_LIVE_THROUGH_CALLS and PSEUDOS_LIVE_THROUGH_SETJUMPS. */
> static inline void
> check_pseudos_live_through_calls (int regno,
> - HARD_REG_SET last_call_used_reg_set)
> + HARD_REG_SET last_call_used_reg_set,
> + rtx_insn *call_insn)
Should document the new parameter.
> @@ -906,17 +933,22 @@ process_bb_lives (basic_block bb, int &curr_point, bool
> dead_insn_p)
>
> bool flush = (! hard_reg_set_empty_p (last_call_used_reg_set)
> && ! hard_reg_set_equal_p (last_call_used_reg_set,
> - this_call_used_reg_set));
> + this_call_used_reg_set)
> + && ! calls_have_same_clobbers_p (call_insn,
> + last_call_insn));
This should be || with the current test, not &&. We need to check
that last_call_insn is nonnull first.
> EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, j)
> {
> IOR_HARD_REG_SET (lra_reg_info[j].actual_call_used_reg_set,
> this_call_used_reg_set);
> +
> if (flush)
> - check_pseudos_live_through_calls
> - (j, last_call_used_reg_set);
> + check_pseudos_live_through_calls (j,
> + last_call_used_reg_set,
> + curr_insn);
> }
Should be last_call_insn rather than curr_insn. I.e. when we flush,
we apply the properties of the previous call to pseudos live after
the new call.
Looks good otherwise.
Thanks,
Richard