MachineInstrBundle

这是一个工具类 Pass,它主要处理 Machine Instruction Bundles(机器指令捆绑) 的构造、解析与分析。换句话说,它负责在 LLVM 后端的代码生成阶段,对一系列底层机器指令进行组合、打包与拆包,从而支持目标平台(尤其是 VLIW、压缩指令等架构)对“指令包(bundle)”的要求。
该 Pass 涉及一些 VLIW 相关的概念:

概念说明
Instruction Bundling某些架构(如 VLIW、Itanium)要求将多个指令打包为一个单元调度或发射,称为指令捆绑
Dead/Kill/Undef Flags注册使用的生命周期属性分析,用于设置寄存器是否已失效或终止使用等优化标记
Subregisters / Lane Masks对支持 SIMD/SVE 等子寄存器体系结构,lane mask 用于追踪特定位宽的寄存器使用

支持 VLIW 架构的处理器如 Hexagon/Itanium/AArch64 都会触发这个 Pass:

  1. LLVM 后端生成的指令流中,若某些指令被标记为 InsideBundle
  2. 在调度/选择指令阶段调用 finalizeBundles:
    • 自动插入一个 BUNDLE 指令
    • 设置寄存器之间的 IsInternalRead、Dead 等标志位
  3. 在稍后的阶段(如 MachineVerifier 或 Emit)通过 UnpackMachineBundles 还原为原始指令流进行进一步优化或发射
原始:
  %r1 = ADD %r2, %r3
  %r4 = MUL %r1, %r5

最终 bundle:
  BUNDLE
    %r1 = ADD %r2, %r3   <-- 被标记为内部定义
    %r4 = MUL %r1, %r5   <-- %r1 是 InternalRead

Pass 仅仅三百多行,主要实现下面两个逻辑:
1.  finalizeBundle/finalizeBundles
功能:构造 BUNDLE 指令包围一组指令 + 更新相关寄存器信息
核心逻辑:

  • 插入一个新的 BUNDLE 指令(使用 BuildMI(…) 构造)
  • 扫描包内所有指令,分析其 MachineOperand:
    • 寄存器若在 bundle 中定义且被其他指令使用 → 标记为 IsInternalRead
    • 若使用了 bundle 外部的寄存器 → 加入到 BUNDLE 的 use 集中
    • 死/杀/undef 标记也被统一合并到 bundle 头指令
  • 还会设置 FrameSetup 等函数调用相关标志(在 prologue/epilogue 场景下)

2. UnpackMachineBundles
功能:恢复为原始指令流,去掉 BUNDLE 和 InsideBundle 标记
实现步骤:

  • 遍历所有指令,遇到 isBundle() 类型的指令
    • 将之后所有带 isBundledWithPred() 标记的指令解除捆绑
    • 移除 IsInternalRead
    • 删除 BUNDLE 指令本身