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



--- Comment #4 from davidxl <xinliangli at gmail dot com> 2012-10-30 18:57:18 
UTC ---

The suggested transformation can be useful in some cases, but won't be general

enough. The listed example is an extreme case. For instance, the second a+b

instance does not have to be in the hot trace but still still hot enough to be

PREed. Or there is no one dominating traces available -- the expression is

available in all incoming paths except for one rare path.



switch (a)

{

   case 1:

     g[1] = a + b;

     break;

   case 2:

     g[2] = a + b;

     break;

   case 3: 

     g[3] = a + b;

   ...

   default:

     g[0] = 0;

 }



switch (b)

{

   case 1:

     ... a + b; // partially redundant

   case 2:

      ... a + b; // redundant



   default:

     // does nothing

     break;

}





Regarding handling dereferences, the availability and down-safety analysis

needs to be extended to to recognize safe speculation candidates.





Example 1:  dereference of same pointer fully available -- 



int g1, g2;

struct A

{

  int a;

  int b;

};



void foo(struct A* ap, int k,int m)

{



   if (__builtin_expect (k, 1))

      g1 = ap->b;

   else

      g2 = ap->a;





   if (__builtin_expect (m, 1))

   {

       g2 = ap->b;        // Good safe speculative PRE candidate

   }

}





Example 2:  deference of ap fully anticipated







int g1, g2;

struct A

{

  int a;

  int b;

};



void foo(struct A* ap, int k,int m)

{



   if (__builtin_expect (k, 1))

      g1 = ap->b;





   if (__builtin_expect (m, 1))

       g2 = ap->b;             // Safe to speculatively hoist across the branch

into the else of the previous branch

   else

       g1 = ap->a;

}





David





(In reply to comment #3)

> Wouldn't this be a candidate for forming a superblock from hot traces of

> a function?  Thus in the testcase

> 

>   if (k && m)

>     {

>       g1 = a + b;

>       g2 = a + b;

>     }

>   else

>     {

> ... old code

>     }

> 

> which would also handle the case where we cannot speculatively move code

> (like dereferences)?

Reply via email to