llvm 中 XXXISelDAGToDAG 和 XXXISelLowering 的区别

Difference between XXXISelDAGToDAG and XXXISelLowering in llvm

我目前正在探索为目标创建自定义后端。在 llvm https://llvm.org/docs/WritingAnLLVMBackend.html#basic-steps 的官方文档中,提到为了降低 Dag,我们需要修改 [Target]ISelDAGToDAG.cpp 和 [Target]ISelLowering.cpp。我探索了几个 llvm 目标。但无法把握其中的不同。

有趣的一点是因为学习后端代码结构并不简单,每个目标都在 Target 下的不同子文件夹中实现 有几个 .cpp.h.td 个文件。

由于您提供的 link 中提到了以下内容:

"也在 XXXISelLowering.cpp 中编写代码以替换或删除 SelectionDAG."[=35] 中本机不支持的操作和数据类型=]

让我们继续前进。我会用一张显示基本步骤的大图来回答 在指令选择之前,从 LLVM IR 开始 top-left 然后引用 Getting Started with LLVM 核心库

First, a SelectionDAGBuilder instance (see SelectionDAGISel.cpp for details) visits every function and creates a SelectionDAG object for each basic block. During this process, some special IR instructions such as call and ret already need targetspecific idioms—for instance, how to pass call arguments and how to return from a function—to be transformed into SelectionDAG nodes. To solve this issue, the algorithms in the TargetLowering class are used for the first time. This class is an abstract interface that each target must implement, but also has plenty of common functionality used throughout all backends.

To implement this abstract interface, each target declares a TargetLowering subclass named <Target>TargetLowering. Each target also overloads methods that implement how a specific target-independent, high-level node should be lowered to a level closer to the one of this machine. As expected, only a small subset of nodes must be lowered in this way, while the majority of the others are matched and replaced at instruction selection. For instance, in SelectionDAG from sum. bc, the X86TargetLowering::LowerReturn() method (see lib/Target/X86/ X86ISelLowering.cpp) is used to lower the IR ret instruction. While doing this, it generates the X86ISD::RET_FLAG node, which copies the function result to EAX—a target-specific way to handle the function return.