LLVM后端怎么声明调用者和被调用者保存寄存器

落萱吖_2536

落萱吖_2536

2026-09-30

129人浏览

原创

llvm后端中默认caller-save的是未被getcalleesavedregs()列出且未被getreservedregs()保留的通用寄存器;callee-save寄存器由getcalleesavedregs()显式返回(如x86-64的rbx、rbp、r12–r15),必须严格符合abi且按调用约定动态适配。

llvm后端怎么声明调用者和被调用者保存寄存器

LLVM后端中哪些寄存器默认是 caller-save 或 callee-save

LLVM 不会自动推断哪些寄存器该由调用者保存、哪些该由被调用者保存 —— 这完全由目标后端在 XXXRegisterInfo.td 和 XXXRegisterInfo.cpp 中显式定义。关键在于两个机制:寄存器别名(Aliases) 和 寄存器类(RegisterClass) 的组合,以及 getReservedRegs() 和 getCalleeSavedRegs() 这两个虚函数的实现。

  • getCalleeSavedRegs() 必须返回一个 const MCPhysReg * 数组,列出所有被调用者承诺保存的物理寄存器(例如 x86-64 下的 RBX, RBP, R12–R15)
  • getReservedRegs() 返回必须始终保留、不能用于分配的寄存器(如栈指针 RSP、帧指针 RBP 在某些模式下、或特殊用途寄存器如 RIP)
  • 所有未出现在 getCalleeSavedRegs() 中、且未被 getReservedRegs() 排除的通用寄存器,默认视为 caller-save

注意:getCalleeSavedRegs() 返回的寄存器列表,必须与实际 ABI 规范严格一致;否则生成的代码在函数调用后可能破坏调用者状态。

如何在 TableGen 中标记 callee-saved 寄存器

TableGen 本身不直接声明“callee-saved”,它只负责定义寄存器及其关系(别名、子寄存器、寄存器类)。真正的 callee-saved 行为是在 C++ 实现中通过 getCalleeSavedRegs() 控制的。但 TableGen 是基础支撑:

  • 在 XXXRegisterInfo.td 中,每个寄存器需正确定义其 Aliases 和 SubRegs,否则寄存器分配器无法正确判断冲突
  • 寄存器类(如 GR64)应只包含语义等价的整数寄存器;若某寄存器(如 RBP)在 ABI 中是 callee-saved,但它属于 GR64 类,那它仍可被分配 —— 是否保存,全看 getCalleeSavedRegs() 是否把它列进去
  • 错误做法:试图在 RegisterClass 定义里加注释或字段标“callee-saved”——LLVM 不读这些

常见疏漏:x86-64 下漏掉 R12~R15 中的某一个,或把 RSP 错误地放进 getCalleeSavedRegs()(它应只在 getReservedRegs() 中)

调用约定(calling convention)如何影响 callee-saved 决策

调用约定不改变寄存器本身的保存责任归属,但它决定 哪些寄存器参与参数传递,进而影响哪些寄存器需要被保存 —— 尤其对 fastcc / cc10 / coldcc 这类非 C ABI 的约定:

Consensus
Consensus

一款AI工具,主要用于一个新型搜索引擎,利用AI在科学研究中为你找到答案,适合需要提升相关任务效率的用户。

下载
  • ccc(C calling convention):严格遵循目标平台 ABI,getCalleeSavedRegs() 必须返回 ABI 规定的 callee-saved 寄存器集
  • fastcc:允许目标使用更多寄存器传参,但 仍要求 callee 保存 ABI 规定的 callee-saved 寄存器;额外用于传参的寄存器(如 R10, R11)默认 caller-save,除非你主动把它们加进 getCalleeSavedRegs()
  • cc10(GHC):明确禁用 callee-saved 寄存器(“通过禁用被调用者保存寄存器来达到这个目的”),此时 getCalleeSavedRegs() 应返回空数组;若仍返回 RBX 等,会导致尾调用优化失败或寄存器污染

关键点:getCalleeSavedRegs() 的返回值必须与当前激活的调用约定语义一致;LLVM 不会为你做适配 —— 你得在函数体内根据 CC 参数分支返回不同数组(见下一点)

如何让 getCalleeSavedRegs() 支持多调用约定

getCalleeSavedRegs() 函数签名是 const MCPhysReg <em>getCalleeSavedRegs(const MachineFunction </em>MF) const override,你可以从 MF->getFunction().getCallingConv() 获取当前函数的调用约定,并据此返回不同集合:

  • 对 CallingConv::C,返回标准 ABI 的 callee-saved 列表(如 x86-64 下 {RBX, RBP, R12, R13, R14, R15})
  • 对 CallingConv::Fast,可返回更小的集合(比如只保 RBP 和 RBX),因为其他寄存器本就不该被 caller 依赖
  • 对 CallingConv::GHC(即 cc10),返回 nullptr 或空数组

容易踩的坑:

  • 忘记检查 MF 是否为空(某些 early pass 可能传入 null)
  • 返回栈上分配的局部数组(如 static MCPhysReg CS[] = {...} 是 OK 的,但 MCPhysReg CS[] = {...} 不行)
  • 在 cc10 下仍返回非空列表,导致 LLVM 生成冗余的 push/pop,破坏 GHC 寄存器固定假设

真正起作用的是你写进 getCalleeSavedRegs() 的逻辑,不是 TableGen 里的任何注释或字段。寄存器保存行为最终由这个函数和指令选择阶段的 CCState 协同决定 —— 后者负责按调用约定把参数分发到寄存器或栈,而前者确保被调用函数不会意外覆盖 caller 的活值。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2183

5

前端和后端的区别
前端和后端的区别

前端关注的是用户界面的设计和交互,而后端则注重数据处理和逻辑控制。想了解更多前端后端的相关内容,可以阅读本专题下面的文章。

2024.03.19

5810

13

后端的主要工作内容介绍
后端的主要工作内容介绍

后端是应用程序的服务端部分,负责核心任务,如数据库交互、业务逻辑处理和响应客户端请求。想了解更多后端的相关内容,可以阅读本专题下面的文章。

2024.03.19

5106

10

PDF转图片方法
PDF转图片方法

需要把 PDF 页面用于上传、预览、分享或图片归档时,PDF 转图片方法专题整理 JPG/PNG 格式选择、逐页导出、清晰度设置、批量下载和结果检查等流程,帮助用户稳定完成 PDF 图片化处理。

2026.09.30

0

26

PixTV AI视频生成与无限画布创作
PixTV AI视频生成与无限画布创作

PixTV专题整理AI视频与视觉内容创作相关功能使用教程,涵盖AI生图、视频生成、无限画布、多模型创作、素材管理、声音音乐及视频剪辑等功能,帮助用户快速掌握PixTV从创意到成片的完整制作方法。

2026.09.29

0

15

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

2026.09.23

200

15

Buffalo框架路由与请求处理实操指南
Buffalo框架路由与请求处理实操指南

本专题讲解Buffalo框架路由与请求处理机制,涵盖路由注册与分组、资源路由、Handler编写规范、Context上下文方法、参数绑定、中间件编写挂载、Session与Cookie读写、Flash消息及错误页面定制方法。

2026.09.23

120

15

Buffalo框架零基础入门教程
Buffalo框架零基础入门教程

本专题整理Buffalo框架入门内容,涵盖Go环境准备、buffalo CLI安装、新项目生成、目录结构说明、dev热加载启动、数据库连接配置与常见报错排查,帮助新手按约定优于配置的思路跑通第一个Buffalo框架应用。

2026.09.23

100

15

Conan创建软件包配方指南
Conan创建软件包配方指南

本专题介绍通过conanfile.py创建软件包的方法,讲解包名、版本、依赖和构建设置等基础信息,以及source、build、package、package_info等常用方法的作用及编写思路。

2026.09.22

60

12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程