------- Comment #8 from rsandifo at gcc dot gnu dot org 2007-11-11 10:06 ------- Created an attachment (id=14529) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14529&action=view) Patch that marks $gp as being live on nonlocal jumps
"daney at gcc dot gnu dot org" <[EMAIL PROTECTED]> writes: > Created an attachment (id=14528) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14528&action=view) > --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14528&action=view) > Proposed patch second half. > > Completely untested patch. It will probably take me a couple of weeks > to test it fully. I will start testing on mipsel-linux... You might have noticed already, but this patch won't work. mips_restore_gp restores $gp from the .cprestore save slot, which doesn't exist unless TARGET_CALL_CLOBBERED_GP. TBH, I'd forgotten when reviewing the original patch how this is supposed to work. If function Inner has a nonlocal jump to function Outer, Inner is supposed to initialise $gp on Outer's behalf. The original form of Inner's prologue does do this, thanks to: static unsigned int mips_global_pointer (void) { [...] /* If the function has a nonlocal goto, $gp must hold the correct global pointer for the target function. */ if (current_function_has_nonlocal_goto) return GLOBAL_POINTER_REGNUM; but at higher optimisation levels, the instructions get deleted as dead for -mno-shared, because nothing in the function itself needs $gp. I think this is a dataflow bug. (Dataflow generally, that is, not the new df machinery.) The code that emits the nonlocal goto records that the target of the jump uses the frame and stack pointers: static rtx expand_builtin_nonlocal_goto (tree exp) { ... /* USE of hard_frame_pointer_rtx added for consistency; not clear if really needed. */ emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); but it doesn't record that it also uses the GP register. The target- independent code does handle the liveness of GP in other situations, thanks originally to flow and now to the df machinery, so I think this is simply an oversight. It won't matter for most targets, since the nonlocal jump involves a symbolic access, and most targets use the GP for all symbolic accesses or for none. Long-term, it would be nice to get rid of these sorts of USEs and handle them entirely in the df machinery. However, given that we don't do that yet, I think the best fix is to emit a use of pic_offset_table_rtx: if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM && fixed_regs[PIC_OFFSET_TABLE_REGNUM]) emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx)); (the condition being the same as that used in flow and df). I think we can then revert the original patch, which would produce an unnecessary restore at the target site. The attached patch seems to work for me, both for o32 and n32. I'll run some regression tests. Richard -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32406