Skip to content

Commit

Permalink
[MC] Move deprecation infos from MCTargetDesc to MCInstrInfo
Browse files Browse the repository at this point in the history
This allows emitting it only when the feature is used by a target.
Shrinks Release+Asserts clang by 900k.
  • Loading branch information
d0k committed Mar 29, 2020
1 parent b9d9968 commit 854f268
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 63 deletions.
14 changes: 0 additions & 14 deletions llvm/include/llvm/MC/MCInstrDesc.h
Expand Up @@ -197,15 +197,6 @@ class MCInstrDesc {
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.
Expand All @@ -219,11 +210,6 @@ class MCInstrDesc {
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; }

Expand Down
23 changes: 22 additions & 1 deletion llvm/include/llvm/MC/MCInstrInfo.h
Expand Up @@ -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;
}

Expand All @@ -51,6 +67,11 @@ class MCInstrInfo {
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
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/MC/CMakeLists.txt
Expand Up @@ -23,6 +23,7 @@ add_llvm_component_library(LLVMMC
MCInstPrinter.cpp
MCInstrAnalysis.cpp
MCInstrDesc.cpp
MCInstrInfo.cpp
MCLabel.cpp
MCLinkerOptimizationHint.cpp
MCMachOStreamer.cpp
Expand Down
11 changes: 0 additions & 11 deletions llvm/lib/MC/MCInstrDesc.cpp
Expand Up @@ -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())
Expand Down
27 changes: 27 additions & 0 deletions llvm/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;
}
26 changes: 10 additions & 16 deletions llvm/unittests/CodeGen/MachineInstrTest.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion llvm/utils/TableGen/AsmMatcherEmitter.cpp
Expand Up @@ -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";
Expand Down
95 changes: 75 additions & 20 deletions llvm/utils/TableGen/InstrInfoEmitter.cpp
Expand Up @@ -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";

Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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";
}

Expand Down

0 comments on commit 854f268

Please sign in to comment.