This is the mail archive of the gcc-bugs@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]

[Bug target/56858] alpha looks for NOTE_INSN_EH_REGION notes that cannot exist


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56858

--- Comment #14 from UroÅ Bizjak <ubizjak at gmail dot com> ---
(In reply to UroÅ Bizjak from comment #12)

> Steven, is it possible to emit NOTE_INSN_EH_REGION_END in such way that it
> would not split the call and its NOTE_INSN_CALL_ARG_LOCATION? This would
> solve the above problem in the most elegant way.

Actually, it is "barriers" pass that splits the call and its
NOTE_INSN_CALL_ARG_LOCATION. Before the pass, we have:

(call_insn:TI 117 113 196 (parallel [
            (call (mem:DI (symbol_ref:DI ("__cxa_throw") [flags 0x41] 
<function_decl 0x7ff44719f900 __cxa_throw>) [0 __cxa_throw S8 A64])
                (const_int 0 [0]))
            (use (reg:DI 29 $29))
            (clobber (reg:DI 26 $26))
        ]) eh-vararg-1.C:62 207 {*call_osf_1_noreturn}
     (expr_list:REG_DEAD (reg:DI 18 $18)
        (expr_list:REG_DEAD (reg:DI 17 $17)
            (expr_list:REG_DEAD (reg:DI 16 $16)
                (expr_list:REG_EH_REGION (const_int 1 [0x1])
                    (expr_list:REG_CALL_DECL (symbol_ref:DI ("__cxa_throw")
[flags 0x41]  <function_decl 0x7ff44719f900 __cxa_throw>)
                        (expr_list:REG_NORETURN (const_int 0 [0])
                            (nil)))))))
    (expr_list:DI (use (reg:DI 16 $16))
        (expr_list:DI (use (reg:DI 17 $17))
            (expr_list:DI (use (reg:DI 18 $18))
                (nil)))))
(note 196 117 195 (expr_list:REG_DEP_TRUE (concat:DI (reg:DI 17 $17)
        (symbol_ref/i:DI ("_ZTI1A")  <var_decl 0x7ff447194630 _ZTI1A>))
    (expr_list:REG_DEP_TRUE (concat:DI (reg:DI 18 $18)
            (const_int 0 [0]))
        (nil))) NOTE_INSN_CALL_ARG_LOCATION)
(note/c 195 196 118 (var_location this (nil)) NOTE_INSN_VAR_LOCATION)
(barrier 118 195 197)

and "barriers" pass reorders this sequence to:

(call_insn:TI 117 113 118 (parallel [
            (call (mem:DI (symbol_ref:DI ("__cxa_throw") [flags 0x41] 
<function_decl 0x7f21556d0900 __cxa_throw>) [0 __cxa_throw S8 A64])
                (const_int 0 [0]))
            (use (reg:DI 29 $29))
            (clobber (reg:DI 26 $26))
        ]) eh-vararg-1.C:62 207 {*call_osf_1_noreturn}
     (expr_list:REG_DEAD (reg:DI 18 $18)
        (expr_list:REG_DEAD (reg:DI 17 $17)
            (expr_list:REG_DEAD (reg:DI 16 $16)
                (expr_list:REG_EH_REGION (const_int 1 [0x1])
                    (expr_list:REG_CALL_DECL (symbol_ref:DI ("__cxa_throw")
[flags 0x41]  <function_decl 0x7f21556d0900 __cxa_throw>)
                        (expr_list:REG_NORETURN (const_int 0 [0])
                            (nil)))))))
    (expr_list:DI (use (reg:DI 16 $16))
        (expr_list:DI (use (reg:DI 17 $17))
            (expr_list:DI (use (reg:DI 18 $18))
                (nil)))))
(barrier 118 117 196)
(note 196 118 195 (expr_list:REG_DEP_TRUE (concat:DI (reg:DI 17 $17)
        (symbol_ref/i:DI ("_ZTI1A")  <var_decl 0x7f21556c5630 _ZTI1A>))
    (expr_list:REG_DEP_TRUE (concat:DI (reg:DI 18 $18)
            (const_int 0 [0]))
        (nil))) NOTE_INSN_CALL_ARG_LOCATION)
(note/c 195 196 197 (var_location this (nil)) NOTE_INSN_VAR_LOCATION)

Indeed the purpose of "barriers" RTL pass is (from jump.c):

--cut here--
/* Some old code expects exactly one BARRIER as the NEXT_INSN of a
   non-fallthru insn.  This is not generally true, as multiple barriers
   may have crept in, or the BARRIER may be separated from the last
   real insn by one or more NOTEs.

   This simple pass moves barriers and removes duplicates so that the
   old code is happy.
 */
static unsigned int
cleanup_barriers (void)
{
  rtx insn, next, prev;
  for (insn = get_insns (); insn; insn = next)
    {
      next = NEXT_INSN (insn);
      if (BARRIER_P (insn))
    {
      prev = prev_nonnote_insn (insn);
      if (!prev)
        continue;
      if (BARRIER_P (prev))
        delete_insn (insn);
      else if (prev != PREV_INSN (insn))
        reorder_insns_nobb (insn, insn, prev);
    }
    }
  return 0;
}
--cut here--

This is the hack to "keep the old code happy" (?!), instead of teaching the
problematic code that varous debug notes can be between paired insns in the
insn stream.

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