[RFC] TableGen-erating SDNode descriptions

The infrastructure part has been merged, here is the promised

Migration Guide

Please see the Draft PR for concrete examples.
Replace XX with your target’s name below.

  1. Add the following line to CMakeLists.txt:
    tablegen(LLVM XXGenSDNodeInfo.inc -gen-sd-node-info)
    
  2. Implement XXSelectionDAGInfo by deriving it from SelectionDAGGenTargetInfo (note Gen).
  3. Implement XXSubtarget::getSelectionDAGInfo().
  4. Add the following lines to XXISelLowering.h, before XXISD::NodeType enum, outside llvm namespace:
    #define GET_SDNODE_ENUM
    #include "XXGenSDNodeInfo.inc"
    
  5. Remove duplicate enum members suggested by an LSP server / compiler. In the ideal case, all enum members will be removed (along with the enum).
  6. Navigate to XXTargetLowering::getTargetNodeName() and remove switch cases referring to the removed enum members. Using switch (static_cast<XXISD::NodeType>(Opcode)) will help identify the cases that should be removed. If all enum members were removed, just delete the metod.
  7. Move the include added in step 4 and the XXISD::NodeType enum (if it still exists) to XXSelectionDAGInfo.h.
  8. Include XXSelectionDAGInfo.h from XXISelLowering.cpp, XXISelDAGToDAG.cpp, and/or from other files that need the node enumeration.
  9. Add the following lines to XXSelectionDAGInfo.cpp, outside llvm namespace:
    #define GET_SDNODE_DESC
    #include "XXGenSDNodeInfo.inc"
    
  10. Implement XXSelectionDAGInfo constructor like this:
    XXSelectionDAGInfo::XXSelectionDAGInfo()
        : SelectionDAGGenTargetInfo(XXGenSDNodeInfo) {}
    
  11. If XXTargetLowering::getTargetNodeName() wasn’t deleted, move its contents to overridden XXSelectionDAGInfo::getTargetNodeName(). In the new method, delegate to SelectionDAGGenTargetInfo::getTargetNodeName() on the default code path.

For simple targets, this is all that should be necessary.

Troubleshooting & Tips

  • If you relied on relative order of enum members (e.g. for doing range checks), you can rewrite the code to use switch / series of equality comparisons, or (better) use SDNode::TSFlags field to add properties to nodes that can be queried from C++ code. See RISCVSelectionDAGInfo::hasPassthruOp() in the draft for an example.

  • It is possible that the backend will start throwing errors from SelectionDAGGenTargetInfo::verifyTargetNode(), which verifies a newly created SDNode against its definition in a *.td file. In most cases the bugfix would be simple, but as a temporary measure you can override the method to suppress checks for specific nodes.

  • If your target had implemented isTargetStrictFPOpcode(), it can now be replaced with the generic version. Just make sure the nodes have SDNode::IsStrictFP bit set. Similarly, the generic version of isTargetMemoryOpcode() picks up SDNPMemOperand property.

  • Consider describing all SDNodes in *.td files. This will enable the verification functionality for them and will allow removing overrides of TargetSelectionDAGInfo methods.

2 Likes