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 >>>> [0xffffffff80000000]) >>>> (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 + 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; }