Title: [279343] trunk
Revision
279343
Author
commit-qu...@webkit.org
Date
2021-06-28 10:55:12 -0700 (Mon, 28 Jun 2021)

Log Message

Add LLInt fast path for less, lesseq, greater and greatereq
https://bugs.webkit.org/show_bug.cgi?id=226266

Patch by Mikhail R. Gadelha <mikh...@igalia.com> on 2021-06-28
Reviewed by Tadeu Zagallo.

The motivation is to add fast path for integers and doubles
in LLInt, so we don't need to go to slow path for those cases.

This patch implements the less, lesseq, greater, greatereq
instruction for ARMv7, MIPS and CLoop.

Microbenchmarking results:
* x86_64: number-comparison-inline definitely 1.3520x faster
* ARMv7: number-comparison-inline definitely 1.3520x faster

JetStream2 results:
* x86_64 jit: 1.015 times better
* x86_64 no-jit: 1.018 times better
* ARMv7 no-jit: 1.004 times worse

* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/arm.rb:
* offlineasm/cloop.rb:
* offlineasm/mips.rb:

Modified Paths

Added Paths

Diff

Added: trunk/JSTests/microbenchmarks/double-comparison-inline.js (0 => 279343)


--- trunk/JSTests/microbenchmarks/double-comparison-inline.js	                        (rev 0)
+++ trunk/JSTests/microbenchmarks/double-comparison-inline.js	2021-06-28 17:55:12 UTC (rev 279343)
@@ -0,0 +1,26 @@
+let c = 0
+let a = 0
+
+for (let i = 0; i < 100000; ++i)
+{
+  let c = (i >= i + 1.5)
+  a = c ? 15 : 20
+}
+
+for (let i = 0; i < 100000; ++i)
+{
+  let c = (i > i + 1.5)
+  a = c ? 15 : 20
+}
+
+for (let i = 0; i < 100000; ++i)
+{
+  let c = (i <= i + 1.5)
+  a = c ? 15 : 20
+}
+
+for (let i = 0; i < 100000; ++i)
+{
+  let c = (i < i + 1.5)
+  a = c ? 15 : 20
+}

Added: trunk/JSTests/microbenchmarks/number-comparison-inline.js (0 => 279343)


--- trunk/JSTests/microbenchmarks/number-comparison-inline.js	                        (rev 0)
+++ trunk/JSTests/microbenchmarks/number-comparison-inline.js	2021-06-28 17:55:12 UTC (rev 279343)
@@ -0,0 +1,26 @@
+let c = 0
+let a = 0
+
+for (let i = 0; i < 100000; ++i)
+{
+  let c = (i >= i + 1)
+  a = c ? 15 : 20
+}
+
+for (let i = 0; i < 100000; ++i)
+{
+  let c = (i > i + 1)
+  a = c ? 15 : 20
+}
+
+for (let i = 0; i < 100000; ++i)
+{
+  let c = (i <= i + 1)
+  a = c ? 15 : 20
+}
+
+for (let i = 0; i < 100000; ++i)
+{
+  let c = (i < i + 1)
+  a = c ? 15 : 20
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (279342 => 279343)


--- trunk/Source/_javascript_Core/ChangeLog	2021-06-28 17:41:25 UTC (rev 279342)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-06-28 17:55:12 UTC (rev 279343)
@@ -1,5 +1,34 @@
 2021-06-28  Mikhail R. Gadelha  <mikh...@igalia.com>
 
+        Add LLInt fast path for less, lesseq, greater and greatereq
+        https://bugs.webkit.org/show_bug.cgi?id=226266
+
+        Reviewed by Tadeu Zagallo.
+
+        The motivation is to add fast path for integers and doubles
+        in LLInt, so we don't need to go to slow path for those cases.
+
+        This patch implements the less, lesseq, greater, greatereq 
+        instruction for ARMv7, MIPS and CLoop.
+
+        Microbenchmarking results:
+        * x86_64: number-comparison-inline definitely 1.3520x faster
+        * ARMv7: number-comparison-inline definitely 1.3520x faster
+
+        JetStream2 results:
+        * x86_64 jit: 1.015 times better
+        * x86_64 no-jit: 1.018 times better
+        * ARMv7 no-jit: 1.004 times worse
+
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/arm.rb:
+        * offlineasm/cloop.rb:
+        * offlineasm/mips.rb:
+
+2021-06-28  Mikhail R. Gadelha  <mikh...@igalia.com>
+
         Prevent sign-extended casts for 32 bits arch
         https://bugs.webkit.org/show_bug.cgi?id=227170
 

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (279342 => 279343)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2021-06-28 17:41:25 UTC (rev 279342)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2021-06-28 17:55:12 UTC (rev 279343)
@@ -1998,8 +1998,6 @@
 slowPathOp(get_direct_pname)
 slowPathOp(get_enumerable_length)
 slowPathOp(get_property_enumerator)
-slowPathOp(greater)
-slowPathOp(greatereq)
 slowPathOp(has_enumerable_indexed_property)
 slowPathOp(has_enumerable_property)
 
@@ -2012,8 +2010,6 @@
 
 slowPathOp(is_callable)
 slowPathOp(is_constructor)
-slowPathOp(less)
-slowPathOp(lesseq)
 slowPathOp(mod)
 slowPathOp(new_array_buffer)
 slowPathOp(new_array_with_spread)
@@ -2112,7 +2108,22 @@
     # Truthy Cell
     macro (dispatch) dispatch() end)
 
+compareOp(greater, OpGreater,
+    macro (left, right, result) cigt left, right, result end,
+    macro (left, right, result) cdgt left, right, result end)
 
+compareOp(greatereq, OpGreatereq,
+    macro (left, right, result) cigteq left, right, result end,
+    macro (left, right, result) cdgteq left, right, result end)
+
+compareOp(less, OpLess,
+    macro (left, right, result) cilt left, right, result end,
+    macro (left, right, result) cdlt left, right, result end)
+
+compareOp(lesseq, OpLesseq,
+    macro (left, right, result) cilteq left, right, result end,
+    macro (left, right, result) cdlteq left, right, result end)
+
 compareJumpOp(
     jless, OpJless,
     macro (left, right, target) bilt left, right, target end,

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm (279342 => 279343)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm	2021-06-28 17:41:25 UTC (rev 279342)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm	2021-06-28 17:55:12 UTC (rev 279343)
@@ -1975,6 +1975,43 @@
 end
 
 
+macro compareOp(opcodeName, opcodeStruct, integerCompareAndSet, doubleCompareAndSet)
+    llintOpWithReturn(op_%opcodeName%, opcodeStruct, macro (size, get, dispatch, return)
+        get(m_lhs, t2)
+        get(m_rhs, t3)
+        loadConstantOrVariable(size, t2, t0, t1)
+        loadConstantOrVariable2Reg(size, t3, t2, t3)
+        bineq t0, Int32Tag, .op1NotInt
+        bineq t2, Int32Tag, .op2NotInt
+        integerCompareAndSet(t1, t3, t1)
+        return(BooleanTag, t1)
+
+    .op1NotInt:
+        bia t0, LowestTag, .slow
+        bib t2, LowestTag, .op1NotIntOp2Double
+        bineq t2, Int32Tag, .slow
+        ci2ds t3, ft1
+        jmp .op1NotIntReady
+    .op1NotIntOp2Double:
+        fii2d t3, t2, ft1
+    .op1NotIntReady:
+        fii2d t1, t0, ft0
+        doubleCompareAndSet(ft0, ft1, t1)
+        return(BooleanTag, t1)
+
+    .op2NotInt:
+        ci2ds t1, ft0
+        bia t2, LowestTag, .slow
+        fii2d t3, t2, ft1
+        doubleCompareAndSet(ft0, ft1, t1)
+        return(BooleanTag, t1)
+
+    .slow:
+        callSlowPath(_slow_path_%opcodeName%)
+        dispatch()
+    end)
+end
+
 macro compareUnsignedOp(opcodeName, opcodeStruct, integerCompareAndSet)
     llintOpWithReturn(op_%opcodeName%, opcodeStruct, macro (size, get, dispatch, return)
         get(m_rhs, t2)

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (279342 => 279343)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2021-06-28 17:41:25 UTC (rev 279342)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2021-06-28 17:55:12 UTC (rev 279343)
@@ -2160,6 +2160,52 @@
 end
 
 
+macro compareOp(opcodeName, opcodeStruct, integerCompareAndSet, doubleCompareAndSet)
+    llintOpWithReturn(op_%opcodeName%, opcodeStruct, macro (size, get, dispatch, return)
+        get(m_lhs, t2)
+        get(m_rhs, t0)
+        loadConstantOrVariable(size, t0, t1)
+        loadConstantOrVariable(size, t2, t0)
+        bqb t0, numberTag, .op1NotInt
+        bqb t1, numberTag, .op2NotInt
+        integerCompareAndSet(t0, t1, t0)
+        orq ValueFalse, t0
+        return(t0)
+
+    .op1NotInt:
+        btqz t0, numberTag, .slow
+        bqb t1, numberTag, .op1NotIntOp2NotInt
+        ci2ds t1, ft1
+        jmp .op1NotIntReady
+
+    .op1NotIntOp2NotInt:
+        btqz t1, numberTag, .slow
+        addq numberTag, t1
+        fq2d t1, ft1
+
+    .op1NotIntReady:
+        addq numberTag, t0
+        fq2d t0, ft0
+        doubleCompareAndSet(ft0, ft1, t0)
+        orq ValueFalse, t0
+        return(t0)
+
+    .op2NotInt:
+        ci2ds t0, ft0
+        btqz t1, numberTag, .slow
+        addq numberTag, t1
+        fq2d t1, ft1
+        doubleCompareAndSet(ft0, ft1, t0)
+        orq ValueFalse, t0
+        return(t0)
+
+    .slow:
+        callSlowPath(_slow_path_%opcodeName%)
+        dispatch()
+    end)
+end
+
+
 macro compareUnsignedOp(opcodeName, opcodeStruct, integerCompareAndSet)
     llintOpWithReturn(op_%opcodeName%, opcodeStruct, macro (size, get, dispatch, return)
         get(m_lhs, t2)

Modified: trunk/Source/_javascript_Core/offlineasm/arm.rb (279342 => 279343)


--- trunk/Source/_javascript_Core/offlineasm/arm.rb	2021-06-28 17:41:25 UTC (rev 279342)
+++ trunk/Source/_javascript_Core/offlineasm/arm.rb	2021-06-28 17:55:12 UTC (rev 279343)
@@ -374,6 +374,14 @@
     end
 end
 
+def emitArmDoubleCompare(operands, code)
+    $asm.puts "mov #{operands[2].armOperand}, \#0"
+    $asm.puts "vcmpe.f64 #{armOperands(operands[0..1])}"
+    $asm.puts "vmrs APSR_nzcv, FPSCR"
+    $asm.puts "it #{code}"
+    $asm.puts "mov#{code} #{operands[2].armOperand}, \#1"
+end
+
 def emitArmCompare(operands, code)
     $asm.puts "movs #{operands[2].armOperand}, \#0"
     $asm.puts "cmp #{operands[0].armOperand}, #{operands[1].armOperand}"
@@ -641,6 +649,14 @@
             emitArmCompare(operands, "lt")
         when "cilteq", "cplteq", "cblteq"
             emitArmCompare(operands, "le")
+        when "cdgt"
+            emitArmDoubleCompare(operands, "gt")
+        when "cdgteq"
+            emitArmDoubleCompare(operands, "ge")
+        when "cdlt"
+            emitArmDoubleCompare(operands, "mi")
+        when "cdlteq"
+            emitArmDoubleCompare(operands, "ls")
         when "tis", "tbs", "tps"
             emitArmTestSet(operands, "mi")
         when "tiz", "tbz", "tpz"

Modified: trunk/Source/_javascript_Core/offlineasm/cloop.rb (279342 => 279343)


--- trunk/Source/_javascript_Core/offlineasm/cloop.rb	2021-06-28 17:41:25 UTC (rev 279342)
+++ trunk/Source/_javascript_Core/offlineasm/cloop.rb	2021-06-28 17:55:12 UTC (rev 279343)
@@ -958,6 +958,8 @@
             cloopEmitCompareAndSet(operands, :int64, ">")
         when "cpgt"
             cloopEmitCompareAndSet(operands, :intptr, ">")
+        when "cdgt"
+            cloopEmitCompareAndSet(operands, :double, ">")
 
         when "cbgteq"
             cloopEmitCompareAndSet(operands, :int8, ">=")
@@ -967,6 +969,8 @@
             cloopEmitCompareAndSet(operands, :int64, ">=")
         when "cpgteq"
             cloopEmitCompareAndSet(operands, :intptr, ">=")
+        when "cdgteq"
+            cloopEmitCompareAndSet(operands, :double, ">=")
 
         when "cblt"
             cloopEmitCompareAndSet(operands, :int8, "<")
@@ -976,6 +980,8 @@
             cloopEmitCompareAndSet(operands, :int64, "<")
         when "cplt"
             cloopEmitCompareAndSet(operands, :intptr, "<")
+        when "cdlt"
+            cloopEmitCompareAndSet(operands, :double, "<")
 
         when "cblteq"
             cloopEmitCompareAndSet(operands, :int8, "<=")
@@ -985,6 +991,8 @@
             cloopEmitCompareAndSet(operands, :int64, "<=")
         when "cplteq"
             cloopEmitCompareAndSet(operands, :intptr, "<=")
+        when "cdlteq"
+            cloopEmitCompareAndSet(operands, :double, "<=")
 
         when "tbs"
             cloopEmitTestSet(operands, :int8, "< 0")

Modified: trunk/Source/_javascript_Core/offlineasm/mips.rb (279342 => 279343)


--- trunk/Source/_javascript_Core/offlineasm/mips.rb	2021-06-28 17:41:25 UTC (rev 279342)
+++ trunk/Source/_javascript_Core/offlineasm/mips.rb	2021-06-28 17:55:12 UTC (rev 279343)
@@ -807,6 +807,16 @@
     end
 end
 
+def emitMIPSDoubleCompare(branchOpcode, neg, operands)
+    mipsMoveImmediate(1, operands[2])
+    $asm.puts "c.#{branchOpcode}.d $fcc0, #{mipsOperands(operands[0..1])}"
+    if (!neg)
+        $asm.puts "movf #{operands[2].mipsOperand}, $zero, $fcc0"
+    else
+        $asm.puts "movt #{operands[2].mipsOperand}, $zero, $fcc0"
+    end
+end
+
 def emitMIPSDoubleBranch(branchOpcode, neg, operands)
     $asm.puts "c.#{branchOpcode}.d #{mipsOperands(operands[0..1])}"
     if (!neg)
@@ -1011,6 +1021,14 @@
         when "cilteq", "cplteq", "cblteq"
             $asm.puts "slt #{operands[2].mipsOperand}, #{operands[1].mipsOperand}, #{operands[0].mipsOperand}"
             $asm.puts "xori #{operands[2].mipsOperand}, 1"
+        when "cdgt"
+            emitMIPSDoubleCompare("ule", true, operands)
+        when "cdgteq"
+            emitMIPSDoubleCompare("ult", true, operands)
+        when "cdlt"
+            emitMIPSDoubleCompare("olt", false, operands)
+        when "cdlteq"
+            emitMIPSDoubleCompare("ole", false, operands)
         when "peek"
             $asm.puts "lw #{operands[1].mipsOperand}, #{operands[0].value * 4}($sp)"
         when "poke"
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to