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"