讲师中心 微信公众号
AI工具推荐 视频效率加速

LLVM后端怎么生成函数序言和尾声

星静酱_4834

星静酱_4834

发布时间:2026-10-06 15:16:00

|

879人浏览过

|

来源于php中文网

原创

函数序言和尾声由PrologEpilogInserter pass在寄存器分配后、指令调度完成时调用TargetFrameLowering::emitPrologue/emitEpilogue生成,插入到MachineInstr列表中,不依赖IR或DAG,仅操作机器指令。

llvm后端怎么生成函数序言和尾声

函数序言(prologue)和尾声(epilogue)由 TargetFrameLowering 子类生成,不是手写汇编,也不是在指令选择阶段插入——它发生在寄存器分配之后、指令调度完成、MachineInstr 已成型但尚未发射的阶段。

什么时候调用 emitPrologue 和 emitEpilogue

LLVM 后端在 MachineFunctionPass 流水线中,由 PrologEpilogInserter pass 负责统一插入。该 pass 会遍历每个 MachineFunction,在入口基本块开头调用 TargetFrameLowering::emitPrologue,在每个有返回指令(如 RET、BR_RET)的基本块末尾调用 emitEpilogue。

  • 这个 pass 运行在寄存器分配(RegisterAllocator)之后,因此能准确知道哪些虚拟寄存器被 spill 到栈上,也清楚帧指针(FP)、栈指针(SP)的偏移关系
  • 它不关心 IR 或 DAG,只操作 MachineInstr 列表,直接往 MBB->instr_begin() 或 MBB->instr_end() 插入新指令
  • 如果你看到序言里有 ADD SP, SP, #-16 或 STR R0, [SP, #-4]! 这类指令,它们是 C++ 代码动态 emit 出来的,不是 TableGen 模式匹配出来的

TargetFrameLowering 必须重写的两个核心函数

每个目标后端都需继承并实现 TargetFrameLowering,最关键的两个虚函数是:

  • emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB):负责分配栈空间、保存 callee-saved 寄存器、设置帧指针(如果需要)。注意:它不负责计算栈大小——那是 computeStackSize 阶段干的,结果存在 MF.getFrameInfo()->getStackSize()
  • emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB):恢复 callee-saved 寄存器、调整栈指针、跳过帧指针恢复逻辑(除非显式启用 hasFP)
  • 还必须实现 hasFP(const MachineFunction &MF) —— 它决定是否把帧指针当作独立寄存器管理;若返回 true,emitPrologue 通常要插入 MOV FP, SP 类似指令,且后续所有栈访问都基于 FP 偏移而非 SP

常见错误:栈偏移算错、寄存器保存顺序颠倒、漏处理变长栈分配

序言/尾声出错,往往不是语法问题,而是语义错位。典型表现包括:

  • 函数返回后寄存器值异常 → 检查 getCalleeSavedRegs() 返回的寄存器列表是否与 emitPrologue 中实际保存的顺序、数量、条件(如是否仅在有栈溢出时才保存)严格一致
  • 局部变量读写越界或值错乱 → 栈帧大小计算错误,常见于未正确处理 hasVarSizedObjects():若函数含变长数组(alloca),getStackSize() 不再是常量,必须在运行时计算并用指令动态调整 SP
  • 调试信息错乱或 GDB 显示栈回溯断裂 → 忘记在 emitPrologue 中调用 addRegOffset 注册 CFI 指令(如 CFI_ADJUST_CFA_OFFSET、CFI_REMEMBER_STATE),导致 DWARF 无法重建调用栈
  • 硬故障或非法指令 → 在 emitPrologue 中试图使用未定义的机器指令(比如用 ARM::STRi12 但当前 subtarget 不支持 Thumb2),应优先通过 getInstrInfo()->get(...) 获取合法 MCID

调试建议:用 -mllvm -print-machineinstrs 看真实插入点

光看 C++ 实现容易误判执行时机。最有效的方式是编译时加参数观察中间状态:

  • llc -march=yourtarget -mllvm -print-machineinstrs input.ll 2>&1 | grep -A5 -B5 "PROLOG" 可定位到序言指令实际插在哪条 MachineInstr 前后
  • 配合 -debug-only=regalloc 或 -debug-only=stack-slot 查看帧信息如何被计算和传播
  • 若修改了 emitPrologue 但没生效,先确认 YourTargetFrameLowering 是否已注册进 YourTargetTargetMachine::createTargetFrameLowering,且 TM.getSubtargetImpl()->getFrameLowering() 确实返回你的实例

序言和尾声看似只是几条栈操作指令,但它横跨帧布局、寄存器保存策略、CFI 调试信息、变长分配四大耦合模块,任何一处 mismatch 都会导致静默崩溃或难以复现的栈破坏——动手前务必通读本 target 的 FrameLowering 实现和对应 ABI 文档。

热门AI工具

更多
Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

相关专题

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

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

2283

2023.08.11

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

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

6030

2024.03.19

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

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

5366

2024.03.19

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

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

80

2026.09.30

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

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

80

2026.09.30

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

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

80

2026.09.30

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

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

40

2026.09.30

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

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

60

2026.09.29

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

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

280

2026.09.23

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn