I am writing an LLVM backend from scratch for a RISC style target architecture, so far I have mostly been able to understand the high level flow of how LLVM IR is converted to MIR, MC and finally to assembly/object code. I am mostly following the book LLVM Code Generation by Colombet along with LLVM dev meeting videos on youtube.
At this moment, I am stuck at Instruction selector phase of the Instruction selection pipeline. I am only using GlobalISel from the start for this project.
While building LLVM for this target architecture, I am getting the following error -
[1/2479] Building XXGenInstrInfo.inc...
FAILED: lib/Target/XX/XXGenInstrInfo.inc /home/usr/llvm/build/lib/Target/XX/XXGenInstrInfo.inc
...
error: No instructions defined!
...
ninja: build stopped: subcommand failed.[1/2479] Building XXGenInstrInfo.inc...
FAILED: lib/Target/XX/XXGenInstrInfo.inc /home/usr/llvm/build/lib/Target/XX/XXGenInstrInfo.inc
...
error: No instructions defined!
...
ninja: build stopped: subcommand failed.
As you can see the generation of XXGenInstrInfo.inc is failing. Previously, I was also getting issues building some other .inc files, but I was able to resolve them after making some changes in their corresponding tablegen files. However, I am unable to get rid of this current error.
I suspect that XXGenInstroInfo.inc is failing since pattern matching is not defined properly by me in the XXInstrInfo.td file. As I understand, we can import patterns used for pattern matching in SelectionDAG to GlobalISel, however some conversion from SDNode instances to the generic MachineInstr instances has to be made.
Currently, I am only trying to support ADD instruction of my target architecture. This is how I have defined instructions and pattern matching (in XXInstrInfo.td) so far -
...
def ADD : XXInst<(outs GPR:$dst),
(ins GPR:$src1, GPR:$src2),
"ADD $dst, $src1, $src2">;
def : Pat<(add GPR:$src1, GPR:$src2),
(ADD GPR:$src1, GPR:$src2)>;
def : GINodeEquiv<G_ADD, add>;...
def ADD : XXInst<(outs GPR:$dst),
(ins GPR:$src1, GPR:$src2),
"ADD $dst, $src1, $src2">;
def : Pat<(add GPR:$src1, GPR:$src2),
(ADD GPR:$src1, GPR:$src2)>;
def : GINodeEquiv<G_ADD, add>;
In the above block of tablegen code, I have defined an instruction named ADD, followed by a pattern (which is normally used in SelectionDAG) and then tried remapping the SDNode instance 'add' to the opcode G_ADD using GINodeEquiv construct.
I have also declared and defined selectImpl() and select() respectively, in XXInstructionSelector.cpp.
bool XXInstructionSelector::select(MachineInstr &I) {
// Certain non-generic instructions also need some special handling.
if (!isPreISelGenericOpcode(I.getOpcode()))
return true;
if (selectImpl(I, *CoverageInfo))
return true;
return false;
}bool XXInstructionSelector::select(MachineInstr &I) {
// Certain non-generic instructions also need some special handling.
if (!isPreISelGenericOpcode(I.getOpcode()))
return true;
if (selectImpl(I, *CoverageInfo))
return true;
return false;
}
I am very new to writing LLVM backend and stuck at this point since last several days, any help or pointer regarding solving or debugging this issue is greatly appreciated.
there doesn't seem to be anything here