[llvm-dev] [RFC] Value Range Based Optimization Opportunity in LLVM

Hal Finkel via llvm-dev llvm-dev at lists.llvm.org
Thu Aug 31 18:22:36 PDT 2017


On 08/31/2017 03:54 PM, Tony Jiang via llvm-dev wrote:
> Hi All,
>
> We have recently found some optimization opportunities created by 
> replicating code into branches in order to enable optimization. In 
> general, the optimization opportunity we are pursuing is like the 
> following.
>
> Given pseudo-code:
>
> // block A
> if (some condition)
>   // block B
> // block C
>
> If it can be efficiently proven that some portion of block C can be 
> simplified had control flow not gone through the if statement, it 
> might be useful to convert this CFG into a diamond and hoist that 
> portion of block C into both block B and the new block.
>
>
> Consider the following example:
>
>
>
> int test(int *Ptr, int a, int b, int c, int d) {
>   int Ret = 0;
>   if (__builtin_expect(!Ptr, 0)) {
>     Ret = calli(a);
>     // return Ret / (a|1) / (b|1) / (c|1) / (d|1); // Copy return to here
>   }
>   return Ret / (a|1) / (b|1) / (c|1) / (d|1); // This can be 
> simplified to return 0
> }
>
> In this case, replicating the return statement in the branch allows 
> the optimizer to prove the value of Ret at the end of the function is 
> 0 and eliminate the arithmetic calculations.
>
> A second example:
>
> unsigned long funcReturningArbitraryi64(unsigned char *p);
> #define LENGTH(uv)  ( (uv) < 0x80             ? 1 :  \
>             (uv) < 0x800        ? 2 :  \
>             (uv) < 0x10000      ? 3 :  \
>             (uv) < 0x200000     ? 4 :  \
>             (uv) < 0x4000000    ? 5 :  \
>             (uv) < 0x80000000   ? 6 : 7 )
>
> int func(unsigned char *p, bool flag)
> {
>   unsigned long c = *p;
>   int len;
>   // ...
> #ifdef _ORIG
>   if(flag) {
>     // ...
>     c = funcReturningArbitraryi64(p);
>   }
> len = LENGTH(c);
> #else
>   if(flag) {
>     // ...
>     c = funcReturningArbitraryi64(p);
>     len = LENGTH(c);
>   } else {
>     len = LENGTH(c);
>   }
> #endif
>
>   // ...
>
>   return len;
> }
>
> In this case, we see that creating an else block and replicating the 
> return statement in both the if and else branch (like the code snippet 
> guarded by the #else) enables the macro UNISKIP in the else branch to 
> be optimized.
>
>
> Most of the examples we have come up with so far are centered around 
> value ranges along the conditional branches. When the range of values 
> a symbol can have along different branches is provably different, 
> opportunities for optimization may arise. However, this likely isn't 
> the only category of optimizations that could benefit from this.
>
> Is there an existing transformation in LLVM that should be doing this 
> already that is missing this opportunity? If not, we would like to 
> pursue adding this. Of course, this optimization would be subject to a 
> cost model as it may result in code growth. For example, it may not be 
> advantageous to do this if the simplified branch is cold. If anyone 
> has any comments/suggestions we are very much interested in hearing them.

We have two transformations that track ranges along CFG edges using 
LazyValueInfo: JumpThreading and CorrelatedValuePropagation. I don't 
think that either does what you're proposing.

  -Hal

>
>
>
> Regards,
>
>
> Tony Jiang, M.Sc.
> LLVM PPC Backend Development
> IBM Toronto Lab, C2/712/8200/MKM
> 8200 Warden Ave, Markham, L6G 1C7
> Email: _jtony at ca.ibm.com_ <mailto:nemanjai at ca.ibm.com>
> Phone: 905-413-3676
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170831/6d863cd4/attachment-0001.html>


More information about the llvm-dev mailing list