当前位置: 首页 > article >正文

llvm后端之函数栈帧的创建与销毁

llvm后端之函数栈帧的创建与销毁

  • 引言
  • 1 目标扩展实现
    • 1.1 emitPrologue和emitEpilogue
    • 1.2 storeRegToStackSlot和loadRegFromStackSlot
  • 2 寄存器存栈与恢复

引言

llvm后端在物理寄存器分配后、指令发射前会调用PEI这个pass来生成函数栈帧的创建与销毁。

1 目标扩展实现

在target下,需要实现如下两个方法:

  • TargetFrameLowering子类重写emitPrologue与emitEpilogue方法;
  • TargetInstrInfo子类重写storeRegToStackSlot和loadRegFromStackSlot方法。

1.1 emitPrologue和emitEpilogue

TargetFrameLowering类的emitPrologue与emitEpilogue方法用于创建和消耗函数栈帧实现。以RISCV为例:

emitPrologue其核心逻辑如下:

  • 基于对齐考虑,调用RISCVFrameLowering::determineFrameLayout调整栈大小;
  • 若栈指针寄存器SPReg被引用,则报错退出;否则继续;
  • 若栈指针需要通过多次调整,则将临时变量StackSize设置为第一次调整的大小。这是通过getFirstSPAdjustAmount计算的;
  • 通过adjustReg生成扩展栈空间的指令。由于栈向下生长,是加上负StackSize大小;此外,该指令是插入到基本块最前端;
  • 将插入指令的迭代器位置往后移需要保存的寄存器的个数;
  • 通过adjustReg调整帧指针FPReg的位置,使其指向参数所在位置;
  • 如果getFirstSPAdjustAmount返回非0,则需要第二次扩展栈空间;
  • 如果TargetRegisterInfo::needsStackRealignment返回要求改函数需要比正常调用约定更严格的栈对齐,则对栈指针SPReg再向下扩展MaxAlignment长度;

注:此外源码中还有包括生成用于栈回溯的cfi指令。

emitEpilogue其核心逻辑如下:

  • 首先将插入指令的位置MBBI设置为基本块末尾;
  • 调整指令插入位置。若有终止指令,将MBBI指向第一个终止指令的前面,否则指向最后一个非终止且非debug指令的后面;
  • 如果栈指针SPReg在emitPrologue中做了多次调整,则需要反序恢复回来。前面的恢复指令插入位置是MBBI向前移动该函数作为被调用者需要保存的寄存器个数;最后一次插入位置是MBBI

1.2 storeRegToStackSlot和loadRegFromStackSlot

TargetInstrInfo类的storeRegToStackSlot和loadRegFromStackSlot方法用于寄存器压栈和出栈指令的生成。同样,以RISCV为例:

  • storeRegToStackSlot则是根据寄存器分类获取不同的压栈指令类型,例如在32位目标下的GPR寄存器类,则是sw指令;
  • loadRegFromStackSlot也是根据寄存器分类获取不同的出栈指令类型,例如在32位目标下的GPR寄存器类,则是lw指令;

2 寄存器存栈与恢复

细心的朋友可能会发现之前的代码逻辑缺失了寄存器的保留与恢复操作。这部分指令是在PEI这个pass中完成的,该pass是在TargetPassConfig::addMachinePasses中完成添加的。在PEI::runOnMachineFunction中:

  • 首先就调用PEI::spillCalleeSavedRegs生成了该函数作为被调用者需要保护寄存器的保留与恢复指令操作,其中包括调用XXXInstrInfo实现的storeRegToStackSlot和loadRegFromStackSlot方法;
  • 后续,调用PEI::insertPrologEpilogCode生成栈帧的创建与销毁指令。

注:由于提前生成保留寄存器的压栈与出栈指令,所以目标在实现emitPrologue和emitEpilogue方法时,需要注意指令的插入位置。


http://www.kler.cn/a/297055.html

相关文章:

  • 线性代数 第七讲 二次型_标准型_规范型_坐标变换_合同_正定二次型详细讲解_重难点题型总结
  • ARM汇编
  • 记录:uniapp直播的弹幕的样式修改与发送弹幕会自动滚动到底部两个技巧
  • HTML 超链接
  • 量化投资策略与技术学习PART9:量化选股之筹码选股
  • 验证码识别之点选验证码识别——绪论
  • 资深研发的心愿:PostgreSQL未来若能加入这些功能,将更臻完善
  • 周报 | 24.9.2-24.9.8文章汇总
  • flutter之常用数据类型
  • 佰朔资本:沪指跌0.23%,金融板块集体上扬,半导体等板块下挫
  • vue使用Export2Excel导出表格
  • 倒推因子分解法——C语言实现
  • 象过河在线进销存软件——简单、高效、智能,让生意更简单!
  • Qt-高DPI显示器
  • 大数据-119 - Flink Window总览 窗口机制-滚动时间窗口-基于时间驱动基于事件驱动
  • “声”临其境:iKF Ultra 降噪耳机,音乐与静谧的完美融合
  • 基于百度AIStudio飞桨paddleRS-develop版道路模型开发训练
  • 鸿蒙轻内核A核源码分析系列四(3) 虚拟内存
  • 视频监控管理平台LntonAIServer视频智能分析噪声检测应用场景
  • 【JUC】13-原子类