Selecting an instruction

An IR instruction in DAG needs to be lowered to a target-specific instruction. The SDAG node contains IR, which needs to be mapped on machine-specific DAG nodes. The outcome of the selection phase is ready for scheduling.

Getting ready

  1. For selecting a machine-specific instruction, a separate class, TOYDAGToDAGISel, needs to be defined. To compile the file containing this class definition, add the filename to the CMakeLists.txt file in the TOY folder:
    $ vi CMakeLists .txt
    add_llvm_target(...
    ...
    TOYISelDAGToDAG.cpp
    ...
    )
  2. A pass entry needs to be added in the TOYTargetMachine.h and TOYTargetMachine.cpp files:
    $ vi TOYTargetMachine.h
    const TOYInstrInfo *getInstrInfo() const override {
    return getSubtargetImpl()->getInstrInfo();
    }
  3. The following code in TOYTargetMachine.cpp will create a pass in the instruction selection stage:
    class TOYPassConfig : public TargetPassConfig {
    public:
    ...
    virtual bool addInstSelector();
    };
    ...
    bool TOYPassConfig::addInstSelector() {
    addPass(createTOYISelDag(getTOYTargetMachine()));
    return false;
    }

How to do it…

To define an instruction selection function, proceed with the following steps:

  1. Create a file called TOYISelDAGToDAG.cpp:
    $ vi TOYISelDAGToDAG.cpp
    
  2. Include the following files:
    #include "TOY.h"
    #include "TOYTargetMachine.h"
    #include "llvm/CodeGen/SelectionDAGISel.h"
    #include "llvm/Support/Compiler.h"
    #include "llvm/Support/Debug.h"
    #include "TOYInstrInfo.h"
    
  3. Define a new class called TOYDAGToDAGISel as follows, which will inherit from the SelectionDAGISel class:
    class TOYDAGToDAGISel : public SelectionDAGISel {
      const TOYSubtarget &Subtarget;
    
    public:
      explicit TOYDAGToDAGISel(TOYTargetMachine &TM, CodeGenOpt::Level OptLevel)
    : SelectionDAGISel(TM, OptLevel),   Subtarget(*TM.getSubtargetImpl()) {}
    };
  4. The most important function to define in this class is Select(), which will return an SDNode object specific to the machine instruction:

    Declare it in the class:

    SDNode *Select(SDNode *N);
    

    Define it further as follows:

    SDNode *TOYDAGToDAGISel::Select(SDNode *N) {
      return SelectCode(N);
    }
    
  5. Another important function is used to define the address selection function, which will calculate the base and offset of the address for load and store operations.

    Declare it as shown here:

        bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset);

    Define it further, like this:

    bool TOYDAGToDAGISel::SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) {
      if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
            Base = CurDAG->getTargetFrameIndex(FIN->getIndex(),
                                           getTargetLowering()- >getPointerTy());
            Offset = CurDAG->getTargetConstant(0, MVT::i32);
            return true;
        }
      if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
            Addr.getOpcode() == ISD::TargetGlobalAddress ||
            Addr.getOpcode() == ISD::TargetGlobalTLSAddress) {
            return false; // direct calls.
      }
    
        Base = Addr;
        Offset = CurDAG->getTargetConstant(0, MVT::i32);
        return true;
    }
  6. The createTOYISelDag pass converts a legalized DAG into a toy-specific DAG, ready for instruction scheduling in the same file:
    FunctionPass *llvm::createTOYISelDag(TOYTargetMachine &TM, CodeGenOpt::Level OptLevel) {
    return new TOYDAGToDAGISel(TM, OptLevel);
    }

How it works…

The TOYDAGToDAGISel::Select() function of TOYISelDAGToDAG.cpp is used for the selection of the OP code DAG node, while TOYDAGToDAGISel::SelectAddr() is used for the selection of the DATA DAG node with the addr type. Note that if the address is global or external, we return false for the address, since its address is calculated in the global context.

See also

  • For details on the selection of DAG for machine instructions of complex architectures, such as ARM, look into the lib/Target/ARM/ARMISelDAGToDAG.cpp file in the LLVM source code.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.159.178