Skip to content

Optimize BBQ for runs of jump targets in br.table - #31786

Open
danlliu wants to merge 1 commit into
WebKit:mainfrom
danlliu:eng/Optimize-BBQ-for-runs-of-jump-targets-in-br-table
Open

Optimize BBQ for runs of jump targets in br.table#31786
danlliu wants to merge 1 commit into
WebKit:mainfrom
danlliu:eng/Optimize-BBQ-for-runs-of-jump-targets-in-br-table

Conversation

@danlliu

@danlliu danlliu commented Aug 6, 2024

Copy link
Copy Markdown
Contributor

d39f470

Optimize BBQ for runs of jump targets in `br.table`
https://bugs.webkit.org/show_bug.cgi?id=277686
rdar://133300128

Reviewed by NOBODY (OOPS!).

Previously, BBQ generated an entire binary search for every possible case in a `br.table`,
even if we had long consecutive runs that could avoid many comparisons. This patch
optimizes `br.table` generation to reduce the tree depth when it is possible.

* Source/JavaScriptCore/jit/BinarySwitch.cpp:
(JSC::BinarySwitch::BinarySwitch):
(JSC::BinarySwitch::advance):
(JSC::BinarySwitch::buildCheckRuns):
(JSC::BinarySwitch::BranchCode::dump const):
* Source/JavaScriptCore/jit/BinarySwitch.h:
(JSC::BinarySwitch::BranchCode::BranchCode):
* Source/JavaScriptCore/wasm/WasmBBQJIT.cpp:
(JSC::Wasm::BBQJITImpl::BBQJIT::addSwitch):

d39f470

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows
❌ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 wincairo
✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ✅ 🧪 wincairo-tests
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe
✅ 🧪 ios-wk2-wpt ✅ 🧪 mac-wk1 ✅ 🛠 wpe-cairo
✅ 🛠 🧪 jsc ✅ 🧪 api-ios ✅ 🧪 mac-wk2 ✅ 🛠 gtk
✅ 🛠 🧪 jsc-arm64 ✅ 🛠 vision ❌ 🧪 mac-AS-debug-wk2 ✅ 🧪 gtk-wk2
✅ 🛠 vision-sim ✅ 🧪 mac-wk2-stress ✅ 🧪 api-gtk
✅ 🧪 vision-wk2 ✅ 🛠 jsc-armv7
✅ 🛠 tv ✅ 🧪 jsc-armv7-tests
✅ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

@danlliu
danlliu requested a review from a team as a code owner August 6, 2024 16:14
@danlliu danlliu self-assigned this Aug 6, 2024
@danlliu danlliu added the JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues. label Aug 6, 2024

@kmiller68 kmiller68 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should integrate this into BinarySwitch rather than add a new class. That could be done by adding a new constructor if needed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whitespace change seems wrong.

Comment on lines 177 to 193

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could just be out.print(kind);

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Aug 6, 2024
@danlliu danlliu removed the merging-blocked Applied to prevent a change from being merged label Aug 6, 2024
@danlliu
danlliu force-pushed the eng/Optimize-BBQ-for-runs-of-jump-targets-in-br-table branch from 707c838 to 8c5b442 Compare August 6, 2024 18:51
https://bugs.webkit.org/show_bug.cgi?id=277686
rdar://133300128

Reviewed by NOBODY (OOPS!).

Previously, BBQ generated an entire binary search for every possible case in a `br.table`,
even if we had long consecutive runs that could avoid many comparisons. This patch
optimizes `br.table` generation to reduce the tree depth when it is possible.

* Source/JavaScriptCore/jit/BinarySwitch.cpp:
(JSC::BinarySwitch::BinarySwitch):
(JSC::BinarySwitch::advance):
(JSC::BinarySwitch::buildCheckRuns):
(JSC::BinarySwitch::BranchCode::dump const):
* Source/JavaScriptCore/jit/BinarySwitch.h:
(JSC::BinarySwitch::BranchCode::BranchCode):
* Source/JavaScriptCore/wasm/WasmBBQJIT.cpp:
(JSC::Wasm::BBQJITImpl::BBQJIT::addSwitch):
@danlliu
danlliu force-pushed the eng/Optimize-BBQ-for-runs-of-jump-targets-in-br-table branch from 8c5b442 to d39f470 Compare August 6, 2024 20:54
while (wasmSwitch.advance(m_jit)) {
unsigned value = wasmSwitch.caseValue();
unsigned index = wasmSwitch.caseIndex();
UNUSED_VARIABLE(value);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove value?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, just get rid of value

m_cases.append(Case(cases[i], i));

std::sort(m_cases.begin(), m_cases.end());
if (type == Int32 || type == IntPtr) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I would add a isCheckRuns() and use that.

while (wasmSwitch.advance(m_jit)) {
unsigned value = wasmSwitch.caseValue();
unsigned index = wasmSwitch.caseIndex();
UNUSED_VARIABLE(value);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, just get rid of value

#endif
build(0, false, m_cases.size());
} else {
m_cases.reserveInitialCapacity(cases.size());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cases are expected to be sorted right? Can we add an ASSERT?

@kmiller68
kmiller68 self-requested a review August 6, 2024 22:36
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Aug 6, 2024
@chicoxyzzy

Copy link
Copy Markdown
Member

Sorry for the noise, I didn’t notice this PR when I picked up the bug. It was unassigned on Bugzilla and I only saw the open work after I had already opened a new patch.

I posted a separate attempt here: #69487

At a high level it tries the same optimization (collapse runs of the same br.table target into a shallower BinarySwitch), with a few differences:

  • only consecutive same targets (no remapping of non-adjacent ones)
  • unsigned range checks for the run tree
  • jump table vs binary based on run count rather than raw table size
  • a small stress test

Happy to close #69487 if you’d rather continue this one, help review / contribute to this PR, or fold any of those bits in here if useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues. merging-blocked Applied to prevent a change from being merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants