http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54200



--- Comment #13 from rguenther at suse dot de <rguenther at suse dot de> 
2013-04-02 07:56:26 UTC ---

On Fri, 29 Mar 2013, jakub at gcc dot gnu.org wrote:



> 

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54200

> 

> Jakub Jelinek <jakub at gcc dot gnu.org> changed:

> 

>            What    |Removed                     |Added

> ----------------------------------------------------------------------------

>                  CC|                            |jakub at gcc dot gnu.org

> 

> --- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> 2013-03-29 
> 15:36:15 UTC ---

> This patch regressed code quality on find_vma function in Linux kernel on

> s390x:

> struct rb_node

> {

>   unsigned long __rb_parent_color;

>   struct rb_node *rb_right;

>   struct rb_node *rb_left;

> } __attribute__ ((aligned (sizeof (long))));

> struct rb_root {

>   struct rb_node *rb_node;

> };

> struct vm_area_struct

> {

>   unsigned long vm_start;

>   unsigned long vm_end;

>   struct vm_area_struct *vm_next, *vm_prev;

>   struct rb_node vm_rb;

> };

> struct mm_struct

> {

>   struct vm_area_struct *mmap;

>   struct rb_root mm_rb;

>   struct vm_area_struct *mmap_cache;

> };

> struct vm_area_struct *

> find_vma (struct mm_struct *mm, unsigned long addr)

> {

>   struct vm_area_struct *vma = ((void *) 0);

>   static _Bool __attribute__ ((__section__ (".data.unlikely"))) __warned;

>   int __ret_warn_once = !!(!mm);

>   if (__builtin_expect (!!(__ret_warn_once), 0))

>     {

>       int __ret_warn_on = !!(!__warned);

>       if (__builtin_expect (!!(__ret_warn_on), 0))

>     asm volatile ("": :"i" (1920), "i" (((1 << 0) | ((9) << 8))), "i" (64));

>       if (__builtin_expect (!!(__ret_warn_on), 0))

>     __warned = 1;

>     }

>   if (__builtin_expect (!!(__ret_warn_once), 0))

>     return ((void *) 0);

>   vma = mm->mmap_cache;

>   if (!(vma && vma->vm_end > addr && vma->vm_start <= addr))

>     {

>       struct rb_node *rb_node;

>       rb_node = mm->mm_rb.rb_node;

>       vma = ((void *) 0);

>       while (rb_node)

>     {

>       struct vm_area_struct *vma_tmp;

>       const typeof (((struct vm_area_struct *)0)->vm_rb) *__mptr = rb_node;

>       vma_tmp = (struct vm_area_struct *) ((char *) __mptr - 
> __builtin_offsetof

> (struct vm_area_struct, vm_rb));

>       if (vma_tmp->vm_end > addr)

>         {

>           vma = vma_tmp;

>           if (vma_tmp->vm_start <= addr)

>         break;

>           rb_node = rb_node->rb_left;

>         }

>       else

>         rb_node = rb_node->rb_right;

>     }

>       if (vma)

>     mm->mmap_cache = vma;

>     }

>   return vma;

> }

> 

> with:

> -fno-strict-aliasing -fno-common -fno-delete-null-pointer-checks -O2 -m64

> -mbackchain -msoft-float -march=z9-109 -mpacked-stack -mstack-size=16384

> -fno-strength-reduce -fno-stack-protector -fomit-frame-pointer

> -fno-inline-functions-called-once -fconserve-stack

> 

> The difference in *.optimized is just:

> -  # vma_5 = PHI <0B(18), vma_2(15), vma_20(6), vma_2(16), 0B(7)>

> -  return vma_5;

> +  # _5 = PHI <0B(18), vma_2(15), vma_20(6), vma_2(16), 0B(7)>

> +  return _5;

> but later on CSE2 decides to use REG_EQUAL somewhere for some reason, and we

> end up reading mm->mmap_cache twice, first into a register to do the

> comparisons of it, and then when we know it is the value we actually want to

> return, we just forget we have it in a pseudo and read it again from memory.



Surely not a bug with the patch but a bug in CSE.  What the patch can

change is how pseudos are coalesced.  A "fix" may be in the coalescing

code, not restrict coalescing to SSA names with the same underlying

decl (with the cost issue of a bigger conflict map).

Reply via email to