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: improving combine pass


Then the combiner is doing exactly what it is supposed to given the information it has.

"clobber x" means "there is no useful data in x".  So the combiner can't combine that with the compare, because the first insn doesn't produce a valid CC according to how it is defined.

I would write it as parallel [(set (reg ... (plus ..)) (set (reg:CCZ (compare (... (const_int 0)))))], approximately.  That expresses that the insn does a plus and sets CC accordingly, i.e., to a meaningful value rather than a useless value.  Then the combiner can (and should, according to what I was told) do the Right Thing.

	paul

On Apr 27, 2011, at 4:20 PM, cirrus75 wrote:

> 
> Hi Paul,
> 
> On i386 (and X86_64) RTL for insn X is generated with a "(clobber reg:CC FLAGS_REG)" instead of indicating exactly what is written on flags regs. I don't know if this could be different (as you suggested).
> 
> Maybe the idea is combine "operation insns" and "test insns" later, but combine is not able to do it on some cases.
> 
> here it is the insns generated by the i386 backend just before combine pass:
> 
> (insn 7 6 8 2 (parallel [
>            (set (reg:SI 61 [ a.2 ])
>                (plus:SI (reg:SI 64 [ a ])
>                    (reg:SI 63 [ b ])))
>            (clobber (reg:CC 17 flags))
>        ]) ../i386_tests/test_and.c:7 252 {*addsi_1}
>     (expr_list:REG_DEAD (reg:SI 64 [ a ])
>        (expr_list:REG_DEAD (reg:SI 63 [ b ])
>            (expr_list:REG_UNUSED (reg:CC 17 flags)
>                (expr_list:REG_EQUAL (plus:SI (mem/c/i:SI (symbol_ref:SI ("a")  <var_decl 0x2aba19b5f000 a>) [2 a+0 S4 A32])
>                        (mem/c/i:SI (symbol_ref:SI ("b")  <var_decl 0x2aba19b5f0a0 b>) [2 b+0 S4 A32]))
>                    (nil))))))
> 
> (insn 8 7 9 2 (set (mem/c/i:SI (symbol_ref:SI ("a")  <var_decl 0x2aba19b5f000 a>) [2 a+0 S4 A32])
>        (reg:SI 61 [ a.2 ])) ../i386_tests/test_and.c:7 64 {*movsi_internal}
>     (nil))
> 
> (insn 9 8 10 2 (set (reg:CCZ 17 flags)
>        (compare:CCZ (reg:SI 61 [ a.2 ])
>            (const_int 0 [0]))) ../i386_tests/test_and.c:9 2 {*cmpsi_ccno_1}
>     (expr_list:REG_DEAD (reg:SI 61 [ a.2 ])
>        (nil)))
> 
> 
> 
> 
> Em 27/04/2011 16:20, Paul Koning < paul_koning@dell.com > escreveu:
> 
> On Apr 27, 2011, at 3:15 PM, cirrus75 wrote:
> 
>> 
>> Hello Ian,
>> 
>> One example is:
>> 
>> insn X   : "REG_X     = "
>> insn X+1 : "MEM(addr) = REG_X"
>> insn X+2 : "REGY:CCmode compare(REG_X, const_int 0)"
>> 
>> generated by C code (already posted by me some weeks ago):
>> ------
>> 
>> int a, b, c, d;
>> 
>> int foo()
>> {
>> a += b;
>> 
>> if(a)
>>   c = d;
>> }
>> 
>> Insns X+2 and X can usually be combined because arithmetic operation
>> usually sets condition codes.
> 
> I haven't gotten into this much yet, so at the risk of showing off confusion...
> 
> I thought that the CCmode stuff allows this to work right without new changes, 
> given that the expressions that make up the RTL are written as (parallel ...)
> which set both the output reg and the CCmode reg (based on the expression
> value). So the rtl for the first insn would have that compare as part of its
> parallel...construct, the second insn (presumably in your example) doesn't
> affect the condition codes register, and the third insn should then be deleted
> since it's redundant.
> 
> Doesn't it work like that?  Am I confused about the right way?
> 
> paul
> 
> 
> 


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