RegBankSelect

此 Pass 将泛型指令的通用虚拟寄存器操作数约束到某些寄存器组

它迭代地将指令映射到一组每个操作数的寄存器组分配。可能的映射由目标提供的RegisterBankInfo确定。然后应用映射,如果需要,可能会引入COPY指令。

它自顶向下遍历MachineFunction,以便在分析指令时所有操作数都已映射。

此 Pass 也可能在有利时重新映射目标特定的指令。将来,这可以替换 ExeDepsFix Pass,因为我们可以直接选择在多个寄存器组上可用的指令的最佳变体。

API: RegisterBankInfo

RegisterBankInfo类描述了寄存器组的多个方面。

  • 寄存器组: addRegBankCoverage — 哪个寄存器组覆盖每个寄存器类。

  • 跨寄存器组复制: copyCost — 从一个寄存器组复制到另一个寄存器组的成本。

  • 默认映射: getInstrMapping — 给定指令的默认寄存器组分配。

  • 备选映射: getInstrAlternativeMapping — 给定指令的其他可能的寄存器组分配。

TODO: 所有这些信息最终都应该是静态的,并由 TableGen 生成,主要使用现有信息并添加寄存器组描述。

TODO: getInstrMapping 目前与 getInstrAlternativeMapping 分开,因为后者更昂贵:随着我们转向静态映射信息,这两种方法都应该是免费的,我们应该将它们合并。

RegBankSelect 模式

RegBankSelect 目前有两种模式

  • 快速 — 对于每个指令,选择目标提供的“默认”寄存器组分配。这是 -O0 下的默认值。

  • 贪婪 — 对于每个指令,选择目标提供的几个寄存器组分配备选方案中最便宜的一个。

我们打算最终引入一种额外的优化模式

  • 全局 — 在多个指令之间,选择寄存器组分配的最便宜组合。

NOTE: 在 AArch64 上,我们正在考虑即使在 -O0(或者可能在后端 -O1)下也使用贪婪模式:因为低级类型不区分浮点数和整数标量,所以加载和存储的默认分配是整数寄存器组,这在大多数浮点运算中引入了跨寄存器组复制。