Add peephole optimisation to 'op_not... jfalse...' (eg. if(!...) )
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Aug 2008 03:17:19 +0000 (03:17 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Aug 2008 03:17:19 +0000 (03:17 +0000)
Reviewed by Geoff Garen

This is a very slight win in sunspider, and a fairly substantial win
in hot code that does if(!...), etc.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@35703 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/VM/CodeGenerator.cpp
JavaScriptCore/VM/CodeGenerator.h

index da6615f..2747991 100644 (file)
@@ -1,3 +1,19 @@
+2008-08-12  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Geoff Garen.
+
+        Add peephole optimisation to 'op_not... jfalse...' (eg. if(!...) )
+
+        This is a very slight win in sunspider, and a fairly substantial win
+        in hot code that does if(!...), etc.
+
+        * VM/CodeGenerator.cpp:
+        (KJS::CodeGenerator::retrieveLastUnaryOp):
+        (KJS::CodeGenerator::rewindBinaryOp):
+        (KJS::CodeGenerator::rewindUnaryOp):
+        (KJS::CodeGenerator::emitJumpIfFalse):
+        * VM/CodeGenerator.h:
+
 2008-08-12  Dan Bernstein  <mitz@apple.com>
 
         - JavaScriptCore part of <rdar://problem/6121636>
index 0bae951..b1647e3 100644 (file)
@@ -433,12 +433,26 @@ void CodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src
     src2Index = instructions().at(size - 1).u.operand;
 }
 
+void CodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
+{
+    ASSERT(instructions().size() >= 3);
+    size_t size = instructions().size();
+    dstIndex = instructions().at(size - 2).u.operand;
+    srcIndex = instructions().at(size - 1).u.operand;
+}
+
 void ALWAYS_INLINE CodeGenerator::rewindBinaryOp()
 {
     ASSERT(instructions().size() >= 4);
     instructions().shrink(instructions().size() - 4);
 }
 
+void ALWAYS_INLINE CodeGenerator::rewindUnaryOp()
+{
+    ASSERT(instructions().size() >= 3);
+    instructions().shrink(instructions().size() - 3);
+}
+
 PassRefPtr<LabelID> CodeGenerator::emitJump(LabelID* target)
 {
     emitOpcode(target->isForwardLabel() ? op_jmp : op_loop);
@@ -490,6 +504,19 @@ PassRefPtr<LabelID> CodeGenerator::emitJumpIfFalse(RegisterID* cond, LabelID* ta
             instructions().append(target->offsetFrom(instructions().size()));
             return target;
         }
+    } else if (m_lastOpcodeID == op_not) {
+        int dstIndex;
+        int srcIndex;
+
+        retrieveLastUnaryOp(dstIndex, srcIndex);
+
+        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
+            rewindUnaryOp();
+            emitOpcode(target->isForwardLabel() ? op_jtrue : op_loop_if_true);
+            instructions().append(srcIndex);
+            instructions().append(target->offsetFrom(instructions().size()));
+            return target;
+        }        
     }
 
     emitOpcode(op_jfalse);
index 32ad4e0..aca5224 100644 (file)
@@ -325,7 +325,9 @@ namespace KJS {
     private:
         void emitOpcode(OpcodeID);
         void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
+        void retrieveLastUnaryOp(int& dstIndex, int& srcIndex);
         void rewindBinaryOp();
+        void rewindUnaryOp();
 
         PassRefPtr<LabelID> emitComplexJumpScopes(LabelID* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
         struct JSValueHashTraits : HashTraits<JSValue*> {