LLVM后端怎么实现栈帧布局

星枫同学_6229

星枫同学_6229

2026-10-07

137人浏览

原创

llvm后端实现栈帧布局的核心是重写targetframelowering子类,在emitprologue/emitepilogue中生成正确栈指令,通过machineframeinfo统一管理slot分配,并由getframeindexoffset返回相对于fp/sp的字节偏移以支持地址计算。

llvm后端怎么实现栈帧布局

LLVM 后端实现栈帧布局,核心在于重写 TargetFrameLowering 子类,并在 emitPrologue / emitEpilogue 中生成正确的栈操作指令。它不是靠硬编码偏移,而是通过 MachineFrameInfo 统一管理 slot 分配,再由后端决定如何将 slot 映射到寄存器或栈内存。

怎么让 LLVM 知道局部变量该放哪

LLVM 不直接处理 C 变量名,而是把每个 alloca 指令转为一个 MachineFrameInfo slot(用 FrameIndex 编号)。后端要做的,是告诉 LLVM:这个 slot 是放在栈上、还是某个 callee-saved 寄存器里、偏移多少、是否需要对齐。

  • getFrameIndexOffset(MF, FI) 必须返回该 FrameIndex 相对于 frame pointer 或 stack pointer 的字节偏移 —— 这个值最终会参与地址计算(如 addi sp, sp, -16 + sw a0, 4(sp))
  • 若 slot 大小超过寄存器宽度(比如 128-bit 向量),且目标不支持向量寄存器 spill/fill,则必须分配栈空间;否则可考虑 isSafeToReallocate 启用寄存器复用
  • RISC-V 向量扩展(V extension)下,getStackAlignment() 需返回 VLEN/8(如 VLEN=256 → 对齐 32 字节),否则 llvm::alignTo 计算出的 slot 偏移可能破坏向量访存边界

Prologue/Epilogue 里哪些指令不能少

emitPrologue 不只是 push 寄存器,它要协调栈增长、帧指针建立、slot 分配三件事。漏掉任一环节,会导致后续 FrameIndex 地址计算错位,甚至段错误。

Vega AI
Vega AI

Vega AI是一款由右脑科技推出的在线 AI 绘画和视频创作平台。

下载
  • 先调用 MFI->setHasCalls()(如有 call),否则 getCalleeSavedSpillSlots 可能不触发
  • 用 BuildMI 插入 ADDI(RISC-V)或 SUBSP(ARM)调整 sp;注意:若启用 frame pointer,还需 ADDI fp, sp, #offset
  • 对每个需保存的 callee-saved 寄存器,调用 saveCalleeSavedRegisters —— 它内部会查 getCalleeSavedSpillSlots 返回的 std::vector<calleesavedinfo></calleesavedinfo>,并为每个 slot 插入 store 指令
  • emitEpilogue 要逆序恢复:先 load 寄存器,再 ADDI sp, sp, #size,最后 ret;顺序颠倒会导致 sp 提前恢复,后续 load 访问野地址

SafeStack 和向量栈帧怎么共存

SafeStack 把敏感数据(返回地址、ra)和普通局部变量分到两个栈上,而 RISC-V 向量扩展要求大块连续对齐内存。两者叠加时,MachineFrameInfo 会为两类 slot 分别维护独立 offset 计数器,但后端必须确保:

  • 向量 slot 的分配不跨 SafeStack 的「unsafe stack」边界 —— 否则 getFrameIndexOffset 返回的偏移无法被安全栈的 base 寻址模式覆盖
  • getStackAlignment() 应取二者最大值(如 SafeStack 默认 16 字节,VLEN=512 → 64 字节),否则向量 load/store 触发 misaligned trap
  • 避免在 emitPrologue 中混用两套栈指针(如 sp 和 ssp)做同一 slot 的地址计算;LLVM 当前不自动推导 multi-stack 地址表达式,需手动检查 MFI->getStackID(FI) == TargetStackID::Safe

真正容易被忽略的是:栈帧布局逻辑一旦写进 TargetFrameLowering,就会影响所有优化阶段 —— 比如 RegAllocFast 会依据 slot 大小决定是否 spill,StackSlotColoring 依赖 offset 对齐性做合并。改 layout 不单是修几个数字,得同步验证 llc -march=riscv32 -mattr=+v 下的 prologue 输出和实际运行时内存布局是否一致。

相关文章

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

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

下载

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

相关专题

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

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

2023.08.11

2303

5

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

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

2024.03.19

6070

13

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

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

2024.03.19

5406

10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

5187

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2288

6

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

2026.09.30

120

10

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

2026.09.30

100

14

LLVM IR中间表示入门指南
LLVM IR中间表示入门指南

本专题整理LLVM IR的核心概念,包括中间表示作用、模块结构、函数、基本块、SSA形式、类型系统和常见语法,帮助新手理解LLVM编译流程中的关键层。

2026.09.30

80

12

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

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

2026.09.30

60

26

热门下载

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

精品课程

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