提问者:小点点

在LLVM后端实现堆栈布局


我正在尝试实现LLVM的后端。现在我遇到了堆栈帧降低的问题。

我需要实现以下堆栈布局:当一个函数被调用时,我需要把一个“返回符号”(因为目标系统只能跳转到绝对地址)和“偏移”放在堆栈上,然后是所有的函数参数。堆栈对齐是1字节,堆栈必须长大。

调用前的堆栈布局:

RetSymb <- SP
Offset
Arguments
Local Data

进入函数之前的堆栈布局:

RetSymb
Offset
Arguments
Local Data
RetSymb <- SP
Offset = SP - Old SP
Arguments
Local Data

返回时,SP会自动递减存储在“偏移”中的值。变量参数处理现在并不重要。

我目前不知道我必须看哪些地方以及我需要在这些地方做什么。我在XXXFrameLowering. cpp中找到了emitPrologue和emitEpilot ogue函数,但我真的不知道它们应该做什么(我想在函数的开始和结束时插入代码)。我还在XXXISelLowering.cpp文件中找到了几个函数。是否有一个列表来解释不同的函数应该做什么?例如:

  • LowerFormalArguments(我猜是从堆栈中插入加载参数)
  • LowerCallResult
  • LowerCall
  • 低返回

提前感谢任何信息,指出我在正确的方向。


共1个答案

匿名用户

据我所知,没有一个地方可以解释这一点。你必须选择一个现有的后端并遵循它的代码来看看魔法是在哪里完成的。emitPrologueemitEpilot ogue是很好的起点,因为它们专门处理函数中设置和破坏框架的代码。一个函数被降低到(粗略近似,有更多细节…):

func_label:
  prologue
  .. function code
  epilogue

因此,要处理自定义堆栈布局,您肯定必须为序言和尾声编写自定义代码。如果调用者负责一些堆栈布局,对函数的调用也是如此。

我建议您首先阅读一些现有后端的堆栈帧布局,然后研究LLVM中的相关代码。例如,我在这里描述了一些x86(32位)帧信息。