Message ID | mpt36h2y7it.fsf@arm.com |
---|---|
State | New |
Headers | show |
Series | Support multiple ABIs in the same translation unit | expand |
On 9/11/19 1:09 PM, Richard Sandiford wrote: > cselib_invalidate_regno is a no-op if REG_VALUES (i) is null, > so we can check that first. Then, if we know what mode the register > currently has, we can check whether it's clobbered in that mode. > > Using GET_MODE (values->elt->val_rtx) to get the mode of the last > set is taken from cselib_reg_set_mode. > > > 2019-09-11 Richard Sandiford <richard.sandiford@arm.com> > > gcc/ > * cselib.c (cselib_process_insn): If we know what mode a > register was set in, check whether it is clobbered in that > mode by a call. Only fall back to reg_raw_mode if that fails. OK jeff
On 9/29/19 11:05 PM, Jeff Law wrote: > On 9/11/19 1:09 PM, Richard Sandiford wrote: >> cselib_invalidate_regno is a no-op if REG_VALUES (i) is null, >> so we can check that first. Then, if we know what mode the register >> currently has, we can check whether it's clobbered in that mode. >> >> Using GET_MODE (values->elt->val_rtx) to get the mode of the last >> set is taken from cselib_reg_set_mode. >> >> >> 2019-09-11 Richard Sandiford <richard.sandiford@arm.com> >> >> gcc/ >> * cselib.c (cselib_process_insn): If we know what mode a >> register was set in, check whether it is clobbered in that >> mode by a call. Only fall back to reg_raw_mode if that fails. > OK > jeff > Caused https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92264 Martin
Index: gcc/cselib.c =================================================================== --- gcc/cselib.c 2019-09-11 19:47:32.894202944 +0100 +++ gcc/cselib.c 2019-09-11 19:48:04.229982128 +0100 @@ -2768,11 +2768,23 @@ cselib_process_insn (rtx_insn *insn) { function_abi abi = call_insn_abi (insn); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (call_used_or_fixed_reg_p (i) - || (REG_VALUES (i) && REG_VALUES (i)->elt - && (targetm.hard_regno_call_part_clobbered - (abi.id (), i, GET_MODE (REG_VALUES (i)->elt->val_rtx))))) - cselib_invalidate_regno (i, reg_raw_mode[i]); + if (elt_list *values = REG_VALUES (i)) + { + /* If we know what mode the value was set in, check whether + it is still available after the call in that mode. If we + don't know the mode, we have to check for the worst-case + scenario instead. */ + if (values->elt) + { + if (abi.clobbers_reg_p (GET_MODE (values->elt->val_rtx), i)) + cselib_invalidate_regno (i, GET_MODE (values->elt->val_rtx)); + } + else + { + if (abi.clobbers_at_least_part_of_reg_p (i)) + cselib_invalidate_regno (i, reg_raw_mode[i]); + } + } /* Since it is not clear how cselib is going to be used, be conservative here and treat looping pure or const functions