[JSC] Optimize Number.prototype.toString on Int32 / Int52 / Double
https://bugs.webkit.org/show_bug.cgi?id=167454

Reviewed by Saam Barati.

JSTests:

* stress/number-to-string-abstract-operation.js: Added.
(shouldBe):
(int32ToString):
(shouldBe.int32ToString.new.Number.int52ToString):
(shouldBe.int32ToString.new.Number):
(shouldBe.doubleToString):
* stress/number-to-string-radix.js: Added.
(shouldBe):
(int32ToString):
(shouldBe.int32ToString.new.Number.int52ToString):
(shouldBe.int32ToString.new.Number):
(shouldBe.doubleToString):
* stress/number-to-string.js: Added.
(shouldBe):
(int32ToString):
(shouldBe.int32ToString.new.Number.int52ToString):
(shouldBe.int32ToString.new.Number):
(shouldBe.doubleToString):

Source/JavaScriptCore:

This patch improves Number.toString(radix) performance
by introducing NumberToStringWithRadix DFG node. It directly
calls the operation and it always returns String.

                                               baseline                  patched

    stanford-crypto-sha256-iterative        45.130+-0.928             44.032+-1.184           might be 1.0250x faster

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@214219 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
index 51dd50e..9fdf9ef 100644
--- a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
@@ -390,6 +390,37 @@
             break;
         }
 
+        case ToString:
+        case CallStringConstructor: {
+            Edge& child1 = m_node->child1();
+            switch (child1.useKind()) {
+            case Int32Use:
+            case Int52RepUse:
+            case DoubleRepUse: {
+                if (child1->hasConstant()) {
+                    JSValue value = child1->constant()->value();
+                    if (value) {
+                        String result;
+                        if (value.isInt32())
+                            result = String::number(value.asInt32());
+                        else if (value.isNumber())
+                            result = String::numberToStringECMAScript(value.asNumber());
+
+                        if (!result.isNull()) {
+                            m_node->convertToLazyJSConstant(m_graph, LazyJSValue::newString(m_graph, result));
+                            m_changed = true;
+                        }
+                    }
+                }
+                break;
+            }
+
+            default:
+                break;
+            }
+            break;
+        }
+
         case GetArrayLength: {
             if (m_node->arrayMode().type() == Array::Generic
                 || m_node->arrayMode().type() == Array::String) {