[JSC] Add lowering for B3's Sub operation with integers
authorbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 31 Oct 2015 04:03:58 +0000 (04:03 +0000)
committerbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 31 Oct 2015 04:03:58 +0000 (04:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150749

Patch by Benjamin Poulain <bpoulain@apple.com> on 2015-10-30
Reviewed by Filip Pizlo.

* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::trySub):
(JSC::B3::Air::LowerToAir::tryStoreSubLoad):
* b3/B3LoweringMatcher.patterns:
Identical to Add but obviously NotCommutative.

* b3/B3ReduceStrength.cpp:
Turn Add/Sub with zero into an identity. I only added for
Add since Sub with a constant is always turned into an Add.

Also switched the Sub optimizations to put the strongest first.

* b3/air/AirOpcode.opcodes:
* b3/testb3.cpp:
(JSC::B3::testAddArgImm):
(JSC::B3::testAddImmArg):
(JSC::B3::testSubArgs):
(JSC::B3::testSubArgImm):
(JSC::B3::testSubImmArg):
(JSC::B3::testSubArgs32):
(JSC::B3::testSubArgImm32):
(JSC::B3::testSubImmArg32):
(JSC::B3::testStoreSubLoad):
(JSC::B3::run):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@191838 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/b3/B3LowerToAir.cpp
Source/JavaScriptCore/b3/B3LoweringMatcher.patterns
Source/JavaScriptCore/b3/B3ReduceStrength.cpp
Source/JavaScriptCore/b3/air/AirOpcode.opcodes
Source/JavaScriptCore/b3/testb3.cpp

index 8da20ea..995a24b 100644 (file)
@@ -1,5 +1,37 @@
 2015-10-30  Benjamin Poulain  <bpoulain@apple.com>
 
+        [JSC] Add lowering for B3's Sub operation with integers
+        https://bugs.webkit.org/show_bug.cgi?id=150749
+
+        Reviewed by Filip Pizlo.
+
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::trySub):
+        (JSC::B3::Air::LowerToAir::tryStoreSubLoad):
+        * b3/B3LoweringMatcher.patterns:
+        Identical to Add but obviously NotCommutative.
+
+        * b3/B3ReduceStrength.cpp:
+        Turn Add/Sub with zero into an identity. I only added for
+        Add since Sub with a constant is always turned into an Add.
+
+        Also switched the Sub optimizations to put the strongest first.
+
+        * b3/air/AirOpcode.opcodes:
+        * b3/testb3.cpp:
+        (JSC::B3::testAddArgImm):
+        (JSC::B3::testAddImmArg):
+        (JSC::B3::testSubArgs):
+        (JSC::B3::testSubArgImm):
+        (JSC::B3::testSubImmArg):
+        (JSC::B3::testSubArgs32):
+        (JSC::B3::testSubArgImm32):
+        (JSC::B3::testSubImmArg32):
+        (JSC::B3::testStoreSubLoad):
+        (JSC::B3::run):
+
+2015-10-30  Benjamin Poulain  <bpoulain@apple.com>
+
         [JSC] Add the Air Opcode definitions to the Xcode project file
         https://bugs.webkit.org/show_bug.cgi?id=150701
 
index 22d6c26..966f493 100644 (file)
@@ -547,6 +547,21 @@ public:
             return false;
         }
     }
+
+    bool trySub(Value* left, Value* right)
+    {
+        switch (left->type()) {
+        case Int32:
+            appendBinOp<Sub32>(left, right);
+            return true;
+        case Int64:
+            appendBinOp<Sub64>(left, right);
+            return true;
+        default:
+            // FIXME: Implement more types!
+            return false;
+        }
+    }
     
     bool tryAnd(Value* left, Value* right)
     {
@@ -573,7 +588,18 @@ public:
             return false;
         }
     }
-    
+
+    bool tryStoreSubLoad(Value* left, Value* right, Value*)
+    {
+        switch (left->type()) {
+        case Int32:
+            return tryAppendStoreBinOp<Sub32, NotCommutative>(left, right);
+        default:
+            // FIXME: Implement more types!
+            return false;
+        }
+    }
+
     bool tryStoreAndLoad(Value* left, Value* right, Value*)
     {
         switch (left->type()) {
index ec839ea..e55c5a1 100644 (file)
@@ -31,9 +31,11 @@ matcher LoweringMatcher
 Load = Load(address)
 
 Add = Add(left, right)
+Sub = Sub(left, right)
 And = BitAnd(left, right)
 
 StoreAddLoad = Store(Add(left, right), address)
+StoreSubLoad = Store(Add(left, right), address)
 StoreAndLoad = Store(BitAnd(left, right), address)
 Store = Store(value, address)
 
index e8ca65f..12fbaf6 100644 (file)
@@ -107,10 +107,28 @@ private:
 
             // Turn this: Add(constant1, constant2)
             // Into this: constant1 + constant2
-            replaceWithNewValue(m_value->child(0)->addConstant(m_proc, m_value->child(1)));
+            if (Value* constantAdd = m_value->child(0)->addConstant(m_proc, m_value->child(1))) {
+                replaceWithNewValue(constantAdd);
+                break;
+            }
+
+            // Turn this: Add(value, zero)
+            // Into an Identity.
+            if (m_value->child(1)->isInt(0)) {
+                m_value->replaceWithIdentity(m_value->child(0));
+                m_changed = true;
+                break;
+            }
             break;
 
         case Sub:
+            // Turn this: Sub(constant1, constant2)
+            // Into this: constant1 - constant2
+            if (Value* constantSub = m_value->child(0)->subConstant(m_proc, m_value->child(1))) {
+                replaceWithNewValue(constantSub);
+                break;
+            }
+
             // Turn this: Sub(value, constant)
             // Into this: Add(value, -constant)
             if (isInt(m_value->type())) {
@@ -122,9 +140,6 @@ private:
                 }
             }
 
-            // Turn this: Sub(constant1, constant2)
-            // Into this: constant1 - constant2
-            replaceWithNewValue(m_value->child(0)->subConstant(m_proc, m_value->child(1)));
             break;
 
         case Load8Z:
index 6edf30b..43fea5c 100644 (file)
@@ -78,6 +78,17 @@ Add64 U:G, UD:G
 Add64 U:G, U:G, D:G
     Imm, Tmp, Tmp
 
+Sub32 U:G, UD:G
+    Tmp, Tmp
+    Imm, Addr
+    Imm, Tmp
+    Addr, Tmp
+    Tmp, Addr
+
+Sub64 U:G, UD:G
+    Tmp, Tmp
+    Imm, Tmp
+
 Lea UA:G, D:G
     Addr, Tmp
 
index ecb7cd5..1672da5 100644 (file)
@@ -134,6 +134,34 @@ void testAddArgs(int a, int b)
     CHECK(compileAndRun<int>(proc, a, b) == a + b);
 }
 
+void testAddArgImm(int a, int b)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(),
+        root->appendNew<Value>(
+            proc, Add, Origin(),
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
+            root->appendNew<Const64Value>(proc, Origin(), b)));
+
+    CHECK(compileAndRun<int>(proc, a) == a + b);
+}
+
+void testAddImmArg(int a, int b)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(),
+        root->appendNew<Value>(
+            proc, Add, Origin(),
+            root->appendNew<Const64Value>(proc, Origin(), a),
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
+
+    CHECK(compileAndRun<int>(proc, b) == a + b);
+}
+
 void testAddArgs32(int a, int b)
 {
     Procedure proc;
@@ -152,6 +180,98 @@ void testAddArgs32(int a, int b)
     CHECK(compileAndRun<int>(proc, a, b) == a + b);
 }
 
+void testSubArgs(int a, int b)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(),
+        root->appendNew<Value>(
+            proc, Sub, Origin(),
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
+
+    CHECK(compileAndRun<int>(proc, a, b) == a - b);
+}
+
+void testSubArgImm(int64_t a, int64_t b)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(),
+        root->appendNew<Value>(
+            proc, Sub, Origin(),
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
+            root->appendNew<Const64Value>(proc, Origin(), b)));
+
+    CHECK(compileAndRun<int64_t>(proc, a) == a - b);
+}
+
+void testSubImmArg(int a, int b)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(),
+        root->appendNew<Value>(
+            proc, Sub, Origin(),
+            root->appendNew<Const64Value>(proc, Origin(), a),
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
+
+    CHECK(compileAndRun<int>(proc, b) == a - b);
+}
+
+void testSubArgs32(int a, int b)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    root->appendNew<ControlValue>(
+        proc, Return, 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<int>(proc, a, b) == a - b);
+}
+
+void testSubArgImm32(int a, int b)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(),
+        root->appendNew<Value>(
+            proc, Sub, Origin(),
+            root->appendNew<Value>(
+                proc, Trunc, Origin(),
+                root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
+            root->appendNew<Const32Value>(proc, Origin(), b)));
+
+    CHECK(compileAndRun<int>(proc, a) == a - b);
+}
+
+void testSubImmArg32(int a, int b)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(),
+        root->appendNew<Value>(
+            proc, Sub, Origin(),
+            root->appendNew<Const32Value>(proc, Origin(), a),
+            root->appendNew<Value>(
+                proc, Trunc, Origin(),
+                root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
+
+    CHECK(compileAndRun<int>(proc, b) == a - b);
+}
+
 void testStore(int value)
 {
     Procedure proc;
@@ -270,6 +390,30 @@ void testStoreAddLoad(int amount)
     CHECK(slot == 37 + amount);
 }
 
+void testStoreSubLoad(int amount)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    int32_t startValue = std::numeric_limits<int32_t>::min();
+    int32_t slot = startValue;
+    ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
+    root->appendNew<MemoryValue>(
+        proc, Store, Origin(),
+        root->appendNew<Value>(
+            proc, Sub, Origin(),
+            root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
+            root->appendNew<Value>(
+                proc, Trunc, Origin(),
+                root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
+        slotPtr);
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(),
+        root->appendNew<Const32Value>(proc, Origin(), 0));
+
+    CHECK(!compileAndRun<int>(proc, amount));
+    CHECK(slot == startValue - amount);
+}
+
 void testStoreAddLoadInterference(int amount)
 {
     Procedure proc;
@@ -944,10 +1088,45 @@ void run(const char* filter)
     RUN(test42());
     RUN(testLoad42());
     RUN(testArg(43));
+
     RUN(testAddArgs(1, 1));
     RUN(testAddArgs(1, 2));
+    RUN(testAddArgImm(1, 2));
+    RUN(testAddArgImm(0, 2));
+    RUN(testAddArgImm(1, 0));
+    RUN(testAddImmArg(1, 2));
+    RUN(testAddImmArg(0, 2));
+    RUN(testAddImmArg(1, 0));
     RUN(testAddArgs32(1, 1));
     RUN(testAddArgs32(1, 2));
+
+    RUN(testSubArgs(1, 1));
+    RUN(testSubArgs(1, 2));
+    RUN(testSubArgs(13, -42));
+    RUN(testSubArgs(-13, 42));
+    RUN(testSubArgImm(1, 1));
+    RUN(testSubArgImm(1, 2));
+    RUN(testSubArgImm(13, -42));
+    RUN(testSubArgImm(-13, 42));
+    RUN(testSubArgImm(42, 0));
+    RUN(testSubImmArg(1, 1));
+    RUN(testSubImmArg(1, 2));
+    RUN(testSubImmArg(13, -42));
+    RUN(testSubImmArg(-13, 42));
+
+    RUN(testSubArgs32(1, 1));
+    RUN(testSubArgs32(1, 2));
+    RUN(testSubArgs32(13, -42));
+    RUN(testSubArgs32(-13, 42));
+    RUN(testSubArgImm32(1, 1));
+    RUN(testSubArgImm32(1, 2));
+    RUN(testSubArgImm32(13, -42));
+    RUN(testSubArgImm32(-13, 42));
+    RUN(testSubImmArg32(1, 1));
+    RUN(testSubImmArg32(1, 2));
+    RUN(testSubImmArg32(13, -42));
+    RUN(testSubImmArg32(-13, 42));
+
     RUN(testStore(44));
     RUN(testStoreConstant(49));
     RUN(testStoreConstantPtr(49));
@@ -956,6 +1135,7 @@ void run(const char* filter)
     RUN(testAdd1Ptr(51));
     RUN(testAdd1Ptr(bitwise_cast<intptr_t>(vm)));
     RUN(testStoreAddLoad(46));
+    RUN(testStoreSubLoad(46));
     RUN(testStoreAddLoadInterference(52));
     RUN(testStoreAddAndLoad(47, 0xffff));
     RUN(testStoreAddAndLoad(470000, 0xffff));