Title: [215365] trunk/Source/_javascript_Core
Revision
215365
Author
fpi...@apple.com
Date
2017-04-14 10:43:42 -0700 (Fri, 14 Apr 2017)

Log Message

Air::RegLiveness should be constraint-based
https://bugs.webkit.org/show_bug.cgi?id=170817

Reviewed by Saam Barati.
        
Previously, I changed the Air liveness analyses based on Air::Liveness<> to be
constraint-based and this was a significant speed-up. Now I'm adding the same
functionality to RegLiveness.
        
This is a 1% speed-up on wasm B3 -O1 compile times.
        
* b3/air/AirAllocateRegistersAndStackByLinearScan.cpp:
* b3/air/AirLivenessAdapter.h:
(JSC::B3::Air::LivenessAdapter::LivenessAdapter):
(JSC::B3::Air::LivenessAdapter::prepareToCompute):
(JSC::B3::Air::LivenessAdapter::actionsAt):
* b3/air/AirRegLiveness.cpp:
(JSC::B3::Air::RegLiveness::RegLiveness):
(JSC::B3::Air::RegLiveness::LocalCalcForUnifiedTmpLiveness::LocalCalcForUnifiedTmpLiveness):
(JSC::B3::Air::RegLiveness::LocalCalcForUnifiedTmpLiveness::execute):
(JSC::B3::Air::RegLiveness::LocalCalc::execute): Deleted.
* b3/air/AirRegLiveness.h:
(JSC::B3::Air::RegLiveness::Actions::Actions):
(JSC::B3::Air::RegLiveness::LocalCalcBase::LocalCalcBase):
(JSC::B3::Air::RegLiveness::LocalCalcBase::live):
(JSC::B3::Air::RegLiveness::LocalCalcBase::isLive):
(JSC::B3::Air::RegLiveness::LocalCalc::LocalCalc):
(JSC::B3::Air::RegLiveness::LocalCalc::execute):
(JSC::B3::Air::RegLiveness::LocalCalc::live): Deleted.
(JSC::B3::Air::RegLiveness::LocalCalc::isLive): Deleted.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (215364 => 215365)


--- trunk/Source/_javascript_Core/ChangeLog	2017-04-14 17:31:50 UTC (rev 215364)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-04-14 17:43:42 UTC (rev 215365)
@@ -1,3 +1,36 @@
+2017-04-13  Filip Pizlo  <fpi...@apple.com>
+
+        Air::RegLiveness should be constraint-based
+        https://bugs.webkit.org/show_bug.cgi?id=170817
+
+        Reviewed by Saam Barati.
+        
+        Previously, I changed the Air liveness analyses based on Air::Liveness<> to be
+        constraint-based and this was a significant speed-up. Now I'm adding the same
+        functionality to RegLiveness.
+        
+        This is a 1% speed-up on wasm B3 -O1 compile times.
+        
+        * b3/air/AirAllocateRegistersAndStackByLinearScan.cpp:
+        * b3/air/AirLivenessAdapter.h:
+        (JSC::B3::Air::LivenessAdapter::LivenessAdapter):
+        (JSC::B3::Air::LivenessAdapter::prepareToCompute):
+        (JSC::B3::Air::LivenessAdapter::actionsAt):
+        * b3/air/AirRegLiveness.cpp:
+        (JSC::B3::Air::RegLiveness::RegLiveness):
+        (JSC::B3::Air::RegLiveness::LocalCalcForUnifiedTmpLiveness::LocalCalcForUnifiedTmpLiveness):
+        (JSC::B3::Air::RegLiveness::LocalCalcForUnifiedTmpLiveness::execute):
+        (JSC::B3::Air::RegLiveness::LocalCalc::execute): Deleted.
+        * b3/air/AirRegLiveness.h:
+        (JSC::B3::Air::RegLiveness::Actions::Actions):
+        (JSC::B3::Air::RegLiveness::LocalCalcBase::LocalCalcBase):
+        (JSC::B3::Air::RegLiveness::LocalCalcBase::live):
+        (JSC::B3::Air::RegLiveness::LocalCalcBase::isLive):
+        (JSC::B3::Air::RegLiveness::LocalCalc::LocalCalc):
+        (JSC::B3::Air::RegLiveness::LocalCalc::execute):
+        (JSC::B3::Air::RegLiveness::LocalCalc::live): Deleted.
+        (JSC::B3::Air::RegLiveness::LocalCalc::isLive): Deleted.
+
 2017-04-13  JF Bastien  <jfbast...@apple.com>
 
         WebAssembly: fix windows build

Modified: trunk/Source/_javascript_Core/b3/air/AirAllocateRegistersAndStackByLinearScan.cpp (215364 => 215365)


--- trunk/Source/_javascript_Core/b3/air/AirAllocateRegistersAndStackByLinearScan.cpp	2017-04-14 17:31:50 UTC (rev 215364)
+++ trunk/Source/_javascript_Core/b3/air/AirAllocateRegistersAndStackByLinearScan.cpp	2017-04-14 17:43:42 UTC (rev 215365)
@@ -221,6 +221,10 @@
             for (unsigned instIndex = 0; instIndex < block->size(); ++instIndex) {
                 Inst& inst = block->at(instIndex);
                 size_t indexOfEarly = indexOfHead + instIndex * 2;
+                // FIXME: We can get this information from the liveness constraints. Except of
+                // course we want to separate the earlies of one instruction from the lates of
+                // the next.
+                // https://bugs.webkit.org/show_bug.cgi?id=170850
                 inst.forEachTmp(
                     [&] (Tmp& tmp, Arg::Role role, Bank, Width) {
                         if (tmp.isReg())
@@ -229,10 +233,15 @@
                     });
             }
 
-            RegLiveness::LocalCalc localCalc(liveness, block);
+            RegLiveness::LocalCalcForUnifiedTmpLiveness localCalc(liveness, block);
             
             auto record = [&] (unsigned instIndex) {
-                RegisterSet regs = localCalc.live();
+                // FIXME: This could get the register sets from somewhere else, like the
+                // liveness constraints. Except we want those constraints to be laid out like
+                // how they would have been by RegLiveness, since we want to separate the lates
+                // of one inst from the earlies of the next.
+                // https://bugs.webkit.org/show_bug.cgi?id=170850
+                const RegisterSet& regs = localCalc.live();
                 if (Inst* prev = block->get(instIndex - 1)) {
                     RegisterSet prevRegs = regs;
                     prev->forEach<Reg>(

Modified: trunk/Source/_javascript_Core/b3/air/AirLivenessAdapter.h (215364 => 215365)


--- trunk/Source/_javascript_Core/b3/air/AirLivenessAdapter.h	2017-04-14 17:31:50 UTC (rev 215364)
+++ trunk/Source/_javascript_Core/b3/air/AirLivenessAdapter.h	2017-04-14 17:43:42 UTC (rev 215365)
@@ -33,6 +33,7 @@
 #include "AirInstInlines.h"
 #include "AirStackSlot.h"
 #include "AirTmpInlines.h"
+#include <wtf/IndexMap.h>
 
 namespace JSC { namespace B3 { namespace Air {
 
@@ -53,7 +54,7 @@
     
     LivenessAdapter(Code& code)
         : code(code)
-        , m_actions(code.size())
+        , actions(code.size())
     {
     }
     
@@ -65,7 +66,7 @@
     void prepareToCompute()
     {
         for (BasicBlock* block : code) {
-            ActionsForBoundary& actionsForBoundary = m_actions[block];
+            ActionsForBoundary& actionsForBoundary = actions[block];
             actionsForBoundary.resize(block->size() + 1);
             
             for (size_t instIndex = block->size(); instIndex--;) {
@@ -92,7 +93,7 @@
     
     Actions& actionsAt(BasicBlock* block, unsigned instBoundaryIndex)
     {
-        return m_actions[block][instBoundaryIndex];
+        return actions[block][instBoundaryIndex];
     }
     
     unsigned blockSize(BasicBlock* block)
@@ -115,7 +116,7 @@
     }
 
     Code& code;
-    IndexMap<BasicBlock*, ActionsForBoundary> m_actions;
+    IndexMap<BasicBlock*, ActionsForBoundary> actions;
 };
 
 template<Bank adapterBank, Arg::Temperature minimumTemperature = Arg::Cold>

Modified: trunk/Source/_javascript_Core/b3/air/AirRegLiveness.cpp (215364 => 215365)


--- trunk/Source/_javascript_Core/b3/air/AirRegLiveness.cpp	2017-04-14 17:31:50 UTC (rev 215364)
+++ trunk/Source/_javascript_Core/b3/air/AirRegLiveness.cpp	2017-04-14 17:43:42 UTC (rev 215365)
@@ -36,7 +36,29 @@
 RegLiveness::RegLiveness(Code& code)
     : m_liveAtHead(code.size())
     , m_liveAtTail(code.size())
+    , m_actions(code.size())
 {
+    // Compute constraints.
+    for (BasicBlock* block : code) {
+        ActionsForBoundary& actionsForBoundary = m_actions[block];
+        actionsForBoundary.resize(block->size() + 1);
+        
+        for (size_t instIndex = block->size(); instIndex--;) {
+            Inst& inst = block->at(instIndex);
+            inst.forEach<Reg>(
+                [&] (Reg& reg, Arg::Role role, Bank, Width) {
+                    if (Arg::isEarlyUse(role))
+                        actionsForBoundary[instIndex].use.add(reg);
+                    if (Arg::isEarlyDef(role))
+                        actionsForBoundary[instIndex].def.add(reg);
+                    if (Arg::isLateUse(role))
+                        actionsForBoundary[instIndex + 1].use.add(reg);
+                    if (Arg::isLateDef(role))
+                        actionsForBoundary[instIndex + 1].def.add(reg);
+                });
+        }
+    }
+    
     // The liveAtTail of each block automatically contains the LateUse's of the terminal.
     for (BasicBlock* block : code) {
         RegisterSet& liveAtTail = m_liveAtTail[block];
@@ -98,43 +120,29 @@
 {
 }
 
-void RegLiveness::LocalCalc::execute(unsigned instIndex)
+RegLiveness::LocalCalcForUnifiedTmpLiveness::LocalCalcForUnifiedTmpLiveness(UnifiedTmpLiveness& liveness, BasicBlock* block)
+    : LocalCalcBase(block)
+    , m_code(liveness.code)
+    , m_actions(liveness.actions[block])
 {
-    Inst& inst = m_block->at(instIndex);
-            
-    // First handle the early def's of the next instruction.
-    if (instIndex + 1 < m_block->size()) {
-        Inst& nextInst = m_block->at(instIndex + 1);
-        nextInst.forEach<Reg>(
-            [&] (Reg& reg, Arg::Role role, Bank, Width) {
-                if (Arg::isEarlyDef(role))
-                    m_workset.remove(reg);
-            });
+    for (Tmp tmp : liveness.liveAtTail(block)) {
+        if (tmp.isReg())
+            m_workset.add(tmp.reg());
     }
-            
-    // Then handle def's.
-    inst.forEach<Reg>(
-        [&] (Reg& reg, Arg::Role role, Bank, Width) {
-            if (Arg::isLateDef(role))
-                m_workset.remove(reg);
-        });
-            
-    // Then handle use's.
-    inst.forEach<Reg>(
-        [&] (Reg& reg, Arg::Role role, Bank, Width) {
-            if (Arg::isEarlyUse(role))
-                m_workset.add(reg);
-        });
-            
-    // And finally, handle the late use's of the previous instruction.
-    if (instIndex) {
-        Inst& prevInst = m_block->at(instIndex - 1);
-        prevInst.forEach<Reg>(
-            [&] (Reg& reg, Arg::Role role, Bank, Width) {
-                if (Arg::isLateUse(role))
-                    m_workset.add(reg);
-            });
+}
+
+void RegLiveness::LocalCalcForUnifiedTmpLiveness::execute(unsigned instIndex)
+{
+    for (unsigned index : m_actions[instIndex + 1].def) {
+        Tmp tmp = Tmp::tmpForLinearIndex(m_code, index);
+        if (tmp.isReg())
+            m_workset.remove(tmp.reg());
     }
+    for (unsigned index : m_actions[instIndex].use) {
+        Tmp tmp = Tmp::tmpForLinearIndex(m_code, index);
+        if (tmp.isReg())
+            m_workset.add(tmp.reg());
+    }
 }
 
 } } } // namespace JSC::B3::Air

Modified: trunk/Source/_javascript_Core/b3/air/AirRegLiveness.h (215364 => 215365)


--- trunk/Source/_javascript_Core/b3/air/AirRegLiveness.h	2017-04-14 17:31:50 UTC (rev 215364)
+++ trunk/Source/_javascript_Core/b3/air/AirRegLiveness.h	2017-04-14 17:43:42 UTC (rev 215365)
@@ -32,6 +32,7 @@
 #include "AirInst.h"
 #include "AirLiveness.h"
 #include "RegisterSet.h"
+#include <wtf/IndexMap.h>
 
 namespace JSC { namespace B3 { namespace Air {
 
@@ -40,6 +41,15 @@
 // register liveness. This is a specialization of Liveness<> that uses bitvectors directly.
 // This makes the code sufficiently different that it didn't make sense to try to share code.
 class RegLiveness {
+    struct Actions {
+        Actions() { }
+        
+        RegisterSet use;
+        RegisterSet def;
+    };
+    
+    typedef Vector<Actions, 0, UnsafeVectorOverflow> ActionsForBoundary;
+    
 public:
     typedef Reg Thing;
     
@@ -46,56 +56,61 @@
     RegLiveness(Code& code);
     ~RegLiveness();
     
-    // This calculator has to be run in reverse.
-    class LocalCalc {
+    class LocalCalcBase {
     public:
-        LocalCalc(RegLiveness& liveness, BasicBlock* block)
+        LocalCalcBase(BasicBlock* block)
             : m_block(block)
-            , m_workset(liveness.m_liveAtTail[block])
         {
         }
         
-        // If you computed Tmp liveness for some bank, you can use reg liveness to fill in the blanks.
-        // Note that what happens to the registers not belonging to the bank is arbitrary - they may get
-        // set or not.
-        template<Bank bank>
-        LocalCalc(TmpLiveness<bank>& liveness, BasicBlock* block)
-            : m_block(block)
+        const RegisterSet& live() const
         {
-            for (Tmp tmp : liveness.liveAtTail(block)) {
-                if (tmp.isReg())
-                    m_workset.set(tmp.reg());
-            }
+            return m_workset;
         }
         
-        LocalCalc(UnifiedTmpLiveness& liveness, BasicBlock* block)
-            : m_block(block)
+        bool isLive(Reg reg) const
         {
-            for (Tmp tmp : liveness.liveAtTail(block)) {
-                if (tmp.isReg())
-                    m_workset.set(tmp.reg());
-            }
+            return m_workset.contains(reg);
         }
         
-        const RegisterSet& live() const
+    protected:
+        BasicBlock* m_block;
+        RegisterSet m_workset;
+    };
+    
+    // This calculator has to be run in reverse.
+    class LocalCalc : public LocalCalcBase {
+    public:
+        LocalCalc(RegLiveness& liveness, BasicBlock* block)
+            : LocalCalcBase(block)
+            , m_actions(liveness.m_actions[block])
         {
-            return m_workset;
+            m_workset = liveness.m_liveAtTail[block];
         }
         
-        bool isLive(Reg reg) const
+        void execute(unsigned instIndex)
         {
-            return m_workset.contains(reg);
+            m_workset.exclude(m_actions[instIndex + 1].def);
+            m_workset.merge(m_actions[instIndex].use);
         }
         
-        void execute(unsigned instIndex);
-        
     private:
         friend class RegLiveness;
         
-        BasicBlock* m_block;
-        RegisterSet m_workset;
+        ActionsForBoundary& m_actions;
     };
     
+    class LocalCalcForUnifiedTmpLiveness : public LocalCalcBase {
+    public:
+        LocalCalcForUnifiedTmpLiveness(UnifiedTmpLiveness& liveness, BasicBlock* block);
+        
+        void execute(unsigned instIndex);
+        
+    private:
+        Code& m_code;
+        UnifiedTmpLiveness::ActionsForBoundary& m_actions;
+    };
+    
     const RegisterSet& liveAtHead(BasicBlock* block) const
     {
         return m_liveAtHead[block];
@@ -109,6 +124,7 @@
 private:
     IndexMap<BasicBlock*, RegisterSet> m_liveAtHead;
     IndexMap<BasicBlock*, RegisterSet> m_liveAtTail;
+    IndexMap<BasicBlock*, ActionsForBoundary> m_actions;
 };
 
 } } } // namespace JSC::B3::Air
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to