| (regbankselect)= | |
| # RegBankSelect | |
| This pass constrains the {ref}`gmir-gvregs` operands of generic | |
| instructions to some {ref}`gmir-regbank`. | |
| It iteratively maps instructions to a set of per-operand bank assignment. | |
| The possible mappings are determined by the target-provided | |
| {ref}`RegisterBankInfo <api-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)= | |
| ## 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 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 {ref}`gmir-llt` 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. | |