[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gcc
Subject:    Re: improving combine pass
From:       Paul Koning <paul_koning () dell ! com>
Date:       2011-04-27 20:27:57
Message-ID: 8DE245F8-793C-47FF-98C1-C8D9D02B6DDB () dell ! com
[Download RAW message or body]

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
> 
> 
> 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic