Title: [91160] trunk/Source/_javascript_Core
Revision
91160
Author
[email protected]
Date
2011-07-16 18:47:45 -0700 (Sat, 16 Jul 2011)

Log Message

DFG JIT compare/branch code emits is-integer tests even when a value is
definitely not an integer.
https://bugs.webkit.org/show_bug.cgi?id=64654

Patch by Filip Pizlo <[email protected]> on 2011-07-16
Reviewed by Gavin Barraclough.

Added the isKnownNotInteger() method, which returns true if a node is
definitely not an integer and will always fail any is-integer test.  Then
modified the compare and branch code to use this method; if it returns
true then is-int tests are omitted and the compiler always emits a slow
call.

* dfg/DFGJITCodeGenerator.cpp:
(JSC::DFG::JITCodeGenerator::isKnownNotInteger):
(JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeBranch):
(JSC::DFG::JITCodeGenerator::nonSpeculativeNonPeepholeCompare):
(JSC::DFG::JITCodeGenerator::nonSpeculativeCompare):
* dfg/DFGJITCodeGenerator.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compare):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (91159 => 91160)


--- trunk/Source/_javascript_Core/ChangeLog	2011-07-17 00:46:03 UTC (rev 91159)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-07-17 01:47:45 UTC (rev 91160)
@@ -1,5 +1,28 @@
 2011-07-16  Filip Pizlo  <[email protected]>
 
+        DFG JIT compare/branch code emits is-integer tests even when a value is
+        definitely not an integer.
+        https://bugs.webkit.org/show_bug.cgi?id=64654
+
+        Reviewed by Gavin Barraclough.
+        
+        Added the isKnownNotInteger() method, which returns true if a node is
+        definitely not an integer and will always fail any is-integer test.  Then
+        modified the compare and branch code to use this method; if it returns
+        true then is-int tests are omitted and the compiler always emits a slow
+        call.
+
+        * dfg/DFGJITCodeGenerator.cpp:
+        (JSC::DFG::JITCodeGenerator::isKnownNotInteger):
+        (JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeBranch):
+        (JSC::DFG::JITCodeGenerator::nonSpeculativeNonPeepholeCompare):
+        (JSC::DFG::JITCodeGenerator::nonSpeculativeCompare):
+        * dfg/DFGJITCodeGenerator.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compare):
+
+2011-07-16  Filip Pizlo  <[email protected]>
+
         DFG speculative JIT has dead code for slow calls for branches.
         https://bugs.webkit.org/show_bug.cgi?id=64653
 

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (91159 => 91160)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp	2011-07-17 00:46:03 UTC (rev 91159)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp	2011-07-17 01:47:45 UTC (rev 91160)
@@ -365,6 +365,17 @@
     return false;
 }
 
+bool JITCodeGenerator::isKnownNotInteger(NodeIndex nodeIndex)
+{
+    Node& node = m_jit.graph()[nodeIndex];
+    VirtualRegister virtualRegister = node.virtualRegister();
+    GenerationInfo& info = m_generationInfo[virtualRegister];
+    
+    return (info.registerFormat() | DataFormatJS) == DataFormatJSDouble
+        || (info.registerFormat() | DataFormatJS) == DataFormatJSCell
+        || (node.isConstant() && !valueOfJSConstant(nodeIndex).isInt32());
+}
+
 JITCompiler::Call JITCodeGenerator::cachedGetById(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, NodeType nodeType)
 {
     GPRReg scratchGPR;
@@ -531,89 +542,116 @@
     GPRReg arg1GPR = arg1.gpr();
     GPRReg arg2GPR = arg2.gpr();
     
-    GPRTemporary result(this, arg2);
-    GPRReg resultGPR = result.gpr();
-    
     JITCompiler::JumpList slowPath;
     
-    if (!isKnownInteger(node.child1()))
-        slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
-    if (!isKnownInteger(node.child2()))
-        slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
+    if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
+        flushRegisters();
+
+        GPRResult result(this);
+        GPRReg resultGPR = result.gpr();
     
-    addBranch(m_jit.branch32(cond, arg1GPR, arg2GPR), taken);
+        callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
+        addBranch(m_jit.branchTest8(callResultCondition, resultGPR), taken);
+    } else {
+        GPRTemporary result(this, arg2);
+        GPRReg resultGPR = result.gpr();
     
-    if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
-        addBranch(m_jit.jump(), notTaken);
+        if (!isKnownInteger(node.child1()))
+            slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
+        if (!isKnownInteger(node.child2()))
+            slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
     
-        slowPath.link(&m_jit);
+        addBranch(m_jit.branch32(cond, arg1GPR, arg2GPR), taken);
     
-        silentSpillAllRegisters(resultGPR);
-        setupStubArguments(arg1GPR, arg2GPR);
-        m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
-        appendCallWithExceptionCheck(helperFunction);
-        m_jit.move(GPRInfo::returnValueGPR, resultGPR);
-        silentFillAllRegisters(resultGPR);
+        if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
+            addBranch(m_jit.jump(), notTaken);
+    
+            slowPath.link(&m_jit);
+    
+            silentSpillAllRegisters(resultGPR);
+            setupStubArguments(arg1GPR, arg2GPR);
+            m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+            appendCallWithExceptionCheck(helperFunction);
+            m_jit.move(GPRInfo::returnValueGPR, resultGPR);
+            silentFillAllRegisters(resultGPR);
         
-        addBranch(m_jit.branchTest8(callResultCondition, resultGPR), taken);
+            addBranch(m_jit.branchTest8(callResultCondition, resultGPR), taken);
+        }
     }
 
     if (notTaken != (m_block + 1))
         addBranch(m_jit.jump(), notTaken);
 }
 
-bool JITCodeGenerator::nonSpeculativeCompare(Node& node, MacroAssembler::RelationalCondition cond, Z_DFGOperation_EJJ helperFunction)
+void JITCodeGenerator::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler::RelationalCondition cond, Z_DFGOperation_EJJ helperFunction)
 {
-    NodeIndex branchNodeIndex = detectPeepHoleBranch();
-    if (branchNodeIndex != NoNode) {
-        ASSERT(node.adjustedRefCount() == 1);
-        
-        nonSpeculativePeepholeBranch(node, branchNodeIndex, cond, helperFunction);
-    
-        use(node.child1());
-        use(node.child2());
-        m_compileIndex = branchNodeIndex;
-        
-        return true;
-    }
-        
     JSValueOperand arg1(this, node.child1());
     JSValueOperand arg2(this, node.child2());
     GPRReg arg1GPR = arg1.gpr();
     GPRReg arg2GPR = arg2.gpr();
     
-    GPRTemporary result(this, arg2);
-    GPRReg resultGPR = result.gpr();
-    
     JITCompiler::JumpList slowPath;
     
-    if (!isKnownInteger(node.child1()))
-        slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
-    if (!isKnownInteger(node.child2()))
-        slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
+    if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
+        flushRegisters();
+        
+        GPRResult result(this);
+        GPRReg resultGPR = result.gpr();
     
-    m_jit.compare32(cond, arg1GPR, arg2GPR, resultGPR);
+        callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
+        
+        m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
+        jsValueResult(resultGPR, m_compileIndex);
+    } else {
+        GPRTemporary result(this, arg2);
+        GPRReg resultGPR = result.gpr();
     
-    if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
-        JITCompiler::Jump haveResult = m_jit.jump();
+        if (!isKnownInteger(node.child1()))
+            slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
+        if (!isKnownInteger(node.child2()))
+            slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
     
-        slowPath.link(&m_jit);
+        m_jit.compare32(cond, arg1GPR, arg2GPR, resultGPR);
+    
+        if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
+            JITCompiler::Jump haveResult = m_jit.jump();
+    
+            slowPath.link(&m_jit);
         
-        silentSpillAllRegisters(resultGPR);
-        setupStubArguments(arg1GPR, arg2GPR);
-        m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
-        appendCallWithExceptionCheck(helperFunction);
-        m_jit.move(GPRInfo::returnValueGPR, resultGPR);
-        silentFillAllRegisters(resultGPR);
+            silentSpillAllRegisters(resultGPR);
+            setupStubArguments(arg1GPR, arg2GPR);
+            m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+            appendCallWithExceptionCheck(helperFunction);
+            m_jit.move(GPRInfo::returnValueGPR, resultGPR);
+            silentFillAllRegisters(resultGPR);
         
-        m_jit.andPtr(TrustedImm32(1), resultGPR);
+            m_jit.andPtr(TrustedImm32(1), resultGPR);
         
-        haveResult.link(&m_jit);
+            haveResult.link(&m_jit);
+        }
+        
+        m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
+        
+        jsValueResult(resultGPR, m_compileIndex);
     }
+}
+
+bool JITCodeGenerator::nonSpeculativeCompare(Node& node, MacroAssembler::RelationalCondition cond, Z_DFGOperation_EJJ helperFunction)
+{
+    NodeIndex branchNodeIndex = detectPeepHoleBranch();
+    if (branchNodeIndex != NoNode) {
+        ASSERT(node.adjustedRefCount() == 1);
+        
+        nonSpeculativePeepholeBranch(node, branchNodeIndex, cond, helperFunction);
     
-    m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
+        use(node.child1());
+        use(node.child2());
+        m_compileIndex = branchNodeIndex;
+        
+        return true;
+    }
     
-    jsValueResult(resultGPR, m_compileIndex);
+    nonSpeculativeNonPeepholeCompare(node, cond, helperFunction);
     
     return false;
 }

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (91159 => 91160)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-07-17 00:46:03 UTC (rev 91159)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-07-17 01:47:45 UTC (rev 91160)
@@ -414,6 +414,8 @@
 
     bool isKnownInteger(NodeIndex);
     bool isKnownNumeric(NodeIndex);
+    
+    bool isKnownNotInteger(NodeIndex);
 
     // Checks/accessors for constant values.
     bool isConstant(NodeIndex nodeIndex) { return m_jit.isConstant(nodeIndex); }
@@ -555,6 +557,7 @@
     void cachedGetMethod(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
     
     void nonSpeculativePeepholeBranch(Node&, NodeIndex branchNodeIndex, MacroAssembler::RelationalCondition, Z_DFGOperation_EJJ helperFunction);
+    void nonSpeculativeNonPeepholeCompare(Node&, MacroAssembler::RelationalCondition, Z_DFGOperation_EJJ helperFunction);
     bool nonSpeculativeCompare(Node&, MacroAssembler::RelationalCondition, Z_DFGOperation_EJJ helperFunction);
     
     void emitBranch(Node&);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (91159 => 91160)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-07-17 00:46:03 UTC (rev 91159)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-07-17 01:47:45 UTC (rev 91160)
@@ -401,16 +401,21 @@
         return true;
     }
 
-    // Normal case, not fused to branch.
-    SpeculateIntegerOperand op1(this, node.child1());
-    SpeculateIntegerOperand op2(this, node.child2());
-    GPRTemporary result(this, op1, op2);
-
-    m_jit.compare32(condition, op1.gpr(), op2.gpr(), result.gpr());
-
-    // If we add a DataFormatBool, we should use it here.
-    m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
-    jsValueResult(result.gpr(), m_compileIndex);
+    if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2()))
+        nonSpeculativeNonPeepholeCompare(node, condition, operation);
+    else {
+        // Normal case, not fused to branch.
+        SpeculateIntegerOperand op1(this, node.child1());
+        SpeculateIntegerOperand op2(this, node.child2());
+        GPRTemporary result(this, op1, op2);
+        
+        m_jit.compare32(condition, op1.gpr(), op2.gpr(), result.gpr());
+        
+        // If we add a DataFormatBool, we should use it here.
+        m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
+        jsValueResult(result.gpr(), m_compileIndex);
+    }
+    
     return false;
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to