[CodeGen] Move instruction predicate verification to emitInstruction

D25618 added a method to verify the instruction predicates for an
emitted instruction, through verifyInstructionPredicates added into
<Target>MCCodeEmitter::encodeInstruction. This is a very useful idea,
but the implementation inside MCCodeEmitter made it only fire for object
files, not assembly which most of the llvm test suite uses.

This patch moves the code into the <Target>_MC::verifyInstructionPredicates
method, inside the InstrInfo.  The allows it to be called from other
places, such as in this patch where it is called from the
<Target>AsmPrinter::emitInstruction methods which should trigger for
both assembly and object files. It can also be called from other places
such as verifyInstruction, but that is not done here (it tends to catch
errors earlier, but in reality just shows all the mir tests that have
incorrect feature predicates). The interface was also simplified
slightly, moving computeAvailableFeatures into the function so that it
does not need to be called externally.

The ARM, AMDGPU (but not R600), AVR, Mips and X86 backends all currently
show errors in the test-suite, so have been disabled with FIXME
comments.

Recommitted with some fixes for the leftover MCII variables in release
builds.

Differential Revision: https://reviews.llvm.org/D129506
This commit is contained in:
David Green 2022-07-14 09:33:28 +01:00
parent 52cb972537
commit 3e0bf1c7a9
90 changed files with 298 additions and 269 deletions

View File

@ -1173,6 +1173,8 @@ void AArch64AsmPrinter::emitFMov0(const MachineInstr &MI) {
#include "AArch64GenMCPseudoLowering.inc"
void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
AArch64_MC::verifyInstructionPredicates(MI->getOpcode(), STI->getFeatureBits());
// Do any auto-generated pseudo lowerings.
if (emitPseudoExpansionLowering(*OutStreamer, MI))
return;

View File

@ -43,11 +43,9 @@ namespace {
class AArch64MCCodeEmitter : public MCCodeEmitter {
MCContext &Ctx;
const MCInstrInfo &MCII;
public:
AArch64MCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
: Ctx(ctx), MCII(mcii) {}
AArch64MCCodeEmitter(const MCInstrInfo &, MCContext &ctx) : Ctx(ctx) {}
AArch64MCCodeEmitter(const AArch64MCCodeEmitter &) = delete;
void operator=(const AArch64MCCodeEmitter &) = delete;
~AArch64MCCodeEmitter() override = default;
@ -193,12 +191,6 @@ public:
uint32_t encodeMatrixIndexGPR32(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
private:
FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
void
verifyInstructionPredicates(const MCInst &MI,
const FeatureBitset &AvailableFeatures) const;
};
} // end anonymous namespace
@ -618,9 +610,6 @@ unsigned AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue,
void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
verifyInstructionPredicates(MI,
computeAvailableFeatures(STI.getFeatureBits()));
if (MI.getOpcode() == AArch64::TLSDESCCALL) {
// This is a directive which applies an R_AARCH64_TLSDESC_CALL to the
// following (BLR) instruction. It doesn't emit any code itself so it
@ -674,7 +663,6 @@ unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
return EncodedValue;
}
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "AArch64GenMCCodeEmitter.inc"
MCCodeEmitter *llvm::createAArch64MCCodeEmitter(const MCInstrInfo &MCII,

View File

@ -34,6 +34,7 @@ using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define GET_INSTRINFO_MC_HELPERS
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "AArch64GenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -33,6 +33,7 @@ class MCSubtargetInfo;
class MCTargetOptions;
class MCTargetStreamer;
class Target;
class FeatureBitset;
MCCodeEmitter *createAArch64MCCodeEmitter(const MCInstrInfo &MCII,
MCContext &Ctx);

View File

@ -171,6 +171,10 @@ const MCExpr *AMDGPUAsmPrinter::lowerConstant(const Constant *CV) {
}
void AMDGPUAsmPrinter::emitInstruction(const MachineInstr *MI) {
// FIXME: Enable feature predicate checks once all the test pass.
// AMDGPU_MC::verifyInstructionPredicates(MI->getOpcode(),
// getSubtargetInfo().getFeatureBits());
if (emitPseudoExpansionLowering(*OutStreamer, MI))
return;

View File

@ -62,12 +62,6 @@ public:
virtual void getAVOperandEncoding(const MCInst &MI, unsigned OpNo, APInt &Op,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const = 0;
protected:
FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
void
verifyInstructionPredicates(const MCInst &MI,
const FeatureBitset &AvailableFeatures) const;
};
} // End namespace llvm

View File

@ -36,6 +36,7 @@
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "AMDGPUGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -50,6 +50,7 @@ createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI,
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_OPERAND_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "AMDGPUGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -58,11 +58,6 @@ private:
uint64_t getBinaryCodeForInstr(const MCInst &MI,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
void
verifyInstructionPredicates(const MCInst &MI,
const FeatureBitset &AvailableFeatures) const;
};
} // end anonymous namespace
@ -92,9 +87,6 @@ MCCodeEmitter *llvm::createR600MCCodeEmitter(const MCInstrInfo &MCII,
void R600MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
verifyInstructionPredicates(MI,
computeAvailableFeatures(STI.getFeatureBits()));
const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
if (MI.getOpcode() == R600::RETURN ||
MI.getOpcode() == R600::FETCH_CLAUSE ||
@ -187,5 +179,4 @@ uint64_t R600MCCodeEmitter::getMachineOpValue(const MCInst &MI,
return MO.getImm();
}
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "R600GenMCCodeEmitter.inc"

View File

@ -13,10 +13,12 @@
#include "R600MCTargetDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/SubtargetFeature.h"
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "R600GenInstrInfo.inc"
MCInstrInfo *llvm::createR600MCInstrInfo() {

View File

@ -35,6 +35,7 @@ MCInstrInfo *createR600MCInstrInfo();
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_OPERAND_ENUM
#define GET_INSTRINFO_SCHED_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "R600GenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -312,9 +312,6 @@ uint64_t SIMCCodeEmitter::getImplicitOpSelHiEncoding(int Opcode) const {
void SIMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
verifyInstructionPredicates(MI,
computeAvailableFeatures(STI.getFeatureBits()));
int Opcode = MI.getOpcode();
APInt Encoding, Scratch;
getBinaryCodeForInstr(MI, Fixups, Encoding, Scratch, STI);
@ -574,5 +571,4 @@ void SIMCCodeEmitter::getMachineOpValueCommon(
llvm_unreachable("Encoding of this operand type is not supported yet.");
}
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "AMDGPUGenMCCodeEmitter.inc"

View File

@ -13,6 +13,7 @@
//
#include "AMDGPUMCInstLower.h"
#include "MCTargetDesc/R600MCTargetDesc.h"
#include "R600AsmPrinter.h"
#include "R600Subtarget.h"
#include "llvm/CodeGen/MachineOperand.h"
@ -42,6 +43,9 @@ void R600MCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
}
void R600AsmPrinter::emitInstruction(const MachineInstr *MI) {
R600_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
const R600Subtarget &STI = MF->getSubtarget<R600Subtarget>();
R600MCInstLower MCInstLowering(OutContext, STI, *this);

View File

@ -49,6 +49,9 @@ public:
} // end anonymous namespace
void ARCAsmPrinter::emitInstruction(const MachineInstr *MI) {
ARC_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
SmallString<128> Str;
raw_svector_ostream O(Str);

View File

@ -26,6 +26,7 @@
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "ARCGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -28,6 +28,7 @@ class Target;
// Defines symbolic names for the ARC instructions.
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "ARCGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -1337,6 +1337,10 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
#include "ARMGenMCPseudoLowering.inc"
void ARMAsmPrinter::emitInstruction(const MachineInstr *MI) {
// TODOD FIXME: Enable feature predicate checks once all the test pass.
// ARM_MC::verifyInstructionPredicates(MI->getOpcode(),
// getSubtargetInfo().getFeatureBits());
const DataLayout &DL = getDataLayout();
MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);

View File

@ -133,6 +133,7 @@ static bool getARMLoadDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
}
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "ARMGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -139,6 +139,7 @@ bool isCDECoproc(size_t Coproc, const MCSubtargetInfo &STI);
// Defines symbolic names for the ARM instructions.
//
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "ARMGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -180,6 +180,10 @@ bool AVRAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
}
void AVRAsmPrinter::emitInstruction(const MachineInstr *MI) {
// FIXME: Enable feature predicate checks once all the test pass.
// AVR_MC::verifyInstructionPredicates(MI->getOpcode(),
// getSubtargetInfo().getFeatureBits());
AVRMCInstLower MCInstLowering(OutContext, *this);
MCInst I;

View File

@ -27,6 +27,7 @@
#include "llvm/MC/TargetRegistry.h"
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "AVRGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -49,6 +49,7 @@ std::unique_ptr<MCObjectTargetWriter> createAVRELFObjectWriter(uint8_t OSABI);
#include "AVRGenRegisterInfo.inc"
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "AVRGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -138,6 +138,9 @@ bool BPFAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
}
void BPFAsmPrinter::emitInstruction(const MachineInstr *MI) {
BPF_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
MCInst TmpInst;
if (!BTF || !BTF->InstLower(MI, TmpInst)) {

View File

@ -31,14 +31,13 @@ using namespace llvm;
namespace {
class BPFMCCodeEmitter : public MCCodeEmitter {
const MCInstrInfo &MCII;
const MCRegisterInfo &MRI;
bool IsLittleEndian;
public:
BPFMCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri,
BPFMCCodeEmitter(const MCInstrInfo &, const MCRegisterInfo &mri,
bool IsLittleEndian)
: MCII(mcii), MRI(mri), IsLittleEndian(IsLittleEndian) {}
: MRI(mri), IsLittleEndian(IsLittleEndian) { }
BPFMCCodeEmitter(const BPFMCCodeEmitter &) = delete;
void operator=(const BPFMCCodeEmitter &) = delete;
~BPFMCCodeEmitter() override = default;
@ -62,12 +61,6 @@ public:
void encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const override;
private:
FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
void
verifyInstructionPredicates(const MCInst &MI,
const FeatureBitset &AvailableFeatures) const;
};
} // end anonymous namespace
@ -117,9 +110,6 @@ static uint8_t SwapBits(uint8_t Val)
void BPFMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
verifyInstructionPredicates(MI,
computeAvailableFeatures(STI.getFeatureBits()));
unsigned Opcode = MI.getOpcode();
support::endian::Writer OSE(OS,
IsLittleEndian ? support::little : support::big);
@ -174,5 +164,4 @@ uint64_t BPFMCCodeEmitter::getMemoryOpValue(const MCInst &MI, unsigned Op,
return Encoding;
}
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "BPFGenMCCodeEmitter.inc"

View File

@ -22,6 +22,7 @@
#include "llvm/Support/Host.h"
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "BPFGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -54,6 +54,7 @@ std::unique_ptr<MCObjectTargetWriter> createBPFELFObjectWriter(uint8_t OSABI);
// Defines symbolic names for the BPF instructions.
//
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "BPFGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -141,6 +141,9 @@ void CSKYAsmPrinter::emitEndOfAsmFile(Module &M) {
}
void CSKYAsmPrinter::emitInstruction(const MachineInstr *MI) {
CSKY_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
// Do any auto-generated pseudo lowerings.
if (emitPseudoExpansionLowering(*OutStreamer, MI))
return;

View File

@ -26,6 +26,7 @@
#include "llvm/MC/TargetRegistry.h"
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "CSKYGenInstrInfo.inc"
#define GET_REGINFO_MC_DESC

View File

@ -41,6 +41,7 @@ MCCodeEmitter *createCSKYMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx);
#include "CSKYGenRegisterInfo.inc"
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "CSKYGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -743,6 +743,9 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
/// Print out a single Hexagon MI to the current output stream.
void HexagonAsmPrinter::emitInstruction(const MachineInstr *MI) {
Hexagon_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
MCInst MCB;
MCB.setOpcode(Hexagon::BUNDLE);
MCB.addOperand(MCOperand::createImm(0));

View File

@ -376,11 +376,9 @@ void HexagonMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
State.Bundle = &MI;
State.Index = 0;
size_t Last = HexagonMCInstrInfo::bundleSize(HMB) - 1;
FeatureBitset Features = computeAvailableFeatures(STI.getFeatureBits());
for (auto &I : HexagonMCInstrInfo::bundleInstructions(HMB)) {
MCInst &HMI = const_cast<MCInst &>(*I.getInst());
verifyInstructionPredicates(HMI, Features);
EncodeSingleInstruction(HMI, OS, Fixups, STI, parseBits(Last, HMB, HMI));
State.Extended = HexagonMCInstrInfo::isImmext(HMI);
@ -793,5 +791,4 @@ MCCodeEmitter *llvm::createHexagonMCCodeEmitter(MCInstrInfo const &MII,
return new HexagonMCCodeEmitter(MII, MCT);
}
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "HexagonGenMCCodeEmitter.inc"

View File

@ -81,11 +81,6 @@ private:
// Return parse bits for instruction `MCI' inside bundle `MCB'
uint32_t parseBits(size_t Last, MCInst const &MCB, MCInst const &MCI) const;
FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
void
verifyInstructionPredicates(const MCInst &MI,
const FeatureBitset &AvailableFeatures) const;
};
} // end namespace llvm

View File

@ -46,6 +46,7 @@
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "HexagonGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -110,6 +110,7 @@ unsigned HexagonConvertUnits(unsigned ItinUnits, unsigned *Lanes);
//
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_SCHED_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "HexagonGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -195,6 +195,9 @@ void LanaiAsmPrinter::customEmitInstruction(const MachineInstr *MI) {
}
void LanaiAsmPrinter::emitInstruction(const MachineInstr *MI) {
Lanai_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
MachineBasicBlock::const_instr_iterator I = MI->getIterator();
MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();

View File

@ -28,6 +28,7 @@
#include <string>
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "LanaiGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -43,6 +43,7 @@ std::unique_ptr<MCObjectTargetWriter> createLanaiELFObjectWriter(uint8_t OSABI);
// Defines symbolic names for the Lanai instructions.
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "LanaiGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -27,6 +27,9 @@ using namespace llvm;
#include "LoongArchGenMCPseudoLowering.inc"
void LoongArchAsmPrinter::emitInstruction(const MachineInstr *MI) {
LoongArch_MC::verifyInstructionPredicates(
MI->getOpcode(), getSubtargetInfo().getFeatureBits());
// Do any auto-generated pseudo lowerings.
if (emitPseudoExpansionLowering(*OutStreamer, MI))
return;

View File

@ -25,6 +25,7 @@
#include "llvm/Support/Compiler.h"
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "LoongArchGenInstrInfo.inc"
#define GET_REGINFO_MC_DESC

View File

@ -46,6 +46,7 @@ createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit);
// Defines symbolic names for LoongArch instructions.
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "LoongArchGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -77,6 +77,9 @@ bool M68kAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
}
void M68kAsmPrinter::emitInstruction(const MachineInstr *MI) {
M68k_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
switch (MI->getOpcode()) {
default: {
if (MI->isPseudo()) {

View File

@ -31,6 +31,7 @@
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "M68kGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -52,6 +52,7 @@ std::unique_ptr<MCObjectTargetWriter> createM68kELFObjectWriter(uint8_t OSABI);
// Defines symbolic names for the M68k instructions.
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "M68kGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -22,6 +22,7 @@
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "MSP430GenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -53,6 +53,7 @@ createMSP430ELFObjectWriter(uint8_t OSABI);
// Defines symbolic names for the MSP430 instructions.
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "MSP430GenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -149,6 +149,9 @@ bool MSP430AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
//===----------------------------------------------------------------------===//
void MSP430AsmPrinter::emitInstruction(const MachineInstr *MI) {
MSP430_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
MSP430MCInstLower MCInstLowering(OutContext, *this);
MCInst TmpInst;

View File

@ -36,6 +36,7 @@
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "MipsGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -55,6 +55,7 @@ StringRef selectMipsCPU(const Triple &TT, StringRef CPU);
// Defines symbolic names for the Mips instructions.
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "MipsGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -181,6 +181,10 @@ static void emitDirectiveRelocJalr(const MachineInstr &MI,
}
void MipsAsmPrinter::emitInstruction(const MachineInstr *MI) {
// FIXME: Enable feature predicate checks once all the test pass.
// Mips_MC::verifyInstructionPredicates(MI->getOpcode(),
// getSubtargetInfo().getFeatureBits());
MipsTargetStreamer &TS = getTargetStreamer();
unsigned Opc = MI->getOpcode();
TS.forbidModuleDirective();

View File

@ -23,6 +23,7 @@
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "NVPTXGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -21,6 +21,7 @@
// Defines symbolic names for the PTX instructions.
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "NVPTXGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -183,6 +183,7 @@ enum CmpMode {
// Defines symbolic names for the NVPTX instructions.
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "NVPTXGenInstrInfo.inc"
#endif

View File

@ -139,6 +139,9 @@ VisitGlobalVariableForEmission(const GlobalVariable *GV,
}
void NVPTXAsmPrinter::emitInstruction(const MachineInstr *MI) {
NVPTX_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
MCInst Inst;
lowerToMCInst(MI, Inst);
EmitToStreamer(*OutStreamer, Inst);

View File

@ -449,12 +449,9 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
return MO.getImm();
}
void PPCMCCodeEmitter::encodeInstruction(
const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
void PPCMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
verifyInstructionPredicates(MI,
computeAvailableFeatures(STI.getFeatureBits()));
uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
// Output the constant in big/little endian byte order.
@ -492,5 +489,4 @@ bool PPCMCCodeEmitter::isPrefixedInstruction(const MCInst &MI) const {
return InstrInfo->isPrefixed(Opcode);
}
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "PPCGenMCCodeEmitter.inc"

View File

@ -121,12 +121,6 @@ public:
// Is this instruction a prefixed instruction.
bool isPrefixedInstruction(const MCInst &MI) const;
private:
FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
void
verifyInstructionPredicates(const MCInst &MI,
const FeatureBitset &AvailableFeatures) const;
};
} // namespace llvm

View File

@ -48,6 +48,7 @@
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "PPCGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -118,6 +118,7 @@ static inline bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME) {
//
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_SCHED_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "PPCGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -659,6 +659,9 @@ static MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO,
/// the current output stream.
///
void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
PPC_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
MCInst TmpInst;
const bool IsPPC64 = Subtarget->isPPC64();
const bool IsAIX = Subtarget->isAIXABI();

View File

@ -84,12 +84,6 @@ public:
unsigned getVMaskReg(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
private:
FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
void
verifyInstructionPredicates(const MCInst &MI,
const FeatureBitset &AvailableFeatures) const;
};
} // end anonymous namespace
@ -188,9 +182,6 @@ void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI, raw_ostream &OS,
void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
verifyInstructionPredicates(MI,
computeAvailableFeatures(STI.getFeatureBits()));
const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
// Get byte count of instruction.
unsigned Size = Desc.getSize();
@ -403,5 +394,4 @@ unsigned RISCVMCCodeEmitter::getVMaskReg(const MCInst &MI, unsigned OpNo,
}
}
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "RISCVGenMCCodeEmitter.inc"

View File

@ -33,6 +33,7 @@
#include "llvm/Support/ErrorHandling.h"
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "RISCVGenInstrInfo.inc"
#define GET_REGINFO_MC_DESC

View File

@ -45,6 +45,7 @@ std::unique_ptr<MCObjectTargetWriter> createRISCVELFObjectWriter(uint8_t OSABI,
// Defines symbolic names for RISC-V instructions.
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "RISCVGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -91,6 +91,9 @@ void RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {
#include "RISCVGenMCPseudoLowering.inc"
void RISCVAsmPrinter::emitInstruction(const MachineInstr *MI) {
RISCV_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
// Do any auto-generated pseudo lowerings.
if (emitPseudoExpansionLowering(*OutStreamer, MI))
return;

View File

@ -46,12 +46,6 @@ public:
void encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const override;
private:
FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
void
verifyInstructionPredicates(const MCInst &MI,
const FeatureBitset &AvailableFeatures) const;
};
} // end anonymous namespace
@ -110,9 +104,6 @@ static void emitUntypedInstrOperands(const MCInst &MI, EndianWriter &OSE) {
void SPIRVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
auto Features = computeAvailableFeatures(STI.getFeatureBits());
verifyInstructionPredicates(MI, Features);
EndianWriter OSE(OS, support::little);
// Encode the first 32 SPIR-V bytes with the number of args and the opcode.
@ -128,5 +119,4 @@ void SPIRVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
emitUntypedInstrOperands(MI, OSE);
}
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "SPIRVGenMCCodeEmitter.inc"

View File

@ -22,6 +22,7 @@
#include "llvm/MC/TargetRegistry.h"
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "SPIRVGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -44,6 +44,7 @@ std::unique_ptr<MCObjectTargetWriter> createSPIRVObjectTargetWriter();
// Defines symbolic names for the SPIR-V instructions.
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "SPIRVGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -215,6 +215,9 @@ void SPIRVAsmPrinter::outputInstruction(const MachineInstr *MI) {
}
void SPIRVAsmPrinter::emitInstruction(const MachineInstr *MI) {
SPIRV_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
if (!MAI->getSkipEmission(MI))
outputInstruction(MI);

View File

@ -44,12 +44,11 @@ STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
namespace {
class SparcMCCodeEmitter : public MCCodeEmitter {
const MCInstrInfo &MCII;
MCContext &Ctx;
public:
SparcMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
: MCII(mcii), Ctx(ctx) {}
SparcMCCodeEmitter(const MCInstrInfo &, MCContext &ctx)
: Ctx(ctx) {}
SparcMCCodeEmitter(const SparcMCCodeEmitter &) = delete;
SparcMCCodeEmitter &operator=(const SparcMCCodeEmitter &) = delete;
~SparcMCCodeEmitter() override = default;
@ -84,12 +83,6 @@ public:
unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
private:
FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
void
verifyInstructionPredicates(const MCInst &MI,
const FeatureBitset &AvailableFeatures) const;
};
} // end anonymous namespace
@ -97,9 +90,6 @@ private:
void SparcMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
verifyInstructionPredicates(MI,
computeAvailableFeatures(STI.getFeatureBits()));
unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI);
support::endian::write(OS, Bits,
Ctx.getAsmInfo()->isLittleEndian() ? support::little
@ -253,7 +243,6 @@ getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
return 0;
}
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "SparcGenMCCodeEmitter.inc"
MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,

View File

@ -24,6 +24,7 @@
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "SparcGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -46,6 +46,7 @@ std::unique_ptr<MCObjectTargetWriter> createSparcELFObjectWriter(bool Is64Bit,
// Defines symbolic names for the Sparc instructions.
//
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "SparcGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -250,6 +250,8 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
}
void SparcAsmPrinter::emitInstruction(const MachineInstr *MI) {
Sparc_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
switch (MI->getOpcode()) {
default: break;

View File

@ -150,23 +150,13 @@ private:
return getPCRelEncoding(MI, OpNum, Fixups,
SystemZ::FK_390_PC24DBL, 3, false);
}
private:
FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
void
verifyInstructionPredicates(const MCInst &MI,
const FeatureBitset &AvailableFeatures) const;
};
} // end anonymous namespace
void SystemZMCCodeEmitter::
encodeInstruction(const MCInst &MI, raw_ostream &OS,
void SystemZMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
verifyInstructionPredicates(MI,
computeAvailableFeatures(STI.getFeatureBits()));
MemOpsEmitted = 0;
uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
unsigned Size = MCII.get(MI.getOpcode()).getSize();
@ -329,7 +319,6 @@ SystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum,
return 0;
}
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "SystemZGenMCCodeEmitter.inc"
MCCodeEmitter *llvm::createSystemZMCCodeEmitter(const MCInstrInfo &MCII,

View File

@ -23,6 +23,7 @@
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "SystemZGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -95,6 +95,7 @@ std::unique_ptr<MCObjectTargetWriter> createSystemZObjectWriter(uint8_t OSABI);
// Defines symbolic names for the SystemZ instructions.
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "SystemZGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -143,6 +143,9 @@ void SystemZAsmPrinter::emitCallInformation(CallType CT) {
}
void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
SystemZ_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
SystemZMCInstLower Lower(MF->getContext(), *this);
MCInst LoweredMI;
switch (MI->getOpcode()) {

View File

@ -39,12 +39,11 @@ STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
namespace {
class VEMCCodeEmitter : public MCCodeEmitter {
const MCInstrInfo &MCII;
MCContext &Ctx;
public:
VEMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
: MCII(mcii), Ctx(ctx) {}
VEMCCodeEmitter(const MCInstrInfo &, MCContext &ctx)
: Ctx(ctx) {}
VEMCCodeEmitter(const VEMCCodeEmitter &) = delete;
VEMCCodeEmitter &operator=(const VEMCCodeEmitter &) = delete;
~VEMCCodeEmitter() override = default;
@ -74,12 +73,6 @@ public:
uint64_t getRDOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
private:
FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
void
verifyInstructionPredicates(const MCInst &MI,
const FeatureBitset &AvailableFeatures) const;
};
} // end anonymous namespace
@ -87,9 +80,6 @@ private:
void VEMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
verifyInstructionPredicates(MI,
computeAvailableFeatures(STI.getFeatureBits()));
uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
support::endian::write<uint64_t>(OS, Bits, support::little);
@ -155,7 +145,6 @@ uint64_t VEMCCodeEmitter::getRDOpValue(const MCInst &MI, unsigned OpNo,
return 0;
}
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "VEGenMCCodeEmitter.inc"
MCCodeEmitter *llvm::createVEMCCodeEmitter(const MCInstrInfo &MCII,

View File

@ -24,6 +24,7 @@
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "VEGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -44,6 +44,7 @@ std::unique_ptr<MCObjectTargetWriter> createVEELFObjectWriter(uint8_t OSABI);
// Defines symbolic names for the VE instructions.
//
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "VEGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -325,6 +325,8 @@ void VEAsmPrinter::lowerGETTLSAddrAndEmitMCInsts(const MachineInstr *MI,
}
void VEAsmPrinter::emitInstruction(const MachineInstr *MI) {
VE_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
switch (MI->getOpcode()) {
default:

View File

@ -26,6 +26,7 @@ using namespace llvm;
#define DEBUG_TYPE "wasm-mc-target-desc"
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "WebAssemblyGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -124,6 +124,7 @@ enum TOF {
// Defines symbolic names for the WebAssembly instructions.
//
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "WebAssemblyGenInstrInfo.inc"
namespace llvm {

View File

@ -37,4 +37,5 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTargetInfo() {
// which have to be in a shared location between CodeGen and MC.
#define GET_INSTRMAP_INFO 1
#define GET_INSTRINFO_ENUM 1
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "WebAssemblyGenInstrInfo.inc"

View File

@ -597,6 +597,8 @@ void WebAssemblyAsmPrinter::emitFunctionBodyStart() {
void WebAssemblyAsmPrinter::emitInstruction(const MachineInstr *MI) {
LLVM_DEBUG(dbgs() << "EmitInstruction: " << *MI << '\n');
WebAssembly_MC::verifyInstructionPredicates(MI->getOpcode(),
Subtarget->getFeatureBits());
switch (MI->getOpcode()) {
case WebAssembly::ARGUMENT_i32:

View File

@ -37,6 +37,7 @@ using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define GET_INSTRINFO_MC_HELPERS
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "X86GenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -2413,6 +2413,10 @@ static void addConstantComments(const MachineInstr *MI,
}
void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {
// FIXME: Enable feature predicate checks once all the test pass.
// X86_MC::verifyInstructionPredicates(MI->getOpcode(),
// Subtarget->getFeatureBits());
X86MCInstLower MCInstLowering(*MF, *this);
const X86RegisterInfo *RI =
MF->getSubtarget<X86Subtarget>().getRegisterInfo();

View File

@ -29,6 +29,7 @@
using namespace llvm;
#define GET_INSTRINFO_MC_DESC
#define ENABLE_INSTR_PREDICATE_VERIFIER
#include "XCoreGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC

View File

@ -22,6 +22,7 @@
// Defines symbolic names for the XCore instructions.
//
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_HELPER_DECLS
#include "XCoreGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM

View File

@ -256,6 +256,9 @@ bool XCoreAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
}
void XCoreAsmPrinter::emitInstruction(const MachineInstr *MI) {
XCore_MC::verifyInstructionPredicates(MI->getOpcode(),
getSubtargetInfo().getFeatureBits());
SmallString<128> Str;
raw_svector_ostream O(Str);

View File

@ -332,14 +332,6 @@ std::string CodeEmitterGen::getInstructionCaseForEncoding(Record *R, Record *Enc
return Case;
}
static std::string
getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
std::string Name = "CEFBS";
for (const auto &Feature : FeatureBitset)
Name += ("_" + Feature->getName()).str();
return Name;
}
static void emitInstBits(raw_ostream &OS, const APInt &Bits) {
for (unsigned I = 0; I < Bits.getNumWords(); ++I)
OS << ((I > 0) ? ", " : "") << "UINT64_C(" << utostr(Bits.getRawData()[I])
@ -530,131 +522,6 @@ void CodeEmitterGen::run(raw_ostream &o) {
o << " return Value;\n";
o << "}\n\n";
}
const auto &All = SubtargetFeatureInfo::getAll(Records);
std::map<Record *, SubtargetFeatureInfo, LessRecordByID> SubtargetFeatures;
SubtargetFeatures.insert(All.begin(), All.end());
o << "#ifdef ENABLE_INSTR_PREDICATE_VERIFIER\n"
<< "#undef ENABLE_INSTR_PREDICATE_VERIFIER\n"
<< "#include <sstream>\n\n";
// Emit the subtarget feature enumeration.
SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
o);
// Emit the name table for error messages.
o << "#ifndef NDEBUG\n";
SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, o);
o << "#endif // NDEBUG\n";
// Emit the available features compute function.
SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
Target.getName(), "MCCodeEmitter", "computeAvailableFeatures",
SubtargetFeatures, o);
std::vector<std::vector<Record *>> FeatureBitsets;
for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
FeatureBitsets.emplace_back();
for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) {
const auto &I = SubtargetFeatures.find(Predicate);
if (I != SubtargetFeatures.end())
FeatureBitsets.back().push_back(I->second.TheDef);
}
}
llvm::sort(FeatureBitsets, [&](const std::vector<Record *> &A,
const std::vector<Record *> &B) {
if (A.size() < B.size())
return true;
if (A.size() > B.size())
return false;
for (auto Pair : zip(A, B)) {
if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
return true;
if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
return false;
}
return false;
});
FeatureBitsets.erase(
std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
FeatureBitsets.end());
o << "#ifndef NDEBUG\n"
<< "// Feature bitsets.\n"
<< "enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n"
<< " CEFBS_None,\n";
for (const auto &FeatureBitset : FeatureBitsets) {
if (FeatureBitset.empty())
continue;
o << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
}
o << "};\n\n"
<< "static constexpr FeatureBitset FeatureBitsets[] = {\n"
<< " {}, // CEFBS_None\n";
for (const auto &FeatureBitset : FeatureBitsets) {
if (FeatureBitset.empty())
continue;
o << " {";
for (const auto &Feature : FeatureBitset) {
const auto &I = SubtargetFeatures.find(Feature);
assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
o << I->second.getEnumBitName() << ", ";
}
o << "},\n";
}
o << "};\n"
<< "#endif // NDEBUG\n\n";
// Emit the predicate verifier.
o << "void " << Target.getName()
<< "MCCodeEmitter::verifyInstructionPredicates(\n"
<< " const MCInst &Inst, const FeatureBitset &AvailableFeatures) const {\n"
<< "#ifndef NDEBUG\n"
<< " static " << getMinimalTypeForRange(FeatureBitsets.size())
<< " RequiredFeaturesRefs[] = {\n";
unsigned InstIdx = 0;
for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
o << " CEFBS";
unsigned NumPredicates = 0;
for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) {
const auto &I = SubtargetFeatures.find(Predicate);
if (I != SubtargetFeatures.end()) {
o << '_' << I->second.TheDef->getName();
NumPredicates++;
}
}
if (!NumPredicates)
o << "_None";
o << ", // " << Inst->TheDef->getName() << " = " << InstIdx << "\n";
InstIdx++;
}
o << " };\n\n";
o << " assert(Inst.getOpcode() < " << InstIdx << ");\n";
o << " const FeatureBitset &RequiredFeatures = "
"FeatureBitsets[RequiredFeaturesRefs[Inst.getOpcode()]];\n";
o << " FeatureBitset MissingFeatures =\n"
<< " (AvailableFeatures & RequiredFeatures) ^\n"
<< " RequiredFeatures;\n"
<< " if (MissingFeatures.any()) {\n"
<< " std::ostringstream Msg;\n"
<< " Msg << \"Attempting to emit \" << "
"MCII.getName(Inst.getOpcode()).str()\n"
<< " << \" instruction but the \";\n"
<< " for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)\n"
<< " if (MissingFeatures.test(i))\n"
<< " Msg << SubtargetFeatureNames[i] << \" \";\n"
<< " Msg << \"predicate(s) are not met\";\n"
<< " report_fatal_error(Msg.str().c_str());\n"
<< " }\n"
<< "#else\n"
<< " // Silence unused variable warning on targets that don't use MCII for "
"other purposes (e.g. BPF).\n"
<< " (void)MCII;\n"
<< "#endif // NDEBUG\n";
o << "}\n";
o << "#endif\n";
}
} // end anonymous namespace

View File

@ -17,7 +17,9 @@
#include "CodeGenTarget.h"
#include "PredicateExpander.h"
#include "SequenceToOffsetTable.h"
#include "SubtargetFeatureInfo.h"
#include "TableGenBackends.h"
#include "Types.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
@ -79,6 +81,9 @@ private:
/// Expand TIIPredicate definitions to functions that accept a const MCInst
/// reference.
void emitMCIIHelperMethods(raw_ostream &OS, StringRef TargetName);
/// Write verifyInstructionPredicates methods.
void emitFeatureVerifier(raw_ostream &OS, const CodeGenTarget &Target);
void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
Record *InstrInfo,
std::map<std::vector<Record*>, unsigned> &EL,
@ -666,14 +671,13 @@ void InstrInfoEmitter::emitLogicalOperandTypeMappings(
void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
StringRef TargetName) {
RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate");
if (TIIPredicates.empty())
return;
OS << "#ifdef GET_INSTRINFO_MC_HELPER_DECLS\n";
OS << "#undef GET_INSTRINFO_MC_HELPER_DECLS\n\n";
OS << "namespace llvm {\n";
OS << "class MCInst;\n\n";
OS << "class MCInst;\n";
OS << "class FeatureBitset;\n\n";
OS << "namespace " << TargetName << "_MC {\n\n";
@ -682,6 +686,9 @@ void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
<< "(const MCInst &MI);\n";
}
OS << "void verifyInstructionPredicates(unsigned Opcode, const FeatureBitset "
"&Features);\n";
OS << "\n} // end namespace " << TargetName << "_MC\n";
OS << "} // end namespace llvm\n\n";
@ -708,7 +715,143 @@ void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
OS << "} // end namespace " << TargetName << "_MC\n";
OS << "} // end namespace llvm\n\n";
OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n";
OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n\n";
}
static std::string
getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
std::string Name = "CEFBS";
for (const auto &Feature : FeatureBitset)
Name += ("_" + Feature->getName()).str();
return Name;
}
void InstrInfoEmitter::emitFeatureVerifier(raw_ostream &OS,
const CodeGenTarget &Target) {
const auto &All = SubtargetFeatureInfo::getAll(Records);
std::map<Record *, SubtargetFeatureInfo, LessRecordByID> SubtargetFeatures;
SubtargetFeatures.insert(All.begin(), All.end());
OS << "#ifdef ENABLE_INSTR_PREDICATE_VERIFIER\n"
<< "#undef ENABLE_INSTR_PREDICATE_VERIFIER\n"
<< "#include <sstream>\n\n";
OS << "namespace llvm {\n";
OS << "namespace " << Target.getName() << "_MC {\n\n";
// Emit the subtarget feature enumeration.
SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
OS);
// Emit the name table for error messages.
OS << "#ifndef NDEBUG\n";
SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS);
OS << "#endif // NDEBUG\n\n";
// Emit the available features compute function.
SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
Target.getName(), "", "computeAvailableFeatures", SubtargetFeatures, OS);
std::vector<std::vector<Record *>> FeatureBitsets;
for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
FeatureBitsets.emplace_back();
for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) {
const auto &I = SubtargetFeatures.find(Predicate);
if (I != SubtargetFeatures.end())
FeatureBitsets.back().push_back(I->second.TheDef);
}
}
llvm::sort(FeatureBitsets, [&](const std::vector<Record *> &A,
const std::vector<Record *> &B) {
if (A.size() < B.size())
return true;
if (A.size() > B.size())
return false;
for (auto Pair : zip(A, B)) {
if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
return true;
if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
return false;
}
return false;
});
FeatureBitsets.erase(
std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
FeatureBitsets.end());
OS << "#ifndef NDEBUG\n"
<< "// Feature bitsets.\n"
<< "enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n"
<< " CEFBS_None,\n";
for (const auto &FeatureBitset : FeatureBitsets) {
if (FeatureBitset.empty())
continue;
OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
}
OS << "};\n\n"
<< "static constexpr FeatureBitset FeatureBitsets[] = {\n"
<< " {}, // CEFBS_None\n";
for (const auto &FeatureBitset : FeatureBitsets) {
if (FeatureBitset.empty())
continue;
OS << " {";
for (const auto &Feature : FeatureBitset) {
const auto &I = SubtargetFeatures.find(Feature);
assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
OS << I->second.getEnumBitName() << ", ";
}
OS << "},\n";
}
OS << "};\n"
<< "#endif // NDEBUG\n\n";
// Emit the predicate verifier.
OS << "void verifyInstructionPredicates(\n"
<< " unsigned Opcode, const FeatureBitset &Features) {\n"
<< "#ifndef NDEBUG\n"
<< " static " << getMinimalTypeForRange(FeatureBitsets.size())
<< " RequiredFeaturesRefs[] = {\n";
unsigned InstIdx = 0;
for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
OS << " CEFBS";
unsigned NumPredicates = 0;
for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) {
const auto &I = SubtargetFeatures.find(Predicate);
if (I != SubtargetFeatures.end()) {
OS << '_' << I->second.TheDef->getName();
NumPredicates++;
}
}
if (!NumPredicates)
OS << "_None";
OS << ", // " << Inst->TheDef->getName() << " = " << InstIdx << "\n";
InstIdx++;
}
OS << " };\n\n";
OS << " assert(Opcode < " << InstIdx << ");\n";
OS << " FeatureBitset AvailableFeatures = "
"computeAvailableFeatures(Features);\n";
OS << " const FeatureBitset &RequiredFeatures = "
"FeatureBitsets[RequiredFeaturesRefs[Opcode]];\n";
OS << " FeatureBitset MissingFeatures =\n"
<< " (AvailableFeatures & RequiredFeatures) ^\n"
<< " RequiredFeatures;\n"
<< " if (MissingFeatures.any()) {\n"
<< " std::ostringstream Msg;\n"
<< " Msg << \"Attempting to emit \" << &" << Target.getName()
<< "InstrNameData[" << Target.getName() << "InstrNameIndices[Opcode]]\n"
<< " << \" instruction but the \";\n"
<< " for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)\n"
<< " if (MissingFeatures.test(i))\n"
<< " Msg << SubtargetFeatureNames[i] << \" \";\n"
<< " Msg << \"predicate(s) are not met\";\n"
<< " report_fatal_error(Msg.str().c_str());\n"
<< " }\n"
<< "#endif // NDEBUG\n";
OS << "}\n";
OS << "} // end namespace " << Target.getName() << "_MC\n";
OS << "} // end namespace llvm\n";
OS << "#endif // ENABLE_INSTR_PREDICATE_VERIFIER\n\n";
}
void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS,
@ -955,6 +1098,9 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
Records.startTimer("Emit helper methods");
emitMCIIHelperMethods(OS, TargetName);
Records.startTimer("Emit verifier methods");
emitFeatureVerifier(OS, Target);
}
void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,

View File

@ -144,8 +144,13 @@ static bool emitFeaturesAux(StringRef TargetName, const Init &Val,
void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
StringRef TargetName, StringRef ClassName, StringRef FuncName,
SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
OS << "FeatureBitset " << TargetName << ClassName << "::\n"
<< FuncName << "(const FeatureBitset &FB) const {\n";
OS << "FeatureBitset ";
if (!ClassName.empty())
OS << TargetName << ClassName << "::\n";
OS << FuncName << "(const FeatureBitset &FB) ";
if (!ClassName.empty())
OS << "const ";
OS << "{\n";
OS << " FeatureBitset Features;\n";
for (const auto &SF : SubtargetFeatures) {
const SubtargetFeatureInfo &SFI = SF.second;