LLVM后端中保留寄存器是编译器绝不分配、也不允许被虚拟寄存器覆盖的物理寄存器,如sp、fp、x0(AArch64)或rsp(x86-64);必须在XXXRegisterInfo.cpp中重载getReservedRegs函数返回准确BitVector,并确保TableGen中未将其纳入allocatable set,否则引发断言失败或运行时错误。

LLVM后端中,保留寄存器(reserved registers)是指**编译器绝不分配、也不允许被虚拟寄存器覆盖的物理寄存器**,比如栈指针 sp、帧指针 fp、零寄存器 x0(AArch64)、或 rsp(x86-64)。设置错误会导致指令生成崩溃、verify-machineinstrs 断言失败,或运行时栈被意外覆写。
在 XXXRegisterInfo.cpp 中重载 getReservedRegs
这是最直接、也是唯一生效的位置。LLVM 寄存器分配器在启动前会调用该函数获取一个 BitVector,其中每一位对应一个物理寄存器编号。必须返回一个准确标记所有保留寄存器的位图。
- 函数签名固定为:
const BitVector &getReservedRegs(const MachineFunction &MF) const override - 不能只写一次静态
BitVector并返回引用——必须每次构造或缓存后返回引用,否则多线程下可能出错 - 寄存器编号需通过
MCRegisterInfo::getAllocatableSet()或MCRegisterInfo::getNumRegs()对齐;推荐用TRI->getEncodingValue(Reg)验证编号是否合法 - 常见误操作:把
sp写成StackPointer(未定义)或漏掉别名寄存器(如 AArch64 的zr和xzr是同一物理寄存器)
示例(AArch64 风格):
const BitVector &AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
static BitVector Reserved;
if (Reserved.empty()) {
Reserved.resize(getNumRegs());
Reserved.set(AArch64::SP); // 必须保留
Reserved.set(AArch64::XZR); // 零寄存器不可分配
Reserved.set(AArch64::FP); // 若启用帧指针
}
return Reserved;
}
确保 TableGen 中未将保留寄存器加入 allocatable set
TableGen 自动生成的可分配寄存器集合(Allocatable)若包含保留寄存器,会与 getReservedRegs 冲突,导致断言 "Reserved register X is in allocatable set" 失败。
- 检查
XXXRegisterInfo.td中的def XXX : RegisterClass<...>定义,确认其成员列表不含SP、XZR、RSP等 - 特别注意子寄存器(
SubRegs):如果SP被列为某寄存器的SubRegs,而该寄存器本身又被放入 allocatable set,则整个链路都会被误认为可分配 - AArch64 常见坑:
Q0的SubRegs包含D0,而D0又含S0/B0——但只要SP不出现在任何RegisterClass的MemberList中,就不会被分配
验证保留是否真正生效
仅靠编译不报错不能说明保留成功。必须用实际 IR 测试并观察寄存器分配行为:
- 用
llc -mtriple=xxx -debug-only=regalloc test.ll -o -查看分配日志,搜索Reserved registers:行,确认列出的寄存器与代码一致 - 故意在 IR 中生成对
sp的虚拟寄存器读写(如%sp_vreg = add i64 %sp, 8),观察是否触发Assertion `!isReserved(Reg)' failed - 用
-verify-machineinstrs运行,若生成指令中出现mov x0, sp类似非法 move(sp不能作为源操作数出现在某些架构),说明保留逻辑未阻止非法 use - 对 RISC-V 后端,
x0必须保留且硬编码为 0;若看到addi t0, x0, 1中x0被当作普通寄存器参与分配,即为失败
最易被忽略的是:保留寄存器的“保留”仅作用于寄存器分配阶段,不阻止指令选择或帧展开手动写入。比如 Prologue 中仍需显式保存 lr,但不能指望 getReservedRegs 自动帮你插入那条指令——它只管“不许分配”,不管“该不该用”。

















