Message ID | 1847684.pGViGHtxfN@polaris |
---|---|
State | New |
Headers | show |
On 11/15/2012 11:34 AM, Eric Botcazou wrote: > The problem is that get_loop_latch_edges finds no latch edges for a loop > because the header of the loop doesn't dominate any of its predecessors. > The reason is that a new edge is added during RTL expansion, which changes the > dominance info. This edge is from a call to __sync_synchronize to a non-local > label generated for a __builtin_setjmp_receiver. > > Fixed by marking the call as "nononlocal", tested on x86_64-suse-linux, OK for > the mainline? While its true that this call is nononlocal, there are plenty of other builtins that we expand with just emit_library_call (as opposed to emit_libcall_block) that also need this sort of treatment. Seems to me that this marking ought to be done in emit_library_call, for at least most values of LCT_*. Otherwise you could get the same ICE for e.g. memcpy. r~ PS: ARM still uses sjlj exceptions for Ada? I thought with the obsolescence of pre-eabi targets that we'd always use unwind tables now.
> r~ > > > PS: ARM still uses sjlj exceptions for Ada? I thought with the obsolescence > of pre-eabi targets that we'd always use unwind tables now. > I believe this is by choice because no one has yet written an unwinder for the ARM exception tables for Ada :( . regards, Ramana
On 11/15/2012 12:01 PM, Ramana Radhakrishnan wrote:
> I believe this is by choice because no one has yet written an unwinder for the ARM exception tables for Ada :( .
Ada is supposed to be using the same libgcc unwinder as the rest of
the compiler. So this cannot be it, exactly.
Perhaps some silly bit of configury is wrong?
r~
On 11/15/12 20:05, Richard Henderson wrote: > On 11/15/2012 12:01 PM, Ramana Radhakrishnan wrote: >> I believe this is by choice because no one has yet written an unwinder for the ARM exception tables for Ada :( . > > Ada is supposed to be using the same libgcc unwinder as the rest of > the compiler. So this cannot be it, exactly. I don't follow Ada much, so if it's not the unwinder then the next place to look would be the generator. Googling around - http://gcc.gnu.org/ml/gcc-patches/2009-09/msg00471.html appears to suggest that GNAT needs to know more to generate the ARM EH unwind tables for the ZCX approach. On Aarch64 life should be much simpler given that it uses the standard eh_frame mechanisms. > > Perhaps some silly bit of configury is wrong? If things have changed maybe it is .... Ramana > > > r~ >
> While its true that this call is nononlocal, there are plenty of other > builtins that we expand with just emit_library_call (as opposed to > emit_libcall_block) that also need this sort of treatment. I'm a little skeptical, although __sync_synchronize is probably not the only one indeed. I'll experiment. > Seems to me that this marking ought to be done in emit_library_call, > for at least most values of LCT_*. Otherwise you could get the same > ICE for e.g. memcpy. For a naked call to memcpy? I don't think so, this is a call so there will be an abnormal edge at the Tree level. The problem arises only when the abnormal edge is created during RTL expansion. > PS: ARM still uses sjlj exceptions for Ada? I thought with the obsolescence > of pre-eabi targets that we'd always use unwind tables now. Yes, that's the last one. Nobody has adapted (or submitted to the FSF) the #ifdef __ARM_EABI_UNWINDER__ / #endif adjustments present in libsupc++ or libjava.
On 11/15/2012 03:08 PM, Eric Botcazou wrote: > For a naked call to memcpy? I don't think so, this is a call so there will be > an abnormal edge at the Tree level. The problem arises only when the abnormal > edge is created during RTL expansion. Well, there's a call at the tree level for __sync_synchronize as well. So the question is: why does __s_s ICE but memcmp doesn't? I suppose it's the mere rarity with which HAVE_cmpmemsi is defined, and expansion of gen_cmpmemsi fails. There are plenty of other calls to emit_library_call_value that are not subsequently protected by emit_libcall_block_1, but they are probably sufficiently rare on common platforms that they'd be difficult to trigger. r~
Index: optabs.c =================================================================== --- optabs.c (revision 193528) +++ optabs.c (working copy) @@ -3838,6 +3838,23 @@ no_conflict_move_test (rtx dest, const_r } +/* Look for any CALL_INSNs in the insn chain starting at INSN and attach a + REG_EH_REGION reg note to indicate that this call cannot throw or execute + a nonlocal goto (unless there is already a REG_EH_REGION note, in which + case we update it). */ + +static void +mark_nothrow_nononlocal (rtx insn) +{ + while (insn) + { + if (CALL_P (insn)) + make_reg_eh_region_note_nothrow_nononlocal (insn); + + insn = NEXT_INSN (insn); + } +} + /* Emit code to make a call to a constant function or a library call. INSNS is a list containing all insns emitted in the call. @@ -3881,15 +3898,7 @@ emit_libcall_block_1 (rtx insns, rtx tar } } else - { - /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION - reg note to indicate that this call cannot throw or execute a nonlocal - goto (unless there is already a REG_EH_REGION note, in which case - we update it). */ - for (insn = insns; insn; insn = NEXT_INSN (insn)) - if (CALL_P (insn)) - make_reg_eh_region_note_nothrow_nononlocal (insn); - } + mark_nothrow_nononlocal (insns); /* First emit all insns that set pseudos. Remove them from the list as we go. Avoid insns that set pseudos which were referenced in previous @@ -7404,7 +7413,15 @@ expand_mem_thread_fence (enum memmodel m if (HAVE_memory_barrier) emit_insn (gen_memory_barrier ()); else if (synchronize_libfunc != NULL_RTX) - emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0); + { + rtx insns; + start_sequence (); + emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0); + insns = get_insns (); + end_sequence (); + mark_nothrow_nononlocal (insns); + emit_insn (insns); + } else expand_asm_memory_barrier (); }