如何添加约束浮点型内建函数

警告

这是一个正在进行的工作。

添加内建函数

添加新的约束内建函数时,需要更新多个文件。

将新的内建函数添加到内建函数表

include/llvm/IR/Intrinsics.td

添加 SelectionDAG 节点类型

将新的 STRICT 版本节点类型添加到 ISD::NodeType 枚举中

include/llvm/CodeGen/ISDOpcodes.h

Strict 版本名称必须是前缀 STRICT_ 和相应非 strict 节点名称的串联。例如,节点 FADD 的 strict 版本必须是 STRICT_FADD。

更新映射

将新记录添加到指令到约束内建函数和 DAG 节点的映射

include/llvm/IR/ConstrainedOps.def

按照此文件中提供的说明进行操作。

更新 IR 组件

更新 IR 验证器

lib/IR/Verifier.cpp

更新 Selector 组件

构建 SelectionDAG

函数 SelectionDAGBuilder::visitConstrainedFPIntrinsic 使用 ConstrainedOps.def 中指定的映射构建 DAG 节点。但是,如果此默认构建不足以满足需求,则可以修改构建,请参阅 STRICT_FP_ROUND 的实现方式。新的 STRICT 节点最终将转换为匹配的非 STRICT 节点。因此,它应该具有与非 STRICT 版本相同的操作数和值,但也应该使用链。这使得后续 STRICT 和非 STRICT 代码路径的代码共享更容易

lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

大多数 STRICT 节点与其匹配的非 STRICT 节点以相同的方式合法化。具有此属性的新 STRICT 节点必须添加到 SelectionDAGLegalize::LegalizeOp() 中的 switch 语句中。

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

legalizer 的其他部分可能也需要更新。查找非 STRICT 对等体合法化的地方,并根据需要进行更新。请注意链,因为 STRICT 节点使用它,但它们的对等体通常不使用。

将 STRICT 节点转换为非 STRICT 版本节点或对其进行突变的代码发生在 SelectionDAG::mutateStrictFPToFP() 中。在大多数情况下,该函数可以使用 ConstrainedOps.def 中的信息进行转换。请注意更新此函数,因为某些节点的返回类型与其输入操作数相同,但有些则不同。这两种情况都必须妥善处理

lib/CodeGen/SelectionDAG/SelectionDAG.cpp

突变是否可能发生取决于新节点在 TargetLoweringBase::initActions() 中的注册方式。默认情况下,所有 strict 节点都使用 Expand 操作注册

lib/CodeGen/TargetLoweringBase.cpp

为了使调试日志更易读,更新 SelectionDAG 的调试记录器会很有帮助:

lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

添加文档和测试

docs/LangRef.rst