[llvm] 1220c5d - [MC] Store implicit ops immediately after the TargetInsts table. NFC.

Jay Foad via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 27 03:39:53 PDT 2023


Author: Jay Foad
Date: 2023-03-27T11:39:18+01:00
New Revision: 1220c5d4ac00ebf64128678e4ffd2abd9f5d60ae

URL: https://github.com/llvm/llvm-project/commit/1220c5d4ac00ebf64128678e4ffd2abd9f5d60ae
DIFF: https://github.com/llvm/llvm-project/commit/1220c5d4ac00ebf64128678e4ffd2abd9f5d60ae.diff

LOG: [MC] Store implicit ops 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 implicit operands,
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/D142218

Added: 
    

Modified: 
    llvm/include/llvm/MC/MCInstrDesc.h
    llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/unittests/CodeGen/MachineInstrTest.cpp
    llvm/unittests/CodeGen/RegAllocScoreTest.cpp
    llvm/utils/TableGen/InstrInfoEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCInstrDesc.h b/llvm/include/llvm/MC/MCInstrDesc.h
index 94350572412cb..bc69f884fe897 100644
--- a/llvm/include/llvm/MC/MCInstrDesc.h
+++ b/llvm/include/llvm/MC/MCInstrDesc.h
@@ -209,9 +209,9 @@ class MCInstrDesc {
   unsigned short SchedClass;     // enum identifying instr sched class
   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
   uint64_t Flags;                // Flags identifying machine instr class
   uint64_t TSFlags;              // Target Specific Flag values
-  const MCPhysReg *ImplicitOps;  // List of implicit uses followed by defs
   const MCOperandInfo *OpInfo;   // 'NumOperands' entries about operands
 
   /// Returns the value of the specified operand constraint if
@@ -563,7 +563,8 @@ class MCInstrDesc {
   /// reading the flags.  Likewise, the variable shift instruction on X86 is
   /// marked as implicitly reading the 'CL' register, which it always does.
   ArrayRef<MCPhysReg> implicit_uses() const {
-    return {ImplicitOps, NumImplicitUses};
+    auto ImplicitOps = reinterpret_cast<const MCPhysReg *>(this + Opcode + 1);
+    return {ImplicitOps + ImplicitOffset, NumImplicitUses};
   }
 
   /// Return a list of registers that are potentially written by any
@@ -575,7 +576,8 @@ class MCInstrDesc {
   /// registers.  For that instruction, this will return a list containing the
   /// EAX/EDX/EFLAGS registers.
   ArrayRef<MCPhysReg> implicit_defs() const {
-    return {ImplicitOps + NumImplicitUses, NumImplicitDefs};
+    auto ImplicitOps = reinterpret_cast<const MCPhysReg *>(this + Opcode + 1);
+    return {ImplicitOps + ImplicitOffset + NumImplicitUses, NumImplicitDefs};
   }
 
   /// Return true if this instruction implicitly

diff  --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 6cbb7120e2667..806ee70dba541 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -70,7 +70,7 @@
 using namespace llvm;
 
 namespace llvm {
-extern const MCInstrDesc ARMInsts[];
+extern const MCInstrDesc ARMDescs[];
 } // end namespace llvm
 
 namespace {
@@ -2504,7 +2504,7 @@ class ARMOperand : public MCParsedAsmOperand {
     } else {
       unsigned NextOpIndex = Inst.getNumOperands();
       const MCInstrDesc &MCID =
-          ARMInsts[ARM::INSTRUCTION_LIST_END - 1 - Inst.getOpcode()];
+          ARMDescs[ARM::INSTRUCTION_LIST_END - 1 - Inst.getOpcode()];
       int TiedOp = MCID.getOperandConstraint(NextOpIndex, MCOI::TIED_TO);
       assert(TiedOp >= 0 &&
              "Inactive register in vpred_r is not tied to an output!");

diff  --git a/llvm/unittests/CodeGen/MachineInstrTest.cpp b/llvm/unittests/CodeGen/MachineInstrTest.cpp
index 574e90d22d574..62b1c6fabb8d6 100644
--- a/llvm/unittests/CodeGen/MachineInstrTest.cpp
+++ b/llvm/unittests/CodeGen/MachineInstrTest.cpp
@@ -54,9 +54,9 @@ TEST(IsIdenticalToTest, DifferentDefs) {
   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,       1ULL << MCID::HasOptionalDef,
-                      0, nullptr, OpInfo};
+  MCInstrDesc MCID = {
+      0, NumOps, NumDefs, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef,
+      0, OpInfo};
 
   // Create two MIs with 
diff erent virtual reg defs and the same uses.
   unsigned VirtualDef1 = -42; // The value doesn't matter, but the sign does.
@@ -125,9 +125,9 @@ TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) {
   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,       1ULL << MCID::HasOptionalDef,
-                      0, nullptr, OpInfo};
+  MCInstrDesc MCID = {
+      0, NumOps, NumDefs, 0, 0, 0, 0, 0, 1ULL << MCID::HasOptionalDef,
+      0, OpInfo};
 
   // Define a series of instructions with 
diff erent kinds of operands and make
   // sure that the hash function is consistent with isEqual for various
@@ -201,7 +201,7 @@ TEST(MachineInstrPrintingTest, DebugLocPrinting) {
   auto MF = createMachineFunction(Ctx, Mod);
 
   MCOperandInfo OpInfo{0, 0, MCOI::OPERAND_REGISTER, 0};
-  MCInstrDesc MCID = {0, 1, 1, 0, 0, 0, 0, 0, 0, nullptr, &OpInfo};
+  MCInstrDesc MCID = {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, &OpInfo};
 
   DIFile *DIF = DIFile::getDistinct(Ctx, "filename", "");
   DISubprogram *DIS = DISubprogram::getDistinct(
@@ -228,7 +228,7 @@ TEST(MachineInstrSpan, DistanceBegin) {
   auto MF = createMachineFunction(Ctx, Mod);
   auto MBB = MF->CreateMachineBasicBlock();
 
-  MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr};
+  MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr};
 
   auto MII = MBB->begin();
   MachineInstrSpan MIS(MII, MBB);
@@ -245,7 +245,7 @@ TEST(MachineInstrSpan, DistanceEnd) {
   auto MF = createMachineFunction(Ctx, Mod);
   auto MBB = MF->CreateMachineBasicBlock();
 
-  MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr};
+  MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr};
 
   auto MII = MBB->end();
   MachineInstrSpan MIS(MII, MBB);
@@ -260,7 +260,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, nullptr, nullptr};
+  MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr};
 
   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
   auto MAI = MCAsmInfo();
@@ -320,7 +320,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, nullptr, nullptr};
+  MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr};
 
   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
   auto MAI = MCAsmInfo();
@@ -361,7 +361,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, nullptr, nullptr};
+  MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr};
 
   auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
   auto MAI = MCAsmInfo();
@@ -428,12 +428,10 @@ TEST(MachineInstrDebugValue, AddDebugValueOperand) {
         TargetOpcode::DBG_INSTR_REF, TargetOpcode::DBG_PHI,
         TargetOpcode::DBG_LABEL}) {
     const MCInstrDesc MCID = {
-        Opcode, 0,
-        0,      0,
-        0,      0,
-        0,      (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),
-        0,      nullptr,
-        nullptr};
+        Opcode, 0,      0,
+        0,      0,      0,
+        0,      0,      (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic),
+        0,      nullptr};
 
     auto *MI = MF->CreateMachineInstr(MCID, DebugLoc());
     MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ false));
@@ -463,7 +461,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, nullptr, nullptr};
+  MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr};
   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 9a0a36aef1122..60ad94b5ed622 100644
--- a/llvm/unittests/CodeGen/RegAllocScoreTest.cpp
+++ b/llvm/unittests/CodeGen/RegAllocScoreTest.cpp
@@ -64,7 +64,7 @@ enum MockInstrId {
 
 const std::array<MCInstrDesc, MockInstrId::TotalMockInstrs> MockInstrDescs{{
 #define MOCK_SPEC(IGNORE, OPCODE, FLAGS)                                       \
-  {OPCODE, 0, 0, 0, 0, 0, 0, FLAGS, 0, nullptr, nullptr},
+  {OPCODE, 0, 0, 0, 0, 0, 0, 0, FLAGS, 0, nullptr},
     MOCK_INSTR(MOCK_SPEC)
 #undef MOCK_SPEC
 }};

diff  --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index c051775890244..58dec4eae6d16 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -114,14 +114,6 @@ class InstrInfoEmitter {
 
 } // end anonymous namespace
 
-static void PrintDefList(const std::vector<Record *> &Uses, unsigned Num,
-                         raw_ostream &OS) {
-  OS << "static const MCPhysReg ImplicitList" << Num << "[] = { ";
-  for (auto [Idx, U] : enumerate(Uses))
-    OS << (Idx ? ", " : "") << getQualifiedName(U);
-  OS << " };\n";
-}
-
 //===----------------------------------------------------------------------===//
 // Operand Info Emission.
 //===----------------------------------------------------------------------===//
@@ -221,7 +213,6 @@ void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
   unsigned OperandListNum = 0;
   OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum;
 
-  OS << "\n";
   const CodeGenTarget &Target = CDP.getTargetInfo();
   for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
     std::vector<std::string> OperandInfo = GetOperandInfo(*Inst);
@@ -891,45 +882,55 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
   emitSourceFileHeader("Target Instruction Enum Values and Descriptors", OS);
   emitEnums(OS);
 
-  OS << "#ifdef GET_INSTRINFO_MC_DESC\n";
-  OS << "#undef GET_INSTRINFO_MC_DESC\n";
-
-  OS << "namespace llvm {\n\n";
-
   CodeGenTarget &Target = CDP.getTargetInfo();
   const std::string &TargetName = std::string(Target.getName());
   Record *InstrInfo = Target.getInstructionSet();
 
-  // Keep track of all of the def lists we have emitted already.
+  // Collect all of the instruction's implicit uses and defs.
+  Records.startTimer("Collect uses/defs");
   std::map<std::vector<Record*>, unsigned> EmittedLists;
-  unsigned ListNumber = 0;
-
-  // Emit all of the instruction's implicit uses and defs.
-  Records.startTimer("Emit uses/defs");
+  std::vector<std::vector<Record *>> ImplicitLists;
+  unsigned ImplicitListSize = 0;
   for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) {
     std::vector<Record *> ImplicitOps = II->ImplicitUses;
     llvm::append_range(ImplicitOps, II->ImplicitDefs);
-    if (!ImplicitOps.empty()) {
-      unsigned &IL = EmittedLists[ImplicitOps];
-      if (!IL) {
-        IL = ++ListNumber;
-        PrintDefList(ImplicitOps, IL, OS);
-      }
+    if (EmittedLists.insert({ImplicitOps, ImplicitListSize}).second) {
+      ImplicitLists.push_back(ImplicitOps);
+      ImplicitListSize += ImplicitOps.size();
     }
   }
 
-  OperandInfoMapTy OperandInfoIDs;
+  ArrayRef<const CodeGenInstruction *> NumberedInstructions =
+      Target.getInstructionsByEnumValue();
+  OS << "#if defined(GET_INSTRINFO_MC_DESC) || "
+        "defined(GET_INSTRINFO_CTOR_DTOR)\n";
+  OS << "namespace llvm {\n\n";
+
+  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 << "  MCPhysReg ImplicitOps[" << std::max(ImplicitListSize, 1U) << "];\n";
+  OS << "};\n\n";
+
+  OS << "} // end namespace llvm\n";
+  OS << "#endif // defined(GET_INSTRINFO_MC_DESC) || "
+        "defined(GET_INSTRINFO_CTOR_DTOR)\n\n";
+
+  OS << "#ifdef GET_INSTRINFO_MC_DESC\n";
+  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 << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n";
-  ArrayRef<const CodeGenInstruction*> NumberedInstructions =
-    Target.getInstructionsByEnumValue();
-
+  OS << "extern const " << TargetName << "InstrTable " << TargetName
+     << "Descs = {\n  {\n";
   SequenceToOffsetTable<std::string> InstrNames;
   unsigned Num = NumberedInstructions.size();
   for (const CodeGenInstruction *Inst : reverse(NumberedInstructions)) {
@@ -938,7 +939,19 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
     // Emit the record into the table.
     emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoIDs, OS);
   }
-  OS << "};\n\n";
+
+  OS << "  }, {\n";
+
+  // Emit all of the instruction's implicit uses and defs.
+  Records.startTimer("Emit uses/defs");
+  for (auto &List : ImplicitLists) {
+    OS << "    /* " << EmittedLists[List] << " */";
+    for (auto &Reg : List)
+      OS << ' ' << getQualifiedName(Reg) << ',';
+    OS << '\n';
+  }
+
+  OS << "  }\n};\n\n";
 
   // Emit the array of instruction names.
   Records.startTimer("Emit instruction names");
@@ -1005,7 +1018,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
   Records.startTimer("Emit initialization routine");
   OS << "static inline void Init" << TargetName
      << "MCInstrInfo(MCInstrInfo *II) {\n";
-  OS << "  II->InitMCInstrInfo(" << TargetName << "Insts, " << TargetName
+  OS << "  II->InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
      << "InstrNameIndices, " << TargetName << "InstrNameData, ";
   if (HasDeprecationFeatures)
     OS << TargetName << "InstrDeprecationFeatures, ";
@@ -1053,7 +1066,8 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
   OS << "#undef GET_INSTRINFO_CTOR_DTOR\n";
 
   OS << "namespace llvm {\n";
-  OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n";
+  OS << "extern const " << TargetName << "InstrTable " << TargetName
+     << "Descs;\n";
   OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
   OS << "extern const char " << TargetName << "InstrNameData[];\n";
   if (HasDeprecationFeatures)
@@ -1067,7 +1081,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
         "CatchRetOpcode, unsigned ReturnOpcode)\n"
      << "  : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, "
         "ReturnOpcode) {\n"
-     << "  InitMCInstrInfo(" << TargetName << "Insts, " << TargetName
+     << "  InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
      << "InstrNameIndices, " << TargetName << "InstrNameData, ";
   if (HasDeprecationFeatures)
     OS << TargetName << "InstrDeprecationFeatures, ";
@@ -1112,13 +1126,16 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
     MinOperands = Inst.Operands.back().MIOperandNo +
                   Inst.Operands.back().MINumOperands;
 
-  OS << "  { ";
-  OS << Num << ",\t" << MinOperands << ",\t"
-     << Inst.Operands.NumDefs << ",\t"
+  OS << "    { ";
+  OS << Num << ",\t" << MinOperands << ",\t" << Inst.Operands.NumDefs << ",\t"
      << Inst.TheDef->getValueAsInt("Size") << ",\t"
-     << SchedModels.getSchedClassIdx(Inst) << ",\t"
-     << Inst.ImplicitUses.size() << ",\t"
-     << Inst.ImplicitDefs.size() << ",\t0";
+     << SchedModels.getSchedClassIdx(Inst) << ",\t";
+
+  // Emit the implicit use/def list...
+  OS << Inst.ImplicitUses.size() << ",\t" << Inst.ImplicitDefs.size() << ",\t";
+  std::vector<Record *> ImplicitOps = Inst.ImplicitUses;
+  llvm::append_range(ImplicitOps, Inst.ImplicitDefs);
+  OS << EmittedLists[ImplicitOps] << ",\t0";
 
   CodeGenTarget &Target = CDP.getTargetInfo();
 
@@ -1183,14 +1200,6 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
   OS.write_hex(Value);
   OS << "ULL, ";
 
-  // Emit the implicit use/def list...
-  std::vector<Record *> ImplicitOps = Inst.ImplicitUses;
-  llvm::append_range(ImplicitOps, Inst.ImplicitDefs);
-  if (ImplicitOps.empty())
-    OS << "nullptr, ";
-  else
-    OS << "ImplicitList" << EmittedLists[ImplicitOps] << ", ";
-
   // Emit the operand info.
   std::vector<std::string> OperandInfo = GetOperandInfo(Inst);
   if (OperandInfo.empty())


        


More information about the llvm-commits mailing list