Title: [278846] trunk/Source/_javascript_Core
Revision
278846
Author
[email protected]
Date
2021-06-14 12:44:02 -0700 (Mon, 14 Jun 2021)

Log Message

Add Air opcode sub32/64(Reg, Imm, Reg) form for ARM64 and select this instruction in Air
https://bugs.webkit.org/show_bug.cgi?id=226937

Patch by Yijia Huang <[email protected]> on 2021-06-14
Reviewed by Saam Barati.

Previously, Air arm64 sub32/64 utilize sub(Imm, Tmp) at optlevel = 0 and
add(Tmp, -Imm) at optlevel > 0 to perform and optimize sub(Tmp, Imm, Tmp).
The issue with this is that we were not eliding redundant operations.

For example:
// B3 IR
@0 = Trunc(ArgumentReg(0))
@1 = Const
@2 = Sub(@0, @1)
@3 = Return(@2)

// Old optimized Air IR
// OptLevel = 0
Move    %x0, %tmp1, @0
Move $Const, %tmp2, @1
Move  %tmp1, %tmp0, @2 // Redundant
Sub  $Const, %tmp0, @2
Move  %tmp0,   %x0, @3
Ret32   %x0,        @3

To remove those redundant instructions, Air arm64 sub32/64 opcode should
indicate a new form sub(Tmp, Imm, Tmp).

// New optimized Air IR
// OptLevel = 0
Move    %x0,  %tmp1,        @0
Move $Const,  %tmp2,        @1
Sub   %tmp1, $Const, %tmp0, @2
Move  %tmp0,    %x0,        @3
Ret32   %x0,                @3

* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::sub32):
(JSC::MacroAssemblerARM64::sub64):
* assembler/testmasm.cpp:
(JSC::testSub32Args):
(JSC::testSub32Imm):
(JSC::testSub32ArgImm):
(JSC::testSub64Imm32):
(JSC::testSub64ArgImm32):
(JSC::testSub64Imm64):
(JSC::testSub64ArgImm64):
* b3/B3ReduceStrength.cpp:
* b3/air/AirOpcode.opcodes:
* b3/testb3.h:
* b3/testb3_2.cpp:
(testSubArgs32ZeroExtend):
* b3/testb3_3.cpp:
(addArgTests):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (278845 => 278846)


--- trunk/Source/_javascript_Core/ChangeLog	2021-06-14 19:20:10 UTC (rev 278845)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-06-14 19:44:02 UTC (rev 278846)
@@ -1,3 +1,60 @@
+2021-06-14  Yijia Huang  <[email protected]>
+
+        Add Air opcode sub32/64(Reg, Imm, Reg) form for ARM64 and select this instruction in Air
+        https://bugs.webkit.org/show_bug.cgi?id=226937
+
+        Reviewed by Saam Barati.
+
+        Previously, Air arm64 sub32/64 utilize sub(Imm, Tmp) at optlevel = 0 and 
+        add(Tmp, -Imm) at optlevel > 0 to perform and optimize sub(Tmp, Imm, Tmp).
+        The issue with this is that we were not eliding redundant operations. 
+
+        For example:
+        // B3 IR
+        @0 = Trunc(ArgumentReg(0))
+        @1 = Const
+        @2 = Sub(@0, @1)
+        @3 = Return(@2)
+
+        // Old optimized Air IR
+        // OptLevel = 0
+        Move    %x0, %tmp1, @0
+        Move $Const, %tmp2, @1
+        Move  %tmp1, %tmp0, @2 // Redundant
+        Sub  $Const, %tmp0, @2
+        Move  %tmp0,   %x0, @3
+        Ret32   %x0,        @3
+
+        To remove those redundant instructions, Air arm64 sub32/64 opcode should 
+        indicate a new form sub(Tmp, Imm, Tmp).
+
+        // New optimized Air IR
+        // OptLevel = 0
+        Move    %x0,  %tmp1,        @0
+        Move $Const,  %tmp2,        @1
+        Sub   %tmp1, $Const, %tmp0, @2
+        Move  %tmp0,    %x0,        @3
+        Ret32   %x0,                @3
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::sub32):
+        (JSC::MacroAssemblerARM64::sub64):
+        * assembler/testmasm.cpp:
+        (JSC::testSub32Args):
+        (JSC::testSub32Imm):
+        (JSC::testSub32ArgImm):
+        (JSC::testSub64Imm32):
+        (JSC::testSub64ArgImm32):
+        (JSC::testSub64Imm64):
+        (JSC::testSub64ArgImm64):
+        * b3/B3ReduceStrength.cpp:
+        * b3/air/AirOpcode.opcodes:
+        * b3/testb3.h:
+        * b3/testb3_2.cpp:
+        (testSubArgs32ZeroExtend):
+        * b3/testb3_3.cpp:
+        (addArgTests):
+
 2021-06-14  Commit Queue  <[email protected]>
 
         Unreviewed, reverting r278734.

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h (278845 => 278846)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2021-06-14 19:20:10 UTC (rev 278845)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2021-06-14 19:44:02 UTC (rev 278846)
@@ -893,17 +893,24 @@
 
     void sub32(TrustedImm32 imm, RegisterID dest)
     {
-        if (isUInt12(imm.m_value)) {
-            m_assembler.sub<32>(dest, dest, UInt12(imm.m_value));
+        sub32(dest, imm, dest);
+    }
+
+    void sub32(RegisterID left, TrustedImm32 imm, RegisterID dest)
+    {
+        intptr_t immediate = imm.m_value;
+
+        if (isUInt12(immediate)) {
+            m_assembler.sub<32>(dest, left, UInt12(immediate));
             return;
         }
-        if (isUInt12(-imm.m_value)) {
-            m_assembler.add<32>(dest, dest, UInt12(-imm.m_value));
+        if (isUInt12(-immediate)) {
+            m_assembler.add<32>(dest, left, UInt12(-immediate));
             return;
         }
 
         move(imm, getCachedDataTempRegisterIDAndInvalidate());
-        m_assembler.sub<32>(dest, dest, dataTempRegister);
+        m_assembler.sub<32>(dest, left, dataTempRegister);
     }
 
     void sub32(TrustedImm32 imm, Address address)
@@ -954,41 +961,53 @@
         m_assembler.sub<64>(dest, dest, src);
     }
 
-    void sub64(RegisterID a, RegisterID b, RegisterID dest)
+    void sub64(RegisterID left, RegisterID right, RegisterID dest)
     {
-        m_assembler.sub<64>(dest, a, b);
+        m_assembler.sub<64>(dest, left, right);
     }
-    
+
     void sub64(TrustedImm32 imm, RegisterID dest)
     {
-        if (isUInt12(imm.m_value)) {
-            m_assembler.sub<64>(dest, dest, UInt12(imm.m_value));
+        sub64(dest, imm, dest);
+    }
+
+    void sub64(RegisterID left, TrustedImm32 imm, RegisterID dest)
+    {
+        intptr_t immediate = imm.m_value;
+
+        if (isUInt12(immediate)) {
+            m_assembler.sub<64>(dest, left, UInt12(immediate));
             return;
         }
-        if (isUInt12(-imm.m_value)) {
-            m_assembler.add<64>(dest, dest, UInt12(-imm.m_value));
+        if (isUInt12(-immediate)) {
+            m_assembler.add<64>(dest, left, UInt12(-immediate));
             return;
         }
 
         signExtend32ToPtr(imm, getCachedDataTempRegisterIDAndInvalidate());
-        m_assembler.sub<64>(dest, dest, dataTempRegister);
+        m_assembler.sub<64>(dest, left, dataTempRegister);
     }
-    
+
     void sub64(TrustedImm64 imm, RegisterID dest)
     {
+        sub64(dest, imm, dest);
+    }
+
+    void sub64(RegisterID left, TrustedImm64 imm, RegisterID dest)
+    {
         intptr_t immediate = imm.m_value;
 
         if (isUInt12(immediate)) {
-            m_assembler.sub<64>(dest, dest, UInt12(static_cast<int32_t>(immediate)));
+            m_assembler.sub<64>(dest, left, UInt12(static_cast<int32_t>(immediate)));
             return;
         }
         if (isUInt12(-immediate)) {
-            m_assembler.add<64>(dest, dest, UInt12(static_cast<int32_t>(-immediate)));
+            m_assembler.add<64>(dest, left, UInt12(static_cast<int32_t>(-immediate)));
             return;
         }
 
         move(imm, getCachedDataTempRegisterIDAndInvalidate());
-        m_assembler.sub<64>(dest, dest, dataTempRegister);
+        m_assembler.sub<64>(dest, left, dataTempRegister);
     }
 
     void urshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)

Modified: trunk/Source/_javascript_Core/assembler/testmasm.cpp (278845 => 278846)


--- trunk/Source/_javascript_Core/assembler/testmasm.cpp	2021-06-14 19:20:10 UTC (rev 278845)
+++ trunk/Source/_javascript_Core/assembler/testmasm.cpp	2021-06-14 19:44:02 UTC (rev 278846)
@@ -920,6 +920,128 @@
             CHECK_EQ(invoke<long int>(mul, value, value2), ((long int) value) * ((long int) value2));
     }
 }
+
+void testSub32Args()
+{
+    for (auto value : int32Operands()) {
+        auto sub = compile([=] (CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+
+            jit.sub32(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::returnValueGPR);
+
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+
+        for (auto value2 : int32Operands())
+            CHECK_EQ(invoke<uint32_t>(sub, value, value2), static_cast<uint32_t>(value - value2));
+    }
+}
+
+void testSub32Imm()
+{
+    for (auto immediate : int32Operands()) {
+        for (auto immediate2 : int32Operands()) {
+            auto sub = compile([=] (CCallHelpers& jit) {
+                emitFunctionPrologue(jit);
+
+                jit.move(CCallHelpers::TrustedImm32(immediate), GPRInfo::returnValueGPR);
+                jit.sub32(CCallHelpers::TrustedImm32(immediate2), GPRInfo::returnValueGPR);
+
+                emitFunctionEpilogue(jit);
+                jit.ret();
+            });
+            CHECK_EQ(invoke<uint32_t>(sub), static_cast<uint32_t>(immediate - immediate2));
+        }
+    }
+}
+
+void testSub32ArgImm()
+{
+    for (auto immediate : int32Operands()) {
+        auto sub = compile([=] (CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+
+            jit.sub32(GPRInfo::argumentGPR0, CCallHelpers::TrustedImm32(immediate), GPRInfo::returnValueGPR);
+
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+
+        for (auto value : int32Operands())
+            CHECK_EQ(invoke<uint32_t>(sub, value), static_cast<uint32_t>(value - immediate));
+    }
+}
+
+void testSub64Imm32()
+{
+    for (auto immediate : int64Operands()) {
+        for (auto immediate2 : int32Operands()) {
+            auto sub = compile([=] (CCallHelpers& jit) {
+                emitFunctionPrologue(jit);
+
+                jit.move(CCallHelpers::TrustedImm64(immediate), GPRInfo::returnValueGPR);
+                jit.sub64(CCallHelpers::TrustedImm32(immediate2), GPRInfo::returnValueGPR);
+
+                emitFunctionEpilogue(jit);
+                jit.ret();
+            });
+            CHECK_EQ(invoke<uint64_t>(sub), static_cast<uint64_t>(immediate - immediate2));
+        }
+    }
+}
+
+void testSub64ArgImm32()
+{
+    for (auto immediate : int32Operands()) {
+        auto sub = compile([=] (CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+
+            jit.sub64(GPRInfo::argumentGPR0, CCallHelpers::TrustedImm32(immediate), GPRInfo::returnValueGPR);
+
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+
+        for (auto value : int64Operands())
+            CHECK_EQ(invoke<int64_t>(sub, value), static_cast<int64_t>(value - immediate));
+    }
+}
+
+void testSub64Imm64()
+{
+    for (auto immediate : int64Operands()) {
+        for (auto immediate2 : int64Operands()) {
+            auto sub = compile([=] (CCallHelpers& jit) {
+                emitFunctionPrologue(jit);
+
+                jit.move(CCallHelpers::TrustedImm64(immediate), GPRInfo::returnValueGPR);
+                jit.sub64(CCallHelpers::TrustedImm64(immediate2), GPRInfo::returnValueGPR);
+
+                emitFunctionEpilogue(jit);
+                jit.ret();
+            });
+            CHECK_EQ(invoke<uint64_t>(sub), static_cast<uint64_t>(immediate - immediate2));
+        }
+    }
+}
+
+void testSub64ArgImm64()
+{
+    for (auto immediate : int64Operands()) {
+        auto sub = compile([=] (CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+
+            jit.sub64(GPRInfo::argumentGPR0, CCallHelpers::TrustedImm64(immediate), GPRInfo::returnValueGPR);
+
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+
+        for (auto value : int64Operands())
+            CHECK_EQ(invoke<int64_t>(sub, value), static_cast<int64_t>(value - immediate));
+    }
+}
 #endif
 
 #if CPU(X86) || CPU(X86_64) || CPU(ARM64)
@@ -2640,6 +2762,13 @@
 
 #if CPU(ARM64)
     RUN(testMul32SignExtend());
+    RUN(testSub32Args());
+    RUN(testSub32Imm());
+    RUN(testSub32ArgImm());
+    RUN(testSub64Imm32());
+    RUN(testSub64ArgImm32());
+    RUN(testSub64Imm64());
+    RUN(testSub64ArgImm64());
 #endif
 
 #if CPU(X86) || CPU(X86_64) || CPU(ARM64)

Modified: trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp (278845 => 278846)


--- trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp	2021-06-14 19:20:10 UTC (rev 278845)
+++ trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp	2021-06-14 19:44:02 UTC (rev 278846)
@@ -633,7 +633,7 @@
                         Add, m_value->origin(), m_value->child(0), negatedConstant);
                     break;
                 }
-                
+
                 // Turn this: Sub(0, value)
                 // Into this: Neg(value)
                 if (m_value->child(0)->isInt(0)) {

Modified: trunk/Source/_javascript_Core/b3/air/AirOpcode.opcodes (278845 => 278846)


--- trunk/Source/_javascript_Core/b3/air/AirOpcode.opcodes	2021-06-14 19:20:10 UTC (rev 278845)
+++ trunk/Source/_javascript_Core/b3/air/AirOpcode.opcodes	2021-06-14 19:44:02 UTC (rev 278846)
@@ -179,6 +179,7 @@
 
 arm64: Sub32 U:G:32, U:G:32, ZD:G:32
     Tmp, Tmp, Tmp
+    Tmp, Imm, Tmp
 
 64: Sub64 U:G:64, UD:G:64
     Tmp, Tmp
@@ -192,6 +193,7 @@
 
 arm64: Sub64 U:G:64, U:G:64, D:G:64
     Tmp, Tmp, Tmp
+    Tmp, Imm, Tmp
 
 SubDouble U:F:64, U:F:64, D:F:64
     arm64: Tmp, Tmp, Tmp

Modified: trunk/Source/_javascript_Core/b3/testb3.h (278845 => 278846)


--- trunk/Source/_javascript_Core/b3/testb3.h	2021-06-14 19:20:10 UTC (rev 278845)
+++ trunk/Source/_javascript_Core/b3/testb3.h	2021-06-14 19:44:02 UTC (rev 278846)
@@ -1027,6 +1027,7 @@
 void testSubImmMem(int64_t, int64_t);
 void testSubMemImm(int64_t, int64_t);
 void testSubArgs32(int, int);
+void testSubArgs32ZeroExtend(int, int);
 void testSubArgImm32(int, int);
 void testSubImmArg32(int, int);
 void testSubMemArg32(int32_t, int32_t);

Modified: trunk/Source/_javascript_Core/b3/testb3_2.cpp (278845 => 278846)


--- trunk/Source/_javascript_Core/b3/testb3_2.cpp	2021-06-14 19:20:10 UTC (rev 278845)
+++ trunk/Source/_javascript_Core/b3/testb3_2.cpp	2021-06-14 19:44:02 UTC (rev 278846)
@@ -2092,6 +2092,28 @@
     CHECK(compileAndRun<int>(proc, a, b) == a - b);
 }
 
+void testSubArgs32ZeroExtend(int a, int b)
+{
+    Procedure proc;
+    if (proc.optLevel() < 1)
+        return;
+    BasicBlock* root = proc.addBlock();
+    root->appendNewControlValue(
+        proc, Return, Origin(),
+        root->appendNew<Value>(
+            proc, ZExt32, Origin(),
+            root->appendNew<Value>(
+                proc, Sub, Origin(),
+                root->appendNew<Value>(
+                    proc, Trunc, Origin(),
+                    root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
+                root->appendNew<Value>(
+                    proc, Trunc, Origin(),
+                    root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)))));
+
+    CHECK(compileAndRun<uint64_t>(proc, a, b) == static_cast<uint64_t>(static_cast<uint32_t>(a - b)));
+}
+
 void testSubArgImm32(int a, int b)
 {
     Procedure proc;

Modified: trunk/Source/_javascript_Core/b3/testb3_3.cpp (278845 => 278846)


--- trunk/Source/_javascript_Core/b3/testb3_3.cpp	2021-06-14 19:20:10 UTC (rev 278845)
+++ trunk/Source/_javascript_Core/b3/testb3_3.cpp	2021-06-14 19:44:02 UTC (rev 278846)
@@ -3301,6 +3301,10 @@
     RUN(testSubArgs32(1, 2));
     RUN(testSubArgs32(13, -42));
     RUN(testSubArgs32(-13, 42));
+    RUN(testSubArgs32ZeroExtend(1, 1));
+    RUN(testSubArgs32ZeroExtend(1, 2));
+    RUN(testSubArgs32ZeroExtend(13, -42));
+    RUN(testSubArgs32ZeroExtend(-13, 42));
     RUN(testSubArgImm32(1, 1));
     RUN(testSubArgImm32(1, 2));
     RUN(testSubArgImm32(13, -42));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to