Jeff Law <l...@redhat.com> writes: > On 07/11/2018 02:07 PM, Steve Ellcey wrote: >> I have a reload/register allocation question and possible patch. While >> working on the Aarch64 SIMD ABI[1] I ran into a problem where GCC was >> saving and restoring registers that it did not need to. I tracked it >> down to lra-constraints.c and its use of >> targetm.hard_regno_call_part_clobbered on instructions that are not >> calls. Specifically need_for_call_save_p would check this macro even >> when the instruction in question (unknown to need_for_call_save_p) >> was not a call instruction. >> >> This seems wrong to me and I was wondering if anyone more familiar >> with the register allocator and reload could look at this patch and >> tell me if it seems reasonable or not. It passed bootstrap and I >> am running tests now. I am just wondering if there is any reason why >> this target function would need to be called on non-call instructions >> or if doing so is just an oversight/bug. >> >> Steve Ellcey >> sell...@cavium.com >> >> >> [1] https://gcc.gnu.org/ml/gcc/2018-07/msg00012.html >> >> >> 2018-07-11 Steve Ellcey <sell...@cavium.com> >> >> * lra-constraints.c (need_for_call_save_p): Add insn argument >> and only check targetm.hard_regno_call_part_clobbered on calls. >> (need_for_split_p): Add insn argument, pass to need_for_call_save_p. >> (split_reg): Pass insn to need_for_call_save_p. >> (split_if_necessary): Pass curr_insn to need_for_split_p. >> (inherit_in_ebb): Ditto. > Various target have calls which are exposed as INSNs rather than as > CALL_INSNs. So we need to check that hook on all insns. > > You can probably see this in action with the TLS insns on aarch64.
Not sure whether it's that: I think other code does only consider hard_regno_call_part_clobbered on calls. But as it stands need_for_call_save_p is checking whether there's a call somewhere inbetween the current instruction and the last use in the EBB: /* Return true if we need a caller save/restore for pseudo REGNO which was assigned to a hard register. */ static inline bool need_for_call_save_p (int regno) { lra_assert (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0); return (usage_insns[regno].calls_num < calls_num ... } So it only calls targetm.hard_regno_call_part_clobbered if such a call is known to exist somewhere between the two references to regno (although we don't have the calls themselves to hand). Thanks, Richard