mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 22:30:13 +00:00
[TableGen][GlobalISel] Allow duplicate RendererFns
Allow different GICustomOperandRenderers to use the same RendererFn. This avoids the need for targets to define a bunch of identical C++ renderer functions with different names. Without this fix TableGen would have emitted code that tried to define the GICR enumeration with duplicate enumerators. Differential Revision: https://reviews.llvm.org/D96587
This commit is contained in:
parent
cea9f05432
commit
7e9ceed9a2
@ -305,16 +305,16 @@ foreach Ty = [i64, p0, p1, p4] in {
|
||||
defm : SMRD_Pattern <"S_LOAD_DWORDX2", Ty>;
|
||||
}
|
||||
|
||||
def gi_as_i32timm : GICustomOperandRenderer<"renderTruncTImm32">,
|
||||
def gi_as_i32timm : GICustomOperandRenderer<"renderTruncTImm">,
|
||||
GISDNodeXFormEquiv<as_i32timm>;
|
||||
|
||||
def gi_as_i16timm : GICustomOperandRenderer<"renderTruncTImm16">,
|
||||
def gi_as_i16timm : GICustomOperandRenderer<"renderTruncTImm">,
|
||||
GISDNodeXFormEquiv<as_i16timm>;
|
||||
|
||||
def gi_as_i8timm : GICustomOperandRenderer<"renderTruncTImm8">,
|
||||
def gi_as_i8timm : GICustomOperandRenderer<"renderTruncTImm">,
|
||||
GISDNodeXFormEquiv<as_i8timm>;
|
||||
|
||||
def gi_as_i1timm : GICustomOperandRenderer<"renderTruncTImm1">,
|
||||
def gi_as_i1timm : GICustomOperandRenderer<"renderTruncTImm">,
|
||||
GISDNodeXFormEquiv<as_i1timm>;
|
||||
|
||||
def gi_NegateImm : GICustomOperandRenderer<"renderNegateImm">,
|
||||
|
@ -275,26 +275,6 @@ private:
|
||||
void renderTruncTImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
|
||||
int OpIdx) const;
|
||||
|
||||
void renderTruncTImm1(MachineInstrBuilder &MIB, const MachineInstr &MI,
|
||||
int OpIdx) const {
|
||||
renderTruncTImm(MIB, MI, OpIdx);
|
||||
}
|
||||
|
||||
void renderTruncTImm8(MachineInstrBuilder &MIB, const MachineInstr &MI,
|
||||
int OpIdx) const {
|
||||
renderTruncTImm(MIB, MI, OpIdx);
|
||||
}
|
||||
|
||||
void renderTruncTImm16(MachineInstrBuilder &MIB, const MachineInstr &MI,
|
||||
int OpIdx) const {
|
||||
renderTruncTImm(MIB, MI, OpIdx);
|
||||
}
|
||||
|
||||
void renderTruncTImm32(MachineInstrBuilder &MIB, const MachineInstr &MI,
|
||||
int OpIdx) const {
|
||||
renderTruncTImm(MIB, MI, OpIdx);
|
||||
}
|
||||
|
||||
void renderNegateImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
|
||||
int OpIdx) const;
|
||||
|
||||
|
@ -51,9 +51,11 @@ def cimm8_xform : SDNodeXForm<imm, [{
|
||||
|
||||
def cimm8 : Operand<i32>, ImmLeaf<i32, [{return isInt<8>(Imm);}], cimm8_xform>;
|
||||
|
||||
def gi_cimm8 : GICustomOperandRenderer<"renderImm8">,
|
||||
def gi_cimm8 : GICustomOperandRenderer<"renderImm">,
|
||||
GISDNodeXFormEquiv<cimm8_xform>;
|
||||
|
||||
def gi_cimm9 : GICustomOperandRenderer<"renderImm">;
|
||||
|
||||
def m1 : OperandWithDefaultOps <i32, (ops (i32 -1))>;
|
||||
def Z : OperandWithDefaultOps <i32, (ops R0)>;
|
||||
def m1Z : OperandWithDefaultOps <i32, (ops (i32 -1), R0)>;
|
||||
@ -206,12 +208,12 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
|
||||
// CHECK-LABEL: // Custom renderers.
|
||||
// CHECK-NEXT: enum {
|
||||
// CHECK-NEXT: GICR_Invalid,
|
||||
// CHECK-NEXT: GICR_renderImm8,
|
||||
// CHECK-NEXT: GICR_renderImm,
|
||||
// CHECK-NEXT: };
|
||||
// CHECK-NEXT: MyTargetInstructionSelector::CustomRendererFn
|
||||
// CHECK-NEXT: MyTargetInstructionSelector::CustomRenderers[] = {
|
||||
// CHECK-NEXT: nullptr, // GICR_Invalid
|
||||
// CHECK-NEXT: &MyTargetInstructionSelector::renderImm8, // gi_cimm8
|
||||
// CHECK-NEXT: &MyTargetInstructionSelector::renderImm,
|
||||
// CHECK-NEXT: };
|
||||
|
||||
// CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const {
|
||||
@ -906,7 +908,7 @@ def MOVimm9 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm9:$i
|
||||
// NOOPT-NEXT: // (imm:{ *:[i32] })<<P:Predicate_cimm8>><<X:cimm8_xform>>:$imm => (MOVcimm8:{ *:[i32] } (cimm8_xform:{ *:[i32] } (imm:{ *:[i32] }):$imm))
|
||||
// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVcimm8,
|
||||
// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
|
||||
// NOOPT-NEXT: GIR_CustomRenderer, /*InsnID*/0, /*OldInsnID*/0, /*Renderer*/GICR_renderImm8, // imm
|
||||
// NOOPT-NEXT: GIR_CustomRenderer, /*InsnID*/0, /*OldInsnID*/0, /*Renderer*/GICR_renderImm, // imm
|
||||
// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0,
|
||||
// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
|
||||
// NOOPT-NEXT: // GIR_Coverage, 10,
|
||||
|
@ -5595,9 +5595,17 @@ void GlobalISelEmitter::run(raw_ostream &OS) {
|
||||
RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
|
||||
llvm::sort(ComplexPredicates, orderByName);
|
||||
|
||||
std::vector<Record *> CustomRendererFns =
|
||||
RK.getAllDerivedDefinitions("GICustomOperandRenderer");
|
||||
llvm::sort(CustomRendererFns, orderByName);
|
||||
std::vector<StringRef> CustomRendererFns;
|
||||
transform(RK.getAllDerivedDefinitions("GICustomOperandRenderer"),
|
||||
std::back_inserter(CustomRendererFns), [](const auto &Record) {
|
||||
return Record->getValueAsString("RendererFn");
|
||||
});
|
||||
// Sort and remove duplicates to get a list of unique renderer functions, in
|
||||
// case some were mentioned more than once.
|
||||
llvm::sort(CustomRendererFns);
|
||||
CustomRendererFns.erase(
|
||||
std::unique(CustomRendererFns.begin(), CustomRendererFns.end()),
|
||||
CustomRendererFns.end());
|
||||
|
||||
unsigned MaxTemporaries = 0;
|
||||
for (const auto &Rule : Rules)
|
||||
@ -5791,17 +5799,15 @@ void GlobalISelEmitter::run(raw_ostream &OS) {
|
||||
OS << "// Custom renderers.\n"
|
||||
<< "enum {\n"
|
||||
<< " GICR_Invalid,\n";
|
||||
for (const auto &Record : CustomRendererFns)
|
||||
OS << " GICR_" << Record->getValueAsString("RendererFn") << ",\n";
|
||||
for (const auto &Fn : CustomRendererFns)
|
||||
OS << " GICR_" << Fn << ",\n";
|
||||
OS << "};\n";
|
||||
|
||||
OS << Target.getName() << "InstructionSelector::CustomRendererFn\n"
|
||||
<< Target.getName() << "InstructionSelector::CustomRenderers[] = {\n"
|
||||
<< " nullptr, // GICR_Invalid\n";
|
||||
for (const auto &Record : CustomRendererFns)
|
||||
OS << " &" << Target.getName()
|
||||
<< "InstructionSelector::" << Record->getValueAsString("RendererFn")
|
||||
<< ", // " << Record->getName() << "\n";
|
||||
for (const auto &Fn : CustomRendererFns)
|
||||
OS << " &" << Target.getName() << "InstructionSelector::" << Fn << ",\n";
|
||||
OS << "};\n\n";
|
||||
|
||||
llvm::stable_sort(Rules, [&](const RuleMatcher &A, const RuleMatcher &B) {
|
||||
|
Loading…
Reference in New Issue
Block a user