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.

Reply via email to