Optimise MPow for Int32 values
Categories
(Core :: JavaScript Engine: JIT, enhancement, P1)
Tracking
()
People
(Reporter: anba, Assigned: anba)
References
Details
Attachments
(4 files, 1 obsolete file)
(deleted),
text/x-phabricator-request
|
Details | |
Bug 1564942 - Part 2: Avoid negative zero check when the base operand in MPow is an Int32. r=jandem!
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details |
MPow with an Int32 base-operand (and an Int32 power-operand) is implemented as MToNumberInt32(MPow(MToDouble(int32), int32))
which makes it slower than an exponentiation with a Double base-operand. That means implementing Int32 specialisations for JSOP_POW
(bug 1188079) will currently lead to a performance degradation, because JSOP_POW
currently always uses the Double base-operand version.
Example:
function f() {
// Math.pow(int, int) -> int: 580ms
// Math.pow(double, int) -> double: 435ms
// With patches:
// Math.pow(int, int) -> int: 340ms
// For comparison:
// int**int -> int: 450ms
// double**int -> double: 435ms
// Int32 operand.
// var xs = [2, 2];
// Double operand.
var xs = [2.1, 2.1];
var ys = [3, 3];
var q = 0;
var t = dateNow();
for (var i = 0; i < 50000000; ++i) {
var x = xs[i & 1];
var y = ys[i & 1];
// q += x ** y;
q += Math.pow(x, y);
}
print(dateNow() - t, q);
}
Assignee | ||
Comment 1•5 years ago
|
||
Assignee | ||
Comment 2•5 years ago
|
||
That way the trailing DoubleToInt32 doesn't emit the negative zero check sequence:
movq %xmm0, %rax
cmpq $0x1, %rax
jo .Lfrom0000
Depends on D37583
Assignee | ||
Comment 3•5 years ago
|
||
Instead of computing pow(int32, int32) -> int32
as MToNumberInt32(MPow(MToDouble(int32), int32))
directly exponentiate both operands in the Int32 space by adding LPowII which inlines
js::powi(double, int)
.
When MPow is used with a constant power which can be folded to MMul, this change will lead to
better codegen, too. For example Math.pow(x, 2)
where x
is an Int32 value, currently generates
the following assembly:
# instruction Int32ToDouble
xorpd %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
# instruction MathD:mul
mulsd %xmm0, %xmm0
# instruction DoubleToInt32
cvttsd2si %xmm0, %eax
xorpd %xmm15, %xmm15
cvtsi2sd %eax, %xmm15
ucomisd %xmm15, %xmm0
jp .Lfrom0000
jne .Lfrom0000
With this patch, this assembly will be generated:
# instruction MoveGroup
movl %eax, %ecx
# instruction MulI
imull %ecx, %eax
jo .Lfrom0000
Depends on D37584
Assignee | ||
Comment 4•5 years ago
|
||
Similar to LIRGeneratorX86Shared::lowerForALU
, try to use the same register when multiplying an
operand with itself.
This change improves the generated assembly for Math.pow(x, 2)
from:
# instruction MoveGroup
movl %eax, %ecx
# instruction MulI
imull %ecx, %eax
jo .Lfrom0000
to:
# instruction MulI
imull %eax, %eax
jo .Lfrom0000
Depends on D37585
Assignee | ||
Comment 5•5 years ago
|
||
In-tree users of Math.pow
show that the function is often called with the base operand equal to
two. This case can easily be optimised to a series of shift-instructions for any power of two. For
now this optimisation is only taken for 2^i with i in {1..8} to avoid generating too many
consecutive shift-instructions. 2^8 = 256 was chosen as the limit, because it is the maximum power
of two base operand for Math.pow
used in-tree.
Depends on D37586
Updated•5 years ago
|
Comment 6•4 years ago
|
||
Landing of part 1 and 2 failed due to:
"applying /tmp/tmp1iTtSV
js/src/jit/MIR.cpp
Hunk #1 FAILED at 3003.
Hunk #2 FAILED at 3014.
2 out of 3 hunks FAILED -- saving rejects to file js/src/jit/MIR.cpp.rej"
:anba can you please take a look?
Updated•4 years ago
|
Updated•4 years ago
|
Updated•4 years ago
|
Assignee | ||
Updated•4 years ago
|
Comment 8•4 years ago
|
||
Backed out 4 changesets (Bug 1564942) for causing SM bustage in pow-base-power-of-two.js CLOSED TREE
Failure log: https://treeherder.mozilla.org/logviewer.html#/jobs?job_id=305661284&repo=autoland&lineNumber=36022
Backout: https://hg.mozilla.org/integration/autoland/rev/b2df79a80c0303df9d710800ae37dce56847eef5
Assignee | ||
Comment 9•4 years ago
|
||
std::pow
is off by one ULP on Windows, which needs to be taken into account for the test case...
Comment 10•4 years ago
|
||
Comment 11•4 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/5b9343de266b
https://hg.mozilla.org/mozilla-central/rev/bfc836af8677
https://hg.mozilla.org/mozilla-central/rev/7765391a4142
https://hg.mozilla.org/mozilla-central/rev/796d8685f8ce
Updated•4 years ago
|
Description
•