我目前正在探索为目标创建自定义后端。在 llvm 的官方文档https://llvm.org/docs/WritingAnLLVMBackend.html#basic-steps中提到,为了降低 Dag,我们需要修改 [Target]ISelDAGToDAG.cpp 和 [Target]ISelLowering.cpp。我探索了几个 llvm 目标。但无法掌握其中的区别。
有趣的一点是,学习后端代码结构并非易事,每个目标都在 Target 下的不同子文件夹中实现,其中包含多个.cpp
、.h
和.td
文件。
由于您提供的链接中提到了以下内容:
“还要编写代码XXXISelLowering.cpp
来替换或删除原生不支持的操作和数据类型SelectionDAG
。 ”
让我们继续前进。我会用一张大图来回答,显示指令选择之前的基本步骤,从左上角的 LLVM IR 步骤开始,然后引用LLVM 核心库入门:
首先,一个
SelectionDAGBuilder
实例(详情请参阅SelectionDAGISel.cpp
)访问每个函数并SelectionDAG
为每个基本块创建一个对象。在此过程中,一些特殊的 IR 指令(例如,call
并且ret
已经需要特定于目标的惯用语(例如,如何传递调用参数以及如何从函数返回))被转换为SelectionDAG
节点。为了解决这个问题,TargetLowering
首次使用了该类中的算法。此类是每个目标都必须实现的抽象接口,但也有许多在所有后端使用的通用功能。
为了实现这个抽象接口,每个目标都声明了一个
TargetLowering
名为 的子类<Target>TargetLowering
。每个目标还重载了方法,这些方法实现了如何将特定的独立于目标的高级节点降低到更接近本机节点的级别。正如预期的那样,只有一小部分节点必须以这种方式降低,而其他大多数节点在指令选择时匹配和替换。例如,在SelectionDAG
fromsum. bc
中,X86TargetLowering::LowerReturn()
方法(参见lib/Target/X86/ X86ISelLowering.cpp
)用于降低 IRret
指令。在执行此操作时,它会生成X86ISD::RET_FLAG
节点,该节点将函数结果复制到EAX
- 一种特定于目标的方式来处理函数返回。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句