Title: [91743] trunk/Source/_javascript_Core
Revision
91743
Author
[email protected]
Date
2011-07-25 22:35:00 -0700 (Mon, 25 Jul 2011)

Log Message

DFG non-speculative JIT emits inefficient code for arithmetic
involving two registers
https://bugs.webkit.org/show_bug.cgi?id=65160

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

The non-speculative JIT now emits inline code for double arithmetic, but
still attempts integer arithmetic first.  This is a speed-up on SunSpider
(albeit a small one), and a large speed-up on Kraken.

* dfg/DFGNonSpeculativeJIT.cpp:
(JSC::DFG::NonSpeculativeJIT::basicArithOp):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (91742 => 91743)


--- trunk/Source/_javascript_Core/ChangeLog	2011-07-26 05:21:06 UTC (rev 91742)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-07-26 05:35:00 UTC (rev 91743)
@@ -1,3 +1,18 @@
+2011-07-25  Filip Pizlo  <[email protected]>
+
+        DFG non-speculative JIT emits inefficient code for arithmetic
+        involving two registers
+        https://bugs.webkit.org/show_bug.cgi?id=65160
+
+        Reviewed by Gavin Barraclough.
+        
+        The non-speculative JIT now emits inline code for double arithmetic, but
+        still attempts integer arithmetic first.  This is a speed-up on SunSpider
+        (albeit a small one), and a large speed-up on Kraken.
+
+        * dfg/DFGNonSpeculativeJIT.cpp:
+        (JSC::DFG::NonSpeculativeJIT::basicArithOp):
+
 2011-07-25  Ryuan Choi  <[email protected]>
 
         [EFL] Build break with --debug after r89153.

Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (91742 => 91743)


--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp	2011-07-26 05:21:06 UTC (rev 91742)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp	2011-07-26 05:35:00 UTC (rev 91743)
@@ -227,38 +227,45 @@
     JSValueOperand arg1(this, node.child1());
     JSValueOperand arg2(this, node.child2());
     
+    FPRTemporary tmp1(this);
+    FPRTemporary tmp2(this);
+    FPRReg tmp1FPR = tmp1.fpr();
+    FPRReg tmp2FPR = tmp2.fpr();
+    
+    GPRTemporary result(this);
+
     GPRReg arg1GPR = arg1.gpr();
     GPRReg arg2GPR = arg2.gpr();
     
-    GPRTemporary result(this);
-
     GPRReg resultGPR = result.gpr();
     
     arg1.use();
     arg2.use();
     
-    JITCompiler::JumpList slowPath;
+    JITCompiler::Jump child1NotInt;
+    JITCompiler::Jump child2NotInt;
+    JITCompiler::JumpList overflow;
     
     if (!isKnownInteger(node.child1()))
-        slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
+        child1NotInt = m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister);
     if (!isKnownInteger(node.child2()))
-        slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
+        child2NotInt = m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister);
     
     switch (op) {
     case ValueAdd:
     case ArithAdd: {
-        slowPath.append(m_jit.branchAdd32(MacroAssembler::Overflow, arg1GPR, arg2GPR, resultGPR));
+        overflow.append(m_jit.branchAdd32(MacroAssembler::Overflow, arg1GPR, arg2GPR, resultGPR));
         break;
     }
         
     case ArithSub: {
-        slowPath.append(m_jit.branchSub32(MacroAssembler::Overflow, arg1GPR, arg2GPR, resultGPR));
+        overflow.append(m_jit.branchSub32(MacroAssembler::Overflow, arg1GPR, arg2GPR, resultGPR));
         break;
     }
         
     case ArithMul: {
-        slowPath.append(m_jit.branchMul32(MacroAssembler::Overflow, arg1GPR, arg2GPR, resultGPR));
-        slowPath.append(m_jit.branchTest32(MacroAssembler::Zero, resultGPR));
+        overflow.append(m_jit.branchMul32(MacroAssembler::Overflow, arg1GPR, arg2GPR, resultGPR));
+        overflow.append(m_jit.branchTest32(MacroAssembler::Zero, resultGPR));
         break;
     }
         
@@ -270,34 +277,84 @@
         
     JITCompiler::Jump done = m_jit.jump();
     
-    slowPath.link(&m_jit);
-    
-    silentSpillAllRegisters(resultGPR);
     if (op == ValueAdd) {
+        if (child1NotInt.isSet())
+            child1NotInt.link(&m_jit);
+        if (child2NotInt.isSet())
+            child2NotInt.link(&m_jit);
+        overflow.link(&m_jit);
+        
+        silentSpillAllRegisters(resultGPR);
         setupStubArguments(arg1GPR, arg2GPR);
         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
         appendCallWithExceptionCheck(operationValueAdd);
+        m_jit.move(GPRInfo::returnValueGPR, resultGPR);
+        silentFillAllRegisters(resultGPR);
     } else {
-        setupTwoStubArgs<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1GPR, arg2GPR);
+        JITCompiler::JumpList haveFPRArguments;
+
+        overflow.link(&m_jit);
+        
+        // both arguments are integers
+        m_jit.convertInt32ToDouble(arg1GPR, tmp1FPR);
+        m_jit.convertInt32ToDouble(arg2GPR, tmp2FPR);
+        
+        haveFPRArguments.append(m_jit.jump());
+        
+        JITCompiler::Jump child2NotInt2;
+        
+        if (!isKnownInteger(node.child1())) {
+            child1NotInt.link(&m_jit);
+            
+            m_jit.move(arg1GPR, resultGPR);
+            unboxDouble(resultGPR, tmp1FPR);
+            
+            // child1 is converted to a double; child2 may either be an int or
+            // a boxed double
+            
+            if (!isKnownInteger(node.child2()))
+                child2NotInt2 = m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister);
+            
+            // child 2 is definitely an integer
+            m_jit.convertInt32ToDouble(arg2GPR, tmp2FPR);
+            
+            haveFPRArguments.append(m_jit.jump());
+        }
+        
+        if (!isKnownInteger(node.child2())) {
+            child2NotInt.link(&m_jit);
+            // child1 is definitely an integer, and child 2 is definitely not
+            
+            m_jit.convertInt32ToDouble(arg1GPR, tmp1FPR);
+            
+            if (child2NotInt2.isSet())
+                child2NotInt2.link(&m_jit);
+            
+            m_jit.move(arg2GPR, resultGPR);
+            unboxDouble(resultGPR, tmp2FPR);
+        }
+        
+        haveFPRArguments.link(&m_jit);
+        
         switch (op) {
         case ArithAdd:
-            m_jit.appendCall(operationArithAdd);
+            m_jit.addDouble(tmp2FPR, tmp1FPR);
             break;
             
         case ArithSub:
-            m_jit.appendCall(operationArithSub);
+            m_jit.subDouble(tmp2FPR, tmp1FPR);
             break;
             
         case ArithMul:
-            m_jit.appendCall(operationArithMul);
+            m_jit.mulDouble(tmp2FPR, tmp1FPR);
             break;
             
         default:
             ASSERT_NOT_REACHED();
         }
+        
+        boxDouble(tmp1FPR, resultGPR);
     }
-    m_jit.move(GPRInfo::returnValueGPR, resultGPR);
-    silentFillAllRegisters(resultGPR);
     
     done.link(&m_jit);
         
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to