Re: RFA: Merge definitions of get_some_local_dynamic_name
On 10/08/14 10:04, Richard Sandiford wrote: Rainer Orth r...@cebitec.uni-bielefeld.de writes: Hi Richard, Does this work for you? I tested it on x86_64-linux-gnu but obviously that's not particularly useful for SEQUENCEs. the patch is fine, as tested on both sparc-sun-solaris2.11 and (for good measure) i386-pc-solaris2.11. OK, great. To recap, the idea is that if PATTERN (insn) is a SEQUENCE: FOR_EACH_SUBRTX (, insn, x) ... should iterate over the insns in the SEQUENCE (including pattern, notes, jump label, etc.). However: FOR_EACH_SUBRTX (, PATTERN (insn), x) ... should only iterate over the patterns of the insns in the SEQUENCE, since the user of FOR_EACH_SUBRTX isn't expecting to see things like REG_NOTES (and might not handle them correctly). Also tested on x86_64-linux-gnu. OK to install? Thanks, Richard gcc/ * rtlanal.c (generic_subrtx_iterator T::add_subrtxes_to_queue): Add the parts of an insn in reverse order, with the pattern at the top of the queue. Detect when we're iterating over a SEQUENCE pattern and in that case just consider patterns of subinstructions. OK. jeff
Re: RFA: Merge definitions of get_some_local_dynamic_name
Hi Richard, Does this work for you? I tested it on x86_64-linux-gnu but obviously that's not particularly useful for SEQUENCEs. the patch is fine, as tested on both sparc-sun-solaris2.11 and (for good measure) i386-pc-solaris2.11. Thanks. Rainer -- - Rainer Orth, Center for Biotechnology, Bielefeld University
Re: RFA: Merge definitions of get_some_local_dynamic_name
Rainer Orth r...@cebitec.uni-bielefeld.de writes: Hi Richard, Does this work for you? I tested it on x86_64-linux-gnu but obviously that's not particularly useful for SEQUENCEs. the patch is fine, as tested on both sparc-sun-solaris2.11 and (for good measure) i386-pc-solaris2.11. OK, great. To recap, the idea is that if PATTERN (insn) is a SEQUENCE: FOR_EACH_SUBRTX (, insn, x) ... should iterate over the insns in the SEQUENCE (including pattern, notes, jump label, etc.). However: FOR_EACH_SUBRTX (, PATTERN (insn), x) ... should only iterate over the patterns of the insns in the SEQUENCE, since the user of FOR_EACH_SUBRTX isn't expecting to see things like REG_NOTES (and might not handle them correctly). Also tested on x86_64-linux-gnu. OK to install? Thanks, Richard gcc/ * rtlanal.c (generic_subrtx_iterator T::add_subrtxes_to_queue): Add the parts of an insn in reverse order, with the pattern at the top of the queue. Detect when we're iterating over a SEQUENCE pattern and in that case just consider patterns of subinstructions. Index: gcc/rtlanal.c === --- gcc/rtlanal.c 2014-09-25 16:40:44.944406590 +0100 +++ gcc/rtlanal.c 2014-10-07 13:13:57.698132753 +0100 @@ -128,29 +128,58 @@ generic_subrtx_iterator T::add_subrtxe value_type *base, size_t end, rtx_type x) { - const char *format = GET_RTX_FORMAT (GET_CODE (x)); + enum rtx_code code = GET_CODE (x); + const char *format = GET_RTX_FORMAT (code); size_t orig_end = end; - for (int i = 0; format[i]; ++i) -if (format[i] == 'e') - { - value_type subx = T::get_value (x-u.fld[i].rt_rtx); - if (__builtin_expect (end LOCAL_ELEMS, true)) - base[end++] = subx; - else - base = add_single_to_queue (array, base, end++, subx); - } -else if (format[i] == 'E') - { - int length = GET_NUM_ELEM (x-u.fld[i].rt_rtvec); - rtx *vec = x-u.fld[i].rt_rtvec-elem; - if (__builtin_expect (end + length = LOCAL_ELEMS, true)) - for (int j = 0; j length; j++) - base[end++] = T::get_value (vec[j]); - else - for (int j = 0; j length; j++) - base = add_single_to_queue (array, base, end++, - T::get_value (vec[j])); - } + if (__builtin_expect (INSN_P (x), false)) +{ + /* Put the pattern at the top of the queue, since that's what +we're likely to want most. It also allows for the SEQUENCE +code below. */ + for (int i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i = 0; --i) + if (format[i] == 'e') + { + value_type subx = T::get_value (x-u.fld[i].rt_rtx); + if (__builtin_expect (end LOCAL_ELEMS, true)) + base[end++] = subx; + else + base = add_single_to_queue (array, base, end++, subx); + } +} + else +for (int i = 0; format[i]; ++i) + if (format[i] == 'e') + { + value_type subx = T::get_value (x-u.fld[i].rt_rtx); + if (__builtin_expect (end LOCAL_ELEMS, true)) + base[end++] = subx; + else + base = add_single_to_queue (array, base, end++, subx); + } + else if (format[i] == 'E') + { + unsigned int length = GET_NUM_ELEM (x-u.fld[i].rt_rtvec); + rtx *vec = x-u.fld[i].rt_rtvec-elem; + if (__builtin_expect (end + length = LOCAL_ELEMS, true)) + for (unsigned int j = 0; j length; j++) + base[end++] = T::get_value (vec[j]); + else + for (unsigned int j = 0; j length; j++) + base = add_single_to_queue (array, base, end++, + T::get_value (vec[j])); + if (code == SEQUENCE end == length) + /* If the subrtxes of the sequence fill the entire array then + we know that no other parts of a containing insn are queued. + The caller is therefore iterating over the sequence as a + PATTERN (...), so we also want the patterns of the + subinstructions. */ + for (unsigned int j = 0; j length; j++) + { + typename T::rtx_type x = T::get_rtx (base[j]); + if (INSN_P (x)) + base[j] = T::get_value (PATTERN (x)); + } + } return end - orig_end; }
Re: RFA: Merge definitions of get_some_local_dynamic_name
Richard Sandiford rdsandif...@googlemail.com writes: Rainer Orth r...@cebitec.uni-bielefeld.de writes: Hi Richard, Rainer Orth r...@cebitec.uni-bielefeld.de writes: Hi Richard, It seems the new get_some_local_dynamic_name implementation in function.c lost the non-NULL check the sparc.c version had. I'm currently testing the following patch: Could you do a: call debug_rtx (...) on the insn that contains a null pointer? Normally insn patterns shouldn't contain nulls, so I was wondering whether this was some SPARC-specific construct. proved a bit difficult to do: at the default -O2, insn was optimized away, at -g3 -O0, I only got can't compute CFA for this frame with gdb 7.8 even after recompiling all of the gcc dir with -g3 -O0. Here's what I find after inserting the call in the source: (insn 30 6 28 (sequence [ (call_insn:TI 8 6 7 (parallel [ (set (reg:SI 8 %o0) (call (mem:SI (unspec:SI [ (symbol_ref:SI (__tls_get_addr)) ] UNSPEC_TLSLDM) [0 S4 A32]) (const_int 1 [0x1]))) (clobber (reg:SI 15 %o7)) ]) /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c:936 390 {tldm_call32} (expr_list:REG_EH_REGION (const_int -2147483648 [0x8000]) (nil)) (expr_list (use (reg:SI 8 %o0)) (nil))) (insn 7 8 28 (set (reg:SI 8 %o0) (plus:SI (reg:SI 23 %l7) (unspec:SI [ (reg:SI 8 %o0 [112]) ] UNSPEC_TLSLDM))) 388 {tldm_add32} (nil)) ]) /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c:936 -1 (nil)) Bah, a sequence. Hadn't thought of that. IMO it's a bug for a walk on a PATTERN to pull in non-PATTERN parts of an insn. We should really be looking at the patterns of the two subinsns instead and ignore the other stuff. Let me have a think about it. did you come to a conclusion here? Sorry, forgot to come back to this. I have a patch that iterates over PATTERNs of a SEQUENCE if the SEQUENCE (rather than its containing insn) is the topmost iterated rtx. So if PATTERN (insn) is a SEQUENCE: FOR_EACH_SUBRTX (, insn, x) ... will iterate over the insns in the SEQUENCE (including pattern, notes, jump label, etc.), whereas: FOR_EACH_SUBRTX (, PATTERN (insn), x) ... would only iterate over the patterns of the insns in the SEQUENCE. Does this work for you? I tested it on x86_64-linux-gnu but obviously that's not particularly useful for SEQUENCEs. Thanks, Richard gcc/ * rtlanal.c (generic_subrtx_iterator T::add_subrtxes_to_queue): Add the parts of an insn in reverse order, with the pattern at the top of the queue. Detect when we're iterating over a SEQUENCE pattern and in that case just consider patterns of subinstructions. Index: gcc/rtlanal.c === --- gcc/rtlanal.c 2014-09-25 16:40:44.944406590 +0100 +++ gcc/rtlanal.c 2014-10-07 13:13:57.698132753 +0100 @@ -128,29 +128,58 @@ generic_subrtx_iterator T::add_subrtxe value_type *base, size_t end, rtx_type x) { - const char *format = GET_RTX_FORMAT (GET_CODE (x)); + enum rtx_code code = GET_CODE (x); + const char *format = GET_RTX_FORMAT (code); size_t orig_end = end; - for (int i = 0; format[i]; ++i) -if (format[i] == 'e') - { - value_type subx = T::get_value (x-u.fld[i].rt_rtx); - if (__builtin_expect (end LOCAL_ELEMS, true)) - base[end++] = subx; - else - base = add_single_to_queue (array, base, end++, subx); - } -else if (format[i] == 'E') - { - int length = GET_NUM_ELEM (x-u.fld[i].rt_rtvec); - rtx *vec = x-u.fld[i].rt_rtvec-elem; - if (__builtin_expect (end + length = LOCAL_ELEMS, true)) - for (int j = 0; j length; j++) - base[end++] = T::get_value (vec[j]); - else - for (int j = 0; j length; j++) - base = add_single_to_queue (array, base, end++, - T::get_value (vec[j])); - } + if (__builtin_expect (INSN_P (x), false)) +{ + /* Put the pattern at the top of the queue, since that's what +we're likely to want most. It also allows for the SEQUENCE +code below. */ + for (int i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i = 0; --i) + if (format[i] == 'e') + { + value_type subx = T::get_value (x-u.fld[i].rt_rtx); + if (__builtin_expect (end LOCAL_ELEMS, true)) + base[end++] = subx; + else
Re: RFA: Merge definitions of get_some_local_dynamic_name
Hi Richard, Rainer Orth r...@cebitec.uni-bielefeld.de writes: Hi Richard, It seems the new get_some_local_dynamic_name implementation in function.c lost the non-NULL check the sparc.c version had. I'm currently testing the following patch: Could you do a: call debug_rtx (...) on the insn that contains a null pointer? Normally insn patterns shouldn't contain nulls, so I was wondering whether this was some SPARC-specific construct. proved a bit difficult to do: at the default -O2, insn was optimized away, at -g3 -O0, I only got can't compute CFA for this frame with gdb 7.8 even after recompiling all of the gcc dir with -g3 -O0. Here's what I find after inserting the call in the source: (insn 30 6 28 (sequence [ (call_insn:TI 8 6 7 (parallel [ (set (reg:SI 8 %o0) (call (mem:SI (unspec:SI [ (symbol_ref:SI (__tls_get_addr)) ] UNSPEC_TLSLDM) [0 S4 A32]) (const_int 1 [0x1]))) (clobber (reg:SI 15 %o7)) ]) /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c:936 390 {tldm_call32} (expr_list:REG_EH_REGION (const_int -2147483648 [0x8000]) (nil)) (expr_list (use (reg:SI 8 %o0)) (nil))) (insn 7 8 28 (set (reg:SI 8 %o0) (plus:SI (reg:SI 23 %l7) (unspec:SI [ (reg:SI 8 %o0 [112]) ] UNSPEC_TLSLDM))) 388 {tldm_add32} (nil)) ]) /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c:936 -1 (nil)) Bah, a sequence. Hadn't thought of that. IMO it's a bug for a walk on a PATTERN to pull in non-PATTERN parts of an insn. We should really be looking at the patterns of the two subinsns instead and ignore the other stuff. Let me have a think about it. did you come to a conclusion here? Now that we know the underlying cause, I personally wouldn't mind the null check being committed as a workaround. If you do though, please could you add a comment saying that this is for SEQUENCEs? I've had the following in my local tree for some weeks now to keep SPARC bootstrap working: 2014-10-06 Rainer Orth r...@cebitec.uni-bielefeld.de * final.c (get_some_local_dynamic_name): Guard against NULL const_rtx. # HG changeset patch # Parent 5768379d027521837a7be746630c3f53cc5bce83 Fix SPARC bootstrap: get_some_local_dynamic_name diff --git a/gcc/final.c b/gcc/final.c --- a/gcc/final.c +++ b/gcc/final.c @@ -1739,7 +1739,8 @@ get_some_local_dynamic_name () FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL) { const_rtx x = *iter; - if (GET_CODE (x) == SYMBOL_REF) + /* NULL check to guard against SEQUENCEs. */ + if (x GET_CODE (x) == SYMBOL_REF) { if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC) return some_local_dynamic_name = XSTR (x, 0); Rainer -- - Rainer Orth, Center for Biotechnology, Bielefeld University
Re: RFA: Merge definitions of get_some_local_dynamic_name
Rainer Orth r...@cebitec.uni-bielefeld.de writes: Hi Richard, Rainer Orth r...@cebitec.uni-bielefeld.de writes: Hi Richard, It seems the new get_some_local_dynamic_name implementation in function.c lost the non-NULL check the sparc.c version had. I'm currently testing the following patch: Could you do a: call debug_rtx (...) on the insn that contains a null pointer? Normally insn patterns shouldn't contain nulls, so I was wondering whether this was some SPARC-specific construct. proved a bit difficult to do: at the default -O2, insn was optimized away, at -g3 -O0, I only got can't compute CFA for this frame with gdb 7.8 even after recompiling all of the gcc dir with -g3 -O0. Here's what I find after inserting the call in the source: (insn 30 6 28 (sequence [ (call_insn:TI 8 6 7 (parallel [ (set (reg:SI 8 %o0) (call (mem:SI (unspec:SI [ (symbol_ref:SI (__tls_get_addr)) ] UNSPEC_TLSLDM) [0 S4 A32]) (const_int 1 [0x1]))) (clobber (reg:SI 15 %o7)) ]) /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c:936 390 {tldm_call32} (expr_list:REG_EH_REGION (const_int -2147483648 [0x8000]) (nil)) (expr_list (use (reg:SI 8 %o0)) (nil))) (insn 7 8 28 (set (reg:SI 8 %o0) (plus:SI (reg:SI 23 %l7) (unspec:SI [ (reg:SI 8 %o0 [112]) ] UNSPEC_TLSLDM))) 388 {tldm_add32} (nil)) ]) /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c:936 -1 (nil)) Bah, a sequence. Hadn't thought of that. IMO it's a bug for a walk on a PATTERN to pull in non-PATTERN parts of an insn. We should really be looking at the patterns of the two subinsns instead and ignore the other stuff. Let me have a think about it. did you come to a conclusion here? Sorry, forgot to come back to this. I have a patch that iterates over PATTERNs of a SEQUENCE if the SEQUENCE (rather than its containing insn) is the topmost iterated rtx. So if PATTERN (insn) is a SEQUENCE: FOR_EACH_SUBRTX (, insn, x) ... will iterate over the insns in the SEQUENCE (including pattern, notes, jump label, etc.), whereas: FOR_EACH_SUBRTX (, PATTERN (insn), x) ... would only iterate over the patterns of the insns in the SEQUENCE. I'll need to pass it through internal review before sending, but hope to post soon. Thanks, Richard
Re: RFA: Merge definitions of get_some_local_dynamic_name
Hi Richard, It seems the new get_some_local_dynamic_name implementation in function.c lost the non-NULL check the sparc.c version had. I'm currently testing the following patch: Could you do a: call debug_rtx (...) on the insn that contains a null pointer? Normally insn patterns shouldn't contain nulls, so I was wondering whether this was some SPARC-specific construct. proved a bit difficult to do: at the default -O2, insn was optimized away, at -g3 -O0, I only got can't compute CFA for this frame with gdb 7.8 even after recompiling all of the gcc dir with -g3 -O0. Here's what I find after inserting the call in the source: (insn 30 6 28 (sequence [ (call_insn:TI 8 6 7 (parallel [ (set (reg:SI 8 %o0) (call (mem:SI (unspec:SI [ (symbol_ref:SI (__tls_get_addr)) ] UNSPEC_TLSLDM) [0 S4 A32]) (const_int 1 [0x1]))) (clobber (reg:SI 15 %o7)) ]) /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c:936 390 {tldm_call32} (expr_list:REG_EH_REGION (const_int -2147483648 [0x8000]) (nil)) (expr_list (use (reg:SI 8 %o0)) (nil))) (insn 7 8 28 (set (reg:SI 8 %o0) (plus:SI (reg:SI 23 %l7) (unspec:SI [ (reg:SI 8 %o0 [112]) ] UNSPEC_TLSLDM))) 388 {tldm_add32} (nil)) ]) /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c:936 -1 (nil)) Rainer -- - Rainer Orth, Center for Biotechnology, Bielefeld University
Re: RFA: Merge definitions of get_some_local_dynamic_name
Rainer Orth r...@cebitec.uni-bielefeld.de writes: Hi Richard, It seems the new get_some_local_dynamic_name implementation in function.c lost the non-NULL check the sparc.c version had. I'm currently testing the following patch: Could you do a: call debug_rtx (...) on the insn that contains a null pointer? Normally insn patterns shouldn't contain nulls, so I was wondering whether this was some SPARC-specific construct. proved a bit difficult to do: at the default -O2, insn was optimized away, at -g3 -O0, I only got can't compute CFA for this frame with gdb 7.8 even after recompiling all of the gcc dir with -g3 -O0. Here's what I find after inserting the call in the source: (insn 30 6 28 (sequence [ (call_insn:TI 8 6 7 (parallel [ (set (reg:SI 8 %o0) (call (mem:SI (unspec:SI [ (symbol_ref:SI (__tls_get_addr)) ] UNSPEC_TLSLDM) [0 S4 A32]) (const_int 1 [0x1]))) (clobber (reg:SI 15 %o7)) ]) /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c:936 390 {tldm_call32} (expr_list:REG_EH_REGION (const_int -2147483648 [0x8000]) (nil)) (expr_list (use (reg:SI 8 %o0)) (nil))) (insn 7 8 28 (set (reg:SI 8 %o0) (plus:SI (reg:SI 23 %l7) (unspec:SI [ (reg:SI 8 %o0 [112]) ] UNSPEC_TLSLDM))) 388 {tldm_add32} (nil)) ]) /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c:936 -1 (nil)) Bah, a sequence. Hadn't thought of that. IMO it's a bug for a walk on a PATTERN to pull in non-PATTERN parts of an insn. We should really be looking at the patterns of the two subinsns instead and ignore the other stuff. Let me have a think about it. Now that we know the underlying cause, I personally wouldn't mind the null check being committed as a workaround. If you do though, please could you add a comment saying that this is for SEQUENCEs? Thanks, Richard
Re: RFA: Merge definitions of get_some_local_dynamic_name
Hi Richard, Several targets define a function like i386's get_some_local_dynamic_name. The function looks through the current output function and returns the first (arbitrary) local-dynamic symbol that it finds. The result can be used in a call to __tls_get_addr, since all local-dynamic symbols have the same base. This patch replaces the various target functions with a single generic one. The only difference between the implementations was that s390 checked for constant pool references while the others didn't need to (because they don't allow TLS symbols to be forced into the pool). Checking for constant pool references is unnecessary but harmless for the other ports. Also, the walk is needed only once per TLS-referencing output function, so it's hardly critical in terms of compile time. All uses of this function are in final. In general it wouldn't be safe to call the function earlier than that, since the symbol reference could in principle be deleted by any rtl pass. I've therefore cached it in a variable local to final rather than in cfun (which is where the ports used to cache it). Also, i386 was robust against uses of % in inline asm. The patch makes sure the other ports are too. Using % in inline asm would often be a mistake, but it should at least trigger a proper error rather than an ICE. Tested on x86_64-linux-gnu. Also tested by building cross compilers before and after the change on: alpha-linux-gnu powerpc64-linux-gnu s390x-linux-gnu sparc64-linux-gnu OK to install? this patch broke Solaris/SPARC bootstrap: compiling libgo/runtime/proc.c with -fPIC SEGVs: /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c: In function 'procresize': /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c:2727:1: internal compiler error: Segmentation Fault } ^ 0x731c97 crash_signal /vol/gcc/src/hg/trunk/local/gcc/toplev.c:339 0x45facc get_some_local_dynamic_name() /vol/gcc/src/hg/trunk/local/gcc/final.c:1742 0xa0886f sparc_print_operand /vol/gcc/src/hg/trunk/local/gcc/config/sparc/sparc.c:8789 0x4606a3 output_operand(rtx_def*, int) /vol/gcc/src/hg/trunk/local/gcc/final.c:3848 0x460fdf output_asm_insn(char const*, rtx_def**) /vol/gcc/src/hg/trunk/local/gcc/final.c:3778 0x46254b output_asm_insn(char const*, rtx_def**) /vol/gcc/src/hg/trunk/local/gcc/recog.h:169 0x46254b final_scan_insn(rtx_insn*, __FILE*, int, int, int*) /vol/gcc/src/hg/trunk/local/gcc/final.c:3027 0x462b53 final(rtx_insn*, __FILE*, int) /vol/gcc/src/hg/trunk/local/gcc/final.c:2063 0x46470f rest_of_handle_final /vol/gcc/src/hg/trunk/local/gcc/final.c:4470 0x46470f execute /vol/gcc/src/hg/trunk/local/gcc/final.c:4545 Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 1 (LWP 1)] get_some_local_dynamic_name () at /vol/gcc/src/hg/trunk/local/gcc/final.c:1742 1742 if (GET_CODE (x) == SYMBOL_REF) 1: x/i $pc = 0x45facc get_some_local_dynamic_name()+84: lduh [ %o0 ], %g1 (gdb) p $o0 $1 = 0 (gdb) where #0 get_some_local_dynamic_name () at /vol/gcc/src/hg/trunk/local/gcc/final.c:1742 #1 0x00a08870 in sparc_print_operand (file=0x10ab0f0 _iob+48, x=0x0, code=optimized out) at /vol/gcc/src/hg/trunk/local/gcc/config/sparc/sparc.c:8789 #2 0x004606a4 in output_operand (x=0x0, code=38) at /vol/gcc/src/hg/trunk/local/gcc/final.c:3848 #3 0x00460fe0 in output_asm_insn (templ=templ@entry=0xf1e5c8 sethi\t%%tldm_hi22(%), %0, operands=0x107feb0 recog_data) at /vol/gcc/src/hg/trunk/local/gcc/final.c:3778 #4 0x0046254c in output_asm_insn (operands=optimized out, templ=0xf1e5c8 sethi\t%%tldm_hi22(%), %0) at /vol/gcc/src/hg/trunk/local/gcc/recog.h:169 #5 final_scan_insn (insn=insn@entry=0xfac70de8, file=file@entry=0x10ab0f0 _iob+48, optimize_p=optimize_p@entry=2, nopeepholes=nopeepholes@entry=0, seen=seen@entry=0xffbfef0c) at /vol/gcc/src/hg/trunk/local/gcc/final.c:3027 #6 0x00462b54 in final (first=0xfac62020, file=0x10ab0f0 _iob+48, optimize_p=2) at /vol/gcc/src/hg/trunk/local/gcc/final.c:2063 #7 0x00464710 in rest_of_handle_final () at /vol/gcc/src/hg/trunk/local/gcc/final.c:4470 #8 (anonymous namespace)::pass_final::execute (this=0x10d9050) at /vol/gcc/src/hg/trunk/local/gcc/final.c:4545 #9 0x00661cf4 in execute_one_pass (pass=pass@entry=0x10d9050) at /vol/gcc/src/hg/trunk/local/gcc/passes.c:2151 #10 0x0066235c in execute_pass_list_1 (pass=0x10d9050) at /vol/gcc/src/hg/trunk/local/gcc/passes.c:2203 #11 0x00662380 in execute_pass_list_1 (pass=0x10d8630) at /vol/gcc/src/hg/trunk/local/gcc/passes.c:2204 #12 0x00662380 in execute_pass_list_1 (pass=0x10d7988, pass@entry=0x10d54a8) at /vol/gcc/src/hg/trunk/local/gcc/passes.c:2204 #13 0x006623c4 in execute_pass_list (fn=0xfb5fc5b0, pass=0x10d54a8) at /vol/gcc/src/hg/trunk/local/gcc/passes.c:2214 #14 0x0037d728 in cgraph_node::expand (this=this@entry=0xfb5f5180) at /vol/gcc/src/hg/trunk/local/gcc/cgraphunit.c:1744 #15 0x0037f078 in
Re: RFA: Merge definitions of get_some_local_dynamic_name
Rainer Orth r...@cebitec.uni-bielefeld.de writes: Hi Richard, Several targets define a function like i386's get_some_local_dynamic_name. The function looks through the current output function and returns the first (arbitrary) local-dynamic symbol that it finds. The result can be used in a call to __tls_get_addr, since all local-dynamic symbols have the same base. This patch replaces the various target functions with a single generic one. The only difference between the implementations was that s390 checked for constant pool references while the others didn't need to (because they don't allow TLS symbols to be forced into the pool). Checking for constant pool references is unnecessary but harmless for the other ports. Also, the walk is needed only once per TLS-referencing output function, so it's hardly critical in terms of compile time. All uses of this function are in final. In general it wouldn't be safe to call the function earlier than that, since the symbol reference could in principle be deleted by any rtl pass. I've therefore cached it in a variable local to final rather than in cfun (which is where the ports used to cache it). Also, i386 was robust against uses of % in inline asm. The patch makes sure the other ports are too. Using % in inline asm would often be a mistake, but it should at least trigger a proper error rather than an ICE. Tested on x86_64-linux-gnu. Also tested by building cross compilers before and after the change on: alpha-linux-gnu powerpc64-linux-gnu s390x-linux-gnu sparc64-linux-gnu OK to install? this patch broke Solaris/SPARC bootstrap: compiling libgo/runtime/proc.c with -fPIC SEGVs: /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c: In function 'procresize': /vol/gcc/src/hg/trunk/local/libgo/runtime/proc.c:2727:1: internal compiler error: Segmentation Fault } ^ 0x731c97 crash_signal /vol/gcc/src/hg/trunk/local/gcc/toplev.c:339 0x45facc get_some_local_dynamic_name() /vol/gcc/src/hg/trunk/local/gcc/final.c:1742 0xa0886f sparc_print_operand /vol/gcc/src/hg/trunk/local/gcc/config/sparc/sparc.c:8789 0x4606a3 output_operand(rtx_def*, int) /vol/gcc/src/hg/trunk/local/gcc/final.c:3848 0x460fdf output_asm_insn(char const*, rtx_def**) /vol/gcc/src/hg/trunk/local/gcc/final.c:3778 0x46254b output_asm_insn(char const*, rtx_def**) /vol/gcc/src/hg/trunk/local/gcc/recog.h:169 0x46254b final_scan_insn(rtx_insn*, __FILE*, int, int, int*) /vol/gcc/src/hg/trunk/local/gcc/final.c:3027 0x462b53 final(rtx_insn*, __FILE*, int) /vol/gcc/src/hg/trunk/local/gcc/final.c:2063 0x46470f rest_of_handle_final /vol/gcc/src/hg/trunk/local/gcc/final.c:4470 0x46470f execute /vol/gcc/src/hg/trunk/local/gcc/final.c:4545 Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 1 (LWP 1)] get_some_local_dynamic_name () at /vol/gcc/src/hg/trunk/local/gcc/final.c:1742 1742if (GET_CODE (x) == SYMBOL_REF) 1: x/i $pc = 0x45facc get_some_local_dynamic_name()+84: lduh [ %o0 ], %g1 (gdb) p $o0 $1 = 0 (gdb) where #0 get_some_local_dynamic_name () at /vol/gcc/src/hg/trunk/local/gcc/final.c:1742 #1 0x00a08870 in sparc_print_operand (file=0x10ab0f0 _iob+48, x=0x0, code=optimized out) at /vol/gcc/src/hg/trunk/local/gcc/config/sparc/sparc.c:8789 #2 0x004606a4 in output_operand (x=0x0, code=38) at /vol/gcc/src/hg/trunk/local/gcc/final.c:3848 #3 0x00460fe0 in output_asm_insn (templ=templ@entry=0xf1e5c8 sethi\t%%tldm_hi22(%), %0, operands=0x107feb0 recog_data) at /vol/gcc/src/hg/trunk/local/gcc/final.c:3778 #4 0x0046254c in output_asm_insn (operands=optimized out, templ=0xf1e5c8 sethi\t%%tldm_hi22(%), %0) at /vol/gcc/src/hg/trunk/local/gcc/recog.h:169 #5 final_scan_insn (insn=insn@entry=0xfac70de8, file=file@entry=0x10ab0f0 _iob+48, optimize_p=optimize_p@entry=2, nopeepholes=nopeepholes@entry=0, seen=seen@entry=0xffbfef0c) at /vol/gcc/src/hg/trunk/local/gcc/final.c:3027 #6 0x00462b54 in final (first=0xfac62020, file=0x10ab0f0 _iob+48, optimize_p=2) at /vol/gcc/src/hg/trunk/local/gcc/final.c:2063 #7 0x00464710 in rest_of_handle_final () at /vol/gcc/src/hg/trunk/local/gcc/final.c:4470 #8 (anonymous namespace)::pass_final::execute (this=0x10d9050) at /vol/gcc/src/hg/trunk/local/gcc/final.c:4545 #9 0x00661cf4 in execute_one_pass (pass=pass@entry=0x10d9050) at /vol/gcc/src/hg/trunk/local/gcc/passes.c:2151 #10 0x0066235c in execute_pass_list_1 (pass=0x10d9050) at /vol/gcc/src/hg/trunk/local/gcc/passes.c:2203 #11 0x00662380 in execute_pass_list_1 (pass=0x10d8630) at /vol/gcc/src/hg/trunk/local/gcc/passes.c:2204 #12 0x00662380 in execute_pass_list_1 (pass=0x10d7988, pass@entry=0x10d54a8) at /vol/gcc/src/hg/trunk/local/gcc/passes.c:2204 #13 0x006623c4 in execute_pass_list (fn=0xfb5fc5b0, pass=0x10d54a8) at /vol/gcc/src/hg/trunk/local/gcc/passes.c:2214 #14 0x0037d728 in
Re: RFA: Merge definitions of get_some_local_dynamic_name
On Tue, 2 Sep 2014, Richard Sandiford wrote: Also, i386 was robust against uses of % in inline asm. The patch makes sure the other ports are too. Using % in inline asm would often be a mistake, but it should at least trigger a proper error rather than an ICE. Tested on x86_64-linux-gnu. Also tested by building cross compilers before and after the change on: alpha-linux-gnu powerpc64-linux-gnu s390x-linux-gnu sparc64-linux-gnu Is it possible this is related to the following new (set of) bootstrap failure(s) my i386-unknown-freebsd10.0 tester shows as new in the last 24 hours? /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c: In function '__lshrdi3': /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c:426:1: internal compiler error: in gen_variable_die, at dwarf2out.c:19017 } ^ /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c: In function '__ashrdi3': /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c: In function '__ashldi3': /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c:483:1: internal compiler error: in gen_variable_die, at dwarf2out.c:19017 } ^ /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c:454:1: internal compiler error: in gen_variable_die, at dwarf2out.c:19017 } ^ Parallel build, hence three ICEs at once. :-) Gerald
Re: RFA: Merge definitions of get_some_local_dynamic_name
Gerald Pfeifer ger...@pfeifer.com writes: On Tue, 2 Sep 2014, Richard Sandiford wrote: Also, i386 was robust against uses of % in inline asm. The patch makes sure the other ports are too. Using % in inline asm would often be a mistake, but it should at least trigger a proper error rather than an ICE. Tested on x86_64-linux-gnu. Also tested by building cross compilers before and after the change on: alpha-linux-gnu powerpc64-linux-gnu s390x-linux-gnu sparc64-linux-gnu Is it possible this is related to the following new (set of) bootstrap failure(s) my i386-unknown-freebsd10.0 tester shows as new in the last 24 hours? /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c: In function '__lshrdi3': /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c:426:1: internal compiler error: in gen_variable_die, at dwarf2out.c:19017 } ^ /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c: In function '__ashrdi3': /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c: In function '__ashldi3': /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c:483:1: internal compiler error: in gen_variable_die, at dwarf2out.c:19017 } ^ /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c:454:1: internal compiler error: in gen_variable_die, at dwarf2out.c:19017 } ^ Parallel build, hence three ICEs at once. :-) Is this stage 1 libgcc or a later libgcc? Seems unlikely if stage 1. Thanks, Richard
Re: RFA: Merge definitions of get_some_local_dynamic_name
On Thu, 4 Sep 2014, Richard Sandiford wrote: Is this stage 1 libgcc or a later libgcc? Seems unlikely if stage 1. Stage 1. I kicked off a non-parallel build, which just failed as follows: /scratch2/tmp/gerald/OBJ-0904-1719/./gcc/xgcc -B/scratch2/tmp/gerald/OBJ-0904-1719/./gcc/ -B/home/gerald/gcc-ref10-i386/i386-unknown-freebsd10.0/bin/ -B/home/gerald/gcc-ref10-i386/i386-unknown-freebsd10.0/lib/ -isystem /home/gerald/gcc-ref10-i386/i386-unknown-freebsd10.0/include -isystem /home/gerald/gcc-ref10-i386/i386-unknown-freebsd10.0/sys-include-g -O2 -O2 -g -O2 -DIN_GCC-W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wno-format -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -fpic -pthread -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -fpic -pthread -I. -I. -I../.././gcc -I/scratch2/tmp/gerald/gcc-HEAD/libgcc -I/scratch2/tmp/gerald/gcc-HEAD/libgcc/. -I/scratch2/tmp/gerald/gcc-HEAD/libgcc/../gcc -I/scratch2/tmp/gerald/gcc-HEAD/libgcc/../include -DHAVE_CC_TLS -o _muldi3.o -MT _muldi3.o -MD -MP -MF _muldi3.dep -DL_muldi3 -c /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c -fvisibility=hidden -DHIDE_EXPORTS /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c: In function ‘__muldi3’: /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c:557:1: internal compiler error: in gen_variable_die, at dwarf2out.c:19017 } ^ no stack trace because unwind library not available gmake[3]: *** [_muldi3.o] Error 1 gmake[3]: Leaving directory `/scratch2/tmp/gerald/OBJ-0904-1719/i386-unknown-freebsd10.0/libgcc' gmake[2]: *** [all-stage1-target-libgcc] Error 2 Any ideas which recent commit this might be due to? Gerald
Re: RFA: Merge definitions of get_some_local_dynamic_name
Gerald Pfeifer ger...@pfeifer.com writes: On Thu, 4 Sep 2014, Richard Sandiford wrote: Is this stage 1 libgcc or a later libgcc? Seems unlikely if stage 1. Stage 1. I kicked off a non-parallel build, which just failed as follows: /scratch2/tmp/gerald/OBJ-0904-1719/./gcc/xgcc -B/scratch2/tmp/gerald/OBJ-0904-1719/./gcc/ -B/home/gerald/gcc-ref10-i386/i386-unknown-freebsd10.0/bin/ -B/home/gerald/gcc-ref10-i386/i386-unknown-freebsd10.0/lib/ -isystem /home/gerald/gcc-ref10-i386/i386-unknown-freebsd10.0/include -isystem /home/gerald/gcc-ref10-i386/i386-unknown-freebsd10.0/sys-include -g -O2 -O2 -g -O2 -DIN_GCC -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wno-format -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -fpic -pthread -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -fpic -pthread -I. -I. -I../.././gcc -I/scratch2/tmp/gerald/gcc-HEAD/libgcc -I/scratch2/tmp/gerald/gcc-HEAD/libgcc/. -I/scratch2/tmp/gerald/gcc-HEAD/libgcc/../gcc -I/scratch2/tmp/gerald/gcc-HEAD/libgcc/../include -DHAVE_CC_TLS -o _muldi3.o -MT _muldi3.o -MD -MP -MF _muldi3.dep -DL_muldi3 -c /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c -fvisibility=hidden -DHIDE_EXPORTS /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c: In function ‘__muldi3’: /scratch2/tmp/gerald/gcc-HEAD/libgcc/libgcc2.c:557:1: internal compiler error: in gen_variable_die, at dwarf2out.c:19017 } ^ no stack trace because unwind library not available gmake[3]: *** [_muldi3.o] Error 1 gmake[3]: Leaving directory `/scratch2/tmp/gerald/OBJ-0904-1719/i386-unknown-freebsd10.0/libgcc' gmake[2]: *** [all-stage1-target-libgcc] Error 2 Any ideas which recent commit this might be due to? It was the debug-early stuff. Everything should be OK if you update and retest. Thanks, Richard
Re: RFA: Merge definitions of get_some_local_dynamic_name
On Tue, Sep 2, 2014 at 8:36 PM, Richard Sandiford rdsandif...@googlemail.com wrote: Several targets define a function like i386's get_some_local_dynamic_name. The function looks through the current output function and returns the first (arbitrary) local-dynamic symbol that it finds. The result can be used in a call to __tls_get_addr, since all local-dynamic symbols have the same base. This patch replaces the various target functions with a single generic one. The only difference between the implementations was that s390 checked for constant pool references while the others didn't need to (because they don't allow TLS symbols to be forced into the pool). Checking for constant pool references is unnecessary but harmless for the other ports. Also, the walk is needed only once per TLS-referencing output function, so it's hardly critical in terms of compile time. All uses of this function are in final. In general it wouldn't be safe to call the function earlier than that, since the symbol reference could in principle be deleted by any rtl pass. I've therefore cached it in a variable local to final rather than in cfun (which is where the ports used to cache it). Also, i386 was robust against uses of % in inline asm. The patch makes sure the other ports are too. Using % in inline asm would often be a mistake, but it should at least trigger a proper error rather than an ICE. Tested on x86_64-linux-gnu. Also tested by building cross compilers before and after the change on: alpha-linux-gnu powerpc64-linux-gnu s390x-linux-gnu sparc64-linux-gnu OK to install? Ok. Thanks, Richard. Thanks, Richard gcc/ * output.h (get_some_local_dynamic_name): Declare. * final.c (some_local_dynamic_name): New variable. (get_some_local_dynamic_name): New function. (final_end_function): Clear some_local_dynamic_name. * config/alpha/alpha.c (machine_function): Remove some_ld_name. (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete. (print_operand): Report an error if '%' is used inappropriately. * config/i386/i386.c (get_some_local_dynamic_name): Delete. (get_some_local_dynamic_name_1): Delete. * config/rs6000/rs6000.c (machine_function): Remove some_ld_name. (rs6000_get_some_local_dynamic_name): Delete. (rs6000_get_some_local_dynamic_name_1): Delete. (print_operand): Report an error if '%' is used inappropriately. * config/s390/s390.c (machine_function): Remove some_ld_name. (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete. (print_operand): Assert that get_some_local_dynamic_name is nonnull. * config/sparc/sparc.c: Include rtl-iter.h. (machine_function): Remove some_ld_name. (sparc_print_operand): Report an error if '%' is used inappropriately. (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete. Index: gcc/output.h === --- gcc/output.h2014-08-31 21:05:04.701330252 +0100 +++ gcc/output.h2014-09-02 19:02:59.820482510 +0100 @@ -52,6 +52,8 @@ extern int get_attr_min_length (rtx); any branches of variable length if possible. */ extern void shorten_branches (rtx_insn *); +const char *get_some_local_dynamic_name (); + /* Output assembler code for the start of a function, and initialize some of the variables in this file for the new function. The label for the function and associated Index: gcc/final.c === --- gcc/final.c 2014-08-31 21:05:04.701330252 +0100 +++ gcc/final.c 2014-09-02 19:17:08.573876805 +0100 @@ -1719,6 +1719,38 @@ reemit_insn_block_notes (void) reorder_blocks (); } +static const char *some_local_dynamic_name; + +/* Locate some local-dynamic symbol still in use by this function + so that we can print its name in local-dynamic base patterns. + Return null if there are no local-dynamic references. */ + +const char * +get_some_local_dynamic_name () +{ + subrtx_iterator::array_type array; + rtx_insn *insn; + + if (some_local_dynamic_name) +return some_local_dynamic_name; + + for (insn = get_insns (); insn ; insn = NEXT_INSN (insn)) +if (NONDEBUG_INSN_P (insn)) + FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL) + { + const_rtx x = *iter; + if (GET_CODE (x) == SYMBOL_REF) + { + if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC) + return some_local_dynamic_name = XSTR (x, 0); + if (CONSTANT_POOL_ADDRESS_P (x)) + iter.substitute (get_pool_constant (x)); + } + } + + return 0; +} + /* Output assembler code for the start of a function, and initialize some of the variables in this file for the new function.
Re: RFA: Merge definitions of get_some_local_dynamic_name
On 09/02/14 12:36, Richard Sandiford wrote: Several targets define a function like i386's get_some_local_dynamic_name. The function looks through the current output function and returns the first (arbitrary) local-dynamic symbol that it finds. The result can be used in a call to __tls_get_addr, since all local-dynamic symbols have the same base. This patch replaces the various target functions with a single generic one. The only difference between the implementations was that s390 checked for constant pool references while the others didn't need to (because they don't allow TLS symbols to be forced into the pool). Checking for constant pool references is unnecessary but harmless for the other ports. Also, the walk is needed only once per TLS-referencing output function, so it's hardly critical in terms of compile time. All uses of this function are in final. In general it wouldn't be safe to call the function earlier than that, since the symbol reference could in principle be deleted by any rtl pass. I've therefore cached it in a variable local to final rather than in cfun (which is where the ports used to cache it). Also, i386 was robust against uses of % in inline asm. The patch makes sure the other ports are too. Using % in inline asm would often be a mistake, but it should at least trigger a proper error rather than an ICE. Tested on x86_64-linux-gnu. Also tested by building cross compilers before and after the change on: alpha-linux-gnu powerpc64-linux-gnu s390x-linux-gnu sparc64-linux-gnu OK to install? Thanks, Richard gcc/ * output.h (get_some_local_dynamic_name): Declare. * final.c (some_local_dynamic_name): New variable. (get_some_local_dynamic_name): New function. (final_end_function): Clear some_local_dynamic_name. * config/alpha/alpha.c (machine_function): Remove some_ld_name. (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete. (print_operand): Report an error if '%' is used inappropriately. * config/i386/i386.c (get_some_local_dynamic_name): Delete. (get_some_local_dynamic_name_1): Delete. * config/rs6000/rs6000.c (machine_function): Remove some_ld_name. (rs6000_get_some_local_dynamic_name): Delete. (rs6000_get_some_local_dynamic_name_1): Delete. (print_operand): Report an error if '%' is used inappropriately. * config/s390/s390.c (machine_function): Remove some_ld_name. (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete. (print_operand): Assert that get_some_local_dynamic_name is nonnull. * config/sparc/sparc.c: Include rtl-iter.h. (machine_function): Remove some_ld_name. (sparc_print_operand): Report an error if '%' is used inappropriately. (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete. OK. Jeff
RFA: Merge definitions of get_some_local_dynamic_name
Several targets define a function like i386's get_some_local_dynamic_name. The function looks through the current output function and returns the first (arbitrary) local-dynamic symbol that it finds. The result can be used in a call to __tls_get_addr, since all local-dynamic symbols have the same base. This patch replaces the various target functions with a single generic one. The only difference between the implementations was that s390 checked for constant pool references while the others didn't need to (because they don't allow TLS symbols to be forced into the pool). Checking for constant pool references is unnecessary but harmless for the other ports. Also, the walk is needed only once per TLS-referencing output function, so it's hardly critical in terms of compile time. All uses of this function are in final. In general it wouldn't be safe to call the function earlier than that, since the symbol reference could in principle be deleted by any rtl pass. I've therefore cached it in a variable local to final rather than in cfun (which is where the ports used to cache it). Also, i386 was robust against uses of % in inline asm. The patch makes sure the other ports are too. Using % in inline asm would often be a mistake, but it should at least trigger a proper error rather than an ICE. Tested on x86_64-linux-gnu. Also tested by building cross compilers before and after the change on: alpha-linux-gnu powerpc64-linux-gnu s390x-linux-gnu sparc64-linux-gnu OK to install? Thanks, Richard gcc/ * output.h (get_some_local_dynamic_name): Declare. * final.c (some_local_dynamic_name): New variable. (get_some_local_dynamic_name): New function. (final_end_function): Clear some_local_dynamic_name. * config/alpha/alpha.c (machine_function): Remove some_ld_name. (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete. (print_operand): Report an error if '%' is used inappropriately. * config/i386/i386.c (get_some_local_dynamic_name): Delete. (get_some_local_dynamic_name_1): Delete. * config/rs6000/rs6000.c (machine_function): Remove some_ld_name. (rs6000_get_some_local_dynamic_name): Delete. (rs6000_get_some_local_dynamic_name_1): Delete. (print_operand): Report an error if '%' is used inappropriately. * config/s390/s390.c (machine_function): Remove some_ld_name. (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete. (print_operand): Assert that get_some_local_dynamic_name is nonnull. * config/sparc/sparc.c: Include rtl-iter.h. (machine_function): Remove some_ld_name. (sparc_print_operand): Report an error if '%' is used inappropriately. (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete. Index: gcc/output.h === --- gcc/output.h2014-08-31 21:05:04.701330252 +0100 +++ gcc/output.h2014-09-02 19:02:59.820482510 +0100 @@ -52,6 +52,8 @@ extern int get_attr_min_length (rtx); any branches of variable length if possible. */ extern void shorten_branches (rtx_insn *); +const char *get_some_local_dynamic_name (); + /* Output assembler code for the start of a function, and initialize some of the variables in this file for the new function. The label for the function and associated Index: gcc/final.c === --- gcc/final.c 2014-08-31 21:05:04.701330252 +0100 +++ gcc/final.c 2014-09-02 19:17:08.573876805 +0100 @@ -1719,6 +1719,38 @@ reemit_insn_block_notes (void) reorder_blocks (); } +static const char *some_local_dynamic_name; + +/* Locate some local-dynamic symbol still in use by this function + so that we can print its name in local-dynamic base patterns. + Return null if there are no local-dynamic references. */ + +const char * +get_some_local_dynamic_name () +{ + subrtx_iterator::array_type array; + rtx_insn *insn; + + if (some_local_dynamic_name) +return some_local_dynamic_name; + + for (insn = get_insns (); insn ; insn = NEXT_INSN (insn)) +if (NONDEBUG_INSN_P (insn)) + FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL) + { + const_rtx x = *iter; + if (GET_CODE (x) == SYMBOL_REF) + { + if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC) + return some_local_dynamic_name = XSTR (x, 0); + if (CONSTANT_POOL_ADDRESS_P (x)) + iter.substitute (get_pool_constant (x)); + } + } + + return 0; +} + /* Output assembler code for the start of a function, and initialize some of the variables in this file for the new function. The label for the function and associated @@ -1904,6 +1936,8 @@ final_end_function (void) if (!dwarf2_debug_info_emitted_p (current_function_decl) dwarf2out_do_frame ())