| ================================================== |
| How To Add A Constrained Floating-Point Intrinsic |
| ================================================== |
| |
| .. contents:: |
| :local: |
| |
| .. warning:: |
| This is a work in progress. |
| |
| Add the intrinsic |
| ================= |
| |
| Multiple files need to be updated when adding a new constrained intrinsic. |
| |
| Add the new intrinsic to the table of intrinsics:: |
| |
| include/llvm/IR/Intrinsics.td |
| |
| Add SelectionDAG node types |
| =========================== |
| |
| Add the new ``STRICT`` version of the node type to the ``ISD::NodeType`` enum:: |
| |
| include/llvm/CodeGen/ISDOpcodes.h |
| |
| Strict version name must be a concatenation of prefix ``STRICT_`` and the name |
| of the corresponding non-strict node name. For instance, strict version of the |
| node ``FADD`` must be ``STRICT_FADD``. |
| |
| Update mappings |
| =============== |
| |
| Add new record to the mapping of instructions to constrained intrinsic and |
| DAG nodes:: |
| |
| include/llvm/IR/ConstrainedOps.def |
| |
| Follow instructions provided in this file. |
| |
| Update IR components |
| ==================== |
| |
| Update the IR verifier:: |
| |
| lib/IR/Verifier.cpp |
| |
| Update Selector components |
| ========================== |
| |
| Building the SelectionDAG |
| ------------------------- |
| |
| The ``SelectionDAGBuilder::visitConstrainedFPIntrinsic`` function builds DAG nodes |
| using mappings specified in ``ConstrainedOps.def``. If however this default build is |
| not sufficient, the build can be modified, see how it is implemented for |
| ``STRICT_FP_ROUND``. The new ``STRICT`` node will eventually be converted |
| to the matching non-``STRICT`` node. For this reason it should have the same |
| operands and values as the non-``STRICT`` version but should also use the chain. |
| This makes subsequent sharing of code for ``STRICT`` and non-``STRICT`` code paths |
| easier:: |
| |
| lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp |
| |
| Most of the ``STRICT`` nodes get legalized the same as their matching non-``STRICT`` |
| counterparts. A new ``STRICT`` node with this property must get added to the |
| switch in ``SelectionDAGLegalize::LegalizeOp()``:: |
| |
| lib/CodeGen/SelectionDAG/LegalizeDAG.cpp |
| |
| Other parts of the legalizer may need to be updated as well. Look for |
| places where the non-``STRICT`` counterpart is legalized and update as needed. |
| Be careful of the chain since ``STRICT`` nodes use it but their counterparts |
| often don't. |
| |
| The conversion or mutation of the ``STRICT`` node to a non-``STRICT`` |
| version of the node happens in ``SelectionDAG::mutateStrictFPToFP()``. In most cases |
| the function can do the conversion using information from ConstrainedOps.def. Be |
| careful updating this function since some nodes have the same return type |
| as their input operand, but some are different. Both of these cases must |
| be properly handled:: |
| |
| lib/CodeGen/SelectionDAG/SelectionDAG.cpp |
| |
| Whether the mutation happens or not depends on how the new node has been |
| registered in ``TargetLoweringBase::initActions()``. By default, all strict nodes are |
| registered with Expand action:: |
| |
| lib/CodeGen/TargetLoweringBase.cpp |
| |
| To make debug logs readable, it is helpful to update the SelectionDAG's |
| debug logger::: |
| |
| lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp |
| |
| Add documentation and tests |
| =========================== |
| |
| :: |
| |
| docs/LangRef.rst |