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) \
\