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