I need to add my own vector to riscv backend. I find riscv’s instruction selection is complex.
RISCV’s RVV how to implement instruction selection.
Other target backend such as mips, llvm IR will pattern to Instruction in XXXGenInstrInfo.inc.But RISCV’s vector Instruction pattern to Pseudo Instruction. And I found that RISCV backend doesn’t handle vector in expandPostRAPseudo pass.
I also find:
defm PseudoVADD : VPseudoVALU_VV_VX_VI;
...
multiclass VPseudoVALU_VV_VX_VI<Operand ImmType = simm5, string Constraint = ""> {
foreach m = MxList in {
defvar mx = m.MX;
defm "" : VPseudoBinaryV_VV<m, Constraint>,
SchedBinary<"WriteVIALUV", "ReadVIALUV", "ReadVIALUV", mx,
forceMergeOpRead=true>;
defm "" : VPseudoBinaryV_VX<m, Constraint>,
SchedBinary<"WriteVIALUX", "ReadVIALUV", "ReadVIALUX", mx,
forceMergeOpRead=true>;
defm "" : VPseudoBinaryV_VI<ImmType, m, Constraint>,
SchedUnary<"WriteVIALUI", "ReadVIALUV", mx, forceMergeOpRead=true>;
}
}
...
multiclass VPseudoBinaryV_VV<LMULInfo m, string Constraint = "", int sew = 0> {
defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint, sew>;
}
...
multiclass VPseudoBinary<VReg RetClass,
VReg Op1Class,
DAGOperand Op2Class,
LMULInfo MInfo,
string Constraint = "",
int sew = 0,
int TargetConstraintType = 1> {
let VLMul = MInfo.value, SEW=sew in {
defvar suffix = !if(sew, "_" # MInfo.MX # "_E" # sew, "_" # MInfo.MX);
def suffix : VPseudoBinaryNoMaskTU<RetClass, Op1Class, Op2Class,
Constraint, TargetConstraintType>;
def suffix # "_MASK" : VPseudoBinaryMaskPolicy<RetClass, Op1Class, Op2Class,
Constraint, TargetConstraintType>,
RISCVMaskedPseudo<MaskIdx=3>;
}
}
...
class VPseudoBinaryNoMaskTU<VReg RetClass,
VReg Op1Class,
DAGOperand Op2Class,
string Constraint,
int TargetConstraintType = 1> :
Pseudo<(outs RetClass:$rd),
(ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, AVL:$vl,
ixlenimm:$sew, ixlenimm:$policy), []>,
RISCVVPseudo {
let mayLoad = 0;
let mayStore = 0;
let hasSideEffects = 0;
let Constraints = !interleave([Constraint, "$rd = $merge"], ",");
let TargetOverlapConstraintType = TargetConstraintType;
let HasVLOp = 1;
let HasSEWOp = 1;
let HasVecPolicyOp = 1;
}
...
// This class holds the record of the RISCVVPseudoTable below.
// This represents the information we need in codegen for each pseudo.
// The definition should be consistent with `struct PseudoInfo` in
// RISCVInstrInfo.h.
class RISCVVPseudo {
Pseudo Pseudo = !cast<Pseudo>(NAME); // Used as a key.
Instruction BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
// SEW = 0 is used to denote that the Pseudo is not SEW specific (or unknown).
bits<8> SEW = 0;
bit NeedBeInPseudoTable = 1;
// TargetOverlapConstraintType indicates that these instructions can
// overlap between source operands and destination operands.
// 1 -> default value, remain current constraint
// 2 -> narrow case
// 3 -> widen case
// TODO: Add TargetOverlapConstraintType into PseudosTable for further
// query.
bits<2> TargetOverlapConstraintType = 1;
}
I’am confused RVV’s pseudo instruction how to map to real instruction?