forked from OSchip/llvm-project
[TableGen][GlobalISel] Fix handling of zero_reg
When generating matching tables for GlobalISel, TableGen would output "::zero_reg" whenever encountering the zero_reg, which in turn would result in compilation error. This patch fixes that by instead outputting NoRegister (== 0), which is the same result that TableGen produces when generating matching tables for ISelDAG. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D86215
This commit is contained in:
parent
2afe4becec
commit
c10200536f
|
@ -164,8 +164,6 @@ createARMInstructionSelector(const ARMBaseTargetMachine &TM,
|
|||
}
|
||||
}
|
||||
|
||||
const unsigned zero_reg = 0;
|
||||
|
||||
#define GET_GLOBALISEL_IMPL
|
||||
#include "ARMGenGlobalISel.inc"
|
||||
#undef GET_GLOBALISEL_IMPL
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
// RUN: llvm-tblgen -gen-global-isel -optimize-match-table=false -I %p/../../include -I %p/Common %s -o - < %s | FileCheck %s
|
||||
|
||||
include "llvm/Target/Target.td"
|
||||
include "GlobalISelEmitterCommon.td"
|
||||
|
||||
def P0 : Register<"p0"> { let Namespace = "MyTarget"; }
|
||||
def PR32 : RegisterClass<"MyTarget", [i32], 32, (add P0)>;
|
||||
def PR32Op : RegisterOperand<PR32>;
|
||||
|
||||
def pred : PredicateOperand<OtherVT,
|
||||
(ops PR32:$FR),
|
||||
(ops (i32 zero_reg))> {}
|
||||
class PredI<dag OOps, dag IOps, list<dag> Pat>
|
||||
: Instruction {
|
||||
let Namespace = "MyTarget";
|
||||
let OutOperandList = OOps;
|
||||
let InOperandList = !con(IOps, (ins pred:$pred));
|
||||
let Pattern = Pat;
|
||||
}
|
||||
|
||||
def INST : PredI<(outs GPR32:$dst), (ins GPR32:$src), []>;
|
||||
|
||||
// CHECK: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
|
||||
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_LOAD,
|
||||
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
|
||||
// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic,
|
||||
// CHECK-NEXT: // MIs[0] dst
|
||||
// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
|
||||
// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
|
||||
// CHECK-NEXT: // MIs[0] src
|
||||
// CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
|
||||
// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
|
||||
// CHECK-NEXT: // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (INST:{ *:[i32] } GPR32:{ *:[i32] }:$src)
|
||||
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INST,
|
||||
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
|
||||
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src
|
||||
// CHECK-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::NoRegister, /*AddRegisterRegFlags*/0,
|
||||
// CHECK-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList,
|
||||
// CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
|
||||
// CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
|
||||
def : Pat<(i32 (load GPR32:$src)),
|
||||
(INST GPR32:$src)>;
|
|
@ -266,6 +266,11 @@ StringRef CodeGenTarget::getInstNamespace() const {
|
|||
return "";
|
||||
}
|
||||
|
||||
StringRef CodeGenTarget::getRegNamespace() const {
|
||||
auto &RegClasses = RegBank->getRegClasses();
|
||||
return RegClasses.size() > 0 ? RegClasses.front().Namespace : "";
|
||||
}
|
||||
|
||||
Record *CodeGenTarget::getInstructionSet() const {
|
||||
return TargetRec->getValueAsDef("InstructionSet");
|
||||
}
|
||||
|
|
|
@ -73,6 +73,9 @@ public:
|
|||
///
|
||||
StringRef getInstNamespace() const;
|
||||
|
||||
/// getRegNamespace - Return the target-specific register namespace.
|
||||
StringRef getRegNamespace() const;
|
||||
|
||||
/// getInstructionSet - Return the InstructionSet object.
|
||||
///
|
||||
Record *getInstructionSet() const;
|
||||
|
|
|
@ -2729,12 +2729,13 @@ protected:
|
|||
unsigned InsnID;
|
||||
const Record *RegisterDef;
|
||||
bool IsDef;
|
||||
const CodeGenTarget &Target;
|
||||
|
||||
public:
|
||||
AddRegisterRenderer(unsigned InsnID, const Record *RegisterDef,
|
||||
bool IsDef = false)
|
||||
AddRegisterRenderer(unsigned InsnID, const CodeGenTarget &Target,
|
||||
const Record *RegisterDef, bool IsDef = false)
|
||||
: OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef),
|
||||
IsDef(IsDef) {}
|
||||
IsDef(IsDef), Target(Target) {}
|
||||
|
||||
static bool classof(const OperandRenderer *R) {
|
||||
return R->getKind() == OR_Register;
|
||||
|
@ -2742,13 +2743,17 @@ public:
|
|||
|
||||
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
||||
Table << MatchTable::Opcode("GIR_AddRegister")
|
||||
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
||||
<< MatchTable::NamedValue(
|
||||
(RegisterDef->getValue("Namespace")
|
||||
? RegisterDef->getValueAsString("Namespace")
|
||||
: ""),
|
||||
RegisterDef->getName())
|
||||
<< MatchTable::Comment("AddRegisterRegFlags");
|
||||
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID);
|
||||
if (RegisterDef->getName() != "zero_reg") {
|
||||
Table << MatchTable::NamedValue(
|
||||
(RegisterDef->getValue("Namespace")
|
||||
? RegisterDef->getValueAsString("Namespace")
|
||||
: ""),
|
||||
RegisterDef->getName());
|
||||
} else {
|
||||
Table << MatchTable::NamedValue(Target.getRegNamespace(), "NoRegister");
|
||||
}
|
||||
Table << MatchTable::Comment("AddRegisterRegFlags");
|
||||
|
||||
// TODO: This is encoded as a 64-bit element, but only 16 or 32-bits are
|
||||
// really needed for a physical register reference. We can pack the
|
||||
|
@ -4419,7 +4424,7 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
|
|||
return failedImport("Dst operand has an unsupported type");
|
||||
|
||||
if (ChildRec->isSubClassOf("Register")) {
|
||||
DstMIBuilder.addRenderer<AddRegisterRenderer>(ChildRec);
|
||||
DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, ChildRec);
|
||||
return InsertPt;
|
||||
}
|
||||
|
||||
|
@ -4479,7 +4484,8 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
|
|||
&Target.getInstruction(RK.getDef("COPY")));
|
||||
BuildMIAction &CopyToPhysRegMIBuilder =
|
||||
*static_cast<BuildMIAction *>(InsertPt->get());
|
||||
CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>(PhysInput.first,
|
||||
CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>(Target,
|
||||
PhysInput.first,
|
||||
true);
|
||||
CopyToPhysRegMIBuilder.addRenderer<CopyPhysRegRenderer>(PhysInput.first);
|
||||
}
|
||||
|
@ -4870,7 +4876,7 @@ Error GlobalISelEmitter::importDefaultOperandRenderers(
|
|||
IDMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
|
||||
DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
|
||||
} else {
|
||||
DstMIBuilder.addRenderer<AddRegisterRenderer>(Def);
|
||||
DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, Def);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue