Message ID | 20111111152150.GB7764@virgil.arch.suse.de |
---|---|
State | New |
Headers | show |
On Fri, Nov 11, 2011 at 4:21 PM, Martin Jambor <mjambor@suse.cz> wrote: > Hi, > > the problem in PR 50605 is that is_gimple_ip_invariant returns false > for > > &MEM[(struct tRecorderImp *)&recorder + 8B] > > where &reorder is an IP gimple invariant. This patch fixes that by > copying the code that handles MEM_REFs from > is_gimple_invariant_address (and only changing > decl_address_invariant_p to decl_address_ip_invariant_p). > > Bootstrapped and tested on x86_64-linux. OK for trunk? Ok. Thanks, Richard. > Thanks, > > Martin > > > > 2011-11-11 Martin Jambor <mjambor@suse.cz> > > PR tree-optimization/50605 > * gimple.c (is_gimple_ip_invariant_address): Also handle MEM_REFs > of IPA invariant decls. > > * testsuite/g++.dg/ipa/pr50605.C: New test. > > > Index: src/gcc/testsuite/g++.dg/ipa/pr50605.C > =================================================================== > --- /dev/null > +++ src/gcc/testsuite/g++.dg/ipa/pr50605.C > @@ -0,0 +1,40 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O3 -fno-early-inlining" } */ > + > +class A > +{ > +public: > + int a; > + void *stuff; > +}; > + > +class B > +{ > +public: > + int b; > + void *other_stuff; > + A array[50]; > +}; > + > +extern B gb; > + > +int process_A (A *a) > +{ > + return a->a; > +} > + > +int process_A_complex (A *a) > +{ > + return process_A (a+3); > +} > + > +int process_B (B *b) > +{ > + return process_A_complex (&b->array[0]); > +} > + > +int foo (void) > +{ > + return process_B (&gb); > +} > + > Index: src/gcc/gimple.c > =================================================================== > --- src.orig/gcc/gimple.c > +++ src/gcc/gimple.c > @@ -2850,8 +2850,18 @@ is_gimple_ip_invariant_address (const_tr > return false; > > op = strip_invariant_refs (TREE_OPERAND (t, 0)); > + if (!op) > + return false; > + > + if (TREE_CODE (op) == MEM_REF) > + { > + const_tree op0 = TREE_OPERAND (op, 0); > + return (TREE_CODE (op0) == ADDR_EXPR > + && (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)) > + || decl_address_ip_invariant_p (TREE_OPERAND (op0, 0)))); > + } > > - return op && (CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op)); > + return CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op); > } > > /* Return true if T is a GIMPLE minimal invariant. It's a restricted > >
Index: src/gcc/testsuite/g++.dg/ipa/pr50605.C =================================================================== --- /dev/null +++ src/gcc/testsuite/g++.dg/ipa/pr50605.C @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-early-inlining" } */ + +class A +{ +public: + int a; + void *stuff; +}; + +class B +{ +public: + int b; + void *other_stuff; + A array[50]; +}; + +extern B gb; + +int process_A (A *a) +{ + return a->a; +} + +int process_A_complex (A *a) +{ + return process_A (a+3); +} + +int process_B (B *b) +{ + return process_A_complex (&b->array[0]); +} + +int foo (void) +{ + return process_B (&gb); +} + Index: src/gcc/gimple.c =================================================================== --- src.orig/gcc/gimple.c +++ src/gcc/gimple.c @@ -2850,8 +2850,18 @@ is_gimple_ip_invariant_address (const_tr return false; op = strip_invariant_refs (TREE_OPERAND (t, 0)); + if (!op) + return false; + + if (TREE_CODE (op) == MEM_REF) + { + const_tree op0 = TREE_OPERAND (op, 0); + return (TREE_CODE (op0) == ADDR_EXPR + && (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)) + || decl_address_ip_invariant_p (TREE_OPERAND (op0, 0)))); + } - return op && (CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op)); + return CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op); } /* Return true if T is a GIMPLE minimal invariant. It's a restricted