Problems with builtin setjmp receiver getting eliminated - Help
Andrew Hutchinson
andrewhutchinson@cox.net
Mon Mar 24 12:50:00 GMT 2008
I have realised that part of the problem is that the receiver block has
no incoming edges so cfgcleanup removes it as unreachable block - right?
So any target that need a non trivial receiver for builtin_setjmp will
not work? That would mean any that have an offset between stack and
pointers?
I guess the same problem exists for non-local goto?
I am not convinced it could be this wrong. So please comment and suggest
solution - I'm sure I can write target handler but it seems so wrong to
leave this as issue open.
Andy
Andrew Hutchinson wrote:
> I have real problems trying to get to the root of bug in
> builtin_setjmp implementation and seek anyones wisdom on what I have
> found and a way forward.
>
> Sometimes it's not always clear which part is wrong - when presented
> with mismatches.
> I will post a bug report when I have got a little closer.
>
> The problem I was looking at is the frame pointer being wrong on the
> AVR target. (Stack and PC are ok)
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21078 - but ANY
> setjmp/longjump has the problem.
>
> I traced this down to the handling of the frame pointer: by the
> receiver - (which is the code the longjmp will jump back to)
>
> Setjmp: - save pointer
>
> Buf[0] = Virtual_stack_var
>
> Longjmp: get pointer
>
> Hard_Frame_pointer=buf[0]
>
> Receiver: put back in frame pointer
>
> Virtual_stack_var = Hard_Frame_pointer
>
> The uniqueness on AVR is that Frame_pointer (and stack pointer) are 1
> byte different from the first stack element. So the Virtual_stack_var
> is 1 different from the frame_pointer
> i.e.
> #define STACK_GROWS_DOWNWARD
> #define STARTING_FRAME_OFFSET 1
> #define STACK_POINTER_OFFSET 1
>
> That's ok as this is recognized by instantiate_virtual_regs, which
> makes the replacements later. In this case
>
> Buf[0] = Frame_pointer+1
> ..
> ..
> Frame_pointer = Virtual_stack_var - 1
>
> However, what is happening is that an earlier pass noted in RTL dump
> file "sibling" eliminates the receiver code block. So the frane
> point is not reset correctly, and ends up being 1 out (which is bad).
> Other targets may survive if they don't have offset between stack and
> pointers.
>
> So where do I look to find out why this is happening? Does the RTL
> have something missing or is the other pass not checking?
>
> The RTL that gets eliminated is:
>
> ;; Start of basic block () -> 5
> (code_label/s 13 12 14 5 4 "" [2 uses])
>
> (note 14 13 15 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
>
> (insn 15 14 16 5 built-in-setjmp.c:17 (use (reg/f:HI 28 r28)) -1 (nil))
>
> (insn 16 15 17 5 built-in-setjmp.c:17 (clobber (reg:HI 2 r2)) -1 (nil))
>
> (insn 17 16 18 5 built-in-setjmp.c:17 (set (reg/f:HI 37
> virtual-stack-vars)
> (reg/f:HI 28 r28)) -1 (nil))
>
> (insn 18 17 19 5 built-in-setjmp.c:17 (clobber (reg/f:HI 28 r28)) -1
> (nil))
>
> (insn 19 18 20 5 built-in-setjmp.c:17 (asm_input/v ("") 0) -1 (nil))
> ;; End of basic block 5 -> ( 6)
>
>
> The second PROBLEM I noted is that gcc creates RTL for TWO receivers
> for a setjmp. One is naturally from "expand_builtin_setjmp_receiver"
> but there is then another one just after created by
> "expand_nl_goto_receiver" in stmt.c- whats all this about?
>
> Despite having two, both get optimised out!
>
>
> Andy
>
>
>
>
>
>
>
>
>
>
>
More information about the Gcc
mailing list