Skip to content

[XLS JIT] Improve LLVM IR codegen for partitions, temporaries, literals, and selects - #5164

Closed
copybara-service[bot] wants to merge 1 commit into
mainfrom
test_1001458076
Closed

copybara-service[bot] wants to merge 1 commit into
mainfrom
test_1001458076

Conversation

@copybara-service

Copy link
Copy Markdown

[XLS JIT] Improve LLVM IR codegen for partitions, temporaries, literals, and selects

Improve XLS JIT/AOT LLVM IR lowering in //xls/jit so that LLVM can inline and discard helper partitions, promote cross-partition temporaries to SSA registers, place constant literal tables in .rodata, and lower bit-level selects and boolean trees without control-flow branches or byte-padding masks:

  1. Private partition functions and stack-promoted cross-partition temporaries: Mark partition functions (__<fn>_partition_<i>) with PrivateLinkage so LLVM discards standalone partition bodies once inlined into the entry function. Emit typed inbounds GEPs in GetOffsetIntoTempBuffer (instead of ptrtoint/add/inttoptr) and allocate a local stack alloca (local_temp_buffer, capped at kMaxLocalTempBufferBytes = 32 KiB) when a function has no early-exit/resume points (such as blocking proc receives/sends that require temp_buffer state to persist across invocations). This allows LLVM's SROA and dead-store elimination to promote cross-partition temporaries directly to SSA registers.
  2. Read-only module-level constant globals for aggregate literals: Materialize all Literal nodes at their uses (ShouldMaterializeAtUse) and emit private unnamed_addr constant globals (CodeModel::Small) in NodeIrContext::GetOperandPtr (as well as on trace/assert string globals, with Cold on assertion failure calls) instead of re-initializing stack alloca buffers at runtime on every call.
  3. SSA select lowering and i1 balanced reduction trees: Lower Bits-typed sel, priority_sel, and one_hot_sel directly in SSA registers (CreateSelect/CreateAnd/CreateOr) instead of emitting per-case basic-block branches (OrInPlace) or pointer-level select + memcpy. Truncate 1-bit (bits[1]) values in bit_slice, not, concat, n-ary bitwise ops, and one_hot_sel to i1 in SSA registers and reduce concat, n-ary ops, and one_hot_sel with a balanced binary tree (TreeReduce) so expression depth stays $O(\log N)$ within LLVM's SimplifyDemandedBits recursion limit (MaxAnalysisRecursionDepth = 6).

Runtime and Memory Performance Impact:

  • CPU Runtime: Strictly faster for JIT and AOT-compiled XLS functions: eliminates per-invocation stack initialization of constant lookup tables, removes per-bit conditional branch mispredictions in one_hot_sel, folds 1-bit one_hot_sel chains into straight-line bitwise and/or instructions instead of cmovs, and eliminates memory round-trips through temp_buffer.
  • Memory Usage: Zero heap overhead; cross-partition temporaries are promoted to registers (bounded by 32 KiB stack alloca prior to SROA), and aggregate literal tables are deduplicated in .rodata.

…ls, and selects

Improve XLS JIT/AOT LLVM IR lowering in `//xls/jit` so that LLVM can inline and discard helper partitions, promote cross-partition temporaries to SSA registers, place constant literal tables in `.rodata`, and lower bit-level selects and boolean trees without control-flow branches or byte-padding masks:

1. **Private partition functions and stack-promoted cross-partition temporaries**: Mark partition functions (`__<fn>_partition_<i>`) with `PrivateLinkage` so LLVM discards standalone partition bodies once inlined into the entry function. Emit typed `inbounds` GEPs in `GetOffsetIntoTempBuffer` (instead of `ptrtoint`/`add`/`inttoptr`) and allocate a local stack `alloca` (`local_temp_buffer`, capped at `kMaxLocalTempBufferBytes = 32 KiB`) when a function has no early-exit/resume points (such as blocking proc receives/sends that require `temp_buffer` state to persist across invocations). This allows LLVM's SROA and dead-store elimination to promote cross-partition temporaries directly to SSA registers.
2. **Read-only module-level constant globals for aggregate literals**: Materialize all `Literal` nodes at their uses (`ShouldMaterializeAtUse`) and emit `private unnamed_addr constant` globals (`CodeModel::Small`) in `NodeIrContext::GetOperandPtr` (as well as on trace/assert string globals, with `Cold` on assertion failure calls) instead of re-initializing stack `alloca` buffers at runtime on every call.
3. **SSA select lowering and `i1` balanced reduction trees**: Lower `Bits`-typed `sel`, `priority_sel`, and `one_hot_sel` directly in SSA registers (`CreateSelect`/`CreateAnd`/`CreateOr`) instead of emitting per-case basic-block branches (`OrInPlace`) or pointer-level `select` + `memcpy`. Truncate 1-bit (`bits[1]`) values in `bit_slice`, `not`, `concat`, n-ary bitwise ops, and `one_hot_sel` to `i1` in SSA registers and reduce `concat`, n-ary ops, and `one_hot_sel` with a balanced binary tree (`TreeReduce`) so expression depth stays $O(\log N)$ within LLVM's `SimplifyDemandedBits` recursion limit (`MaxAnalysisRecursionDepth = 6`).

**Runtime and Memory Performance Impact**:
- **CPU Runtime**: Strictly faster for JIT and AOT-compiled XLS functions: eliminates per-invocation stack initialization of constant lookup tables, removes per-bit conditional branch mispredictions in `one_hot_sel`, folds 1-bit `one_hot_sel` chains into straight-line bitwise `and`/`or` instructions instead of `cmov`s, and eliminates memory round-trips through `temp_buffer`.
- **Memory Usage**: Zero heap overhead; cross-partition temporaries are promoted to registers (bounded by `32 KiB` stack `alloca` prior to SROA), and aggregate literal tables are deduplicated in `.rodata`.

PiperOrigin-RevId: 1001458076
@copybara-service copybara-service Bot closed this Oct 17, 2026
@copybara-service
copybara-service Bot deleted the test_1001458076 branch October 17, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant