RFR: 8276673: Optimize abs operations in C2 compiler [v5]

Andrew Haley aph at openjdk.java.net
Thu Dec 16 10:05:02 UTC 2021


On Wed, 15 Dec 2021 15:07:39 GMT, Fei Gao <fgao at openjdk.org> wrote:

>> The patch aims to help optimize Math.abs() mainly from these three parts:
>> 1) Remove redundant instructions for abs with constant values
>> 2) Remove redundant instructions for abs with char type
>> 3) Convert some common abs operations to ideal forms
>> 
>> 1. Remove redundant instructions for abs with constant values
>> 
>> If we can decide the value of the input node for function Math.abs()
>> at compile-time, we can substitute the Abs node with the absolute
>> value of the constant and don't have to calculate it at runtime.
>> 
>> For example,
>>   int[] a
>>   for (int i = 0; i < SIZE; i++) {
>>     a[i] = Math.abs(-38);
>>   }
>> 
>> Before the patch, the generated code for the testcase above is:
>> ...
>>   mov   w10, #0xffffffda
>>   cmp   w10, wzr
>>   cneg  w17, w10, lt
>>   dup   v16.8h, w17
>> ...
>> After the patch, the generated code for the testcase above is :
>> ...
>>   movi  v16.4s, #0x26
>> ...
>> 
>> 2. Remove redundant instructions for abs with char type
>> 
>> In Java semantics, as the char type is always non-negative, we
>> could actually remove the absI node in the C2 middle end.
>> 
>> As for vectorization part, in current SLP, the vectorization of
>> Math.abs() with char type is intentionally disabled after
>> JDK-8261022 because it generates incorrect result before. After
>> removing the AbsI node in the middle end, Math.abs(char) can be
>> vectorized naturally.
>> 
>> For example,
>> 
>>   char[] a;
>>   char[] b;
>>   for (int i = 0; i < SIZE; i++) {
>>     b[i] = (char) Math.abs(a[i]);
>>   }
>> 
>> Before the patch, the generated assembly code for the testcase
>> above is:
>> 
>> B15:
>>   add   x13, x21, w20, sxtw #1
>>   ldrh  w11, [x13, #16]
>>   cmp   w11, wzr
>>   cneg  w10, w11, lt
>>   strh  w10, [x13, #16]
>>   ldrh  w10, [x13, #18]
>>   cmp   w10, wzr
>>   cneg  w10, w10, lt
>>   strh  w10, [x13, #18]
>>   ...
>>   add   w20, w20, #0x1
>>   cmp   w20, w17
>>   b.lt  B15
>> 
>> After the patch, the generated assembly code is:
>> B15:
>>   sbfiz x18, x19, #1, #32
>>   add   x0, x14, x18
>>   ldr   q16, [x0, #16]
>>   add   x18, x21, x18
>>   str   q16, [x18, #16]
>>   ldr   q16, [x0, #32]
>>   str   q16, [x18, #32]
>>   ...
>>   add   w19, w19, #0x40
>>   cmp   w19, w17
>>   b.lt  B15
>> 
>> 3. Convert some common abs operations to ideal forms
>> 
>> The patch overrides some virtual support functions for AbsNode
>> so that optimization of gvn can work on it. Here are the optimizable
>> forms:
>> 
>> a) abs(0 - x) => abs(x)
>> 
>> Before the patch:
>>   ...
>>   ldr   w13, [x13, #16]
>>   neg   w13, w13
>>   cmp   w13, wzr
>>   cneg  w14, w13, lt
>>   ...
>> After the patch:
>>   ...
>>   ldr   w13, [x13, #16]
>>   cmp   w13, wzr
>>   cneg  w13, w13, lt
>>   ...
>> 
>> b) abs(abs(x))  => abs(x)
>> 
>> Before the patch:
>>   ...
>>   ldr   w12, [x12, #16]
>>   cmp   w12, wzr
>>   cneg  w12, w12, lt
>>   cmp   w12, wzr
>>   cneg  w12, w12, lt
>>   ...
>> After the patch:
>>   ...
>>   ldr   w13, [x13, #16]
>>   cmp   w13, wzr
>>   cneg  w13, w13, lt
>>   ...
>
> Fei Gao has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains four commits:
> 
>  - Add a jmh benchmark case
>    
>    Change-Id: I64938d543126c2e3f9fad8ffc4a50e25e4473d8f
>  - Merge branch 'master' of github.com:fg1417/jdk into fg8276673
>    
>    Change-Id: I71987594e9288a489a04de696e69a62f4ad19357
>  - Merge branch 'master' into fg8276673
>    
>    Change-Id: I5e3898054b75f49653b8c3b37e4f5007675fa963
>  - 8276673: Optimize abs operations in C2 compiler
>    
>    The patch aims to help optimize Math.abs() mainly from these three parts:
>    1) Remove redundant instructions for abs with constant values
>    2) Remove redundant instructions for abs with char type
>    3) Convert some common abs operations to ideal forms
>    
>    1. Remove redundant instructions for abs with constant values
>    
>    If we can decide the value of the input node for function Math.abs()
>    at compile-time, we can substitute the Abs node with the absolute
>    value of the constant and don't have to calculate it at runtime.
>    
>    For example,
>      int[] a
>      for (int i = 0; i < SIZE; i++) {
>        a[i] = Math.abs(-38);
>      }
>    
>    Before the patch, the generated code for the testcase above is:
>    ...
>      mov   w10, #0xffffffda
>      cmp   w10, wzr
>      cneg  w17, w10, lt
>      dup   v16.8h, w17
>    ...
>    After the patch, the generated code for the testcase above is :
>    ...
>      movi  v16.4s, #0x26
>    ...
>    
>    2. Remove redundant instructions for abs with char type
>    
>    In Java semantics, as the char type is always non-negative, we
>    could actually remove the absI node in the C2 middle end.
>    
>    As for vectorization part, in current SLP, the vectorization of
>    Math.abs() with char type is intentionally disabled after
>    JDK-8261022 because it generates incorrect result before. After
>    removing the AbsI node in the middle end, Math.abs(char) can be
>    vectorized naturally.
>    
>    For example,
>    
>      char[] a;
>      char[] b;
>      for (int i = 0; i < SIZE; i++) {
>        b[i] = (char) Math.abs(a[i]);
>      }
>    
>    Before the patch, the generated assembly code for the testcase
>    above is:
>    
>    B15:
>      add   x13, x21, w20, sxtw #1
>      ldrh  w11, [x13, #16]
>      cmp   w11, wzr
>      cneg  w10, w11, lt
>      strh  w10, [x13, #16]
>      ldrh  w10, [x13, #18]
>      cmp   w10, wzr
>      cneg  w10, w10, lt
>      strh  w10, [x13, #18]
>      ...
>      add   w20, w20, #0x1
>      cmp   w20, w17
>      b.lt  B15
>    
>    After the patch, the generated assembly code is:
>    B15:
>      sbfiz x18, x19, #1, #32
>      add   x0, x14, x18
>      ldr   q16, [x0, #16]
>      add   x18, x21, x18
>      str   q16, [x18, #16]
>      ldr   q16, [x0, #32]
>      str   q16, [x18, #32]
>      ...
>      add   w19, w19, #0x40
>      cmp   w19, w17
>      b.lt  B15
>    
>    3. Convert some common abs operations to ideal forms
>    
>    The patch overrides some virtual support functions for AbsNode
>    so that optimization of gvn can work on it. Here are the optimizable
>    forms:
>    
>    a) abs(0 - x) => abs(x)
>    
>    Before the patch:
>      ...
>      ldr   w13, [x13, #16]
>      neg   w13, w13
>      cmp   w13, wzr
>      cneg  w14, w13, lt
>      ...
>    After the patch:
>      ...
>      ldr   w13, [x13, #16]
>      cmp   w13, wzr
>      cneg  w13, w13, lt
>      ...
>    
>    b) abs(abs(x))  => abs(x)
>    
>    Before the patch:
>      ...
>      ldr   w12, [x12, #16]
>      cmp   w12, wzr
>      cneg  w12, w12, lt
>      cmp   w12, wzr
>      cneg  w12, w12, lt
>      ...
>    After the patch:
>      ...
>      ldr   w13, [x13, #16]
>      cmp   w13, wzr
>      cneg  w13, w13, lt
>      ...
>    
>    Change-Id: I5434c01a225796caaf07ffbb19983f4fe2e206bd

src/hotspot/share/opto/subnode.cpp line 1854:

> 1852:       // Special case for min_jint: Math.abs(min_jint) = min_jint.
> 1853:       // Do not use C++ abs() for min_jint to avoid undefined behavior.
> 1854:       return (ti->is_con(min_jint)) ? TypeInt::MIN : TypeInt::make(abs(ti->get_con()));

Suggestion:

      return TypeInt::make(uabs(ti->get_con());

We have uabs() for julong and unsigned int.

-------------

PR: https://git.openjdk.java.net/jdk/pull/6755


More information about the hotspot-compiler-dev mailing list