ValueToInt32 speculation will cause OSR exits even when it does not have to
https://bugs.webkit.org/show_bug.cgi?id=81068
<rdar://problem/11043926>

Reviewed by Anders Carlsson.
        
Two related changes:
1) ValueToInt32 will now always just defer to the non-speculative path, instead
   of exiting, if it doesn't know what speculations to perform.
2) ValueToInt32 will speculate boolean if it sees this to be profitable.

* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
* dfg/DFGNode.h:
(JSC::DFG::Node::shouldSpeculateBoolean):
(Node):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileValueToInt32):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@110661 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index 2e20baf..c93fc15 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -291,11 +291,12 @@
         break;
             
     case ValueToInt32:
-        if (m_graph[node.child1()].shouldNotSpeculateInteger()) {
-            if (m_graph[node.child1()].shouldSpeculateDouble())
-                forNode(node.child1()).filter(PredictNumber);
-        } else
+        if (m_graph[node.child1()].shouldSpeculateInteger())
             forNode(node.child1()).filter(PredictInt32);
+        else if (m_graph[node.child1()].shouldSpeculateNumber())
+            forNode(node.child1()).filter(PredictNumber);
+        else if (m_graph[node.child1()].shouldSpeculateBoolean())
+            forNode(node.child1()).filter(PredictBoolean);
         
         forNode(nodeIndex).set(PredictInt32);
         break;
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index 3a159b9..11922db 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -700,6 +700,11 @@
         return !!(prediction() & PredictDouble);
     }
     
+    bool shouldSpeculateBoolean()
+    {
+        return isBooleanPrediction(prediction());
+    }
+    
     bool shouldSpeculateFinalObject()
     {
         return isFinalObjectPrediction(prediction());
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index 1317aa7..90c7171 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -1490,31 +1490,43 @@
 
 void SpeculativeJIT::compileValueToInt32(Node& node)
 {
-    if (at(node.child1()).shouldNotSpeculateInteger()) {
-        if (at(node.child1()).shouldSpeculateDouble()) {
-            SpeculateDoubleOperand op1(this, node.child1());
-            GPRTemporary result(this);
-            FPRReg fpr = op1.fpr();
-            GPRReg gpr = result.gpr();
-            JITCompiler::Jump truncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateSuccessful);
-            
-            silentSpillAllRegisters(gpr);
-            callOperation(toInt32, gpr, fpr);
-            silentFillAllRegisters(gpr);
-            
-            truncatedToInteger.link(&m_jit);
-            integerResult(gpr, m_compileIndex);
-            return;
-        }
-        // Do it the safe way.
-        nonSpeculativeValueToInt32(node);
+    if (at(node.child1()).shouldSpeculateInteger()) {
+        SpeculateIntegerOperand op1(this, node.child1());
+        GPRTemporary result(this, op1);
+        m_jit.move(op1.gpr(), result.gpr());
+        integerResult(result.gpr(), m_compileIndex, op1.format());
         return;
     }
     
-    SpeculateIntegerOperand op1(this, node.child1());
-    GPRTemporary result(this, op1);
-    m_jit.move(op1.gpr(), result.gpr());
-    integerResult(result.gpr(), m_compileIndex, op1.format());
+    if (at(node.child1()).shouldSpeculateNumber()) {
+        SpeculateDoubleOperand op1(this, node.child1());
+        GPRTemporary result(this);
+        FPRReg fpr = op1.fpr();
+        GPRReg gpr = result.gpr();
+        JITCompiler::Jump truncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateSuccessful);
+        
+        silentSpillAllRegisters(gpr);
+        callOperation(toInt32, gpr, fpr);
+        silentFillAllRegisters(gpr);
+        
+        truncatedToInteger.link(&m_jit);
+        integerResult(gpr, m_compileIndex);
+        return;
+    }
+    
+    if (at(node.child1()).shouldSpeculateBoolean()) {
+        SpeculateBooleanOperand op1(this, node.child1());
+        GPRTemporary result(this, op1);
+        
+        m_jit.and32(JITCompiler::TrustedImm32(1), op1.gpr());
+        
+        integerResult(op1.gpr(), m_compileIndex);
+        return;
+    }
+    
+    // Do it the safe way.
+    nonSpeculativeValueToInt32(node);
+    return;
 }
 
 void SpeculativeJIT::compileUInt32ToNumber(Node& node)