Implementing DAG-to-DAG transformations within instruction selection – Instruction Selection
By Peggy Johnston / September 18, 2023 / No Comments / Creating the disassembler, Emitting machine instructions, Global instruction selection, Implementing M88kSubtarget, ITCertification Exams
One crucial part is still missing: we need to define the pass that performs the DAG transformations defined in the target descriptions. The class is called M88kDAGToDAGISel and is stored in the M88kISelDAGToDAG.cpp file. Most of the class is generated, but we still need to add some code:
- We’ll begin by defining the debug type and providing a descriptive name for the pass:
define DEBUG_TYPE “m88k-isel”
define PASS_NAME
“M88k DAG->DAG Pattern Instruction Selection”
- Then, we must declare the class inside an anonymous namespace. We will only override the Select() method; the other code is generated and included in the body of the class:
class M88kDAGToDAGISel : public SelectionDAGISel {
public:
static char ID;
M88kDAGToDAGISel(M88kTargetMachine &TM,
CodeGenOpt::Level OptLevel)
: SelectionDAGISel(ID, TM, OptLevel) {}
void Select(SDNode *Node) override;
include “M88kGenDAGISel.inc”
};
} // end anonymous namespace
- After, we must add the code to initialize the pass. The LLVM backends still use the legacy pass manager, and the setup differs from the pass manager used for IR transformations. The static member ID value is used to identify the pass. Initializing the pass can be implemented using the INITIALIZE_PASS macro, which expands to C++ code. We must also add a factory method to create an instance of the pass:
char M88kDAGToDAGISel::ID = 0;
INITIALIZE_PASS(M88kDAGToDAGISel, DEBUG_TYPE, PASS_NAME,
false, false)
FunctionPass *
llvm::createM88kISelDag(M88kTargetMachine &TM,
CodeGenOpt::Level OptLevel) {
return new M88kDAGToDAGISel(TM, OptLevel);
}
- Finally, we must implement the Select() method. For now, we only call the generated code. However, if we encounter a complex transformation that we cannot express as a DAG pattern, then we can add our own code to perform the transformation before calling the generated code:
void M88kDAGToDAGISel::Select(SDNode *Node) {
SelectCode(Node);
}
With that, we have implemented the instruction selection. However, we still need to add some support classes before we can do the first test. We’ll look at those classes in the next few sections.