This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Problems with builtin setjmp receiver getting eliminated - Help


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














Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]