Title: [230975] trunk/Source/_javascript_Core
Revision
230975
Author
[email protected]
Date
2018-04-24 15:29:39 -0700 (Tue, 24 Apr 2018)

Log Message

MultiByOffset should emit one fewer branches in the case that the set of structures is proved already
https://bugs.webkit.org/show_bug.cgi?id=184923

Reviewed by Saam Barati.
        
If we have a MultiGetByOffset or MultiPutByOffset over a structure set that we've already proved
(i.e. we know that the object has one of those structures), then previously we would still emit a
switch with a case per structure along with a default case. That would mean one extra redundant
branch to check that whatever structure we wound up with belongs to the set. In that case, we
were already making the default case be an Oops.
        
One possible solution would be to say that the default case being Oops means that B3 doesn't need
to emit the extra branch. But that would require having B3 exploit the fact that Oops is known to
be unreachable. Although B3 IR semantics (webkit.org/docs/b3/intermediate-representation.html)
seem to allow this, I don't particularly like that style of optimization. I like Oops to mean
trap.
        
So, this patch makes FTL lowering turn one of the cases into the default, explicitly removing the
extra branch.
        
This is not a speed-up. But it makes the B3 IR for MultiByOffset a lot simpler, which should make
it easier to implement B3-level optimizations for MultiByOffset. It also makes the IR easier to
read.

* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileMultiGetByOffset):
(JSC::FTL::DFG::LowerDFGToB3::compileMultiPutByOffset):
(JSC::FTL::DFG::LowerDFGToB3::emitSwitchForMultiByOffset):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (230974 => 230975)


--- trunk/Source/_javascript_Core/ChangeLog	2018-04-24 22:11:53 UTC (rev 230974)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-04-24 22:29:39 UTC (rev 230975)
@@ -1,5 +1,36 @@
 2018-04-24  Filip Pizlo  <[email protected]>
 
+        MultiByOffset should emit one fewer branches in the case that the set of structures is proved already
+        https://bugs.webkit.org/show_bug.cgi?id=184923
+
+        Reviewed by Saam Barati.
+        
+        If we have a MultiGetByOffset or MultiPutByOffset over a structure set that we've already proved
+        (i.e. we know that the object has one of those structures), then previously we would still emit a
+        switch with a case per structure along with a default case. That would mean one extra redundant
+        branch to check that whatever structure we wound up with belongs to the set. In that case, we
+        were already making the default case be an Oops.
+        
+        One possible solution would be to say that the default case being Oops means that B3 doesn't need
+        to emit the extra branch. But that would require having B3 exploit the fact that Oops is known to
+        be unreachable. Although B3 IR semantics (webkit.org/docs/b3/intermediate-representation.html)
+        seem to allow this, I don't particularly like that style of optimization. I like Oops to mean
+        trap.
+        
+        So, this patch makes FTL lowering turn one of the cases into the default, explicitly removing the
+        extra branch.
+        
+        This is not a speed-up. But it makes the B3 IR for MultiByOffset a lot simpler, which should make
+        it easier to implement B3-level optimizations for MultiByOffset. It also makes the IR easier to
+        read.
+
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileMultiGetByOffset):
+        (JSC::FTL::DFG::LowerDFGToB3::compileMultiPutByOffset):
+        (JSC::FTL::DFG::LowerDFGToB3::emitSwitchForMultiByOffset):
+
+2018-04-24  Filip Pizlo  <[email protected]>
+
         DFG CSE should know how to decay a MultiGetByOffset
         https://bugs.webkit.org/show_bug.cgi?id=159859
 

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (230974 => 230975)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2018-04-24 22:11:53 UTC (rev 230974)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2018-04-24 22:29:39 UTC (rev 230975)
@@ -6438,14 +6438,6 @@
         
         MultiGetByOffsetData& data = ""
 
-        if (data.cases.isEmpty()) {
-            // Protect against creating a Phi function with zero inputs. LLVM didn't like that.
-            // It's not clear if this is needed anymore.
-            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=154382
-            terminate(BadCache);
-            return;
-        }
-        
         Vector<LBasicBlock, 2> blocks(data.cases.size());
         for (unsigned i = data.cases.size(); i--;)
             blocks[i] = m_out.newBlock();
@@ -6462,8 +6454,8 @@
                 cases.append(SwitchCase(weakStructureID(structure), blocks[i], Weight(1)));
             }
         }
-        m_out.switchInstruction(
-            m_out.load32(base, m_heaps.JSCell_structureID), cases, exit, Weight(0));
+        bool structuresChecked = m_interpreter.forNode(m_node->child1()).m_structure.isSubsetOf(baseSet);
+        emitSwitchForMultiByOffset(base, structuresChecked, cases, exit);
         
         LBasicBlock lastNext = m_out.m_nextBlock;
         
@@ -6504,7 +6496,7 @@
         }
         
         m_out.appendTo(exit, continuation);
-        if (!m_interpreter.forNode(m_node->child1()).m_structure.isSubsetOf(baseSet))
+        if (!structuresChecked)
             speculate(BadCache, noValue(), nullptr, m_out.booleanTrue);
         m_out.unreachable();
         
@@ -6544,8 +6536,8 @@
                 cases.append(SwitchCase(weakStructureID(structure), blocks[i], Weight(1)));
             }
         }
-        m_out.switchInstruction(
-            m_out.load32(base, m_heaps.JSCell_structureID), cases, exit, Weight(0));
+        bool structuresChecked = m_interpreter.forNode(m_node->child1()).m_structure.isSubsetOf(baseSet);
+        emitSwitchForMultiByOffset(base, structuresChecked, cases, exit);
         
         LBasicBlock lastNext = m_out.m_nextBlock;
         
@@ -6587,7 +6579,7 @@
         }
         
         m_out.appendTo(exit, continuation);
-        if (!m_interpreter.forNode(m_node->child1()).m_structure.isSubsetOf(baseSet))
+        if (!structuresChecked)
             speculate(BadCache, noValue(), nullptr, m_out.booleanTrue);
         m_out.unreachable();
         
@@ -12030,6 +12022,29 @@
         setJSValue(patchpoint);
     }
     
+    void emitSwitchForMultiByOffset(LValue base, bool structuresChecked, Vector<SwitchCase, 2>& cases, LBasicBlock exit)
+    {
+        if (cases.isEmpty()) {
+            m_out.jump(exit);
+            return;
+        }
+        
+        if (structuresChecked) {
+            std::sort(
+                cases.begin(), cases.end(),
+                [&] (const SwitchCase& a, const SwitchCase& b) -> bool {
+                    return a.value()->asInt() < b.value()->asInt();
+                });
+            SwitchCase last = cases.takeLast();
+            m_out.switchInstruction(
+                m_out.load32(base, m_heaps.JSCell_structureID), cases, last.target(), Weight(0));
+            return;
+        }
+        
+        m_out.switchInstruction(
+            m_out.load32(base, m_heaps.JSCell_structureID), cases, exit, Weight(0));
+    }
+    
     void compareEqObjectOrOtherToObject(Edge leftChild, Edge rightChild)
     {
         LValue rightCell = lowCell(rightChild);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to