Skip to content

Add JIT-time array map lookup inline optimization#46

Merged
yunwei37 merged 1 commit intomainfrom
array-map-inline-poc
Mar 13, 2026
Merged

Add JIT-time array map lookup inline optimization#46
yunwei37 merged 1 commit intomainfrom
array-map-inline-poc

Conversation

@yunwei37
Copy link
Copy Markdown
Member

Summary

  • JIT-time inline optimization for bpf_map_lookup_elem on array maps. When a BPF program calls helper-1 (bpf_map_lookup_elem) with a constant map handle that has been registered as an array map, the JIT rewrites the call into direct address arithmetic — eliminating the helper call entirely.
  • New register_array_map() API lets the host register an array map's metadata (fd/handle, max_entries, value_size, and data base pointer) before JIT compilation. During the LLVM IR rewrite pass, calls to _bpf_helper_ext_0001 where arg0 matches a registered handle are replaced with an inline bounds-check and pointer computation: key < max_entries ? base + key * value_size : nullptr.
  • Result: 1.30x speedup — execution time drops from 7.51 ns to 5.77 ns per iteration on an array-map-lookup micro-benchmark. Helper calls go from 10M to 0 (verified via bpf_get_helper_call_count()).
  • Limitations: JIT path only (not AOT), helper-1 only, array maps only, key_size == 4, constant map handle only. Does not cover per-CPU array maps or hash maps.

Changed files (7 files, +445 lines)

File Change
include/llvmbpf.hpp New register_array_map() public API on llvmbpf_vm
src/vm.cpp Stores array map metadata, passes to JIT context
src/llvm_jit_context.cpp LLVM IR rewrite: scan for helper-1 calls, replace with inline arithmetic
src/llvm_jit_context.hpp Internal struct for array map info
example/array_map_inline_bench.cpp End-to-end benchmark (10M iterations, before/after comparison)
example/CMakeLists.txt Build target for the benchmark
test/unit-test/vm_test.cpp Unit test verifying inline correctness and zero helper calls

Test plan

  • Unit test (vm_test.cpp): verify that exec() returns the correct looked-up value and bpf_get_helper_call_count() reports 0 helper-1 calls after inlining
  • Benchmark (array_map_inline_bench.cpp): run ./build/example/array_map_inline_bench and confirm ~1.3x speedup vs baseline (no inline)
  • Build: cmake --build build -j succeeds with no warnings on the new files
  • Existing tests: ctest --test-dir build passes (no regressions)

🤖 Generated with Claude Code

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 12, 2026

Codecov Report

❌ Patch coverage is 79.56989% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.47%. Comparing base (f037a7e) to head (7f19854).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/vm.cpp 50.00% 10 Missing ⚠️
src/llvm_jit_context.cpp 87.67% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #46      +/-   ##
==========================================
+ Coverage   74.12%   74.47%   +0.35%     
==========================================
  Files           5        5              
  Lines        1341     1434      +93     
  Branches      153      176      +23     
==========================================
+ Hits          994     1068      +74     
- Misses        347      366      +19     
Flag Coverage Δ
bpf_conformance 55.61% <4.30%> (-3.71%) ⬇️
spirv_opencl 36.48% <4.30%> (-2.27%) ⬇️
unittests 50.97% <79.56%> (+2.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

optimizeModule(M, vm.optimization_level, vm.disabled_passes_,
vm.log_passes_);
if (inline_array_map_lookup_helpers(M)) {
optimizeModule(M, vm.optimization_level,
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.

Why calling optimizeModule two times?

@yunwei37 yunwei37 merged commit 7f19854 into main Mar 13, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants