[MC,X86] emitInstruction: remove virtual function calls due to Intel JCC Erratum

https://reviews.llvm.org/D70157 (for Intel Jump Conditional Code
Erratum) introduced two virtual function calls in the generic
MCObjectStreamer::emitInstruction, which added some overhead.

This patch removes the virtual function overhead:

* Define `llvm::X86_MC::emitInstruction` that calls `emitInstruction{Begin,End}`.
* Define {X86ELFStreamer,X86WinCOFFStreamer}::emitInstruction to call `llvm::X86_MC::emitInstruction`

Pull Request: https://github.com/llvm/llvm-project/pull/96835
This commit is contained in:
Fangrui Song 2024-06-27 09:43:32 -07:00 committed by GitHub
parent 4168233bad
commit aa3589f0cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 54 additions and 12 deletions

View File

@ -62,13 +62,6 @@ public:
/// tricky way for optimization.
virtual bool allowEnhancedRelaxation() const { return false; }
/// Give the target a chance to manipulate state related to instruction
/// alignment (e.g. padding for optimization), instruction relaxablility, etc.
/// before and after actually emitting the instruction.
virtual void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst,
const MCSubtargetInfo &STI) {}
virtual void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst) {}
/// lifetime management
virtual void reset() {}

View File

@ -330,9 +330,7 @@ void MCObjectStreamer::emitInstruction(const MCInst &Inst,
"' cannot have instructions");
return;
}
getAssembler().getBackend().emitInstructionBegin(*this, Inst, STI);
emitInstructionImpl(Inst, STI);
getAssembler().getBackend().emitInstructionEnd(*this, Inst);
}
void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst,

View File

@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include "MCTargetDesc/X86BaseInfo.h"
#include "MCTargetDesc/X86FixupKinds.h"
#include "MCTargetDesc/X86EncodingOptimization.h"
#include "MCTargetDesc/X86FixupKinds.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/BinaryFormat/MachO.h"
@ -19,6 +19,7 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCInst.h"
@ -162,8 +163,8 @@ public:
bool allowAutoPadding() const override;
bool allowEnhancedRelaxation() const override;
void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst,
const MCSubtargetInfo &STI) override;
void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst) override;
const MCSubtargetInfo &STI);
void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst);
unsigned getNumFixupKinds() const override {
return X86::NumTargetFixupKinds;
@ -1546,3 +1547,37 @@ MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
return new ELFX86_X32AsmBackend(T, OSABI, STI);
return new ELFX86_64AsmBackend(T, OSABI, STI);
}
namespace {
class X86ELFStreamer : public MCELFStreamer {
public:
X86ELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
std::unique_ptr<MCObjectWriter> OW,
std::unique_ptr<MCCodeEmitter> Emitter)
: MCELFStreamer(Context, std::move(TAB), std::move(OW),
std::move(Emitter)) {}
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
};
} // end anonymous namespace
void X86_MC::emitInstruction(MCObjectStreamer &S, const MCInst &Inst,
const MCSubtargetInfo &STI) {
auto &Backend = static_cast<X86AsmBackend &>(S.getAssembler().getBackend());
Backend.emitInstructionBegin(S, Inst, STI);
S.MCObjectStreamer::emitInstruction(Inst, STI);
Backend.emitInstructionEnd(S, Inst);
}
void X86ELFStreamer::emitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI) {
X86_MC::emitInstruction(*this, Inst, STI);
}
MCStreamer *llvm::createX86ELFStreamer(const Triple &T, MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB,
std::unique_ptr<MCObjectWriter> &&MOW,
std::unique_ptr<MCCodeEmitter> &&MCE) {
return new X86ELFStreamer(Context, std::move(MAB), std::move(MOW),
std::move(MCE));
}

View File

@ -742,6 +742,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86TargetMC() {
TargetRegistry::RegisterNullTargetStreamer(*T, createX86NullTargetStreamer);
TargetRegistry::RegisterCOFFStreamer(*T, createX86WinCOFFStreamer);
TargetRegistry::RegisterELFStreamer(*T, createX86ELFStreamer);
// Register the MCInstPrinter.
TargetRegistry::RegisterMCInstPrinter(*T, createX86MCInstPrinter);

View File

@ -24,6 +24,7 @@ class MCContext;
class MCInst;
class MCInstPrinter;
class MCInstrInfo;
class MCObjectStreamer;
class MCObjectTargetWriter;
class MCObjectWriter;
class MCRegister;
@ -89,6 +90,9 @@ bool needsAddressSizeOverride(const MCInst &MI, const MCSubtargetInfo &STI,
/// do not need to go through TargetRegistry.
MCSubtargetInfo *createX86MCSubtargetInfo(const Triple &TT, StringRef CPU,
StringRef FS);
void emitInstruction(MCObjectStreamer &, const MCInst &Inst,
const MCSubtargetInfo &STI);
}
MCCodeEmitter *createX86MCCodeEmitter(const MCInstrInfo &MCII,
@ -123,6 +127,11 @@ MCStreamer *createX86WinCOFFStreamer(MCContext &C,
std::unique_ptr<MCCodeEmitter> &&CE,
bool IncrementalLinkerCompatible);
MCStreamer *createX86ELFStreamer(const Triple &T, MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB,
std::unique_ptr<MCObjectWriter> &&MOW,
std::unique_ptr<MCCodeEmitter> &&MCE);
/// Construct an X86 Mach-O object writer.
std::unique_ptr<MCObjectTargetWriter>
createX86MachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype);

View File

@ -26,6 +26,7 @@ public:
std::unique_ptr<MCObjectWriter> OW)
: MCWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)) {}
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
void emitWinEHHandlerData(SMLoc Loc) override;
void emitWindowsUnwindTables(WinEH::FrameInfo *Frame) override;
void emitWindowsUnwindTables() override;
@ -33,6 +34,11 @@ public:
void finishImpl() override;
};
void X86WinCOFFStreamer::emitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI) {
X86_MC::emitInstruction(*this, Inst, STI);
}
void X86WinCOFFStreamer::emitWinEHHandlerData(SMLoc Loc) {
MCStreamer::emitWinEHHandlerData(Loc);