RESOLVED FIXED Bug 192664
[BigInt] Add ValueBitLShift into DFG
https://bugs.webkit.org/show_bug.cgi?id=192664
Summary [BigInt] Add ValueBitLShift into DFG
Caio Lima
Reported 2018-12-13 04:35:32 PST
...
Attachments
WIP - Patch (30.19 KB, patch)
2018-12-30 07:41 PST, Caio Lima
no flags
Benchmarks (94.51 KB, text/plain)
2018-12-30 07:44 PST, Caio Lima
no flags
Patch (31.20 KB, patch)
2019-01-16 09:30 PST, Caio Lima
no flags
Benchmarks (93.85 KB, text/plain)
2019-01-16 09:32 PST, Caio Lima
no flags
Patch (31.02 KB, patch)
2019-01-19 06:17 PST, Caio Lima
no flags
Patch (41.51 KB, patch)
2019-01-23 17:34 PST, Caio Lima
no flags
Patch (41.17 KB, patch)
2019-01-24 06:34 PST, Caio Lima
no flags
Patch (41.12 KB, patch)
2019-02-01 18:05 PST, Caio Lima
no flags
Patch (41.08 KB, patch)
2019-02-17 15:02 PST, Caio Lima
no flags
Patch (39.58 KB, patch)
2019-03-17 18:52 PDT, Caio Lima
no flags
Patch (39.53 KB, patch)
2019-06-16 17:52 PDT, Caio Lima
no flags
Patch (39.56 KB, patch)
2019-06-17 04:26 PDT, Caio Lima
no flags
Patch (35.69 KB, patch)
2019-07-09 12:14 PDT, Caio Lima
no flags
Patch (40.06 KB, patch)
2019-07-10 09:28 PDT, Caio Lima
no flags
Benchmarks (97.21 KB, text/plain)
2019-07-10 09:30 PDT, Caio Lima
no flags
Patch (40.42 KB, patch)
2019-07-12 06:03 PDT, Caio Lima
no flags
Caio Lima
Comment 1 2018-12-30 07:41:33 PST
Created attachment 358148 [details] WIP - Patch
Caio Lima
Comment 2 2018-12-30 07:44:00 PST
Created attachment 358149 [details] Benchmarks This change is perf neutral on x86_64 macOS build.
Yusuke Suzuki
Comment 3 2018-12-30 11:44:59 PST
Comment on attachment 358148 [details] WIP - Patch View in context: https://bugs.webkit.org/attachment.cgi?id=358148&action=review quick review. The direction looks really nice. Please make the code consistent with the existing bit operations :) > Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp:123 > + case ValueBitLShift: Is it correct? If it is correct, why aren't ValueBitOr and ValueBitXor included? > Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp:223 > + case ValueBitLShift: Ditto. > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:3439 > // We can use a BitLShift here because typed arrays will never have a byteLength Change this to `ArithBitLShift`. > Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:220 > + if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) { > + fixEdge<UntypedUse>(node->child1()); > + fixEdge<UntypedUse>(node->child2()); > + break; > + } > + > + node->setOp(ArithBitLShift); > + node->clearFlags(NodeMustGenerate); > + node->setResult(NodeResultInt32); > + fixIntConvertingEdge(node->child1()); > + fixIntConvertingEdge(node->child2()); > + break; > + } I'm not sure why this is separated from ValueBitXor, ValueBitOr and ValueBitAnd. This checks shouldSpeculateUntypedForBitOps. But ValueBitXor, ValueBitOr and ValueBitAnd do not.
Caio Lima
Comment 4 2018-12-30 14:54:48 PST
(In reply to Yusuke Suzuki from comment #3) > Comment on attachment 358148 [details] > WIP - Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=358148&action=review > > quick review. The direction looks really nice. Please make the code > consistent with the existing bit operations :) Thx for the review! This is the goal. I'm thinking in handle other BitOps into https://bugs.webkit.org/show_bug.cgi?id=192966 > > Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp:123 > > + case ValueBitLShift: > > Is it correct? If it is correct, why aren't ValueBitOr and ValueBitXor > included? > > > Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp:223 > > + case ValueBitLShift: > > Ditto. > > > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:3439 > > // We can use a BitLShift here because typed arrays will never have a byteLength > > Change this to `ArithBitLShift`. > > > Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:220 > > + if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) { > > + fixEdge<UntypedUse>(node->child1()); > > + fixEdge<UntypedUse>(node->child2()); > > + break; > > + } > > + > > + node->setOp(ArithBitLShift); > > + node->clearFlags(NodeMustGenerate); > > + node->setResult(NodeResultInt32); > > + fixIntConvertingEdge(node->child1()); > > + fixIntConvertingEdge(node->child2()); > > + break; > > + } > > I'm not sure why this is separated from ValueBitXor, ValueBitOr and > ValueBitAnd. > This checks shouldSpeculateUntypedForBitOps. But ValueBitXor, ValueBitOr and > ValueBitAnd do not. Ditto.
Caio Lima
Comment 5 2019-01-16 09:30:18 PST
Caio Lima
Comment 6 2019-01-16 09:32:32 PST
Created attachment 359272 [details] Benchmarks These changes seems to be perf neutral on macOS x86_ 64
Caio Lima
Comment 7 2019-01-19 06:17:28 PST
Saam Barati
Comment 8 2019-01-20 14:46:58 PST
Comment on attachment 359605 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=359605&action=review > Source/JavaScriptCore/dfg/DFGDoesGC.cpp:103 > + case ValueBitLShift: same comment as I've written in other bugs. Should return true if BigIntUse.
Caio Lima
Comment 9 2019-01-23 17:34:00 PST
Caio Lima
Comment 10 2019-01-24 06:34:10 PST
Caio Lima
Comment 11 2019-02-01 18:05:30 PST
Caio Lima
Comment 12 2019-02-17 15:02:32 PST
Caio Lima
Comment 13 2019-03-17 18:52:48 PDT
Caio Lima
Comment 14 2019-06-16 17:52:04 PDT
EWS Watchlist
Comment 15 2019-06-16 19:55:43 PDT
Comment on attachment 372229 [details] Patch Attachment 372229 [details] did not pass jsc-ews (mac): Output: https://webkit-queues.webkit.org/results/12493738 New failing tests: stress/urshift-int32-overflow.js.ftl-no-cjit-b3o0 stress/urshift-int32-overflow.js.bytecode-cache stress/urshift-int32-overflow.js.ftl-no-cjit-small-pool stress/urshift-int32-overflow.js.ftl-no-cjit-no-put-stack-validate stress/urshift-int32-overflow.js.ftl-eager-no-cjit-b3o1 stress/urshift-int32-overflow.js.ftl-no-cjit-validate-sampling-profiler stress/urshift-int32-overflow.js.ftl-eager stress/urshift-int32-overflow.js.ftl-eager-no-cjit stress/urshift-int32-overflow.js.ftl-no-cjit-no-inline-validate stress/urshift-int32-overflow.js.default apiTests
Caio Lima
Comment 16 2019-06-17 04:26:12 PDT
Caio Lima
Comment 17 2019-06-25 11:09:19 PDT
Ping Review
Caio Lima
Comment 18 2019-06-27 12:43:42 PDT
Ping Review.
Keith Miller
Comment 19 2019-06-28 11:32:29 PDT
Comment on attachment 372240 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=372240&action=review > Source/JavaScriptCore/ChangeLog:15 > + not using `getHeapPrediction()` during prediction propagation, because > + it causes performance regression on Octane's zlib and mandreel. Why does this cause a regression?
Caio Lima
Comment 20 2019-06-28 13:15:15 PDT
(In reply to Keith Miller from comment #19) > Comment on attachment 372240 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=372240&action=review > > > Source/JavaScriptCore/ChangeLog:15 > > + not using `getHeapPrediction()` during prediction propagation, because > > + it causes performance regression on Octane's zlib and mandreel. > > Why does this cause a regression? The problem is when we use getPrediction() to populate “getHeapTopPrediction()” and the instruction was never executed before, we emit a ForceOSRExit. It means that the program will have more OSRExits than desired. Such case seems to be very common for those benchmarks. Another option would be to use getPredictionWithoutOSR(), but in this case we will have Untyped as the prediction for instructions never executed. This means that we will stop the prediction propagation for those instructions and will emit ValueBitLShift in cases where it would totally possible to speculate Int32 or other types. IIRC, the best approach is then use the instruction inputs to propagate the predictions.
Caio Lima
Comment 21 2019-07-02 13:54:24 PDT
Ping
Saam Barati
Comment 22 2019-07-09 09:51:25 PDT
Comment on attachment 372240 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=372240&action=review > Source/JavaScriptCore/bytecode/BytecodeList.rb:263 > + :lshift, Where are you actually using the value profile? > Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:182 > + case ValueBitLShift: { Did you mean to make this just use the value profile? > Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:190 > + else if (isFullNumberOrBooleanSpeculationExpectingDefined(left) && isFullNumberOrBooleanSpeculationExpectingDefined(right)) > + changed |= mergePrediction(SpecInt32Only); shouldn't this just be something like: if ((!left & SpecBigInt) && !(right & SpecBigInt)) Since this will always return int32 unless the input might be BigInt? Or maybe ValueOf allows you to return BigInt and therefore I'm wrong?
Caio Lima
Comment 23 2019-07-09 11:11:54 PDT
Thx a lot for the feedback. (In reply to Saam Barati from comment #22) > Comment on attachment 372240 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=372240&action=review > > > Source/JavaScriptCore/bytecode/BytecodeList.rb:263 > > + :lshift, > > Where are you actually using the value profile? IIRC, the idea of keeping ValueProfile on this instruction was to get predictions injected during PredictionInjectionPhase and potentially making `PredictionPropagationPhase` converge in less iterations. However, I think the predictions are never injected for those nodes. Even though, leaving this profiler there don't make much sense anymore and I think we should remove it. > > Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:182 > > + case ValueBitLShift: { > > Did you mean to make this just use the value profile? Since this version gave up on using getHeapTopPrediction(), I don't think we need to have ValueProfile anymore. > > Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:190 > > + else if (isFullNumberOrBooleanSpeculationExpectingDefined(left) && isFullNumberOrBooleanSpeculationExpectingDefined(right)) > > + changed |= mergePrediction(SpecInt32Only); > > shouldn't this just be something like: > if ((!left & SpecBigInt) && !(right & SpecBigInt)) > > Since this will always return int32 unless the input might be BigInt? Or > maybe ValueOf allows you to return BigInt and therefore I'm wrong? Yes, `valueOf` can return BigInt and, as you mentioned, `if ((!left & SpecBigInt) && !(right & SpecBigInt))` don't catch those cases.
Caio Lima
Comment 24 2019-07-09 12:14:51 PDT
Caio Lima
Comment 25 2019-07-09 12:16:20 PDT
(In reply to Caio Lima from comment #24) > Created attachment 373741 [details] > Patch In this Patch I removed the ValueProfile of ValueBitLShift and also added a test case to cover when BigInt can be a return of a `valueOf` method.
Saam Barati
Comment 26 2019-07-09 16:34:37 PDT
Comment on attachment 373741 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=373741&action=review > Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:192 > + else > + changed |= mergePrediction(SpecBigInt | SpecInt32Only); btw, this is where the value profile would help you out. You could make this mergePrediction(getHeapPrediction())
Caio Lima
Comment 27 2019-07-10 09:28:17 PDT
Caio Lima
Comment 28 2019-07-10 09:30:46 PDT
Created attachment 373841 [details] Benchmarks Benchmark results for the new version of the Patch. Perf looks neutral.
Caio Lima
Comment 29 2019-07-10 13:20:20 PDT
(In reply to Saam Barati from comment #26) > Comment on attachment 373741 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=373741&action=review > > > Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:192 > > + else > > + changed |= mergePrediction(SpecBigInt | SpecInt32Only); > > btw, this is where the value profile would help you out. You could make this > mergePrediction(getHeapPrediction()) Thx a lot for this advice! I uploaded a new version using this idea and there is no performance regression on last report.
Saam Barati
Comment 30 2019-07-11 12:20:29 PDT
Comment on attachment 373840 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=373840&action=review > Source/JavaScriptCore/ChangeLog:14 > + not using `getHeapPrediction()` during prediction propagation, because not true anymore
Caio Lima
Comment 31 2019-07-12 06:03:45 PDT
WebKit Commit Bot
Comment 32 2019-07-12 07:47:43 PDT
Comment on attachment 374006 [details] Patch Clearing flags on attachment: 374006 Committed r247387: <https://trac.webkit.org/changeset/247387>
WebKit Commit Bot
Comment 33 2019-07-12 07:47:45 PDT
All reviewed patches have been landed. Closing bug.
Radar WebKit Bug Importer
Comment 34 2019-07-12 07:48:27 PDT
Caio Lima
Comment 35 2019-07-12 07:49:00 PDT
(In reply to Saam Barati from comment #30) > Comment on attachment 373840 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=373840&action=review > > > Source/JavaScriptCore/ChangeLog:14 > > + not using `getHeapPrediction()` during prediction propagation, because > > not true anymore Thx a lot for the reviews!
Note You need to log in before you can comment on or make changes to this bug.