LibJS: Optimize x >> 0 to ToInt32 in bytecode codegen
x >> 0 is a common JS idiom equivalent to ToInt32(x). We already had this optimization for x | 0, now do it for right shift by zero as well. This allows the asmint handler for ToInt32 to run instead of the more expensive RightShift handler, which wastes time loading and checking the rhs operand and performing a shift by zero.
This commit is contained in:
parent
02b0746676
commit
bb0acb54ae
3 changed files with 52 additions and 5 deletions
|
|
@ -2077,11 +2077,29 @@ fn emit_binary_op(
|
|||
lhs: lhs_op,
|
||||
rhs: rhs_op,
|
||||
}),
|
||||
BinaryOp::RightShift => generator.emit(Instruction::RightShift {
|
||||
dst: dst_op,
|
||||
lhs: lhs_op,
|
||||
rhs: rhs_op,
|
||||
}),
|
||||
BinaryOp::RightShift => {
|
||||
// OPTIMIZATION: x >> 0 == ToInt32(x) (matches C++)
|
||||
if let Some(ConstantValue::Number(n)) = generator.get_constant(rhs) {
|
||||
if *n == 0.0 && n.is_sign_positive() {
|
||||
generator.emit(Instruction::ToInt32 {
|
||||
dst: dst_op,
|
||||
value: lhs_op,
|
||||
});
|
||||
} else {
|
||||
generator.emit(Instruction::RightShift {
|
||||
dst: dst_op,
|
||||
lhs: lhs_op,
|
||||
rhs: rhs_op,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
generator.emit(Instruction::RightShift {
|
||||
dst: dst_op,
|
||||
lhs: lhs_op,
|
||||
rhs: rhs_op,
|
||||
});
|
||||
}
|
||||
}
|
||||
BinaryOp::UnsignedRightShift => generator.emit(Instruction::UnsignedRightShift {
|
||||
dst: dst_op,
|
||||
lhs: lhs_op,
|
||||
|
|
|
|||
24
Tests/LibJS/Bytecode/expected/right-shift-by-zero.txt
Normal file
24
Tests/LibJS/Bytecode/expected/right-shift-by-zero.txt
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
$a08063d8 right-shift-by-zero.js:5:1
|
||||
Registers: 7
|
||||
Blocks: 1
|
||||
Constants:
|
||||
[0] = Undefined
|
||||
[1] = Double(1.5)
|
||||
|
||||
block0:
|
||||
[ 0] GetLexicalEnvironment dst:reg4
|
||||
[ 8] GetGlobal dst:reg6, `foo`
|
||||
[ 20] Call dst:reg5, callee:reg6, this_value:Undefined, foo, arguments:[Double(1.5)]
|
||||
[ 48] End value:reg5
|
||||
|
||||
|
||||
foo$197906fe right-shift-by-zero.js:2:5
|
||||
Registers: 6
|
||||
Blocks: 1
|
||||
Constants:
|
||||
[0] = Int32(0)
|
||||
|
||||
block0:
|
||||
[ 0] GetLexicalEnvironment dst:reg4
|
||||
[ 8] ToInt32 dst:reg5, value:arg0
|
||||
[ 18] Return value:reg5
|
||||
5
Tests/LibJS/Bytecode/input/right-shift-by-zero.js
Normal file
5
Tests/LibJS/Bytecode/input/right-shift-by-zero.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
function foo(x) {
|
||||
return x >> 0;
|
||||
}
|
||||
|
||||
foo(1.5);
|
||||
Loading…
Reference in a new issue