Title: [243744] trunk/Source/_javascript_Core
Revision
243744
Author
sbar...@apple.com
Date
2019-04-02 08:58:34 -0700 (Tue, 02 Apr 2019)

Log Message

Add a ValueRepReduction phase
https://bugs.webkit.org/show_bug.cgi?id=196234

Reviewed by Filip Pizlo.

This patch adds a ValueRepReduction phase. The main idea here is
to try to reduce DoubleRep(RealNumberUse:ValueRep(DoubleRepUse:@x))
to just be @x. This patch handles such above strengh reduction rules
as long as we prove that all users of the ValueRep can be converted
to using the incoming double value. That way we prevent introducing
a parallel live range for the double value.

This patch tracks the uses of the ValueRep through Phi variables,
so we can convert entire Phi variables to being Double instead
of JSValue if the Phi also has only double uses.

This is implemented through a simple escape analysis. DoubleRep(RealNumberUse:)
and OSR exit hints are not counted as escapes. All other uses are counted
as escapes. Connected Phi graphs are converted to being Double only if the
entire graph is ok with the result being Double.

Some ways we could extend this phase in the future:
- There are a lot of DoubleRep(NumberUse:@ValueRep(@x)) uses. This ensures
  that the result of the DoubleRep of @x is not impure NaN. We could
  handle this case if we introduced a PurifyNaN node and replace the DoubleRep
  with PurifyNaN(@x). Alternatively, we could see if certain users of this
  DoubleRep are okay with impure NaN flowing into them and we'd need to ensure
  their output type is always treated as if the input is impure NaN.
- We could do sinking of ValueRep where we think it's profitable. So instead
  of an escape making it so we never represent the variable as a Double, we
  could make the escape reconstruct the JSValueRep where profitable.
- We can extend this phase to handle Int52Rep if it's profitable.
- We can opt other nodes into accepting incoming Doubles so we no longer
  treat them as escapes.

This patch is somewhere between neutral and a 1% progression on JetStream 2.

* _javascript_Core.xcodeproj/project.pbxproj:
* Sources.txt:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGValueRepReductionPhase.cpp: Added.
(JSC::DFG::ValueRepReductionPhase::ValueRepReductionPhase):
(JSC::DFG::ValueRepReductionPhase::run):
(JSC::DFG::ValueRepReductionPhase::convertValueRepsToDouble):
(JSC::DFG::performValueRepReduction):
* dfg/DFGValueRepReductionPhase.h: Added.
* runtime/Options.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (243743 => 243744)


--- trunk/Source/_javascript_Core/ChangeLog	2019-04-02 15:57:38 UTC (rev 243743)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-04-02 15:58:34 UTC (rev 243744)
@@ -1,3 +1,54 @@
+2019-04-02  Saam barati  <sbar...@apple.com>
+
+        Add a ValueRepReduction phase
+        https://bugs.webkit.org/show_bug.cgi?id=196234
+
+        Reviewed by Filip Pizlo.
+
+        This patch adds a ValueRepReduction phase. The main idea here is
+        to try to reduce DoubleRep(RealNumberUse:ValueRep(DoubleRepUse:@x))
+        to just be @x. This patch handles such above strengh reduction rules
+        as long as we prove that all users of the ValueRep can be converted
+        to using the incoming double value. That way we prevent introducing
+        a parallel live range for the double value.
+        
+        This patch tracks the uses of the ValueRep through Phi variables,
+        so we can convert entire Phi variables to being Double instead
+        of JSValue if the Phi also has only double uses.
+        
+        This is implemented through a simple escape analysis. DoubleRep(RealNumberUse:)
+        and OSR exit hints are not counted as escapes. All other uses are counted
+        as escapes. Connected Phi graphs are converted to being Double only if the
+        entire graph is ok with the result being Double.
+        
+        Some ways we could extend this phase in the future:
+        - There are a lot of DoubleRep(NumberUse:@ValueRep(@x)) uses. This ensures
+          that the result of the DoubleRep of @x is not impure NaN. We could
+          handle this case if we introduced a PurifyNaN node and replace the DoubleRep
+          with PurifyNaN(@x). Alternatively, we could see if certain users of this
+          DoubleRep are okay with impure NaN flowing into them and we'd need to ensure
+          their output type is always treated as if the input is impure NaN.
+        - We could do sinking of ValueRep where we think it's profitable. So instead
+          of an escape making it so we never represent the variable as a Double, we
+          could make the escape reconstruct the JSValueRep where profitable.
+        - We can extend this phase to handle Int52Rep if it's profitable.
+        - We can opt other nodes into accepting incoming Doubles so we no longer
+          treat them as escapes.
+        
+        This patch is somewhere between neutral and a 1% progression on JetStream 2.
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGValueRepReductionPhase.cpp: Added.
+        (JSC::DFG::ValueRepReductionPhase::ValueRepReductionPhase):
+        (JSC::DFG::ValueRepReductionPhase::run):
+        (JSC::DFG::ValueRepReductionPhase::convertValueRepsToDouble):
+        (JSC::DFG::performValueRepReduction):
+        * dfg/DFGValueRepReductionPhase.h: Added.
+        * runtime/Options.h:
+
 2019-04-01  Yusuke Suzuki  <ysuz...@apple.com>
 
         [JSC] JSRunLoopTimer::Manager should be small

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (243743 => 243744)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2019-04-02 15:57:38 UTC (rev 243743)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2019-04-02 15:58:34 UTC (rev 243744)
@@ -883,6 +883,7 @@
 		52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		52B311011975B4670080857C /* TypeLocationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B311001975B4670080857C /* TypeLocationCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		52C55566224C2AEA0099F5CC /* DFGValueRepReductionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C55565224C2AE70099F5CC /* DFGValueRepReductionPhase.h */; };
 		52C952B719A289850069B386 /* TypeProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C952B619A289850069B386 /* TypeProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		52CD0F5D2242F569004A18A5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
 		52CD0F5E2242F569004A18A5 /* _javascript_Core.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* _javascript_Core.framework */; };
@@ -3389,6 +3390,8 @@
 		52B311001975B4670080857C /* TypeLocationCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeLocationCache.h; sourceTree = "<group>"; };
 		52B717B41A0597E1007AF4F3 /* ControlFlowProfiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ControlFlowProfiler.cpp; sourceTree = "<group>"; };
 		52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeType.h; sourceTree = "<group>"; };
+		52C55564224C2AE70099F5CC /* DFGValueRepReductionPhase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DFGValueRepReductionPhase.cpp; path = dfg/DFGValueRepReductionPhase.cpp; sourceTree = "<group>"; };
+		52C55565224C2AE70099F5CC /* DFGValueRepReductionPhase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DFGValueRepReductionPhase.h; path = dfg/DFGValueRepReductionPhase.h; sourceTree = "<group>"; };
 		52C952B619A289850069B386 /* TypeProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeProfiler.h; sourceTree = "<group>"; };
 		52C952B819A28A1C0069B386 /* TypeProfiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfiler.cpp; sourceTree = "<group>"; };
 		52CD0F642242F569004A18A5 /* testdfg */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testdfg; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -7651,6 +7654,8 @@
 				0F34B14816D4200E001CDA5A /* DFGUseKind.h */,
 				0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */,
 				0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */,
+				52C55564224C2AE70099F5CC /* DFGValueRepReductionPhase.cpp */,
+				52C55565224C2AE70099F5CC /* DFGValueRepReductionPhase.h */,
 				0F2BDC4E15228BE700CD8910 /* DFGValueSource.cpp */,
 				0F2BDC401522801700CD8910 /* DFGValueSource.h */,
 				0F0123301944EA1B00843A0C /* DFGValueStrength.cpp */,
@@ -9379,6 +9384,7 @@
 				D9722752DC54459B9125B539 /* JSModuleLoader.h in Headers */,
 				996B73201BDA08EF00331B84 /* JSModuleLoader.lut.h in Headers */,
 				E318CBC11B8AEF5100A2929D /* JSModuleNamespaceObject.h in Headers */,
+				52C55566224C2AEA0099F5CC /* DFGValueRepReductionPhase.h in Headers */,
 				E39DA4A71B7E8B7C0084F33A /* JSModuleRecord.h in Headers */,
 				E33E8D1D1B9013C300346B52 /* JSNativeStdFunction.h in Headers */,
 				E38D999C221B78BB00D50474 /* JSNonDestructibleProxy.h in Headers */,

Modified: trunk/Source/_javascript_Core/Sources.txt (243743 => 243744)


--- trunk/Source/_javascript_Core/Sources.txt	2019-04-02 15:57:38 UTC (rev 243743)
+++ trunk/Source/_javascript_Core/Sources.txt	2019-04-02 15:58:34 UTC (rev 243744)
@@ -416,6 +416,7 @@
 dfg/DFGUnificationPhase.cpp
 dfg/DFGUseKind.cpp
 dfg/DFGValidate.cpp
+dfg/DFGValueRepReductionPhase.cpp
 dfg/DFGValueSource.cpp
 dfg/DFGValueStrength.cpp
 dfg/DFGVarargsForwardingPhase.cpp

Modified: trunk/Source/_javascript_Core/dfg/DFGPlan.cpp (243743 => 243744)


--- trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2019-04-02 15:57:38 UTC (rev 243743)
+++ trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2019-04-02 15:58:34 UTC (rev 243744)
@@ -71,6 +71,7 @@
 #include "DFGTypeCheckHoistingPhase.h"
 #include "DFGUnificationPhase.h"
 #include "DFGValidate.h"
+#include "DFGValueRepReductionPhase.h"
 #include "DFGVarargsForwardingPhase.h"
 #include "DFGVirtualRegisterAllocationPhase.h"
 #include "DFGWatchpointCollectionPhase.h"
@@ -424,6 +425,8 @@
             RUN_PHASE(performCriticalEdgeBreaking);
             RUN_PHASE(performObjectAllocationSinking);
         }
+        if (Options::useValueRepElimination())
+            RUN_PHASE(performValueRepReduction);
         if (changed) {
             // State-at-tail and state-at-head will be invalid if we did strength reduction since
             // it might increase live ranges.

Added: trunk/Source/_javascript_Core/dfg/DFGValueRepReductionPhase.cpp (0 => 243744)


--- trunk/Source/_javascript_Core/dfg/DFGValueRepReductionPhase.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGValueRepReductionPhase.cpp	2019-04-02 15:58:34 UTC (rev 243744)
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGValueRepReductionPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGPhase.h"
+#include "DFGPhiChildren.h"
+
+namespace JSC { namespace DFG {
+
+class ValueRepReductionPhase : public Phase {
+    static constexpr bool verbose = false;
+    
+public:
+    ValueRepReductionPhase(Graph& graph)
+        : Phase(graph, "ValueRep reduction")
+        , m_insertionSet(graph)
+    {
+    }
+    
+    bool run()
+    {
+        ASSERT(m_graph.m_form == SSA);
+        return convertValueRepsToDouble();
+    }
+
+private:
+    bool convertValueRepsToDouble()
+    {
+        HashSet<Node*> candidates;
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block) {
+                if (node->op() == ValueRep && node->child1().useKind() == DoubleRepUse)
+                    candidates.add(node);
+            }
+        }
+
+        if (!candidates.size())
+            return false;
+
+        HashMap<Node*, Vector<Node*>> usersOf;
+        auto getUsersOf = [&] (Node* candidate) {
+            auto iter = usersOf.find(candidate);
+            RELEASE_ASSERT(iter != usersOf.end());
+            return iter->value;
+        };
+
+        for (BasicBlock* block : m_graph.blocksInPreOrder()) {
+            for (Node* node : *block) {
+                if (node->op() == Phi || (node->op() == ValueRep && candidates.contains(node)))
+                    usersOf.add(node, Vector<Node*>());
+
+                Vector<Node*, 3> alreadyAdded;
+                m_graph.doToChildren(node, [&] (Edge edge) {
+                    Node* candidate = edge.node();
+                    if (alreadyAdded.contains(candidate))
+                        return;
+                    auto iter = usersOf.find(candidate);
+                    if (iter == usersOf.end())
+                        return;
+                    iter->value.append(node);
+                    alreadyAdded.append(candidate);
+                });
+            }
+        }
+
+        PhiChildren phiChildren(m_graph);
+
+        // - Any candidate that forwards into a Phi turns that Phi into a candidate.
+        // - Any Phi-1 that forwards into another Phi-2, where Phi-2 is a candidate,
+        //   makes Phi-1 a candidate too.
+        do {
+            HashSet<Node*> eligiblePhis;
+            for (Node* candidate : candidates) {
+                if (candidate->op() == Phi) {
+                    phiChildren.forAllIncomingValues(candidate, [&] (Node* incoming) {
+                        if (incoming->op() == Phi)
+                            eligiblePhis.add(incoming);
+                    });
+                }
+
+                for (Node* user : getUsersOf(candidate)) {
+                    if (user->op() == Upsilon)
+                        eligiblePhis.add(user->phi());
+                }
+            }
+
+            bool sawNewCandidate = false;
+            for (Node* phi : eligiblePhis)
+                sawNewCandidate |= candidates.add(phi).isNewEntry;
+
+            if (!sawNewCandidate)
+                break;
+        } while (true);
+
+        do {
+            HashSet<Node*> toRemove;
+
+            auto isEscaped = [&] (Node* node) {
+                return !candidates.contains(node) || toRemove.contains(node);
+            };
+
+            // Escape rules are as follows:
+            // - Any non-well-known use is an escape. Currently, we allow DoubleRep, Hints, Upsilons (described below).
+            // - Any Upsilon that forwards the candidate into an escaped phi escapes the candidate.
+            // - A Phi remains a candidate as long as all values flowing into it can be made a double.
+            //   Currently, this means these are valid things we support to forward into the Phi:
+            //    - A JSConstant(some number "x") => DoubleConstant("x")
+            //    - ValueRep(DoubleRepUse:@x) => @x
+            //    - A Phi so long as that Phi is not escaped.
+            for (Node* candidate : candidates) {
+                bool ok = true;
+
+                auto dumpEscape = [&] (const char* description, Node* node) {
+                    if (!verbose)
+                        return;
+                    dataLogLn(description);
+                    dataLog("   candidate: ");
+                    m_graph.dump(WTF::dataFile(), "", candidate);
+                    dataLog("   reason: ");
+                    m_graph.dump(WTF::dataFile(), "", node);
+                    dataLogLn();
+                };
+
+                if (candidate->op() == Phi) {
+                    phiChildren.forAllIncomingValues(candidate, [&] (Node* node) {
+                        if (node->op() == JSConstant) {
+                            if (!node->asJSValue().isNumber()) {
+                                ok = false;
+                                dumpEscape("Phi Incoming JSConstant not a number: ", node);
+                            }
+                        } else if (node->op() == ValueRep) {
+                            if (node->child1().useKind() != DoubleRepUse) {
+                                ok = false;
+                                dumpEscape("Phi Incoming ValueRep not DoubleRepUse: ", node);
+                            }
+                        } else if (node->op() == Phi) {
+                            if (isEscaped(node)) {
+                                ok = false;
+                                dumpEscape("An incoming Phi to another Phi is escaped: ", node);
+                            }
+                        } else {
+                            ok = false;
+                            dumpEscape("Unsupported incoming value to Phi: ", node);
+                        }
+                    });
+
+                    if (!ok) {
+                        toRemove.add(candidate);
+                        continue;
+                    }
+                }
+
+                for (Node* user : getUsersOf(candidate)) {
+                    switch (user->op()) {
+                    case DoubleRep:
+                        if (user->child1().useKind() != RealNumberUse) {
+                            ok = false;
+                            dumpEscape("DoubleRep escape: ", user);
+                        }
+                        break;
+
+                    case PutHint:
+                    case MovHint:
+                        break;
+
+                    case Upsilon: {
+                        Node* phi = user->phi();
+                        if (isEscaped(phi)) {
+                            dumpEscape("Upsilon of escaped phi escapes candidate: ", phi);
+                            ok = false;
+                        }
+                        break;
+                    }
+
+                    default:
+                        dumpEscape("Normal escape: ", user);
+                        ok = false;
+                        break;
+                    }
+
+                    if (!ok)
+                        break;
+                }
+
+                if (!ok)
+                    toRemove.add(candidate);
+            }
+
+            if (toRemove.isEmpty())
+                break;
+
+            for (Node* node : toRemove)
+                candidates.remove(node);
+        } while (true);
+
+        if (!candidates.size())
+            return false;
+
+        NodeOrigin originForConstant = m_graph.block(0)->at(0)->origin;
+        HashSet<Node*> doubleRepRealCheckLocations;
+
+        for (Node* candidate : candidates) {
+            if (verbose)
+                dataLogLn("Optimized: ", candidate);
+
+            Node* resultNode;
+            if (candidate->op() == Phi) {
+                resultNode = candidate;
+
+                for (Node* upsilon : phiChildren.upsilonsOf(candidate)) {
+                    Node* incomingValue = upsilon->child1().node();
+                    Node* newChild;
+                    if (incomingValue->op() == JSConstant) {
+                        double number = incomingValue->asJSValue().asNumber();
+                        newChild = m_insertionSet.insertConstant(0, originForConstant, jsDoubleNumber(number), DoubleConstant);
+                    } else if (incomingValue->op() == ValueRep) {
+                        // We don't care about the incoming value being an impure NaN because users of
+                        // this Phi are either OSR exit or DoubleRep(RealNumberUse:@phi)
+                        ASSERT(incomingValue->child1().useKind() == DoubleRepUse);
+                        newChild = incomingValue->child1().node();
+                    } else if (incomingValue->op() == Phi)
+                        newChild = incomingValue;
+                    else
+                        RELEASE_ASSERT_NOT_REACHED();
+
+                    upsilon->child1() = Edge(newChild, DoubleRepUse);
+                }
+
+                candidate->setResult(NodeResultDouble);
+            } else if (candidate->op() == ValueRep)
+                resultNode = candidate->child1().node();
+            else
+                RELEASE_ASSERT_NOT_REACHED();
+
+            for (Node* user : getUsersOf(candidate)) {
+                switch (user->op()) {
+                case DoubleRep: {
+                    ASSERT(user->child1().useKind() == RealNumberUse);
+                    user->convertToIdentityOn(resultNode);
+                    doubleRepRealCheckLocations.add(user);
+                    break;
+                }
+                    
+                case PutHint:
+                    user->child2() = Edge(resultNode, DoubleRepUse);
+                    break;
+
+                case MovHint:
+                    user->child1() = Edge(resultNode, DoubleRepUse);
+                    break;
+
+                case Upsilon: {
+                    Node* phi = user->phi();
+                    ASSERT_UNUSED(phi, candidates.contains(phi));
+                    break;
+                }
+
+                default:
+                    RELEASE_ASSERT_NOT_REACHED();
+                    break;
+                }
+            }
+        }
+
+        // Insert constants.
+        m_insertionSet.execute(m_graph.block(0));
+
+        // Insert checks that are needed when removing DoubleRep(RealNumber:@x)
+        if (doubleRepRealCheckLocations.size()) {
+            for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+                for (unsigned i = 0; i < block->size(); ++i) {
+                    Node* node = block->at(i);
+                    if (node->op() != Identity) {
+                        ASSERT(!doubleRepRealCheckLocations.contains(node));
+                        continue;
+                    }
+                    if (!doubleRepRealCheckLocations.contains(node))
+                        continue;
+                    m_insertionSet.insertNode(
+                        i, SpecNone, Check, node->origin,
+                        Edge(node->child1().node(), DoubleRepRealUse));
+                }
+
+                m_insertionSet.execute(block);
+            }
+        }
+
+        return true;
+    }
+
+    InsertionSet m_insertionSet;
+};
+    
+bool performValueRepReduction(Graph& graph)
+{
+    return runPhase<ValueRepReductionPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+

Added: trunk/Source/_javascript_Core/dfg/DFGValueRepReductionPhase.h (0 => 243744)


--- trunk/Source/_javascript_Core/dfg/DFGValueRepReductionPhase.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGValueRepReductionPhase.h	2019-04-02 15:58:34 UTC (rev 243744)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#pragma once
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Tries to eliminate DoubleRep(ValueRep) roundtrips.
+
+bool performValueRepReduction(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)

Modified: trunk/Source/_javascript_Core/runtime/Options.h (243743 => 243744)


--- trunk/Source/_javascript_Core/runtime/Options.h	2019-04-02 15:57:38 UTC (rev 243743)
+++ trunk/Source/_javascript_Core/runtime/Options.h	2019-04-02 15:58:34 UTC (rev 243744)
@@ -283,6 +283,7 @@
     v(bool, useMovHintRemoval, true, Normal, nullptr) \
     v(bool, usePutStackSinking, true, Normal, nullptr) \
     v(bool, useObjectAllocationSinking, true, Normal, nullptr) \
+    v(bool, useValueRepElimination, true, Normal, nullptr) \
     v(bool, useArityFixupInlining, true, Normal, nullptr) \
     v(bool, logExecutableAllocation, false, Normal, nullptr) \
     \
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to