From 4c79d49be937ce0247166bb2d09bff05f5577823 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sun, 29 Mar 2020 21:09:07 +0200 Subject: [PATCH] [MC] Move deprecation infos from MCTargetDesc to MCInstrInfo This allows emitting it only when the feature is used by a target. Shrinks Release+Asserts clang by 900k. --- include/llvm/MC/MCInstrDesc.h | 14 ---- include/llvm/MC/MCInstrInfo.h | 23 ++++++- lib/MC/CMakeLists.txt | 1 + lib/MC/MCInstrDesc.cpp | 11 --- lib/MC/MCInstrInfo.cpp | 27 ++++++++ unittests/CodeGen/MachineInstrTest.cpp | 26 +++---- utils/TableGen/AsmMatcherEmitter.cpp | 2 +- utils/TableGen/InstrInfoEmitter.cpp | 95 ++++++++++++++++++++------ 8 files changed, 136 insertions(+), 63 deletions(-) create mode 100644 lib/MC/MCInstrInfo.cpp diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index 29175af7eb0..fa620d21a12 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -197,15 +197,6 @@ public: const MCPhysReg *ImplicitUses; // Registers implicitly read by this instr const MCPhysReg *ImplicitDefs; // Registers implicitly defined by this instr const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands - // Subtarget feature that this is deprecated on, if any - // -1 implies this is not deprecated by any single feature. It may still be - // deprecated due to a "complex" reason, below. - int64_t DeprecatedFeature; - - // A complex method to determine if a certain instruction is deprecated or - // not, and return the reason for deprecation. - bool (*ComplexDeprecationInfo)(MCInst &, const MCSubtargetInfo &, - std::string &); /// Returns the value of the specific constraint if /// it is set. Returns -1 if it is not set. @@ -219,11 +210,6 @@ public: return -1; } - /// Returns true if a certain instruction is deprecated and if so - /// returns the reason in \p Info. - bool getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI, - std::string &Info) const; - /// Return the opcode number for this descriptor. unsigned getOpcode() const { return Opcode; } diff --git a/include/llvm/MC/MCInstrInfo.h b/include/llvm/MC/MCInstrInfo.h index 874b1e46795..f5c944eed68 100644 --- a/include/llvm/MC/MCInstrInfo.h +++ b/include/llvm/MC/MCInstrInfo.h @@ -21,19 +21,35 @@ namespace llvm { //--------------------------------------------------------------------------- /// Interface to description of machine instruction set. class MCInstrInfo { +public: + using ComplexDeprecationPredicate = bool (*)(MCInst &, + const MCSubtargetInfo &, + std::string &); + +private: const MCInstrDesc *Desc; // Raw array to allow static init'n const unsigned *InstrNameIndices; // Array for name indices in InstrNameData const char *InstrNameData; // Instruction name string pool + // Subtarget feature that an instruction is deprecated on, if any + // -1 implies this is not deprecated by any single feature. It may still be + // deprecated due to a "complex" reason, below. + const uint8_t *DeprecatedFeatures; + // A complex method to determine if a certain instruction is deprecated or + // not, and return the reason for deprecation. + const ComplexDeprecationPredicate *ComplexDeprecationInfos; unsigned NumOpcodes; // Number of entries in the desc array public: /// Initialize MCInstrInfo, called by TableGen auto-generated routines. /// *DO NOT USE*. void InitMCInstrInfo(const MCInstrDesc *D, const unsigned *NI, const char *ND, - unsigned NO) { + const uint8_t *DF, + const ComplexDeprecationPredicate *CDI, unsigned NO) { Desc = D; InstrNameIndices = NI; InstrNameData = ND; + DeprecatedFeatures = DF; + ComplexDeprecationInfos = CDI; NumOpcodes = NO; } @@ -51,6 +67,11 @@ public: assert(Opcode < NumOpcodes && "Invalid opcode!"); return StringRef(&InstrNameData[InstrNameIndices[Opcode]]); } + + /// Returns true if a certain instruction is deprecated and if so + /// returns the reason in \p Info. + bool getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI, + std::string &Info) const; }; } // End llvm namespace diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt index ab809daf527..9ef61d79dcc 100644 --- a/lib/MC/CMakeLists.txt +++ b/lib/MC/CMakeLists.txt @@ -23,6 +23,7 @@ add_llvm_component_library(LLVMMC MCInstPrinter.cpp MCInstrAnalysis.cpp MCInstrDesc.cpp + MCInstrInfo.cpp MCLabel.cpp MCLinkerOptimizationHint.cpp MCMachOStreamer.cpp diff --git a/lib/MC/MCInstrDesc.cpp b/lib/MC/MCInstrDesc.cpp index d54aeba89ed..b5c43f5edc0 100644 --- a/lib/MC/MCInstrDesc.cpp +++ b/lib/MC/MCInstrDesc.cpp @@ -18,17 +18,6 @@ using namespace llvm; -bool MCInstrDesc::getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI, - std::string &Info) const { - if (ComplexDeprecationInfo) - return ComplexDeprecationInfo(MI, STI, Info); - if (DeprecatedFeature != -1 && STI.getFeatureBits()[DeprecatedFeature]) { - // FIXME: it would be nice to include the subtarget feature here. - Info = "deprecated"; - return true; - } - return false; -} bool MCInstrDesc::mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const { if (isBranch() || isCall() || isReturn() || isIndirectBranch()) diff --git a/lib/MC/MCInstrInfo.cpp b/lib/MC/MCInstrInfo.cpp new file mode 100644 index 00000000000..ab63db04053 --- /dev/null +++ b/lib/MC/MCInstrInfo.cpp @@ -0,0 +1,27 @@ +//===- lib/MC/MCInstrInfo.cpp - Target Instruction Info -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCSubtargetInfo.h" + +using namespace llvm; + +bool MCInstrInfo::getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI, + std::string &Info) const { + unsigned Opcode = MI.getOpcode(); + if (ComplexDeprecationInfos && ComplexDeprecationInfos[Opcode]) + return ComplexDeprecationInfos[Opcode](MI, STI, Info); + if (DeprecatedFeatures && DeprecatedFeatures[Opcode] != uint8_t(-1U) && + STI.getFeatureBits()[DeprecatedFeatures[Opcode]]) { + // FIXME: it would be nice to include the subtarget feature here. + Info = "deprecated"; + return true; + } + return false; +} diff --git a/unittests/CodeGen/MachineInstrTest.cpp b/unittests/CodeGen/MachineInstrTest.cpp index 4151ef7a6d0..a641dc8c452 100644 --- a/unittests/CodeGen/MachineInstrTest.cpp +++ b/unittests/CodeGen/MachineInstrTest.cpp @@ -50,8 +50,8 @@ TEST(IsIdenticalToTest, DifferentDefs) { {0, 0, MCOI::OPERAND_REGISTER, 0}, {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}; MCInstrDesc MCID = { - 0, NumOps, NumDefs, 0, 0, 1ULL << MCID::HasOptionalDef, - 0, nullptr, nullptr, OpInfo, 0, nullptr}; + 0, NumOps, NumDefs, 0, 0, 1ULL << MCID::HasOptionalDef, + 0, nullptr, nullptr, OpInfo}; // Create two MIs with different virtual reg defs and the same uses. unsigned VirtualDef1 = -42; // The value doesn't matter, but the sign does. @@ -121,8 +121,8 @@ TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) { {0, 0, MCOI::OPERAND_REGISTER, 0}, {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}}; MCInstrDesc MCID = { - 0, NumOps, NumDefs, 0, 0, 1ULL << MCID::HasOptionalDef, - 0, nullptr, nullptr, OpInfo, 0, nullptr}; + 0, NumOps, NumDefs, 0, 0, 1ULL << MCID::HasOptionalDef, + 0, nullptr, nullptr, OpInfo}; // Define a series of instructions with different kinds of operands and make // sure that the hash function is consistent with isEqual for various @@ -196,8 +196,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, nullptr, nullptr, &OpInfo, 0, nullptr}; + MCInstrDesc MCID = {0, 1, 1, 0, 0, 0, 0, nullptr, nullptr, &OpInfo}; DIFile *DIF = DIFile::getDistinct(Ctx, "filename", ""); DISubprogram *DIS = DISubprogram::getDistinct( @@ -224,8 +223,7 @@ TEST(MachineInstrSpan, DistanceBegin) { auto MF = createMachineFunction(Ctx, Mod); auto MBB = MF->CreateMachineBasicBlock(); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, - 0, nullptr, nullptr, nullptr, 0, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr}; auto MII = MBB->begin(); MachineInstrSpan MIS(MII, MBB); @@ -242,8 +240,7 @@ TEST(MachineInstrSpan, DistanceEnd) { auto MF = createMachineFunction(Ctx, Mod); auto MBB = MF->CreateMachineBasicBlock(); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, - 0, nullptr, nullptr, nullptr, 0, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr}; auto MII = MBB->end(); MachineInstrSpan MIS(MII, MBB); @@ -258,8 +255,7 @@ TEST(MachineInstrExtraInfo, AddExtraInfo) { LLVMContext Ctx; Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, - 0, nullptr, nullptr, nullptr, 0, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr}; auto MI = MF->CreateMachineInstr(MCID, DebugLoc()); auto MAI = MCAsmInfo(); @@ -306,8 +302,7 @@ TEST(MachineInstrExtraInfo, ChangeExtraInfo) { LLVMContext Ctx; Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, - 0, nullptr, nullptr, nullptr, 0, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr}; auto MI = MF->CreateMachineInstr(MCID, DebugLoc()); auto MAI = MCAsmInfo(); @@ -344,8 +339,7 @@ TEST(MachineInstrExtraInfo, RemoveExtraInfo) { LLVMContext Ctx; Module Mod("Module", Ctx); auto MF = createMachineFunction(Ctx, Mod); - MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, - 0, nullptr, nullptr, nullptr, 0, nullptr}; + MCInstrDesc MCID = {0, 0, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr}; auto MI = MF->CreateMachineInstr(MCID, DebugLoc()); auto MAI = MCAsmInfo(); diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 01133c13ae6..3d63059dcb8 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -3863,7 +3863,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " std::string Info;\n"; OS << " if (!getParser().getTargetParser().\n"; OS << " getTargetOptions().MCNoDeprecatedWarn &&\n"; - OS << " MII.get(Inst.getOpcode()).getDeprecatedInfo(Inst, getSTI(), Info)) {\n"; + OS << " MII.getDeprecatedInfo(Inst, getSTI(), Info)) {\n"; OS << " SMLoc Loc = ((" << Target.getName() << "Operand&)*Operands[0]).getStartLoc();\n"; OS << " getParser().Warning(Loc, Info, None);\n"; diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index c857d36f901..2da2bec112f 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -581,15 +581,66 @@ void InstrInfoEmitter::run(raw_ostream &OS) { OS << InstrNames.get(std::string(Inst->TheDef->getName())) << "U, "; ++Num; } - OS << "\n};\n\n"; + bool HasDeprecationFeatures = + llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) { + return !Inst->HasComplexDeprecationPredicate && + !Inst->DeprecatedReason.empty(); + }); + if (HasDeprecationFeatures) { + OS << "extern const uint8_t " << TargetName + << "InstrDeprecationFeatures[] = {"; + Num = 0; + for (const CodeGenInstruction *Inst : NumberedInstructions) { + if (Num % 8 == 0) + OS << "\n "; + if (!Inst->HasComplexDeprecationPredicate && + !Inst->DeprecatedReason.empty()) + OS << Target.getInstNamespace() << "::" << Inst->DeprecatedReason + << ", "; + else + OS << "uint8_t(-1), "; + ++Num; + } + OS << "\n};\n\n"; + } + + bool HasComplexDeprecationInfos = + llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) { + return Inst->HasComplexDeprecationPredicate; + }); + if (HasComplexDeprecationInfos) { + OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName + << "InstrComplexDeprecationInfos[] = {"; + Num = 0; + for (const CodeGenInstruction *Inst : NumberedInstructions) { + if (Num % 8 == 0) + OS << "\n "; + if (Inst->HasComplexDeprecationPredicate) + // Emit a function pointer to the complex predicate method. + OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, "; + else + OS << "nullptr, "; + ++Num; + } + OS << "\n};\n\n"; + } + // MCInstrInfo initialization routine. OS << "static inline void Init" << TargetName << "MCInstrInfo(MCInstrInfo *II) {\n"; - OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " - << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, " - << NumberedInstructions.size() << ");\n}\n\n"; + OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " << TargetName + << "InstrNameIndices, " << TargetName << "InstrNameData, "; + if (HasDeprecationFeatures) + OS << TargetName << "InstrDeprecationFeatures, "; + else + OS << "nullptr, "; + if (HasComplexDeprecationInfos) + OS << TargetName << "InstrComplexDeprecationInfos, "; + else + OS << "nullptr, "; + OS << NumberedInstructions.size() << ");\n}\n\n"; OS << "} // end namespace llvm\n"; @@ -629,12 +680,28 @@ void InstrInfoEmitter::run(raw_ostream &OS) { OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n"; OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n"; OS << "extern const char " << TargetName << "InstrNameData[];\n"; + if (HasDeprecationFeatures) + OS << "extern const uint8_t " << TargetName + << "InstrDeprecationFeatures[];\n"; + if (HasComplexDeprecationInfos) + OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName + << "InstrComplexDeprecationInfos[];\n"; OS << ClassName << "::" << ClassName - << "(int CFSetupOpcode, int CFDestroyOpcode, int CatchRetOpcode, int ReturnOpcode)\n" - << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, ReturnOpcode) {\n" + << "(int CFSetupOpcode, int CFDestroyOpcode, int CatchRetOpcode, int " + "ReturnOpcode)\n" + << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, " + "ReturnOpcode) {\n" << " InitMCInstrInfo(" << TargetName << "Insts, " << TargetName - << "InstrNameIndices, " << TargetName << "InstrNameData, " - << NumberedInstructions.size() << ");\n}\n"; + << "InstrNameIndices, " << TargetName << "InstrNameData, "; + if (HasDeprecationFeatures) + OS << TargetName << "InstrDeprecationFeatures, "; + else + OS << "nullptr, "; + if (HasComplexDeprecationInfos) + OS << TargetName << "InstrComplexDeprecationInfos, "; + else + OS << "nullptr, "; + OS << NumberedInstructions.size() << ");\n}\n"; OS << "} // end namespace llvm\n"; OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n"; @@ -745,18 +812,6 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, else OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; - if (Inst.HasComplexDeprecationPredicate) - // Emit a function pointer to the complex predicate method. - OS << ", -1 " - << ",&get" << Inst.DeprecatedReason << "DeprecationInfo"; - else if (!Inst.DeprecatedReason.empty()) - // Emit the Subtarget feature. - OS << ", " << Target.getInstNamespace() << "::" << Inst.DeprecatedReason - << " ,nullptr"; - else - // Instruction isn't deprecated. - OS << ", -1 ,nullptr"; - OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; }