147
|
1 ==================================================
|
|
2 How To Add A Constrained Floating-Point Intrinsic
|
|
3 ==================================================
|
|
4
|
|
5 .. contents::
|
|
6 :local:
|
|
7
|
|
8 .. warning::
|
|
9 This is a work in progress.
|
|
10
|
|
11 Add the intrinsic
|
|
12 =================
|
|
13
|
|
14 Multiple files need to be updated when adding a new constrained intrinsic.
|
|
15
|
|
16 Add the new intrinsic to the table of intrinsics.::
|
|
17
|
|
18 include/llvm/IR/Intrinsics.td
|
|
19
|
|
20 Update class ConstrainedFPIntrinsic to know about the intrinsics.::
|
|
21
|
|
22 include/llvm/IR/IntrinsicInst.h
|
|
23
|
|
24 Functions like ConstrainedFPIntrinsic::isUnaryOp() or
|
|
25 ConstrainedFPIntrinsic::isTernaryOp() may need to know about the new
|
|
26 intrinsic.::
|
|
27
|
|
28 lib/IR/IntrinsicInst.cpp
|
|
29
|
|
30 Update the IR verifier::
|
|
31
|
|
32 lib/IR/Verifier.cpp
|
|
33
|
|
34 Add SelectionDAG node types
|
|
35 ===========================
|
|
36
|
|
37 Add the new STRICT version of the node type to the ISD::NodeType enum.::
|
|
38
|
|
39 include/llvm/CodeGen/ISDOpcodes.h
|
|
40
|
|
41 In class SDNode update isStrictFPOpcode()::
|
|
42
|
|
43 include/llvm/CodeGen/SelectionDAGNodes.h
|
|
44
|
|
45 A mapping from the STRICT SDnode type to the non-STRICT is done in
|
|
46 TargetLoweringBase::getStrictFPOperationAction(). This allows STRICT
|
|
47 nodes to be legalized similarly to the non-STRICT node type.::
|
|
48
|
|
49 include/llvm/CodeGen/TargetLowering.h
|
|
50
|
|
51 Building the SelectionDAG
|
|
52 -------------------------
|
|
53
|
|
54 The switch statement in SelectionDAGBuilder::visitIntrinsicCall() needs
|
|
55 to be updated to call SelectionDAGBuilder::visitConstrainedFPIntrinsic().
|
|
56 That function, in turn, needs to be updated to know how to create the
|
|
57 SDNode for the intrinsic. The new STRICT node will eventually be converted
|
|
58 to the matching non-STRICT node. For this reason it should have the same
|
|
59 operands and values as the non-STRICT version but should also use the chain.
|
|
60 This makes subsequent sharing of code for STRICT and non-STRICT code paths
|
|
61 easier.::
|
|
62
|
|
63 lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
|
|
64
|
|
65 Most of the STRICT nodes get legalized the same as their matching non-STRICT
|
|
66 counterparts. A new STRICT node with this property must get added to the
|
|
67 switch in SelectionDAGLegalize::LegalizeOp().::
|
|
68
|
|
69 lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
|
|
70
|
|
71 Other parts of the legalizer may need to be updated as well. Look for
|
|
72 places where the non-STRICT counterpart is legalized and update as needed.
|
|
73 Be careful of the chain since STRICT nodes use it but their counterparts
|
|
74 often don't.
|
|
75
|
|
76 The code to do the conversion or mutation of the STRICT node to a non-STRICT
|
|
77 version of the node happens in SelectionDAG::mutateStrictFPToFP(). Be
|
|
78 careful updating this function since some nodes have the same return type
|
|
79 as their input operand, but some are different. Both of these cases must
|
|
80 be properly handled.::
|
|
81
|
|
82 lib/CodeGen/SelectionDAG/SelectionDAG.cpp
|
|
83
|
|
84 However, the mutation may not happen if the new node has not been registered
|
|
85 in TargetLoweringBase::initActions(). If the corresponding non-STRICT node
|
|
86 is Legal but a target does not know about STRICT nodes then the STRICT
|
|
87 node will default to Legal and mutation will be bypassed with a "Cannot
|
|
88 select" error. Register the new STRICT node as Expand to avoid this bug.::
|
|
89
|
|
90 lib/CodeGen/TargetLoweringBase.cpp
|
|
91
|
|
92 To make debug logs readable it is helpful to update the SelectionDAG's
|
|
93 debug logger:::
|
|
94
|
|
95 lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
|
|
96
|
|
97 Add documentation and tests
|
|
98 ===========================
|
|
99
|
|
100 ::
|
|
101
|
|
102 docs/LangRef.rst
|