llvm后端之局部变量

引言

llvm后端对局部变量(即alloc节点)的访问,首先,将对alloc节点转为FrameIndex,所有对alloc的load和store均用FrameIndex取代;最后,在PEI这个pass中调用XXXRegisterInfo::eliminateFrameIndex将FrameIndex操作数转换为FP寄存器偏移量。

1 生成FrameIndexSDNode

  • 在SelectionDAGISel::runOnMachineFunction->FunctionLoweringInfo::set中会为每个AllocaInst生成FrameIndex、并在FunctionLoweringInfo::StaticAllocaMap存储AllocaInst与FrameIndex的索引关系。由于可变参数在帧指针上面、局部变量在帧指针下面,所以FrameIndex就是由AllocaInst封装的栈对象在MachineFrameInfo::Objects中的位置序号减去前面的可变参数对象个数(可变参数也是栈对象,它也记录在该Objects且放置在前面);
  • 当生成DAG阶段,节点引用的操作数是AllocaInst时,在FunctionLoweringInfo::StaticAllocaMap中查找对应FrameIndex值,并创建FrameIndexSDNode节点。

注:MachineFrameInfo::Objects列表依次放置可变参数、异常参数、局部变量。其中可变参数和异常参数是FixedObjects。局部变量包括固定大小的变量,不固定大小的变量(例如不定长的数组)。

2 消除FrameIndex

由于FrameIndex操作数是一个抽象的操作数,对它的替换是在PEI这个pass中进行的。核心流程如下:

  • 在函数PEI::replaceFrameIndices(MachineFunction &MF)中,通过df_iterator对每个基本块按DFS进行迭代,每个迭代项记录entry节点到当前节点的DFS搜索路径。针对每个节点调用PEI::replaceFrameIndices的重载函数来迭代基本块的每条指令;
  • 如果指令是帧操作指令,则需要获取此指令栈指针偏移大小,并且要累加到后续迭代中。并且通过XXXFrameLowering::eliminateCallFramePseudoInstr将该伪指令展开为真实的栈指针的操作;
  • 对于非debug指令且非TargetOpcode::STATEPOINT类型的指令,通过XXXRegisterInfo::eliminateFrameIndex将操作数更改为基于帧指针FP的偏移。

注:帧操作指令的定义由class XXXInstrInfo构造时,由XXXGenInstrInfo传入。对于RISCV而言,就是RISCV::ADJCALLSTACKDOWN和RISCV::ADJCALLSTACKUP两条指令,前者是增长栈、后者为缩小栈

2.1 eliminateCallFramePseudoInstr

该函数为TargetFrameLowering的虚函数,以RISCV为例,其逻辑如下:

  • 当没有保护栈空间,或者说没有将栈空间固定死(也就是函数有可变长的局部变量),则插入累加SP寄存器的指令;
  • 最后,删除之前的老指令(无论函数有无可变长的局部变量)。

2.2 eliminateFrameIndex

该函数为TargetRegisterInfo的虚函数,以RISCV为例,其逻辑如下:

  • 首先,进行断言。本函数是不希望出现动态调整栈指针情况,当然出现过调整又恢复的情况是可以接受的;
  • 通过RISCVFrameLowering::getFrameIndexReference计算FrameIndex的空间相对FrameReg的偏移,并通过引用返回FrameReg;
  • 最后,当Offset是有效12位立即数,则将FrameIndex操作数设置为FrameReg的引用,下一个操作数设置为offset立即数;当Offset不是有效12位立即数,则将FrameReg与offset相加后,设置FrameIndex操作数为累加的值,下一个操作数设置为0;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值