如何新增受限浮點數內建函數

警告

這是進行中的工作。

新增內建函數

新增受限內建函數時,需要更新多個檔案。

將新的內建函數新增到內建函數表

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

合法化器的其他部分也可能需要更新。尋找非 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