RegBankSelect — LLVM 21.1.1 documentation

# RegBankSelect

This pass constrains the Generic Virtual Registers operands of generic instructions to some Register Bank.

It iteratively maps instructions to a set of per-operand bank assignment. The possible mappings are determined by the target-provided RegisterBankInfo. The mapping is then applied, possibly introducing `COPY` instructions if necessary.

It traverses the `MachineFunction` top down so that all operands are already mapped when analyzing an instruction.

This pass could also remap target-specific instructions when beneficial. In the future, this could replace the ExeDepsFix pass, as we can directly select the best variant for an instruction that’s available on multiple banks.

## API: RegisterBankInfo

The `RegisterBankInfo` class describes multiple aspects of register banks.

- Banks: `addRegBankCoverage` — which register bank covers each register class.

- Cross-Bank Copies: `copyCost` — the cost of a `COPY` from one bank to another.

- Default Mapping: `getInstrMapping` — the default bank assignments for a given instruction.

- Alternative Mapping: `getInstrAlternativeMapping` — the other possible bank assignments for a given instruction.

`TODO`: All this information should eventually be static and generated by TableGen, mostly using existing information augmented by bank descriptions.

`TODO`: `getInstrMapping` is currently separate from `getInstrAlternativeMapping` because the latter is more expensive: as we move to static mapping info, both methods should be free, and we should merge them.

## RegBankSelect Modes

`RegBankSelect` currently has two modes:

- Fast — For each instruction, pick a target-provided “default” bank assignment. This is the default at -O0.

- Greedy — For each instruction, pick the cheapest of several target-provided bank assignment alternatives.

We intend to eventually introduce an additional optimizing mode:

- Global — Across multiple instructions, pick the cheapest combination of bank assignments.

`NOTE`: On AArch64, we are considering using the Greedy mode even at -O0 (or perhaps at backend -O1): because Low Level Type doesn’t distinguish floating point from integer scalars, the default assignment for loads and stores is the integer bank, introducing cross-bank copies on most floating point operations.