From 8dcdc37a5fca72db61c63304c52e0e2da925143a Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Thu, 12 Jan 2023 21:02:23 +0000 Subject: [PATCH] [MC] Store operand info immediately after the TargetInsts table. NFC. This shrinks MCInstrDesc (and hence the whole TargetInsts table) because we can store a 16-bit offset value to access the operands info, instead of a pointer. This also reduces the number of relocs that need to be applied when LLVM is compiled as position-independent code. Differential Revision: https://reviews.llvm.org/D142219 --- llvm/include/llvm/MC/MCInstrDesc.h | 15 ++-- llvm/unittests/CodeGen/MachineInstrTest.cpp | 74 +++++++++-------- llvm/unittests/CodeGen/RegAllocScoreTest.cpp | 2 +- llvm/utils/TableGen/InstrInfoEmitter.cpp | 115 ++++++++++++++++----------- 4 files changed, 117 insertions(+), 89 deletions(-) diff --git a/llvm/include/llvm/MC/MCInstrDesc.h b/llvm/include/llvm/MC/MCInstrDesc.h index bc69f88..0f406cb 100644 --- a/llvm/include/llvm/MC/MCInstrDesc.h +++ b/llvm/include/llvm/MC/MCInstrDesc.h @@ -210,9 +210,9 @@ public: unsigned char NumImplicitUses; // Num of regs implicitly used unsigned char NumImplicitDefs; // Num of regs implicitly defined unsigned short ImplicitOffset; // Offset to start of implicit op list + unsigned short OpInfoOffset; // Offset to info about operands uint64_t Flags; // Flags identifying machine instr class uint64_t TSFlags; // Target Specific Flag values - const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands /// Returns the value of the specified operand constraint if /// it is present. Returns -1 if it is not present. @@ -237,7 +237,8 @@ public: unsigned getNumOperands() const { return NumOperands; } ArrayRef operands() const { - return ArrayRef(OpInfo, NumOperands); + auto OpInfo = reinterpret_cast(this + Opcode + 1); + return ArrayRef(OpInfo + OpInfoOffset, NumOperands); } /// Return the number of MachineOperands that are register @@ -563,8 +564,9 @@ public: /// reading the flags. Likewise, the variable shift instruction on X86 is /// marked as implicitly reading the 'CL' register, which it always does. ArrayRef implicit_uses() const { - auto ImplicitOps = reinterpret_cast(this + Opcode + 1); - return {ImplicitOps + ImplicitOffset, NumImplicitUses}; + auto ImplicitOps = + reinterpret_cast(this + Opcode + 1) + ImplicitOffset; + return {ImplicitOps, NumImplicitUses}; } /// Return a list of registers that are potentially written by any @@ -576,8 +578,9 @@ public: /// registers. For that instruction, this will return a list containing the /// EAX/EDX/EFLAGS registers. ArrayRef implicit_defs() const { - auto ImplicitOps = reinterpret_cast(this + Opcode + 1); - return {ImplicitOps + ImplicitOffset + NumImplicitUses, NumImplicitDefs}; + auto ImplicitOps = + reinterpret_cast(this + Opcode + 1) + ImplicitOffset; + return {ImplicitOps + NumImplicitUses, NumImplicitDefs}; } /// Return true if this instruction implicitly diff --git a/llvm/unittests/CodeGen/MachineInstrTest.cpp b/llvm/unittests/CodeGen/MachineInstrTest.cpp index 62b1c6f..be409a5 100644 --- a/llvm/unittests/CodeGen/MachineInstrTest.cpp +++ b/llvm/unittests/CodeGen/MachineInstrTest.cpp @@ -51,23 +51,24 @@ TEST(IsIdenticalToTest, DifferentDefs) { unsigned short NumOps = 2; unsigned char NumDefs = 1; - MCOperandInfo OpInfo[] = { - {0, 0, MCOI::OPERAND_REGISTER, 0}, - {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}; - MCInstrDesc MCID = { - 0, NumOps, NumDefs, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef, - 0, OpInfo}; + struct { + MCInstrDesc MCID; + MCOperandInfo OpInfo[2]; + } Table = { + {0, NumOps, NumDefs, 0, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef, 0}, + {{0, 0, MCOI::OPERAND_REGISTER, 0}, + {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}}; // Create two MIs with different virtual reg defs and the same uses. unsigned VirtualDef1 = -42; // The value doesn't matter, but the sign does. unsigned VirtualDef2 = -43; unsigned VirtualUse = -44; - auto MI1 = MF->CreateMachineInstr(MCID, DebugLoc()); + auto MI1 = MF->CreateMachineInstr(Table.MCID, DebugLoc()); MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true)); MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false)); - auto MI2 = MF->CreateMachineInstr(MCID, DebugLoc()); + auto MI2 = MF->CreateMachineInstr(Table.MCID, DebugLoc()); MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true)); MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false)); @@ -83,11 +84,11 @@ TEST(IsIdenticalToTest, DifferentDefs) { // sentinel register. unsigned SentinelReg = 0; - auto MI3 = MF->CreateMachineInstr(MCID, DebugLoc()); + auto MI3 = MF->CreateMachineInstr(Table.MCID, DebugLoc()); MI3->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true)); MI3->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ true)); - auto MI4 = MF->CreateMachineInstr(MCID, DebugLoc()); + auto MI4 = MF->CreateMachineInstr(Table.MCID, DebugLoc()); MI4->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true)); MI4->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ false)); @@ -122,12 +123,13 @@ TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) { unsigned short NumOps = 2; unsigned char NumDefs = 1; - MCOperandInfo OpInfo[] = { - {0, 0, MCOI::OPERAND_REGISTER, 0}, - {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}; - MCInstrDesc MCID = { - 0, NumOps, NumDefs, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef, - 0, OpInfo}; + struct { + MCInstrDesc MCID; + MCOperandInfo OpInfo[2]; + } Table = { + {0, NumOps, NumDefs, 0, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef, 0}, + {{0, 0, MCOI::OPERAND_REGISTER, 0}, + {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}}; // Define a series of instructions with different kinds of operands and make // sure that the hash function is consistent with isEqual for various @@ -138,37 +140,37 @@ TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) { unsigned SentinelReg = 0; unsigned PhysicalReg = 45; - auto VD1VU = MF->CreateMachineInstr(MCID, DebugLoc()); + auto VD1VU = MF->CreateMachineInstr(Table.MCID, DebugLoc()); VD1VU->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true)); VD1VU->addOperand(*MF, MachineOperand::CreateReg(VirtualReg, /*isDef*/ false)); - auto VD2VU = MF->CreateMachineInstr(MCID, DebugLoc()); + auto VD2VU = MF->CreateMachineInstr(Table.MCID, DebugLoc()); VD2VU->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true)); VD2VU->addOperand(*MF, MachineOperand::CreateReg(VirtualReg, /*isDef*/ false)); - auto VD1SU = MF->CreateMachineInstr(MCID, DebugLoc()); + auto VD1SU = MF->CreateMachineInstr(Table.MCID, DebugLoc()); VD1SU->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true)); VD1SU->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ false)); - auto VD1SD = MF->CreateMachineInstr(MCID, DebugLoc()); + auto VD1SD = MF->CreateMachineInstr(Table.MCID, DebugLoc()); VD1SD->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true)); VD1SD->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ true)); - auto VD2PU = MF->CreateMachineInstr(MCID, DebugLoc()); + auto VD2PU = MF->CreateMachineInstr(Table.MCID, DebugLoc()); VD2PU->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true)); VD2PU->addOperand(*MF, MachineOperand::CreateReg(PhysicalReg, /*isDef*/ false)); - auto VD2PD = MF->CreateMachineInstr(MCID, DebugLoc()); + auto VD2PD = MF->CreateMachineInstr(Table.MCID, DebugLoc()); VD2PD->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true)); VD2PD->addOperand(*MF, @@ -200,8 +202,11 @@ TEST(MachineInstrPrintingTest, DebugLocPrinting) { Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); - MCOperandInfo OpInfo{0, 0, MCOI::OPERAND_REGISTER, 0}; - MCInstrDesc MCID = {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, &OpInfo}; + struct { + MCInstrDesc MCID; + MCOperandInfo OpInfo; + } Table = {{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, MCOI::OPERAND_REGISTER, 0}}; DIFile *DIF = DIFile::getDistinct(Ctx, "filename", ""); DISubprogram *DIS = DISubprogram::getDistinct( @@ -209,7 +214,7 @@ TEST(MachineInstrPrintingTest, DebugLocPrinting) { DISubprogram::SPFlagZero, nullptr); DILocation *DIL = DILocation::get(Ctx, 1, 5, DIS); DebugLoc DL(DIL); - MachineInstr *MI = MF->CreateMachineInstr(MCID, DL); + MachineInstr *MI = MF->CreateMachineInstr(Table.MCID, DL); MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ true)); std::string str; @@ -228,7 +233,7 @@ TEST(MachineInstrSpan, DistanceBegin) { auto MF = createMachineFunction(Ctx, Mod); auto MBB = MF->CreateMachineBasicBlock(); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; auto MII = MBB->begin(); MachineInstrSpan MIS(MII, MBB); @@ -245,7 +250,7 @@ TEST(MachineInstrSpan, DistanceEnd) { auto MF = createMachineFunction(Ctx, Mod); auto MBB = MF->CreateMachineBasicBlock(); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; auto MII = MBB->end(); MachineInstrSpan MIS(MII, MBB); @@ -260,7 +265,7 @@ TEST(MachineInstrExtraInfo, AddExtraInfo) { LLVMContext Ctx; Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; auto MI = MF->CreateMachineInstr(MCID, DebugLoc()); auto MAI = MCAsmInfo(); @@ -320,7 +325,7 @@ TEST(MachineInstrExtraInfo, ChangeExtraInfo) { LLVMContext Ctx; Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; auto MI = MF->CreateMachineInstr(MCID, DebugLoc()); auto MAI = MCAsmInfo(); @@ -361,7 +366,7 @@ TEST(MachineInstrExtraInfo, RemoveExtraInfo) { LLVMContext Ctx; Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; auto MI = MF->CreateMachineInstr(MCID, DebugLoc()); auto MAI = MCAsmInfo(); @@ -428,10 +433,9 @@ TEST(MachineInstrDebugValue, AddDebugValueOperand) { TargetOpcode::DBG_INSTR_REF, TargetOpcode::DBG_PHI, TargetOpcode::DBG_LABEL}) { const MCInstrDesc MCID = { - Opcode, 0, 0, - 0, 0, 0, - 0, 0, (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic), - 0, nullptr}; + Opcode, 0, 0, 0, 0, + 0, 0, 0, 0, (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic), + 0}; auto *MI = MF->CreateMachineInstr(MCID, DebugLoc()); MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ false)); @@ -461,7 +465,7 @@ TEST(MachineInstrBuilder, BuildMI) { Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); auto MBB = MF->CreateMachineBasicBlock(); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; EXPECT_THAT(BuildMI(*MF, MIMD, MCID), HasMIMetadata(MIMD)); EXPECT_THAT(BuildMI(*MF, MIMD, MCID), HasMIMetadata(MIMD)); EXPECT_THAT(BuildMI(*MBB, MBB->end(), MIMD, MCID), HasMIMetadata(MIMD)); diff --git a/llvm/unittests/CodeGen/RegAllocScoreTest.cpp b/llvm/unittests/CodeGen/RegAllocScoreTest.cpp index 60ad94b..ff7146e 100644 --- a/llvm/unittests/CodeGen/RegAllocScoreTest.cpp +++ b/llvm/unittests/CodeGen/RegAllocScoreTest.cpp @@ -64,7 +64,7 @@ enum MockInstrId { const std::array MockInstrDescs{{ #define MOCK_SPEC(IGNORE, OPCODE, FLAGS) \ - {OPCODE, 0, 0, 0, 0, 0, 0, 0, FLAGS, 0, nullptr}, + {OPCODE, 0, 0, 0, 0, 0, 0, 0, 0, FLAGS, 0}, MOCK_INSTR(MOCK_SPEC) #undef MOCK_SPEC }}; diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp index 58dec4e..d305858 100644 --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -61,7 +61,9 @@ public: private: void emitEnums(raw_ostream &OS); - typedef std::map, unsigned> OperandInfoMapTy; + typedef std::vector OperandInfoTy; + typedef std::vector OperandInfoListTy; + typedef std::map OperandInfoMapTy; /// The keys of this map are maps which have OpName enum values as their keys /// and instruction operand indices as their values. The values of this map @@ -86,9 +88,8 @@ private: void emitFeatureVerifier(raw_ostream &OS, const CodeGenTarget &Target); void emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, - std::map, unsigned> &EL, - const OperandInfoMapTy &OpInfo, - raw_ostream &OS); + std::map, unsigned> &EL, + const OperandInfoMapTy &OperandInfo, raw_ostream &OS); void emitOperandTypeMappings( raw_ostream &OS, const CodeGenTarget &Target, ArrayRef NumberedInstructions); @@ -108,8 +109,10 @@ private: ArrayRef NumberedInstructions); // Operand information. - void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs); - std::vector GetOperandInfo(const CodeGenInstruction &Inst); + unsigned CollectOperandInfo(OperandInfoListTy &OperandInfoList, + OperandInfoMapTy &OperandInfoMap); + void EmitOperandInfo(raw_ostream &OS, OperandInfoListTy &OperandInfoList); + OperandInfoTy GetOperandInfo(const CodeGenInstruction &Inst); }; } // end anonymous namespace @@ -118,9 +121,9 @@ private: // Operand Info Emission. //===----------------------------------------------------------------------===// -std::vector +InstrInfoEmitter::OperandInfoTy InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { - std::vector Result; + OperandInfoTy Result; for (auto &Op : Inst.Operands) { // Handle aggregate operands and normal operands the same way by expanding @@ -207,23 +210,30 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { return Result; } -void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, - OperandInfoMapTy &OperandInfoIDs) { - // ID #0 is for no operand info. - unsigned OperandListNum = 0; - OperandInfoIDs[std::vector()] = ++OperandListNum; - +unsigned +InstrInfoEmitter::CollectOperandInfo(OperandInfoListTy &OperandInfoList, + OperandInfoMapTy &OperandInfoMap) { const CodeGenTarget &Target = CDP.getTargetInfo(); + unsigned Offset = 0; for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) { - std::vector OperandInfo = GetOperandInfo(*Inst); - unsigned &N = OperandInfoIDs[OperandInfo]; - if (N != 0) continue; - - N = ++OperandListNum; - OS << "static const MCOperandInfo OperandInfo" << N << "[] = { "; - for (const std::string &Info : OperandInfo) - OS << "{ " << Info << " }, "; - OS << "};\n"; + OperandInfoTy OperandInfo = GetOperandInfo(*Inst); + if (OperandInfoMap.insert({OperandInfo, Offset}).second) { + OperandInfoList.push_back(OperandInfo); + Offset += OperandInfo.size(); + } + } + return Offset; +} + +void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, + OperandInfoListTy &OperandInfoList) { + unsigned Offset = 0; + for (auto &OperandInfo : OperandInfoList) { + OS << " /* " << Offset << " */"; + for (auto &Info : OperandInfo) + OS << " { " << Info << " },"; + OS << '\n'; + Offset += OperandInfo.size(); } } @@ -886,6 +896,13 @@ void InstrInfoEmitter::run(raw_ostream &OS) { const std::string &TargetName = std::string(Target.getName()); Record *InstrInfo = Target.getInstructionSet(); + // Collect all of the operand info records. + Records.startTimer("Collect operand info"); + OperandInfoListTy OperandInfoList; + OperandInfoMapTy OperandInfoMap; + unsigned OperandInfoSize = + CollectOperandInfo(OperandInfoList, OperandInfoMap); + // Collect all of the instruction's implicit uses and defs. Records.startTimer("Collect uses/defs"); std::map, unsigned> EmittedLists; @@ -908,8 +925,11 @@ void InstrInfoEmitter::run(raw_ostream &OS) { OS << "struct " << TargetName << "InstrTable {\n"; OS << " MCInstrDesc Insts[" << NumberedInstructions.size() << "];\n"; - OS << " static_assert(alignof(MCInstrDesc) >= alignof(MCPhysReg), " - "\"Unwanted padding between Insts and ImplicitOps\");\n"; + OS << " static_assert(alignof(MCInstrDesc) >= alignof(MCOperandInfo), " + "\"Unwanted padding between Insts and OperandInfo\");\n"; + OS << " MCOperandInfo OperandInfo[" << OperandInfoSize << "];\n"; + OS << " static_assert(alignof(MCOperandInfo) >= alignof(MCPhysReg), " + "\"Unwanted padding between OperandInfo and ImplicitOps\");\n"; OS << " MCPhysReg ImplicitOps[" << std::max(ImplicitListSize, 1U) << "];\n"; OS << "};\n\n"; @@ -921,14 +941,12 @@ void InstrInfoEmitter::run(raw_ostream &OS) { OS << "#undef GET_INSTRINFO_MC_DESC\n"; OS << "namespace llvm {\n\n"; - // Emit all of the operand info records. - Records.startTimer("Emit operand info"); - OperandInfoMapTy OperandInfoIDs; - EmitOperandInfo(OS, OperandInfoIDs); - OS << "\n"; - // Emit all of the MCInstrDesc records in reverse ENUM ordering. Records.startTimer("Emit InstrDesc records"); + OS << "static_assert(sizeof(MCOperandInfo) % sizeof(MCPhysReg) == 0);\n"; + OS << "static constexpr unsigned " << TargetName << "ImpOpBase = sizeof " + << TargetName << "InstrTable::OperandInfo / (sizeof(MCPhysReg));\n\n"; + OS << "extern const " << TargetName << "InstrTable " << TargetName << "Descs = {\n {\n"; SequenceToOffsetTable InstrNames; @@ -937,11 +955,17 @@ void InstrInfoEmitter::run(raw_ostream &OS) { // Keep a list of the instruction names. InstrNames.add(std::string(Inst->TheDef->getName())); // Emit the record into the table. - emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoIDs, OS); + emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoMap, OS); } OS << " }, {\n"; + // Emit all of the operand info records. + Records.startTimer("Emit operand info"); + EmitOperandInfo(OS, OperandInfoList); + + OS << " }, {\n"; + // Emit all of the instruction's implicit uses and defs. Records.startTimer("Emit uses/defs"); for (auto &List : ImplicitLists) { @@ -1115,11 +1139,10 @@ void InstrInfoEmitter::run(raw_ostream &OS) { emitFeatureVerifier(OS, Target); } -void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, - Record *InstrInfo, - std::map, unsigned> &EmittedLists, - const OperandInfoMapTy &OpInfo, - raw_ostream &OS) { +void InstrInfoEmitter::emitRecord( + const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, + std::map, unsigned> &EmittedLists, + const OperandInfoMapTy &OperandInfoMap, raw_ostream &OS) { int MinOperands = 0; if (!Inst.Operands.empty()) // Each logical operand can be multiple MI operands. @@ -1131,13 +1154,18 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, << Inst.TheDef->getValueAsInt("Size") << ",\t" << SchedModels.getSchedClassIdx(Inst) << ",\t"; + CodeGenTarget &Target = CDP.getTargetInfo(); + // Emit the implicit use/def list... OS << Inst.ImplicitUses.size() << ",\t" << Inst.ImplicitDefs.size() << ",\t"; std::vector ImplicitOps = Inst.ImplicitUses; llvm::append_range(ImplicitOps, Inst.ImplicitDefs); - OS << EmittedLists[ImplicitOps] << ",\t0"; + OS << Target.getName() << "ImpOpBase + " << EmittedLists[ImplicitOps] + << ",\t"; - CodeGenTarget &Target = CDP.getTargetInfo(); + // Emit the operand info offset. + OperandInfoTy OperandInfo = GetOperandInfo(Inst); + OS << OperandInfoMap.find(OperandInfo)->second << ",\t0"; // Emit all of the target independent flags... if (Inst.isPreISelOpcode) OS << "|(1ULL< OperandInfo = GetOperandInfo(Inst); - if (OperandInfo.empty()) - OS << "nullptr"; - else - OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; + OS << "ULL"; OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; } -- 2.7.4