Title: [195307] trunk/Source/_javascript_Core
Revision
195307
Author
fpi...@apple.com
Date
2016-01-19 12:55:34 -0800 (Tue, 19 Jan 2016)

Log Message

Reconsider B3's constant motion policy
https://bugs.webkit.org/show_bug.cgi?id=152202

Reviewed by Geoffrey Garen.

This changes moveConstants() to hoist constants. This is a speed-up on things like mandreel.
It has a generally positive impact on the Octane score, but it's within margin of error.

This also changes IRC to make it a bit more likely to spill constants. We don't want it to
spill them too much, because we can't rely on fixObviousSpills() to always replace a load of
a constant from the stack with the constant itself, especially in case of instructions that
need an extra register to materialize the immediate.

Also fixed DFG graph dumping to print a bit less things. It was trying to print the results of
constant property inference, and this sometimes caused crashes when you dumped the graph at an
inopportune time.

* _javascript_Core.xcodeproj/project.pbxproj:
* b3/B3MoveConstants.cpp:
* b3/air/AirArg.h:
* b3/air/AirArgInlines.h: Added.
(JSC::B3::Air::ArgThingHelper<Tmp>::is):
(JSC::B3::Air::ArgThingHelper<Tmp>::as):
(JSC::B3::Air::ArgThingHelper<Tmp>::forEachFast):
(JSC::B3::Air::ArgThingHelper<Tmp>::forEach):
(JSC::B3::Air::ArgThingHelper<Arg>::is):
(JSC::B3::Air::ArgThingHelper<Arg>::as):
(JSC::B3::Air::ArgThingHelper<Arg>::forEachFast):
(JSC::B3::Air::ArgThingHelper<Arg>::forEach):
(JSC::B3::Air::Arg::is):
(JSC::B3::Air::Arg::as):
(JSC::B3::Air::Arg::forEachFast):
(JSC::B3::Air::Arg::forEach):
* b3/air/AirIteratedRegisterCoalescing.cpp:
* b3/air/AirUseCounts.h:
(JSC::B3::Air::UseCounts::UseCounts):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (195306 => 195307)


--- trunk/Source/_javascript_Core/ChangeLog	2016-01-19 20:32:01 UTC (rev 195306)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-01-19 20:55:34 UTC (rev 195307)
@@ -1,3 +1,44 @@
+2016-01-19  Filip Pizlo  <fpi...@apple.com>
+
+        Reconsider B3's constant motion policy
+        https://bugs.webkit.org/show_bug.cgi?id=152202
+
+        Reviewed by Geoffrey Garen.
+
+        This changes moveConstants() to hoist constants. This is a speed-up on things like mandreel.
+        It has a generally positive impact on the Octane score, but it's within margin of error.
+
+        This also changes IRC to make it a bit more likely to spill constants. We don't want it to
+        spill them too much, because we can't rely on fixObviousSpills() to always replace a load of
+        a constant from the stack with the constant itself, especially in case of instructions that
+        need an extra register to materialize the immediate.
+
+        Also fixed DFG graph dumping to print a bit less things. It was trying to print the results of
+        constant property inference, and this sometimes caused crashes when you dumped the graph at an
+        inopportune time.
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * b3/B3MoveConstants.cpp:
+        * b3/air/AirArg.h:
+        * b3/air/AirArgInlines.h: Added.
+        (JSC::B3::Air::ArgThingHelper<Tmp>::is):
+        (JSC::B3::Air::ArgThingHelper<Tmp>::as):
+        (JSC::B3::Air::ArgThingHelper<Tmp>::forEachFast):
+        (JSC::B3::Air::ArgThingHelper<Tmp>::forEach):
+        (JSC::B3::Air::ArgThingHelper<Arg>::is):
+        (JSC::B3::Air::ArgThingHelper<Arg>::as):
+        (JSC::B3::Air::ArgThingHelper<Arg>::forEachFast):
+        (JSC::B3::Air::ArgThingHelper<Arg>::forEach):
+        (JSC::B3::Air::Arg::is):
+        (JSC::B3::Air::Arg::as):
+        (JSC::B3::Air::Arg::forEachFast):
+        (JSC::B3::Air::Arg::forEach):
+        * b3/air/AirIteratedRegisterCoalescing.cpp:
+        * b3/air/AirUseCounts.h:
+        (JSC::B3::Air::UseCounts::UseCounts):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+
 2016-01-19  Enrica Casucci  <enr...@apple.com>
 
         Add support for DataDetectors in WK (iOS).

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (195306 => 195307)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2016-01-19 20:32:01 UTC (rev 195306)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2016-01-19 20:55:34 UTC (rev 195307)
@@ -433,6 +433,7 @@
 		0F64B2721A784BAF006E4E66 /* BinarySwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F64B2701A784BAF006E4E66 /* BinarySwitch.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F64B2791A7957B2006E4E66 /* CallEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F64B2771A7957B2006E4E66 /* CallEdge.cpp */; };
 		0F64B27A1A7957B2006E4E66 /* CallEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F64B2781A7957B2006E4E66 /* CallEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F64EAF31C4ECD0600621E9B /* AirArgInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F64EAF21C4ECD0600621E9B /* AirArgInlines.h */; };
 		0F666EC0183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F666EC1183566F900D017F1 /* FullBytecodeLiveness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666EBF183566F900D017F1 /* FullBytecodeLiveness.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F666EC61835672B00D017F1 /* DFGAvailability.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F666EC21835672B00D017F1 /* DFGAvailability.cpp */; };
@@ -2601,6 +2602,7 @@
 		0F64B2701A784BAF006E4E66 /* BinarySwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BinarySwitch.h; sourceTree = "<group>"; };
 		0F64B2771A7957B2006E4E66 /* CallEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallEdge.cpp; sourceTree = "<group>"; };
 		0F64B2781A7957B2006E4E66 /* CallEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallEdge.h; sourceTree = "<group>"; };
+		0F64EAF21C4ECD0600621E9B /* AirArgInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirArgInlines.h; path = b3/air/AirArgInlines.h; sourceTree = "<group>"; };
 		0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeLivenessAnalysisInlines.h; sourceTree = "<group>"; };
 		0F666EBF183566F900D017F1 /* FullBytecodeLiveness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FullBytecodeLiveness.h; sourceTree = "<group>"; };
 		0F666EC21835672B00D017F1 /* DFGAvailability.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAvailability.cpp; path = dfg/DFGAvailability.cpp; sourceTree = "<group>"; };
@@ -4850,6 +4852,7 @@
 				0FEC85491BDACDC70080FF74 /* AirAllocateStack.h */,
 				0FEC854A1BDACDC70080FF74 /* AirArg.cpp */,
 				0FEC854B1BDACDC70080FF74 /* AirArg.h */,
+				0F64EAF21C4ECD0600621E9B /* AirArgInlines.h */,
 				0FEC854C1BDACDC70080FF74 /* AirBasicBlock.cpp */,
 				0FEC854D1BDACDC70080FF74 /* AirBasicBlock.h */,
 				0FB3878B1BFBC44D00E3AB1E /* AirBlockWorklist.h */,
@@ -7506,6 +7509,7 @@
 				C4703CCE192844CC0013FBEA /* generate_js_backend_commands.py in Headers */,
 				A5EA710319F6DE6F0098F5EC /* generate_objc_backend_dispatcher_header.py in Headers */,
 				A5EA710419F6DE720098F5EC /* generate_objc_backend_dispatcher_implementation.py in Headers */,
+				0F64EAF31C4ECD0600621E9B /* AirArgInlines.h in Headers */,
 				A5EA710519F6DE740098F5EC /* generate_objc_configuration_header.py in Headers */,
 				A5EA710619F6DE760098F5EC /* generate_objc_configuration_implementation.py in Headers */,
 				A5EA710719F6DE780098F5EC /* generate_objc_conversion_helpers.py in Headers */,

Modified: trunk/Source/_javascript_Core/b3/B3MoveConstants.cpp (195306 => 195307)


--- trunk/Source/_javascript_Core/b3/B3MoveConstants.cpp	2016-01-19 20:32:01 UTC (rev 195306)
+++ trunk/Source/_javascript_Core/b3/B3MoveConstants.cpp	2016-01-19 20:55:34 UTC (rev 195307)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,27 +53,22 @@
 
     void run()
     {
-        // This phase uses super simple heuristics to ensure that constants are in profitable places
-        // and also lowers constant materialization code. Constants marked "fast" by the client are
-        // hoisted to the lowest common dominator. A table is created for constants that need to be
-        // loaded to be materialized, and all of their Values are turned into loads from that table.
-        // Non-fast constants get materialized in the block that uses them. Constants that are
-        // materialized by loading get special treatment when they get used in some kind of Any in a
-        // StackmapValue. In that case, the Constants are sunk to the point of use, since that allows
-        // the instruction selector to sink the constants into an Arg::imm64.
-
-        // FIXME: Implement a better story for constants. For example, the table used to hold double
-        // constants should have a pointer to it that is hoisted. If we wanted to be more aggressive,
-        // we could make constant materialization be a feature of Air: we could label some Tmps as
-        // being unmaterialized constants and have a late Air phase - post register allocation - that
-        // creates materializations of those constant Tmps by scavenging leftover registers.
-
-        hoistFastConstants();
-        sinkSlowConstants();
+        hoistConstants(
+            [&] (const ValueKey& key) -> bool {
+                return key.opcode() == ConstFloat || key.opcode() == ConstDouble;
+            });
+        
+        lowerFPConstants();
+        
+        hoistConstants(
+            [&] (const ValueKey& key) -> bool {
+                return key.opcode() == Const32 || key.opcode() == Const64;
+            });
     }
 
 private:
-    void hoistFastConstants()
+    template<typename Filter>
+    void hoistConstants(const Filter& filter)
     {
         Dominators& dominators = m_proc.dominators();
         HashMap<ValueKey, Value*> valueForConstant;
@@ -84,7 +79,7 @@
             for (Value* value : *block) {
                 for (Value*& child : value->children()) {
                     ValueKey key = child->key();
-                    if (!m_proc.isFastConstant(key))
+                    if (!filter(key))
                         continue;
 
                     auto result = valueForConstant.add(key, child);
@@ -116,7 +111,7 @@
                 if (block->frequency() < value->owner->frequency())
                     value->owner = block;
             }
-            materializations[entry.value->owner].append(entry.value);
+            materializations[value->owner].append(value);
         }
 
         // Get rid of Value's that are fast constants but aren't canonical. Also remove the canonical
@@ -124,7 +119,7 @@
         for (BasicBlock* block : m_proc) {
             for (Value*& value : *block) {
                 ValueKey key = value->key();
-                if (!m_proc.isFastConstant(key))
+                if (!filter(key))
                     continue;
 
                 if (valueForConstant.get(key) == value)
@@ -141,7 +136,7 @@
                 Value* value = block->at(valueIndex);
                 for (Value* child : value->children()) {
                     ValueKey key = child->key();
-                    if (!m_proc.isFastConstant(key))
+                    if (!filter(key))
                         continue;
 
                     // If we encounter a fast constant, then it must be canonical, since we already
@@ -174,16 +169,11 @@
             m_insertionSet.execute(block);
         }
     }
-    
-    void sinkSlowConstants()
+
+    void lowerFPConstants()
     {
-        // First we need to figure out which constants go into the data section. These are non-zero
-        // double constants.
         for (Value* value : m_proc.values()) {
             ValueKey key = value->key();
-            if (!needsMotion(key))
-                continue;
-            m_toRemove.append(value);
             if (goesInTable(key))
                 m_constTable.add(key, m_constTable.size());
         }
@@ -191,67 +181,52 @@
         m_dataSection = static_cast<int64_t*>(m_proc.addDataSection(m_constTable.size() * sizeof(int64_t)));
         for (auto& entry : m_constTable)
             m_dataSection[entry.value] = entry.key.value();
-        
+
+        IndexSet<Value> offLimits;
         for (BasicBlock* block : m_proc) {
-            m_constants.clear();
-            
             for (unsigned valueIndex = 0; valueIndex < block->size(); ++valueIndex) {
-                Value* value = block->at(valueIndex);
-                StackmapValue* stackmap = value->as<StackmapValue>();
+                StackmapValue* value = block->at(valueIndex)->as<StackmapValue>();
+                if (!value)
+                    continue;
+
                 for (unsigned childIndex = 0; childIndex < value->numChildren(); ++childIndex) {
+                    if (!value->constrainedChild(childIndex).rep().isAny())
+                        continue;
+                    
                     Value*& child = value->child(childIndex);
                     ValueKey key = child->key();
-                    if (!needsMotion(key))
+                    if (!goesInTable(key))
                         continue;
 
-                    if (stackmap
-                        && goesInTable(key)
-                        && stackmap->constrainedChild(childIndex).rep().isAny()) {
-                        // This is a weird special case. When we constant-fold an argument to a
-                        // stackmap, and that argument has the Any constraint, we want to just
-                        // tell the stackmap's generator that the argument is a constant rather
-                        // than materializing it in a register. For this to work, we need
-                        // lowerToAir to see this argument as a constant rather than as a load
-                        // from a table.
-                        child = m_insertionSet.insertValue(
-                            valueIndex, key.materialize(m_proc, value->origin()));
-                        continue;
-                    }
-                    
-                    child = materialize(valueIndex, key, value->origin());
+                    child = m_insertionSet.insertValue(
+                        valueIndex, key.materialize(m_proc, value->origin()));
+                    offLimits.add(child);
                 }
             }
-            
+
             m_insertionSet.execute(block);
         }
 
-        for (Value* toRemove : m_toRemove)
-            toRemove->replaceWithNop();
-    }
-    
-    Value* materialize(unsigned valueIndex, const ValueKey& key, const Origin& origin)
-    {
-        if (Value* result = m_constants.get(key))
-            return result;
+        for (BasicBlock* block : m_proc) {
+            for (unsigned valueIndex = 0; valueIndex < block->size(); ++valueIndex) {
+                Value* value = block->at(valueIndex);
+                ValueKey key = value->key();
+                if (!goesInTable(key))
+                    continue;
+                if (offLimits.contains(value))
+                    continue;
 
-        // Note that we deliberately don't do this in one add() because this is a recursive function
-        // that may rehash the map.
+                Value* tableBase = m_insertionSet.insertIntConstant(
+                    valueIndex, value->origin(), pointerType(),
+                    bitwise_cast<intptr_t>(m_dataSection));
+                Value* result = m_insertionSet.insert<MemoryValue>(
+                    valueIndex, Load, value->type(), value->origin(), tableBase,
+                    sizeof(int64_t) * m_constTable.get(key));
+                value->replaceWithIdentity(result);
+            }
 
-        Value* result;
-        if (goesInTable(key)) {
-            Value* tableBase = materialize(
-                valueIndex,
-                ValueKey(
-                    constPtrOpcode(), pointerType(),
-                    static_cast<int64_t>(bitwise_cast<intptr_t>(m_dataSection))),
-                origin);
-            result = m_insertionSet.insert<MemoryValue>(
-                valueIndex, Load, key.type(), origin, tableBase,
-                sizeof(int64_t) * m_constTable.get(key));
-        } else
-            result = m_insertionSet.insertValue(valueIndex, key.materialize(m_proc, origin));
-        m_constants.add(key, result);
-        return result;
+            m_insertionSet.execute(block);
+        }
     }
 
     bool goesInTable(const ValueKey& key)
@@ -260,11 +235,6 @@
             || (key.opcode() == ConstFloat && key != floatZero());
     }
 
-    bool needsMotion(const ValueKey& key)
-    {
-        return key.isConstant() && !m_proc.isFastConstant(key);
-    }
-
     static ValueKey doubleZero()
     {
         return ValueKey(ConstDouble, Double, 0.0);

Modified: trunk/Source/_javascript_Core/b3/air/AirArg.h (195306 => 195307)


--- trunk/Source/_javascript_Core/b3/air/AirArg.h	2016-01-19 20:32:01 UTC (rev 195306)
+++ trunk/Source/_javascript_Core/b3/air/AirArg.h	2016-01-19 20:55:34 UTC (rev 195307)
@@ -1078,6 +1078,18 @@
 
     bool usesTmp(Air::Tmp tmp) const;
 
+    template<typename Thing>
+    bool is() const;
+
+    template<typename Thing>
+    Thing as() const;
+
+    template<typename Thing, typename Functor>
+    void forEachFast(const Functor&);
+
+    template<typename Thing, typename Functor>
+    void forEach(Role, Type, Width, const Functor&);
+
     // This is smart enough to know that an address arg in a Def or UseDef rule will use its
     // tmps and never def them. For example, this:
     //

Added: trunk/Source/_javascript_Core/b3/air/AirArgInlines.h (0 => 195307)


--- trunk/Source/_javascript_Core/b3/air/AirArgInlines.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/b3/air/AirArgInlines.h	2016-01-19 20:55:34 UTC (rev 195307)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 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. 
+ */
+
+#ifndef AirArgInlines_h
+#define AirArgInlines_h
+
+#if ENABLE(B3_JIT)
+
+#include "AirArg.h"
+
+namespace JSC { namespace B3 { namespace Air {
+
+template<typename T> struct ArgThingHelper;
+
+template<> struct ArgThingHelper<Tmp> {
+    static bool is(const Arg& arg)
+    {
+        return arg.isTmp();
+    }
+
+    static Tmp as(const Arg& arg)
+    {
+        if (is(arg))
+            return arg.tmp();
+        return Tmp();
+    }
+
+    template<typename Functor>
+    static void forEachFast(Arg& arg, const Functor& functor)
+    {
+        arg.forEachTmpFast(functor);
+    }
+
+    template<typename Functor>
+    static void forEach(Arg& arg, Arg::Role role, Arg::Type type, Arg::Width width, const Functor& functor)
+    {
+        arg.forEachTmp(role, type, width, functor);
+    }
+};
+
+template<> struct ArgThingHelper<Arg> {
+    static bool is(const Arg&)
+    {
+        return true;
+    }
+
+    static Arg as(const Arg& arg)
+    {
+        return arg;
+    }
+
+    template<typename Functor>
+    static void forEachFast(Arg& arg, const Functor& functor)
+    {
+        functor(arg);
+    }
+
+    template<typename Functor>
+    static void forEach(Arg& arg, Arg::Role role, Arg::Type type, Arg::Width width, const Functor& functor)
+    {
+        functor(arg, role, type, width);
+    }
+};
+
+template<typename Thing>
+bool Arg::is() const
+{
+    return ArgThingHelper<Thing>::is(*this);
+}
+
+template<typename Thing>
+Thing Arg::as() const
+{
+    return ArgThingHelper<Thing>::as(*this);
+}
+
+template<typename Thing, typename Functor>
+void Arg::forEachFast(const Functor& functor)
+{
+    ArgThingHelper<Thing>::forEachFast(*this, functor);
+}
+
+template<typename Thing, typename Functor>
+void Arg::forEach(Role role, Type type, Width width, const Functor& functor)
+{
+    ArgThingHelper<Thing>::forEach(*this, role, type, width, functor);
+}
+
+} } } // namespace JSC::B3::Air
+
+#endif // ENABLE(B3_JIT)
+
+#endif // AirArgInlines_h
+

Modified: trunk/Source/_javascript_Core/b3/air/AirIteratedRegisterCoalescing.cpp (195306 => 195307)


--- trunk/Source/_javascript_Core/b3/air/AirIteratedRegisterCoalescing.cpp	2016-01-19 20:32:01 UTC (rev 195306)
+++ trunk/Source/_javascript_Core/b3/air/AirIteratedRegisterCoalescing.cpp	2016-01-19 20:55:34 UTC (rev 195307)
@@ -948,6 +948,11 @@
             const UseCounts<Tmp>::Counts& counts = m_useCounts[tmp];
             double uses = counts.numWarmUses + counts.numDefs;
 
+            // If it's a constant, then it's not as bad to spill. We can rematerialize it in many
+            // cases.
+            if (counts.numConstDefs == counts.numDefs)
+                uses /= 2;
+
             return degree / uses;
         };
 

Modified: trunk/Source/_javascript_Core/b3/air/AirUseCounts.h (195306 => 195307)


--- trunk/Source/_javascript_Core/b3/air/AirUseCounts.h	2016-01-19 20:32:01 UTC (rev 195306)
+++ trunk/Source/_javascript_Core/b3/air/AirUseCounts.h	2016-01-19 20:55:34 UTC (rev 195307)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,7 +28,7 @@
 
 #if ENABLE(B3_JIT)
 
-#include "AirArg.h"
+#include "AirArgInlines.h"
 #include "AirBlockWorklist.h"
 #include "AirCode.h"
 #include "AirInstInlines.h"
@@ -57,6 +57,7 @@
         double numWarmUses { 0 };
         double numColdUses { 0 };
         double numDefs { 0 };
+        double numConstDefs { 0 };
     };
     
     UseCounts(Code& code)
@@ -87,6 +88,11 @@
                         if (Arg::isAnyDef(role))
                             counts.numDefs += frequency;
                     });
+
+                if ((inst.opcode == Move || inst.opcode == Move32)
+                    && inst.args[0].isSomeImm()
+                    && inst.args[1].is<Thing>())
+                    m_counts.add(inst.args[1].as<Thing>(), Counts()).iterator->value.numConstDefs++;
             }
         }
     }

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (195306 => 195307)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2016-01-19 20:32:01 UTC (rev 195306)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2016-01-19 20:55:34 UTC (rev 195307)
@@ -271,11 +271,8 @@
     if (node->hasMultiGetByOffsetData()) {
         MultiGetByOffsetData& data = ""
         out.print(comma, "id", data.identifierNumber, "{", identifiers()[data.identifierNumber], "}");
-        for (unsigned i = 0; i < data.cases.size(); ++i) {
+        for (unsigned i = 0; i < data.cases.size(); ++i)
             out.print(comma, inContext(data.cases[i], context));
-            if (data.cases[i].method().kind() == GetByOffsetMethod::Load)
-                out.print(" (inferred value = ", inContext(inferredValueForProperty(data.cases[i].set(), identifiers()[data.identifierNumber]), context), ")");
-        }
     }
     if (node->hasMultiPutByOffsetData()) {
         MultiPutByOffsetData& data = ""
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to