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: CSE not combining equivalent expressions.


On 1/15/07, pranav bhandarkar <pranav.bhandarkar@gmail.com> wrote:
Hello Everyone,
I have the following source code

static int i;
static char a;

char foo_gen(int);
void foo_assert(char);
void foo ()
{
   int *x = &i;
   a = foo_gen(0);
   a |= 1;     /*  ----1-----*/
   if (*x) goto end:
   a | =1; /* -----2------*/
   foo_assert(a);
end:
   return;
}

Now I expect the CSE pass to realise that 1 and 2 are equal and eliminate 2.
However the RTL code before the first CSE pass    the RTL snippet is as follows

(insn 11 9 12 0 (set (reg:SI 1 $c1)
       (const_int 0 [0x0])) 43 {*movsi} (nil)
   (nil))

(call_insn 12 11 13 0 (parallel [
           (set (reg:SI 1 $c1)
               (call (mem:SI (symbol_ref:SI ("gen_T") [flags 0x41]
<function_decl 0xb7d54e00 gen_T>) [0 S4 A32])
                   (const_int 0 [0x0])))
           (use (const_int 0 [0x0]))
           (clobber (reg:SI 31 $link))
       ]) 39 {*call_value_direct} (nil)
   (nil)
   (expr_list:REG_DEP_TRUE (use (reg:SI 1 $c1))
       (nil)))

(insn 13 12 14 0 (set (reg:SI 137)
       (reg:SI 1 $c1)) 43 {*movsi} (nil)
   (nil))

(insn 14 13 16 0 (set (reg:SI 135 [ D.1217 ])
       (reg:SI 137)) 43 {*movsi} (nil)
   (nil))

(insn 16 14 17 0 (set (reg:SI 138)
       (ior:SI (reg:SI 135 [ D.1217 ])
           (const_int 1 [0x1]))) 63 {iorsi3} (nil)
   (nil))

(insn 17 16 18 0 (set (reg:SI 134 [ D.1219 ])
       (zero_extend:SI (subreg:QI (reg:SI 138) 0))) 84 {zero_extendqisi2} (nil)
   (nil))

(insn 18 17 19 0 (set (reg/f:SI 139)
       (symbol_ref:SI ("a") [flags 0x2] <var_decl 0xb7d5d05c a>)) 43
{*movsi} (nil)
   (nil))

(insn 19 18 21 0 (set (mem/c/i:QI (reg/f:SI 139) [0 a+0 S1 A8])
       (subreg/s/u:QI (reg:SI 134 [ D.1219 ]) 0)) 56 {*movqi} (nil)
   (nil))

<<<<< expansion of the if condition >>>>>>>>

;; End of basic block 0, registers live:
(nil)

;; Start of basic block 1, registers live: (nil)
(note 25 23 27 1 [bb 1] NOTE_INSN_BASIC_BLOCK)

(insn 27 25 28 1 (set (reg:SI 142)
       (ior:SI (reg:SI 134 [ D.1219 ])
           (const_int 1 [0x1]))) 63 {iorsi3} (nil)
   (nil))

(insn 28 27 29 1 (set (reg:SI 133 [ temp.28 ])
       (zero_extend:SI (subreg:QI (reg:SI 142) 0))) 84 {zero_extendqisi2} (nil)
   (nil))

(insn 29 28 30 1 (set (reg/f:SI 143)
       (symbol_ref:SI ("a") [flags 0x2] <var_decl 0xb7d5d05c a>)) 43
{*movsi} (nil)
   (nil))

(insn 30 29 32 1 (set (mem/c/i:QI (reg/f:SI 143) [0 a+0 S1 A8])
       (subreg/s/u:QI (reg:SI 133 [ temp.28 ]) 0)) 56 {*movqi} (nil)
   (nil))



Now the problem is that the CSE  pass doesnt identify that the source
of the set in insn 27 is equivalent to the source of the set in insn
16. This It seems happens because of the zero_extend in insn 17. I am
using a 4.1 toolchain. However with a 3.4.6 toolchain no zero_extend
gets generated and the result of the ior operation is immediately
copied into memory. I am compiling this case with -O3. Can  anybody
please tell me how this problem can be overcome.

CSE/FRE or VRP do not track bit operations and CSE of bits. To overcome this you need to implement such.

Richard.


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